diff --git a/README.md b/README.md index 409451fa6..deb371683 100644 --- a/README.md +++ b/README.md @@ -161,6 +161,9 @@ Samples are in the [`samples/`](https://github.com/googleapis/nodejs-spanner/tre | Showcases how a Spanner PostgreSQL database orders null values in a query. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-ordering-nulls.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/pg-ordering-nulls.js,samples/README.md) | | Execute a query with parameters on a Spanner PostgreSQL database. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-query-parameter.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/pg-query-parameter.js,samples/README.md) | | Query the information schema metadata in a Spanner PostgreSQL database. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-schema-information.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/pg-schema-information.js,samples/README.md) | +| Alters a sequence in a PostgreSQL database. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-sequence-alter.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/pg-sequence-alter.js,samples/README.md) | +| Creates sequence in PostgreSQL database. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-sequence-create.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/pg-sequence-create.js,samples/README.md) | +| Drops a sequence in PostgreSQL database. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-sequence-drop.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/pg-sequence-drop.js,samples/README.md) | | Queryoptions | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/queryoptions.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/queryoptions.js,samples/README.md) | | Quickstart | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/quickstart.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/quickstart.js,samples/README.md) | | Read data with database role | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/read-data-with-database-role.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/read-data-with-database-role.js,samples/README.md) | @@ -172,6 +175,9 @@ Samples are in the [`samples/`](https://github.com/googleapis/nodejs-spanner/tre | Query data with RPC Priority | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/rpc-priority-run.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-run.js,samples/README.md) | | 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) | +| Alters a sequence in a GoogleSQL database. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/sequence-alter.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/sequence-alter.js,samples/README.md) | +| Creates sequence in GoogleSQL database. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/sequence-create.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/sequence-create.js,samples/README.md) | +| Drops a sequence in GoogleSQL database. | [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/sequence-drop.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/sequence-drop.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) | diff --git a/samples/README.md b/samples/README.md index 7cbe6dc2f..5c15b0c31 100644 --- a/samples/README.md +++ b/samples/README.md @@ -86,6 +86,9 @@ and automatic, synchronous replication for high availability. * [Showcases how a Spanner PostgreSQL database orders null values in a query.](#showcases-how-a-spanner-postgresql-database-orders-null-values-in-a-query.) * [Execute a query with parameters on a Spanner PostgreSQL database.](#execute-a-query-with-parameters-on-a-spanner-postgresql-database.) * [Query the information schema metadata in a Spanner PostgreSQL database.](#query-the-information-schema-metadata-in-a-spanner-postgresql-database.) + * [Alters a sequence in a PostgreSQL database.](#alters-a-sequence-in-a-postgresql-database.) + * [Creates sequence in PostgreSQL database.](#creates-sequence-in-postgresql-database.) + * [Drops a sequence in PostgreSQL database.](#drops-a-sequence-in-postgresql-database.) * [Queryoptions](#queryoptions) * [Quickstart](#quickstart) * [Read data with database role](#read-data-with-database-role) @@ -97,6 +100,9 @@ and automatic, synchronous replication for high availability. * [Query data with RPC Priority](#query-data-with-rpc-priority) * [Run transaction with RPC priority](#run-transaction-with-rpc-priority) * [Schema](#schema) + * [Alters a sequence in a GoogleSQL database.](#alters-a-sequence-in-a-googlesql-database.) + * [Creates sequence in GoogleSQL database.](#creates-sequence-in-googlesql-database.) + * [Drops a sequence in GoogleSQL database.](#drops-a-sequence-in-googlesql-database.) * [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) @@ -1344,6 +1350,57 @@ __Usage:__ +### Alters a sequence in a PostgreSQL database. + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-sequence-alter.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/pg-sequence-alter.js,samples/README.md) + +__Usage:__ + + +`node pg-sequence-alter.js ` + + +----- + + + + +### Creates sequence in PostgreSQL database. + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-sequence-create.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/pg-sequence-create.js,samples/README.md) + +__Usage:__ + + +`node pg-sequence-create.js ` + + +----- + + + + +### Drops a sequence in PostgreSQL database. + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/pg-sequence-drop.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/pg-sequence-drop.js,samples/README.md) + +__Usage:__ + + +`node pg-sequence-drop.js ` + + +----- + + + + ### Queryoptions View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/queryoptions.js). @@ -1531,6 +1588,57 @@ __Usage:__ +### Alters a sequence in a GoogleSQL database. + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/sequence-alter.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/sequence-alter.js,samples/README.md) + +__Usage:__ + + +`node sequence-alter.js ` + + +----- + + + + +### Creates sequence in GoogleSQL database. + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/sequence-create.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/sequence-create.js,samples/README.md) + +__Usage:__ + + +`node sequence-create.js ` + + +----- + + + + +### Drops a sequence in GoogleSQL database. + +View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/sequence-drop.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/sequence-drop.js,samples/README.md) + +__Usage:__ + + +`node sequence-drop.js ` + + +----- + + + + ### Struct View the [source code](https://github.com/googleapis/nodejs-spanner/blob/main/samples/struct.js). diff --git a/samples/pg-sequence-alter.js b/samples/pg-sequence-alter.js new file mode 100644 index 000000000..9992cb3b5 --- /dev/null +++ b/samples/pg-sequence-alter.js @@ -0,0 +1,95 @@ +// 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 sequence in a PostgreSQL database. +// usage: node pg-sequence-alter.js + +'use strict'; + +async function main(instanceId, databaseId, projectId) { + // [START spanner_postgresql_alter_sequence] + // 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'; + // const databaseId = 'my-database'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + async function alterSequence(instanceId, databaseId) { + // Gets a reference to a Cloud Spanner instance and database + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + const request = ['ALTER SEQUENCE Seq SKIP RANGE 1000 5000000']; + + try { + const [operation] = await database.updateSchema(request); + + console.log('Waiting for operation to complete...'); + await operation.promise(); + + console.log( + 'Altered Seq sequence to skip an inclusive range between 1000 and 5000000.' + ); + } catch (err) { + console.error('ERROR:', err); + } + database.runTransaction(async (err, transaction) => { + if (err) { + console.error(err); + return; + } + try { + const [rows, stats] = await transaction.run({ + sql: "INSERT INTO Customers (CustomerName) VALUES ('Lea'), ('Catalina'), ('Smith') RETURNING CustomerId", + }); + + rows.forEach(row => { + console.log( + `Inserted customer record with CustomerId: ${ + row.toJSON({wrapNumbers: true}).customerid.value + }` + ); + }); + + const rowCount = Math.floor(stats[stats.rowCount]); + console.log(`Number of customer records inserted is: ${rowCount}`); + + await transaction.commit(); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } + }); + } + await alterSequence(instanceId, databaseId); + // [END spanner_postgresql_alter_sequence] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/pg-sequence-create.js b/samples/pg-sequence-create.js new file mode 100644 index 000000000..4b3077d7d --- /dev/null +++ b/samples/pg-sequence-create.js @@ -0,0 +1,99 @@ +// 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 sequence in PostgreSQL database. +// usage: node pg-sequence-create.js + +'use strict'; + +async function main(instanceId, databaseId, projectId) { + // [START spanner_postgresql_create_sequence] + // 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'; + // const databaseId = 'my-database'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + async function createSequence(instanceId, databaseId) { + // Gets a reference to a Cloud Spanner instance and database + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + const request = [ + 'CREATE SEQUENCE Seq BIT_REVERSED_POSITIVE', + "CREATE TABLE Customers (CustomerId BIGINT DEFAULT nextval('Seq'), CustomerName character varying(1024), PRIMARY KEY (CustomerId))", + ]; + + // Creates a new table with sequence + try { + const [operation] = await database.updateSchema(request); + + console.log('Waiting for operation to complete...'); + await operation.promise(); + + console.log( + 'Created Seq sequence and Customers table, where the key column CustomerId uses the sequence as a default value' + ); + } catch (err) { + console.error('ERROR:', err); + } + database.runTransaction(async (err, transaction) => { + if (err) { + console.error(err); + return; + } + try { + const [rows, stats] = await transaction.run({ + sql: "INSERT INTO Customers (CustomerName) VALUES ('Alice'), ('David'), ('Marc') RETURNING CustomerId", + }); + + rows.forEach(row => { + console.log( + `Inserted customer record with CustomerId: ${ + row.toJSON({wrapNumbers: true}).customerid.value + }` + ); + }); + + const rowCount = Math.floor(stats[stats.rowCount]); + console.log(`Number of customer records inserted is: ${rowCount}`); + + await transaction.commit(); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } + }); + } + await createSequence(instanceId, databaseId); + // [END spanner_postgresql_create_sequence] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/pg-sequence-drop.js b/samples/pg-sequence-drop.js new file mode 100644 index 000000000..3cdbfb1f2 --- /dev/null +++ b/samples/pg-sequence-drop.js @@ -0,0 +1,73 @@ +// 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 sequence in PostgreSQL database. +// usage: node pg-sequence-drop.js + +'use strict'; + +async function main(instanceId, databaseId, projectId) { + // [START spanner_drop_sequence] + // 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'; + // const databaseId = 'my-database'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + async function dropSequence(instanceId, databaseId) { + // Gets a reference to a Cloud Spanner instance and database + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + const request = [ + 'ALTER TABLE Customers ALTER COLUMN CustomerId DROP DEFAULT', + 'DROP SEQUENCE Seq', + ]; + + // Drop sequence from DDL + try { + const [operation] = await database.updateSchema(request); + + console.log('Waiting for operation to complete...'); + await operation.promise(); + + console.log( + 'Altered Customers table to drop DEFAULT from CustomerId column and dropped the Seq sequence.' + ); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } + } + await dropSequence(instanceId, databaseId); + // [END spanner_drop_sequence] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/sequence-alter.js b/samples/sequence-alter.js new file mode 100644 index 000000000..1fe9a64e7 --- /dev/null +++ b/samples/sequence-alter.js @@ -0,0 +1,97 @@ +// 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 sequence in a GoogleSQL database. +// usage: node sequence-alter.js + +'use strict'; + +async function main(instanceId, databaseId, projectId) { + // [START spanner_alter_sequence] + // 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'; + // const databaseId = 'my-database'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + async function alterSequence(instanceId, databaseId) { + // Gets a reference to a Cloud Spanner instance and database + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + const request = [ + 'ALTER SEQUENCE Seq SET OPTIONS (skip_range_min = 1000, skip_range_max = 5000000)', + ]; + + try { + const [operation] = await database.updateSchema(request); + + console.log('Waiting for operation to complete...'); + await operation.promise(); + + console.log( + 'Altered Seq sequence to skip an inclusive range between 1000 and 5000000.' + ); + } catch (err) { + console.error('ERROR:', err); + } + database.runTransaction(async (err, transaction) => { + if (err) { + console.error(err); + return; + } + try { + const [rows, stats] = await transaction.run({ + sql: "INSERT INTO Customers (CustomerName) VALUES ('Lea'), ('Catalina'), ('Smith') THEN RETURN CustomerId", + }); + + rows.forEach(row => { + console.log( + `Inserted customer record with CustomerId: ${ + row.toJSON({wrapNumbers: true}).CustomerId.value + }` + ); + }); + + const rowCount = Math.floor(stats[stats.rowCount]); + console.log(`Number of customer records inserted is: ${rowCount}`); + + await transaction.commit(); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } + }); + } + await alterSequence(instanceId, databaseId); + // [END spanner_alter_sequence] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/sequence-create.js b/samples/sequence-create.js new file mode 100644 index 000000000..643440e8d --- /dev/null +++ b/samples/sequence-create.js @@ -0,0 +1,99 @@ +// 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 sequence in GoogleSQL database. +// usage: node sequence-create.js + +'use strict'; + +async function main(instanceId, databaseId, projectId) { + // [START spanner_create_sequence] + // 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'; + // const databaseId = 'my-database'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + async function createSequence(instanceId, databaseId) { + // Gets a reference to a Cloud Spanner instance and database + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + const request = [ + "CREATE SEQUENCE Seq OPTIONS (sequence_kind = 'bit_reversed_positive')", + 'CREATE TABLE Customers (CustomerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(Sequence Seq)), CustomerName STRING(1024)) PRIMARY KEY (CustomerId)', + ]; + + // Creates a new table with sequence + try { + const [operation] = await database.updateSchema(request); + + console.log('Waiting for operation to complete...'); + await operation.promise(); + + console.log( + 'Created Seq sequence and Customers table, where the key column CustomerId uses the sequence as a default value.' + ); + } catch (err) { + console.error('ERROR:', err); + } + database.runTransaction(async (err, transaction) => { + if (err) { + console.error(err); + return; + } + try { + const [rows, stats] = await transaction.run({ + sql: "INSERT INTO Customers (CustomerName) VALUES ('Alice'), ('David'), ('Marc') THEN RETURN CustomerId", + }); + + rows.forEach(row => { + console.log( + `Inserted customer record with CustomerId: ${ + row.toJSON({wrapNumbers: true}).CustomerId.value + }` + ); + }); + + const rowCount = Math.floor(stats[stats.rowCount]); + console.log(`Number of customer records inserted is: ${rowCount}`); + + await transaction.commit(); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } + }); + } + await createSequence(instanceId, databaseId); + // [END spanner_create_sequence] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/sequence-drop.js b/samples/sequence-drop.js new file mode 100644 index 000000000..513b112d3 --- /dev/null +++ b/samples/sequence-drop.js @@ -0,0 +1,73 @@ +// 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 sequence in GoogleSQL database. +// usage: node sequence-drop.js + +'use strict'; + +async function main(instanceId, databaseId, projectId) { + // [START spanner_drop_sequence] + // 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'; + // const databaseId = 'my-database'; + + // Creates a client + const spanner = new Spanner({ + projectId: projectId, + }); + + async function dropSequence(instanceId, databaseId) { + // Gets a reference to a Cloud Spanner instance and database + const instance = spanner.instance(instanceId); + const database = instance.database(databaseId); + + const request = [ + 'ALTER TABLE Customers ALTER COLUMN CustomerId DROP DEFAULT', + 'DROP SEQUENCE Seq', + ]; + + // Drop sequence from DDL + try { + const [operation] = await database.updateSchema(request); + + console.log('Waiting for operation to complete...'); + await operation.promise(); + + console.log( + 'Altered Customers table to drop DEFAULT from CustomerId column and dropped the Seq sequence.' + ); + } catch (err) { + console.error('ERROR:', err); + } finally { + // Close the database when finished. + await database.close(); + } + } + await dropSequence(instanceId, databaseId); + // [END spanner_drop_sequence] +} + +process.on('unhandledRejection', err => { + console.error(err.message); + process.exitCode = 1; +}); +main(...process.argv.slice(2)); diff --git a/samples/system-test/spanner.test.js b/samples/system-test/spanner.test.js index c632af347..0b73b238d 100644 --- a/samples/system-test/spanner.test.js +++ b/samples/system-test/spanner.test.js @@ -66,6 +66,7 @@ const ENCRYPTED_RESTORE_DATABASE_ID = `test-database-${CURRENT_TIME}-r-enc`; const VERSION_RETENTION_DATABASE_ID = `test-database-${CURRENT_TIME}-v`; const ENCRYPTED_DATABASE_ID = `test-database-${CURRENT_TIME}-enc`; const DEFAULT_LEADER_DATABASE_ID = `test-database-${CURRENT_TIME}-dl`; +const SEQUENCE_DATABASE_ID = `test-seq-database-${CURRENT_TIME}-r`; const BACKUP_ID = `test-backup-${CURRENT_TIME}`; const COPY_BACKUP_ID = `test-copy-backup-${CURRENT_TIME}`; const ENCRYPTED_BACKUP_ID = `test-backup-${CURRENT_TIME}-enc`; @@ -1419,6 +1420,67 @@ describe('Spanner', () => { ); }); + describe('sequence', () => { + before(async () => { + const instance = spanner.instance(INSTANCE_ID); + const database = instance.database(SEQUENCE_DATABASE_ID); + const [, operation_seq] = await database.create(); + await operation_seq.promise(); + }); + + after(async () => { + await spanner + .instance(INSTANCE_ID) + .database(SEQUENCE_DATABASE_ID) + .delete(); + }); + + // create_sequence + it('should create a sequence', async () => { + const output = execSync( + `node sequence-create.js "${INSTANCE_ID}" "${SEQUENCE_DATABASE_ID}" ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp('Created Seq sequence and Customers table') + ); + assert.match( + output, + new RegExp('Number of customer records inserted is: 3') + ); + }); + + // alter_sequence + it('should alter a sequence', async () => { + const output = execSync( + `node sequence-alter.js "${INSTANCE_ID}" "${SEQUENCE_DATABASE_ID}" ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp( + 'Altered Seq sequence to skip an inclusive range between 1000 and 5000000.' + ) + ); + assert.match( + output, + new RegExp('Number of customer records inserted is: 3') + ); + }); + + // drop_sequence + it('should drop a sequence', async () => { + const output = execSync( + `node sequence-drop.js "${INSTANCE_ID}" "${SEQUENCE_DATABASE_ID}" ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp( + 'Altered Customers table to drop DEFAULT from CustomerId column and dropped the Seq sequence.' + ) + ); + }); + }); + describe('leader options', () => { before(async () => { const instance = spanner.instance(SAMPLE_INSTANCE_ID); @@ -1878,5 +1940,50 @@ describe('Spanner', () => { ); assert.match(output, new RegExp('Virginia1 Watson1')); }); + + // pg_create_sequence + it('should create a sequence', async () => { + const output = execSync( + `node pg-sequence-create.js ${SAMPLE_INSTANCE_ID} ${PG_DATABASE_ID} ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp('Created Seq sequence and Customers table') + ); + assert.match( + output, + new RegExp('Number of customer records inserted is: 3') + ); + }); + + // pg_alter_sequence + it('should alter a sequence', async () => { + const output = execSync( + `node pg-sequence-alter.js ${SAMPLE_INSTANCE_ID} ${PG_DATABASE_ID} ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp( + 'Altered Seq sequence to skip an inclusive range between 1000 and 5000000.' + ) + ); + assert.match( + output, + new RegExp('Number of customer records inserted is: 3') + ); + }); + + // pg_drop_sequence + it('should drop a sequence', async () => { + const output = execSync( + `node pg-sequence-drop.js ${SAMPLE_INSTANCE_ID} ${PG_DATABASE_ID} ${PROJECT_ID}` + ); + assert.match( + output, + new RegExp( + 'Altered Customers table to drop DEFAULT from CustomerId column and dropped the Seq sequence.' + ) + ); + }); }); });