Skip to content

Commit

Permalink
Interim
Browse files Browse the repository at this point in the history
  • Loading branch information
benmerckx committed Apr 26, 2024
1 parent 26525a4 commit 2dd6c35
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 17 deletions.
26 changes: 24 additions & 2 deletions src/core/Builder.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {getData, internalData, type HasTable} from './Internal.ts'
import type {QueryMeta} from './MetaData.ts'
import {getData, internalData, type HasSql, type HasTable} from './Internal.ts'
import type {IsPostgres, QueryMeta} from './MetaData.ts'
import type {QueryData} from './Query.ts'
import type {SelectionInput} from './Selection.ts'
import type {Table, TableDefinition} from './Table.ts'
Expand Down Expand Up @@ -59,6 +59,28 @@ export class Builder<Meta extends QueryMeta> {
})
}

selectDistinctOn(
this: Builder<IsPostgres>,
columns: Array<HasSql>
): WithoutSelection<Meta>
selectDistinctOn<Input extends SelectionInput>(
this: Builder<IsPostgres>,
columns: Array<HasSql>,
selection: Input
): WithSelection<Input, Meta>
selectDistinctOn(columns: any, selection?: any): any {
return new Select({
...getData(this),
select: {
type: selection ? 'selection' : 'allFrom',
input: selection,
tables: [],
nullable: []
},
distinctOn: columns
})
}

update<Definition extends TableDefinition>(table: Table<Definition>) {
return new UpdateTable<Definition, Meta>({...getData(this), table})
}
Expand Down
18 changes: 15 additions & 3 deletions src/core/Emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,24 @@ export abstract class Emitter {
}

emitSelect(select: Select<unknown>): void {
const {from, distinct, where, groupBy, orderBy, having, limit, offset} =
getData(select)
const {
from,
distinct,
distinctOn,
where,
groupBy,
orderBy,
having,
limit,
offset
} = getData(select)
const selected = getSelection(select)
const prefix = distinctOn
? sql`distinct on (${sql.join(distinctOn, sql`, `)})`
: distinct && sql`distinct`
sql
.query({
select: distinct ? sql`distinct ${selected}` : selected,
select: sql.join([prefix, selected]),
from,
where,
groupBy,
Expand Down
8 changes: 8 additions & 0 deletions src/core/MetaData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ export interface IsPostgres extends QueryMeta {
dialect: 'postgres'
}

export interface IsMysql extends QueryMeta {
dialect: 'mysql'
}

export interface IsSqlite extends QueryMeta {
dialect: 'sqlite'
}

export interface Either extends QueryMeta {
mode: 'sync' | 'async'
dialect: QueryDialect
Expand Down
13 changes: 10 additions & 3 deletions src/core/query/Insert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import {
} from '../Internal.ts'
import type {IsPostgres, QueryMeta} from '../MetaData.ts'
import {Query, QueryData} from '../Query.ts'
import {selection, type Selection} from '../Selection.ts'
import {
selection,
type Selection,
type SelectionInput,
type SelectionRow
} from '../Selection.ts'
import {sql} from '../Sql.ts'
import type {
TableDefinition,
Expand Down Expand Up @@ -53,8 +58,10 @@ class InsertCanReturn<
Meta extends QueryMeta
> extends Insert<void, Meta> {
returning(): Insert<TableRow<Definition>, Meta>
returning<T>(returning: HasSql<T>): Insert<T, Meta>
returning(returning?: HasSql) {
returning<Input extends SelectionInput>(
returning: Input
): Insert<SelectionRow<Input>, Meta>
returning(returning?: SelectionInput) {
const data = getData(this)
return new Insert({
...data,
Expand Down
33 changes: 32 additions & 1 deletion src/core/query/Select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
type HasSql,
type HasTable
} from '../Internal.ts'
import type {QueryMeta} from '../MetaData.ts'
import type {IsMysql, IsPostgres, QueryMeta} from '../MetaData.ts'
import {Query, QueryData} from '../Query.ts'
import {
selection,
Expand All @@ -41,6 +41,7 @@ export class SelectData<Meta extends QueryMeta> extends QueryData<Meta> {
input?: SelectionInput
}
distinct?: boolean
distinctOn?: Array<HasSql>
from?: HasSql
subject?: HasSql
where?: HasSql
Expand Down Expand Up @@ -205,6 +206,19 @@ export class Select<Input, Meta extends QueryMeta = QueryMeta>
})
}

intersectAll(
this: SelectBase<Input, IsPostgres | IsMysql>,
right: SelectBase<Input, Meta>
): Union<Input, Meta> {
return new Union({
...getData(<SelectBase<Input, Meta>>this),
selection: getSelection(this),
left: this,
operator: sql`intersect all`,
right
})
}

except(right: SelectBase<Input, Meta>): Union<Input, Meta> {
return new Union({
...getData(this),
Expand All @@ -215,6 +229,18 @@ export class Select<Input, Meta extends QueryMeta = QueryMeta>
})
}

exceptAll(
right: SelectBase<Input, IsPostgres | IsMysql>
): Union<Input, Meta> {
return new Union({
...getData(<SelectBase<Input, Meta>>this),
selection: getSelection(this),
left: this,
operator: sql`except all`,
right
})
}

get [internalSelection]() {
const {select} = getData(this)
if (!select.input) throw new Error('No selection defined')
Expand All @@ -240,7 +266,12 @@ export interface SelectBase<Input, Meta extends QueryMeta>
union(right: SelectBase<Input, Meta>): Union<Input, Meta>
unionAll(right: SelectBase<Input, Meta>): Union<Input, Meta>
intersect(right: SelectBase<Input, Meta>): Union<Input, Meta>
intersectAll(
this: SelectBase<Input, IsPostgres | IsMysql>,
right: SelectBase<Input, Meta>
): Union<Input, Meta>
except(right: SelectBase<Input, Meta>): Union<Input, Meta>
exceptAll(right: SelectBase<Input, IsPostgres | IsMysql>): Union<Input, Meta>
as(name: string): SubQuery<Input>
}

Expand Down
44 changes: 43 additions & 1 deletion src/core/query/Union.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
type HasSelection,
type HasSql
} from '../Internal.ts'
import type {QueryMeta} from '../MetaData.ts'
import type {IsMysql, IsPostgres, QueryMeta} from '../MetaData.ts'
import {Query, QueryData} from '../Query.ts'
import type {Selection} from '../Selection.ts'
import {sql} from '../Sql.ts'
Expand Down Expand Up @@ -73,3 +73,45 @@ export class Union<Result, Meta extends QueryMeta = QueryMeta>
return sql.chunk('emitUnion', this)
}
}

export function union<Result, Meta extends QueryMeta>(
left: SelectBase<Result, Meta>,
right: SelectBase<Result, Meta>
): Union<Result, Meta> {
return left.union(right)
}

export function unionAll<Result, Meta extends QueryMeta>(
left: SelectBase<Result, Meta>,
right: SelectBase<Result, Meta>
): Union<Result, Meta> {
return left.unionAll(right)
}

export function intersect<Result, Meta extends QueryMeta>(
left: SelectBase<Result, Meta>,
right: SelectBase<Result, Meta>
): Union<Result, Meta> {
return left.intersect(right)
}

export function intersectAll<Result, Meta extends IsPostgres | IsMysql>(
left: SelectBase<Result, Meta>,
right: SelectBase<Result, Meta>
): Union<Result, Meta> {
return left.intersectAll(right)
}

export function except<Result, Meta extends QueryMeta>(
left: SelectBase<Result, Meta>,
right: SelectBase<Result, Meta>
): Union<Result, Meta> {
return left.except(right)
}

export function exceptAll<Result, Meta extends IsPostgres | IsMysql>(
left: SelectBase<Result, Meta>,
right: SelectBase<Result, Meta>
): Union<Result, Meta> {
return left.exceptAll(right)
}
8 changes: 5 additions & 3 deletions src/core/query/Update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class UpdateTable<
Definition extends TableDefinition,
Meta extends QueryMeta
> extends Update<void, Meta> {
set(values: TableUpdate<Definition>) {
set(values: TableUpdate<Definition>): UpdateTable<Definition, Meta> {
const set = sql.join(
Object.entries(values).map(
([key, value]) => sql`${sql.identifier(key)} = ${input(value)}`
Expand All @@ -59,11 +59,13 @@ export class UpdateTable<
return new UpdateTable<Definition, Meta>({...getData(this), set})
}

where(where: HasSql<boolean>) {
where(where: HasSql<boolean>): UpdateTable<Definition, Meta> {
return new UpdateTable<Definition, Meta>({...getData(this), where})
}

returning<Input extends SelectionInput>(returning: Input) {
returning<Input extends SelectionInput>(
returning: Input
): Update<SelectionRow<Input>, Meta> {
return new Update<SelectionRow<Input>, Meta>({
...getData(this),
returning: selection(returning)
Expand Down
10 changes: 6 additions & 4 deletions test/driver/pglite.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import {Os} from '@sinclair/carbon'
import {connect} from '../../src/driver/pglite.ts'
import {testDriver} from '../TestDriver.ts'

await testDriver('pglite', async () => {
const {PGlite} = await import('@electric-sql/pglite')
return connect(new PGlite())
})
if (Os.type() !== 'win32')
await testDriver('pglite', async () => {
const {PGlite} = await import('@electric-sql/pglite')
return connect(new PGlite())
})

0 comments on commit 2dd6c35

Please sign in to comment.