@proteinjs/db-driver-spanner 1.19.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/test/index.js +1 -1
- package/dist/generated/test/index.js.map +1 -1
- package/dist/src/SpannerDriver.d.ts +36 -3
- package/dist/src/SpannerDriver.d.ts.map +1 -1
- package/dist/src/SpannerDriver.js +106 -17
- package/dist/src/SpannerDriver.js.map +1 -1
- package/dist/src/SpannerSchemaOperations.d.ts +9 -1
- package/dist/src/SpannerSchemaOperations.d.ts.map +1 -1
- package/dist/src/SpannerSchemaOperations.js +88 -124
- package/dist/src/SpannerSchemaOperations.js.map +1 -1
- package/dist/test/BatchedDdl.test.d.ts +2 -0
- package/dist/test/BatchedDdl.test.d.ts.map +1 -0
- package/dist/test/BatchedDdl.test.js +496 -0
- package/dist/test/BatchedDdl.test.js.map +1 -0
- package/generated/index.ts +1 -1
- package/generated/test/index.ts +1 -1
- package/package.json +5 -5
- package/src/SpannerDriver.ts +72 -10
- package/src/SpannerSchemaOperations.ts +69 -55
- package/test/BatchedDdl.test.ts +293 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
20
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
21
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
22
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
23
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
27
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
28
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
29
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
30
|
+
function step(op) {
|
|
31
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
32
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
33
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
34
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
35
|
+
switch (op[0]) {
|
|
36
|
+
case 0: case 1: t = op; break;
|
|
37
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
38
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
39
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
40
|
+
default:
|
|
41
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
42
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
43
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
44
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
45
|
+
if (t[2]) _.ops.pop();
|
|
46
|
+
_.trys.pop(); continue;
|
|
47
|
+
}
|
|
48
|
+
op = body.call(thisArg, _);
|
|
49
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
50
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
54
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
55
|
+
if (ar || !(i in from)) {
|
|
56
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
57
|
+
ar[i] = from[i];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
61
|
+
};
|
|
62
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
|
+
var spanner_1 = require("@google-cloud/spanner");
|
|
64
|
+
var logger_1 = require("@proteinjs/logger");
|
|
65
|
+
var db_driver_spanner_1 = require("@proteinjs/db-driver-spanner");
|
|
66
|
+
var db_1 = require("@proteinjs/db");
|
|
67
|
+
var getDropTestTable_1 = require("./util/getDropTestTable");
|
|
68
|
+
var SpannerEmulatorProvisioner_1 = require("./util/SpannerEmulatorProvisioner");
|
|
69
|
+
require("../generated/test/index");
|
|
70
|
+
var spannerConfig = {
|
|
71
|
+
projectId: 'proteinjs-test',
|
|
72
|
+
instanceName: 'proteinjs-test',
|
|
73
|
+
databaseName: 'test',
|
|
74
|
+
};
|
|
75
|
+
var spannerDriver = new db_driver_spanner_1.SpannerDriver(spannerConfig);
|
|
76
|
+
/** Parent with a declared index — its create is CREATE TABLE + CREATE INDEX. */
|
|
77
|
+
var parentTable = function () {
|
|
78
|
+
return new (/** @class */ (function (_super) {
|
|
79
|
+
__extends(class_1, _super);
|
|
80
|
+
function class_1() {
|
|
81
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
82
|
+
_this.name = 'db_test_batchddl_parent';
|
|
83
|
+
_this.columns = (0, db_1.withRecordColumns)({
|
|
84
|
+
name: new db_1.StringColumn('name'),
|
|
85
|
+
});
|
|
86
|
+
_this.indexes = [{ name: 'db_test_batchddl_parent_name_index', columns: ['name'] }];
|
|
87
|
+
return _this;
|
|
88
|
+
}
|
|
89
|
+
return class_1;
|
|
90
|
+
}(db_1.Table)))();
|
|
91
|
+
};
|
|
92
|
+
/** Child whose FK references the parent — creation order across the two tables is load-bearing. */
|
|
93
|
+
var childTable = function () {
|
|
94
|
+
return new (/** @class */ (function (_super) {
|
|
95
|
+
__extends(class_2, _super);
|
|
96
|
+
function class_2() {
|
|
97
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
98
|
+
_this.name = 'db_test_batchddl_child';
|
|
99
|
+
_this.columns = (0, db_1.withRecordColumns)({
|
|
100
|
+
label: new db_1.StringColumn('label'),
|
|
101
|
+
parentId: new db_1.StringColumn('parent_id', { references: { table: 'db_test_batchddl_parent' } }),
|
|
102
|
+
});
|
|
103
|
+
_this.indexes = [{ name: 'db_test_batchddl_child_label_index', columns: ['label'] }];
|
|
104
|
+
return _this;
|
|
105
|
+
}
|
|
106
|
+
return class_2;
|
|
107
|
+
}(db_1.Table)))();
|
|
108
|
+
};
|
|
109
|
+
/** Parent redeclared with an extra column + extra index — the alter pass under test. */
|
|
110
|
+
var grownParentTable = function () {
|
|
111
|
+
return new (/** @class */ (function (_super) {
|
|
112
|
+
__extends(class_3, _super);
|
|
113
|
+
function class_3() {
|
|
114
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
115
|
+
_this.name = 'db_test_batchddl_parent';
|
|
116
|
+
_this.columns = (0, db_1.withRecordColumns)({
|
|
117
|
+
name: new db_1.StringColumn('name'),
|
|
118
|
+
nickname: new db_1.StringColumn('nickname'),
|
|
119
|
+
});
|
|
120
|
+
_this.indexes = [
|
|
121
|
+
{ name: 'db_test_batchddl_parent_name_index', columns: ['name'] },
|
|
122
|
+
{ name: 'db_test_batchddl_parent_nickname_index', columns: ['nickname'] },
|
|
123
|
+
];
|
|
124
|
+
return _this;
|
|
125
|
+
}
|
|
126
|
+
return class_3;
|
|
127
|
+
}(db_1.Table)))();
|
|
128
|
+
};
|
|
129
|
+
describe('Batched DDL', function () {
|
|
130
|
+
var dropTable = (0, getDropTestTable_1.getDropTestTable)(spannerDriver);
|
|
131
|
+
var tableManager = spannerDriver.getTableManager();
|
|
132
|
+
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
133
|
+
return __generator(this, function (_a) {
|
|
134
|
+
switch (_a.label) {
|
|
135
|
+
case 0: return [4 /*yield*/, SpannerEmulatorProvisioner_1.SpannerEmulatorProvisioner.ensureProvisioned(spannerConfig)];
|
|
136
|
+
case 1:
|
|
137
|
+
_a.sent();
|
|
138
|
+
return [4 /*yield*/, dropTable(childTable())];
|
|
139
|
+
case 2:
|
|
140
|
+
_a.sent();
|
|
141
|
+
return [4 /*yield*/, dropTable(parentTable())];
|
|
142
|
+
case 3:
|
|
143
|
+
_a.sent();
|
|
144
|
+
return [2 /*return*/];
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}); }, 60000);
|
|
148
|
+
afterAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
149
|
+
return __generator(this, function (_a) {
|
|
150
|
+
switch (_a.label) {
|
|
151
|
+
case 0: return [4 /*yield*/, dropTable(childTable())];
|
|
152
|
+
case 1:
|
|
153
|
+
_a.sent();
|
|
154
|
+
return [4 /*yield*/, dropTable(parentTable())];
|
|
155
|
+
case 2:
|
|
156
|
+
_a.sent();
|
|
157
|
+
SpannerEmulatorProvisioner_1.SpannerEmulatorProvisioner.release();
|
|
158
|
+
return [2 /*return*/];
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}); }, 60000);
|
|
162
|
+
afterEach(function () {
|
|
163
|
+
jest.restoreAllMocks();
|
|
164
|
+
});
|
|
165
|
+
test('a new table lands via one runUpdateSchema call (CREATE TABLE + its indexes in one batch)', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
166
|
+
var parent, spy, _a, indexes;
|
|
167
|
+
return __generator(this, function (_b) {
|
|
168
|
+
switch (_b.label) {
|
|
169
|
+
case 0:
|
|
170
|
+
parent = parentTable();
|
|
171
|
+
spy = jest.spyOn(spannerDriver, 'runUpdateSchema');
|
|
172
|
+
return [4 /*yield*/, tableManager.loadTable(parent)];
|
|
173
|
+
case 1:
|
|
174
|
+
_b.sent();
|
|
175
|
+
// Call-shape at the driver seam: the table's whole schema rides ONE schema-update operation.
|
|
176
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
177
|
+
// Outcome: the schema actually landed (INFORMATION_SCHEMA-backed metadata).
|
|
178
|
+
_a = expect;
|
|
179
|
+
return [4 /*yield*/, tableManager.tableExists(parent)];
|
|
180
|
+
case 2:
|
|
181
|
+
// Outcome: the schema actually landed (INFORMATION_SCHEMA-backed metadata).
|
|
182
|
+
_a.apply(void 0, [_b.sent()]).toBe(true);
|
|
183
|
+
return [4 /*yield*/, tableManager.schemaMetadata.getIndexes(parent)];
|
|
184
|
+
case 3:
|
|
185
|
+
indexes = _b.sent();
|
|
186
|
+
expect(indexes['db_test_batchddl_parent_name_index']).toEqual(['name']);
|
|
187
|
+
return [4 /*yield*/, dropTable(parent)];
|
|
188
|
+
case 4:
|
|
189
|
+
_b.sent();
|
|
190
|
+
return [2 /*return*/];
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}); }, 60000);
|
|
194
|
+
test('an alter pass (add column + add index) lands via one runUpdateSchema call', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
195
|
+
var grown, spy, columnMetadata, indexes;
|
|
196
|
+
return __generator(this, function (_a) {
|
|
197
|
+
switch (_a.label) {
|
|
198
|
+
case 0: return [4 /*yield*/, tableManager.loadTable(parentTable())];
|
|
199
|
+
case 1:
|
|
200
|
+
_a.sent();
|
|
201
|
+
grown = grownParentTable();
|
|
202
|
+
spy = jest.spyOn(spannerDriver, 'runUpdateSchema');
|
|
203
|
+
return [4 /*yield*/, tableManager.loadTable(grown)];
|
|
204
|
+
case 2:
|
|
205
|
+
_a.sent();
|
|
206
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
207
|
+
return [4 /*yield*/, tableManager.schemaMetadata.getColumnMetadata(grown)];
|
|
208
|
+
case 3:
|
|
209
|
+
columnMetadata = _a.sent();
|
|
210
|
+
expect(columnMetadata['nickname']).toBeDefined();
|
|
211
|
+
return [4 /*yield*/, tableManager.schemaMetadata.getIndexes(grown)];
|
|
212
|
+
case 4:
|
|
213
|
+
indexes = _a.sent();
|
|
214
|
+
expect(indexes['db_test_batchddl_parent_nickname_index']).toEqual(['nickname']);
|
|
215
|
+
return [4 /*yield*/, dropTable(grown)];
|
|
216
|
+
case 5:
|
|
217
|
+
_a.sent();
|
|
218
|
+
return [2 /*return*/];
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}); }, 60000);
|
|
222
|
+
test('parent and FK child land in one ordered batch, and the FK is live', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
223
|
+
var parent, child, spy, updateSchemaSpy, statements, parentCreateIndex, childCreateIndex, _a, _b, foreignKeys, childIndexes;
|
|
224
|
+
return __generator(this, function (_c) {
|
|
225
|
+
switch (_c.label) {
|
|
226
|
+
case 0:
|
|
227
|
+
parent = parentTable();
|
|
228
|
+
child = childTable();
|
|
229
|
+
spy = jest.spyOn(spannerDriver, 'runUpdateSchema');
|
|
230
|
+
updateSchemaSpy = jest.spyOn(spanner_1.Database.prototype, 'updateSchema');
|
|
231
|
+
return [4 /*yield*/, tableManager.schemaOperations.createTables([parent, child])];
|
|
232
|
+
case 1:
|
|
233
|
+
_c.sent();
|
|
234
|
+
// One schema-update operation carrying the whole set: 2 CREATE TABLE + 2 CREATE INDEX,
|
|
235
|
+
// parent's CREATE before the child's (the child's inline FK resolves against it in-batch).
|
|
236
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
237
|
+
expect(updateSchemaSpy).toHaveBeenCalledTimes(1);
|
|
238
|
+
expect(updateSchemaSpy.mock.calls[0][0]).toHaveLength(4);
|
|
239
|
+
statements = spy.mock.calls[0][0];
|
|
240
|
+
expect(Array.isArray(statements)).toBe(true);
|
|
241
|
+
expect(statements).toHaveLength(4);
|
|
242
|
+
parentCreateIndex = statements.findIndex(function (sql) { return sql.includes('CREATE TABLE `db_test_batchddl_parent`'); });
|
|
243
|
+
childCreateIndex = statements.findIndex(function (sql) { return sql.includes('CREATE TABLE `db_test_batchddl_child`'); });
|
|
244
|
+
expect(parentCreateIndex).toBeGreaterThanOrEqual(0);
|
|
245
|
+
expect(childCreateIndex).toBeGreaterThan(parentCreateIndex);
|
|
246
|
+
// Outcome: both tables live, the child's foreign key and index actually exist.
|
|
247
|
+
_a = expect;
|
|
248
|
+
return [4 /*yield*/, tableManager.tableExists(parent)];
|
|
249
|
+
case 2:
|
|
250
|
+
// Outcome: both tables live, the child's foreign key and index actually exist.
|
|
251
|
+
_a.apply(void 0, [_c.sent()]).toBe(true);
|
|
252
|
+
_b = expect;
|
|
253
|
+
return [4 /*yield*/, tableManager.tableExists(child)];
|
|
254
|
+
case 3:
|
|
255
|
+
_b.apply(void 0, [_c.sent()]).toBe(true);
|
|
256
|
+
return [4 /*yield*/, tableManager.schemaMetadata.getForeignKeys(child)];
|
|
257
|
+
case 4:
|
|
258
|
+
foreignKeys = _c.sent();
|
|
259
|
+
expect(foreignKeys['parent_id']).toEqual({
|
|
260
|
+
referencedTableName: 'db_test_batchddl_parent',
|
|
261
|
+
referencedColumnName: 'id',
|
|
262
|
+
});
|
|
263
|
+
return [4 /*yield*/, tableManager.schemaMetadata.getIndexes(child)];
|
|
264
|
+
case 5:
|
|
265
|
+
childIndexes = _c.sent();
|
|
266
|
+
expect(childIndexes['db_test_batchddl_child_label_index']).toEqual(['label']);
|
|
267
|
+
return [4 /*yield*/, dropTable(child)];
|
|
268
|
+
case 6:
|
|
269
|
+
_c.sent();
|
|
270
|
+
return [4 /*yield*/, dropTable(parent)];
|
|
271
|
+
case 7:
|
|
272
|
+
_c.sent();
|
|
273
|
+
return [2 /*return*/];
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}); }, 60000);
|
|
277
|
+
test('a wrong-ordered batch (FK child before parent) is REJECTED by the backend — ordering is load-bearing', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
278
|
+
var parent, child, ops, childFirst, _a, _b;
|
|
279
|
+
return __generator(this, function (_c) {
|
|
280
|
+
switch (_c.label) {
|
|
281
|
+
case 0:
|
|
282
|
+
parent = parentTable();
|
|
283
|
+
child = childTable();
|
|
284
|
+
ops = tableManager.schemaOperations;
|
|
285
|
+
childFirst = __spreadArray(__spreadArray([], ops.createTableStatements(child), true), ops.createTableStatements(parent), true);
|
|
286
|
+
// The child's CREATE TABLE carries an inline FK to a parent that is not yet in the
|
|
287
|
+
// projected schema at its position in the batch — validation rejects the batch and NOTHING
|
|
288
|
+
// applies. This is the failure our ordered assembly exists to prevent.
|
|
289
|
+
return [4 /*yield*/, expect(spannerDriver.runUpdateSchema(childFirst)).rejects.toThrow()];
|
|
290
|
+
case 1:
|
|
291
|
+
// The child's CREATE TABLE carries an inline FK to a parent that is not yet in the
|
|
292
|
+
// projected schema at its position in the batch — validation rejects the batch and NOTHING
|
|
293
|
+
// applies. This is the failure our ordered assembly exists to prevent.
|
|
294
|
+
_c.sent();
|
|
295
|
+
_a = expect;
|
|
296
|
+
return [4 /*yield*/, tableManager.tableExists(child)];
|
|
297
|
+
case 2:
|
|
298
|
+
_a.apply(void 0, [_c.sent()]).toBe(false);
|
|
299
|
+
_b = expect;
|
|
300
|
+
return [4 /*yield*/, tableManager.tableExists(parent)];
|
|
301
|
+
case 3:
|
|
302
|
+
_b.apply(void 0, [_c.sent()]).toBe(false);
|
|
303
|
+
return [2 /*return*/];
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}); }, 60000);
|
|
307
|
+
test('a schema-invalid statement mid-batch rejects the WHOLE batch upfront — nothing applied (validation phase)', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
308
|
+
var parent, ops, _a, createParentSql, createNameIndexSql, badIndexSql, _b;
|
|
309
|
+
return __generator(this, function (_c) {
|
|
310
|
+
switch (_c.label) {
|
|
311
|
+
case 0:
|
|
312
|
+
parent = parentTable();
|
|
313
|
+
ops = tableManager.schemaOperations;
|
|
314
|
+
_a = ops.createTableStatements(parent), createParentSql = _a[0], createNameIndexSql = _a[1];
|
|
315
|
+
badIndexSql = 'CREATE INDEX db_test_batchddl_parent_bogus_index ON db_test_batchddl_parent(no_such_column)';
|
|
316
|
+
return [4 /*yield*/, expect(spannerDriver.runUpdateSchema([createParentSql, badIndexSql, createNameIndexSql])).rejects.toThrow(/no_such_column/)];
|
|
317
|
+
case 1:
|
|
318
|
+
_c.sent();
|
|
319
|
+
_b = expect;
|
|
320
|
+
return [4 /*yield*/, tableManager.tableExists(parent)];
|
|
321
|
+
case 2:
|
|
322
|
+
_b.apply(void 0, [_c.sent()]).toBe(false);
|
|
323
|
+
return [2 /*return*/];
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
}); }, 60000);
|
|
327
|
+
test('a data-dependent failure mid-batch leaves EARLIER statements applied, LATER unapplied (apply phase)', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
328
|
+
var parent, client, database, statements, logErrorSpy, failureLog, indexes;
|
|
329
|
+
return __generator(this, function (_a) {
|
|
330
|
+
switch (_a.label) {
|
|
331
|
+
case 0:
|
|
332
|
+
parent = parentTable();
|
|
333
|
+
return [4 /*yield*/, tableManager.loadTable(parent)];
|
|
334
|
+
case 1:
|
|
335
|
+
_a.sent();
|
|
336
|
+
client = new spanner_1.Spanner({ projectId: spannerConfig.projectId });
|
|
337
|
+
database = client.instance(spannerConfig.instanceName).database(spannerConfig.databaseName);
|
|
338
|
+
database.on('error', function () { return undefined; });
|
|
339
|
+
_a.label = 2;
|
|
340
|
+
case 2:
|
|
341
|
+
_a.trys.push([2, , 4, 6]);
|
|
342
|
+
return [4 /*yield*/, database.table(parent.name).insert([
|
|
343
|
+
{ id: 'dup-1', name: 'dup', created: new Date(), updated: new Date() },
|
|
344
|
+
{ id: 'dup-2', name: 'dup', created: new Date(), updated: new Date() },
|
|
345
|
+
])];
|
|
346
|
+
case 3:
|
|
347
|
+
_a.sent();
|
|
348
|
+
return [3 /*break*/, 6];
|
|
349
|
+
case 4: return [4 /*yield*/, database.close().catch(function () { return undefined; })];
|
|
350
|
+
case 5:
|
|
351
|
+
_a.sent();
|
|
352
|
+
client.close();
|
|
353
|
+
return [7 /*endfinally*/];
|
|
354
|
+
case 6:
|
|
355
|
+
statements = [
|
|
356
|
+
'CREATE INDEX db_test_batchddl_parent_pre_index ON db_test_batchddl_parent(name, id)',
|
|
357
|
+
'CREATE UNIQUE INDEX db_test_batchddl_parent_dup_unique ON db_test_batchddl_parent(name)',
|
|
358
|
+
'CREATE INDEX db_test_batchddl_parent_post_index ON db_test_batchddl_parent(id, name)',
|
|
359
|
+
];
|
|
360
|
+
logErrorSpy = jest.spyOn(logger_1.Logger.prototype, 'error');
|
|
361
|
+
return [4 /*yield*/, expect(spannerDriver.runUpdateSchema(statements)).rejects.toThrow(/uniqueness violation/)];
|
|
362
|
+
case 7:
|
|
363
|
+
_a.sent();
|
|
364
|
+
failureLog = logErrorSpy.mock.calls.find(function (_a) {
|
|
365
|
+
var entry = _a[0];
|
|
366
|
+
return entry.message === 'Failed when executing schema update';
|
|
367
|
+
});
|
|
368
|
+
expect(failureLog).toBeDefined();
|
|
369
|
+
expect(String(failureLog[0].obj.errorDetails)).toMatch(/uniqueness violation/);
|
|
370
|
+
return [4 /*yield*/, tableManager.schemaMetadata.getIndexes(parent)];
|
|
371
|
+
case 8:
|
|
372
|
+
indexes = _a.sent();
|
|
373
|
+
expect(indexes['db_test_batchddl_parent_pre_index']).toEqual(['name', 'id']);
|
|
374
|
+
expect(indexes['db_test_batchddl_parent_dup_unique']).toBeUndefined();
|
|
375
|
+
expect(indexes['db_test_batchddl_parent_post_index']).toBeUndefined();
|
|
376
|
+
return [4 /*yield*/, dropTable(parent)];
|
|
377
|
+
case 9:
|
|
378
|
+
_a.sent();
|
|
379
|
+
return [2 /*return*/];
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
}); }, 60000);
|
|
383
|
+
test('loadTables creates the whole absent set via one runUpdateSchema call; a second pass issues none', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
384
|
+
var registeredTables, _i, _a, table, spy, _b, registeredTables_1, table, _c;
|
|
385
|
+
return __generator(this, function (_d) {
|
|
386
|
+
switch (_d.label) {
|
|
387
|
+
case 0:
|
|
388
|
+
registeredTables = (0, db_1.getTables)();
|
|
389
|
+
// This package registers the migration table (@proteinjs/db) and the service-verbs doc table.
|
|
390
|
+
expect(registeredTables.length).toBeGreaterThanOrEqual(2);
|
|
391
|
+
_i = 0, _a = __spreadArray([], registeredTables, true).reverse();
|
|
392
|
+
_d.label = 1;
|
|
393
|
+
case 1:
|
|
394
|
+
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
395
|
+
table = _a[_i];
|
|
396
|
+
return [4 /*yield*/, dropTable(table)];
|
|
397
|
+
case 2:
|
|
398
|
+
_d.sent();
|
|
399
|
+
_d.label = 3;
|
|
400
|
+
case 3:
|
|
401
|
+
_i++;
|
|
402
|
+
return [3 /*break*/, 1];
|
|
403
|
+
case 4:
|
|
404
|
+
spy = jest.spyOn(spannerDriver, 'runUpdateSchema');
|
|
405
|
+
return [4 /*yield*/, tableManager.loadTables()];
|
|
406
|
+
case 5:
|
|
407
|
+
_d.sent();
|
|
408
|
+
expect(spy).toHaveBeenCalledTimes(1);
|
|
409
|
+
_b = 0, registeredTables_1 = registeredTables;
|
|
410
|
+
_d.label = 6;
|
|
411
|
+
case 6:
|
|
412
|
+
if (!(_b < registeredTables_1.length)) return [3 /*break*/, 9];
|
|
413
|
+
table = registeredTables_1[_b];
|
|
414
|
+
_c = expect;
|
|
415
|
+
return [4 /*yield*/, tableManager.tableExists(table)];
|
|
416
|
+
case 7:
|
|
417
|
+
_c.apply(void 0, [_d.sent()]).toBe(true);
|
|
418
|
+
_d.label = 8;
|
|
419
|
+
case 8:
|
|
420
|
+
_b++;
|
|
421
|
+
return [3 /*break*/, 6];
|
|
422
|
+
case 9:
|
|
423
|
+
// Reconcile pass on an up-to-date schema issues zero DDL.
|
|
424
|
+
spy.mockClear();
|
|
425
|
+
return [4 /*yield*/, tableManager.loadTables()];
|
|
426
|
+
case 10:
|
|
427
|
+
_d.sent();
|
|
428
|
+
expect(spy).not.toHaveBeenCalled();
|
|
429
|
+
return [2 /*return*/];
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}); }, 60000);
|
|
433
|
+
test('createDb with ddl births a queryable database; dropDb removes it', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
434
|
+
var databaseName, _a, client, database, rows, indexRows, _b;
|
|
435
|
+
return __generator(this, function (_c) {
|
|
436
|
+
switch (_c.label) {
|
|
437
|
+
case 0:
|
|
438
|
+
databaseName = 'batchddl-born';
|
|
439
|
+
return [4 /*yield*/, spannerDriver.dbExists(databaseName)];
|
|
440
|
+
case 1:
|
|
441
|
+
if (!_c.sent()) return [3 /*break*/, 3];
|
|
442
|
+
return [4 /*yield*/, spannerDriver.dropDb(databaseName)];
|
|
443
|
+
case 2:
|
|
444
|
+
_c.sent();
|
|
445
|
+
_c.label = 3;
|
|
446
|
+
case 3: return [4 /*yield*/, spannerDriver.createDb(databaseName, {
|
|
447
|
+
ddl: [
|
|
448
|
+
'CREATE TABLE born_row (id STRING(36) NOT NULL, label STRING(MAX)) PRIMARY KEY (id)',
|
|
449
|
+
'CREATE INDEX born_row_label_index ON born_row(label)',
|
|
450
|
+
],
|
|
451
|
+
})];
|
|
452
|
+
case 4:
|
|
453
|
+
_c.sent();
|
|
454
|
+
_a = expect;
|
|
455
|
+
return [4 /*yield*/, spannerDriver.dbExists(databaseName)];
|
|
456
|
+
case 5:
|
|
457
|
+
_a.apply(void 0, [_c.sent()]).toBe(true);
|
|
458
|
+
client = new spanner_1.Spanner({ projectId: spannerConfig.projectId });
|
|
459
|
+
database = client.instance(spannerConfig.instanceName).database(databaseName);
|
|
460
|
+
database.on('error', function () { return undefined; });
|
|
461
|
+
_c.label = 6;
|
|
462
|
+
case 6:
|
|
463
|
+
_c.trys.push([6, , 10, 12]);
|
|
464
|
+
return [4 /*yield*/, database.table('born_row').insert({ id: 'r1', label: 'born' })];
|
|
465
|
+
case 7:
|
|
466
|
+
_c.sent();
|
|
467
|
+
return [4 /*yield*/, database.run({ sql: 'SELECT id, label FROM born_row', json: true })];
|
|
468
|
+
case 8:
|
|
469
|
+
rows = (_c.sent())[0];
|
|
470
|
+
expect(rows).toEqual([{ id: 'r1', label: 'born' }]);
|
|
471
|
+
return [4 /*yield*/, database.run({
|
|
472
|
+
sql: "SELECT i.INDEX_NAME FROM INFORMATION_SCHEMA.INDEXES i WHERE i.TABLE_NAME = 'born_row' AND i.INDEX_NAME = 'born_row_label_index'",
|
|
473
|
+
json: true,
|
|
474
|
+
})];
|
|
475
|
+
case 9:
|
|
476
|
+
indexRows = (_c.sent())[0];
|
|
477
|
+
expect(indexRows).toHaveLength(1);
|
|
478
|
+
return [3 /*break*/, 12];
|
|
479
|
+
case 10: return [4 /*yield*/, database.close().catch(function () { return undefined; })];
|
|
480
|
+
case 11:
|
|
481
|
+
_c.sent();
|
|
482
|
+
client.close();
|
|
483
|
+
return [7 /*endfinally*/];
|
|
484
|
+
case 12: return [4 /*yield*/, spannerDriver.dropDb(databaseName)];
|
|
485
|
+
case 13:
|
|
486
|
+
_c.sent();
|
|
487
|
+
_b = expect;
|
|
488
|
+
return [4 /*yield*/, spannerDriver.dbExists(databaseName)];
|
|
489
|
+
case 14:
|
|
490
|
+
_b.apply(void 0, [_c.sent()]).toBe(false);
|
|
491
|
+
return [2 /*return*/];
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}); }, 60000);
|
|
495
|
+
});
|
|
496
|
+
//# sourceMappingURL=BatchedDdl.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BatchedDdl.test.js","sourceRoot":"","sources":["../../test/BatchedDdl.test.ts"],"names":[],"mappings":"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"}
|