spice-couchbase 2.0.61 → 2.0.63

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.
@@ -94,9 +94,10 @@ function createStatements(scope) {
94
94
  return statement.startsWith("CREATE INDEX ");
95
95
  });
96
96
  } // Isolate optimizer state and time without connecting to Couchbase or sleeping.
97
+ // Each load is a fresh module: its own seen-set, cooldown and policy.
97
98
 
98
99
 
99
- function createDatabase(durationMs) {
100
+ function loadDriver(durationMs) {
100
101
  var env = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
101
102
  var tick = BigInt(0);
102
103
  var module = {
@@ -117,7 +118,11 @@ function createDatabase(durationMs) {
117
118
  }
118
119
  }
119
120
  });
120
- var db = Object.create(module.exports.prototype);
121
+ return module.exports;
122
+ }
123
+
124
+ function instanceOf(Database) {
125
+ var db = Object.create(Database.prototype);
121
126
  db.bucket = "saturn";
122
127
  db.scope_name = "test";
123
128
  db.collection_name = "users";
@@ -137,6 +142,14 @@ function createDatabase(durationMs) {
137
142
  }()
138
143
  };
139
144
  return db;
145
+ } // Opted in wholesale: per-resource resolution has its own tests further down.
146
+
147
+
148
+ function createDatabase(durationMs) {
149
+ var env = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
150
+ var db = instanceOf(loadDriver(durationMs, env));
151
+ db.auto_optimize = true;
152
+ return db;
140
153
  }
141
154
 
142
155
  test("auto-optimization only starts above the default 3-second threshold",
@@ -373,4 +386,193 @@ _asyncToGenerator(function* () {
373
386
  collection: "_default"
374
387
  }));
375
388
  assert.match(createStatements(scope)[0].statement, /`saturn`\.`_default`\.`_default`/);
389
+ })); // ---- Per-resource opt-in for auto cover indexing ----
390
+ // Nothing decided at instance level: resolution falls through to the call,
391
+ // the application policy and the static lists.
392
+
393
+ function createUnconfiguredDatabase() {
394
+ var env = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
395
+ return instanceOf(loadDriver(3001, env));
396
+ }
397
+
398
+ function optimizationsFor(_x2, _x3) {
399
+ return _optimizationsFor.apply(this, arguments);
400
+ }
401
+
402
+ function _optimizationsFor() {
403
+ _optimizationsFor = _asyncToGenerator(function* (db, statement) {
404
+ var optimizations = 0;
405
+ db.optimize =
406
+ /*#__PURE__*/
407
+ _asyncToGenerator(function* () {
408
+ optimizations += 1;
409
+ });
410
+
411
+ for (var _len = arguments.length, queryArgs = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
412
+ queryArgs[_key - 2] = arguments[_key];
413
+ }
414
+
415
+ yield db.query(statement, ...queryArgs);
416
+ return optimizations;
417
+ });
418
+ return _optimizationsFor.apply(this, arguments);
419
+ }
420
+
421
+ var slowLookup = "SELECT name FROM users WHERE status = 'active'";
422
+ var EVERY_RESOURCE = {
423
+ SPICE_COUCHBASE_OPTIMIZE_RESOURCES: "*"
424
+ };
425
+ test("no resource is auto-indexed unless something opts it in",
426
+ /*#__PURE__*/
427
+ _asyncToGenerator(function* () {
428
+ assert.equal((yield optimizationsFor(createUnconfiguredDatabase(), slowLookup)), 0);
429
+ assert.equal((yield optimizationsFor(createUnconfiguredDatabase({
430
+ SPICE_COUCHBASE_OPTIMIZE_RESOURCES: ""
431
+ }), slowLookup)), 0);
432
+ }));
433
+ test("SPICE_COUCHBASE_OPTIMIZE_RESOURCES enables the instance's collection, case-insensitively",
434
+ /*#__PURE__*/
435
+ _asyncToGenerator(function* () {
436
+ var env = {
437
+ SPICE_COUCHBASE_OPTIMIZE_RESOURCES: " Users ,audit_log,, `sessions` "
438
+ };
439
+ assert.equal((yield optimizationsFor(createUnconfiguredDatabase(env), slowLookup)), 1);
440
+ var sessions = createUnconfiguredDatabase(env);
441
+ sessions.collection_name = "sessions";
442
+ assert.equal((yield optimizationsFor(sessions, "SELECT id FROM sessions")), 1);
443
+ var orders = createUnconfiguredDatabase(env);
444
+ orders.collection_name = "orders";
445
+ assert.equal((yield optimizationsFor(orders, "SELECT total FROM orders WHERE status = 'paid'")), 0);
446
+ }));
447
+ test("a wildcard restores auto indexing for every resource",
448
+ /*#__PURE__*/
449
+ _asyncToGenerator(function* () {
450
+ var db = createUnconfiguredDatabase(EVERY_RESOURCE);
451
+ db.collection_name = "anything";
452
+ assert.equal((yield optimizationsFor(db, "SELECT a FROM anything WHERE b = 1")), 1);
453
+ }));
454
+ test("legacy bucket mode resolves the resource from the type literal the driver adds",
455
+ /*#__PURE__*/
456
+ _asyncToGenerator(function* () {
457
+ var env = {
458
+ SPICE_COUCHBASE_OPTIMIZE_RESOURCES: "audit_log"
459
+ };
460
+
461
+ for (var [type, expected] of [["audit_log", 1], ["users", 0]]) {
462
+ var db = createUnconfiguredDatabase(env);
463
+ db.collection_name = "_default";
464
+ db.scope_name = "_default";
465
+ assert.equal((yield optimizationsFor(db, "SELECT actor FROM `saturn` WHERE type = '".concat(type, "' AND deleted = false"))), expected, type);
466
+ }
467
+ }));
468
+ test("a fully qualified or aliased FROM keyspace matches on its last segment",
469
+ /*#__PURE__*/
470
+ _asyncToGenerator(function* () {
471
+ var env = {
472
+ SPICE_COUCHBASE_OPTIMIZE_RESOURCES: "logs"
473
+ };
474
+
475
+ for (var statement of ["SELECT level FROM `default`:`saturn`.`app`.`logs` WHERE level = 'error'", "SELECT l.level FROM saturn.app.logs AS l WHERE l.level = 'error'", "SELECT u.name FROM users AS u JOIN `logs` AS l ON l.user_id = META(u).id"]) {
476
+ var db = createUnconfiguredDatabase(env);
477
+ db.collection_name = "_default";
478
+ assert.equal((yield optimizationsFor(db, statement)), 1, statement);
479
+ }
480
+ }));
481
+ test("connection or constructor lists work without the environment variable",
482
+ /*#__PURE__*/
483
+ _asyncToGenerator(function* () {
484
+ var db = createUnconfiguredDatabase();
485
+ db.enabled_resources = new Set(["users"]);
486
+ assert.equal((yield optimizationsFor(db, slowLookup)), 1);
487
+ }));
488
+ test("an explicit instance setting overrides every resource list",
489
+ /*#__PURE__*/
490
+ _asyncToGenerator(function* () {
491
+ var on = createUnconfiguredDatabase();
492
+ on.auto_optimize = true;
493
+ assert.equal((yield optimizationsFor(on, slowLookup)), 1);
494
+ var off = createUnconfiguredDatabase(EVERY_RESOURCE);
495
+ off.auto_optimize = false;
496
+ assert.equal((yield optimizationsFor(off, slowLookup)), 0);
497
+ }));
498
+ test("a single call can opt in or out through query options",
499
+ /*#__PURE__*/
500
+ _asyncToGenerator(function* () {
501
+ assert.equal((yield optimizationsFor(createUnconfiguredDatabase(), slowLookup, {
502
+ auto_optimize: true
503
+ })), 1);
504
+ assert.equal((yield optimizationsFor(createUnconfiguredDatabase(EVERY_RESOURCE), slowLookup, {
505
+ auto_optimize: false
506
+ })), 0);
507
+ assert.equal((yield optimizationsFor(createUnconfiguredDatabase(EVERY_RESOURCE), slowLookup, "cluster", {
508
+ optimize: false
509
+ })), 0); // The scan-consistency shorthand is not an opt-in or opt-out.
510
+
511
+ assert.equal((yield optimizationsFor(createUnconfiguredDatabase(EVERY_RESOURCE), slowLookup, "cluster", true)), 1);
512
+ assert.equal((yield optimizationsFor(createUnconfiguredDatabase(), slowLookup, "cluster", true)), 0);
513
+ }));
514
+ test("an application policy decides per resource and sees the statement context",
515
+ /*#__PURE__*/
516
+ _asyncToGenerator(function* () {
517
+ var Database = loadDriver(3001);
518
+ var seen = [];
519
+ Database.setAutoOptimizePolicy((resource, context) => {
520
+ seen.push([resource, context]);
521
+ return resource === "users";
522
+ });
523
+ assert.equal(Database.getAutoOptimizePolicy().length, 2);
524
+ var users = instanceOf(Database);
525
+ users.connection_name = "default";
526
+ assert.equal((yield optimizationsFor(users, slowLookup)), 1); // Objects cross the vm boundary, so compare by value rather than prototype.
527
+
528
+ assert.equal(JSON.stringify(seen[0]), JSON.stringify(["users", {
529
+ query: slowLookup,
530
+ connection: "default",
531
+ collection: "users"
532
+ }]));
533
+ var orders = instanceOf(Database);
534
+ orders.collection_name = "orders";
535
+ assert.equal((yield optimizationsFor(orders, "SELECT total FROM orders WHERE status = 'paid'")), 0);
536
+ }));
537
+ test("a policy that returns undefined defers to the static lists",
538
+ /*#__PURE__*/
539
+ _asyncToGenerator(function* () {
540
+ for (var [env, expected] of [[{
541
+ SPICE_COUCHBASE_OPTIMIZE_RESOURCES: "users"
542
+ }, 1], [{}, 0]]) {
543
+ var Database = loadDriver(3001, env);
544
+ Database.setAutoOptimizePolicy(() => undefined);
545
+ assert.equal((yield optimizationsFor(instanceOf(Database), slowLookup)), expected);
546
+ }
547
+ }));
548
+ test("an explicit policy refusal wins over the wildcard, and a throwing policy counts as a refusal",
549
+ /*#__PURE__*/
550
+ _asyncToGenerator(function* () {
551
+ for (var policy of [() => false, () => {
552
+ throw new Error("settings unavailable");
553
+ }]) {
554
+ var Database = loadDriver(3001, EVERY_RESOURCE);
555
+ Database.setAutoOptimizePolicy(policy);
556
+ assert.equal((yield optimizationsFor(instanceOf(Database), slowLookup)), 0);
557
+ }
558
+ }));
559
+ test("the policy can be cleared and must be a function",
560
+ /*#__PURE__*/
561
+ _asyncToGenerator(function* () {
562
+ var Database = loadDriver(3001, EVERY_RESOURCE);
563
+ Database.setAutoOptimizePolicy(() => false);
564
+ Database.setAutoOptimizePolicy(null);
565
+ assert.equal(Database.getAutoOptimizePolicy(), null);
566
+ assert.equal((yield optimizationsFor(instanceOf(Database), slowLookup)), 1);
567
+ assert.throws(() => Database.setAutoOptimizePolicy("users"), {
568
+ name: "TypeError"
569
+ });
570
+ }));
571
+ test("a declined statement is not remembered as already optimised",
572
+ /*#__PURE__*/
573
+ _asyncToGenerator(function* () {
574
+ var db = createUnconfiguredDatabase();
575
+ assert.equal((yield optimizationsFor(db, slowLookup)), 0);
576
+ db.auto_optimize = true;
577
+ assert.equal((yield optimizationsFor(db, slowLookup)), 1);
376
578
  }));