spice-couchbase 2.0.55 → 2.0.57
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/build/index.js +8 -3
- package/package.json +3 -2
- package/src/index.count-query.test.js +129 -0
- package/src/index.js +9 -2
package/build/index.js
CHANGED
|
@@ -704,10 +704,15 @@ module.exports = class Database {
|
|
|
704
704
|
|
|
705
705
|
if (query) {
|
|
706
706
|
conditions.push(query);
|
|
707
|
-
}
|
|
707
|
+
} // The conditions are folded into `where_clause` itself so that both queries below are built
|
|
708
|
+
// from one string. Previously this held the bare literal " WHERE " and only the data query
|
|
709
|
+
// appended `conditions.join(" AND ")`, which left the count query emitting a dangling
|
|
710
|
+
// `WHERE` — Couchbase answered "syntax error - at end of input" and every `do_count=true`
|
|
711
|
+
// request failed with a 400, on every resource.
|
|
712
|
+
|
|
708
713
|
|
|
709
|
-
var where_clause = conditions.length ? " WHERE " : "";
|
|
710
|
-
query = front_query + where_clause
|
|
714
|
+
var where_clause = conditions.length ? " WHERE ".concat(conditions.join(" AND ")) : "";
|
|
715
|
+
query = front_query + where_clause;
|
|
711
716
|
var count_query = "SELECT count(meta(".concat(bucket, ").id) as count FROM ").concat(bucket, " ").concat(join, " ").concat(where_clause); //console.log("Cound Query::", count_query);
|
|
712
717
|
|
|
713
718
|
var order_by_clause = order_by ? " ORDER BY ".concat(order_by) : "";
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spice-couchbase",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.57",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "node src/utility.test.js",
|
|
8
|
-
"test:query-consistency": "node src/index.query-consistency.test.js"
|
|
8
|
+
"test:query-consistency": "node src/index.query-consistency.test.js",
|
|
9
|
+
"test:count-query": "node src/index.count-query.test.js"
|
|
9
10
|
},
|
|
10
11
|
"author": "Chad Fraser <chad@sonover.com> (http://sonover.com)",
|
|
11
12
|
"license": "ISC",
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Regression tests for the WHERE clause shared by the data and count queries in `search()`.
|
|
5
|
+
*
|
|
6
|
+
* The count query used to be built from a `where_clause` that held the bare literal `" WHERE "`,
|
|
7
|
+
* while the conditions were appended only to the data query. Every `do_count` request therefore
|
|
8
|
+
* emitted `... FROM \`bucket\` WHERE` and Couchbase answered
|
|
9
|
+
* "syntax error - at end of input" (code 3000) with a 400 — on every resource, for every caller.
|
|
10
|
+
*
|
|
11
|
+
* It survived the existing suite because nothing exercised the count statement.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const assert = require("assert");
|
|
15
|
+
const Database = require("./index");
|
|
16
|
+
|
|
17
|
+
let passed = 0;
|
|
18
|
+
let failed = 0;
|
|
19
|
+
|
|
20
|
+
/** Captures the two statements `search()` produces without touching a cluster. */
|
|
21
|
+
function createSearchDb() {
|
|
22
|
+
const statements = { data: null, count: null };
|
|
23
|
+
const db = Object.create(Database.prototype);
|
|
24
|
+
|
|
25
|
+
db.use_bucket_name = false;
|
|
26
|
+
db.bucket = "test";
|
|
27
|
+
db.scope_name = "scope";
|
|
28
|
+
db.collection_name = "platformtask";
|
|
29
|
+
|
|
30
|
+
db.getData = async (statement) => {
|
|
31
|
+
statements.data = statement;
|
|
32
|
+
return [];
|
|
33
|
+
};
|
|
34
|
+
db.getCount = async (statement) => {
|
|
35
|
+
statements.count = statement;
|
|
36
|
+
return 0;
|
|
37
|
+
};
|
|
38
|
+
db.optimize = () => {};
|
|
39
|
+
|
|
40
|
+
return { db, statements };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function test(name, fn) {
|
|
44
|
+
try {
|
|
45
|
+
await fn();
|
|
46
|
+
console.log(`✓ ${name}`);
|
|
47
|
+
passed += 1;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.log(`✗ ${name}`);
|
|
50
|
+
console.log(` Error: ${error.stack || error.message}`);
|
|
51
|
+
failed += 1;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function run() {
|
|
56
|
+
console.log("\n--- count query tests ---");
|
|
57
|
+
|
|
58
|
+
await test("the count query carries the predicates, not a dangling WHERE", async () => {
|
|
59
|
+
const { db, statements } = createSearchDb();
|
|
60
|
+
|
|
61
|
+
await db.search("platformtask", "id", `status = "pending"`, 1, 0, null, "true");
|
|
62
|
+
|
|
63
|
+
assert.ok(
|
|
64
|
+
statements.count.includes(`status = "pending"`),
|
|
65
|
+
`count query lost its predicate: ${statements.count}`
|
|
66
|
+
);
|
|
67
|
+
assert.ok(
|
|
68
|
+
!/WHERE\s*$/.test(statements.count.trim()),
|
|
69
|
+
`count query ends in a dangling WHERE: ${statements.count}`
|
|
70
|
+
);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
await test("multiple conditions are joined with AND in the count query", async () => {
|
|
74
|
+
const { db, statements } = createSearchDb();
|
|
75
|
+
|
|
76
|
+
await db.search(
|
|
77
|
+
"platformtask",
|
|
78
|
+
"id",
|
|
79
|
+
`status = "pending" AND assignee_type = "user"`,
|
|
80
|
+
1,
|
|
81
|
+
0,
|
|
82
|
+
null,
|
|
83
|
+
"true"
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
assert.ok(statements.count.includes(`status = "pending"`));
|
|
87
|
+
assert.ok(statements.count.includes(`assignee_type = "user"`));
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
await test("an unfiltered count emits no WHERE at all", async () => {
|
|
91
|
+
const { db, statements } = createSearchDb();
|
|
92
|
+
|
|
93
|
+
await db.search("platformtask", "id", "", 1, 0, null, "true");
|
|
94
|
+
|
|
95
|
+
assert.ok(
|
|
96
|
+
!/WHERE/i.test(statements.count),
|
|
97
|
+
`unfiltered count should have no WHERE: ${statements.count}`
|
|
98
|
+
);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
await test("the data and count queries agree on the WHERE clause", async () => {
|
|
102
|
+
const { db, statements } = createSearchDb();
|
|
103
|
+
|
|
104
|
+
await db.search("platformtask", "id", `status = "blocked"`, 1, 0, null, "true");
|
|
105
|
+
|
|
106
|
+
const whereOf = (sql) => {
|
|
107
|
+
const m = sql.match(/WHERE\s+(.*?)(?:\s+ORDER BY|\s+LIMIT|\s+OFFSET|$)/is);
|
|
108
|
+
return m ? m[1].trim() : null;
|
|
109
|
+
};
|
|
110
|
+
assert.strictEqual(whereOf(statements.data), whereOf(statements.count));
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
await test("no count statement is produced when do_count is off", async () => {
|
|
114
|
+
const { db, statements } = createSearchDb();
|
|
115
|
+
|
|
116
|
+
await db.search("platformtask", "id", `status = "pending"`, 1, 0, null, "false");
|
|
117
|
+
|
|
118
|
+
assert.strictEqual(statements.count, null);
|
|
119
|
+
assert.ok(statements.data.includes(`status = "pending"`));
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
console.log("\n========================================");
|
|
123
|
+
console.log(`Tests: ${passed + failed} | Passed: ${passed} | Failed: ${failed}`);
|
|
124
|
+
console.log("========================================");
|
|
125
|
+
|
|
126
|
+
if (failed > 0) process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
run();
|
package/src/index.js
CHANGED
|
@@ -671,8 +671,15 @@ module.exports = class Database {
|
|
|
671
671
|
conditions.push(query);
|
|
672
672
|
}
|
|
673
673
|
|
|
674
|
-
|
|
675
|
-
|
|
674
|
+
// The conditions are folded into `where_clause` itself so that both queries below are built
|
|
675
|
+
// from one string. Previously this held the bare literal " WHERE " and only the data query
|
|
676
|
+
// appended `conditions.join(" AND ")`, which left the count query emitting a dangling
|
|
677
|
+
// `WHERE` — Couchbase answered "syntax error - at end of input" and every `do_count=true`
|
|
678
|
+
// request failed with a 400, on every resource.
|
|
679
|
+
const where_clause = conditions.length
|
|
680
|
+
? ` WHERE ${conditions.join(" AND ")}`
|
|
681
|
+
: "";
|
|
682
|
+
query = front_query + where_clause;
|
|
676
683
|
|
|
677
684
|
const count_query = `SELECT count(meta(${bucket}).id) as count FROM ${bucket} ${join} ${where_clause}`;
|
|
678
685
|
//console.log("Cound Query::", count_query);
|