@proteinjs/db-driver-spanner 1.1.1 → 1.1.3

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 (40) hide show
  1. package/.eslintrc.js +20 -0
  2. package/.prettierignore +3 -0
  3. package/.prettierrc +8 -0
  4. package/CHANGELOG.md +14 -20
  5. package/LICENSE +21 -0
  6. package/README.md +29 -29
  7. package/dist/generated/index.js +1 -1
  8. package/dist/generated/index.js.map +1 -1
  9. package/dist/src/SpannerColumnTypeFactory.d.ts.map +1 -1
  10. package/dist/src/SpannerColumnTypeFactory.js +17 -9
  11. package/dist/src/SpannerColumnTypeFactory.js.map +1 -1
  12. package/dist/src/SpannerConfig.d.ts.map +1 -1
  13. package/dist/src/SpannerDriver.d.ts.map +1 -1
  14. package/dist/src/SpannerDriver.js +22 -9
  15. package/dist/src/SpannerDriver.js.map +1 -1
  16. package/dist/src/SpannerSchemaMetadata.d.ts.map +1 -1
  17. package/dist/src/SpannerSchemaMetadata.js +25 -14
  18. package/dist/src/SpannerSchemaMetadata.js.map +1 -1
  19. package/dist/src/SpannerSchemaOperations.d.ts.map +1 -1
  20. package/dist/src/SpannerSchemaOperations.js +5 -1
  21. package/dist/src/SpannerSchemaOperations.js.map +1 -1
  22. package/dist/test/Crud.test.js.map +1 -1
  23. package/dist/test/TableManager.test.js.map +1 -1
  24. package/dist/test/dropTable.d.ts.map +1 -1
  25. package/dist/test/dropTable.js +7 -2
  26. package/dist/test/dropTable.js.map +1 -1
  27. package/generated/index.ts +6 -9
  28. package/index.ts +1 -1
  29. package/jest.config.js +9 -18
  30. package/package.json +46 -40
  31. package/src/SpannerColumnTypeFactory.ts +23 -12
  32. package/src/SpannerConfig.ts +6 -6
  33. package/src/SpannerDriver.ts +125 -107
  34. package/src/SpannerSchemaMetadata.ts +74 -50
  35. package/src/SpannerSchemaOperations.ts +51 -26
  36. package/test/Crud.test.ts +7 -13
  37. package/test/TableManager.test.ts +12 -17
  38. package/test/dropTable.ts +16 -7
  39. package/test/setup.js +1 -1
  40. package/tsconfig.json +18 -22
@@ -8,111 +8,129 @@ import { SpannerColumnTypeFactory } from './SpannerColumnTypeFactory';
8
8
  import { SpannerSchemaMetadata } from './SpannerSchemaMetadata';
9
9
 
10
10
  export class SpannerDriver implements DbDriver {
11
- private static SPANNER: Spanner;
12
- private static SPANNER_INSTANCE: Instance;
13
- private static SPANNER_DB: Database;
14
- private logger = new Logger(this.constructor.name);
15
- private config: SpannerConfig;
16
-
17
- constructor(config: SpannerConfig) {
18
- this.config = config;
19
- }
20
-
21
- private getSpanner(): Spanner {
22
- if (!SpannerDriver.SPANNER) {
23
- if (this.config.spannerOptions)
24
- SpannerDriver.SPANNER = new Spanner(Object.assign({ projectId: this.config.projectId }, this.config.spannerOptions));
25
- else
26
- SpannerDriver.SPANNER = new Spanner({ projectId: this.config.projectId });
27
- }
28
-
29
- return SpannerDriver.SPANNER;
30
- }
31
-
32
- private getSpannerInstance(): Instance {
33
- if (!SpannerDriver.SPANNER_INSTANCE)
34
- SpannerDriver.SPANNER_INSTANCE = this.getSpanner().instance(this.config.instanceName);
35
-
36
- return SpannerDriver.SPANNER_INSTANCE;
37
- }
38
-
39
- private getSpannerDb(): Database {
40
- if (!SpannerDriver.SPANNER_DB)
41
- SpannerDriver.SPANNER_DB = this.getSpannerInstance().database(this.config.databaseName);
42
-
43
- return SpannerDriver.SPANNER_DB;
44
- }
45
-
46
- getDbName() {
47
- return this.config.databaseName;
48
- }
49
-
50
- getTableManager(): TableManager {
51
- const columnTypeFactory = new SpannerColumnTypeFactory();
52
- const schemaOperations = new SpannerSchemaOperations(this);
53
- const schemaMetadata = new SpannerSchemaMetadata(this, false);
54
- return new TableManager(this, columnTypeFactory, schemaOperations, schemaMetadata);
55
- }
56
-
57
- async createDbIfNotExists(): Promise<void> {
58
- if (await this.dbExists(this.getDbName()))
59
- return;
60
-
61
- await this.getSpannerInstance().createDatabase(this.getDbName());
62
- }
63
-
64
- private async dbExists(databaseName: string): Promise<boolean> {
65
- const [exists] = await this.getSpannerInstance().database(databaseName).exists();
66
- return exists;
67
- }
68
-
69
- async runQuery(generateStatement: (config: DbDriverStatementConfig) => Statement): Promise<any[]> {
70
- const { sql, namedParams } = generateStatement({ useParams: true, useNamedParams: true, prefixTablesWithDb: false });
71
- try {
72
- this.logger.debug(`Executing query: ${sql}`);
73
- const [rows] = await this.getSpannerDb().run({ sql, params: namedParams?.params });
74
- return rows.map(row => row.toJSON());
75
- // return JSON.parse(JSON.stringify((await this.getSpannerDb().run({ sql, params: namedParams?.params }))[0]));
76
- } catch(error: any) {
77
- this.logger.error(`Failed when executing query: ${sql}\nreason: ${error.details}`);
78
- throw error;
79
- }
80
- }
81
-
82
- /**
83
- * Execute a write operation.
84
- *
85
- * @returns number of affected rows
86
- */
87
- async runDml(generateStatement: (config: DbDriverStatementConfig) => Statement): Promise<number> {
88
- const { sql, namedParams } = generateStatement({ useParams: true, useNamedParams: true, prefixTablesWithDb: false });
89
- try {
90
- return await this.getSpannerDb().runTransactionAsync(async (transaction) => {
91
- this.logger.debug(`Executing dml: ${sql}`);
92
- const [rowCount] = await transaction.runUpdate({
93
- sql,
94
- params: namedParams?.params,
95
- });
96
- await transaction.commit();
97
- return rowCount;
98
- });
99
- } catch(error: any) {
100
- this.logger.error(`Failed when executing dml: ${sql}\nreason: ${error.details}`);
101
- throw error;
102
- }
103
- }
104
-
105
- /**
106
- * Execute a schema write operation.
107
- */
108
- async runUpdateSchema(sql: string): Promise<void> {
109
- try {
110
- this.logger.debug(`Executing schema update: ${sql}`)
111
- const [operation] = await this.getSpannerDb().updateSchema(sql);
11
+ private static SPANNER: Spanner;
12
+ private static SPANNER_INSTANCE: Instance;
13
+ private static SPANNER_DB: Database;
14
+ private logger = new Logger(this.constructor.name);
15
+ private config: SpannerConfig;
16
+
17
+ constructor(config: SpannerConfig) {
18
+ this.config = config;
19
+ }
20
+
21
+ private getSpanner(): Spanner {
22
+ if (!SpannerDriver.SPANNER) {
23
+ if (this.config.spannerOptions) {
24
+ SpannerDriver.SPANNER = new Spanner(
25
+ Object.assign({ projectId: this.config.projectId }, this.config.spannerOptions)
26
+ );
27
+ } else {
28
+ SpannerDriver.SPANNER = new Spanner({ projectId: this.config.projectId });
29
+ }
30
+ }
31
+
32
+ return SpannerDriver.SPANNER;
33
+ }
34
+
35
+ private getSpannerInstance(): Instance {
36
+ if (!SpannerDriver.SPANNER_INSTANCE) {
37
+ SpannerDriver.SPANNER_INSTANCE = this.getSpanner().instance(this.config.instanceName);
38
+ }
39
+
40
+ return SpannerDriver.SPANNER_INSTANCE;
41
+ }
42
+
43
+ private getSpannerDb(): Database {
44
+ if (!SpannerDriver.SPANNER_DB) {
45
+ SpannerDriver.SPANNER_DB = this.getSpannerInstance().database(this.config.databaseName);
46
+ }
47
+
48
+ return SpannerDriver.SPANNER_DB;
49
+ }
50
+
51
+ getDbName() {
52
+ return this.config.databaseName;
53
+ }
54
+
55
+ getTableManager(): TableManager {
56
+ const columnTypeFactory = new SpannerColumnTypeFactory();
57
+ const schemaOperations = new SpannerSchemaOperations(this);
58
+ const schemaMetadata = new SpannerSchemaMetadata(this, false);
59
+ return new TableManager(this, columnTypeFactory, schemaOperations, schemaMetadata);
60
+ }
61
+
62
+ async createDbIfNotExists(): Promise<void> {
63
+ if (await this.dbExists(this.getDbName())) {
64
+ return;
65
+ }
66
+
67
+ await this.getSpannerInstance().createDatabase(this.getDbName());
68
+ }
69
+
70
+ private async dbExists(databaseName: string): Promise<boolean> {
71
+ const [exists] = await this.getSpannerInstance().database(databaseName).exists();
72
+ return exists;
73
+ }
74
+
75
+ async runQuery(generateStatement: (config: DbDriverStatementConfig) => Statement): Promise<any[]> {
76
+ const { sql, namedParams } = generateStatement({
77
+ useParams: true,
78
+ useNamedParams: true,
79
+ prefixTablesWithDb: false,
80
+ });
81
+ try {
82
+ this.logger.debug(`Executing query: ${sql}`);
83
+ const [rows] = await this.getSpannerDb().run({ sql, params: namedParams?.params });
84
+ return rows.map((row) => row.toJSON());
85
+ // return JSON.parse(JSON.stringify((await this.getSpannerDb().run({ sql, params: namedParams?.params }))[0]));
86
+ } catch (error: any) {
87
+ this.logger.error(
88
+ `Failed when executing query: ${sql}\nparams: ${JSON.stringify(namedParams, null, 2)}\nreason: ${error.details}`
89
+ );
90
+ throw error;
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Execute a write operation.
96
+ *
97
+ * @returns number of affected rows
98
+ */
99
+ async runDml(generateStatement: (config: DbDriverStatementConfig) => Statement): Promise<number> {
100
+ const { sql, namedParams } = generateStatement({
101
+ useParams: true,
102
+ useNamedParams: true,
103
+ prefixTablesWithDb: false,
104
+ });
105
+ try {
106
+ return await this.getSpannerDb().runTransactionAsync(async (transaction) => {
107
+ this.logger.debug(`Executing dml: ${sql}`);
108
+ const [rowCount] = await transaction.runUpdate({
109
+ sql,
110
+ params: namedParams?.params,
111
+ });
112
+ await transaction.commit();
113
+ return rowCount;
114
+ });
115
+ } catch (error: any) {
116
+ this.logger.error(
117
+ `Failed when executing dml: ${sql}\nparams: ${JSON.stringify(namedParams, null, 2)}\nreason: ${error.details}`
118
+ );
119
+ throw error;
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Execute a schema write operation.
125
+ */
126
+ async runUpdateSchema(sql: string): Promise<void> {
127
+ try {
128
+ this.logger.debug(`Executing schema update: ${sql}`);
129
+ const [operation] = await this.getSpannerDb().updateSchema(sql);
112
130
  await operation.promise();
113
- } catch(error: any) {
114
- this.logger.error(`Failed when executing schema update: ${sql}\nreason: ${error.details}`);
115
- throw error;
116
- }
117
- }
118
- }
131
+ } catch (error: any) {
132
+ this.logger.error(`Failed when executing schema update: ${sql}\nreason: ${error.details}`);
133
+ throw error;
134
+ }
135
+ }
136
+ }
@@ -2,58 +2,80 @@ import { ParameterizationConfig, QueryBuilder, SchemaMetadata, Table } from '@pr
2
2
 
3
3
  export class SpannerSchemaMetadata extends SchemaMetadata {
4
4
  async tableExists(table: Table<any>): Promise<boolean> {
5
- const qb = new QueryBuilder('TABLES').condition({ field: 'TABLE_NAME', operator: '=', value: table.name });
6
- const generateStatement = (config: ParameterizationConfig) => qb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
7
- const results = await this.dbDriver.runQuery(generateStatement);
8
- return results.length > 0;
9
- }
10
-
11
- async getColumnMetadata(table: Table<any>): Promise<{[columnName: string]: { type: string, isNullable: boolean }}> {
12
- const qb = QueryBuilder.fromObject({
13
- 'TABLE_NAME': table.name
14
- }, 'COLUMNS');
5
+ const qb = new QueryBuilder('TABLES').condition({ field: 'TABLE_NAME', operator: '=', value: table.name });
15
6
  const generateStatement = (config: ParameterizationConfig) => qb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
16
- const results = await this.dbDriver.runQuery(generateStatement);
17
- const columnMetadata: {[columnName: string]: { type: string, isNullable: boolean }} = {};
18
- for (const row of results)
7
+ const results = await this.dbDriver.runQuery(generateStatement);
8
+ return results.length > 0;
9
+ }
10
+
11
+ async getColumnMetadata(table: Table<any>): Promise<{ [columnName: string]: { type: string; isNullable: boolean } }> {
12
+ const qb = QueryBuilder.fromObject(
13
+ {
14
+ TABLE_NAME: table.name,
15
+ },
16
+ 'COLUMNS'
17
+ );
18
+ const generateStatement = (config: ParameterizationConfig) => qb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
19
+ const results = await this.dbDriver.runQuery(generateStatement);
20
+ const columnMetadata: { [columnName: string]: { type: string; isNullable: boolean } } = {};
21
+ for (const row of results) {
19
22
  columnMetadata[row['COLUMN_NAME']] = { type: row['SPANNER_TYPE'], isNullable: row['IS_NULLABLE'] === 'YES' };
20
-
23
+ }
24
+
21
25
  return columnMetadata;
22
26
  }
23
27
 
24
28
  async getPrimaryKey(table: Table<any>): Promise<string[]> {
25
- const indexes = await this.getIndexes(table);
29
+ const indexes = await this.getIndexes(table);
26
30
  return indexes['PRIMARY_KEY'];
27
31
  }
28
32
 
29
- async getForeignKeys(table: Table<any>): Promise<{[columnName: string]: { referencedTableName: string, referencedColumnName: string }}> {
30
- const tableConstraintsQb = QueryBuilder.fromObject({
31
- 'TABLE_NAME': table.name,
32
- 'CONSTRAINT_TYPE': 'FOREIGN KEY'
33
- }, 'TABLE_CONSTRAINTS');
34
- const generateTableConstraintsStatement = (config: ParameterizationConfig) => tableConstraintsQb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
35
- const tableConstraints = await this.dbDriver.runQuery(generateTableConstraintsStatement);
36
- const foreignKeys: {[columnName: string]: { referencedTableName: string, referencedColumnName: string }} = {};
33
+ async getForeignKeys(
34
+ table: Table<any>
35
+ ): Promise<{ [columnName: string]: { referencedTableName: string; referencedColumnName: string } }> {
36
+ const tableConstraintsQb = QueryBuilder.fromObject(
37
+ {
38
+ TABLE_NAME: table.name,
39
+ CONSTRAINT_TYPE: 'FOREIGN KEY',
40
+ },
41
+ 'TABLE_CONSTRAINTS'
42
+ );
43
+ const generateTableConstraintsStatement = (config: ParameterizationConfig) =>
44
+ tableConstraintsQb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
45
+ const tableConstraints = await this.dbDriver.runQuery(generateTableConstraintsStatement);
46
+ const foreignKeys: { [columnName: string]: { referencedTableName: string; referencedColumnName: string } } = {};
37
47
  for (const tableConstraint of tableConstraints) {
38
- const referentialConstraintsQb = QueryBuilder.fromObject({
39
- 'CONSTRAINT_NAME': tableConstraint['CONSTRAINT_NAME']
40
- }, 'REFERENTIAL_CONSTRAINTS');
41
- const generateReferentialConstraintsStatement = (config: ParameterizationConfig) => referentialConstraintsQb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
48
+ const referentialConstraintsQb = QueryBuilder.fromObject(
49
+ {
50
+ CONSTRAINT_NAME: tableConstraint['CONSTRAINT_NAME'],
51
+ },
52
+ 'REFERENTIAL_CONSTRAINTS'
53
+ );
54
+ const generateReferentialConstraintsStatement = (config: ParameterizationConfig) =>
55
+ referentialConstraintsQb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
42
56
  const referentialConstraints = await this.dbDriver.runQuery(generateReferentialConstraintsStatement);
43
57
  const referencedTableConstraintName = referentialConstraints[0]['UNIQUE_CONSTRAINT_NAME'];
44
-
45
- const referenceTableConstraintsQb = QueryBuilder.fromObject({
46
- 'CONSTRAINT_NAME': referencedTableConstraintName
47
- }, 'TABLE_CONSTRAINTS');
48
- const generateReferenceTableConstraintsStatement = (config: ParameterizationConfig) => referenceTableConstraintsQb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
58
+
59
+ const referenceTableConstraintsQb = QueryBuilder.fromObject(
60
+ {
61
+ CONSTRAINT_NAME: referencedTableConstraintName,
62
+ },
63
+ 'TABLE_CONSTRAINTS'
64
+ );
65
+ const generateReferenceTableConstraintsStatement = (config: ParameterizationConfig) =>
66
+ referenceTableConstraintsQb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
49
67
  const referenceTableConstraints = await this.dbDriver.runQuery(generateReferenceTableConstraintsStatement);
50
68
  const referencedTableName = referenceTableConstraints[0]['TABLE_NAME'];
51
69
 
52
- const keyColumnUsageQb = QueryBuilder.fromObject({
53
- 'TABLE_NAME': table.name,
54
- 'CONSTRAINT_NAME': tableConstraint['CONSTRAINT_NAME']
55
- }, 'KEY_COLUMN_USAGE');
56
- const generateKeyColumnUsageStatement = (config: ParameterizationConfig) => keyColumnUsageQb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
70
+ const keyColumnUsageQb = QueryBuilder.fromObject(
71
+ {
72
+ TABLE_NAME: table.name,
73
+ CONSTRAINT_NAME: tableConstraint['CONSTRAINT_NAME'],
74
+ },
75
+ 'KEY_COLUMN_USAGE'
76
+ );
77
+ const generateKeyColumnUsageStatement = (config: ParameterizationConfig) =>
78
+ keyColumnUsageQb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
57
79
  const keyColumnUsages = await this.dbDriver.runQuery(generateKeyColumnUsageStatement);
58
80
  const referencingColumnName = keyColumnUsages[0]['COLUMN_NAME'];
59
81
 
@@ -62,7 +84,7 @@ export class SpannerSchemaMetadata extends SchemaMetadata {
62
84
  referencedColumnName: 'id',
63
85
  };
64
86
  }
65
-
87
+
66
88
  return foreignKeys;
67
89
  }
68
90
 
@@ -70,34 +92,36 @@ export class SpannerSchemaMetadata extends SchemaMetadata {
70
92
  const indexes = await this.getIndexes(table);
71
93
  const uniqueColumns: string[] = [];
72
94
  for (const indexName in indexes) {
73
- if (!indexName.endsWith('_unique'))
95
+ if (!indexName.endsWith('_unique')) {
74
96
  continue;
75
-
97
+ }
98
+
76
99
  const indexedColumns = indexes[indexName];
77
100
  uniqueColumns.push(...indexedColumns);
78
101
  }
79
-
102
+
80
103
  return uniqueColumns;
81
104
  }
82
105
 
83
- async getIndexes(table: Table<any>): Promise<{[keyName: string]: string[]}> {
106
+ async getIndexes(table: Table<any>): Promise<{ [keyName: string]: string[] }> {
84
107
  const qb = new QueryBuilder('INDEX_COLUMNS')
85
108
  .condition({ field: 'TABLE_NAME', operator: '=', value: table.name })
86
- .sort([{ field: 'ORDINAL_POSITION', desc: false }])
87
- ;
109
+ .sort([{ field: 'ORDINAL_POSITION', desc: false }]);
88
110
  const generateStatement = (config: ParameterizationConfig) => qb.toSql({ dbName: 'INFORMATION_SCHEMA', ...config });
89
- const results: any[] = await this.dbDriver.runQuery(generateStatement);
111
+ const results: any[] = await this.dbDriver.runQuery(generateStatement);
90
112
  const indexes: { [keyName: string]: string[] } = {};
91
113
  for (const row of results) {
92
- if (!row['INDEX_NAME'])
114
+ if (!row['INDEX_NAME']) {
93
115
  continue;
116
+ }
94
117
 
95
- if (!indexes[row['INDEX_NAME']])
118
+ if (!indexes[row['INDEX_NAME']]) {
96
119
  indexes[row['INDEX_NAME']] = [];
97
-
120
+ }
121
+
98
122
  indexes[row['INDEX_NAME']].push(row['COLUMN_NAME']);
99
123
  }
100
-
124
+
101
125
  return indexes;
102
126
  }
103
- }
127
+ }
@@ -1,33 +1,39 @@
1
1
  import { Logger } from '@proteinjs/util';
2
- import { Table, SchemaOperations, TableChanges, StatementFactory, AlterTableParams, StatementUtil, getColumnByName } from '@proteinjs/db';
2
+ import {
3
+ Table,
4
+ SchemaOperations,
5
+ TableChanges,
6
+ StatementFactory,
7
+ AlterTableParams,
8
+ StatementUtil,
9
+ getColumnByName,
10
+ } from '@proteinjs/db';
3
11
  import { SpannerDriver } from './SpannerDriver';
4
12
  import { SpannerColumnTypeFactory } from './SpannerColumnTypeFactory';
5
13
 
6
14
  export class SpannerSchemaOperations implements SchemaOperations {
7
15
  private logger = new Logger(this.constructor.name);
8
16
 
9
- constructor(
10
- private spannerDriver: SpannerDriver
11
- ){}
17
+ constructor(private spannerDriver: SpannerDriver) {}
12
18
 
13
19
  async createTable(table: Table<any>) {
14
- const indexes: { name?: string, columns: string|string[], unique?: boolean }[] = [];
15
- for (let index of table.indexes) {
20
+ const indexes: { name?: string; columns: string | string[]; unique?: boolean }[] = [];
21
+ for (const index of table.indexes) {
16
22
  indexes.push({ name: index.name, columns: index.columns as string[] });
17
23
  }
18
24
 
19
- const serializedColumns: { name: string, type: string, nullable?: boolean }[] = [];
20
- const foreignKeys: { table: string, column: string, referencedByColumn: string }[] = [];
25
+ const serializedColumns: { name: string; type: string; nullable?: boolean }[] = [];
26
+ const foreignKeys: { table: string; column: string; referencedByColumn: string }[] = [];
21
27
  for (const columnPropertyName in table.columns) {
22
28
  const column = table.columns[columnPropertyName];
23
29
  const columnType = new SpannerColumnTypeFactory().getType(column);
24
30
  serializedColumns.push({ name: column.name, type: columnType, nullable: column.options?.nullable });
25
- this.logger.info(`[${table.name}] Creating column: ${column.name} (${column.constructor.name})`)
31
+ this.logger.info(`[${table.name}] Creating column: ${column.name} (${column.constructor.name})`);
26
32
  if (column.options?.unique?.unique) {
27
33
  indexes.push({ name: column.options.unique.indexName, columns: column.name, unique: true });
28
34
  this.logger.info(`[${table.name}.${column.name}] Adding unique constraint`);
29
35
  }
30
-
36
+
31
37
  if (column.options?.references) {
32
38
  foreignKeys.push({ table: column.options.references.table, column: 'id', referencedByColumn: column.name });
33
39
  this.logger.info(`[${table.name}.${column.name}] Adding foreign key -> ${column.options.references.table}.id`);
@@ -36,12 +42,16 @@ export class SpannerSchemaOperations implements SchemaOperations {
36
42
  const createTableSql = new StatementFactory().createTable(table.name, serializedColumns, 'id', foreignKeys).sql;
37
43
  await this.spannerDriver.runUpdateSchema(createTableSql);
38
44
 
39
- for (let index of indexes) {
45
+ for (const index of indexes) {
40
46
  const createIndexSql = new StatementFactory().createIndex(index, table.name).sql;
41
47
  const indexName = StatementUtil.getIndexName(table.name, index);
42
- this.logger.info(`[${table.name}] Creating index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`);
48
+ this.logger.info(
49
+ `[${table.name}] Creating index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`
50
+ );
43
51
  await this.spannerDriver.runUpdateSchema(createIndexSql);
44
- this.logger.info(`[${table.name}] Created index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`);
52
+ this.logger.info(
53
+ `[${table.name}] Created index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`
54
+ );
45
55
  }
46
56
  }
47
57
 
@@ -55,7 +65,7 @@ export class SpannerSchemaOperations implements SchemaOperations {
55
65
  };
56
66
  const indexesToDrop = tableChanges.indexesToDrop;
57
67
  const indexesToAdd = tableChanges.indexesToCreate;
58
- for (const columnPropertyName of tableChanges.columnsToCreate) {
68
+ for (const columnPropertyName of tableChanges.columnsToCreate) {
59
69
  const column = table.columns[columnPropertyName];
60
70
  const columnType = new SpannerColumnTypeFactory().getType(column);
61
71
  alterParams.columnsToAdd?.push({ name: column.name, type: columnType, nullable: column.options?.nullable });
@@ -64,9 +74,13 @@ export class SpannerSchemaOperations implements SchemaOperations {
64
74
  indexesToAdd.push({ name: column.options.unique.indexName, columns: column.name, unique: true });
65
75
  this.logger.info(`[${table.name}.${column.name}] Adding unique constraint`);
66
76
  }
67
-
77
+
68
78
  if (column.options?.references && tableChanges.columnsWithForeignKeysToCreate.includes(column.name)) {
69
- alterParams.foreignKeysToAdd?.push({ table: column.options.references.table, column: 'id', referencedByColumn: column.name });
79
+ alterParams.foreignKeysToAdd?.push({
80
+ table: column.options.references.table,
81
+ column: 'id',
82
+ referencedByColumn: column.name,
83
+ });
70
84
  this.logger.info(`[${table.name}.${column.name}] Adding foreign key -> ${column.options.references.table}.id`);
71
85
  }
72
86
  }
@@ -78,7 +92,9 @@ export class SpannerSchemaOperations implements SchemaOperations {
78
92
 
79
93
  for (const foreignKey of tableChanges.foreignKeysToDrop) {
80
94
  alterParams.foreignKeysToDrop?.push(foreignKey);
81
- this.logger.info(`[${table.name}.${foreignKey.referencedByColumn}] Dropping foreign key -> ${foreignKey.table}.${foreignKey.column}`);
95
+ this.logger.info(
96
+ `[${table.name}.${foreignKey.referencedByColumn}] Dropping foreign key -> ${foreignKey.table}.${foreignKey.column}`
97
+ );
82
98
  }
83
99
 
84
100
  for (const columnTypeChange of tableChanges.columnTypeChanges) {
@@ -101,22 +117,31 @@ export class SpannerSchemaOperations implements SchemaOperations {
101
117
  }
102
118
 
103
119
  const alterStatements = new StatementFactory().alterTable(alterParams);
104
- for (let alterStatement of alterStatements)
120
+ for (const alterStatement of alterStatements) {
105
121
  await this.spannerDriver.runUpdateSchema(alterStatement.sql);
122
+ }
106
123
 
107
- for (let index of tableChanges.indexesToDrop) {
124
+ for (const index of tableChanges.indexesToDrop) {
108
125
  const dropIndexSql = new StatementFactory().dropIndex(index, table.name).sql;
109
- this.logger.info(`[${table.name}] Dropping index: ${index.name} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`);
126
+ this.logger.info(
127
+ `[${table.name}] Dropping index: ${index.name} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`
128
+ );
110
129
  await this.spannerDriver.runUpdateSchema(dropIndexSql);
111
- this.logger.info(`[${table.name}] Dropped index: ${index.name} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`);
130
+ this.logger.info(
131
+ `[${table.name}] Dropped index: ${index.name} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`
132
+ );
112
133
  }
113
134
 
114
- for (let index of tableChanges.indexesToCreate) {
135
+ for (const index of tableChanges.indexesToCreate) {
115
136
  const createIndexSql = new StatementFactory().createIndex(index, table.name).sql;
116
137
  const indexName = StatementUtil.getIndexName(table.name, index);
117
- this.logger.info(`[${table.name}] Creating index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`);
138
+ this.logger.info(
139
+ `[${table.name}] Creating index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`
140
+ );
118
141
  await this.spannerDriver.runUpdateSchema(createIndexSql);
119
- this.logger.info(`[${table.name}] Created index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`);
142
+ this.logger.info(
143
+ `[${table.name}] Created index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`
144
+ );
120
145
  }
121
- }
122
- }
146
+ }
147
+ }
package/test/Crud.test.ts CHANGED
@@ -1,17 +1,11 @@
1
- import { crudTests } from '@proteinjs/db'
2
- import { SpannerDriver } from '../src/SpannerDriver'
3
- import { getDropTable } from './dropTable'
1
+ import { crudTests } from '@proteinjs/db';
2
+ import { SpannerDriver } from '../src/SpannerDriver';
3
+ import { getDropTable } from './dropTable';
4
4
 
5
5
  const spannerDriver = new SpannerDriver({
6
- projectId: 'proteinjs-test',
7
- instanceName: 'proteinjs-test',
8
- databaseName: 'test',
6
+ projectId: 'proteinjs-test',
7
+ instanceName: 'proteinjs-test',
8
+ databaseName: 'test',
9
9
  });
10
10
 
11
- describe(
12
- 'CRUD Tests',
13
- crudTests(
14
- spannerDriver,
15
- getDropTable(spannerDriver)
16
- )
17
- );
11
+ describe('CRUD Tests', crudTests(spannerDriver, getDropTable(spannerDriver)));
@@ -1,24 +1,19 @@
1
- import { tableManagerTests } from '@proteinjs/db'
2
- import { SpannerDriver } from '../src/SpannerDriver'
1
+ import { tableManagerTests } from '@proteinjs/db';
2
+ import { SpannerDriver } from '../src/SpannerDriver';
3
3
  import { SpannerColumnTypeFactory } from '../src/SpannerColumnTypeFactory';
4
4
  import { getDropTable } from './dropTable';
5
5
 
6
6
  const spannerDriver = new SpannerDriver({
7
- projectId: 'proteinjs-test',
8
- instanceName: 'proteinjs-test',
9
- databaseName: 'test',
7
+ projectId: 'proteinjs-test',
8
+ instanceName: 'proteinjs-test',
9
+ databaseName: 'test',
10
10
  });
11
11
 
12
12
  describe(
13
- 'Table Manager Tests',
14
- tableManagerTests(
15
- spannerDriver,
16
- getDropTable(spannerDriver),
17
- new SpannerColumnTypeFactory().getType,
18
- {
19
- alterColumnName: true,
20
- alterColumnTypes: true,
21
- alterNullableConstraint: true,
22
- }
23
- )
24
- );
13
+ 'Table Manager Tests',
14
+ tableManagerTests(spannerDriver, getDropTable(spannerDriver), new SpannerColumnTypeFactory().getType, {
15
+ alterColumnName: true,
16
+ alterColumnTypes: true,
17
+ alterNullableConstraint: true,
18
+ })
19
+ );