rqlite-js 2.5.7 → 2.6.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/README.md +174 -155
- package/lib/api/backup/index.js +46 -46
- package/lib/api/backup/index.js.map +1 -1
- package/lib/api/backup/test.unit.js +45 -0
- package/lib/api/backup/test.unit.js.map +1 -0
- package/lib/api/backup-formats.js +16 -0
- package/lib/api/backup-formats.js.map +1 -0
- package/lib/api/client/index.js +63 -42
- package/lib/api/client/index.js.map +1 -1
- package/lib/api/client/test.unit.js +53 -0
- package/lib/api/client/test.unit.js.map +1 -0
- package/lib/api/consistency-levels.js +30 -0
- package/lib/api/consistency-levels.js.map +1 -0
- package/lib/api/data/index.js +50 -72
- package/lib/api/data/index.js.map +1 -1
- package/lib/api/data/test.unit.js +98 -0
- package/lib/api/data/test.unit.js.map +1 -0
- package/lib/api/paths.js +33 -0
- package/lib/api/paths.js.map +1 -0
- package/lib/api/query-params.js +43 -0
- package/lib/api/query-params.js.map +1 -0
- package/lib/api/results/data-result-error.js +39 -10
- package/lib/api/results/data-result-error.js.map +1 -1
- package/lib/api/results/data-result.js +57 -51
- package/lib/api/results/data-result.js.map +1 -1
- package/lib/api/results/data-results.js +50 -30
- package/lib/api/results/data-results.js.map +1 -1
- package/lib/api/results/index.js +1 -1
- package/lib/api/results/result-fields.js +47 -0
- package/lib/api/results/result-fields.js.map +1 -0
- package/lib/api/results/test.unit.js +238 -0
- package/lib/api/results/test.unit.js.map +1 -0
- package/lib/api/status/index.js +40 -28
- package/lib/api/status/index.js.map +1 -1
- package/lib/api/status/test.unit.js +57 -0
- package/lib/api/status/test.unit.js.map +1 -0
- package/lib/http-request/auth-keys.js +15 -0
- package/lib/http-request/auth-keys.js.map +1 -0
- package/lib/http-request/http-headers.js +20 -0
- package/lib/http-request/http-headers.js.map +1 -0
- package/lib/http-request/index.js +291 -271
- package/lib/http-request/index.js.map +1 -1
- package/lib/http-request/test.unit.js +560 -0
- package/lib/http-request/test.unit.js.map +1 -0
- package/lib/index.js +23 -4
- package/lib/index.js.map +1 -1
- package/lib/test/api-data-execute-nock.js +142 -0
- package/lib/test/api-data-execute-nock.js.map +1 -0
- package/lib/test/api-data-query-nock.js +210 -0
- package/lib/test/api-data-query-nock.js.map +1 -0
- package/lib/test/backups/backup-nock.js +29 -0
- package/lib/test/backups/backup-nock.js.map +1 -0
- package/lib/test/backups/restore-nock.js +30 -0
- package/lib/test/backups/restore-nock.js.map +1 -0
- package/lib/test/env.js +15 -0
- package/lib/test/env.js.map +1 -0
- package/lib/test/unit/index.unit.js +27 -0
- package/lib/test/unit/index.unit.js.map +1 -0
- package/lib/test.integration.js +238 -0
- package/lib/test.integration.js.map +1 -0
- package/package.json +33 -23
- package/.eslintrc +0 -20
- package/.travis.yml +0 -24
- package/es6/api/backup/index.js +0 -71
- package/es6/api/client/index.js +0 -83
- package/es6/api/data/index.js +0 -129
- package/es6/api/results/data-result-error.js +0 -32
- package/es6/api/results/data-result.js +0 -134
- package/es6/api/results/data-results.js +0 -121
- package/es6/api/results/index.js +0 -7
- package/es6/api/status/index.js +0 -54
- package/es6/http-request/content-types.js +0 -4
- package/es6/http-request/errors.js +0 -16
- package/es6/http-request/http-methods.js +0 -39
- package/es6/http-request/index.js +0 -743
- package/es6/http-request/retryable.js +0 -41
- package/es6/index.js +0 -19
- package/jsconfig.json +0 -19
package/lib/api/client/index.js
CHANGED
|
@@ -1,34 +1,51 @@
|
|
|
1
|
-
"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports, "__esModule", { value: true });exports.createQuery = createQuery;exports.default = void 0;
|
|
1
|
+
"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports, "__esModule", { value: true });exports.createQuery = createQuery;exports.default = void 0;
|
|
2
|
+
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
var _httpRequest = _interopRequireDefault(require("../../http-request"));
|
|
6
|
-
var _httpMethods = require("../../http-request/http-methods");
|
|
7
|
+
var _httpMethods = require("../../http-request/http-methods");
|
|
8
|
+
var _queryParams = require("../query-params"); /**
|
|
7
9
|
* Base API client for RQLite which abstracts the HTTP calls
|
|
8
10
|
* @module api/client
|
|
9
|
-
|
|
10
|
-
* @typedef HttpRequestOptions
|
|
11
|
-
* @type {import('../../http-request').HttpRequestOptions}
|
|
11
|
+
* @see https://rqlite.io/docs/api/api/
|
|
12
12
|
*/
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* RQLite API query-string / request options for data endpoints
|
|
19
|
+
* @typedef {Object} ApiClientRequestOptions
|
|
20
|
+
* @property {Boolean} [useLeader] Prefer the leader host
|
|
21
|
+
* @property {String} [level] Consistency level
|
|
22
|
+
* @property {Boolean} [pretty] Pretty-print JSON
|
|
23
|
+
* @property {Boolean} [timings] Include timings
|
|
24
|
+
* @property {Boolean} [atomic] Transaction (RQLite v5+)
|
|
25
|
+
* @property {Boolean} [transaction] Transaction (RQLite v4)
|
|
26
|
+
* @property {Boolean} [raw] Return raw HTTP response
|
|
27
|
+
*/
|
|
28
|
+
|
|
13
29
|
/**
|
|
14
30
|
* Create the base HTTP query options from RQLite API options
|
|
15
|
-
* @param {
|
|
16
|
-
* @param {String} [options.level] The consistency level
|
|
17
|
-
* @param {String} [options.pretty] Pretty print the response body
|
|
18
|
-
* @param {String} [options.timings] Provide query timings
|
|
19
|
-
* @param {String} [options.atomic] Treat all commands in the request as a single transaction
|
|
20
|
-
* for RQLite v5 and higher
|
|
21
|
-
* @param {String} [options.transaction] Treat all commands in the request as a single transaction
|
|
22
|
-
* for RQLite v4 and lower
|
|
31
|
+
* @param {ApiClientRequestOptions} [options={}] The RQLite API options
|
|
23
32
|
* @returns {Object} The HTTP query
|
|
33
|
+
* @see https://rqlite.io/docs/api/api/
|
|
34
|
+
* @see module:api/query-params
|
|
24
35
|
*/
|
|
25
36
|
function createQuery(options = {}) {
|
|
26
|
-
const
|
|
37
|
+
const { level, pretty, timings, atomic, transaction } = options;
|
|
27
38
|
|
|
28
39
|
// Remove all undefined values
|
|
29
|
-
const query = {
|
|
40
|
+
const query = {
|
|
41
|
+
[_queryParams.QUERY_PARAM_LEVEL]: level,
|
|
42
|
+
[_queryParams.QUERY_PARAM_PRETTY]: pretty,
|
|
43
|
+
[_queryParams.QUERY_PARAM_TIMINGS]: timings,
|
|
44
|
+
[_queryParams.QUERY_PARAM_ATOMIC]: atomic,
|
|
45
|
+
[_queryParams.QUERY_PARAM_TRANSACTION]: transaction
|
|
46
|
+
};
|
|
30
47
|
return Object.entries(query).reduce((acc, entry) => {
|
|
31
|
-
const
|
|
48
|
+
const [key, val] = entry;
|
|
32
49
|
// Only take defined values
|
|
33
50
|
if (typeof val !== 'undefined') {
|
|
34
51
|
acc[key] = val;
|
|
@@ -46,39 +63,43 @@ class ApiClient extends _httpRequest.default {
|
|
|
46
63
|
* Perform a RQLite data API get request
|
|
47
64
|
* @param {String} path The path for the request i.e. /db/query
|
|
48
65
|
* @param {String} sql The SQL query
|
|
49
|
-
* @param {
|
|
66
|
+
* @param {ApiClientRequestOptions} [options={}] RQLite API options
|
|
67
|
+
* @returns {Promise<{status: Number, body: *}>}
|
|
68
|
+
* @see https://rqlite.io/docs/api/api/
|
|
50
69
|
*/
|
|
51
|
-
get(path, sql, options = {}) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
async get(path, sql, options = {}) {
|
|
71
|
+
const { useLeader } = options;
|
|
72
|
+
if (!path) {
|
|
73
|
+
throw new Error('The path argument is required');
|
|
74
|
+
}
|
|
75
|
+
return super.get({
|
|
76
|
+
useLeader,
|
|
77
|
+
uri: path,
|
|
78
|
+
httpMethod: _httpMethods.HTTP_METHOD_GET,
|
|
79
|
+
query: { ...createQuery(options), [_queryParams.QUERY_PARAM_Q]: sql }
|
|
80
|
+
});
|
|
62
81
|
}
|
|
63
82
|
|
|
64
83
|
/**
|
|
65
84
|
* Perform a RQLite data API post request
|
|
66
85
|
* @param {String} path The path for the request i.e. /db/query
|
|
67
|
-
* @param {String} sql The SQL query
|
|
68
|
-
* @param {
|
|
86
|
+
* @param {String|String[]} sql The SQL query or queries
|
|
87
|
+
* @param {ApiClientRequestOptions} [options={}] RQLite API options
|
|
88
|
+
* @returns {Promise<{status: Number, body: *}>}
|
|
89
|
+
* @see https://rqlite.io/docs/api/api/
|
|
69
90
|
*/
|
|
70
|
-
post(path, sql, options = {}) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
91
|
+
async post(path, sql, options = {}) {
|
|
92
|
+
const { useLeader } = options;
|
|
93
|
+
if (!path) {
|
|
94
|
+
throw new Error('The path argument is required');
|
|
95
|
+
}
|
|
96
|
+
return super.post({
|
|
97
|
+
useLeader,
|
|
98
|
+
uri: path,
|
|
99
|
+
httpMethod: _httpMethods.HTTP_METHOD_POST,
|
|
100
|
+
query: createQuery(options),
|
|
101
|
+
body: Array.isArray(sql) ? sql : [sql]
|
|
102
|
+
});
|
|
82
103
|
}
|
|
83
104
|
}exports.default = ApiClient;
|
|
84
105
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_httpRequest","_interopRequireDefault","require","_httpMethods","
|
|
1
|
+
{"version":3,"file":"index.js","names":["_httpRequest","_interopRequireDefault","require","_httpMethods","_queryParams","createQuery","options","level","pretty","timings","atomic","transaction","query","QUERY_PARAM_LEVEL","QUERY_PARAM_PRETTY","QUERY_PARAM_TIMINGS","QUERY_PARAM_ATOMIC","QUERY_PARAM_TRANSACTION","Object","entries","reduce","acc","entry","key","val","ApiClient","HttpRequest","get","path","sql","useLeader","Error","uri","httpMethod","HTTP_METHOD_GET","QUERY_PARAM_Q","post","HTTP_METHOD_POST","body","Array","isArray","exports","default"],"sources":["../../../es6/api/client/index.js"],"sourcesContent":["/**\n * Base API client for RQLite which abstracts the HTTP calls\n * @module api/client\n * @see https://rqlite.io/docs/api/api/\n */\nimport HttpRequest from '../../http-request'\nimport { HTTP_METHOD_GET, HTTP_METHOD_POST } from '../../http-request/http-methods'\nimport {\n QUERY_PARAM_ATOMIC,\n QUERY_PARAM_LEVEL,\n QUERY_PARAM_PRETTY,\n QUERY_PARAM_Q,\n QUERY_PARAM_TIMINGS,\n QUERY_PARAM_TRANSACTION,\n} from '../query-params'\n\n/**\n * RQLite API query-string / request options for data endpoints\n * @typedef {Object} ApiClientRequestOptions\n * @property {Boolean} [useLeader] Prefer the leader host\n * @property {String} [level] Consistency level\n * @property {Boolean} [pretty] Pretty-print JSON\n * @property {Boolean} [timings] Include timings\n * @property {Boolean} [atomic] Transaction (RQLite v5+)\n * @property {Boolean} [transaction] Transaction (RQLite v4)\n * @property {Boolean} [raw] Return raw HTTP response\n */\n\n/**\n * Create the base HTTP query options from RQLite API options\n * @param {ApiClientRequestOptions} [options={}] The RQLite API options\n * @returns {Object} The HTTP query\n * @see https://rqlite.io/docs/api/api/\n * @see module:api/query-params\n */\nexport function createQuery (options = {}) {\n const { level, pretty, timings, atomic, transaction } = options\n\n // Remove all undefined values\n const query = {\n [QUERY_PARAM_LEVEL]: level,\n [QUERY_PARAM_PRETTY]: pretty,\n [QUERY_PARAM_TIMINGS]: timings,\n [QUERY_PARAM_ATOMIC]: atomic,\n [QUERY_PARAM_TRANSACTION]: transaction,\n }\n return Object.entries(query).reduce((acc, entry) => {\n const [key, val] = entry\n // Only take defined values\n if (typeof val !== 'undefined') {\n acc[key] = val\n }\n return acc\n }, {})\n}\n\n/**\n * Base API client for RQLite which abstracts the HTTP calls\n * from the user\n */\nexport default class ApiClient extends HttpRequest {\n /**\n * Perform a RQLite data API get request\n * @param {String} path The path for the request i.e. /db/query\n * @param {String} sql The SQL query\n * @param {ApiClientRequestOptions} [options={}] RQLite API options\n * @returns {Promise<{status: Number, body: *}>}\n * @see https://rqlite.io/docs/api/api/\n */\n async get (path, sql, options = {}) {\n const { useLeader } = options\n if (!path) {\n throw new Error('The path argument is required')\n }\n return super.get({\n useLeader,\n uri: path,\n httpMethod: HTTP_METHOD_GET,\n query: { ...createQuery(options), [QUERY_PARAM_Q]: sql },\n })\n }\n\n /**\n * Perform a RQLite data API post request\n * @param {String} path The path for the request i.e. /db/query\n * @param {String|String[]} sql The SQL query or queries\n * @param {ApiClientRequestOptions} [options={}] RQLite API options\n * @returns {Promise<{status: Number, body: *}>}\n * @see https://rqlite.io/docs/api/api/\n */\n async post (path, sql, options = {}) {\n const { useLeader } = options\n if (!path) {\n throw new Error('The path argument is required')\n }\n return super.post({\n useLeader,\n uri: path,\n httpMethod: HTTP_METHOD_POST,\n query: createQuery(options),\n body: Array.isArray(sql) ? sql : [sql],\n })\n }\n}\n"],"mappings":";;;;;AAKA,IAAAA,YAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AACA,IAAAE,YAAA,GAAAF,OAAA,oBAOwB,CAdxB;AACA;AACA;AACA;AACA;;;;;AAYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,WAAWA,CAAEC,OAAO,GAAG,CAAC,CAAC,EAAE;EACzC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,OAAO,EAAEC,MAAM,EAAEC,WAAW,CAAC,CAAC,GAAGL,OAAO;;EAE/D;EACA,MAAMM,KAAK,GAAG;IACZ,CAACC,8BAAiB,GAAGN,KAAK;IAC1B,CAACO,+BAAkB,GAAGN,MAAM;IAC5B,CAACO,gCAAmB,GAAGN,OAAO;IAC9B,CAACO,+BAAkB,GAAGN,MAAM;IAC5B,CAACO,oCAAuB,GAAGN;EAC7B,CAAC;EACD,OAAOO,MAAM,CAACC,OAAO,CAACP,KAAK,CAAC,CAACQ,MAAM,CAAC,CAACC,GAAG,EAAEC,KAAK,KAAK;IAClD,MAAM,CAACC,GAAG,EAAEC,GAAG,CAAC,GAAGF,KAAK;IACxB;IACA,IAAI,OAAOE,GAAG,KAAK,WAAW,EAAE;MAC9BH,GAAG,CAACE,GAAG,CAAC,GAAGC,GAAG;IAChB;IACA,OAAOH,GAAG;EACZ,CAAC,EAAE,CAAC,CAAC,CAAC;AACR;;AAEA;AACA;AACA;AACA;AACe,MAAMI,SAAS,SAASC,oBAAW,CAAC;EACjD;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACE,MAAMC,GAAGA,CAAEC,IAAI,EAAEC,GAAG,EAAEvB,OAAO,GAAG,CAAC,CAAC,EAAE;IAClC,MAAM,EAAEwB,SAAS,CAAC,CAAC,GAAGxB,OAAO;IAC7B,IAAI,CAACsB,IAAI,EAAE;MACT,MAAM,IAAIG,KAAK,CAAC,+BAA+B,CAAC;IAClD;IACA,OAAO,KAAK,CAACJ,GAAG,CAAC;MACfG,SAAS;MACTE,GAAG,EAAEJ,IAAI;MACTK,UAAU,EAAEC,4BAAe;MAC3BtB,KAAK,EAAE,EAAE,GAAGP,WAAW,CAACC,OAAO,CAAC,EAAE,CAAC6B,0BAAa,GAAGN,GAAG,CAAC;IACzD,CAAC,CAAC;EACJ;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACE,MAAMO,IAAIA,CAAER,IAAI,EAAEC,GAAG,EAAEvB,OAAO,GAAG,CAAC,CAAC,EAAE;IACnC,MAAM,EAAEwB,SAAS,CAAC,CAAC,GAAGxB,OAAO;IAC7B,IAAI,CAACsB,IAAI,EAAE;MACT,MAAM,IAAIG,KAAK,CAAC,+BAA+B,CAAC;IAClD;IACA,OAAO,KAAK,CAACK,IAAI,CAAC;MAChBN,SAAS;MACTE,GAAG,EAAEJ,IAAI;MACTK,UAAU,EAAEI,6BAAgB;MAC5BzB,KAAK,EAAEP,WAAW,CAACC,OAAO,CAAC;MAC3BgC,IAAI,EAAEC,KAAK,CAACC,OAAO,CAACX,GAAG,CAAC,GAAGA,GAAG,GAAG,CAACA,GAAG;IACvC,CAAC,CAAC;EACJ;AACF,CAACY,OAAA,CAAAC,OAAA,GAAAjB,SAAA","ignoreList":[]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";var _chai = require("chai");
|
|
2
|
+
var _data = require("../data");
|
|
3
|
+
var _apiDataQueryNock = require("../../test/api-data-query-nock");
|
|
4
|
+
var _apiDataExecuteNock = require("../../test/api-data-execute-nock");
|
|
5
|
+
var _ = _interopRequireWildcard(require("."));var cache;function _interopRequireWildcard(e, t) {if (!t && e && e.__esModule) return e;var r,c,a = Object.defineProperty,n = { __proto__: null, default: e };if (Object(e) !== e) return n;if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) {if (cache.has(e)) return cache.get(e);cache.set(e, n);}for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]);return n;}
|
|
6
|
+
|
|
7
|
+
const HOST = 'http://www.rqlite.com:4001';
|
|
8
|
+
|
|
9
|
+
describe('api client', () => {
|
|
10
|
+
describe('Function: createQuery()', () => {
|
|
11
|
+
it('it should create the httpOptions using standard request options', () => {
|
|
12
|
+
const options = {
|
|
13
|
+
atomic: true,
|
|
14
|
+
level: 'strong',
|
|
15
|
+
pretty: true,
|
|
16
|
+
timings: true,
|
|
17
|
+
transaction: true
|
|
18
|
+
};
|
|
19
|
+
const expected = {
|
|
20
|
+
atomic: true,
|
|
21
|
+
level: 'strong',
|
|
22
|
+
pretty: true,
|
|
23
|
+
timings: true,
|
|
24
|
+
transaction: true
|
|
25
|
+
};
|
|
26
|
+
const result = (0, _.createQuery)(options);
|
|
27
|
+
_chai.assert.deepEqual(result, expected);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe('Function: post()', () => {
|
|
31
|
+
it(`should call ${HOST}${_data.PATH_EXECUTE} endpoint with a request body using HTTP POST when using insert`, async () => {
|
|
32
|
+
const apiClient = new _.default(HOST);
|
|
33
|
+
const sql = 'INSERT INTO foo(name) VALUES("fiona")';
|
|
34
|
+
const scope = (0, _apiDataExecuteNock.executeSuccess)({ url: HOST, path: _data.PATH_EXECUTE, body: [sql] });
|
|
35
|
+
const res = await apiClient.post(_data.PATH_EXECUTE, sql);
|
|
36
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
37
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
38
|
+
_chai.assert.deepEqual(res.body, _apiDataExecuteNock.EXECUTE_SUCCESS_RESPONSE);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe('Function: get()', () => {
|
|
42
|
+
it(`should call ${HOST}${_data.PATH_QUERY} endpoint with a query using HTTP GET when using select`, async () => {
|
|
43
|
+
const apiClient = new _.default(HOST);
|
|
44
|
+
const sql = 'SELECT * FROM foo';
|
|
45
|
+
const query = { q: sql };
|
|
46
|
+
const scope = (0, _apiDataQueryNock.querySuccess)({ url: HOST, path: _data.PATH_QUERY, query });
|
|
47
|
+
const res = await apiClient.get(_data.PATH_QUERY, sql);
|
|
48
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
49
|
+
_chai.assert.deepEqual(res.body, _apiDataQueryNock.QUERY_SUCCESS_RESPONSE);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=test.unit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.unit.js","names":["_chai","require","_data","_apiDataQueryNock","_apiDataExecuteNock","_","_interopRequireWildcard","cache","e","t","__esModule","r","c","a","Object","defineProperty","n","__proto__","default","WeakMap","has","get","set","hasOwnProperty","call","getOwnPropertyDescriptor","HOST","describe","it","options","atomic","level","pretty","timings","transaction","expected","result","createQuery","assert","deepEqual","PATH_EXECUTE","apiClient","ApiClient","sql","scope","executeSuccess","url","path","body","res","post","isTrue","isDone","EXECUTE_SUCCESS_RESPONSE","PATH_QUERY","query","q","querySuccess","QUERY_SUCCESS_RESPONSE"],"sources":["../../../es6/api/client/test.unit.js"],"sourcesContent":["import { assert } from 'chai'\nimport { PATH_QUERY, PATH_EXECUTE } from '../data'\nimport { querySuccess, QUERY_SUCCESS_RESPONSE } from '../../test/api-data-query-nock'\nimport { executeSuccess, EXECUTE_SUCCESS_RESPONSE } from '../../test/api-data-execute-nock'\nimport ApiClient, { createQuery } from '.'\n\nconst HOST = 'http://www.rqlite.com:4001'\n\ndescribe('api client', () => {\n describe('Function: createQuery()', () => {\n it('it should create the httpOptions using standard request options', () => {\n const options = {\n atomic: true,\n level: 'strong',\n pretty: true,\n timings: true,\n transaction: true,\n }\n const expected = {\n atomic: true,\n level: 'strong',\n pretty: true,\n timings: true,\n transaction: true,\n }\n const result = createQuery(options)\n assert.deepEqual(result, expected)\n })\n })\n describe('Function: post()', () => {\n it(`should call ${HOST}${PATH_EXECUTE} endpoint with a request body using HTTP POST when using insert`, async () => {\n const apiClient = new ApiClient(HOST)\n const sql = 'INSERT INTO foo(name) VALUES(\"fiona\")'\n const scope = executeSuccess({ url: HOST, path: PATH_EXECUTE, body: [sql] })\n const res = await apiClient.post(PATH_EXECUTE, sql)\n assert.isTrue(scope.isDone(), 'http request captured by nock')\n // eslint-disable-next-line no-underscore-dangle\n assert.deepEqual(res.body, EXECUTE_SUCCESS_RESPONSE)\n })\n })\n describe('Function: get()', () => {\n it(`should call ${HOST}${PATH_QUERY} endpoint with a query using HTTP GET when using select`, async () => {\n const apiClient = new ApiClient(HOST)\n const sql = 'SELECT * FROM foo'\n const query = { q: sql }\n const scope = querySuccess({ url: HOST, path: PATH_QUERY, query })\n const res = await apiClient.get(PATH_QUERY, sql)\n assert.isTrue(scope.isDone(), 'http request captured by nock')\n assert.deepEqual(res.body, QUERY_SUCCESS_RESPONSE)\n })\n })\n})\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.CONSISTENCY_LEVEL_WEAK = exports.CONSISTENCY_LEVEL_STRONG = exports.CONSISTENCY_LEVEL_NONE = exports.CONSISTENCY_LEVEL_LINEARIZABLE = void 0; /**
|
|
2
|
+
* RQLite read consistency level constants
|
|
3
|
+
* @module api/consistency-levels
|
|
4
|
+
* @see https://rqlite.io/docs/api/read-consistency/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Read query consistency level none which means
|
|
9
|
+
* any node can respond
|
|
10
|
+
*/
|
|
11
|
+
const CONSISTENCY_LEVEL_NONE = exports.CONSISTENCY_LEVEL_NONE = 'none';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Read query consistency strong which must come from
|
|
15
|
+
* the leader node
|
|
16
|
+
*/
|
|
17
|
+
const CONSISTENCY_LEVEL_STRONG = exports.CONSISTENCY_LEVEL_STRONG = 'strong';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Read query consistency linearizable which must come from
|
|
21
|
+
* the leader node
|
|
22
|
+
*/
|
|
23
|
+
const CONSISTENCY_LEVEL_LINEARIZABLE = exports.CONSISTENCY_LEVEL_LINEARIZABLE = 'linearizable';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Read query consistency weak (default) which must come from
|
|
27
|
+
* the leader node
|
|
28
|
+
*/
|
|
29
|
+
const CONSISTENCY_LEVEL_WEAK = exports.CONSISTENCY_LEVEL_WEAK = 'weak';
|
|
30
|
+
//# sourceMappingURL=consistency-levels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consistency-levels.js","names":["CONSISTENCY_LEVEL_NONE","exports","CONSISTENCY_LEVEL_STRONG","CONSISTENCY_LEVEL_LINEARIZABLE","CONSISTENCY_LEVEL_WEAK"],"sources":["../../es6/api/consistency-levels.js"],"sourcesContent":["/**\n * RQLite read consistency level constants\n * @module api/consistency-levels\n * @see https://rqlite.io/docs/api/read-consistency/\n */\n\n/**\n * Read query consistency level none which means\n * any node can respond\n */\nexport const CONSISTENCY_LEVEL_NONE = 'none'\n\n/**\n * Read query consistency strong which must come from\n * the leader node\n */\nexport const CONSISTENCY_LEVEL_STRONG = 'strong'\n\n/**\n * Read query consistency linearizable which must come from\n * the leader node\n */\nexport const CONSISTENCY_LEVEL_LINEARIZABLE = 'linearizable'\n\n/**\n * Read query consistency weak (default) which must come from\n * the leader node\n */\nexport const CONSISTENCY_LEVEL_WEAK = 'weak'\n"],"mappings":"iOAAA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACO,MAAMA,sBAAsB,GAAAC,OAAA,CAAAD,sBAAA,GAAG,MAAM;;AAE5C;AACA;AACA;AACA;AACO,MAAME,wBAAwB,GAAAD,OAAA,CAAAC,wBAAA,GAAG,QAAQ;;AAEhD;AACA;AACA;AACA;AACO,MAAMC,8BAA8B,GAAAF,OAAA,CAAAE,8BAAA,GAAG,cAAc;;AAE5D;AACA;AACA;AACA;AACO,MAAMC,sBAAsB,GAAAH,OAAA,CAAAG,sBAAA,GAAG,MAAM","ignoreList":[]}
|
package/lib/api/data/index.js
CHANGED
|
@@ -1,85 +1,57 @@
|
|
|
1
|
-
"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports, "__esModule", { value: true });exports
|
|
1
|
+
"use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports, "__esModule", { value: true });Object.defineProperty(exports, "CONSISTENCY_LEVEL_LINEARIZABLE", { enumerable: true, get: function () {return _consistencyLevels.CONSISTENCY_LEVEL_LINEARIZABLE;} });Object.defineProperty(exports, "CONSISTENCY_LEVEL_NONE", { enumerable: true, get: function () {return _consistencyLevels.CONSISTENCY_LEVEL_NONE;} });Object.defineProperty(exports, "CONSISTENCY_LEVEL_STRONG", { enumerable: true, get: function () {return _consistencyLevels.CONSISTENCY_LEVEL_STRONG;} });Object.defineProperty(exports, "CONSISTENCY_LEVEL_WEAK", { enumerable: true, get: function () {return _consistencyLevels.CONSISTENCY_LEVEL_WEAK;} });Object.defineProperty(exports, "PATH_EXECUTE", { enumerable: true, get: function () {return _paths.PATH_EXECUTE;} });Object.defineProperty(exports, "PATH_QUERY", { enumerable: true, get: function () {return _paths.PATH_QUERY;} });exports.default = void 0;
|
|
2
|
+
|
|
3
|
+
|
|
2
4
|
|
|
3
5
|
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
var _client = _interopRequireDefault(require("../client"));
|
|
7
|
-
var _results = require("../results");
|
|
9
|
+
var _results = require("../results");
|
|
10
|
+
var _paths = require("../paths");
|
|
11
|
+
var _consistencyLevels = require("../consistency-levels"); /**
|
|
8
12
|
* Data api client to perform RQLite data operations such
|
|
9
13
|
* as query and execute
|
|
10
14
|
* @module api/data
|
|
11
|
-
|
|
12
|
-
*
|
|
13
|
-
*/const PATH_QUERY = exports.PATH_QUERY = '/db/query';
|
|
14
|
-
/**
|
|
15
|
-
* The RQLite execute api path
|
|
15
|
+
* @see https://rqlite.io/docs/api/api/
|
|
16
|
+
* @see https://rqlite.io/docs/api/read-consistency/
|
|
16
17
|
*/
|
|
17
|
-
const PATH_EXECUTE = exports.PATH_EXECUTE = '/db/execute';
|
|
18
18
|
|
|
19
|
-
/**
|
|
20
|
-
* Read query consistency level none which means
|
|
21
|
-
* any node can respond
|
|
22
|
-
*/
|
|
23
|
-
const CONSISTENCY_LEVEL_NONE = exports.CONSISTENCY_LEVEL_NONE = 'none';
|
|
24
19
|
|
|
25
|
-
/**
|
|
26
|
-
* Read query consistency strong which must come from
|
|
27
|
-
* the master node
|
|
28
|
-
*/
|
|
29
|
-
const CONSISTENCY_LEVEL_STRONG = exports.CONSISTENCY_LEVEL_STRONG = 'strong';
|
|
30
20
|
|
|
31
|
-
/**
|
|
32
|
-
* Read query consistency linearizable which must come from
|
|
33
|
-
* the master node
|
|
34
|
-
*/
|
|
35
|
-
const CONSISTENCY_LEVEL_LINEARIZABLE = exports.CONSISTENCY_LEVEL_LINEARIZABLE = 'linearizable';
|
|
36
21
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* the master node
|
|
40
|
-
*/
|
|
41
|
-
const CONSISTENCY_LEVEL_WEAK = exports.CONSISTENCY_LEVEL_WEAK = 'weak';
|
|
22
|
+
|
|
23
|
+
|
|
42
24
|
|
|
43
25
|
/**
|
|
44
|
-
* @typedef
|
|
45
|
-
* @type {import('../../http-request').HttpRequestOptions}
|
|
26
|
+
* @typedef {import('../client').ApiClientRequestOptions} ApiClientRequestOptions
|
|
46
27
|
*/
|
|
47
28
|
|
|
48
29
|
/**
|
|
49
30
|
* Data request base options
|
|
50
|
-
* @typedef DataRequestBaseOptions
|
|
51
|
-
* @type {Object}
|
|
31
|
+
* @typedef {Object} DataRequestBaseOptions
|
|
52
32
|
* @property {Boolean} [raw] If true return the raw http response from
|
|
53
33
|
* RQLite response
|
|
54
34
|
*/
|
|
55
35
|
|
|
56
|
-
/**
|
|
57
|
-
* Data query request base options
|
|
58
|
-
* @typedef QueryRequestBaseOptions
|
|
59
|
-
* @type {Object}
|
|
60
|
-
* @property {String} level The api consistency level
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
36
|
/**
|
|
64
37
|
* Data query request options
|
|
65
|
-
* @typedef QueryRequestOptions
|
|
66
|
-
* @type {HttpRequestOptions & DataRequestBaseOptions & QueryRequestBaseOptions}
|
|
38
|
+
* @typedef {ApiClientRequestOptions & DataRequestBaseOptions} QueryRequestOptions
|
|
67
39
|
*/
|
|
68
40
|
|
|
69
41
|
/**
|
|
70
42
|
* Data execute request options
|
|
71
|
-
* @typedef ExecuteRequestOptions
|
|
72
|
-
* @type {HttpRequestOptions & DataRequestBaseOptions}
|
|
43
|
+
* @typedef {ApiClientRequestOptions & DataRequestBaseOptions} ExecuteRequestOptions
|
|
73
44
|
*/
|
|
74
45
|
|
|
75
46
|
/**
|
|
76
|
-
*
|
|
77
|
-
* @param {
|
|
47
|
+
* Handle an RQLite data API response
|
|
48
|
+
* @param {{status: Number, body: Object}} response The HTTP response
|
|
78
49
|
* @param {DataRequestBaseOptions} [options={}] RQLite api options
|
|
50
|
+
* @returns {DataResults|{status: Number, body: Object}}
|
|
79
51
|
*/
|
|
80
52
|
function handleResponse(response, options = {}) {
|
|
81
|
-
const raw = options
|
|
82
|
-
const body = response
|
|
53
|
+
const { raw } = options;
|
|
54
|
+
const { body } = response;
|
|
83
55
|
if (raw) {
|
|
84
56
|
return response;
|
|
85
57
|
}
|
|
@@ -92,39 +64,45 @@ function handleResponse(response, options = {}) {
|
|
|
92
64
|
class DataApiClient extends _client.default {
|
|
93
65
|
/**
|
|
94
66
|
* Send an RQLite query API request to the RQLite server
|
|
95
|
-
* @param {String} sql The SQL string to
|
|
67
|
+
* @param {String|String[]} sql The SQL string to execute on the server
|
|
96
68
|
* @param {QueryRequestOptions} [options={}] RQLite api options
|
|
69
|
+
* @returns {Promise<DataResults|{status: Number, body: Object}>}
|
|
70
|
+
* @see https://rqlite.io/docs/api/api/
|
|
71
|
+
* @see https://rqlite.io/docs/api/read-consistency/
|
|
72
|
+
* @see module:api/consistency-levels
|
|
97
73
|
*/
|
|
98
|
-
query(sql, options = {}) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
74
|
+
async query(sql, options = {}) {
|
|
75
|
+
const { level } = options;
|
|
76
|
+
let { useLeader } = options;
|
|
77
|
+
// Weak and strong consistency will be redirect to the master anyway
|
|
78
|
+
// so skip the redirect HTTP response and got right to the master
|
|
79
|
+
if (level !== _consistencyLevels.CONSISTENCY_LEVEL_NONE) {
|
|
80
|
+
useLeader = true;
|
|
81
|
+
}
|
|
82
|
+
let response;
|
|
83
|
+
if (Array.isArray(sql)) {
|
|
84
|
+
response = await super.post(_paths.PATH_QUERY, sql, { ...options, useLeader });
|
|
85
|
+
} else {
|
|
86
|
+
response = await super.get(_paths.PATH_QUERY, sql, { ...options, useLeader });
|
|
87
|
+
}
|
|
88
|
+
// If round robin is true try and balance selects across hosts when
|
|
89
|
+
// the master node is not queried directly
|
|
90
|
+
if (!useLeader) {
|
|
91
|
+
this.setNextActiveHostIndex();
|
|
92
|
+
}
|
|
93
|
+
return handleResponse(response, options);
|
|
118
94
|
}
|
|
119
95
|
|
|
120
96
|
/**
|
|
121
97
|
* Send an RQLite execute API request to the RQLite server
|
|
122
|
-
* @param {String} sql The SQL string to
|
|
98
|
+
* @param {String|String[]} sql The SQL string to execute on the server
|
|
123
99
|
* @param {ExecuteRequestOptions} [options={}] RQLite execute api options
|
|
100
|
+
* @returns {Promise<DataResults|{status: Number, body: Object}>}
|
|
101
|
+
* @see https://rqlite.io/docs/api/api/
|
|
124
102
|
*/
|
|
125
|
-
execute(sql, options = {}) {
|
|
126
|
-
|
|
127
|
-
|
|
103
|
+
async execute(sql, options = {}) {
|
|
104
|
+
const response = await super.post(_paths.PATH_EXECUTE, sql, options);
|
|
105
|
+
return handleResponse(response, options);
|
|
128
106
|
}
|
|
129
107
|
}exports.default = DataApiClient;
|
|
130
108
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_client","_interopRequireDefault","require","_results","
|
|
1
|
+
{"version":3,"file":"index.js","names":["_client","_interopRequireDefault","require","_results","_paths","_consistencyLevels","handleResponse","response","options","raw","body","DataResults","DataApiClient","ApiClient","query","sql","level","useLeader","CONSISTENCY_LEVEL_NONE","Array","isArray","post","PATH_QUERY","get","setNextActiveHostIndex","execute","PATH_EXECUTE","exports","default"],"sources":["../../../es6/api/data/index.js"],"sourcesContent":["/**\n * Data api client to perform RQLite data operations such\n * as query and execute\n * @module api/data\n * @see https://rqlite.io/docs/api/api/\n * @see https://rqlite.io/docs/api/read-consistency/\n */\nimport ApiClient from '../client'\nimport { DataResults } from '../results'\nimport { PATH_EXECUTE, PATH_QUERY } from '../paths'\nimport { CONSISTENCY_LEVEL_NONE } from '../consistency-levels'\n\nexport {\n PATH_QUERY,\n PATH_EXECUTE,\n} from '../paths'\n\nexport {\n CONSISTENCY_LEVEL_NONE,\n CONSISTENCY_LEVEL_STRONG,\n CONSISTENCY_LEVEL_LINEARIZABLE,\n CONSISTENCY_LEVEL_WEAK,\n} from '../consistency-levels'\n\n/**\n * @typedef {import('../client').ApiClientRequestOptions} ApiClientRequestOptions\n */\n\n/**\n * Data request base options\n * @typedef {Object} DataRequestBaseOptions\n * @property {Boolean} [raw] If true return the raw http response from\n * RQLite response\n */\n\n/**\n * Data query request options\n * @typedef {ApiClientRequestOptions & DataRequestBaseOptions} QueryRequestOptions\n */\n\n/**\n * Data execute request options\n * @typedef {ApiClientRequestOptions & DataRequestBaseOptions} ExecuteRequestOptions\n */\n\n/**\n * Handle an RQLite data API response\n * @param {{status: Number, body: Object}} response The HTTP response\n * @param {DataRequestBaseOptions} [options={}] RQLite api options\n * @returns {DataResults|{status: Number, body: Object}}\n */\nfunction handleResponse (response, options = {}) {\n const { raw } = options\n const { body } = response\n if (raw) {\n return response\n }\n return new DataResults(body)\n}\n\n/**\n * Data api client to perform RQLite queries\n */\nexport default class DataApiClient extends ApiClient {\n /**\n * Send an RQLite query API request to the RQLite server\n * @param {String|String[]} sql The SQL string to execute on the server\n * @param {QueryRequestOptions} [options={}] RQLite api options\n * @returns {Promise<DataResults|{status: Number, body: Object}>}\n * @see https://rqlite.io/docs/api/api/\n * @see https://rqlite.io/docs/api/read-consistency/\n * @see module:api/consistency-levels\n */\n async query (sql, options = {}) {\n const { level } = options\n let { useLeader } = options\n // Weak and strong consistency will be redirect to the master anyway\n // so skip the redirect HTTP response and got right to the master\n if (level !== CONSISTENCY_LEVEL_NONE) {\n useLeader = true\n }\n let response\n if (Array.isArray(sql)) {\n response = await super.post(PATH_QUERY, sql, { ...options, useLeader })\n } else {\n response = await super.get(PATH_QUERY, sql, { ...options, useLeader })\n }\n // If round robin is true try and balance selects across hosts when\n // the master node is not queried directly\n if (!useLeader) {\n this.setNextActiveHostIndex()\n }\n return handleResponse(response, options)\n }\n\n /**\n * Send an RQLite execute API request to the RQLite server\n * @param {String|String[]} sql The SQL string to execute on the server\n * @param {ExecuteRequestOptions} [options={}] RQLite execute api options\n * @returns {Promise<DataResults|{status: Number, body: Object}>}\n * @see https://rqlite.io/docs/api/api/\n */\n async execute (sql, options = {}) {\n const response = await super.post(PATH_EXECUTE, sql, options)\n return handleResponse(response, options)\n }\n}\n"],"mappings":";;;;;;;AAOA,IAAAA,OAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,QAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AACA,IAAAG,kBAAA,GAAAH,OAAA,0BAA8D,CAV9D;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAkBA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASI,cAAcA,CAAEC,QAAQ,EAAEC,OAAO,GAAG,CAAC,CAAC,EAAE;EAC/C,MAAM,EAAEC,GAAG,CAAC,CAAC,GAAGD,OAAO;EACvB,MAAM,EAAEE,IAAI,CAAC,CAAC,GAAGH,QAAQ;EACzB,IAAIE,GAAG,EAAE;IACP,OAAOF,QAAQ;EACjB;EACA,OAAO,IAAII,oBAAW,CAACD,IAAI,CAAC;AAC9B;;AAEA;AACA;AACA;AACe,MAAME,aAAa,SAASC,eAAS,CAAC;EACnD;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,MAAMC,KAAKA,CAAEC,GAAG,EAAEP,OAAO,GAAG,CAAC,CAAC,EAAE;IAC9B,MAAM,EAAEQ,KAAK,CAAC,CAAC,GAAGR,OAAO;IACzB,IAAI,EAAES,SAAS,CAAC,CAAC,GAAGT,OAAO;IAC3B;IACA;IACA,IAAIQ,KAAK,KAAKE,yCAAsB,EAAE;MACpCD,SAAS,GAAG,IAAI;IAClB;IACA,IAAIV,QAAQ;IACZ,IAAIY,KAAK,CAACC,OAAO,CAACL,GAAG,CAAC,EAAE;MACtBR,QAAQ,GAAG,MAAM,KAAK,CAACc,IAAI,CAACC,iBAAU,EAAEP,GAAG,EAAE,EAAE,GAAGP,OAAO,EAAES,SAAS,CAAC,CAAC,CAAC;IACzE,CAAC,MAAM;MACLV,QAAQ,GAAG,MAAM,KAAK,CAACgB,GAAG,CAACD,iBAAU,EAAEP,GAAG,EAAE,EAAE,GAAGP,OAAO,EAAES,SAAS,CAAC,CAAC,CAAC;IACxE;IACA;IACA;IACA,IAAI,CAACA,SAAS,EAAE;MACd,IAAI,CAACO,sBAAsB,CAAC,CAAC;IAC/B;IACA,OAAOlB,cAAc,CAACC,QAAQ,EAAEC,OAAO,CAAC;EAC1C;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACE,MAAMiB,OAAOA,CAAEV,GAAG,EAAEP,OAAO,GAAG,CAAC,CAAC,EAAE;IAChC,MAAMD,QAAQ,GAAG,MAAM,KAAK,CAACc,IAAI,CAACK,mBAAY,EAAEX,GAAG,EAAEP,OAAO,CAAC;IAC7D,OAAOF,cAAc,CAACC,QAAQ,EAAEC,OAAO,CAAC;EAC1C;AACF,CAACmB,OAAA,CAAAC,OAAA,GAAAhB,aAAA","ignoreList":[]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";var _chai = require("chai");
|
|
2
|
+
var _apiDataQueryNock = require("../../test/api-data-query-nock");
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _apiDataExecuteNock = require("../../test/api-data-execute-nock");
|
|
9
|
+
var _ = _interopRequireWildcard(require("."));var cache;function _interopRequireWildcard(e, t) {if (!t && e && e.__esModule) return e;var r,c,a = Object.defineProperty,n = { __proto__: null, default: e };if (Object(e) !== e) return n;if (cache || "function" != typeof WeakMap || (cache = new WeakMap()), cache) {if (cache.has(e)) return cache.get(e);cache.set(e, n);}for (c in e) "default" !== c && {}.hasOwnProperty.call(e, c) && ((r = a && Object.getOwnPropertyDescriptor(e, c)) && (r.get || r.set) ? a(n, c, r) : n[c] = e[c]);return n;}
|
|
10
|
+
|
|
11
|
+
const HOST = 'http://www.rqlite.com:4001';
|
|
12
|
+
|
|
13
|
+
describe('api data', () => {
|
|
14
|
+
describe('DataApiclient.query()', () => {
|
|
15
|
+
it(`should call ${HOST}${_.PATH_QUERY} endpoint with a query using HTTP GET and include a level query`, async () => {
|
|
16
|
+
const dataApiClient = new _.default(HOST);
|
|
17
|
+
const sql = 'SELECT * FROM foo';
|
|
18
|
+
const level = 'strong';
|
|
19
|
+
const apiQuery = { q: sql, level };
|
|
20
|
+
const scope = (0, _apiDataQueryNock.querySuccess)({ url: HOST, path: _.PATH_QUERY, query: apiQuery });
|
|
21
|
+
const res = await dataApiClient.query(sql, { level, raw: true });
|
|
22
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
23
|
+
_chai.assert.deepEqual(_apiDataQueryNock.QUERY_SUCCESS_RESPONSE, res.body);
|
|
24
|
+
});
|
|
25
|
+
it(`should call ${HOST}${_.PATH_QUERY} endpoint with a query using HTTP POST if sql is an array`, async () => {
|
|
26
|
+
const dataApiClient = new _.default(HOST);
|
|
27
|
+
const sql = ['SELECT * FROM foo', 'SELECT * FROM bar'];
|
|
28
|
+
const level = 'weak';
|
|
29
|
+
const apiQuery = { level };
|
|
30
|
+
const scope = (0, _apiDataQueryNock.queryMultipleSuccess)({
|
|
31
|
+
url: HOST, path: _.PATH_QUERY, query: apiQuery, body: sql
|
|
32
|
+
});
|
|
33
|
+
const res = await dataApiClient.query(sql, { level, raw: true });
|
|
34
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
35
|
+
_chai.assert.deepEqual(_apiDataQueryNock.QUERY_MULTIPLE_SUCCESS_RESPONSE, res.body);
|
|
36
|
+
});
|
|
37
|
+
it(`should call ${HOST}${_.PATH_QUERY} endpoint with a query using HTTP GET when using select`, async () => {
|
|
38
|
+
const dataApiClient = new _.default(HOST);
|
|
39
|
+
const sql = 'SELECT * FROM foo';
|
|
40
|
+
const query = { q: sql };
|
|
41
|
+
const scope = (0, _apiDataQueryNock.querySuccess)({ url: HOST, path: _.PATH_QUERY, query });
|
|
42
|
+
const res = await dataApiClient.query(sql, { raw: true });
|
|
43
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
44
|
+
_chai.assert.deepEqual(_apiDataQueryNock.QUERY_SUCCESS_RESPONSE, res.body);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('DataApiclient.execute()', () => {
|
|
48
|
+
it(`should call ${HOST}${_.PATH_EXECUTE} endpoint with a query using HTTP POST`, async () => {
|
|
49
|
+
const dataApiClient = new _.default(HOST);
|
|
50
|
+
const sql = 'INSERT INTO foo(name) VALUES("fiona")';
|
|
51
|
+
const scope = (0, _apiDataExecuteNock.executeSuccess)({ url: HOST, path: _.PATH_EXECUTE, body: [sql] });
|
|
52
|
+
const res = await dataApiClient.execute(sql, { raw: true });
|
|
53
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
54
|
+
_chai.assert.deepEqual(res.body, _apiDataExecuteNock.EXECUTE_SUCCESS_RESPONSE);
|
|
55
|
+
});
|
|
56
|
+
it(`should call ${HOST}${_.PATH_EXECUTE} endpoint with a request body using HTTP POST when performing an insert`, async () => {
|
|
57
|
+
const dataApiClient = new _.default(HOST);
|
|
58
|
+
const sql = 'INSERT INTO foo(name) VALUES("fiona")';
|
|
59
|
+
const scope = (0, _apiDataExecuteNock.executeSuccess)({ url: HOST, path: _.PATH_EXECUTE, body: [sql] });
|
|
60
|
+
const res = await dataApiClient.execute(sql, { raw: true });
|
|
61
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
62
|
+
_chai.assert.deepEqual(_apiDataExecuteNock.EXECUTE_SUCCESS_RESPONSE, res.body);
|
|
63
|
+
});
|
|
64
|
+
it(`should call ${HOST}${_.PATH_EXECUTE} endpoint with a request body using HTTP POST when performing an update`, async () => {
|
|
65
|
+
const dataApiClient = new _.default(HOST);
|
|
66
|
+
const sql = 'UPDATE foo SET name="fionaTest" WHERE name="fiona"';
|
|
67
|
+
const scope = (0, _apiDataExecuteNock.executeSuccess)({ url: HOST, path: _.PATH_EXECUTE, body: [sql] });
|
|
68
|
+
const res = await dataApiClient.execute(sql, { raw: true });
|
|
69
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
70
|
+
_chai.assert.deepEqual(_apiDataExecuteNock.EXECUTE_SUCCESS_RESPONSE, res.body);
|
|
71
|
+
});
|
|
72
|
+
it(`should call ${HOST}${_.PATH_EXECUTE} endpoint with a request body using HTTP POST when performing a delete`, async () => {
|
|
73
|
+
const dataApiClient = new _.default(HOST);
|
|
74
|
+
const sql = 'DELETE FROM foo WHERE name="fiona"';
|
|
75
|
+
const scope = (0, _apiDataExecuteNock.executeSuccess)({ url: HOST, path: _.PATH_EXECUTE, body: [sql] });
|
|
76
|
+
const res = await dataApiClient.execute(sql, { raw: true });
|
|
77
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
78
|
+
_chai.assert.deepEqual(_apiDataExecuteNock.EXECUTE_SUCCESS_RESPONSE, res.body);
|
|
79
|
+
});
|
|
80
|
+
it(`should call ${HOST}${_.PATH_EXECUTE} endpoint with a request body using HTTP POST when performing a create table`, async () => {
|
|
81
|
+
const dataApiClient = new _.default(HOST);
|
|
82
|
+
const sql = 'CREATE TABLE foo (id integer not null primary key, name text)';
|
|
83
|
+
const scope = (0, _apiDataExecuteNock.executeSuccess)({ url: HOST, path: _.PATH_EXECUTE, body: [sql] });
|
|
84
|
+
const res = await dataApiClient.execute(sql, { raw: true });
|
|
85
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
86
|
+
_chai.assert.deepEqual(_apiDataExecuteNock.EXECUTE_SUCCESS_RESPONSE, res.body);
|
|
87
|
+
});
|
|
88
|
+
it(`should call ${HOST}${_.PATH_EXECUTE} endpoint with a request body using HTTP POST when performing a drop table`, async () => {
|
|
89
|
+
const dataApiClient = new _.default(HOST);
|
|
90
|
+
const sql = 'DROP TABLE foo';
|
|
91
|
+
const scope = (0, _apiDataExecuteNock.executeSuccess)({ url: HOST, path: _.PATH_EXECUTE, body: [sql] });
|
|
92
|
+
const res = await dataApiClient.execute(sql, { raw: true });
|
|
93
|
+
_chai.assert.isTrue(scope.isDone(), 'http request captured by nock');
|
|
94
|
+
_chai.assert.deepEqual(_apiDataExecuteNock.EXECUTE_SUCCESS_RESPONSE, res.body);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=test.unit.js.map
|