@proteinjs/db 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +21 -0
  3. package/dist/generated/index.d.ts +11 -0
  4. package/dist/generated/index.d.ts.map +1 -0
  5. package/dist/generated/index.js +59 -0
  6. package/dist/generated/index.js.map +1 -0
  7. package/dist/index.d.ts +21 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +37 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/src/Columns.d.ts +100 -0
  12. package/dist/src/Columns.d.ts.map +1 -0
  13. package/dist/src/Columns.js +381 -0
  14. package/dist/src/Columns.js.map +1 -0
  15. package/dist/src/Db.d.ts +46 -0
  16. package/dist/src/Db.d.ts.map +1 -0
  17. package/dist/src/Db.js +393 -0
  18. package/dist/src/Db.js.map +1 -0
  19. package/dist/src/MigrationRunner.d.ts +10 -0
  20. package/dist/src/MigrationRunner.d.ts.map +1 -0
  21. package/dist/src/MigrationRunner.js +124 -0
  22. package/dist/src/MigrationRunner.js.map +1 -0
  23. package/dist/src/QueryBuilderFactory.d.ts +8 -0
  24. package/dist/src/QueryBuilderFactory.d.ts.map +1 -0
  25. package/dist/src/QueryBuilderFactory.js +21 -0
  26. package/dist/src/QueryBuilderFactory.js.map +1 -0
  27. package/dist/src/Record.d.ts +38 -0
  28. package/dist/src/Record.d.ts.map +1 -0
  29. package/dist/src/Record.js +209 -0
  30. package/dist/src/Record.js.map +1 -0
  31. package/dist/src/RecordIterator.d.ts +13 -0
  32. package/dist/src/RecordIterator.d.ts.map +1 -0
  33. package/dist/src/RecordIterator.js +98 -0
  34. package/dist/src/RecordIterator.js.map +1 -0
  35. package/dist/src/StatementConfigFactory.d.ts +11 -0
  36. package/dist/src/StatementConfigFactory.d.ts.map +1 -0
  37. package/dist/src/StatementConfigFactory.js +31 -0
  38. package/dist/src/StatementConfigFactory.js.map +1 -0
  39. package/dist/src/Table.d.ts +98 -0
  40. package/dist/src/Table.d.ts.map +1 -0
  41. package/dist/src/Table.js +56 -0
  42. package/dist/src/Table.js.map +1 -0
  43. package/dist/src/auth/TableAuth.d.ts +29 -0
  44. package/dist/src/auth/TableAuth.d.ts.map +1 -0
  45. package/dist/src/auth/TableAuth.js +45 -0
  46. package/dist/src/auth/TableAuth.js.map +1 -0
  47. package/dist/src/auth/TableServiceAuth.d.ts +5 -0
  48. package/dist/src/auth/TableServiceAuth.d.ts.map +1 -0
  49. package/dist/src/auth/TableServiceAuth.js +37 -0
  50. package/dist/src/auth/TableServiceAuth.js.map +1 -0
  51. package/dist/src/opt/moment.d.ts +4 -0
  52. package/dist/src/opt/moment.d.ts.map +1 -0
  53. package/dist/src/opt/moment.js +9 -0
  54. package/dist/src/opt/moment.js.map +1 -0
  55. package/dist/src/reference/Reference.d.ts +26 -0
  56. package/dist/src/reference/Reference.d.ts.map +1 -0
  57. package/dist/src/reference/Reference.js +90 -0
  58. package/dist/src/reference/Reference.js.map +1 -0
  59. package/dist/src/reference/ReferenceArray.d.ts +29 -0
  60. package/dist/src/reference/ReferenceArray.d.ts.map +1 -0
  61. package/dist/src/reference/ReferenceArray.js +101 -0
  62. package/dist/src/reference/ReferenceArray.js.map +1 -0
  63. package/dist/src/schema/SchemaMetadata.d.ts +27 -0
  64. package/dist/src/schema/SchemaMetadata.d.ts.map +1 -0
  65. package/dist/src/schema/SchemaMetadata.js +227 -0
  66. package/dist/src/schema/SchemaMetadata.js.map +1 -0
  67. package/dist/src/schema/SchemaOperations.d.ts +40 -0
  68. package/dist/src/schema/SchemaOperations.d.ts.map +1 -0
  69. package/dist/src/schema/SchemaOperations.js +3 -0
  70. package/dist/src/schema/SchemaOperations.js.map +1 -0
  71. package/dist/src/schema/TableManager.d.ts +21 -0
  72. package/dist/src/schema/TableManager.d.ts.map +1 -0
  73. package/dist/src/schema/TableManager.js +254 -0
  74. package/dist/src/schema/TableManager.js.map +1 -0
  75. package/dist/src/serializers/GraphSerializer.d.ts +13 -0
  76. package/dist/src/serializers/GraphSerializer.d.ts.map +1 -0
  77. package/dist/src/serializers/GraphSerializer.js +21 -0
  78. package/dist/src/serializers/GraphSerializer.js.map +1 -0
  79. package/dist/src/serializers/QueryBuilderSerializer.d.ts +19 -0
  80. package/dist/src/serializers/QueryBuilderSerializer.d.ts.map +1 -0
  81. package/dist/src/serializers/QueryBuilderSerializer.js +32 -0
  82. package/dist/src/serializers/QueryBuilderSerializer.js.map +1 -0
  83. package/dist/src/serializers/ReferenceArraySerializer.d.ts +15 -0
  84. package/dist/src/serializers/ReferenceArraySerializer.d.ts.map +1 -0
  85. package/dist/src/serializers/ReferenceArraySerializer.js +23 -0
  86. package/dist/src/serializers/ReferenceArraySerializer.js.map +1 -0
  87. package/dist/src/serializers/ReferenceSerializer.d.ts +15 -0
  88. package/dist/src/serializers/ReferenceSerializer.d.ts.map +1 -0
  89. package/dist/src/serializers/ReferenceSerializer.js +23 -0
  90. package/dist/src/serializers/ReferenceSerializer.js.map +1 -0
  91. package/dist/src/serializers/TableSerializer.d.ts +13 -0
  92. package/dist/src/serializers/TableSerializer.d.ts.map +1 -0
  93. package/dist/src/serializers/TableSerializer.js +19 -0
  94. package/dist/src/serializers/TableSerializer.js.map +1 -0
  95. package/dist/src/services/DbService.d.ts +19 -0
  96. package/dist/src/services/DbService.d.ts.map +1 -0
  97. package/dist/src/services/DbService.js +6 -0
  98. package/dist/src/services/DbService.js.map +1 -0
  99. package/dist/src/services/MigrationRunnerService.d.ts +6 -0
  100. package/dist/src/services/MigrationRunnerService.d.ts.map +1 -0
  101. package/dist/src/services/MigrationRunnerService.js +6 -0
  102. package/dist/src/services/MigrationRunnerService.js.map +1 -0
  103. package/dist/src/source/SourceRecord.d.ts +44 -0
  104. package/dist/src/source/SourceRecord.d.ts.map +1 -0
  105. package/dist/src/source/SourceRecord.js +49 -0
  106. package/dist/src/source/SourceRecord.js.map +1 -0
  107. package/dist/src/source/SourceRecordLoader.d.ts +6 -0
  108. package/dist/src/source/SourceRecordLoader.d.ts.map +1 -0
  109. package/dist/src/source/SourceRecordLoader.js +156 -0
  110. package/dist/src/source/SourceRecordLoader.js.map +1 -0
  111. package/dist/src/source/SourceRecordRepo.d.ts +8 -0
  112. package/dist/src/source/SourceRecordRepo.d.ts.map +1 -0
  113. package/dist/src/source/SourceRecordRepo.js +20 -0
  114. package/dist/src/source/SourceRecordRepo.js.map +1 -0
  115. package/dist/src/tables/MigrationTable.d.ts +41 -0
  116. package/dist/src/tables/MigrationTable.d.ts.map +1 -0
  117. package/dist/src/tables/MigrationTable.js +86 -0
  118. package/dist/src/tables/MigrationTable.js.map +1 -0
  119. package/dist/src/tables/tables.d.ts +6 -0
  120. package/dist/src/tables/tables.d.ts.map +1 -0
  121. package/dist/src/tables/tables.js +8 -0
  122. package/dist/src/tables/tables.js.map +1 -0
  123. package/dist/test/CrudTests.d.ts +20 -0
  124. package/dist/test/CrudTests.d.ts.map +1 -0
  125. package/dist/test/CrudTests.js +251 -0
  126. package/dist/test/CrudTests.js.map +1 -0
  127. package/dist/test/TableManagerTests.d.ts +8 -0
  128. package/dist/test/TableManagerTests.d.ts.map +1 -0
  129. package/dist/test/TableManagerTests.js +687 -0
  130. package/dist/test/TableManagerTests.js.map +1 -0
  131. package/generated/index.ts +55 -0
  132. package/index.ts +25 -0
  133. package/jest.config.js +18 -0
  134. package/package.json +45 -0
  135. package/src/Columns.ts +257 -0
  136. package/src/Db.ts +195 -0
  137. package/src/MigrationRunner.ts +62 -0
  138. package/src/QueryBuilderFactory.ts +18 -0
  139. package/src/Record.ts +113 -0
  140. package/src/RecordIterator.ts +44 -0
  141. package/src/StatementConfigFactory.ts +36 -0
  142. package/src/Table.ts +124 -0
  143. package/src/auth/TableAuth.ts +60 -0
  144. package/src/auth/TableServiceAuth.ts +32 -0
  145. package/src/opt/moment.ts +4 -0
  146. package/src/reference/Reference.ts +45 -0
  147. package/src/reference/ReferenceArray.ts +56 -0
  148. package/src/schema/SchemaMetadata.ts +115 -0
  149. package/src/schema/SchemaOperations.ts +44 -0
  150. package/src/schema/TableManager.ts +198 -0
  151. package/src/serializers/GraphSerializer.ts +22 -0
  152. package/src/serializers/QueryBuilderSerializer.ts +39 -0
  153. package/src/serializers/ReferenceArraySerializer.ts +26 -0
  154. package/src/serializers/ReferenceSerializer.ts +26 -0
  155. package/src/serializers/TableSerializer.ts +20 -0
  156. package/src/services/DbService.ts +19 -0
  157. package/src/services/MigrationRunnerService.ts +7 -0
  158. package/src/source/SourceRecord.ts +75 -0
  159. package/src/source/SourceRecordLoader.ts +68 -0
  160. package/src/source/SourceRecordRepo.ts +17 -0
  161. package/src/tables/MigrationTable.ts +36 -0
  162. package/src/tables/tables.ts +6 -0
  163. package/test/CrudTests.ts +110 -0
  164. package/test/TableManagerTests.ts +382 -0
  165. package/tsconfig.json +23 -0
@@ -0,0 +1,75 @@
1
+ import { Loadable, SourceRepository } from '@proteinjs/reflection';
2
+ import { Columns, Table, getTables } from '../Table';
3
+ import { Record as DbRecord, withRecordColumns } from '../Record';
4
+ import { BooleanColumn } from '../Columns';
5
+
6
+ export const getSourceRecordLoaders = <T extends SourceRecord = SourceRecord>() => SourceRepository.get().objects<SourceRecordLoader<T>>('@proteinjs/db/SourceRecordLoader');
7
+
8
+ export function getSourceRecordTables() {
9
+ const tables = getTables();
10
+ const sourceRecordTables: Table<any>[] = [];
11
+ for (let table of tables) {
12
+ if (isSourceRecordTable(table))
13
+ sourceRecordTables.push(table);
14
+ }
15
+
16
+ return sourceRecordTables;
17
+ }
18
+
19
+ export function isSourceRecordTable(table: Table<any>) {
20
+ for (let columnPropertyName in table.columns) {
21
+ const column = table.columns[columnPropertyName];
22
+ if (column.name == getSourceRecordColumns().isLoadedFromSource.name)
23
+ return true;
24
+ }
25
+
26
+ return false;
27
+ }
28
+
29
+ export interface SourceRecord extends DbRecord {
30
+ isLoadedFromSource?: boolean;
31
+ }
32
+
33
+ const getSourceRecordColumns = (hideFromUi = true) => {
34
+ return {
35
+ isLoadedFromSource: new BooleanColumn('is_loaded_from_source', { ui: { hidden: hideFromUi } }),
36
+ };
37
+ }
38
+
39
+ /**
40
+ * Wrapper function to add default Record and SourceRecord columns to your table's columns.
41
+ *
42
+ * Note: using this requires an explicit dependency on moment@2.29.4 in your package (since transient dependencies are brittle by typescript's standards)
43
+ *
44
+ * @param columns your columns
45
+ * @param hideFromUi if true, source record columns are hidden from RecordTable and RecordForm
46
+ * @returns recordColumns & sourceRecordColumns & your columns
47
+ */
48
+ export function withSourceRecordColumns<T extends SourceRecord>(columns: Columns<Omit<T, keyof SourceRecord>>, hideFromUi?: boolean): Columns<SourceRecord> & Columns<Omit<T, keyof SourceRecord>> {
49
+ return Object.assign(Object.assign({}, getSourceRecordColumns(hideFromUi)), withRecordColumns<DbRecord>(columns) as any);
50
+ }
51
+
52
+ type InferRecordFromTable<T> = T extends Table<infer R> ? R : never;
53
+ type InferRecordWithoutTimestamps<T> = Omit<InferRecordFromTable<T>, 'created'|'updated'>;
54
+ type RequiredProperties<T> = Pick<T, {
55
+ [K in keyof T]: T extends Record<K, T[K]> ? K : never
56
+ }[keyof T]>;
57
+ type OptionalProperties<T> = Pick<T, {
58
+ [K in keyof T]: T extends Record<K, T[K]> ? never : K
59
+ }[keyof T]>;
60
+
61
+ /**
62
+ * Use this to load a record from source into the db.
63
+ *
64
+ * On Db.init, the record will be inserted if it doesn't exist, and updated if it does exist to mirror what is in source.
65
+ *
66
+ * If the SourceRecordLoader is deleted from source, the record will be deleted from the db on server startup. This will also be the behavior if id is changed - the record with the old id will be deleted.
67
+ */
68
+ export interface SourceRecordLoader<T extends SourceRecord> extends Loadable {
69
+ table: Table<T>,
70
+ record: {
71
+ [P in keyof RequiredProperties<InferRecordWithoutTimestamps<Table<T>>>]: RequiredProperties<InferRecordWithoutTimestamps<Table<T>>>[P];
72
+ } & {
73
+ [P in keyof OptionalProperties<InferRecordWithoutTimestamps<Table<T>>>]?: OptionalProperties<InferRecordWithoutTimestamps<Table<T>>>[P];
74
+ }
75
+ }
@@ -0,0 +1,68 @@
1
+ import { Logger } from '@proteinjs/util';
2
+ import { QueryBuilder } from '@proteinjs/db-query';
3
+ import { getSourceRecordLoaders, SourceRecord, getSourceRecordTables } from './SourceRecord';
4
+ import { Table } from '../Table';
5
+ import { getSystemDb } from '../Db';
6
+ import { SourceRecordRepo } from './SourceRecordRepo';
7
+
8
+ type SourceRecordsMap = {[tableName: string]: { table: Table<any>, records: Omit<SourceRecord, 'created'|'updated'>[], recordIds: string[] }}
9
+
10
+ export class SourceRecordLoader {
11
+ private logger = new Logger(this.constructor.name);
12
+
13
+ async load() {
14
+ const sourceRecordsMap = await this.getSourceRecordsMap();
15
+ const db = getSystemDb();
16
+ for (let tableName in sourceRecordsMap) {
17
+ let insertCount = 0;
18
+ let updateCount = 0;
19
+ let deleteCount = 0;
20
+ const table = sourceRecordsMap[tableName].table;
21
+ const sourceRecordIds = sourceRecordsMap[tableName].recordIds;
22
+ if (!table.sourceRecordOptions.doNotDeleteSourceRecordsFromDb) {
23
+ const qb = QueryBuilder.fromObject<SourceRecord>({ isLoadedFromSource: true }, table.name);
24
+ if (sourceRecordIds.length > 0)
25
+ qb.condition({ field: 'id', operator: 'NOT IN', value: sourceRecordIds });
26
+
27
+ deleteCount = await db.delete(table, qb);
28
+ }
29
+
30
+ const sourceRecords = sourceRecordsMap[tableName].records;
31
+ for (let sourceRecord of sourceRecords) {
32
+ sourceRecord.isLoadedFromSource = true;
33
+ const count = await db.update(table, sourceRecord);
34
+ if (count > 0) {
35
+ updateCount += count;
36
+ } else {
37
+ const dbSourceRecord = await db.insert(table, sourceRecord);
38
+ sourceRecord = { ...sourceRecord, ...dbSourceRecord };
39
+ insertCount += 1;
40
+ }
41
+
42
+ new SourceRecordRepo().loadSourceRecord(table.name, sourceRecord as any)
43
+ }
44
+
45
+ this.logger.info(`(${table.name}) Loaded ${sourceRecords.length} ${sourceRecords.length == 1 ? 'record' : 'records'} from source (inserts: ${insertCount}, updates: ${updateCount}, deletes: ${deleteCount})`);
46
+ }
47
+ }
48
+
49
+ private async getSourceRecordsMap() {
50
+ const sourceRecordsMap: SourceRecordsMap = {};
51
+ const sourceRecordTables = getSourceRecordTables();
52
+ for (let sourceRecordTable of sourceRecordTables) {
53
+ if (!sourceRecordsMap[sourceRecordTable.name])
54
+ sourceRecordsMap[sourceRecordTable.name] = { table: sourceRecordTable, records: [], recordIds: []};
55
+ }
56
+
57
+ const sourceRecordLoaders = getSourceRecordLoaders();
58
+ for (let sourceRecordLoader of sourceRecordLoaders) {
59
+ if (!sourceRecordsMap[sourceRecordLoader.table.name])
60
+ sourceRecordsMap[sourceRecordLoader.table.name] = { table: sourceRecordLoader.table, records: [], recordIds: []};
61
+
62
+ sourceRecordsMap[sourceRecordLoader.table.name].records.push(sourceRecordLoader.record);
63
+ sourceRecordsMap[sourceRecordLoader.table.name].recordIds.push(sourceRecordLoader.record.id);
64
+ }
65
+
66
+ return sourceRecordsMap;
67
+ }
68
+ }
@@ -0,0 +1,17 @@
1
+ import { SourceRecord } from './SourceRecord';
2
+
3
+ export class SourceRecordRepo {
4
+ private static SOURCE_RECORD_MAP: {[key: string]: SourceRecord} = {};
5
+
6
+ private getKey(tableName: string, recordId: string) {
7
+ return `${tableName}:${recordId}`;
8
+ }
9
+
10
+ loadSourceRecord(tableName: string, sourceRecord: SourceRecord): void {
11
+ SourceRecordRepo.SOURCE_RECORD_MAP[this.getKey(tableName, sourceRecord.id)] = sourceRecord;
12
+ }
13
+
14
+ getSourceRecord<T extends SourceRecord = SourceRecord>(tableName: string, sourceRecordId: string): T|undefined {
15
+ return SourceRecordRepo.SOURCE_RECORD_MAP[this.getKey(tableName, sourceRecordId)] as T;
16
+ }
17
+ }
@@ -0,0 +1,36 @@
1
+ import { Moment } from '../opt/moment';
2
+ import { DateTimeColumn, ObjectColumn, StringColumn } from '../Columns';
3
+ import { Table } from '../Table';
4
+ import { SourceRecord, withSourceRecordColumns } from '../source/SourceRecord';
5
+
6
+ export interface Migration extends SourceRecord {
7
+ description: string;
8
+ status?: 'proposed'|'running'|'success'|'failure';
9
+ failureMessage?: string;
10
+ failureStack?: string;
11
+ startTime?: Moment;
12
+ endTime?: Moment;
13
+ duration?: string;
14
+ output?: any;
15
+ run: () => Promise<any|void>;
16
+ }
17
+
18
+ export class MigrationTable extends Table<Migration> {
19
+ public name = 'migration';
20
+ public columns = withSourceRecordColumns<Migration>({
21
+ description: new StringColumn('description', {}, 4000),
22
+ status: new StringColumn('status', { defaultValue: async () => 'proposed' }),
23
+ failureMessage: new StringColumn('failure_message', {}, 4000),
24
+ failureStack: new StringColumn('failure_stack', {}, 'MAX'),
25
+ startTime: new DateTimeColumn('start_time'),
26
+ endTime: new DateTimeColumn('end_time'),
27
+ duration: new StringColumn('duration'),
28
+ output: new ObjectColumn('output'),
29
+ });
30
+ public sourceRecordOptions = {
31
+ doNotDeleteSourceRecordsFromDb: true,
32
+ ui: {
33
+ hideColumns: true,
34
+ },
35
+ };
36
+ }
@@ -0,0 +1,6 @@
1
+ import { Table } from '../Table';
2
+ import { Migration, MigrationTable } from './MigrationTable';
3
+
4
+ export const tables = {
5
+ Migration: new MigrationTable() as Table<Migration>,
6
+ }
@@ -0,0 +1,110 @@
1
+ import { QueryBuilder } from '@proteinjs/db-query';
2
+ import { DbDriver, Db } from '../src/Db';
3
+ import { withRecordColumns, Record } from '../src/Record';
4
+ import { StringColumn } from '../src/Columns';
5
+ import { Table } from '../src/Table';
6
+
7
+ export interface Employee extends Record {
8
+ name: string;
9
+ department?: string;
10
+ }
11
+
12
+ export class EmployeeTable extends Table<Employee> {
13
+ name = 'db_test_employee';
14
+ columns = withRecordColumns<Employee>({
15
+ name: new StringColumn('name'),
16
+ department: new StringColumn('department'),
17
+ });
18
+ }
19
+
20
+ export const crudTests = (
21
+ driver: DbDriver,
22
+ dropTable: (table: Table<any>) => Promise<void>,
23
+ ) => {
24
+ return () => {
25
+ const getTable = (tableName: string) => {
26
+ const employeeTable = new EmployeeTable();
27
+ if (employeeTable.name == tableName)
28
+ return employeeTable;
29
+
30
+ throw new Error('Cannot find test table');
31
+ };
32
+ const db = new Db(driver, getTable);
33
+
34
+ beforeAll(async () => {
35
+ if (driver.start)
36
+ await driver.start();
37
+
38
+ await driver.getTableManager().loadTable(new EmployeeTable());
39
+ })
40
+
41
+ afterAll(async () => {
42
+ await dropTable(new EmployeeTable());
43
+
44
+ if (driver.stop)
45
+ await driver.stop();
46
+ });
47
+
48
+ test('Insert', async () => {
49
+ const testEmployee: Omit<Employee, keyof Record> = { name: 'Veronica' };
50
+ const emplyeeTable: Table<Employee> = new EmployeeTable();
51
+ const insertedEmployee = await db.insert(emplyeeTable, testEmployee);
52
+ const fetchedEmployee = await db.get(emplyeeTable, { id: insertedEmployee.id });
53
+ expect(fetchedEmployee).toBeTruthy();
54
+ await db.delete(emplyeeTable, { id: fetchedEmployee.id });
55
+ });
56
+
57
+ test('Update', async () => {
58
+ const testEmployee: Omit<Employee, keyof Record> = { name: 'Veronica' };
59
+ const emplyeeTable: Table<Employee> = new EmployeeTable();
60
+ const insertedEmployee = await db.insert(emplyeeTable, testEmployee);
61
+ const updateCount = await db.update(emplyeeTable, { department: 'Cake Factory' }, { id: insertedEmployee.id });
62
+ expect(updateCount).toBe(1);
63
+ const fetchedEmployee = await db.get(emplyeeTable, { id: insertedEmployee.id });
64
+ expect(fetchedEmployee.department).toBe('Cake Factory');
65
+ await db.delete(emplyeeTable, { id: fetchedEmployee.id });
66
+ });
67
+
68
+ test('Delete', async () => {
69
+ const testEmployee: Omit<Employee, keyof Record> = { name: 'Veronica' };
70
+ const emplyeeTable: Table<Employee> = new EmployeeTable();
71
+ const insertedEmployee = await db.insert(emplyeeTable, testEmployee);
72
+ let fetchedEmployee = await db.get(emplyeeTable, { id: insertedEmployee.id });
73
+ expect(fetchedEmployee).toBeTruthy();
74
+ const deleteCount = await db.delete(emplyeeTable, { id: fetchedEmployee.id });
75
+ expect(deleteCount).toBe(1);
76
+ fetchedEmployee = await db.get(emplyeeTable, { id: insertedEmployee.id });
77
+ expect(fetchedEmployee).toBeFalsy();
78
+ });
79
+
80
+ test('Query', async () => {
81
+ const testEmployee1: Omit<Employee, keyof Record> = { name: 'Veronica', department: 'Cake Factory' };
82
+ const testEmployee2: Omit<Employee, keyof Record> = { name: 'Brent', department: 'Cake Factory' };
83
+ const testEmployee3: Omit<Employee, keyof Record> = { name: 'Sean', department: 'Pug Playhouse' };
84
+ const emplyeeTable: Table<Employee> = new EmployeeTable();
85
+ const fetchedEmployee1 = await db.insert(emplyeeTable, testEmployee1);
86
+ const fetchedEmployee2 = await db.insert(emplyeeTable, testEmployee2);
87
+ const fetchedEmployee3 = await db.insert(emplyeeTable, testEmployee3);
88
+ const fetchedEmployees = await db.query(emplyeeTable, { department: 'Cake Factory' });
89
+ expect(fetchedEmployees.length).toBe(2);
90
+ expect(fetchedEmployees[0].name).toBe('Veronica');
91
+ expect(fetchedEmployees[1].name).toBe('Brent');
92
+ const qb = new QueryBuilder<Employee>(emplyeeTable.name).condition({ field: 'id', operator: 'IN', value: [fetchedEmployee1.id, fetchedEmployee2.id, fetchedEmployee3.id] });
93
+ await db.delete(emplyeeTable, qb);
94
+ });
95
+
96
+ test('Get row count', async () => {
97
+ const testEmployee1: Omit<Employee, keyof Record> = { name: 'Veronica', department: 'Cake Factory' };
98
+ const testEmployee2: Omit<Employee, keyof Record> = { name: 'Brent', department: 'Cake Factory' };
99
+ const testEmployee3: Omit<Employee, keyof Record> = { name: 'Sean', department: 'Pug Playhouse' };
100
+ const emplyeeTable: Table<Employee> = new EmployeeTable();
101
+ const fetchedEmployee1 = await db.insert(emplyeeTable, testEmployee1);
102
+ const fetchedEmployee2 = await db.insert(emplyeeTable, testEmployee2);
103
+ const fetchedEmployee3 = await db.insert(emplyeeTable, testEmployee3);
104
+ const rowCount = await db.getRowCount(emplyeeTable, { department: 'Cake Factory' });
105
+ expect(rowCount).toBe(2);
106
+ const qb = new QueryBuilder<Employee>(emplyeeTable.name).condition({ field: 'id', operator: 'IN', value: [fetchedEmployee1.id, fetchedEmployee2.id, fetchedEmployee3.id] });
107
+ await db.delete(emplyeeTable, qb);
108
+ });
109
+ };
110
+ }