Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #162 from patrickdronk/master
Add truncate functionality
- Loading branch information
Showing
6 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`truncate should truncate (type) should match snapshot 1`] = `"never"`; | ||
|
||
exports[`truncate should truncate and await affected row count (type) should match snapshot 1`] = `"number"`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { defineDb, defineTable, integer, text, timestampWithTimeZone, uuid } from '../../.build'; | ||
import { Query } from '../../.build/query'; | ||
import { ResultSet } from '../../.build/result-set'; | ||
|
||
const toSnap = <T extends Query<any>>(query: T): ResultSet<T, true> => { | ||
return undefined as any; | ||
}; | ||
|
||
/** @dts-jest enable:test-type */ | ||
|
||
const foo = defineTable({ | ||
id: uuid().primaryKey().default(`gen_random_uuid()`), | ||
createDate: timestampWithTimeZone().notNull().default(`now()`), | ||
name: text().notNull(), | ||
value: integer(), | ||
}); | ||
|
||
const db = defineDb({ foo }, () => Promise.resolve({ rows: [], affectedCount: 0 })); | ||
|
||
// @dts-jest:group truncate | ||
{ | ||
// @dts-jest:snap should truncate | ||
toSnap(db.truncate(db.foo)); | ||
|
||
db.truncate(db.foo).then((result) => { | ||
// @dts-jest:snap should truncate and await affected row count | ||
result; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { defineDb, defineTable, integer, text, timestampWithTimeZone, uuid } from '..'; | ||
|
||
import { toSnap } from './helpers'; | ||
|
||
describe(`truncate`, () => { | ||
const foo = defineTable({ | ||
id: uuid().primaryKey().default(`gen_random_uuid()`), | ||
createDate: timestampWithTimeZone().notNull().default(`now()`), | ||
name: text().notNull(), | ||
value: integer(), | ||
}); | ||
|
||
const bar = defineTable({ | ||
id: uuid().primaryKey().default(`gen_random_uuid()`), | ||
}); | ||
|
||
const baz = defineTable({ | ||
id: uuid().primaryKey().default(`gen_random_uuid()`), | ||
}); | ||
|
||
const db = defineDb( | ||
{ | ||
foo, | ||
bar, | ||
baz, | ||
}, | ||
() => Promise.resolve({ rows: [], affectedCount: 1 }), | ||
); | ||
|
||
it(`should truncate`, () => { | ||
const query = db.truncate(db.foo); | ||
|
||
expect(toSnap(query)).toMatchInlineSnapshot(` | ||
Object { | ||
"parameters": Array [], | ||
"text": "TRUNCATE foo", | ||
} | ||
`); | ||
}); | ||
|
||
it(`should restart identity`, () => { | ||
const query = db.truncate(db.foo).restartIdentity(); | ||
|
||
expect(toSnap(query)).toMatchInlineSnapshot(` | ||
Object { | ||
"parameters": Array [], | ||
"text": "TRUNCATE foo RESTART IDENTITY", | ||
} | ||
`); | ||
}); | ||
|
||
it(`should continue identity`, () => { | ||
const query = db.truncate(db.foo).continueIdentity(); | ||
|
||
expect(toSnap(query)).toMatchInlineSnapshot(` | ||
Object { | ||
"parameters": Array [], | ||
"text": "TRUNCATE foo CONTINUE IDENTITY", | ||
} | ||
`); | ||
}); | ||
|
||
it(`should cascade`, () => { | ||
const query = db.truncate(db.foo).cascade(); | ||
|
||
expect(toSnap(query)).toMatchInlineSnapshot(` | ||
Object { | ||
"parameters": Array [], | ||
"text": "TRUNCATE foo CASCADE", | ||
} | ||
`); | ||
}); | ||
|
||
it(`should restrict`, () => { | ||
const query = db.truncate(db.foo).restrict(); | ||
|
||
expect(toSnap(query)).toMatchInlineSnapshot(` | ||
Object { | ||
"parameters": Array [], | ||
"text": "TRUNCATE foo RESTRICT", | ||
} | ||
`); | ||
}); | ||
|
||
it(`should return affectedCount`, async () => { | ||
const affectedRows = await db.truncate(db.foo); | ||
expect(affectedRows).toBe(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { QueryExecutorFn, ResultType } from './types'; | ||
import { StringToken, Token, createQueryState } from './tokens'; | ||
|
||
import { Query } from './query'; | ||
import { Table } from './TableType'; | ||
import { TableDefinition } from './table'; | ||
|
||
export const makeTruncate = (queryExecutor: QueryExecutorFn) => <T extends Table<any, any>>( | ||
table: T, | ||
): T extends TableDefinition<any> ? never : TruncateQuery<T> => { | ||
return new TruncateQuery<T>(queryExecutor, table, 'AFFECTED_COUNT', [ | ||
new StringToken(`TRUNCATE`), | ||
new StringToken((table as Table<any, any>).getName()), | ||
]) as any; | ||
}; | ||
|
||
export class TruncateQuery< | ||
T extends Table<any, any>, | ||
Returning = number, | ||
TableColumns = T extends Table<any, infer Columns> ? Columns : never | ||
> extends Query<Returning> { | ||
constructor( | ||
private readonly queryExecutor: QueryExecutorFn, | ||
private readonly table: T, | ||
private readonly resultType: ResultType, | ||
private readonly tokens: Token[], | ||
) { | ||
super(); | ||
} | ||
|
||
then( | ||
onFulfilled?: ((value: number) => any | PromiseLike<any>) | undefined | null, | ||
onRejected?: ((reason: any) => void | PromiseLike<void>) | undefined | null, | ||
) { | ||
const queryState = createQueryState(this.tokens); | ||
|
||
return this.queryExecutor(queryState.text.join(` `), queryState.parameters) | ||
.then((result) => onFulfilled?.(result.affectedCount)) | ||
.catch(onRejected); | ||
} | ||
|
||
restartIdentity<T extends Table<any, any>>() { | ||
return this.newTruncateQuery([...this.tokens, new StringToken(`RESTART IDENTITY`)]) as any; | ||
} | ||
|
||
continueIdentity<T extends Table<any, any>>() { | ||
return this.newTruncateQuery([...this.tokens, new StringToken(`CONTINUE IDENTITY`)]) as any; | ||
} | ||
|
||
cascade<T extends Table<any, any>>() { | ||
return this.newTruncateQuery([...this.tokens, new StringToken('CASCADE')]); | ||
} | ||
|
||
restrict<T extends Table<any, any>>() { | ||
return this.newTruncateQuery([...this.tokens, new StringToken('RESTRICT')]); | ||
} | ||
|
||
private newTruncateQuery(tokens: Token[]): TruncateQuery<any> { | ||
return new TruncateQuery(this.queryExecutor, this.table, 'AFFECTED_COUNT', tokens); | ||
} | ||
|
||
getReturningKeys(): string[] { | ||
return []; | ||
} | ||
|
||
toTokens(): Token[] { | ||
return this.tokens; | ||
} | ||
} |