@proteinjs/db-driver-spanner 1.23.5 → 1.24.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 +16 -0
- package/dist/generated/test/index.d.ts.map +1 -1
- package/dist/generated/test/index.js +15 -1
- package/dist/generated/test/index.js.map +1 -1
- package/dist/src/SpannerSchemaOperations.d.ts.map +1 -1
- package/dist/src/SpannerSchemaOperations.js +4 -1
- package/dist/src/SpannerSchemaOperations.js.map +1 -1
- package/dist/test/ColumnEncryption.test.d.ts +2 -0
- package/dist/test/ColumnEncryption.test.d.ts.map +1 -0
- package/dist/test/ColumnEncryption.test.js +482 -0
- package/dist/test/ColumnEncryption.test.js.map +1 -0
- package/dist/test/EncryptedSearch.test.d.ts +2 -0
- package/dist/test/EncryptedSearch.test.d.ts.map +1 -0
- package/dist/test/EncryptedSearch.test.js +455 -0
- package/dist/test/EncryptedSearch.test.js.map +1 -0
- package/dist/test/EncryptionLifecycleWalker.test.d.ts +2 -0
- package/dist/test/EncryptionLifecycleWalker.test.d.ts.map +1 -0
- package/dist/test/EncryptionLifecycleWalker.test.js +408 -0
- package/dist/test/EncryptionLifecycleWalker.test.js.map +1 -0
- package/dist/test/EncryptionPerf.test.d.ts +2 -0
- package/dist/test/EncryptionPerf.test.d.ts.map +1 -0
- package/dist/test/EncryptionPerf.test.js +278 -0
- package/dist/test/EncryptionPerf.test.js.map +1 -0
- package/dist/test/EncryptionSortAndUnique.test.d.ts +2 -0
- package/dist/test/EncryptionSortAndUnique.test.d.ts.map +1 -0
- package/dist/test/EncryptionSortAndUnique.test.js +229 -0
- package/dist/test/EncryptionSortAndUnique.test.js.map +1 -0
- package/dist/test/index.d.ts +1 -0
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +1 -0
- package/dist/test/index.js.map +1 -1
- package/dist/test/util/columnEncryptionTestHarness.d.ts +23 -0
- package/dist/test/util/columnEncryptionTestHarness.d.ts.map +1 -0
- package/dist/test/util/columnEncryptionTestHarness.js +136 -0
- package/dist/test/util/columnEncryptionTestHarness.js.map +1 -0
- package/dist/test/util/columnEncryptionTestTables.d.ts +75 -0
- package/dist/test/util/columnEncryptionTestTables.d.ts.map +1 -0
- package/dist/test/util/columnEncryptionTestTables.js +124 -0
- package/dist/test/util/columnEncryptionTestTables.js.map +1 -0
- package/dist/test/util/serviceUpdateVerbsTestTables.d.ts +2 -2
- package/generated/test/index.ts +15 -1
- package/package.json +6 -6
- package/src/SpannerSchemaOperations.ts +4 -1
- package/test/ColumnEncryption.test.ts +252 -0
- package/test/EncryptedSearch.test.ts +247 -0
- package/test/EncryptionLifecycleWalker.test.ts +223 -0
- package/test/EncryptionPerf.test.ts +156 -0
- package/test/EncryptionSortAndUnique.test.ts +130 -0
- package/test/index.ts +1 -0
- package/test/util/columnEncryptionTestHarness.ts +54 -0
- package/test/util/columnEncryptionTestTables.ts +115 -0
package/generated/test/index.ts
CHANGED
|
@@ -9,11 +9,18 @@ import '@proteinjs/logger';
|
|
|
9
9
|
/** Generate Source Graph */
|
|
10
10
|
|
|
11
11
|
const sourceGraph =
|
|
12
|
-
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/db-driver-spanner/TestDbDriverFactory","value":{"packageName":"@proteinjs/db-driver-spanner","name":"TestDbDriverFactory","filePath":"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":"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":"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":"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":"bindableParams","returnType":{"packageName":"@proteinjs/db-driver-spanner","name":"{ [param: string]: any } | undefined","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/{ [param: string]: any } | undefined","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"namedParams","type":{"packageName":"","name":"Statement[\'namedParams\']","filePath":null,"qualifiedName":"/Statement[\'namedParams\']","typeParameters":null,"directParents":null}}]},{"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":"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":"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":"isAlreadyExistsError","returnType":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"error","type":{"packageName":"","name":"unknown","filePath":null,"qualifiedName":"/unknown","typeParameters":null,"directParents":null}}]},{"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"}]}';
|
|
12
|
+
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/db-driver-spanner/TestDbDriverFactory","value":{"packageName":"@proteinjs/db-driver-spanner","name":"TestDbDriverFactory","filePath":"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/EncNote","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncNote","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncNote","properties":[{"name":"scope","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"title","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"label","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"body","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"status","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","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/EncNoteTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncNoteTable","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncNoteTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":{"packageName":"","name":"Table<EncNote>[\'columns\']","filePath":null,"qualifiedName":"/Table<EncNote>[\'columns\']","typeParameters":null,"directParents":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/EncNote"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db/Table"},{"v":"@proteinjs/db-driver-spanner/EncSearchDoc","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncSearchDoc","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncSearchDoc","properties":[{"name":"scope","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"title","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"name","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"kind","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","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-driver-spanner/EncSearchDocTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncSearchDocTable","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncSearchDocTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":{"packageName":"","name":"Table<EncSearchDoc>[\'columns\']","filePath":null,"qualifiedName":"/Table<EncSearchDoc>[\'columns\']","typeParameters":null,"directParents":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/EncSearchDoc"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db-driver-spanner/EncSortedItem","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncSortedItem","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncSortedItem","properties":[{"name":"scope","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"title","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","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-driver-spanner/EncSortedItemTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncSortedItemTable","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncSortedItemTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":{"packageName":"","name":"Table<EncSortedItem>[\'columns\']","filePath":null,"qualifiedName":"/Table<EncSortedItem>[\'columns\']","typeParameters":null,"directParents":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/EncSortedItem"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db-driver-spanner/EncUniqueTag","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncUniqueTag","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncUniqueTag","properties":[{"name":"scope","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"name","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","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-driver-spanner/EncUniqueTagTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncUniqueTagTable","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncUniqueTagTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":{"packageName":"","name":"Table<EncUniqueTag>[\'columns\']","filePath":null,"qualifiedName":"/Table<EncUniqueTag>[\'columns\']","typeParameters":null,"directParents":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/EncUniqueTag"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db-driver-spanner/EncWalkRow","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncWalkRow","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncWalkRow","properties":[{"name":"scope","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"title","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"body","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","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-driver-spanner/EncWalkRowTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncWalkRowTable","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncWalkRowTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":{"packageName":"","name":"Table<EncWalkRow>[\'columns\']","filePath":null,"qualifiedName":"/Table<EncWalkRow>[\'columns\']","typeParameters":null,"directParents":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/EncWalkRow"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db-driver-spanner/EncPerfRow","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncPerfRow","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncPerfRow","properties":[{"name":"scope","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"body","type":{"packageName":"","name":"string | null","filePath":null,"qualifiedName":"/string | null","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-driver-spanner/EncPerfRowTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"EncPerfRowTable","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/EncPerfRowTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":{"packageName":"","name":"Table<EncPerfRow>[\'columns\']","filePath":null,"qualifiedName":"/Table<EncPerfRow>[\'columns\']","typeParameters":null,"directParents":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/EncPerfRow"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db-driver-spanner/PlainPerfRowTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"PlainPerfRowTable","filePath":"test/util/columnEncryptionTestTables.ts","qualifiedName":"@proteinjs/db-driver-spanner/PlainPerfRowTable","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"name","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"columns","type":{"packageName":"","name":"Table<EncPerfRow>[\'columns\']","filePath":null,"qualifiedName":"/Table<EncPerfRow>[\'columns\']","typeParameters":null,"directParents":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/EncPerfRow"],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}},{"v":"@proteinjs/db-driver-spanner/ServiceVerbsDoc","value":{"packageName":"@proteinjs/db-driver-spanner","name":"ServiceVerbsDoc","filePath":"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-driver-spanner/ServiceVerbsDocTable","value":{"packageName":"@proteinjs/db-driver-spanner","name":"ServiceVerbsDocTable","filePath":"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-driver-spanner/SpannerDriver","value":{"packageName":"@proteinjs/db-driver-spanner","name":"SpannerDriver","filePath":"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":"bindableParams","returnType":{"packageName":"@proteinjs/db-driver-spanner","name":"{ [param: string]: any } | undefined","filePath":null,"qualifiedName":"@proteinjs/db-driver-spanner/{ [param: string]: any } | undefined","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"namedParams","type":{"packageName":"","name":"Statement[\'namedParams\']","filePath":null,"qualifiedName":"/Statement[\'namedParams\']","typeParameters":null,"directParents":null}}]},{"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":"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":"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":"isAlreadyExistsError","returnType":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"error","type":{"packageName":"","name":"unknown","filePath":null,"qualifiedName":"/unknown","typeParameters":null,"directParents":null}}]},{"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/EncNote","w":"@proteinjs/db/Record","value":"extends interface"},{"v":"@proteinjs/db-driver-spanner/EncNoteTable","w":"@proteinjs/db/Table","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/EncSearchDoc","w":"@proteinjs/db/Record","value":"extends interface"},{"v":"@proteinjs/db-driver-spanner/EncSearchDocTable","w":"@proteinjs/db/Table","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/EncSortedItem","w":"@proteinjs/db/Record","value":"extends interface"},{"v":"@proteinjs/db-driver-spanner/EncSortedItemTable","w":"@proteinjs/db/Table","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/EncUniqueTag","w":"@proteinjs/db/Record","value":"extends interface"},{"v":"@proteinjs/db-driver-spanner/EncUniqueTagTable","w":"@proteinjs/db/Table","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/EncWalkRow","w":"@proteinjs/db/Record","value":"extends interface"},{"v":"@proteinjs/db-driver-spanner/EncWalkRowTable","w":"@proteinjs/db/Table","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/EncPerfRow","w":"@proteinjs/db/Record","value":"extends interface"},{"v":"@proteinjs/db-driver-spanner/EncPerfRowTable","w":"@proteinjs/db/Table","value":"extends class"},{"v":"@proteinjs/db-driver-spanner/PlainPerfRowTable","w":"@proteinjs/db/Table","value":"extends class"},{"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"}]}';
|
|
13
13
|
|
|
14
14
|
/** Generate Source Links */
|
|
15
15
|
|
|
16
16
|
import { TestDbDriverFactory } from '../../test/config/TestDbDriverFactory';
|
|
17
|
+
import { EncNoteTable } from '../../test/util/columnEncryptionTestTables';
|
|
18
|
+
import { EncSearchDocTable } from '../../test/util/columnEncryptionTestTables';
|
|
19
|
+
import { EncSortedItemTable } from '../../test/util/columnEncryptionTestTables';
|
|
20
|
+
import { EncUniqueTagTable } from '../../test/util/columnEncryptionTestTables';
|
|
21
|
+
import { EncWalkRowTable } from '../../test/util/columnEncryptionTestTables';
|
|
22
|
+
import { EncPerfRowTable } from '../../test/util/columnEncryptionTestTables';
|
|
23
|
+
import { PlainPerfRowTable } from '../../test/util/columnEncryptionTestTables';
|
|
17
24
|
import { ServiceVerbsDocTable } from '../../test/util/serviceUpdateVerbsTestTables';
|
|
18
25
|
import { SpannerDriver } from '../../src/SpannerDriver';
|
|
19
26
|
import { SpannerSchemaMetadata } from '../../src/SpannerSchemaMetadata';
|
|
@@ -21,6 +28,13 @@ import { SpannerSchemaOperations } from '../../src/SpannerSchemaOperations';
|
|
|
21
28
|
|
|
22
29
|
const sourceLinks = {
|
|
23
30
|
'@proteinjs/db-driver-spanner/TestDbDriverFactory': TestDbDriverFactory,
|
|
31
|
+
'@proteinjs/db-driver-spanner/EncNoteTable': EncNoteTable,
|
|
32
|
+
'@proteinjs/db-driver-spanner/EncSearchDocTable': EncSearchDocTable,
|
|
33
|
+
'@proteinjs/db-driver-spanner/EncSortedItemTable': EncSortedItemTable,
|
|
34
|
+
'@proteinjs/db-driver-spanner/EncUniqueTagTable': EncUniqueTagTable,
|
|
35
|
+
'@proteinjs/db-driver-spanner/EncWalkRowTable': EncWalkRowTable,
|
|
36
|
+
'@proteinjs/db-driver-spanner/EncPerfRowTable': EncPerfRowTable,
|
|
37
|
+
'@proteinjs/db-driver-spanner/PlainPerfRowTable': PlainPerfRowTable,
|
|
24
38
|
'@proteinjs/db-driver-spanner/ServiceVerbsDocTable': ServiceVerbsDocTable,
|
|
25
39
|
'@proteinjs/db-driver-spanner/SpannerDriver': SpannerDriver,
|
|
26
40
|
'@proteinjs/db-driver-spanner/SpannerSchemaMetadata': SpannerSchemaMetadata,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/db-driver-spanner",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.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.36.0",
|
|
46
|
+
"@proteinjs/db-query": "^1.8.0",
|
|
47
|
+
"@proteinjs/db-spanner-common": "^1.3.20",
|
|
48
|
+
"@proteinjs/db-transaction-context": "^0.5.20",
|
|
49
49
|
"@proteinjs/logger": "^1.0.21",
|
|
50
50
|
"@proteinjs/reflection": "^1.2.0",
|
|
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": "b25c88ae26fffd1c784b4c7b1174825b52751987"
|
|
67
67
|
}
|
|
@@ -191,7 +191,10 @@ export class SpannerSchemaOperations implements SchemaOperations {
|
|
|
191
191
|
if (column.options?.unique?.unique) {
|
|
192
192
|
indexes.push({
|
|
193
193
|
name: column.options.unique.indexName,
|
|
194
|
-
|
|
194
|
+
// the column object in hand IS the unique column — indexing table.columns by
|
|
195
|
+
// column NAME assumed property name == column name (crashes for any column
|
|
196
|
+
// whose property differs, e.g. jobTitle -> job_title)
|
|
197
|
+
columns: [column.name],
|
|
195
198
|
unique: true,
|
|
196
199
|
});
|
|
197
200
|
this.logger.info({ message: `[${table.name}.${column.name}] Adding unique constraint` });
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Db,
|
|
3
|
+
Table,
|
|
4
|
+
setDbEncryptionConfig,
|
|
5
|
+
InMemoryMasterKeyProvider,
|
|
6
|
+
DataKeyStore,
|
|
7
|
+
EncryptionEnvelope,
|
|
8
|
+
EncryptionKeyUnavailableError,
|
|
9
|
+
MasterKeyProvider,
|
|
10
|
+
QueryBuilder,
|
|
11
|
+
} from '@proteinjs/db';
|
|
12
|
+
import { SpannerDriver } from '@proteinjs/db-driver-spanner';
|
|
13
|
+
import { TransactionContext } from '@proteinjs/db-transaction-context';
|
|
14
|
+
import { getDropTestTable } from './util/getDropTestTable';
|
|
15
|
+
import { SpannerEmulatorProvisioner } from './util/SpannerEmulatorProvisioner';
|
|
16
|
+
import { EncNote, EncNoteTable } from './util/columnEncryptionTestTables';
|
|
17
|
+
import { loadColumnEncryptionTestSchema, purgeColumnEncryptionTestRows } from './util/columnEncryptionTestHarness';
|
|
18
|
+
import { registerTestUser, clearTestUser } from '@proteinjs/db/test';
|
|
19
|
+
import '../generated/test/index';
|
|
20
|
+
|
|
21
|
+
const spannerDriver = new SpannerDriver({
|
|
22
|
+
projectId: 'proteinjs-test',
|
|
23
|
+
instanceName: 'proteinjs-test',
|
|
24
|
+
databaseName: 'test',
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
/** Key IO (DataKeyStore) rides the process's default driver — the getDbAsSystem idiom the
|
|
28
|
+
* migration ledger already uses. The driver test harness has no DefaultDbDriverFactory, so
|
|
29
|
+
* seed the global the same way the factory would (test-harness convention: runtime access
|
|
30
|
+
* to internals rather than widening the API). */
|
|
31
|
+
(globalThis as any)['__proteinjs_db_defaultDbDriver'] = spannerDriver;
|
|
32
|
+
|
|
33
|
+
const OWNER_A = 'enc-core-owner-a';
|
|
34
|
+
const OWNER_B = 'enc-core-owner-b';
|
|
35
|
+
|
|
36
|
+
/** Counts vault calls, so unwrap-once caching is asserted on OUTCOMES (vault traffic). */
|
|
37
|
+
class CountingMasterKeyProvider implements MasterKeyProvider {
|
|
38
|
+
public wrapCalls = 0;
|
|
39
|
+
public unwrapCalls = 0;
|
|
40
|
+
private delegate = new InMemoryMasterKeyProvider('column-encryption-test');
|
|
41
|
+
|
|
42
|
+
async wrapDataKey(material: Buffer): Promise<string> {
|
|
43
|
+
this.wrapCalls++;
|
|
44
|
+
return await this.delegate.wrapDataKey(material);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async unwrapDataKey(wrapped: string): Promise<Buffer> {
|
|
48
|
+
this.unwrapCalls++;
|
|
49
|
+
return await this.delegate.unwrapDataKey(wrapped);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getMasterKeyId(): string {
|
|
53
|
+
return 'counting-in-memory';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const masterKeyProvider = new CountingMasterKeyProvider();
|
|
58
|
+
let accessibleOwners: string[] = [OWNER_A];
|
|
59
|
+
|
|
60
|
+
const noteTable = new EncNoteTable() as Table<EncNote>;
|
|
61
|
+
const db = new Db(spannerDriver, undefined, new TransactionContext());
|
|
62
|
+
const envelope = new EncryptionEnvelope();
|
|
63
|
+
|
|
64
|
+
const rawColumn = async (tableName: string, id: string, columnName: string): Promise<any> => {
|
|
65
|
+
const rows = await spannerDriver.runQuery(() => ({
|
|
66
|
+
sql: `SELECT \`${columnName}\` FROM \`${tableName}\` WHERE \`id\` = '${id}'`,
|
|
67
|
+
}));
|
|
68
|
+
return rows[0]?.[columnName];
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
describe('Column encryption: the transparent seam', () => {
|
|
72
|
+
const dropTable = getDropTestTable(spannerDriver);
|
|
73
|
+
const tableManager = spannerDriver.getTableManager();
|
|
74
|
+
|
|
75
|
+
beforeAll(async () => {
|
|
76
|
+
await SpannerEmulatorProvisioner.ensureProvisioned({
|
|
77
|
+
projectId: 'proteinjs-test',
|
|
78
|
+
instanceName: 'proteinjs-test',
|
|
79
|
+
databaseName: 'test',
|
|
80
|
+
});
|
|
81
|
+
registerTestUser();
|
|
82
|
+
setDbEncryptionConfig({
|
|
83
|
+
masterKeyProvider,
|
|
84
|
+
getAccessibleKeyOwners: async () => accessibleOwners,
|
|
85
|
+
});
|
|
86
|
+
await loadColumnEncryptionTestSchema(tableManager, [noteTable]);
|
|
87
|
+
await purgeColumnEncryptionTestRows(spannerDriver, [noteTable]);
|
|
88
|
+
}, 120000);
|
|
89
|
+
|
|
90
|
+
afterAll(async () => {
|
|
91
|
+
setDbEncryptionConfig(undefined);
|
|
92
|
+
clearTestUser();
|
|
93
|
+
const { EncryptedColumns } = await import('@proteinjs/db');
|
|
94
|
+
await dropTable(new EncryptedColumns().tokenTableFor(noteTable)!);
|
|
95
|
+
await dropTable(noteTable);
|
|
96
|
+
await SpannerEmulatorProvisioner.release();
|
|
97
|
+
}, 60000);
|
|
98
|
+
|
|
99
|
+
beforeEach(() => {
|
|
100
|
+
accessibleOwners = [OWNER_A];
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('round trip is transparent: callers write and read plaintext; the database stores a ciphertext envelope', async () => {
|
|
104
|
+
const inserted = await db.insert(noteTable, {
|
|
105
|
+
scope: OWNER_A,
|
|
106
|
+
title: 'Therapy notes — divorce',
|
|
107
|
+
label: 'personal',
|
|
108
|
+
body: 'The most sensitive words in the account.',
|
|
109
|
+
status: 'active',
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Caller-visible: plaintext, unchanged API
|
|
113
|
+
const fetched = await db.get(noteTable, { id: inserted.id });
|
|
114
|
+
expect(fetched.title).toBe('Therapy notes — divorce');
|
|
115
|
+
expect(fetched.label).toBe('personal');
|
|
116
|
+
expect(fetched.body).toBe('The most sensitive words in the account.');
|
|
117
|
+
expect(fetched.status).toBe('active');
|
|
118
|
+
|
|
119
|
+
// At rest: self-describing envelopes, no plaintext, plaintext column untouched
|
|
120
|
+
for (const columnName of ['title', 'label', 'body']) {
|
|
121
|
+
const stored = await rawColumn(noteTable.name, inserted.id, columnName);
|
|
122
|
+
expect(envelope.isEnvelope(stored)).toBe(true);
|
|
123
|
+
expect(stored).not.toContain('divorce');
|
|
124
|
+
expect(stored).not.toContain('sensitive');
|
|
125
|
+
const parsed = envelope.parse(stored)!;
|
|
126
|
+
expect(parsed.owner).toBe(OWNER_A);
|
|
127
|
+
}
|
|
128
|
+
expect(await rawColumn(noteTable.name, inserted.id, 'status')).toBe('active');
|
|
129
|
+
|
|
130
|
+
// Deserialized records carry no framework companion columns
|
|
131
|
+
expect(Object.keys(fetched).some((key) => key.includes('__enc'))).toBe(false);
|
|
132
|
+
|
|
133
|
+
await db.delete(noteTable, { id: inserted.id });
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('update through the seam: new ciphertext at rest, plaintext to callers', async () => {
|
|
137
|
+
const inserted = await db.insert(noteTable, { scope: OWNER_A, title: 'Before', label: 'a', body: 'b' });
|
|
138
|
+
const updateCount = await db.update(noteTable, { id: inserted.id, title: 'After the update' });
|
|
139
|
+
expect(updateCount).toBe(1);
|
|
140
|
+
|
|
141
|
+
const fetched = await db.get(noteTable, { id: inserted.id });
|
|
142
|
+
expect(fetched.title).toBe('After the update');
|
|
143
|
+
expect(fetched.label).toBe('a'); // untouched columns survive
|
|
144
|
+
|
|
145
|
+
const stored = await rawColumn(noteTable.name, inserted.id, 'title');
|
|
146
|
+
expect(envelope.isEnvelope(stored)).toBe(true);
|
|
147
|
+
expect(stored).not.toContain('After');
|
|
148
|
+
|
|
149
|
+
await db.delete(noteTable, { id: inserted.id });
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test('null stays null: IS NULL / IS NOT NULL queries keep working natively', async () => {
|
|
153
|
+
const withTitle = await db.insert(noteTable, { scope: OWNER_A, title: 'present', label: 'x', body: null });
|
|
154
|
+
const withoutTitle = await db.insert(noteTable, { scope: OWNER_A, title: null, label: 'y', body: 'here' });
|
|
155
|
+
|
|
156
|
+
expect(await rawColumn(noteTable.name, withoutTitle.id, 'title')).toBeNull();
|
|
157
|
+
|
|
158
|
+
const nullTitles = await db.query(
|
|
159
|
+
noteTable,
|
|
160
|
+
new QueryBuilder<EncNote>(noteTable.name).condition({ field: 'title', operator: 'IS NULL' })
|
|
161
|
+
);
|
|
162
|
+
expect(nullTitles.some((row) => row.id === withoutTitle.id)).toBe(true);
|
|
163
|
+
expect(nullTitles.some((row) => row.id === withTitle.id)).toBe(false);
|
|
164
|
+
|
|
165
|
+
await db.delete(noteTable, { id: withTitle.id });
|
|
166
|
+
await db.delete(noteTable, { id: withoutTitle.id });
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('adoption path: a pre-encryption plaintext row reads through the seam unchanged', async () => {
|
|
170
|
+
const id = 'enc-adoption-row-1';
|
|
171
|
+
await spannerDriver.runDml(() => ({
|
|
172
|
+
sql:
|
|
173
|
+
`INSERT INTO \`${noteTable.name}\` (\`id\`, \`created\`, \`updated\`, \`scope\`, \`title\`, \`status\`) ` +
|
|
174
|
+
`VALUES ('${id}', CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '${OWNER_A}', 'legacy plaintext title', 'active')`,
|
|
175
|
+
}));
|
|
176
|
+
|
|
177
|
+
const fetched = await db.get(noteTable, { id });
|
|
178
|
+
expect(fetched.title).toBe('legacy plaintext title');
|
|
179
|
+
await db.delete(noteTable, { id });
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test('scope-owner keying: each row encrypts under its scope owner; the vault is called once per key (unwrap caching)', async () => {
|
|
183
|
+
const rowA = await db.insert(noteTable, { scope: OWNER_A, title: 'a note', label: 'la', body: 'ba' });
|
|
184
|
+
const rowB = await db.insert(noteTable, { scope: OWNER_B, title: 'b note', label: 'lb', body: 'bb' });
|
|
185
|
+
|
|
186
|
+
expect(envelope.parse(await rawColumn(noteTable.name, rowA.id, 'title'))!.owner).toBe(OWNER_A);
|
|
187
|
+
expect(envelope.parse(await rawColumn(noteTable.name, rowB.id, 'title'))!.owner).toBe(OWNER_B);
|
|
188
|
+
|
|
189
|
+
// Server-side sharing mechanics: decrypt resolves the key FROM the envelope, so one
|
|
190
|
+
// reader's reads return both owners' rows decrypted.
|
|
191
|
+
const bothRows = [await db.get(noteTable, { id: rowA.id }), await db.get(noteTable, { id: rowB.id })];
|
|
192
|
+
expect(bothRows.map((row) => row.title)).toEqual(['a note', 'b note']);
|
|
193
|
+
|
|
194
|
+
// Unwrap-once caching: repeat reads add ZERO vault calls
|
|
195
|
+
const unwrapCallsBefore = masterKeyProvider.unwrapCalls;
|
|
196
|
+
for (let i = 0; i < 5; i++) {
|
|
197
|
+
await db.get(noteTable, { id: rowA.id });
|
|
198
|
+
await db.get(noteTable, { id: rowB.id });
|
|
199
|
+
}
|
|
200
|
+
expect(masterKeyProvider.unwrapCalls).toBe(unwrapCallsBefore);
|
|
201
|
+
|
|
202
|
+
await db.delete(noteTable, { id: rowA.id });
|
|
203
|
+
await db.delete(noteTable, { id: rowB.id });
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('a shared-scope row keys by the scope owner, not the writer: config resolveKeyOwner decides', async () => {
|
|
207
|
+
setDbEncryptionConfig({
|
|
208
|
+
masterKeyProvider,
|
|
209
|
+
getAccessibleKeyOwners: async () => accessibleOwners,
|
|
210
|
+
// The consumer's scope→owner mapping (thought-common's permission-source resolver in
|
|
211
|
+
// the app): here, rows whose scope starts with 'shared:' belong to OWNER_B.
|
|
212
|
+
resolveKeyOwner: async ({ record }) =>
|
|
213
|
+
typeof record.scope === 'string' && record.scope.startsWith('shared:') ? OWNER_B : undefined,
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
const sharedRow = await db.insert(noteTable, { scope: 'shared:tree-root', title: 'contributed text', label: 'l' });
|
|
217
|
+
expect(envelope.parse(await rawColumn(noteTable.name, sharedRow.id, 'title'))!.owner).toBe(OWNER_B);
|
|
218
|
+
|
|
219
|
+
await db.delete(noteTable, { id: sharedRow.id });
|
|
220
|
+
setDbEncryptionConfig({ masterKeyProvider, getAccessibleKeyOwners: async () => accessibleOwners });
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
test('crypto-shred: deleting an owner key makes their rows permanently unreadable, loudly', async () => {
|
|
224
|
+
const shredOwner = 'enc-core-shred-owner';
|
|
225
|
+
const row = await db.insert(noteTable, { scope: shredOwner, title: 'to be shredded', label: 'x', body: 'y' });
|
|
226
|
+
|
|
227
|
+
const deleted = await new DataKeyStore().shredOwnerKeys(shredOwner);
|
|
228
|
+
expect(deleted).toBeGreaterThanOrEqual(1);
|
|
229
|
+
|
|
230
|
+
await expect(db.get(noteTable, { id: row.id })).rejects.toThrow(EncryptionKeyUnavailableError);
|
|
231
|
+
|
|
232
|
+
// other owners' rows are untouched (blast radius = one owner)
|
|
233
|
+
const survivor = await db.insert(noteTable, { scope: OWNER_A, title: 'still fine', label: 'ok' });
|
|
234
|
+
expect((await db.get(noteTable, { id: survivor.id })).title).toBe('still fine');
|
|
235
|
+
|
|
236
|
+
await spannerDriver.runDml(() => ({
|
|
237
|
+
sql: `DELETE FROM \`${noteTable.name}\` WHERE \`id\` = '${row.id}'`,
|
|
238
|
+
}));
|
|
239
|
+
await db.delete(noteTable, { id: survivor.id });
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
test('transactions: encrypted writes and reads ride runTransaction like any other write', async () => {
|
|
243
|
+
const result = await db.runTransaction(async () => {
|
|
244
|
+
const inserted = await db.insert(noteTable, { scope: OWNER_A, title: 'txn title', label: 'txn' });
|
|
245
|
+
await db.update(noteTable, { id: inserted.id, body: 'txn body' });
|
|
246
|
+
return await db.get(noteTable, { id: inserted.id });
|
|
247
|
+
});
|
|
248
|
+
expect(result.title).toBe('txn title');
|
|
249
|
+
expect(result.body).toBe('txn body');
|
|
250
|
+
await db.delete(noteTable, { id: result.id });
|
|
251
|
+
});
|
|
252
|
+
});
|