From 889a885b134f7b8d9c39fbb136f29810f3f740b1 Mon Sep 17 00:00:00 2001 From: surbhigarg92 Date: Tue, 14 Mar 2023 16:19:21 +0530 Subject: [PATCH 1/7] feat: foreign key delete cascade testing, samples --- system-test/spanner.ts | 196 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/system-test/spanner.ts b/system-test/spanner.ts index 7b6bc90ca..1eba82beb 100644 --- a/system-test/spanner.ts +++ b/system-test/spanner.ts @@ -2440,6 +2440,202 @@ describe('Spanner', () => { await setIamPolicy(PG_DATABASE); }); }); + + describe('ForeignKeyDeleteCascadeAction', () => { + const fkadc_database_id = generateName('fkadc'); + const fkadc_database_pg_id = generateName('fkadc-pg'); + const fkadc_database = instance.database(fkadc_database_id); + const fkadc_database_pg = instance.database(fkadc_database_pg_id); + + const fkadc_schema = [ + `CREATE TABLE Customers ( + CustomerId INT64, + CustomerName STRING(62) NOT NULL + ) PRIMARY KEY (CustomerId)`, + `CREATE TABLE ShoppingCarts ( + CartId INT64 NOT NULL, + CustomerId INT64 NOT NULL, + CustomerName STRING(62) NOT NULL, + CONSTRAINT FKShoppingCartsCustomerId FOREIGN KEY (CustomerId) + REFERENCES Customers (CustomerId) ON DELETE CASCADE, + ) PRIMARY KEY (CartId)`, + ]; + const fkadc_pg_schema = [ + `CREATE TABLE Customers ( + CustomerId BIGINT, + CustomerName VARCHAR(62) NOT NULL, + PRIMARY KEY (CustomerId) + ) `, + `CREATE TABLE ShoppingCarts ( + CartId BIGINT, + CustomerId BIGINT NOT NULL, + CustomerName VARCHAR(62) NOT NULL, + CONSTRAINT "FKShoppingCartsCustomerId" FOREIGN KEY (CustomerId) + REFERENCES Customers (CustomerId) ON DELETE CASCADE, + PRIMARY KEY (CartId) + )`, + ]; + + const createDatabaseWithFKADC = async ( + dialect, + database_id, + database_schema + ) => { + const [database, operation] = await instance.createDatabase( + database_id, + {databaseDialect: dialect} + ); + await operation.promise(); + + const [operationUpdateDDL] = await database.updateSchema( + database_schema + ); + await operationUpdateDDL.promise(); + + const [schema] = await database.getSchema(); + assert.strictEqual( + schema.filter(x => x.includes('FKShoppingCartsCustomerId')).length, + 1 + ); + }; + + it('GOOGLE_STANDARD_SQL should create a database with foreign key delete cascade action', async () => { + await createDatabaseWithFKADC( + Spanner.GOOGLE_STANDARD_SQL, + fkadc_database_id, + fkadc_schema + ); + }); + + it('POSTGRESQL should create a database with foreign key delete cascade action', async function () { + if (IS_EMULATOR_ENABLED) { + this.skip(); + } + await createDatabaseWithFKADC( + Spanner.POSTGRESQL, + fkadc_database_pg_id, + fkadc_pg_schema + ); + }); + + const alterDatabaseWithFKADC = async (dialect, database) => { + const constraint_name = + dialect === Spanner.POSTGRESQL + ? '"FKShoppingCartsCustomerName"' + : 'FKShoppingCartsCustomerName'; + + const ddl_statements_add_constraints = [ + `ALTER TABLE ShoppingCarts ADD CONSTRAINT ${constraint_name} FOREIGN KEY (CustomerName) REFERENCES Customers(CustomerName) ON DELETE CASCADE`, + ]; + const [operationAddConstraint] = await database.updateSchema( + ddl_statements_add_constraints + ); + await operationAddConstraint.promise(); + const [schema] = await database.getSchema(); + assert.strictEqual( + schema.filter(x => x.includes('FKShoppingCartsCustomerName')).length, + 1 + ); + + const ddl_statements_drop_constraints = [ + 'ALTER TABLE ShoppingCarts DROP CONSTRAINT FKShoppingCartsCustomerName', + ]; + const [operationDropConstraint] = await database.updateSchema( + ddl_statements_drop_constraints + ); + await operationDropConstraint.promise(); + const [schema1] = await database.getSchema(); + assert.strictEqual( + schema1.filter(x => x.includes('FKShoppingCartsCustomerName')).length, + 0 + ); + }; + + it('GOOGLE_STANDARD_SQL should alter a database with foreign key delete cascade action', async () => { + await alterDatabaseWithFKADC( + Spanner.GOOGLE_STANDARD_SQL, + fkadc_database + ); + }); + + it('POSTGRESQL should alter a database with foreign key delete cascade action', async function () { + if (IS_EMULATOR_ENABLED) { + this.skip(); + } + await alterDatabaseWithFKADC(Spanner.POSTGRESQL, fkadc_database_pg); + }); + + const insertAndDeleteRowWithFKADC = async database => { + const customersTable = database.table('Customers'); + await customersTable.insert({ + CustomerId: 1, + CustomerName: 'Marc', + }); + + const cartsTable = database.table('ShoppingCarts'); + await cartsTable.insert({ + CartId: 1, + CustomerId: 1, + CustomerName: 'Marc', + }); + + const [rows] = await cartsTable.read({ + columns: ['CartId', 'CustomerId'], + }); + assert.strictEqual(rows.length, 1); + + await customersTable.deleteRows([1]); + const [rows1] = await cartsTable.read({ + columns: ['CartId', 'CustomerId'], + }); + assert.strictEqual(rows1.length, 0); + }; + + it('GOOGLE_STANDARD_SQL should insert a row and then delete with all references', async () => { + await insertAndDeleteRowWithFKADC(fkadc_database); + }); + + it('POSTGRESQL should insert a row and then delete with all references', async function () { + if (IS_EMULATOR_ENABLED) { + this.skip(); + } + await insertAndDeleteRowWithFKADC(fkadc_database_pg); + }); + + const insertRowErrorWithFKADC = async database => { + const cartsTable = database.table('ShoppingCarts'); + await cartsTable.insert({ + CartId: 2, + CustomerId: 2, + CustomerName: 'Jack', + }); + }; + + it('GOOGLE_STANDARD_SQL should throw error when insert a row without reference', async () => { + try { + await insertRowErrorWithFKADC(fkadc_database); + } catch (err) { + assert.match( + (err as grpc.ServiceError).message, + /Foreign key constraint `FKShoppingCartsCustomerId` is violated on table `ShoppingCarts`\./ + ); + } + }); + + it('POSTGRESQL should throw error when insert a row without reference', async function () { + if (IS_EMULATOR_ENABLED) { + this.skip(); + } + try { + await insertRowErrorWithFKADC(fkadc_database_pg); + } catch (err) { + assert.match( + (err as grpc.ServiceError).message, + /Foreign key constraint `FKShoppingCartsCustomerId` is violated on table `shoppingcarts`\./ + ); + } + }); + }); }); describe('Backups', () => { From 222c3939a078ba3f14638973be7915364fe02361 Mon Sep 17 00:00:00 2001 From: surbhigarg92 Date: Tue, 14 Mar 2023 20:48:32 +0530 Subject: [PATCH 2/7] samples: fkadc --- samples/system-test/spanner.test.js | 48 +++++++++++++ ...e-alter-with-foreign-key-delete-cascade.js | 64 +++++++++++++++++ ...-create-with-foreign-key-delete-cascade.js | 72 +++++++++++++++++++ ...p-foreign-key-constraint-delete-cascade.js | 63 ++++++++++++++++ 4 files changed, 247 insertions(+) create mode 100644 samples/table-alter-with-foreign-key-delete-cascade.js create mode 100644 samples/table-create-with-foreign-key-delete-cascade.js create mode 100644 samples/table-drop-foreign-key-constraint-delete-cascade.js diff --git a/samples/system-test/spanner.test.js b/samples/system-test/spanner.test.js index 95f07187d..90629734c 100644 --- a/samples/system-test/spanner.test.js +++ b/samples/system-test/spanner.test.js @@ -43,6 +43,12 @@ const dmlCmd = 'node dml.js'; const datatypesCmd = 'node datatypes.js'; const backupsCmd = 'node backups.js'; const instanceCmd = 'node instance.js'; +const createTableWithForeignKeyDeleteCascadeCommand = + 'node table-create-with-foreign-key-delete-cascade.js'; +const alterTableWithForeignKeyDeleteCascadeCommand = + 'node table-alter-with-foreign-key-delete-cascade.js'; +const dropForeignKeyConstraintDeleteCascaseCommand = + 'node table-drop-foreign-key-constraint-delete-cascade.js'; const CURRENT_TIME = Math.round(Date.now() / 1000).toString(); const PROJECT_ID = process.env.GCLOUD_PROJECT; @@ -1348,6 +1354,48 @@ describe('Spanner', () => { assert.include(output, 'Earliest version time:'); }); + it('should create a table with foreign key delete cascade', async () => { + const output = execSync( + `${createTableWithForeignKeyDeleteCascadeCommand} "${INSTANCE_ID}" "${DATABASE_ID}" ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp(`Waiting for operation on ${DATABASE_ID} to complete...`) + ); + assert.match( + output, + 'Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId' + ); + }); + + it('should alter a table with foreign key delete cascade', async () => { + const output = execSync( + `${alterTableWithForeignKeyDeleteCascadeCommand} "${INSTANCE_ID}" "${DATABASE_ID}" ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp(`Waiting for operation on ${DATABASE_ID} to complete...`) + ); + assert.match( + output, + 'Altered ShoppingCarts table with FKShoppingCartsCustomerName' + ); + }); + + it('should drop a foreign key constraint delete cascade', async () => { + const output = execSync( + `${dropForeignKeyConstraintDeleteCascaseCommand} "${INSTANCE_ID}" "${DATABASE_ID}" ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp(`Waiting for operation on ${DATABASE_ID} to complete...`) + ); + assert.match( + output, + 'Altered ShoppingCarts table to drop FKShoppingCartsCustomerName' + ); + }); + describe('leader options', () => { before(async () => { const instance = spanner.instance(SAMPLE_INSTANCE_ID); diff --git a/samples/table-alter-with-foreign-key-delete-cascade.js b/samples/table-alter-with-foreign-key-delete-cascade.js new file mode 100644 index 000000000..444e864a3 --- /dev/null +++ b/samples/table-alter-with-foreign-key-delete-cascade.js @@ -0,0 +1,64 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Alters a table with foreign key delete cascade action +// usage: node table-alter-with-foreign-key-delete-cascade.js + +'use strict'; + +function main(instanceId, databaseId, projectId) { + // [START spanner_alter_table_with_foreign_key_delete_cascade] + + // Imports the Google Cloud client library + const {Spanner} = require('@google-cloud/spanner'); + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // const projectId = 'my-project-id'; + // const instanceId = 'my-instance-id'; + // const databaseId = 'my-database-id'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + // Gets a reference to a Cloud Spanner instance and a database. The database does not need to exist. + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + async function alterTableWithForeignKeyDeleteCascade() { + const [operation] = await database.updateSchema([ + `ALTER TABLE ShoppingCarts + ADD CONSTRAINT FKShoppingCartsCustomerName + FOREIGN KEY (CustomerName) + REFERENCES Customers(CustomerName) + ON DELETE CASCADE`, + ]); + + console.log(`Waiting for operation on ${databaseId} to complete...`); + await operation.promise(); + + console.log('Altered ShoppingCarts table with FKShoppingCartsCustomerName'); + } + alterTableWithForeignKeyDeleteCascade(); + // [END spanner_alter_table_with_foreign_key_delete_cascade] +} +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/table-create-with-foreign-key-delete-cascade.js b/samples/table-create-with-foreign-key-delete-cascade.js new file mode 100644 index 000000000..a41faf7f5 --- /dev/null +++ b/samples/table-create-with-foreign-key-delete-cascade.js @@ -0,0 +1,72 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Creates a table with foreign key delete cascade action +// usage: node table-create-with-foreign-key-delete-cascade.js.js + +'use strict'; + +function main(instanceId, databaseId, projectId) { + // [START spanner_create_table_with_foreign_key_delete_cascade] + + // Imports the Google Cloud client library + const {Spanner} = require('@google-cloud/spanner'); + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // const projectId = 'my-project-id'; + // const instanceId = 'my-instance-id'; + // const databaseId = 'my-database-id'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + // Gets a reference to a Cloud Spanner instance and a database. The database does not need to exist. + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + async function createTableWithForeignKeyDeleteCascade() { + const [operation] = await database.updateSchema([ + `CREATE TABLE Customers ( + CustomerId INT64, + CustomerName STRING(62) NOT NULL + ) PRIMARY KEY (CustomerId)`, + `CREATE TABLE ShoppingCarts ( + CartId INT64 NOT NULL, + CustomerId INT64 NOT NULL, + CustomerName STRING(62) NOT NULL, + CONSTRAINT FKShoppingCartsCustomerId FOREIGN KEY (CustomerId) + REFERENCES Customers (CustomerId) ON DELETE CASCADE, + ) PRIMARY KEY (CartId)`, + ]); + + console.log(`Waiting for operation on ${databaseId} to complete...`); + await operation.promise(); + + console.log( + 'Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId' + ); + } + createTableWithForeignKeyDeleteCascade(); + // [END spanner_create_table_with_foreign_key_delete_cascade] +} +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/table-drop-foreign-key-constraint-delete-cascade.js b/samples/table-drop-foreign-key-constraint-delete-cascade.js new file mode 100644 index 000000000..def4292c2 --- /dev/null +++ b/samples/table-drop-foreign-key-constraint-delete-cascade.js @@ -0,0 +1,63 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// sample-metadata: +// title: Drops a foreign key constraint with delete cascade action +// usage: node table-drop-foreign-key-constraint-delete-cascade.js + +'use strict'; + +function main(instanceId, databaseId, projectId) { + // [START spanner_drop_foreign_key_constraint_delete_cascade] + + // Imports the Google Cloud client library + const {Spanner} = require('@google-cloud/spanner'); + + /** + * TODO(developer): Uncomment the following lines before running the sample. + */ + // const projectId = 'my-project-id'; + // const instanceId = 'my-instance-id'; + // const databaseId = 'my-database-id'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + // Gets a reference to a Cloud Spanner instance and a database. The database does not need to exist. + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + async function dropForeignKeyConstraintDeleteCascade() { + const [operation] = await database.updateSchema([ + `ALTER TABLE ShoppingCarts + DROP CONSTRAINT FKShoppingCartsCustomerName`, + ]); + + console.log(`Waiting for operation on ${databaseId} to complete...`); + await operation.promise(); + + console.log( + 'Altered ShoppingCarts table to drop FKShoppingCartsCustomerName' + ); + } + dropForeignKeyConstraintDeleteCascade(); + // [END spanner_drop_foreign_key_constraint_delete_cascade] +} +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); From bb5a8a562ec6611f50481044be8d7b1a971bb6e3 Mon Sep 17 00:00:00 2001 From: surbhigarg92 Date: Thu, 16 Mar 2023 17:22:41 +0530 Subject: [PATCH 3/7] feat: fkadc tests --- system-test/spanner.ts | 119 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/system-test/spanner.ts b/system-test/spanner.ts index 1eba82beb..b8c6cd452 100644 --- a/system-test/spanner.ts +++ b/system-test/spanner.ts @@ -86,7 +86,7 @@ describe('Spanner', () => { : spanner.instance(generateName('instance')); const INSTANCE_CONFIG = { - config: 'regional-us-west2', + config: 'regional-us-central1', nodes: 1, labels: { [LABEL]: 'true', @@ -2635,6 +2635,123 @@ describe('Spanner', () => { ); } }); + + const insertAndDeleteInSameTransactionErrorWithFKADC = ( + done, + database + ) => { + database.runTransaction((err, transaction) => { + assert.ifError(err); + transaction!.insert('Customers', { + CustomerId: 2, + CustomerName: 'John', + }); + transaction!.deleteRows('Customers', [2]); + transaction!.commit(err => { + assert.match( + (err as grpc.ServiceError).message.toLowerCase(), + /9 failed_precondition: cannot write a value for the referenced column `customers.customerid` and delete it in the same transaction\./ + ); + done(); + }); + }); + }; + + it('GOOGLE_STANDARD_SQL should throw error when insert and delete a referenced key', done => { + insertAndDeleteInSameTransactionErrorWithFKADC(done, fkadc_database); + }); + + it('POSTGRESQL should throw error when insert and delete a referenced key', function (done) { + if (IS_EMULATOR_ENABLED) { + this.skip(); + } + insertAndDeleteInSameTransactionErrorWithFKADC(done, fkadc_database_pg); + }); + + const insertReferencingKeyAndDeleteReferencedKeyErrorWithFKADC = ( + done, + database + ) => { + const customersTable = database.table('Customers'); + customersTable.insert( + { + CustomerId: 2, + CustomerName: 'Marc', + }, + err => { + assert.ifError(err); + database.runTransaction((err, transaction) => { + assert.ifError(err); + transaction!.insert('ShoppingCarts', { + CartId: 3, + CustomerId: 2, + CustomerName: 'Marc', + }); + transaction!.deleteRows('Customers', [2]); + transaction!.commit(err => { + assert.strictEqual( + (err as grpc.ServiceError).message.toLowerCase(), + '9 failed_precondition: foreign key constraint `fkshoppingcartscustomerid` is violated on table `shoppingcarts`. cannot find referenced values in customers(customerid).' + ); + done(); + }); + }); + } + ); + }; + + it('GOOGLE_STANDARD_SQL should throw error when insert a referencing key and delete a referenced key', done => { + insertReferencingKeyAndDeleteReferencedKeyErrorWithFKADC( + done, + fkadc_database + ); + }); + + it('POSTGRESQL should throw error when insert a referencing key and delete a referenced key', function (done) { + if (IS_EMULATOR_ENABLED) { + this.skip(); + } + insertReferencingKeyAndDeleteReferencedKeyErrorWithFKADC( + done, + fkadc_database_pg + ); + }); + + const deleteRuleOnInformationSchemaReferentialConstraints = ( + done, + database + ) => { + database.getSnapshot((err, transaction) => { + assert.ifError(err); + + transaction!.run( + "SELECT DELETE_RULE FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME = 'FKShoppingCartsCustomerId'", + (err, rows) => { + assert.ifError(err); + assert.strictEqual(rows[0][0].value, 'CASCADE'); + transaction!.end(); + done(); + } + ); + }); + }; + + it('GOOGLE_STANDARD_SQL should test information schema referential constraints', done => { + deleteRuleOnInformationSchemaReferentialConstraints( + done, + fkadc_database + ); + }); + + it('POSTGRESQL should test information schema referential constraints', function (done) { + if (IS_EMULATOR_ENABLED) { + this.skip(); + } + deleteRuleOnInformationSchemaReferentialConstraints( + done, + fkadc_database_pg + ); + }); }); }); From 5aac510b4b1199b1326ba054d7937801aaa5f2a4 Mon Sep 17 00:00:00 2001 From: surbhigarg92 Date: Tue, 21 Mar 2023 22:06:47 +0530 Subject: [PATCH 4/7] fix: test case --- system-test/spanner.ts | 53 ++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/system-test/spanner.ts b/system-test/spanner.ts index b8c6cd452..add6bd15d 100644 --- a/system-test/spanner.ts +++ b/system-test/spanner.ts @@ -2673,29 +2673,46 @@ describe('Spanner', () => { database ) => { const customersTable = database.table('Customers'); + const cartsTable = database.table('ShoppingCarts'); customersTable.insert( - { - CustomerId: 2, - CustomerName: 'Marc', - }, + [ + { + CustomerId: 2, + CustomerName: 'Marc', + }, + { + CustomerId: 3, + CustomerName: 'John', + }, + ], err => { assert.ifError(err); - database.runTransaction((err, transaction) => { - assert.ifError(err); - transaction!.insert('ShoppingCarts', { - CartId: 3, + cartsTable.insert( + { + CartId: 2, CustomerId: 2, CustomerName: 'Marc', - }); - transaction!.deleteRows('Customers', [2]); - transaction!.commit(err => { - assert.strictEqual( - (err as grpc.ServiceError).message.toLowerCase(), - '9 failed_precondition: foreign key constraint `fkshoppingcartscustomerid` is violated on table `shoppingcarts`. cannot find referenced values in customers(customerid).' - ); - done(); - }); - }); + }, + err => { + assert.ifError(err); + database.runTransaction((err, transaction) => { + assert.ifError(err); + transaction!.update('ShoppingCarts', { + CartId: 2, + CustomerId: 3, + CustomerName: 'John', + }); + transaction!.deleteRows('Customers', [2]); + transaction!.commit(err => { + assert.match( + (err as grpc.ServiceError).message.toLowerCase(), + /9 failed_precondition: cannot modify a row in the table `shoppingcarts` because a referential action is deleting it in the same transaction\./ + ); + done(); + }); + }); + } + ); } ); }; From c25954587f7cedfd504c79cc90ace5de16604968 Mon Sep 17 00:00:00 2001 From: surbhigarg92 Date: Thu, 20 Jul 2023 09:07:36 +0000 Subject: [PATCH 5/7] fix: Disable FKADC tests for Emulator --- system-test/spanner.ts | 41 +++++++++++++---------------------------- 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/system-test/spanner.ts b/system-test/spanner.ts index 6eafe9e70..30983c1a8 100644 --- a/system-test/spanner.ts +++ b/system-test/spanner.ts @@ -2566,6 +2566,12 @@ describe('Spanner', () => { }); describe('ForeignKeyDeleteCascadeAction', () => { + before(async function () { + if (IS_EMULATOR_ENABLED) { + this.skip(); + } + }); + const fkadc_database_id = generateName('fkadc'); const fkadc_database_pg_id = generateName('fkadc-pg'); const fkadc_database = instance.database(fkadc_database_id); @@ -2631,10 +2637,7 @@ describe('Spanner', () => { ); }); - it('POSTGRESQL should create a database with foreign key delete cascade action', async function () { - if (IS_EMULATOR_ENABLED) { - this.skip(); - } + it('POSTGRESQL should create a database with foreign key delete cascade action', async () => { await createDatabaseWithFKADC( Spanner.POSTGRESQL, fkadc_database_pg_id, @@ -2682,10 +2685,7 @@ describe('Spanner', () => { ); }); - it('POSTGRESQL should alter a database with foreign key delete cascade action', async function () { - if (IS_EMULATOR_ENABLED) { - this.skip(); - } + it('POSTGRESQL should alter a database with foreign key delete cascade action', async () => { await alterDatabaseWithFKADC(Spanner.POSTGRESQL, fkadc_database_pg); }); @@ -2719,10 +2719,7 @@ describe('Spanner', () => { await insertAndDeleteRowWithFKADC(fkadc_database); }); - it('POSTGRESQL should insert a row and then delete with all references', async function () { - if (IS_EMULATOR_ENABLED) { - this.skip(); - } + it('POSTGRESQL should insert a row and then delete with all references', async () => { await insertAndDeleteRowWithFKADC(fkadc_database_pg); }); @@ -2746,10 +2743,7 @@ describe('Spanner', () => { } }); - it('POSTGRESQL should throw error when insert a row without reference', async function () { - if (IS_EMULATOR_ENABLED) { - this.skip(); - } + it('POSTGRESQL should throw error when insert a row without reference', async () => { try { await insertRowErrorWithFKADC(fkadc_database_pg); } catch (err) { @@ -2785,10 +2779,7 @@ describe('Spanner', () => { insertAndDeleteInSameTransactionErrorWithFKADC(done, fkadc_database); }); - it('POSTGRESQL should throw error when insert and delete a referenced key', function (done) { - if (IS_EMULATOR_ENABLED) { - this.skip(); - } + it('POSTGRESQL should throw error when insert and delete a referenced key', done => { insertAndDeleteInSameTransactionErrorWithFKADC(done, fkadc_database_pg); }); @@ -2848,10 +2839,7 @@ describe('Spanner', () => { ); }); - it('POSTGRESQL should throw error when insert a referencing key and delete a referenced key', function (done) { - if (IS_EMULATOR_ENABLED) { - this.skip(); - } + it('POSTGRESQL should throw error when insert a referencing key and delete a referenced key', done => { insertReferencingKeyAndDeleteReferencedKeyErrorWithFKADC( done, fkadc_database_pg @@ -2884,10 +2872,7 @@ describe('Spanner', () => { ); }); - it('POSTGRESQL should test information schema referential constraints', function (done) { - if (IS_EMULATOR_ENABLED) { - this.skip(); - } + it('POSTGRESQL should test information schema referential constraints', done => { deleteRuleOnInformationSchemaReferentialConstraints( done, fkadc_database_pg From c4391a10d614f9430f25c04931da33147ffa5496 Mon Sep 17 00:00:00 2001 From: surbhigarg92 Date: Fri, 21 Jul 2023 14:46:19 +0530 Subject: [PATCH 6/7] fix: samples --- samples/system-test/spanner.test.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/samples/system-test/spanner.test.js b/samples/system-test/spanner.test.js index 3c9a43110..c632af347 100644 --- a/samples/system-test/spanner.test.js +++ b/samples/system-test/spanner.test.js @@ -1383,7 +1383,9 @@ describe('Spanner', () => { ); assert.match( output, - 'Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId' + new RegExp( + 'Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId' + ) ); }); @@ -1397,7 +1399,7 @@ describe('Spanner', () => { ); assert.match( output, - 'Altered ShoppingCarts table with FKShoppingCartsCustomerName' + new RegExp('Altered ShoppingCarts table with FKShoppingCartsCustomerName') ); }); @@ -1411,7 +1413,9 @@ describe('Spanner', () => { ); assert.match( output, - 'Altered ShoppingCarts table to drop FKShoppingCartsCustomerName' + new RegExp( + 'Altered ShoppingCarts table to drop FKShoppingCartsCustomerName' + ) ); }); From c9718b5a890e6fab9fa9c30e23be416a4a44273d Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Fri, 21 Jul 2023 10:52:34 +0000 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot=20po?= =?UTF-8?q?st-processor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- README.md | 3 +++ samples/README.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/README.md b/README.md index 9769833c7..409451fa6 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,9 @@ Samples are in the [`samples/`](https://github.com/googleapis/nodejs-spanner/tre | Run transaction with RPC priority | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/rpc-priority-transaction.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/rpc-priority-transaction.js,samples/README.md) | | Schema | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/schema.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/schema.js,samples/README.md) | | Struct | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/struct.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/struct.js,samples/README.md) | +| Alters a table with foreign key delete cascade action | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-alter-with-foreign-key-delete-cascade.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/table-alter-with-foreign-key-delete-cascade.js,samples/README.md) | +| Creates a table with foreign key delete cascade action | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-create-with-foreign-key-delete-cascade.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/table-create-with-foreign-key-delete-cascade.js,samples/README.md) | +| Drops a foreign key constraint with delete cascade action | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-drop-foreign-key-constraint-delete-cascade.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/table-drop-foreign-key-constraint-delete-cascade.js,samples/README.md) | | Timestamp | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/timestamp.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/timestamp.js,samples/README.md) | | Executes a read/write transaction with transaction and request tags | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/transaction-tag.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/transaction-tag.js,samples/README.md) | | Transaction | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/transaction.js) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/transaction.js,samples/README.md) | diff --git a/samples/README.md b/samples/README.md index 66dddee2c..7cbe6dc2f 100644 --- a/samples/README.md +++ b/samples/README.md @@ -98,6 +98,9 @@ and automatic, synchronous replication for high availability. * [Run transaction with RPC priority](#run-transaction-with-rpc-priority) * [Schema](#schema) * [Struct](#struct) + * [Alters a table with foreign key delete cascade action](#alters-a-table-with-foreign-key-delete-cascade-action) + * [Creates a table with foreign key delete cascade action](#creates-a-table-with-foreign-key-delete-cascade-action) + * [Drops a foreign key constraint with delete cascade action](#drops-a-foreign-key-constraint-with-delete-cascade-action) * [Timestamp](#timestamp) * [Executes a read/write transaction with transaction and request tags](#executes-a-read/write-transaction-with-transaction-and-request-tags) * [Transaction](#transaction) @@ -1545,6 +1548,57 @@ __Usage:__ +### Alters a table with foreign key delete cascade action + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-alter-with-foreign-key-delete-cascade.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/table-alter-with-foreign-key-delete-cascade.js,samples/README.md) + +__Usage:__ + + +`node table-alter-with-foreign-key-delete-cascade.js ` + + +----- + + + + +### Creates a table with foreign key delete cascade action + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-create-with-foreign-key-delete-cascade.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/table-create-with-foreign-key-delete-cascade.js,samples/README.md) + +__Usage:__ + + +`node table-create-with-foreign-key-delete-cascade.js.js ` + + +----- + + + + +### Drops a foreign key constraint with delete cascade action + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-drop-foreign-key-constraint-delete-cascade.js). + +[![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/nodejs-spanner&page=editor&open_in_editor=samples/table-drop-foreign-key-constraint-delete-cascade.js,samples/README.md) + +__Usage:__ + + +`node table-drop-foreign-key-constraint-delete-cascade.js ` + + +----- + + + + ### Timestamp View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/timestamp.js).