Skip to content

Commit 74a54b0

Browse files
authored
feat: foreign key delete cascade testing, samples (#1825)
1 parent 1ff14d8 commit 74a54b0

File tree

7 files changed

+624
-1
lines changed

7 files changed

+624
-1
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ Samples are in the [`samples/`](https://github.com/googleapis/nodejs-spanner/tre
173173
| 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) |
174174
| 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) |
175175
| 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) |
176+
| 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) |
177+
| 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) |
178+
| 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) |
176179
| 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) |
177180
| 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) |
178181
| 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) |

samples/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ and automatic, synchronous replication for high availability.
9898
* [Run transaction with RPC priority](#run-transaction-with-rpc-priority)
9999
* [Schema](#schema)
100100
* [Struct](#struct)
101+
* [Alters a table with foreign key delete cascade action](#alters-a-table-with-foreign-key-delete-cascade-action)
102+
* [Creates a table with foreign key delete cascade action](#creates-a-table-with-foreign-key-delete-cascade-action)
103+
* [Drops a foreign key constraint with delete cascade action](#drops-a-foreign-key-constraint-with-delete-cascade-action)
101104
* [Timestamp](#timestamp)
102105
* [Executes a read/write transaction with transaction and request tags](#executes-a-read/write-transaction-with-transaction-and-request-tags)
103106
* [Transaction](#transaction)
@@ -1545,6 +1548,57 @@ __Usage:__
15451548

15461549

15471550

1551+
### Alters a table with foreign key delete cascade action
1552+
1553+
View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-alter-with-foreign-key-delete-cascade.js).
1554+
1555+
[![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)
1556+
1557+
__Usage:__
1558+
1559+
1560+
`node table-alter-with-foreign-key-delete-cascade.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID>`
1561+
1562+
1563+
-----
1564+
1565+
1566+
1567+
1568+
### Creates a table with foreign key delete cascade action
1569+
1570+
View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-create-with-foreign-key-delete-cascade.js).
1571+
1572+
[![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)
1573+
1574+
__Usage:__
1575+
1576+
1577+
`node table-create-with-foreign-key-delete-cascade.js.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID>`
1578+
1579+
1580+
-----
1581+
1582+
1583+
1584+
1585+
### Drops a foreign key constraint with delete cascade action
1586+
1587+
View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/table-drop-foreign-key-constraint-delete-cascade.js).
1588+
1589+
[![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)
1590+
1591+
__Usage:__
1592+
1593+
1594+
`node table-drop-foreign-key-constraint-delete-cascade.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID>`
1595+
1596+
1597+
-----
1598+
1599+
1600+
1601+
15481602
### Timestamp
15491603

15501604
View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/timestamp.js).

samples/system-test/spanner.test.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ const dmlCmd = 'node dml.js';
4343
const datatypesCmd = 'node datatypes.js';
4444
const backupsCmd = 'node backups.js';
4545
const instanceCmd = 'node instance.js';
46+
const createTableWithForeignKeyDeleteCascadeCommand =
47+
'node table-create-with-foreign-key-delete-cascade.js';
48+
const alterTableWithForeignKeyDeleteCascadeCommand =
49+
'node table-alter-with-foreign-key-delete-cascade.js';
50+
const dropForeignKeyConstraintDeleteCascaseCommand =
51+
'node table-drop-foreign-key-constraint-delete-cascade.js';
4652

4753
const CURRENT_TIME = Math.round(Date.now() / 1000).toString();
4854
const PROJECT_ID = process.env.GCLOUD_PROJECT;
@@ -1367,6 +1373,52 @@ describe('Spanner', () => {
13671373
assert.include(output, 'Earliest version time:');
13681374
});
13691375

1376+
it('should create a table with foreign key delete cascade', async () => {
1377+
const output = execSync(
1378+
`${createTableWithForeignKeyDeleteCascadeCommand} "${INSTANCE_ID}" "${DATABASE_ID}" ${PROJECT_ID}`
1379+
);
1380+
assert.match(
1381+
output,
1382+
new RegExp(`Waiting for operation on ${DATABASE_ID} to complete...`)
1383+
);
1384+
assert.match(
1385+
output,
1386+
new RegExp(
1387+
'Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId'
1388+
)
1389+
);
1390+
});
1391+
1392+
it('should alter a table with foreign key delete cascade', async () => {
1393+
const output = execSync(
1394+
`${alterTableWithForeignKeyDeleteCascadeCommand} "${INSTANCE_ID}" "${DATABASE_ID}" ${PROJECT_ID}`
1395+
);
1396+
assert.match(
1397+
output,
1398+
new RegExp(`Waiting for operation on ${DATABASE_ID} to complete...`)
1399+
);
1400+
assert.match(
1401+
output,
1402+
new RegExp('Altered ShoppingCarts table with FKShoppingCartsCustomerName')
1403+
);
1404+
});
1405+
1406+
it('should drop a foreign key constraint delete cascade', async () => {
1407+
const output = execSync(
1408+
`${dropForeignKeyConstraintDeleteCascaseCommand} "${INSTANCE_ID}" "${DATABASE_ID}" ${PROJECT_ID}`
1409+
);
1410+
assert.match(
1411+
output,
1412+
new RegExp(`Waiting for operation on ${DATABASE_ID} to complete...`)
1413+
);
1414+
assert.match(
1415+
output,
1416+
new RegExp(
1417+
'Altered ShoppingCarts table to drop FKShoppingCartsCustomerName'
1418+
)
1419+
);
1420+
});
1421+
13701422
describe('leader options', () => {
13711423
before(async () => {
13721424
const instance = spanner.instance(SAMPLE_INSTANCE_ID);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// sample-metadata:
16+
// title: Alters a table with foreign key delete cascade action
17+
// usage: node table-alter-with-foreign-key-delete-cascade.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID>
18+
19+
'use strict';
20+
21+
function main(instanceId, databaseId, projectId) {
22+
// [START spanner_alter_table_with_foreign_key_delete_cascade]
23+
24+
// Imports the Google Cloud client library
25+
const {Spanner} = require('@google-cloud/spanner');
26+
27+
/**
28+
* TODO(developer): Uncomment the following lines before running the sample.
29+
*/
30+
// const projectId = 'my-project-id';
31+
// const instanceId = 'my-instance-id';
32+
// const databaseId = 'my-database-id';
33+
34+
// Creates a client
35+
const spanner = new Spanner({
36+
projectId: projectId,
37+
});
38+
39+
// Gets a reference to a Cloud Spanner instance and a database. The database does not need to exist.
40+
const instance = spanner.instance(instanceId);
41+
const database = instance.database(databaseId);
42+
43+
async function alterTableWithForeignKeyDeleteCascade() {
44+
const [operation] = await database.updateSchema([
45+
`ALTER TABLE ShoppingCarts
46+
ADD CONSTRAINT FKShoppingCartsCustomerName
47+
FOREIGN KEY (CustomerName)
48+
REFERENCES Customers(CustomerName)
49+
ON DELETE CASCADE`,
50+
]);
51+
52+
console.log(`Waiting for operation on ${databaseId} to complete...`);
53+
await operation.promise();
54+
55+
console.log('Altered ShoppingCarts table with FKShoppingCartsCustomerName');
56+
}
57+
alterTableWithForeignKeyDeleteCascade();
58+
// [END spanner_alter_table_with_foreign_key_delete_cascade]
59+
}
60+
process.on('unhandledRejection', err => {
61+
console.error(err.message);
62+
process.exitCode = 1;
63+
});
64+
main(...process.argv.slice(2));
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// sample-metadata:
16+
// title: Creates a table with foreign key delete cascade action
17+
// usage: node table-create-with-foreign-key-delete-cascade.js.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID>
18+
19+
'use strict';
20+
21+
function main(instanceId, databaseId, projectId) {
22+
// [START spanner_create_table_with_foreign_key_delete_cascade]
23+
24+
// Imports the Google Cloud client library
25+
const {Spanner} = require('@google-cloud/spanner');
26+
27+
/**
28+
* TODO(developer): Uncomment the following lines before running the sample.
29+
*/
30+
// const projectId = 'my-project-id';
31+
// const instanceId = 'my-instance-id';
32+
// const databaseId = 'my-database-id';
33+
34+
// Creates a client
35+
const spanner = new Spanner({
36+
projectId: projectId,
37+
});
38+
39+
// Gets a reference to a Cloud Spanner instance and a database. The database does not need to exist.
40+
const instance = spanner.instance(instanceId);
41+
const database = instance.database(databaseId);
42+
43+
async function createTableWithForeignKeyDeleteCascade() {
44+
const [operation] = await database.updateSchema([
45+
`CREATE TABLE Customers (
46+
CustomerId INT64,
47+
CustomerName STRING(62) NOT NULL
48+
) PRIMARY KEY (CustomerId)`,
49+
`CREATE TABLE ShoppingCarts (
50+
CartId INT64 NOT NULL,
51+
CustomerId INT64 NOT NULL,
52+
CustomerName STRING(62) NOT NULL,
53+
CONSTRAINT FKShoppingCartsCustomerId FOREIGN KEY (CustomerId)
54+
REFERENCES Customers (CustomerId) ON DELETE CASCADE,
55+
) PRIMARY KEY (CartId)`,
56+
]);
57+
58+
console.log(`Waiting for operation on ${databaseId} to complete...`);
59+
await operation.promise();
60+
61+
console.log(
62+
'Created Customers and ShoppingCarts table with FKShoppingCartsCustomerId'
63+
);
64+
}
65+
createTableWithForeignKeyDeleteCascade();
66+
// [END spanner_create_table_with_foreign_key_delete_cascade]
67+
}
68+
process.on('unhandledRejection', err => {
69+
console.error(err.message);
70+
process.exitCode = 1;
71+
});
72+
main(...process.argv.slice(2));
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// sample-metadata:
16+
// title: Drops a foreign key constraint with delete cascade action
17+
// usage: node table-drop-foreign-key-constraint-delete-cascade.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID>
18+
19+
'use strict';
20+
21+
function main(instanceId, databaseId, projectId) {
22+
// [START spanner_drop_foreign_key_constraint_delete_cascade]
23+
24+
// Imports the Google Cloud client library
25+
const {Spanner} = require('@google-cloud/spanner');
26+
27+
/**
28+
* TODO(developer): Uncomment the following lines before running the sample.
29+
*/
30+
// const projectId = 'my-project-id';
31+
// const instanceId = 'my-instance-id';
32+
// const databaseId = 'my-database-id';
33+
34+
// Creates a client
35+
const spanner = new Spanner({
36+
projectId: projectId,
37+
});
38+
39+
// Gets a reference to a Cloud Spanner instance and a database. The database does not need to exist.
40+
const instance = spanner.instance(instanceId);
41+
const database = instance.database(databaseId);
42+
43+
async function dropForeignKeyConstraintDeleteCascade() {
44+
const [operation] = await database.updateSchema([
45+
`ALTER TABLE ShoppingCarts
46+
DROP CONSTRAINT FKShoppingCartsCustomerName`,
47+
]);
48+
49+
console.log(`Waiting for operation on ${databaseId} to complete...`);
50+
await operation.promise();
51+
52+
console.log(
53+
'Altered ShoppingCarts table to drop FKShoppingCartsCustomerName'
54+
);
55+
}
56+
dropForeignKeyConstraintDeleteCascade();
57+
// [END spanner_drop_foreign_key_constraint_delete_cascade]
58+
}
59+
process.on('unhandledRejection', err => {
60+
console.error(err.message);
61+
process.exitCode = 1;
62+
});
63+
main(...process.argv.slice(2));

0 commit comments

Comments
 (0)