Skip to content

Commit f31d7b2

Browse files
alkatrivedisurbhigarg92renovate-botgcf-owl-bot[bot]danieljbruce
authored
Fix: drop table statement (#2036)
* chore: integration test fix * fix: drop table * fix(deps): update dependency google-gax to v4.3.2 (#2026) * fix(deps): update dependency google-gax to v4.3.2 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> * feat(spanner): adding `EXPECTED_FULFILLMENT_PERIOD` to the indicate instance creation times (with `FULFILLMENT_PERIOD_NORMAL` or `FULFILLMENT_PERIOD_EXTENDED` ENUM) with the extended instance creation time triggered by On-Demand Capacity Feature (#2024) * feat: add several fields to manage state of database encryption update PiperOrigin-RevId: 619289281 Source-Link: googleapis/googleapis@3a7c334 Source-Link: googleapis/googleapis-gen@6a8c733 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiNmE4YzczMzA2MmQ4MzNkMTFjNTI0NWVkYTUwZjUxMDhlMGU1NTMyNCJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat: Add SessionPoolOptions, SpannerOptions protos in executor protos PiperOrigin-RevId: 621265883 Source-Link: googleapis/googleapis@fed9845 Source-Link: googleapis/googleapis-gen@c66a769 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYzY2YTc2OTU3ZTJlMTYzNDdiYzFkZDNmNGM2MzgyMjNmMDY1ZWU4MCJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * feat(spanner): adding `EXPECTED_FULFILLMENT_PERIOD` to the indicate instance creation times (with `FULFILLMENT_PERIOD_NORMAL` or `FULFILLMENT_PERIOD_EXTENDED` ENUM) with the extended instance creation time triggered by On-Demand Capacity Feature PiperOrigin-RevId: 621488048 Source-Link: googleapis/googleapis@0aa0992 Source-Link: googleapis/googleapis-gen@b8ad4c7 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiYjhhZDRjNzNhNWMwNWZlZDhiY2ZkZGI5MzEzMjY5OTZjMzQ0MTc5MSJ9 * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: danieljbruce <[email protected]> * feat: optimisticLock option for getTransaction method (#2028) * feat: add option for optimistic lock in getTransaction method * feat: add option for optimistic lock in getTransaction method * add sample for read and write transaction * add sample for read and write transaction * chore: add integration test for the read/write query samples * fix: presubmit error * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix: presubmit error * refactor: sample doc * refactor: sample doc * refator: getTransaction method * fix: lint errors * fix: lint errors * refactor: remove logs * fix: presubmit error * fix: lint errors * test: add a unit test for getTransaction * tests: add integration and unit test for getTransaction options properties * fix: lint errors * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * refactor: naming convention for varaible in getTransaction method * refactor: naming convention for varaible in getTransaction method * fix: lint errors * fix: lint error --------- Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> * chore(main): release 7.7.0 (#2027) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> * fix: drop table statement * refactor: delete method for drop statement * Modified delete method to use async await * fix: lint errors * test: unit test for delete method * fix: lint errors * refactor: unit test for drop table * refactor: remove unwanted commented lines * fix: lint errors * refactor: remove unwanted logs and refactor docs of the method * refactor * remove sample file * refactor: unit test for delete method * fix: lint error * refactor: remove unused lines * refactor: remove unused lines * refactor: remove unused lines * fix: lint errors * refactor: remove sample file * refactor * fix: lint errors * fix: lint errors * refactor * fix: lint errors * refactor * refactor * refactor --------- Co-authored-by: surbhigarg92 <[email protected]> Co-authored-by: Mend Renovate <[email protected]> Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: gcf-owl-bot[bot] <78513119+gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: danieljbruce <[email protected]> Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
1 parent ae59c7f commit f31d7b2

File tree

5 files changed

+243
-12
lines changed

5 files changed

+243
-12
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ system-test/*key.json
1212
.DS_Store
1313
package-lock.json
1414
__pycache__
15+
.vscode

src/database.ts

+72-1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ export interface SessionPoolConstructor {
133133
): SessionPoolInterface;
134134
}
135135

136+
export type GetDatabaseDialectCallback = NormalCallback<
137+
EnumKey<typeof google.spanner.admin.database.v1.DatabaseDialect>
138+
>;
139+
136140
export interface SetIamPolicyRequest {
137141
policy: Policy | null;
138142
updateMask?: FieldMask | null;
@@ -166,7 +170,15 @@ type IDatabaseTranslatedEnum = Omit<
166170
typeof databaseAdmin.spanner.admin.database.v1.Database.State
167171
>,
168172
'restoreInfo'
169-
> & {restoreInfo?: IRestoreInfoTranslatedEnum | null};
173+
> &
174+
Omit<
175+
TranslateEnumKeys<
176+
databaseAdmin.spanner.admin.database.v1.IDatabase,
177+
'databaseDialect',
178+
typeof databaseAdmin.spanner.admin.database.v1.DatabaseDialect
179+
>,
180+
'restoreInfo'
181+
> & {restoreInfo?: IRestoreInfoTranslatedEnum | null};
170182

171183
/**
172184
* IRestoreInfo structure with restore source type enum translated to string form.
@@ -312,6 +324,9 @@ class Database extends common.GrpcServiceObject {
312324
resourceHeader_: {[k: string]: string};
313325
request: DatabaseRequest;
314326
databaseRole?: string | null;
327+
databaseDialect?: EnumKey<
328+
typeof databaseAdmin.spanner.admin.database.v1.DatabaseDialect
329+
> | null;
315330
constructor(
316331
instance: Instance,
317332
name: string,
@@ -1476,6 +1491,61 @@ class Database extends common.GrpcServiceObject {
14761491
return metadata.state || undefined;
14771492
}
14781493

1494+
/**
1495+
* Retrieves the dialect of the database
1496+
*
1497+
* @see {@link #getMetadata}
1498+
*
1499+
* @method Database#getDatabaseDialect
1500+
*
1501+
* @param {object} [gaxOptions] Request configuration options,
1502+
* See {@link https://googleapis.dev/nodejs/google-gax/latest/interfaces/CallOptions.html|CallOptions}
1503+
* for more details.
1504+
* @param {GetDatabaseDialectCallback} [callback] Callback function.
1505+
* @returns {Promise<EnumKey<typeof, databaseAdmin.spanner.admin.database.v1.DatabaseDialect> | undefined>}
1506+
* When resolved, contains the database dialect of the database if the dialect is defined.
1507+
* @example
1508+
* const {Spanner} = require('@google-cloud/spanner');
1509+
* const spanner = new Spanner();
1510+
* const instance = spanner.instance('my-instance');
1511+
* const database = instance.database('my-database');
1512+
* const dialect = await database.getDatabaseDialect();
1513+
* const isGoogleSQL = (dialect === 'GOOGLE_STANDARD_SQL');
1514+
* const isPostgreSQL = (dialect === 'POSTGRESQL');
1515+
*/
1516+
1517+
getDatabaseDialect(
1518+
options?: CallOptions
1519+
): Promise<
1520+
| EnumKey<typeof databaseAdmin.spanner.admin.database.v1.DatabaseDialect>
1521+
| undefined
1522+
>;
1523+
getDatabaseDialect(callback: GetDatabaseDialectCallback): void;
1524+
getDatabaseDialect(
1525+
options: CallOptions,
1526+
callback: GetDatabaseDialectCallback
1527+
): void;
1528+
async getDatabaseDialect(
1529+
optionsOrCallback?: CallOptions | GetDatabaseDialectCallback,
1530+
cb?: GetDatabaseDialectCallback
1531+
): Promise<
1532+
| EnumKey<typeof databaseAdmin.spanner.admin.database.v1.DatabaseDialect>
1533+
| undefined
1534+
> {
1535+
const gaxOptions =
1536+
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
1537+
1538+
if (
1539+
this.databaseDialect === 'DATABASE_DIALECT_UNSPECIFIED' ||
1540+
this.databaseDialect === null ||
1541+
this.databaseDialect === undefined
1542+
) {
1543+
const [metadata] = await this.getMetadata(gaxOptions);
1544+
this.databaseDialect = metadata.databaseDialect;
1545+
}
1546+
return this.databaseDialect || undefined;
1547+
}
1548+
14791549
/**
14801550
* @typedef {array} GetSchemaResponse
14811551
* @property {string[]} 0 An array of database DDL statements.
@@ -3429,6 +3499,7 @@ promisifyAll(Database, {
34293499
'batchTransaction',
34303500
'getRestoreInfo',
34313501
'getState',
3502+
'getDatabaseDialect',
34323503
'getOperations',
34333504
'runTransaction',
34343505
'runTransactionAsync',

src/table.ts

+33-5
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ export type UpsertRowsCallback = CommitCallback;
6868
export type UpsertRowsResponse = CommitResponse;
6969
export type UpsertRowsOptions = MutateRowsOptions;
7070

71+
const GOOGLE_STANDARD_SQL = 'GOOGLE_STANDARD_SQL';
72+
const POSTGRESQL = 'POSTGRESQL';
7173
/**
7274
* Create a Table object to interact with a table in a Cloud Spanner
7375
* database.
@@ -342,11 +344,37 @@ class Table {
342344
const callback =
343345
typeof gaxOptionsOrCallback === 'function' ? gaxOptionsOrCallback : cb!;
344346

345-
return this.database.updateSchema(
346-
'DROP TABLE `' + this.name + '`',
347-
gaxOptions,
348-
callback!
349-
);
347+
const [schema, table] = this.name.includes('.')
348+
? this.name.split('.')
349+
: [null, this.name];
350+
351+
let dropStatement = 'DROP TABLE `' + table + '`';
352+
353+
const performDelete = async (): Promise<void | DropTableResponse> => {
354+
const result = await this.database.getDatabaseDialect(gaxOptions);
355+
356+
if (result && result.includes(POSTGRESQL)) {
357+
dropStatement = schema
358+
? `DROP TABLE "${schema}"."${table}"`
359+
: `DROP TABLE "${table}"`;
360+
} else if (result && result.includes(GOOGLE_STANDARD_SQL)) {
361+
dropStatement = schema
362+
? 'DROP TABLE `' + schema + '`.`' + table + '`'
363+
: dropStatement;
364+
}
365+
366+
const updateSchemaResult = callback
367+
? this.database.updateSchema(dropStatement, gaxOptions, callback)
368+
: this.database.updateSchema(dropStatement, gaxOptions);
369+
370+
return updateSchemaResult as Promise<DropTableResponse | void>;
371+
};
372+
373+
if (!callback) {
374+
return performDelete() as Promise<DropTableResponse>;
375+
} else {
376+
performDelete();
377+
}
350378
}
351379
/**
352380
* @typedef {array} DeleteRowsResponse

test/database.ts

+30
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const fakePfy = extend({}, pfy, {
5252
'batchTransaction',
5353
'getRestoreInfo',
5454
'getState',
55+
'getDatabaseDialect',
5556
'getOperations',
5657
'runTransaction',
5758
'runTransactionAsync',
@@ -2795,6 +2796,35 @@ describe('Database', () => {
27952796
});
27962797
});
27972798

2799+
describe('getDatabaseDialect', () => {
2800+
it('should get database dialect from database metadata', async () => {
2801+
database.getMetadata = async () => [
2802+
{databaseDialect: 'GOOGLE_STANDARD_SQL'},
2803+
];
2804+
const result = await database.getDatabaseDialect();
2805+
assert.strictEqual(result, 'GOOGLE_STANDARD_SQL');
2806+
});
2807+
2808+
it('should accept and pass gaxOptions to getMetadata', async () => {
2809+
const options = {};
2810+
database.getMetadata = async gaxOptions => {
2811+
assert.strictEqual(gaxOptions, options);
2812+
return [{}];
2813+
};
2814+
await database.getDatabaseDialect(options);
2815+
});
2816+
2817+
it('should accept callback and return database dialect', done => {
2818+
const databaseDialect = 'GOOGLE_STANDARD_SQL';
2819+
database.getMetadata = async () => [{databaseDialect}];
2820+
database.getDatabaseDialect((err, result) => {
2821+
assert.ifError(err);
2822+
assert.strictEqual(result, databaseDialect);
2823+
done();
2824+
});
2825+
});
2826+
});
2827+
27982828
describe('getRestoreInfo', () => {
27992829
it('should get restore info from database metadata', async () => {
28002830
const restoreInfo = {sourceType: 'BACKUP'};

test/table.ts

+107-6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ describe('Table', () => {
6767
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6868
let TableCached: any;
6969
let table;
70+
let tableWithSchema;
7071
let transaction: FakeTransaction;
7172

7273
const DATABASE = {
@@ -75,6 +76,7 @@ describe('Table', () => {
7576
};
7677

7778
const NAME = 'table-name';
79+
const NAMEWITHSCHEMA = 'schema.' + NAME;
7880

7981
before(() => {
8082
Table = proxyquire('../src/table.js', {
@@ -86,6 +88,7 @@ describe('Table', () => {
8688
beforeEach(() => {
8789
extend(Table, TableCached);
8890
table = new Table(DATABASE, NAME);
91+
tableWithSchema = new Table(DATABASE, NAMEWITHSCHEMA);
8992
transaction = new FakeTransaction();
9093
});
9194

@@ -209,26 +212,124 @@ describe('Table', () => {
209212
});
210213

211214
describe('delete', () => {
212-
it('should update the schema on the database', () => {
213-
const updateSchemaReturnValue = {};
215+
it('should update the schema on the database for GoogleSQL using await', async () => {
216+
table.database = {
217+
getDatabaseDialect: () => {
218+
return 'GOOGLE_STANDARD_SQL';
219+
},
220+
updateSchema: schema => {
221+
assert.strictEqual(schema, 'DROP TABLE `table-name`');
222+
},
223+
};
224+
225+
await table.delete();
226+
});
227+
228+
it('should update the schema on the database for GoogleSQL using callbacks', () => {
229+
function callback() {}
230+
table.database = {
231+
getDatabaseDialect: () => {
232+
return 'GOOGLE_STANDARD_SQL';
233+
},
234+
updateSchema: (schema, gaxOptions, callback_) => {
235+
assert.strictEqual(schema, 'DROP TABLE `table-name`');
236+
assert.strictEqual(callback_, callback);
237+
},
238+
};
239+
table.delete(callback);
240+
});
241+
242+
it('should update the schema on the database for GoogleSQL with schema in the table name using await', async () => {
243+
tableWithSchema.database = {
244+
getDatabaseDialect: () => {
245+
return 'GOOGLE_STANDARD_SQL';
246+
},
247+
updateSchema: schema => {
248+
assert.strictEqual(schema, 'DROP TABLE `schema`.`table-name`');
249+
},
250+
};
251+
252+
await tableWithSchema.delete();
253+
});
254+
255+
it('should update the schema on the database for GoogleSQL with schema in the table name using callbacks', () => {
256+
function callback() {}
257+
tableWithSchema.database = {
258+
getDatabaseDialect: () => {
259+
return 'GOOGLE_STANDARD_SQL';
260+
},
261+
updateSchema: (schema, gaxOptions, callback_) => {
262+
assert.strictEqual(schema, 'DROP TABLE `schema`.`table-name`');
263+
assert.strictEqual(callback_, callback);
264+
},
265+
};
266+
tableWithSchema.delete(callback);
267+
});
268+
269+
it('should update the schema on the database for PostgresSQL using await', async () => {
270+
table.database = {
271+
getDatabaseDialect: () => {
272+
return 'POSTGRESQL';
273+
},
274+
updateSchema: schema => {
275+
assert.strictEqual(schema, `DROP TABLE "${table.name}"`);
276+
},
277+
};
214278

279+
await table.delete();
280+
});
281+
282+
it('should update the schema on the database for PostgresSQL using callbacks', () => {
215283
function callback() {}
216284

217285
table.database = {
286+
getDatabaseDialect: () => {
287+
return 'POSTGRESQL';
288+
},
218289
updateSchema: (schema, gaxOptions, callback_) => {
219-
assert.strictEqual(schema, 'DROP TABLE `' + table.name + '`');
290+
assert.strictEqual(schema, 'DROP TABLE "table-name"');
220291
assert.strictEqual(callback_, callback);
221-
return updateSchemaReturnValue;
222292
},
223293
};
224294

225-
const returnValue = table.delete(callback);
226-
assert.strictEqual(returnValue, updateSchemaReturnValue);
295+
table.delete(callback);
296+
});
297+
298+
it('should update the schema on the database for PostgresSQL with schema in the table name using await', async () => {
299+
tableWithSchema.database = {
300+
getDatabaseDialect: () => {
301+
return 'POSTGRESQL';
302+
},
303+
updateSchema: schema => {
304+
assert.strictEqual(schema, `DROP TABLE "schema"."${table.name}"`);
305+
},
306+
};
307+
308+
await tableWithSchema.delete();
309+
});
310+
311+
it('should update the schema on the database for PostgresSQL with schema in the table name using callbacks', () => {
312+
function callback() {}
313+
tableWithSchema.database = {
314+
getDatabaseDialect: () => {
315+
return 'POSTGRESQL';
316+
},
317+
updateSchema: (schema, gaxOptions, callback_) => {
318+
assert.strictEqual(schema, `DROP TABLE "schema"."${table.name}"`);
319+
assert.strictEqual(callback_, callback);
320+
},
321+
};
322+
323+
tableWithSchema.delete(callback);
227324
});
228325

229326
it('should accept and pass gaxOptions to updateSchema', done => {
230327
const gaxOptions = {};
231328
table.database = {
329+
getDatabaseDialect: gaxOptionsFromTable => {
330+
assert.strictEqual(gaxOptionsFromTable, gaxOptions);
331+
return 'GOOGLE_STANDARD_SQL';
332+
},
232333
updateSchema: (schema, gaxOptionsFromTable) => {
233334
assert.strictEqual(gaxOptionsFromTable, gaxOptions);
234335
done();

0 commit comments

Comments
 (0)