-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: Samples and tests for Database Admin Client APIs (#1986)
This PR contains sample files and their integration tests for the database admin client APIs.
- Loading branch information
1 parent
494a996
commit f34a33a
Showing
24 changed files
with
2,364 additions
and
4 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Copyright 2024 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: Add and drop new database role | ||
// usage: node add-and-drop-new-database-role.js <INSTANCE_ID> <DATABASE_ID> <PROJECT_ID> | ||
|
||
'use strict'; | ||
|
||
function main( | ||
instanceId = 'my-instance', | ||
databaseId = 'my-database', | ||
projectId = 'my-project-id' | ||
) { | ||
// [START spanner_add_and_drop_database_role] | ||
/** | ||
* TODO(developer): Uncomment these variables before running the sample. | ||
*/ | ||
// const instanceId = 'my-instance'; | ||
// const databaseId = 'my-database'; | ||
// const projectId = 'my-project-id'; | ||
|
||
// Imports the Google Cloud client library | ||
const {Spanner} = require('@google-cloud/spanner'); | ||
|
||
// creates a client | ||
const spanner = new Spanner({ | ||
projectId: projectId, | ||
}); | ||
|
||
const databaseAdminClient = spanner.getDatabaseAdminClient(); | ||
|
||
async function addAndDropNewDatabaseRole() { | ||
// Creates a new user defined role and grant permissions | ||
try { | ||
const request = [ | ||
'CREATE ROLE parent', | ||
'GRANT SELECT ON TABLE Singers TO ROLE parent', | ||
'CREATE ROLE child', | ||
'GRANT ROLE parent TO ROLE child', | ||
]; | ||
const [operation] = await databaseAdminClient.updateDatabaseDdl({ | ||
database: databaseAdminClient.databasePath( | ||
projectId, | ||
instanceId, | ||
databaseId | ||
), | ||
statements: request, | ||
}); | ||
|
||
console.log('Waiting for operation to complete...'); | ||
await operation.promise(); | ||
|
||
console.log('Created roles child and parent and granted privileges'); | ||
} catch (err) { | ||
console.error('ERROR:', err); | ||
} | ||
|
||
// Revoke permissions and drop child role. | ||
// A role can't be dropped until all its permissions are revoked. | ||
try { | ||
const request = ['REVOKE ROLE parent FROM ROLE child', 'DROP ROLE child']; | ||
const [operation] = await databaseAdminClient.updateDatabaseDdl({ | ||
database: databaseAdminClient.databasePath( | ||
projectId, | ||
instanceId, | ||
databaseId | ||
), | ||
statements: request, | ||
}); | ||
|
||
console.log('Waiting for operation to complete...'); | ||
await operation.promise(); | ||
|
||
console.log('Revoked privileges and dropped role child'); | ||
} catch (err) { | ||
console.error('ERROR:', err); | ||
} finally { | ||
// Close the spanner client when finished. | ||
// The databaseAdminClient does not require explicit closure. The closure of the Spanner client will automatically close the databaseAdminClient. | ||
spanner.close(); | ||
} | ||
} | ||
addAndDropNewDatabaseRole(); | ||
// [END spanner_add_and_drop_database_role] | ||
} | ||
|
||
process.on('unhandledRejection', err => { | ||
console.error(err.message); | ||
process.exitCode = 1; | ||
}); | ||
main(...process.argv.slice(2)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/** | ||
* Copyright 2024 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 new database with a specific default leader | ||
// usage: node database-create-with-default-leader.js <INSTANCE_ID> <DATABASE_ID> <DEFAULT_LEADER> <PROJECT_ID> | ||
|
||
'use strict'; | ||
|
||
function main(instanceId, databaseId, defaultLeader, projectId) { | ||
/** | ||
* 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'; | ||
// const defaultLeader = 'my-default-leader'; example: 'asia-northeast1' | ||
|
||
// Imports the Google Cloud client library | ||
const {Spanner} = require('@google-cloud/spanner'); | ||
|
||
// creates a client | ||
const spanner = new Spanner({ | ||
projectId: projectId, | ||
}); | ||
|
||
const databaseAdminClient = spanner.getDatabaseAdminClient(); | ||
|
||
async function createDatabaseWithDefaultLeader() { | ||
// Create a new database with an extra statement which will alter the | ||
// database after creation to set the default leader. | ||
console.log( | ||
`Creating database ${databaseAdminClient.databasePath( | ||
projectId, | ||
instanceId, | ||
databaseId | ||
)}.` | ||
); | ||
const createSingersTableStatement = ` | ||
CREATE TABLE Singers ( | ||
SingerId INT64 NOT NULL, | ||
FirstName STRING(1024), | ||
LastName STRING(1024), | ||
SingerInfo BYTES(MAX) | ||
) PRIMARY KEY (SingerId)`; | ||
const createAlbumsStatement = ` | ||
CREATE TABLE Albums ( | ||
SingerId INT64 NOT NULL, | ||
AlbumId INT64 NOT NULL, | ||
AlbumTitle STRING(MAX) | ||
) PRIMARY KEY (SingerId, AlbumId), | ||
INTERLEAVE IN PARENT Singers ON DELETE CASCADE`; | ||
|
||
// Default leader is one of the possible values in the leaderOptions field of the | ||
// instance config of the instance where the database is created. | ||
const setDefaultLeaderStatement = ` | ||
ALTER DATABASE \`${databaseId}\` | ||
SET OPTIONS (default_leader = '${defaultLeader}')`; | ||
|
||
const [operation] = await databaseAdminClient.createDatabase({ | ||
createStatement: 'CREATE DATABASE `' + databaseId + '`', | ||
extraStatements: [ | ||
createSingersTableStatement, | ||
createAlbumsStatement, | ||
setDefaultLeaderStatement, | ||
], | ||
parent: databaseAdminClient.instancePath(projectId, instanceId), | ||
}); | ||
|
||
console.log(`Waiting for creation of ${databaseId} to complete...`); | ||
await operation.promise(); | ||
console.log( | ||
`Created database ${databaseId} with default leader ${defaultLeader}.` | ||
); | ||
} | ||
createDatabaseWithDefaultLeader(); | ||
} | ||
process.on('unhandledRejection', err => { | ||
console.error(err.message); | ||
process.exitCode = 1; | ||
}); | ||
main(...process.argv.slice(2)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright 2024 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. | ||
|
||
'use strict'; | ||
|
||
async function createDatabaseWithEncryptionKey( | ||
instanceId, | ||
databaseId, | ||
projectId, | ||
keyName | ||
) { | ||
/** | ||
* TODO(developer): Uncomment the following lines before running the sample. | ||
*/ | ||
// const projectId = 'my-project-id'; | ||
// const instanceId = 'my-instance'; | ||
// const databaseId = 'my-database'; | ||
// const keyName = | ||
// 'projects/my-project-id/my-region/keyRings/my-key-ring/cryptoKeys/my-key'; | ||
|
||
// Imports the Google Cloud client library | ||
const {Spanner, protos} = require('@google-cloud/spanner'); | ||
|
||
// creates a client | ||
const spanner = new Spanner({ | ||
projectId: projectId, | ||
}); | ||
|
||
const databaseAdminClient = spanner.getDatabaseAdminClient(); | ||
|
||
// Creates a database | ||
const [operation] = await databaseAdminClient.createDatabase({ | ||
createStatement: 'CREATE DATABASE `' + databaseId + '`', | ||
parent: databaseAdminClient.instancePath(projectId, instanceId), | ||
encryptionConfig: | ||
(protos.google.spanner.admin.database.v1.EncryptionConfig = { | ||
kmsKeyName: keyName, | ||
}), | ||
}); | ||
|
||
console.log(`Waiting for operation on ${databaseId} to complete...`); | ||
await operation.promise(); | ||
|
||
console.log(`Created database ${databaseId} on instance ${instanceId}.`); | ||
|
||
// Get encryption key | ||
const [metadata] = await databaseAdminClient.getDatabase({ | ||
name: databaseAdminClient.databasePath(projectId, instanceId, databaseId), | ||
}); | ||
|
||
console.log( | ||
`Database encrypted with key ${metadata.encryptionConfig.kmsKeyName}.` | ||
); | ||
} | ||
|
||
module.exports.createDatabaseWithEncryptionKey = | ||
createDatabaseWithEncryptionKey; |
82 changes: 82 additions & 0 deletions
82
samples/v2/database-create-with-version-retention-period.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* Copyright 2024 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. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
async function createDatabaseWithVersionRetentionPeriod( | ||
instanceId, | ||
databaseId, | ||
projectId | ||
) { | ||
// [START spanner_create_database_with_version_retention_period] | ||
|
||
// 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'; | ||
|
||
// creates a client | ||
const spanner = new Spanner({ | ||
projectId: projectId, | ||
}); | ||
|
||
const databaseAdminClient = spanner.getDatabaseAdminClient(); | ||
|
||
try { | ||
// Create a new database with an extra statement which will alter the | ||
// database after creation to set the version retention period. | ||
console.log( | ||
`Creating database ${databaseAdminClient.instancePath( | ||
projectId, | ||
instanceId | ||
)}.` | ||
); | ||
const versionRetentionStatement = ` | ||
ALTER DATABASE \`${databaseId}\` | ||
SET OPTIONS (version_retention_period = '1d')`; | ||
|
||
const [operation] = await databaseAdminClient.createDatabase({ | ||
createStatement: 'CREATE DATABASE `' + databaseId + '`', | ||
extraStatements: [versionRetentionStatement], | ||
parent: databaseAdminClient.instancePath(projectId, instanceId), | ||
}); | ||
|
||
console.log(`Waiting for operation on ${databaseId} to complete...`); | ||
await operation.promise(); | ||
console.log(` | ||
Created database ${databaseId} with version retention period.`); | ||
|
||
const [metadata] = await databaseAdminClient.getDatabase({ | ||
name: databaseAdminClient.databasePath(projectId, instanceId, databaseId), | ||
}); | ||
|
||
console.log(`Version retention period: ${metadata.versionRetentionPeriod}`); | ||
const milliseconds = | ||
parseInt(metadata.earliestVersionTime.seconds, 10) * 1000 + | ||
parseInt(metadata.earliestVersionTime.nanos, 10) / 1e6; | ||
const date = new Date(milliseconds); | ||
console.log(`Earliest version time: ${date.toString()}`); | ||
} catch (err) { | ||
console.error('ERROR:', err); | ||
} | ||
// [END spanner_create_database_with_version_retention_period] | ||
} | ||
|
||
module.exports.createDatabaseWithVersionRetentionPeriod = | ||
createDatabaseWithVersionRetentionPeriod; |
Oops, something went wrong.