@proteinjs/db-driver-spanner 1.18.0 → 1.20.0
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.
- package/CHANGELOG.md +34 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/test/index.js +1 -1
- package/dist/generated/test/index.js.map +1 -1
- package/dist/src/SpannerDriver.d.ts +52 -3
- package/dist/src/SpannerDriver.d.ts.map +1 -1
- package/dist/src/SpannerDriver.js +141 -33
- package/dist/src/SpannerDriver.js.map +1 -1
- package/dist/src/SpannerSchemaOperations.d.ts +9 -1
- package/dist/src/SpannerSchemaOperations.d.ts.map +1 -1
- package/dist/src/SpannerSchemaOperations.js +88 -124
- package/dist/src/SpannerSchemaOperations.js.map +1 -1
- package/dist/test/BatchedDdl.test.d.ts +2 -0
- package/dist/test/BatchedDdl.test.d.ts.map +1 -0
- package/dist/test/BatchedDdl.test.js +496 -0
- package/dist/test/BatchedDdl.test.js.map +1 -0
- package/dist/test/DmlRetrySafety.test.d.ts +2 -0
- package/dist/test/DmlRetrySafety.test.d.ts.map +1 -0
- package/dist/test/DmlRetrySafety.test.js +472 -0
- package/dist/test/DmlRetrySafety.test.js.map +1 -0
- package/dist/test/RecordIterator.test.d.ts +2 -0
- package/dist/test/RecordIterator.test.d.ts.map +1 -0
- package/dist/test/RecordIterator.test.js +14 -0
- package/dist/test/RecordIterator.test.js.map +1 -0
- package/dist/test/RunPendingMigrations.test.d.ts +2 -0
- package/dist/test/RunPendingMigrations.test.d.ts.map +1 -0
- package/dist/test/RunPendingMigrations.test.js +354 -0
- package/dist/test/RunPendingMigrations.test.js.map +1 -0
- package/dist/test/SpannerOperationDeadline.test.js +1 -1
- package/dist/test/SpannerOperationDeadline.test.js.map +1 -1
- package/generated/index.ts +1 -1
- package/generated/test/index.ts +1 -1
- package/package.json +6 -6
- package/src/SpannerDriver.ts +110 -18
- package/src/SpannerSchemaOperations.ts +69 -55
- package/test/BatchedDdl.test.ts +293 -0
- package/test/DmlRetrySafety.test.ts +305 -0
- package/test/RecordIterator.test.ts +16 -0
- package/test/RunPendingMigrations.test.ts +201 -0
- package/test/SpannerOperationDeadline.test.ts +1 -1
package/generated/test/index.ts
CHANGED
|
@@ -12,7 +12,7 @@ import '@proteinjs/util';
|
|
|
12
12
|
/** Generate Source Graph */
|
|
13
13
|
|
|
14
14
|
const sourceGraph =
|
|
15
|
-
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/db-driver-spanner/TestDbDriverFactory","value":{"packageName":"@proteinjs/db-driver-spanner","name":"TestDbDriverFactory","filePath":"/home/runner/work/db/db/packages/drivers/spanner/test/config/TestDbDriverFactory.ts","qualifiedName":"@proteinjs/db-driver-spanner/TestDbDriverFactory","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[{"name":"getDbDriver","returnType":{"packageName":"@proteinjs/db","name":"DbDriver","filePath":null,"qualifiedName":"@proteinjs/db/DbDriver","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/db","name":"DefaultDbDriverFactory","filePath":null,"qualifiedName":"@proteinjs/db/DefaultDbDriverFactory","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/db/DefaultDbDriverFactory"},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDoc","value":{"packageName":"@proteinjs/db-driver-spanner","name":"ServiceVerbsDoc","filePath":"/home/runner/work/db/db/packages/drivers/spanner/test/util/serviceUpdateVerbsTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/ServiceVerbsDoc","properties":[{"name":"title","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"scope","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"members","type":{"packageName":"","name":"ReferenceArray<ServiceVerbsDoc>","filePath":null,"qualifiedName":"/ReferenceArray<ServiceVerbsDoc>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"body","type":{"packageName":"@proteinjs/db-driver-spanner","name":"ServiceVerbsDocBody","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/ServiceVerbsDocBody","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[],"typeParameters":[],"directParents":[{"packageName":"@proteinjs/db","name":"Record","filePath":null,"qualifiedName":"@proteinjs/db/Record","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"sourceType":3}},{"v":"@proteinjs/db/Record"},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDocTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"ServiceVerbsDocTable","filePath":"/home/runner/work/db/db/packages/drivers/spanner/test/util/serviceUpdateVerbsTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/ServiceVerbsDocTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[{"packageName":"@proteinjs/db","name":"Table","filePath":null,"qualifiedName":"@proteinjs/db/Table","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[],"typeParameters":["@proteinjs/db-driver-spanner/ServiceVerbsDoc"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db/Table"},{"v":"@proteinjs/db-driver-spanner/SpannerDriver","value":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerDriver","filePath":"/home/runner/work/db/db/packages/drivers/spanner/src/SpannerDriver.ts","qualifiedName":"@proteinjs/db-driver-spanner/SpannerDriver","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"SPANNER","type":{"packageName":"@google-cloud/spanner","name":"Spanner","filePath":null,"qualifiedName":"@google-cloud/spanner/Spanner","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"SPANNER_INSTANCE","type":{"packageName":"@google-cloud/spanner","name":"Instance","filePath":null,"qualifiedName":"@google-cloud/spanner/Instance","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"SPANNER_DB","type":{"packageName":"@google-cloud/spanner","name":"Database","filePath":null,"qualifiedName":"@google-cloud/spanner/Database","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"LIVENESS_MONITOR","type":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerLivenessMonitor","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/SpannerLivenessMonitor","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"CLIENT_GENERATION","type":null,"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"CONSECUTIVE_DEADLINE_FAILURES","type":null,"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"logger","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"config","type":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerConfig","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/SpannerConfig","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"getTable","type":{"packageName":"","name":"((name: string) => Table<any>) | undefined","filePath":null,"qualifiedName":"/((name: string) => Table<any>) | undefined","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"getSessionPoolStats","returnType":{"packageName":"","name":"SpannerSessionPoolStats | undefined","filePath":null,"qualifiedName":"/SpannerSessionPoolStats | undefined","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"public","parameters":[]},{"name":"getSpanner","returnType":{"packageName":"@google-cloud/spanner","name":"Spanner","filePath":null,"qualifiedName":"@google-cloud/spanner/Spanner","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"getSpannerInstance","returnType":{"packageName":"@google-cloud/spanner","name":"Instance","filePath":null,"qualifiedName":"@google-cloud/spanner/Instance","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"getSpannerDb","returnType":{"packageName":"@google-cloud/spanner","name":"Database","filePath":null,"qualifiedName":"@google-cloud/spanner/Database","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"getDbName","returnType":null,"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"getTableManager","returnType":{"packageName":"@proteinjs/db","name":"TableManager","filePath":null,"qualifiedName":"@proteinjs/db/TableManager","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"getColumnType","returnType":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"tableName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"columnName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"handleCaseSensitivity","returnType":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"tableName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"columnName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"caseSensitive","type":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null}}]},{"name":"createDbIfNotExists","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"dbExists","returnType":{"packageName":"","name":"Promise<boolean>","filePath":null,"qualifiedName":"/Promise<boolean>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"databaseName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"runQuery","returnType":{"packageName":"","name":"Promise<any[]>","filePath":null,"qualifiedName":"/Promise<any[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"generateStatement","type":{"packageName":"","name":"(config: DbDriverQueryStatementConfig) => Statement","filePath":null,"qualifiedName":"/(config: DbDriverQueryStatementConfig) => Statement","typeParameters":null,"directParents":null}},{"name":"transaction","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"executeQuery","returnType":{"packageName":"","name":"Promise<any[]>","filePath":null,"qualifiedName":"/Promise<any[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"generateStatement","type":{"packageName":"","name":"(config: DbDriverQueryStatementConfig) => Statement","filePath":null,"qualifiedName":"/(config: DbDriverQueryStatementConfig) => Statement","typeParameters":null,"directParents":null}},{"name":"runner","type":{"packageName":"","name":"Database | Transaction","filePath":null,"qualifiedName":"/Database | Transaction","typeParameters":null,"directParents":null}}]},{"name":"runDml","returnType":{"packageName":"","name":"Promise<number>","filePath":null,"qualifiedName":"/Promise<number>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"generateStatement","type":{"packageName":"","name":"(config: DbDriverDmlStatementConfig) => Statement","filePath":null,"qualifiedName":"/(config: DbDriverDmlStatementConfig) => Statement","typeParameters":null,"directParents":null}},{"name":"transaction","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"executeDml","returnType":{"packageName":"","name":"Promise<number>","filePath":null,"qualifiedName":"/Promise<number>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"generateStatement","type":{"packageName":"","name":"(config: DbDriverDmlStatementConfig) => Statement","filePath":null,"qualifiedName":"/(config: DbDriverDmlStatementConfig) => Statement","typeParameters":null,"directParents":null}},{"name":"runner","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"runTransaction","returnType":{"packageName":"","name":"Promise<T>","filePath":null,"qualifiedName":"/Promise<T>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"fn","type":{"packageName":"","name":"(transaction: Transaction) => Promise<T>","filePath":null,"qualifiedName":"/(transaction: Transaction) => Promise<T>","typeParameters":null,"directParents":null}}]},{"name":"commit","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"transaction","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"rollbackQuietly","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"transaction","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"withDeadline","returnType":{"packageName":"","name":"Promise<T>","filePath":null,"qualifiedName":"/Promise<T>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"op","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"sql","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"promise","type":{"packageName":"","name":"PromiseLike<T>","filePath":null,"qualifiedName":"/PromiseLike<T>","typeParameters":null,"directParents":null}}]},{"name":"recordOpSuccess","returnType":{"packageName":"","name":"void","filePath":null,"qualifiedName":"/void","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"generation","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]},{"name":"recordDeadlineFailure","returnType":{"packageName":"","name":"void","filePath":null,"qualifiedName":"/void","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"generation","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]},{"name":"recycleClient","returnType":{"packageName":"","name":"void","filePath":null,"qualifiedName":"/void","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"operationDeadlineMs","returnType":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"deadlineFailuresBeforeRecycle","returnType":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"runUpdateSchema","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"sql","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/db","name":"DbDriver","filePath":null,"qualifiedName":"@proteinjs/db/DbDriver","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/db/DbDriver"},{"v":"@proteinjs/db-driver-spanner/SpannerSchemaMetadata","value":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerSchemaMetadata","filePath":"/home/runner/work/db/db/packages/drivers/spanner/src/SpannerSchemaMetadata.ts","qualifiedName":"@proteinjs/db-driver-spanner/SpannerSchemaMetadata","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[{"name":"tableExists","returnType":{"packageName":"","name":"Promise<boolean>","filePath":null,"qualifiedName":"/Promise<boolean>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getColumnMetadata","returnType":{"packageName":"","name":"Promise<{ [columnName: string]: { type: string; isNullable: boolean } }>","filePath":null,"qualifiedName":"/Promise<{ [columnName: string]: { type: string; isNullable: boolean } }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getPrimaryKey","returnType":{"packageName":"","name":"Promise<string[]>","filePath":null,"qualifiedName":"/Promise<string[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getForeignKeys","returnType":{"packageName":"","name":"Promise<{ [columnName: string]: { referencedTableName: string; referencedColumnName: string } }>","filePath":null,"qualifiedName":"/Promise<{ [columnName: string]: { referencedTableName: string; referencedColumnName: string } }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getUniqueColumns","returnType":{"packageName":"","name":"Promise<string[]>","filePath":null,"qualifiedName":"/Promise<string[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getIndexes","returnType":{"packageName":"","name":"Promise<{ [keyName: string]: string[] }>","filePath":null,"qualifiedName":"/Promise<{ [keyName: string]: string[] }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[{"packageName":"@proteinjs/db","name":"SchemaMetadata","filePath":null,"qualifiedName":"@proteinjs/db/SchemaMetadata","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db/SchemaMetadata"},{"v":"@proteinjs/db-driver-spanner/SpannerSchemaOperations","value":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerSchemaOperations","filePath":"/home/runner/work/db/db/packages/drivers/spanner/src/SpannerSchemaOperations.ts","qualifiedName":"@proteinjs/db-driver-spanner/SpannerSchemaOperations","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"logger","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"spannerDriver","type":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerDriver","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/SpannerDriver","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"createTable","returnType":null,"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"alterTable","returnType":null,"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}},{"name":"tableChanges","type":{"packageName":"@proteinjs/db","name":"TableChanges","filePath":null,"qualifiedName":"@proteinjs/db/TableChanges","typeParameters":null,"directParents":null}}]},{"name":"stringWideningStatement","returnType":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}},{"name":"change","type":{"packageName":"@proteinjs/db-driver-spanner","name":"{ name: string; newType: string; oldType: string }","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/{ name: string; newType: string; oldType: string }","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/db","name":"SchemaOperations","filePath":null,"qualifiedName":"@proteinjs/db/SchemaOperations","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/db/SchemaOperations"}],"edges":[{"v":"@proteinjs/db-driver-spanner/TestDbDriverFactory","w":"@proteinjs/db/DefaultDbDriverFactory","value":"implements interface"},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDoc","w":"@proteinjs/db/Record","value":"extends interface"},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDocTable","w":"@proteinjs/db/Table","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/SpannerDriver","w":"@proteinjs/db/DbDriver","value":"implements interface"},{"v":"@proteinjs/db-driver-spanner/SpannerSchemaMetadata","w":"@proteinjs/db/SchemaMetadata","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/SpannerSchemaOperations","w":"@proteinjs/db/SchemaOperations","value":"implements interface"}]}';
|
|
15
|
+
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/db-driver-spanner/TestDbDriverFactory","value":{"packageName":"@proteinjs/db-driver-spanner","name":"TestDbDriverFactory","filePath":"/home/runner/work/db/db/packages/drivers/spanner/test/config/TestDbDriverFactory.ts","qualifiedName":"@proteinjs/db-driver-spanner/TestDbDriverFactory","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[{"name":"getDbDriver","returnType":{"packageName":"@proteinjs/db","name":"DbDriver","filePath":null,"qualifiedName":"@proteinjs/db/DbDriver","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/db","name":"DefaultDbDriverFactory","filePath":null,"qualifiedName":"@proteinjs/db/DefaultDbDriverFactory","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/db/DefaultDbDriverFactory"},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDoc","value":{"packageName":"@proteinjs/db-driver-spanner","name":"ServiceVerbsDoc","filePath":"/home/runner/work/db/db/packages/drivers/spanner/test/util/serviceUpdateVerbsTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/ServiceVerbsDoc","properties":[{"name":"title","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"scope","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"members","type":{"packageName":"","name":"ReferenceArray<ServiceVerbsDoc>","filePath":null,"qualifiedName":"/ReferenceArray<ServiceVerbsDoc>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"body","type":{"packageName":"@proteinjs/db-driver-spanner","name":"ServiceVerbsDocBody","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/ServiceVerbsDocBody","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[],"typeParameters":[],"directParents":[{"packageName":"@proteinjs/db","name":"Record","filePath":null,"qualifiedName":"@proteinjs/db/Record","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"sourceType":3}},{"v":"@proteinjs/db/Record"},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDocTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"ServiceVerbsDocTable","filePath":"/home/runner/work/db/db/packages/drivers/spanner/test/util/serviceUpdateVerbsTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/ServiceVerbsDocTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[{"packageName":"@proteinjs/db","name":"Table","filePath":null,"qualifiedName":"@proteinjs/db/Table","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[],"typeParameters":["@proteinjs/db-driver-spanner/ServiceVerbsDoc"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db/Table"},{"v":"@proteinjs/db-driver-spanner/SpannerDriver","value":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerDriver","filePath":"/home/runner/work/db/db/packages/drivers/spanner/src/SpannerDriver.ts","qualifiedName":"@proteinjs/db-driver-spanner/SpannerDriver","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"SPANNER","type":{"packageName":"@google-cloud/spanner","name":"Spanner","filePath":null,"qualifiedName":"@google-cloud/spanner/Spanner","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"SPANNER_INSTANCE","type":{"packageName":"@google-cloud/spanner","name":"Instance","filePath":null,"qualifiedName":"@google-cloud/spanner/Instance","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"SPANNER_DB","type":{"packageName":"@google-cloud/spanner","name":"Database","filePath":null,"qualifiedName":"@google-cloud/spanner/Database","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"LIVENESS_MONITOR","type":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerLivenessMonitor","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/SpannerLivenessMonitor","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"CLIENT_GENERATION","type":null,"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"CONSECUTIVE_DEADLINE_FAILURES","type":null,"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"private"},{"name":"logger","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"config","type":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerConfig","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/SpannerConfig","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"getTable","type":{"packageName":"","name":"((name: string) => Table<any>) | undefined","filePath":null,"qualifiedName":"/((name: string) => Table<any>) | undefined","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"getSessionPoolStats","returnType":{"packageName":"","name":"SpannerSessionPoolStats | undefined","filePath":null,"qualifiedName":"/SpannerSessionPoolStats | undefined","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":true,"visibility":"public","parameters":[]},{"name":"getSpanner","returnType":{"packageName":"@google-cloud/spanner","name":"Spanner","filePath":null,"qualifiedName":"@google-cloud/spanner/Spanner","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"getSpannerInstance","returnType":{"packageName":"@google-cloud/spanner","name":"Instance","filePath":null,"qualifiedName":"@google-cloud/spanner/Instance","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"getSpannerDb","returnType":{"packageName":"@google-cloud/spanner","name":"Database","filePath":null,"qualifiedName":"@google-cloud/spanner/Database","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"getDbName","returnType":null,"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"getTableManager","returnType":{"packageName":"@proteinjs/db","name":"TableManager","filePath":null,"qualifiedName":"@proteinjs/db/TableManager","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"getColumnType","returnType":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"tableName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"columnName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"handleCaseSensitivity","returnType":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"tableName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"columnName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"caseSensitive","type":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null}}]},{"name":"createDbIfNotExists","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"createDb","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"name","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"options","type":{"packageName":"@proteinjs/db-driver-spanner","name":"{ ddl?: string[] }","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/{ ddl?: string[] }","typeParameters":null,"directParents":null}}]},{"name":"dropDb","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"name","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"dbExists","returnType":{"packageName":"","name":"Promise<boolean>","filePath":null,"qualifiedName":"/Promise<boolean>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"databaseName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"adminDbHandle","returnType":{"packageName":"@google-cloud/spanner","name":"Database","filePath":null,"qualifiedName":"@google-cloud/spanner/Database","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"name","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"runQuery","returnType":{"packageName":"","name":"Promise<any[]>","filePath":null,"qualifiedName":"/Promise<any[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"generateStatement","type":{"packageName":"","name":"(config: DbDriverQueryStatementConfig) => Statement","filePath":null,"qualifiedName":"/(config: DbDriverQueryStatementConfig) => Statement","typeParameters":null,"directParents":null}},{"name":"transaction","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"executeQuery","returnType":{"packageName":"","name":"Promise<any[]>","filePath":null,"qualifiedName":"/Promise<any[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"generateStatement","type":{"packageName":"","name":"(config: DbDriverQueryStatementConfig) => Statement","filePath":null,"qualifiedName":"/(config: DbDriverQueryStatementConfig) => Statement","typeParameters":null,"directParents":null}},{"name":"runner","type":{"packageName":"","name":"Database | Transaction","filePath":null,"qualifiedName":"/Database | Transaction","typeParameters":null,"directParents":null}}]},{"name":"runDml","returnType":{"packageName":"","name":"Promise<number>","filePath":null,"qualifiedName":"/Promise<number>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"generateStatement","type":{"packageName":"","name":"(config: DbDriverDmlStatementConfig) => Statement","filePath":null,"qualifiedName":"/(config: DbDriverDmlStatementConfig) => Statement","typeParameters":null,"directParents":null}},{"name":"transaction","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"executeDml","returnType":{"packageName":"","name":"Promise<number>","filePath":null,"qualifiedName":"/Promise<number>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"generateStatement","type":{"packageName":"","name":"(config: DbDriverDmlStatementConfig) => Statement","filePath":null,"qualifiedName":"/(config: DbDriverDmlStatementConfig) => Statement","typeParameters":null,"directParents":null}},{"name":"runner","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"runTransaction","returnType":{"packageName":"","name":"Promise<T>","filePath":null,"qualifiedName":"/Promise<T>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"fn","type":{"packageName":"","name":"(transaction: Transaction) => Promise<T>","filePath":null,"qualifiedName":"/(transaction: Transaction) => Promise<T>","typeParameters":null,"directParents":null}}]},{"name":"commit","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"transaction","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"rollbackQuietly","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"transaction","type":{"packageName":"@google-cloud/spanner","name":"Transaction","filePath":null,"qualifiedName":"@google-cloud/spanner/Transaction","typeParameters":null,"directParents":null}}]},{"name":"withDeadline","returnType":{"packageName":"","name":"Promise<T>","filePath":null,"qualifiedName":"/Promise<T>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"op","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"sql","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"promise","type":{"packageName":"","name":"PromiseLike<T>","filePath":null,"qualifiedName":"/PromiseLike<T>","typeParameters":null,"directParents":null}}]},{"name":"recordOpSuccess","returnType":{"packageName":"","name":"void","filePath":null,"qualifiedName":"/void","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"generation","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]},{"name":"recordDeadlineFailure","returnType":{"packageName":"","name":"void","filePath":null,"qualifiedName":"/void","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"generation","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]},{"name":"recycleClient","returnType":{"packageName":"","name":"void","filePath":null,"qualifiedName":"/void","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"dmlGaxOptions","returnType":{"packageName":"@proteinjs/db-driver-spanner","name":"{ timeout: number; retry?: null }","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/{ timeout: number; retry?: null }","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"operationDeadlineMs","returnType":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"deadlineFailuresBeforeRecycle","returnType":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"runUpdateSchema","returnType":{"packageName":"","name":"Promise<void>","filePath":null,"qualifiedName":"/Promise<void>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"statements","type":{"packageName":"","name":"string | string[]","filePath":null,"qualifiedName":"/string | string[]","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/db","name":"DbDriver","filePath":null,"qualifiedName":"@proteinjs/db/DbDriver","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/db/DbDriver"},{"v":"@proteinjs/db-driver-spanner/SpannerSchemaMetadata","value":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerSchemaMetadata","filePath":"/home/runner/work/db/db/packages/drivers/spanner/src/SpannerSchemaMetadata.ts","qualifiedName":"@proteinjs/db-driver-spanner/SpannerSchemaMetadata","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[{"name":"tableExists","returnType":{"packageName":"","name":"Promise<boolean>","filePath":null,"qualifiedName":"/Promise<boolean>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getColumnMetadata","returnType":{"packageName":"","name":"Promise<{ [columnName: string]: { type: string; isNullable: boolean } }>","filePath":null,"qualifiedName":"/Promise<{ [columnName: string]: { type: string; isNullable: boolean } }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getPrimaryKey","returnType":{"packageName":"","name":"Promise<string[]>","filePath":null,"qualifiedName":"/Promise<string[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getForeignKeys","returnType":{"packageName":"","name":"Promise<{ [columnName: string]: { referencedTableName: string; referencedColumnName: string } }>","filePath":null,"qualifiedName":"/Promise<{ [columnName: string]: { referencedTableName: string; referencedColumnName: string } }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getUniqueColumns","returnType":{"packageName":"","name":"Promise<string[]>","filePath":null,"qualifiedName":"/Promise<string[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"getIndexes","returnType":{"packageName":"","name":"Promise<{ [keyName: string]: string[] }>","filePath":null,"qualifiedName":"/Promise<{ [keyName: string]: string[] }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[{"packageName":"@proteinjs/db","name":"SchemaMetadata","filePath":null,"qualifiedName":"@proteinjs/db/SchemaMetadata","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db/SchemaMetadata"},{"v":"@proteinjs/db-driver-spanner/SpannerSchemaOperations","value":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerSchemaOperations","filePath":"/home/runner/work/db/db/packages/drivers/spanner/src/SpannerSchemaOperations.ts","qualifiedName":"@proteinjs/db-driver-spanner/SpannerSchemaOperations","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"logger","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"spannerDriver","type":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerDriver","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/SpannerDriver","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"createTables","returnType":null,"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"tables","type":{"packageName":"","name":"Table<any>[]","filePath":null,"qualifiedName":"/Table<any>[]","typeParameters":null,"directParents":null}}]},{"name":"alterTable","returnType":null,"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}},{"name":"tableChanges","type":{"packageName":"@proteinjs/db","name":"TableChanges","filePath":null,"qualifiedName":"@proteinjs/db/TableChanges","typeParameters":null,"directParents":null}}]},{"name":"createTableStatements","returnType":{"packageName":"","name":"string[]","filePath":null,"qualifiedName":"/string[]","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}}]},{"name":"stringWideningStatement","returnType":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null}},{"name":"change","type":{"packageName":"@proteinjs/db-driver-spanner","name":"{ name: string; newType: string; oldType: string }","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/{ name: string; newType: string; oldType: string }","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/db","name":"SchemaOperations","filePath":null,"qualifiedName":"@proteinjs/db/SchemaOperations","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/db/SchemaOperations"}],"edges":[{"v":"@proteinjs/db-driver-spanner/TestDbDriverFactory","w":"@proteinjs/db/DefaultDbDriverFactory","value":"implements interface"},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDoc","w":"@proteinjs/db/Record","value":"extends interface"},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDocTable","w":"@proteinjs/db/Table","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/SpannerDriver","w":"@proteinjs/db/DbDriver","value":"implements interface"},{"v":"@proteinjs/db-driver-spanner/SpannerSchemaMetadata","w":"@proteinjs/db/SchemaMetadata","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/SpannerSchemaOperations","w":"@proteinjs/db/SchemaOperations","value":"implements interface"}]}';
|
|
16
16
|
|
|
17
17
|
/** Generate Source Links */
|
|
18
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/db-driver-spanner",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
4
4
|
"main": "./dist/generated/index.js",
|
|
5
5
|
"types": "./dist/generated/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@google-cloud/spanner": "7.5.0",
|
|
45
|
-
"@proteinjs/db": "^1.
|
|
46
|
-
"@proteinjs/db-query": "^1.
|
|
47
|
-
"@proteinjs/db-spanner-common": "^1.3.
|
|
48
|
-
"@proteinjs/db-transaction-context": "^0.5.
|
|
45
|
+
"@proteinjs/db": "^1.32.0",
|
|
46
|
+
"@proteinjs/db-query": "^1.7.0",
|
|
47
|
+
"@proteinjs/db-spanner-common": "^1.3.8",
|
|
48
|
+
"@proteinjs/db-transaction-context": "^0.5.8",
|
|
49
49
|
"@proteinjs/logger": "^1.0.21",
|
|
50
50
|
"@proteinjs/reflection": "^1.1.12",
|
|
51
51
|
"@proteinjs/util": "^1.6.1"
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"ts-jest": "29.1.1",
|
|
64
64
|
"typescript": "5.2.2"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "edfed2d7826c7e42ddc0ae84bf97cda11614c1f0"
|
|
67
67
|
}
|
package/src/SpannerDriver.ts
CHANGED
|
@@ -167,12 +167,54 @@ export class SpannerDriver implements DbDriver {
|
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
await this.
|
|
170
|
+
await this.createDb(this.getDbName());
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Create the named database in one operation. `ddl` statements ride the create as
|
|
175
|
+
* `CreateDatabase.extra_statements` — applied in order, atomically with the creation (if any
|
|
176
|
+
* statement fails, the database is not created) — so a database can be born with its full
|
|
177
|
+
* schema without a second schema-update operation.
|
|
178
|
+
*/
|
|
179
|
+
async createDb(name: string, options?: { ddl?: string[] }): Promise<void> {
|
|
180
|
+
const [database, operation] = await this.getSpannerInstance().createDatabase(name, {
|
|
181
|
+
extraStatements: options?.ddl ?? [],
|
|
182
|
+
// Admin-handle hygiene (see adminDbHandle): the client constructs the returned handle
|
|
183
|
+
// BEFORE the create operation completes — a default eager pool races the operation and
|
|
184
|
+
// crashes on NOT_FOUND.
|
|
185
|
+
poolOptions: { min: 0 },
|
|
186
|
+
});
|
|
187
|
+
database.on('error', () => undefined);
|
|
188
|
+
await operation.promise();
|
|
189
|
+
await database.close().catch(() => undefined);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Drop the named database (client `Database.delete()` — closes the handle, then drops). */
|
|
193
|
+
async dropDb(name: string): Promise<void> {
|
|
194
|
+
await this.adminDbHandle(name).delete();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async dbExists(databaseName: string): Promise<boolean> {
|
|
198
|
+
const database = this.adminDbHandle(databaseName);
|
|
199
|
+
try {
|
|
200
|
+
const [exists] = await database.exists();
|
|
201
|
+
return exists;
|
|
202
|
+
} finally {
|
|
203
|
+
await database.close().catch(() => undefined);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* A Database handle for admin operations (exists/drop): admin RPCs ride the admin client, not
|
|
209
|
+
* sessions, so the pool is configured to hold ZERO sessions — the default pool eagerly fills
|
|
210
|
+
* in the handle's constructor and emits process-crashing unlistened 'error' events when the
|
|
211
|
+
* database does not exist, which is the NORMAL case for these operations. Its error channel is
|
|
212
|
+
* owned for the same reason.
|
|
213
|
+
*/
|
|
214
|
+
private adminDbHandle(name: string): Database {
|
|
215
|
+
const database = this.getSpannerInstance().database(name, { min: 0 });
|
|
216
|
+
database.on('error', () => undefined);
|
|
217
|
+
return database;
|
|
176
218
|
}
|
|
177
219
|
|
|
178
220
|
/**
|
|
@@ -280,18 +322,25 @@ export class SpannerDriver implements DbDriver {
|
|
|
280
322
|
|
|
281
323
|
try {
|
|
282
324
|
this.logger.debug({ message: `Executing dml`, obj: { sql, params: namedParams } });
|
|
283
|
-
|
|
325
|
+
// DML rides the unary ExecuteBatchDml RPC (`batchUpdate`), never streaming `runUpdate`
|
|
326
|
+
// (ExecuteStreamingSql). The client's streaming transport TRANSPARENTLY RE-SENDS a DML
|
|
327
|
+
// whose response was lost: gax wraps every server-streaming call in retry-request, which
|
|
328
|
+
// silently replays on ANY pre-response error. Seqno replay protection only covers the
|
|
329
|
+
// same-transaction geometry; the geometries it cannot cover are where the 2026-08-13
|
|
330
|
+
// splice incident lived — an inline-begin replay BEGINS A FRESH TRANSACTION per attempt
|
|
331
|
+
// (abandoned applied-but-uncommitted siblings churn locks and collide with rows committed
|
|
332
|
+
// by other paths: spurious `6 ALREADY_EXISTS` under pool pressure), and the stream-
|
|
333
|
+
// resumption layer re-mints a NEW seqno into the SAME transaction after inline-begin
|
|
334
|
+
// learned its id (unprotected even on real Spanner). The unary RPC has none of that
|
|
335
|
+
// machinery — see dmlGaxOptions() for the per-backend retry policy on it.
|
|
336
|
+
const [rowCounts] = await this.withDeadline(
|
|
284
337
|
'spanner dml',
|
|
285
338
|
sql,
|
|
286
|
-
runner.
|
|
287
|
-
|
|
288
|
-
params: namedParams?.params,
|
|
289
|
-
types: namedParams?.types,
|
|
290
|
-
// gRPC deadline: cancels the RPC on a dead channel so the transaction's run function
|
|
291
|
-
// settles and the library releases the session (see runDml).
|
|
292
|
-
gaxOptions: { timeout: this.operationDeadlineMs() },
|
|
339
|
+
runner.batchUpdate([{ sql, params: namedParams?.params, types: namedParams?.types }], {
|
|
340
|
+
gaxOptions: this.dmlGaxOptions(),
|
|
293
341
|
})
|
|
294
342
|
);
|
|
343
|
+
const rowCount = rowCounts[0] ?? 0;
|
|
295
344
|
const durationMs = Number(process.hrtime.bigint() - startTime) / 1_000_000;
|
|
296
345
|
this.logger.debug({
|
|
297
346
|
message: `Dml executed`,
|
|
@@ -512,6 +561,29 @@ export class SpannerDriver implements DbDriver {
|
|
|
512
561
|
}
|
|
513
562
|
}
|
|
514
563
|
|
|
564
|
+
/**
|
|
565
|
+
* Per-call gax options for the DML RPC (ExecuteBatchDml). The gRPC deadline (see runDml)
|
|
566
|
+
* applies everywhere. The transparent-retry policy differs by backend:
|
|
567
|
+
*
|
|
568
|
+
* - Real Spanner: gax's default unary policy (UNAVAILABLE only) stands. A replay re-sends the
|
|
569
|
+
* identical request — same seqno, deduped in the same-transaction geometry — and in the
|
|
570
|
+
* inline-begin geometry only the transaction the client ultimately commits applies durably,
|
|
571
|
+
* so the transient-blip resilience is safe there.
|
|
572
|
+
* - Emulator (SPANNER_EMULATOR_HOST — the same switch the client library keys on): a replayed
|
|
573
|
+
* inline-begin DML begins a fresh transaction per attempt, and the abandoned
|
|
574
|
+
* applied-but-uncommitted siblings are exactly what fed the splice incident's spurious
|
|
575
|
+
* failures under pool pressure. `retry: null` makes the call single-attempt: a lost response
|
|
576
|
+
* surfaces as the loss to the caller, deterministically, instead of invisible multi-
|
|
577
|
+
* transaction churn. Loopback needs no blip resilience.
|
|
578
|
+
*/
|
|
579
|
+
private dmlGaxOptions(): { timeout: number; retry?: null } {
|
|
580
|
+
const gaxOptions: { timeout: number; retry?: null } = { timeout: this.operationDeadlineMs() };
|
|
581
|
+
if (process.env.SPANNER_EMULATOR_HOST) {
|
|
582
|
+
gaxOptions.retry = null;
|
|
583
|
+
}
|
|
584
|
+
return gaxOptions;
|
|
585
|
+
}
|
|
586
|
+
|
|
515
587
|
private operationDeadlineMs(): number {
|
|
516
588
|
return this.config.operationDeadlineMs ?? 60_000;
|
|
517
589
|
}
|
|
@@ -521,21 +593,41 @@ export class SpannerDriver implements DbDriver {
|
|
|
521
593
|
}
|
|
522
594
|
|
|
523
595
|
/**
|
|
524
|
-
* Execute a schema write operation
|
|
596
|
+
* Execute a schema write operation — one long-running operation for the WHOLE statement list
|
|
597
|
+
* (`UpdateDatabaseDdl` applies the statements in order). Sequential per-statement operations
|
|
598
|
+
* are what made a 37-statement prod boot take 10m31s; callers batch and pass the list.
|
|
599
|
+
*
|
|
600
|
+
* Partial-failure semantics (verified against the emulator; matches Spanner's documented
|
|
601
|
+
* batch-DDL behavior — both phases are covered in BatchedDdl.test.ts):
|
|
602
|
+
* - VALIDATION failure (schema-shape errors, checked upfront for the whole batch, in order,
|
|
603
|
+
* against the projected schema): the batch is rejected before anything applies — NOTHING
|
|
604
|
+
* lands. Strictly safer than the old serial path, which stranded the earlier statements.
|
|
605
|
+
* - APPLY failure (data-dependent errors, e.g. a unique-index backfill over duplicate rows):
|
|
606
|
+
* statements BEFORE the failing one stay applied; the failing one and everything after are
|
|
607
|
+
* cancelled — the serial path's semantics.
|
|
608
|
+
* Neither phase reports a positional statement index: the backend error names the offending
|
|
609
|
+
* OBJECT (table/index/column). The failure log below carries the full statement list plus
|
|
610
|
+
* that reason, which together locate the statement.
|
|
525
611
|
*/
|
|
526
|
-
async runUpdateSchema(
|
|
612
|
+
async runUpdateSchema(statements: string | string[]): Promise<void> {
|
|
613
|
+
const statementList = Array.isArray(statements) ? statements : [statements];
|
|
527
614
|
const startTime = process.hrtime.bigint();
|
|
528
615
|
try {
|
|
529
|
-
this.logger.debug({ message: `Executing schema update`, obj: {
|
|
530
|
-
const [operation] = await this.getSpannerDb().updateSchema(
|
|
616
|
+
this.logger.debug({ message: `Executing schema update`, obj: { statements: statementList } });
|
|
617
|
+
const [operation] = await this.getSpannerDb().updateSchema(statementList);
|
|
531
618
|
await operation.promise();
|
|
532
619
|
const durationMs = Number(process.hrtime.bigint() - startTime) / 1_000_000;
|
|
533
|
-
this.logger.debug({
|
|
620
|
+
this.logger.debug({
|
|
621
|
+
message: `Schema update executed`,
|
|
622
|
+
obj: { statementCount: statementList.length, durationMs },
|
|
623
|
+
});
|
|
534
624
|
} catch (error: any) {
|
|
535
625
|
const durationMs = Number(process.hrtime.bigint() - startTime) / 1_000_000;
|
|
536
626
|
this.logger.error({
|
|
537
627
|
message: `Failed when executing schema update`,
|
|
538
|
-
|
|
628
|
+
// Apply-phase LRO failures carry their reason only in `message` (`details` is
|
|
629
|
+
// undefined there); validation-phase gRPC errors carry both.
|
|
630
|
+
obj: { statements: statementList, errorDetails: error.details ?? String(error), durationMs },
|
|
539
631
|
});
|
|
540
632
|
throw error;
|
|
541
633
|
}
|
|
@@ -18,49 +18,24 @@ export class SpannerSchemaOperations implements SchemaOperations {
|
|
|
18
18
|
|
|
19
19
|
constructor(private spannerDriver: SpannerDriver) {}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Create every table in `tables` — each table's `CREATE TABLE` plus all of its `CREATE INDEX`
|
|
23
|
+
* statements, concatenated across tables in the given order — as ONE schema-update operation.
|
|
24
|
+
* `UpdateDatabaseDdl` applies the batch in order, so a table whose foreign keys reference an
|
|
25
|
+
* earlier table in the list resolves against it, exactly as it did when the statements ran
|
|
26
|
+
* serially.
|
|
27
|
+
*/
|
|
28
|
+
async createTables(tables: Table<any>[]) {
|
|
29
|
+
const statements: string[] = [];
|
|
30
|
+
for (const table of tables) {
|
|
31
|
+
statements.push(...this.createTableStatements(table));
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
for (const columnPropertyName in table.columns) {
|
|
30
|
-
const column = table.columns[columnPropertyName];
|
|
31
|
-
const columnType = new SpannerColumnTypeFactory().getType(column);
|
|
32
|
-
serializedColumns.push({ name: column.name, type: columnType, nullable: column.options?.nullable });
|
|
33
|
-
this.logger.info({ message: `[${table.name}] Creating column: ${column.name} (${column.constructor.name})` });
|
|
34
|
-
if (column.options?.unique?.unique) {
|
|
35
|
-
indexes.push({
|
|
36
|
-
name: column.options.unique.indexName,
|
|
37
|
-
columns: [table.columns[column.name]!.name],
|
|
38
|
-
unique: true,
|
|
39
|
-
});
|
|
40
|
-
this.logger.info({ message: `[${table.name}.${column.name}] Adding unique constraint` });
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (column.options?.references) {
|
|
44
|
-
foreignKeys.push({ table: column.options.references.table, column: 'id', referencedByColumn: column.name });
|
|
45
|
-
this.logger.info({
|
|
46
|
-
message: `[${table.name}.${column.name}] Adding foreign key -> ${column.options.references.table}.id`,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
34
|
+
if (statements.length === 0) {
|
|
35
|
+
return;
|
|
49
36
|
}
|
|
50
|
-
const createTableSql = new StatementFactory().createTable(table.name, serializedColumns, 'id', foreignKeys).sql;
|
|
51
|
-
await this.spannerDriver.runUpdateSchema(createTableSql);
|
|
52
37
|
|
|
53
|
-
|
|
54
|
-
const createIndexSql = new StatementFactory().createIndex(index, table.name).sql;
|
|
55
|
-
const indexName = StatementUtil.getIndexName(table.name, index);
|
|
56
|
-
this.logger.info({
|
|
57
|
-
message: `[${table.name}] Creating index: ${indexName} (${index.columns.join(', ')})`,
|
|
58
|
-
});
|
|
59
|
-
await this.spannerDriver.runUpdateSchema(createIndexSql);
|
|
60
|
-
this.logger.info({
|
|
61
|
-
message: `[${table.name}] Created index: ${indexName} (${index.columns.join(', ')})`,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
38
|
+
await this.spannerDriver.runUpdateSchema(statements);
|
|
64
39
|
}
|
|
65
40
|
|
|
66
41
|
async alterTable(table: Table<any>, tableChanges: TableChanges) {
|
|
@@ -134,37 +109,76 @@ export class SpannerSchemaOperations implements SchemaOperations {
|
|
|
134
109
|
throw new Error(errorMessage);
|
|
135
110
|
}
|
|
136
111
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
112
|
+
// One schema-update operation for the whole alter pass, preserving the statement order the
|
|
113
|
+
// serial version applied: alters (add column / drop+add FK), STRING widenings, index drops,
|
|
114
|
+
// index creates.
|
|
115
|
+
const statements: string[] = new StatementFactory()
|
|
116
|
+
.alterTable(alterParams)
|
|
117
|
+
.map((alterStatement) => alterStatement.sql);
|
|
118
|
+
statements.push(...wideningStatements);
|
|
145
119
|
|
|
146
120
|
for (const index of tableChanges.indexesToDrop) {
|
|
147
|
-
const dropIndexSql = new StatementFactory().dropIndex(index, table.name).sql;
|
|
148
121
|
this.logger.info({
|
|
149
122
|
message: `[${table.name}] Dropping index: ${index.name} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`,
|
|
150
123
|
});
|
|
151
|
-
|
|
152
|
-
this.logger.info({
|
|
153
|
-
message: `[${table.name}] Dropped index: ${index.name} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`,
|
|
154
|
-
});
|
|
124
|
+
statements.push(new StatementFactory().dropIndex(index, table.name).sql);
|
|
155
125
|
}
|
|
156
126
|
|
|
157
127
|
for (const index of tableChanges.indexesToCreate) {
|
|
158
|
-
const createIndexSql = new StatementFactory().createIndex(index, table.name).sql;
|
|
159
128
|
const indexName = StatementUtil.getIndexName(table.name, index);
|
|
160
129
|
this.logger.info({
|
|
161
130
|
message: `[${table.name}] Creating index: ${indexName} (${typeof index.columns === 'string' ? index.columns : index.columns.join(', ')})`,
|
|
162
131
|
});
|
|
163
|
-
|
|
132
|
+
statements.push(new StatementFactory().createIndex(index, table.name).sql);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (statements.length === 0) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
await this.spannerDriver.runUpdateSchema(statements);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private createTableStatements(table: Table<any>): string[] {
|
|
143
|
+
const indexes: { name?: string; columns: string[]; unique?: boolean }[] = [];
|
|
144
|
+
for (const { name, columns, unique } of table.indexes) {
|
|
145
|
+
indexes.push({ name, columns: columns.map((x) => table.columns[x as string]!.name), unique });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const serializedColumns: { name: string; type: string; nullable?: boolean }[] = [];
|
|
149
|
+
const foreignKeys: { table: string; column: string; referencedByColumn: string }[] = [];
|
|
150
|
+
for (const columnPropertyName in table.columns) {
|
|
151
|
+
const column = table.columns[columnPropertyName];
|
|
152
|
+
const columnType = new SpannerColumnTypeFactory().getType(column);
|
|
153
|
+
serializedColumns.push({ name: column.name, type: columnType, nullable: column.options?.nullable });
|
|
154
|
+
this.logger.info({ message: `[${table.name}] Creating column: ${column.name} (${column.constructor.name})` });
|
|
155
|
+
if (column.options?.unique?.unique) {
|
|
156
|
+
indexes.push({
|
|
157
|
+
name: column.options.unique.indexName,
|
|
158
|
+
columns: [table.columns[column.name]!.name],
|
|
159
|
+
unique: true,
|
|
160
|
+
});
|
|
161
|
+
this.logger.info({ message: `[${table.name}.${column.name}] Adding unique constraint` });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (column.options?.references) {
|
|
165
|
+
foreignKeys.push({ table: column.options.references.table, column: 'id', referencedByColumn: column.name });
|
|
166
|
+
this.logger.info({
|
|
167
|
+
message: `[${table.name}.${column.name}] Adding foreign key -> ${column.options.references.table}.id`,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const statements = [new StatementFactory().createTable(table.name, serializedColumns, 'id', foreignKeys).sql];
|
|
173
|
+
for (const index of indexes) {
|
|
174
|
+
const indexName = StatementUtil.getIndexName(table.name, index);
|
|
164
175
|
this.logger.info({
|
|
165
|
-
message: `[${table.name}]
|
|
176
|
+
message: `[${table.name}] Creating index: ${indexName} (${index.columns.join(', ')})`,
|
|
166
177
|
});
|
|
178
|
+
statements.push(new StatementFactory().createIndex(index, table.name).sql);
|
|
167
179
|
}
|
|
180
|
+
|
|
181
|
+
return statements;
|
|
168
182
|
}
|
|
169
183
|
|
|
170
184
|
/**
|