ueberdb2 4.0.10 → 4.0.15
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/.eslintignore +2 -0
- package/.eslintrc.cjs +44 -5
- package/databases/{cassandra_db.js → cassandra_db.ts} +45 -30
- package/databases/{couch_db.js → couch_db.ts} +78 -31
- package/databases/{dirty_db.js → dirty_db.ts} +19 -14
- package/databases/{dirty_git_db.js → dirty_git_db.ts} +19 -15
- package/databases/{elasticsearch_db.js → elasticsearch_db.ts} +30 -21
- package/databases/{memory_db.js → memory_db.ts} +8 -8
- package/databases/mock_db.ts +43 -0
- package/databases/{mongodb_db.js → mongodb_db.ts} +22 -16
- package/databases/{mssql_db.js → mssql_db.ts} +29 -21
- package/databases/{mysql_db.js → mysql_db.ts} +20 -15
- package/databases/{postgres_db.js → postgres_db.ts} +37 -22
- package/databases/{postgrespool_db.js → postgrespool_db.ts} +3 -3
- package/databases/redis_db.ts +129 -0
- package/databases/{rethink_db.js → rethink_db.ts} +35 -19
- package/databases/{sqlite_db.js → sqlite_db.ts} +37 -36
- package/docker-compose.yml +44 -0
- package/{index.js → index.ts} +76 -25
- package/lib/AbstractDatabase.ts +79 -0
- package/lib/{CacheAndBufferLayer.js → CacheAndBufferLayer.ts} +17 -16
- package/lib/{logging.js → logging.ts} +10 -6
- package/package.json +17 -3
- package/test/lib/{databases.js → databases.ts} +8 -5
- package/test/test.ts +328 -0
- package/test/test_bulk.ts +69 -0
- package/test/{test_elasticsearch.js → test_elasticsearch.ts} +48 -53
- package/test/{test_findKeys.js → test_findKeys.ts} +15 -17
- package/test/{test_flush.js → test_flush.ts} +16 -22
- package/test/test_getSub.ts +28 -0
- package/test/test_lru.ts +151 -0
- package/test/test_memory.ts +32 -0
- package/test/{test_metrics.js → test_metrics.ts} +73 -68
- package/test/{test_mysql.js → test_mysql.ts} +16 -22
- package/test/test_postgres.ts +16 -0
- package/test/{test_setSub.js → test_setSub.ts} +8 -12
- package/test/test_tojson.ts +34 -0
- package/databases/mock_db.js +0 -42
- package/databases/redis_db.js +0 -96
- package/lib/AbstractDatabase.js +0 -37
- package/test/test.js +0 -328
- package/test/test_bulk.js +0 -69
- package/test/test_getSub.js +0 -31
- package/test/test_lru.js +0 -145
- package/test/test_memory.js +0 -31
- package/test/test_postgres.js +0 -16
- package/test/test_tojson.js +0 -37
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
1
|
/**
|
|
3
2
|
* 2011 Peter 'Pita' Martischka
|
|
4
3
|
*
|
|
@@ -15,12 +14,15 @@
|
|
|
15
14
|
* limitations under the License.
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
import AbstractDatabase, {Settings} from '../lib/AbstractDatabase';
|
|
18
|
+
import async from 'async';
|
|
19
|
+
import pg, {Pool, QueryResult} from 'pg';
|
|
20
|
+
import {BulkObject} from './cassandra_db';
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
export const Database = class extends AbstractDatabase {
|
|
23
|
+
private db: Pool;
|
|
24
|
+
private upsertStatement: string | null | undefined;
|
|
25
|
+
constructor(settings:Settings | string) {
|
|
24
26
|
super();
|
|
25
27
|
if (typeof settings === 'string') settings = {connectionString: settings};
|
|
26
28
|
this.settings = settings;
|
|
@@ -34,10 +36,11 @@ exports.Database = class extends AbstractDatabase {
|
|
|
34
36
|
this.settings.min = this.settings.min || 4;
|
|
35
37
|
this.settings.idleTimeoutMillis = this.settings.idleTimeoutMillis || 1000;
|
|
36
38
|
|
|
39
|
+
// @ts-ignore
|
|
37
40
|
this.db = new pg.Pool(this.settings);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
init(callback) {
|
|
43
|
+
init(callback: (err: Error)=>{}) {
|
|
41
44
|
const testTableExists = "SELECT 1 as exists FROM pg_tables WHERE tablename = 'store'";
|
|
42
45
|
|
|
43
46
|
const createTable = 'CREATE TABLE IF NOT EXISTS store (' +
|
|
@@ -58,7 +61,7 @@ exports.Database = class extends AbstractDatabase {
|
|
|
58
61
|
* statement that needs to be used, based on the detection result
|
|
59
62
|
* - calls the callback
|
|
60
63
|
*/
|
|
61
|
-
const detectUpsertMethod = (callback) => {
|
|
64
|
+
const detectUpsertMethod = (callback: (err?: Error) => {}) => {
|
|
62
65
|
const upsertViaFunction = 'SELECT ueberdb_insert_or_update($1,$2)';
|
|
63
66
|
const upsertNatively =
|
|
64
67
|
'INSERT INTO store(key, value) VALUES ($1, $2) ' +
|
|
@@ -102,15 +105,17 @@ exports.Database = class extends AbstractDatabase {
|
|
|
102
105
|
if (result.rows.length === 0) {
|
|
103
106
|
this.db.query(createTable, (err) => {
|
|
104
107
|
if (err != null) return callback(err);
|
|
108
|
+
// @ts-ignore
|
|
105
109
|
detectUpsertMethod(callback);
|
|
106
110
|
});
|
|
107
111
|
} else {
|
|
112
|
+
// @ts-ignore
|
|
108
113
|
detectUpsertMethod(callback);
|
|
109
114
|
}
|
|
110
115
|
});
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
get(key, callback) {
|
|
118
|
+
get(key:string, callback: (err: Error | null, value: any)=>{}) {
|
|
114
119
|
this.db.query('SELECT value FROM store WHERE key=$1', [key], (err, results) => {
|
|
115
120
|
let value = null;
|
|
116
121
|
|
|
@@ -122,7 +127,7 @@ exports.Database = class extends AbstractDatabase {
|
|
|
122
127
|
});
|
|
123
128
|
}
|
|
124
129
|
|
|
125
|
-
findKeys(key, notKey, callback) {
|
|
130
|
+
findKeys(key:string, notKey:string, callback: (err: Error | null, value: any)=>{}) {
|
|
126
131
|
let query = 'SELECT key FROM store WHERE key LIKE $1';
|
|
127
132
|
const params = [];
|
|
128
133
|
// desired keys are %key:%, e.g. pad:%
|
|
@@ -136,7 +141,7 @@ exports.Database = class extends AbstractDatabase {
|
|
|
136
141
|
params.push(notKey);
|
|
137
142
|
}
|
|
138
143
|
this.db.query(query, params, (err, results) => {
|
|
139
|
-
const value = [];
|
|
144
|
+
const value:string[] = [];
|
|
140
145
|
|
|
141
146
|
if (!err && results.rows.length > 0) {
|
|
142
147
|
results.rows.forEach((val) => {
|
|
@@ -148,22 +153,23 @@ exports.Database = class extends AbstractDatabase {
|
|
|
148
153
|
});
|
|
149
154
|
}
|
|
150
155
|
|
|
151
|
-
set(key, value, callback) {
|
|
156
|
+
set(key:string, value:string, callback:(err: Error, result: QueryResult<any>) => void) {
|
|
152
157
|
if (key.length > 100) {
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
const val = '' as any;
|
|
159
|
+
callback(Error('Your Key can only be 100 chars'), val);
|
|
160
|
+
} else if (this.upsertStatement != null) {
|
|
155
161
|
this.db.query(this.upsertStatement, [key, value], callback);
|
|
156
162
|
}
|
|
157
163
|
}
|
|
158
164
|
|
|
159
|
-
remove(key, callback) {
|
|
165
|
+
remove(key:string, callback:()=>{}) {
|
|
160
166
|
this.db.query('DELETE FROM store WHERE key=$1', [key], callback);
|
|
161
167
|
}
|
|
162
168
|
|
|
163
|
-
doBulk(bulk, callback) {
|
|
169
|
+
doBulk(bulk:BulkObject[], callback:()=>{}) {
|
|
164
170
|
const replaceVALs = [];
|
|
165
171
|
let removeSQL = 'DELETE FROM store WHERE key IN (';
|
|
166
|
-
const removeVALs = [];
|
|
172
|
+
const removeVALs: string[] = [];
|
|
167
173
|
|
|
168
174
|
let removeCount = 0;
|
|
169
175
|
|
|
@@ -181,18 +187,27 @@ exports.Database = class extends AbstractDatabase {
|
|
|
181
187
|
|
|
182
188
|
removeSQL += ');';
|
|
183
189
|
|
|
184
|
-
|
|
190
|
+
if (!this.upsertStatement) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
// @ts-ignore
|
|
196
|
+
const functions = replaceVALs.map((v) => (cb:()=>{}) => this.db.query(this.upsertStatement, v, cb));
|
|
185
197
|
|
|
186
|
-
const removeFunction = (callback) => {
|
|
187
|
-
|
|
188
|
-
|
|
198
|
+
const removeFunction = (callback: ()=>{}) => {
|
|
199
|
+
// @ts-ignore
|
|
200
|
+
if (!(removeVALs.length) > 1) {
|
|
201
|
+
this.db.query(removeSQL, removeVALs, callback);
|
|
202
|
+
} else { callback(); }
|
|
189
203
|
};
|
|
190
204
|
functions.push(removeFunction);
|
|
191
205
|
|
|
206
|
+
// @ts-ignore
|
|
192
207
|
async.parallel(functions, callback);
|
|
193
208
|
}
|
|
194
209
|
|
|
195
|
-
close(callback) {
|
|
210
|
+
close(callback:()=>{}) {
|
|
196
211
|
this.db.end(callback);
|
|
197
212
|
}
|
|
198
213
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import {Settings} from '../lib/AbstractDatabase';
|
|
2
2
|
|
|
3
3
|
const postgres = require('./postgres_db');
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
constructor(settings) {
|
|
5
|
+
export const Database = class PostgresDB extends postgres.Database {
|
|
6
|
+
constructor(settings:Settings) {
|
|
7
7
|
console.warn('ueberdb: The postgrespool database driver is deprecated ' +
|
|
8
8
|
'and will be removed in a future version. Use postgres instead.');
|
|
9
9
|
super(settings);
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 2011 Peter 'Pita' Martischka
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS-IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import AbstractDatabase, {Settings} from '../lib/AbstractDatabase';
|
|
18
|
+
import {createClient, RedisScripts, RedisFunctions, RedisModules} from 'redis';
|
|
19
|
+
import {BulkObject} from './cassandra_db';
|
|
20
|
+
import {RedisClientType} from '@redis/client';
|
|
21
|
+
|
|
22
|
+
export const Database = class RedisDB extends AbstractDatabase {
|
|
23
|
+
private _client: RedisClientType<{graph:
|
|
24
|
+
{CONFIG_GET: typeof import('@redis/graph/dist/commands/CONFIG_GET');
|
|
25
|
+
configGet: typeof import('@redis/graph/dist/commands/CONFIG_GET');
|
|
26
|
+
CONFIG_SET: typeof import('@redis/graph/dist/commands/CONFIG_SET');
|
|
27
|
+
configSet: typeof import('@redis/graph/dist/commands/CONFIG_SET');
|
|
28
|
+
DELETE: typeof import('@redis/graph/dist/commands/DELETE');
|
|
29
|
+
delete: typeof import('@redis/graph/dist/commands/DELETE');
|
|
30
|
+
EXPLAIN: typeof import('@redis/graph/dist/commands/EXPLAIN');
|
|
31
|
+
explain: typeof import('@redis/graph/dist/commands/EXPLAIN');
|
|
32
|
+
LIST: typeof import('@redis/graph/dist/commands/LIST');
|
|
33
|
+
list: typeof import('@redis/graph/dist/commands/LIST');
|
|
34
|
+
PROFILE: typeof import('@redis/graph/dist/commands/PROFILE');
|
|
35
|
+
profile: typeof import('@redis/graph/dist/commands/PROFILE');
|
|
36
|
+
QUERY: typeof import('@redis/graph/dist/commands/QUERY');
|
|
37
|
+
query: typeof import('@redis/graph/dist/commands/QUERY');
|
|
38
|
+
RO_QUERY: typeof import('@redis/graph/dist/commands/RO_QUERY');
|
|
39
|
+
roQuery: typeof import('@redis/graph/dist/commands/RO_QUERY');
|
|
40
|
+
SLOWLOG: typeof import('@redis/graph/dist/commands/SLOWLOG');
|
|
41
|
+
slowLog: typeof import('@redis/graph/dist/commands/SLOWLOG');};
|
|
42
|
+
json: {ARRAPPEND: typeof import('@redis/json/dist/commands/ARRAPPEND');
|
|
43
|
+
arrAppend: typeof import('@redis/json/dist/commands/ARRAPPEND');
|
|
44
|
+
ARRINDEX: typeof import('@redis/json/dist/commands/ARRINDEX');
|
|
45
|
+
arrIndex: typeof import('@redis/json/dist/commands/ARRINDEX');
|
|
46
|
+
ARRINSERT: typeof import('@redis/json/dist/commands/ARRINSERT');
|
|
47
|
+
arrInsert: typeof import('@redis/json/dist/commands/ARRINSERT'); ARRLEN: typeof import('@redis/json/dist/commands/ARRLEN'); arrLen: typeof import('@redis/json/dist/commands/ARRLEN'); ARRPOP: typeof import('@redis/json/dist/commands/ARRPOP'); arrPop: typeof import('@redis/json/dist/commands/ARRPOP'); ARRTRIM: typeof import('@redis/json/dist/commands/ARRTRIM'); arrTrim: typeof import('@redis/json/dist/commands/ARRTRIM'); DEBUG_MEMORY: typeof import('@redis/json/dist/commands/DEBUG_MEMORY'); debugMemory: typeof import('@redis/json/dist/commands/DEBUG_MEMORY'); DEL: typeof import('@redis/json/dist/commands/DEL'); del: typeof import('@redis/json/dist/commands/DEL'); FORGET: typeof import('@redis/json/dist/commands/FORGET'); forget: typeof import('@redis/json/dist/commands/FORGET'); GET: typeof import('@redis/json/dist/commands/GET'); get: typeof import('@redis/json/dist/commands/GET'); MGET: typeof import('@redis/json/dist/commands/MGET'); mGet: typeof import('@redis/json/dist/commands/MGET'); NUMINCRBY: typeof import('@redis/json/dist/commands/NUMINCRBY'); numIncrBy: typeof import('@redis/json/dist/commands/NUMINCRBY'); NUMMULTBY: typeof import('@redis/json/dist/commands/NUMMULTBY'); numMultBy: typeof import('@redis/json/dist/commands/NUMMULTBY'); OBJKEYS: typeof import('@redis/json/dist/commands/OBJKEYS'); objKeys: typeof import('@redis/json/dist/commands/OBJKEYS'); OBJLEN: typeof import('@redis/json/dist/commands/OBJLEN'); objLen: typeof import('@redis/json/dist/commands/OBJLEN'); RESP: typeof import('@redis/json/dist/commands/RESP'); resp: typeof import('@redis/json/dist/commands/RESP'); SET: typeof import('@redis/json/dist/commands/SET'); set: typeof import('@redis/json/dist/commands/SET'); STRAPPEND: typeof import('@redis/json/dist/commands/STRAPPEND'); strAppend: typeof import('@redis/json/dist/commands/STRAPPEND'); STRLEN: typeof import('@redis/json/dist/commands/STRLEN'); strLen: typeof import('@redis/json/dist/commands/STRLEN'); TYPE: typeof import('@redis/json/dist/commands/TYPE'); type: typeof import('@redis/json/dist/commands/TYPE');}; ft: {_LIST: typeof import('@redis/search/dist/commands/_LIST'); _list: typeof import('@redis/search/dist/commands/_LIST'); ALTER: typeof import('@redis/search/dist/commands/ALTER'); alter: typeof import('@redis/search/dist/commands/ALTER'); AGGREGATE_WITHCURSOR: typeof import('@redis/search/dist/commands/AGGREGATE_WITHCURSOR'); aggregateWithCursor: typeof import('@redis/search/dist/commands/AGGREGATE_WITHCURSOR'); AGGREGATE: typeof import('@redis/search/dist/commands/AGGREGATE'); aggregate: typeof import('@redis/search/dist/commands/AGGREGATE'); ALIASADD: typeof import('@redis/search/dist/commands/ALIASADD'); aliasAdd: typeof import('@redis/search/dist/commands/ALIASADD'); ALIASDEL: typeof import('@redis/search/dist/commands/ALIASDEL'); aliasDel: typeof import('@redis/search/dist/commands/ALIASDEL'); ALIASUPDATE: typeof import('@redis/search/dist/commands/ALIASUPDATE'); aliasUpdate: typeof import('@redis/search/dist/commands/ALIASUPDATE'); CONFIG_GET: typeof import('@redis/search/dist/commands/CONFIG_GET'); configGet: typeof import('@redis/search/dist/commands/CONFIG_GET'); CONFIG_SET: typeof import('@redis/search/dist/commands/CONFIG_SET'); configSet: typeof import('@redis/search/dist/commands/CONFIG_SET'); CREATE: typeof import('@redis/search/dist/commands/CREATE'); create: typeof import('@redis/search/dist/commands/CREATE'); CURSOR_DEL: typeof import('@redis/search/dist/commands/CURSOR_DEL'); cursorDel: typeof import('@redis/search/dist/commands/CURSOR_DEL'); CURSOR_READ: typeof import('@redis/search/dist/commands/CURSOR_READ'); cursorRead: typeof import('@redis/search/dist/commands/CURSOR_READ'); DICTADD: typeof import('@redis/search/dist/commands/DICTADD'); dictAdd: typeof import('@redis/search/dist/commands/DICTADD'); DICTDEL: typeof import('@redis/search/dist/commands/DICTDEL'); dictDel: typeof import('@redis/search/dist/commands/DICTDEL'); DICTDUMP: typeof import('@redis/search/dist/commands/DICTDUMP'); dictDump: typeof import('@redis/search/dist/commands/DICTDUMP'); DROPINDEX: typeof import('@redis/search/dist/commands/DROPINDEX'); dropIndex: typeof import('@redis/search/dist/commands/DROPINDEX'); EXPLAIN: typeof import('@redis/search/dist/commands/EXPLAIN'); explain: typeof import('@redis/search/dist/commands/EXPLAIN'); EXPLAINCLI: typeof import('@redis/search/dist/commands/EXPLAINCLI'); explainCli: typeof import('@redis/search/dist/commands/EXPLAINCLI'); INFO: typeof import('@redis/search/dist/commands/INFO'); info: typeof import('@redis/search/dist/commands/INFO'); PROFILESEARCH: typeof import('@redis/search/dist/commands/PROFILE_SEARCH'); profileSearch: typeof import('@redis/search/dist/commands/PROFILE_SEARCH'); PROFILEAGGREGATE: typeof import('@redis/search/dist/commands/PROFILE_AGGREGATE'); profileAggregate: typeof import('@redis/search/dist/commands/PROFILE_AGGREGATE'); SEARCH: typeof import('@redis/search/dist/commands/SEARCH'); search: typeof import('@redis/search/dist/commands/SEARCH'); SPELLCHECK: typeof import('@redis/search/dist/commands/SPELLCHECK'); spellCheck: typeof import('@redis/search/dist/commands/SPELLCHECK'); SUGADD: typeof import('@redis/search/dist/commands/SUGADD'); sugAdd: typeof import('@redis/search/dist/commands/SUGADD'); SUGDEL: typeof import('@redis/search/dist/commands/SUGDEL'); sugDel: typeof import('@redis/search/dist/commands/SUGDEL'); SUGGET_WITHPAYLOADS: typeof import('@redis/search/dist/commands/SUGGET_WITHPAYLOADS'); sugGetWithPayloads: typeof import('@redis/search/dist/commands/SUGGET_WITHPAYLOADS'); SUGGET_WITHSCORES_WITHPAYLOADS: typeof import('@redis/search/dist/commands/SUGGET_WITHSCORES_WITHPAYLOADS'); sugGetWithScoresWithPayloads: typeof import('@redis/search/dist/commands/SUGGET_WITHSCORES_WITHPAYLOADS'); SUGGET_WITHSCORES: typeof import('@redis/search/dist/commands/SUGGET_WITHSCORES'); sugGetWithScores: typeof import('@redis/search/dist/commands/SUGGET_WITHSCORES'); SUGGET: typeof import('@redis/search/dist/commands/SUGGET'); sugGet: typeof import('@redis/search/dist/commands/SUGGET'); SUGLEN: typeof import('@redis/search/dist/commands/SUGLEN'); sugLen: typeof import('@redis/search/dist/commands/SUGLEN'); SYNDUMP: typeof import('@redis/search/dist/commands/SYNDUMP'); synDump: typeof import('@redis/search/dist/commands/SYNDUMP'); SYNUPDATE: typeof import('@redis/search/dist/commands/SYNUPDATE'); synUpdate: typeof import('@redis/search/dist/commands/SYNUPDATE'); TAGVALS: typeof import('@redis/search/dist/commands/TAGVALS'); tagVals: typeof import('@redis/search/dist/commands/TAGVALS');}; ts: {ADD: typeof import('@redis/time-series/dist/commands/ADD'); add: typeof import('@redis/time-series/dist/commands/ADD'); ALTER: typeof import('@redis/time-series/dist/commands/ALTER'); alter: typeof import('@redis/time-series/dist/commands/ALTER'); CREATE: typeof import('@redis/time-series/dist/commands/CREATE'); create: typeof import('@redis/time-series/dist/commands/CREATE'); CREATERULE: typeof import('@redis/time-series/dist/commands/CREATERULE'); createRule: typeof import('@redis/time-series/dist/commands/CREATERULE'); DECRBY: typeof import('@redis/time-series/dist/commands/DECRBY'); decrBy: typeof import('@redis/time-series/dist/commands/DECRBY'); DEL: typeof import('@redis/time-series/dist/commands/DEL'); del: typeof import('@redis/time-series/dist/commands/DEL'); DELETERULE: typeof import('@redis/time-series/dist/commands/DELETERULE'); deleteRule: typeof import('@redis/time-series/dist/commands/DELETERULE'); GET: typeof import('@redis/time-series/dist/commands/GET'); get: typeof import('@redis/time-series/dist/commands/GET'); INCRBY: typeof import('@redis/time-series/dist/commands/INCRBY'); incrBy: typeof import('@redis/time-series/dist/commands/INCRBY'); INFO_DEBUG: typeof import('@redis/time-series/dist/commands/INFO_DEBUG'); infoDebug: typeof import('@redis/time-series/dist/commands/INFO_DEBUG'); INFO: typeof import('@redis/time-series/dist/commands/INFO'); info: typeof import('@redis/time-series/dist/commands/INFO'); MADD: typeof import('@redis/time-series/dist/commands/MADD'); mAdd: typeof import('@redis/time-series/dist/commands/MADD'); MGET: typeof import('@redis/time-series/dist/commands/MGET'); mGet: typeof import('@redis/time-series/dist/commands/MGET'); MGET_WITHLABELS: typeof import('@redis/time-series/dist/commands/MGET_WITHLABELS'); mGetWithLabels: typeof import('@redis/time-series/dist/commands/MGET_WITHLABELS'); QUERYINDEX: typeof import('@redis/time-series/dist/commands/QUERYINDEX'); queryIndex: typeof import('@redis/time-series/dist/commands/QUERYINDEX'); RANGE: typeof import('@redis/time-series/dist/commands/RANGE'); range: typeof import('@redis/time-series/dist/commands/RANGE'); REVRANGE: typeof import('@redis/time-series/dist/commands/REVRANGE'); revRange: typeof import('@redis/time-series/dist/commands/REVRANGE'); MRANGE: typeof import('@redis/time-series/dist/commands/MRANGE'); mRange: typeof import('@redis/time-series/dist/commands/MRANGE'); MRANGE_WITHLABELS: typeof import('@redis/time-series/dist/commands/MRANGE_WITHLABELS'); mRangeWithLabels: typeof import('@redis/time-series/dist/commands/MRANGE_WITHLABELS'); MREVRANGE: typeof import('@redis/time-series/dist/commands/MREVRANGE'); mRevRange: typeof import('@redis/time-series/dist/commands/MREVRANGE'); MREVRANGE_WITHLABELS: typeof import('@redis/time-series/dist/commands/MREVRANGE_WITHLABELS'); mRevRangeWithLabels: typeof import('@redis/time-series/dist/commands/MREVRANGE_WITHLABELS');}; bf: {ADD: typeof import('@redis/bloom/dist/commands/bloom/ADD'); add: typeof import('@redis/bloom/dist/commands/bloom/ADD'); CARD: typeof import('@redis/bloom/dist/commands/bloom/CARD'); card: typeof import('@redis/bloom/dist/commands/bloom/CARD'); EXISTS: typeof import('@redis/bloom/dist/commands/bloom/EXISTS'); exists: typeof import('@redis/bloom/dist/commands/bloom/EXISTS'); INFO: typeof import('@redis/bloom/dist/commands/bloom/INFO'); info: typeof import('@redis/bloom/dist/commands/bloom/INFO'); INSERT: typeof import('@redis/bloom/dist/commands/bloom/INSERT'); insert: typeof import('@redis/bloom/dist/commands/bloom/INSERT'); LOADCHUNK: typeof import('@redis/bloom/dist/commands/bloom/LOADCHUNK'); loadChunk: typeof import('@redis/bloom/dist/commands/bloom/LOADCHUNK'); MADD: typeof import('@redis/bloom/dist/commands/bloom/MADD'); mAdd: typeof import('@redis/bloom/dist/commands/bloom/MADD'); MEXISTS: typeof import('@redis/bloom/dist/commands/bloom/MEXISTS'); mExists: typeof import('@redis/bloom/dist/commands/bloom/MEXISTS'); RESERVE: typeof import('@redis/bloom/dist/commands/bloom/RESERVE'); reserve: typeof import('@redis/bloom/dist/commands/bloom/RESERVE'); SCANDUMP: typeof import('@redis/bloom/dist/commands/bloom/SCANDUMP'); scanDump: typeof import('@redis/bloom/dist/commands/bloom/SCANDUMP');}; cms: {INCRBY: typeof import('@redis/bloom/dist/commands/count-min-sketch/INCRBY'); incrBy: typeof import('@redis/bloom/dist/commands/count-min-sketch/INCRBY'); INFO: typeof import('@redis/bloom/dist/commands/count-min-sketch/INFO'); info: typeof import('@redis/bloom/dist/commands/count-min-sketch/INFO'); INITBYDIM: typeof import('@redis/bloom/dist/commands/count-min-sketch/INITBYDIM'); initByDim: typeof import('@redis/bloom/dist/commands/count-min-sketch/INITBYDIM'); INITBYPROB: typeof import('@redis/bloom/dist/commands/count-min-sketch/INITBYPROB'); initByProb: typeof import('@redis/bloom/dist/commands/count-min-sketch/INITBYPROB'); MERGE: typeof import('@redis/bloom/dist/commands/count-min-sketch/MERGE'); merge: typeof import('@redis/bloom/dist/commands/count-min-sketch/MERGE'); QUERY: typeof import('@redis/bloom/dist/commands/count-min-sketch/QUERY'); query: typeof import('@redis/bloom/dist/commands/count-min-sketch/QUERY');}; cf: {ADD: typeof import('@redis/bloom/dist/commands/cuckoo/ADD'); add: typeof import('@redis/bloom/dist/commands/cuckoo/ADD'); ADDNX: typeof import('@redis/bloom/dist/commands/cuckoo/ADDNX'); addNX: typeof import('@redis/bloom/dist/commands/cuckoo/ADDNX'); COUNT: typeof import('@redis/bloom/dist/commands/cuckoo/COUNT'); count: typeof import('@redis/bloom/dist/commands/cuckoo/COUNT'); DEL: typeof import('@redis/bloom/dist/commands/cuckoo/DEL'); del: typeof import('@redis/bloom/dist/commands/cuckoo/DEL'); EXISTS: typeof import('@redis/bloom/dist/commands/cuckoo/EXISTS'); exists: typeof import('@redis/bloom/dist/commands/cuckoo/EXISTS'); INFO: typeof import('@redis/bloom/dist/commands/cuckoo/INFO'); info: typeof import('@redis/bloom/dist/commands/cuckoo/INFO'); INSERT: typeof import('@redis/bloom/dist/commands/cuckoo/INSERT'); insert: typeof import('@redis/bloom/dist/commands/cuckoo/INSERT'); INSERTNX: typeof import('@redis/bloom/dist/commands/cuckoo/INSERTNX'); insertNX: typeof import('@redis/bloom/dist/commands/cuckoo/INSERTNX'); LOADCHUNK: typeof import('@redis/bloom/dist/commands/cuckoo/LOADCHUNK'); loadChunk: typeof import('@redis/bloom/dist/commands/cuckoo/LOADCHUNK'); RESERVE: typeof import('@redis/bloom/dist/commands/cuckoo/RESERVE'); reserve: typeof import('@redis/bloom/dist/commands/cuckoo/RESERVE'); SCANDUMP: typeof import('@redis/bloom/dist/commands/cuckoo/SCANDUMP'); scanDump: typeof import('@redis/bloom/dist/commands/cuckoo/SCANDUMP');}; tDigest: {ADD: typeof import('@redis/bloom/dist/commands/t-digest/ADD'); add: typeof import('@redis/bloom/dist/commands/t-digest/ADD'); BYRANK: typeof import('@redis/bloom/dist/commands/t-digest/BYRANK'); byRank: typeof import('@redis/bloom/dist/commands/t-digest/BYRANK'); BYREVRANK: typeof import('@redis/bloom/dist/commands/t-digest/BYREVRANK'); byRevRank: typeof import('@redis/bloom/dist/commands/t-digest/BYREVRANK'); CDF: typeof import('@redis/bloom/dist/commands/t-digest/CDF'); cdf: typeof import('@redis/bloom/dist/commands/t-digest/CDF'); CREATE: typeof import('@redis/bloom/dist/commands/t-digest/CREATE'); create: typeof import('@redis/bloom/dist/commands/t-digest/CREATE'); INFO: typeof import('@redis/bloom/dist/commands/t-digest/INFO'); info: typeof import('@redis/bloom/dist/commands/t-digest/INFO'); MAX: typeof import('@redis/bloom/dist/commands/t-digest/MAX'); max: typeof import('@redis/bloom/dist/commands/t-digest/MAX'); MERGE: typeof import('@redis/bloom/dist/commands/t-digest/MERGE'); merge: typeof import('@redis/bloom/dist/commands/t-digest/MERGE'); MIN: typeof import('@redis/bloom/dist/commands/t-digest/MIN'); min: typeof import('@redis/bloom/dist/commands/t-digest/MIN'); QUANTILE: typeof import('@redis/bloom/dist/commands/t-digest/QUANTILE'); quantile: typeof import('@redis/bloom/dist/commands/t-digest/QUANTILE'); RANK: typeof import('@redis/bloom/dist/commands/t-digest/RANK'); rank: typeof import('@redis/bloom/dist/commands/t-digest/RANK'); RESET: typeof import('@redis/bloom/dist/commands/t-digest/RESET'); reset: typeof import('@redis/bloom/dist/commands/t-digest/RESET'); REVRANK: typeof import('@redis/bloom/dist/commands/t-digest/REVRANK'); revRank: typeof import('@redis/bloom/dist/commands/t-digest/REVRANK'); TRIMMED_MEAN: typeof import('@redis/bloom/dist/commands/t-digest/TRIMMED_MEAN'); trimmedMean: typeof import('@redis/bloom/dist/commands/t-digest/TRIMMED_MEAN');}; topK: {ADD: typeof import('@redis/bloom/dist/commands/top-k/ADD'); add: typeof import('@redis/bloom/dist/commands/top-k/ADD'); COUNT: typeof import('@redis/bloom/dist/commands/top-k/COUNT'); count: typeof import('@redis/bloom/dist/commands/top-k/COUNT'); INCRBY: typeof import('@redis/bloom/dist/commands/top-k/INCRBY'); incrBy: typeof import('@redis/bloom/dist/commands/top-k/INCRBY'); INFO: typeof import('@redis/bloom/dist/commands/top-k/INFO'); info: typeof import('@redis/bloom/dist/commands/top-k/INFO'); LIST_WITHCOUNT: typeof import('@redis/bloom/dist/commands/top-k/LIST_WITHCOUNT'); listWithCount: typeof import('@redis/bloom/dist/commands/top-k/LIST_WITHCOUNT'); LIST: typeof import('@redis/bloom/dist/commands/top-k/LIST'); list: typeof import('@redis/bloom/dist/commands/top-k/LIST'); QUERY: typeof import('@redis/bloom/dist/commands/top-k/QUERY'); query: typeof import('@redis/bloom/dist/commands/top-k/QUERY'); RESERVE: typeof import('@redis/bloom/dist/commands/top-k/RESERVE'); reserve: typeof import('@redis/bloom/dist/commands/top-k/RESERVE');};} & RedisModules, RedisFunctions, RedisScripts> | null;
|
|
48
|
+
constructor(settings:Settings) {
|
|
49
|
+
super();
|
|
50
|
+
this._client = null;
|
|
51
|
+
this.settings = settings || {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get isAsync() { return true; }
|
|
55
|
+
|
|
56
|
+
async init() {
|
|
57
|
+
this._client = createClient({url: this.settings.url});
|
|
58
|
+
if (this._client) {
|
|
59
|
+
await this._client.connect();
|
|
60
|
+
await this._client.ping();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async get(key:string) {
|
|
65
|
+
if (this._client == null) return null;
|
|
66
|
+
return await this._client.get(key);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async findKeys(key:string, notKey:string) {
|
|
70
|
+
if (this._client == null) return null;
|
|
71
|
+
const [type] = /^([^:*]+):\*$/.exec(key) || [];
|
|
72
|
+
if (type != null && ['*:*:*', `${key}:*`].includes(notKey)) {
|
|
73
|
+
// Performance optimization for a common Etherpad case.
|
|
74
|
+
return await this._client.sMembers(`ueberDB:keys:${type}`);
|
|
75
|
+
}
|
|
76
|
+
let keys = await this._client.keys(key.replace(/[?[\]\\]/g, '\\$&'));
|
|
77
|
+
if (notKey != null) {
|
|
78
|
+
const regex = this.createFindRegex(key, notKey);
|
|
79
|
+
keys = keys.filter((k:string) => regex.test(k));
|
|
80
|
+
}
|
|
81
|
+
return keys;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async set(key:string, value:string) {
|
|
85
|
+
if (this._client == null) return null;
|
|
86
|
+
const matches = /^([^:]+):([^:]+)$/.exec(key);
|
|
87
|
+
await Promise.all([
|
|
88
|
+
matches && this._client.sAdd(`ueberDB:keys:${matches[1]}`, matches[0]),
|
|
89
|
+
this._client.set(key, value),
|
|
90
|
+
]);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async remove(key:string) {
|
|
94
|
+
if (this._client == null) return null;
|
|
95
|
+
const matches = /^([^:]+):([^:]+)$/.exec(key);
|
|
96
|
+
await Promise.all([
|
|
97
|
+
matches && this._client.sRem(`ueberDB:keys:${matches[1]}`, matches[0]),
|
|
98
|
+
this._client.del(key),
|
|
99
|
+
]);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async doBulk(bulk: BulkObject[]) {
|
|
103
|
+
if (this._client == null) return null;
|
|
104
|
+
const multi = this._client.multi();
|
|
105
|
+
|
|
106
|
+
for (const {key, type, value} of bulk) {
|
|
107
|
+
const matches = /^([^:]+):([^:]+)$/.exec(key);
|
|
108
|
+
if (type === 'set') {
|
|
109
|
+
if (matches) {
|
|
110
|
+
multi.sAdd(`ueberDB:keys:${matches[1]}`, matches[0]);
|
|
111
|
+
}
|
|
112
|
+
multi.set(key, value as string);
|
|
113
|
+
} else if (type === 'remove') {
|
|
114
|
+
if (matches) {
|
|
115
|
+
multi.sRem(`ueberDB:keys:${matches[1]}`, matches[0]);
|
|
116
|
+
}
|
|
117
|
+
multi.del(key);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
await multi.exec();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async close() {
|
|
125
|
+
if (this._client == null) return null;
|
|
126
|
+
await this._client.quit();
|
|
127
|
+
this._client = null;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
'use strict';
|
|
2
1
|
/**
|
|
3
2
|
* 2016 Remi Arnaud
|
|
4
3
|
*
|
|
@@ -15,12 +14,18 @@
|
|
|
15
14
|
* limitations under the License.
|
|
16
15
|
*/
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
import AbstractDatabase, {Settings} from '../lib/AbstractDatabase';
|
|
18
|
+
import r from 'rethinkdb';
|
|
19
|
+
import async from 'async';
|
|
20
|
+
import {BulkObject} from './cassandra_db';
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
export const Database = class extends AbstractDatabase {
|
|
23
|
+
private host: string;
|
|
24
|
+
private db: string;
|
|
25
|
+
private port: number | string;
|
|
26
|
+
private table: string;
|
|
27
|
+
private connection: r.Connection | null;
|
|
28
|
+
constructor(settings:Settings) {
|
|
24
29
|
super();
|
|
25
30
|
if (!settings) settings = {};
|
|
26
31
|
if (!settings.host) { settings.host = 'localhost'; }
|
|
@@ -35,7 +40,8 @@ exports.Database = class extends AbstractDatabase {
|
|
|
35
40
|
this.connection = null;
|
|
36
41
|
}
|
|
37
42
|
|
|
38
|
-
init(callback) {
|
|
43
|
+
init(callback: (p: any, cursor: any)=>{}) {
|
|
44
|
+
// @ts-ignore
|
|
39
45
|
r.connect(this, (err, conn) => {
|
|
40
46
|
if (err) throw err;
|
|
41
47
|
this.connection = conn;
|
|
@@ -43,21 +49,25 @@ exports.Database = class extends AbstractDatabase {
|
|
|
43
49
|
r.table(this.table).run(this.connection, (err, cursor) => {
|
|
44
50
|
if (err) {
|
|
45
51
|
// assuming table does not exists
|
|
52
|
+
// @ts-ignore
|
|
46
53
|
r.tableCreate(this.table).run(this.connection, callback);
|
|
47
54
|
} else if (callback) { callback(null, cursor); }
|
|
48
55
|
});
|
|
49
56
|
});
|
|
50
57
|
}
|
|
51
58
|
|
|
52
|
-
get(key, callback) {
|
|
59
|
+
get(key:string, callback: (err: Error, p: any)=>{}) {
|
|
60
|
+
// @ts-ignore
|
|
53
61
|
r.table(this.table).get(key).run(this.connection, (err, item) => {
|
|
62
|
+
// @ts-ignore
|
|
54
63
|
callback(err, (item ? item.content : item));
|
|
55
64
|
});
|
|
56
65
|
}
|
|
57
66
|
|
|
58
|
-
findKeys(key, notKey, callback) {
|
|
67
|
+
findKeys(key:string, notKey:string, callback:()=>{}) {
|
|
59
68
|
const keys = [];
|
|
60
69
|
const regex = this.createFindRegex(key, notKey);
|
|
70
|
+
// @ts-ignore
|
|
61
71
|
r.filter((item) => {
|
|
62
72
|
if (item.id.search(regex) !== -1) {
|
|
63
73
|
keys.push(item.id);
|
|
@@ -65,15 +75,15 @@ exports.Database = class extends AbstractDatabase {
|
|
|
65
75
|
}).run(this.connection, callback);
|
|
66
76
|
}
|
|
67
77
|
|
|
68
|
-
set(key, value, callback) {
|
|
78
|
+
set(key:string, value:string, callback:()=>{}) {
|
|
69
79
|
r.table(this.table)
|
|
70
80
|
.insert({id: key, content: value}, {conflict: 'replace'})
|
|
71
|
-
.run(this.connection, callback);
|
|
81
|
+
.run(this.connection as r.Connection, callback);
|
|
72
82
|
}
|
|
73
83
|
|
|
74
|
-
doBulk(bulk, callback) {
|
|
75
|
-
const _in = [];
|
|
76
|
-
const _out = [];
|
|
84
|
+
doBulk(bulk: BulkObject[], callback: ()=>{}) {
|
|
85
|
+
const _in: any[] = [];
|
|
86
|
+
const _out: string | string[] | r.Expression<any> = [];
|
|
77
87
|
|
|
78
88
|
for (const i in bulk) {
|
|
79
89
|
if (bulk[i].type === 'set') {
|
|
@@ -82,17 +92,23 @@ exports.Database = class extends AbstractDatabase {
|
|
|
82
92
|
_out.push(bulk[i].key);
|
|
83
93
|
}
|
|
84
94
|
}
|
|
95
|
+
|
|
85
96
|
async.parallel([
|
|
86
|
-
(cb) => {
|
|
87
|
-
|
|
97
|
+
(cb) => { // @ts-ignore
|
|
98
|
+
r.table(this.table).insert(_in, {conflict: 'replace'}).run(this.connection, cb);
|
|
99
|
+
},
|
|
100
|
+
(cb) => { // @ts-ignore
|
|
101
|
+
r.table(this.table).getAll(_out).delete().run(this.connection, cb);
|
|
102
|
+
},
|
|
88
103
|
], callback);
|
|
89
104
|
}
|
|
90
105
|
|
|
91
|
-
remove(key, callback) {
|
|
106
|
+
remove(key:string, callback:()=>{}) {
|
|
107
|
+
// @ts-ignore
|
|
92
108
|
r.table(this.table).get(key).delete().run(this.connection, callback);
|
|
93
109
|
}
|
|
94
110
|
|
|
95
|
-
close(callback) {
|
|
96
|
-
this.connection.close(callback);
|
|
111
|
+
close(callback:()=>{}) {
|
|
112
|
+
if (this.connection) { this.connection.close(callback); }
|
|
97
113
|
}
|
|
98
114
|
};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
+
import {BulkObject} from "./cassandra_db";
|
|
3
|
+
import {Settings} from "../lib/AbstractDatabase";
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
6
|
* 2011 Peter 'Pita' Martischka
|
|
4
7
|
*
|
|
@@ -15,9 +18,9 @@
|
|
|
15
18
|
* limitations under the License.
|
|
16
19
|
*/
|
|
17
20
|
|
|
18
|
-
let
|
|
21
|
+
let SQDB: any;
|
|
19
22
|
try {
|
|
20
|
-
|
|
23
|
+
SQDB = require('sqlite3').Database;
|
|
21
24
|
} catch (err) {
|
|
22
25
|
throw new Error(
|
|
23
26
|
'sqlite3 not found. It was removed from ueberdb\'s dependencies because it requires ' +
|
|
@@ -25,13 +28,14 @@ try {
|
|
|
25
28
|
'"npm install sqlite3" in your etherpad-lite ./src directory.');
|
|
26
29
|
}
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
import AbstractDatabase from '../lib/AbstractDatabase';
|
|
32
|
+
import util from 'util';
|
|
30
33
|
|
|
31
|
-
const escape = (val) => `'${val.replace(/'/g, "''")}'`;
|
|
34
|
+
const escape = (val:string) => `'${val.replace(/'/g, "''")}'`;
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
export const Database = class SQLiteDB extends AbstractDatabase {
|
|
37
|
+
private db: typeof SQDB|null;
|
|
38
|
+
constructor(settings:Settings) {
|
|
35
39
|
super();
|
|
36
40
|
this.db = null;
|
|
37
41
|
|
|
@@ -53,7 +57,15 @@ exports.Database = class extends AbstractDatabase {
|
|
|
53
57
|
}
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
|
|
60
|
+
init(callback:Function) {
|
|
61
|
+
util.callbackify(async () => {
|
|
62
|
+
this.db = new SQDB(this.settings.filename as string)
|
|
63
|
+
await this._query('CREATE TABLE IF NOT EXISTS store (key TEXT PRIMARY KEY, value TEXT)');
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
})(callback);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async _query(sql:string, params = []) {
|
|
57
69
|
// It is unclear how util.promisify() deals with variadic functions, so it is not used here.
|
|
58
70
|
return await new Promise((resolve, reject) => {
|
|
59
71
|
// According to sqlite3's documentation, .run() method (and maybe .all() and .get(); the
|
|
@@ -61,7 +73,7 @@ exports.Database = class extends AbstractDatabase {
|
|
|
61
73
|
// guarantees that it is safe to call a Promise executor's resolve and reject functions
|
|
62
74
|
// multiple times. The subsequent calls are ignored, except Node.js's 'process' object emits a
|
|
63
75
|
// 'multipleResolves' event to aid in debugging.
|
|
64
|
-
this.db.all(sql, params, (err, rows) => {
|
|
76
|
+
this.db&&this.db.all(sql, params, (err:Error, rows:any) => {
|
|
65
77
|
if (err != null) return reject(err);
|
|
66
78
|
resolve(rows);
|
|
67
79
|
});
|
|
@@ -70,33 +82,21 @@ exports.Database = class extends AbstractDatabase {
|
|
|
70
82
|
|
|
71
83
|
// Temporary callbackified version of _query. This will be removed once all database objects are
|
|
72
84
|
// asyncified.
|
|
73
|
-
_queryCb(sql, params, callback) {
|
|
85
|
+
_queryCb(sql: string, params: string[], callback: Function) {
|
|
74
86
|
// It is unclear how util.callbackify() handles optional parameters, so it is not used here.
|
|
75
|
-
const p = this._query(sql, params);
|
|
87
|
+
const p = this._query(sql, params as []);
|
|
76
88
|
if (callback) p.then((rows) => callback(null, rows), (err) => callback(err || new Error(err)));
|
|
77
89
|
}
|
|
78
90
|
|
|
79
|
-
init(callback) {
|
|
80
|
-
util.callbackify(async () => {
|
|
81
|
-
this.db = await new Promise((resolve, reject) => {
|
|
82
|
-
new sqlite3.Database(this.settings.filename, function (err) {
|
|
83
|
-
if (err != null) return reject(err);
|
|
84
|
-
// The use of `this` relies on an undocumented feature of sqlite3:
|
|
85
|
-
// https://github.com/mapbox/node-sqlite3/issues/1408
|
|
86
|
-
resolve(this);
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
await this._query('CREATE TABLE IF NOT EXISTS store (key TEXT PRIMARY KEY, value TEXT)');
|
|
90
|
-
})(callback);
|
|
91
|
-
}
|
|
92
91
|
|
|
93
|
-
|
|
92
|
+
|
|
93
|
+
get(key:string, callback:Function) {
|
|
94
94
|
this._queryCb(
|
|
95
95
|
'SELECT value FROM store WHERE key = ?', [key],
|
|
96
|
-
(err, rows) => callback(err, err == null && rows && rows.length ? rows[0].value : null));
|
|
96
|
+
(err:Error, rows:any) => callback(err, err == null && rows && rows.length ? rows[0].value : null));
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
findKeys(key, notKey, callback) {
|
|
99
|
+
findKeys(key:string, notKey:string, callback:Function) {
|
|
100
100
|
let query = 'SELECT key FROM store WHERE key LIKE ?';
|
|
101
101
|
const params = [];
|
|
102
102
|
// desired keys are %key:%, e.g. pad:%
|
|
@@ -110,8 +110,8 @@ exports.Database = class extends AbstractDatabase {
|
|
|
110
110
|
params.push(notKey);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
this._queryCb(query, params, (err, results) => {
|
|
114
|
-
const value = [];
|
|
113
|
+
this._queryCb(query, params, (err: Error, results: { val: string, key: string }[]) => {
|
|
114
|
+
const value: string[] = [];
|
|
115
115
|
|
|
116
116
|
if (!err && Object.keys(results).length > 0) {
|
|
117
117
|
results.forEach((val) => {
|
|
@@ -123,26 +123,26 @@ exports.Database = class extends AbstractDatabase {
|
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
set(key, value, callback) {
|
|
126
|
+
set(key:string, value:string, callback:Function) {
|
|
127
127
|
this._queryCb('REPLACE INTO store VALUES (?,?)', [key, value], callback);
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
remove(key, callback) {
|
|
130
|
+
remove(key:string, callback:Function) {
|
|
131
131
|
this._queryCb('DELETE FROM store WHERE key = ?', [key], callback);
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
doBulk(bulk, callback) {
|
|
134
|
+
doBulk(bulk:BulkObject[], callback:Function) {
|
|
135
135
|
let sql = 'BEGIN TRANSACTION;\n';
|
|
136
136
|
for (const i in bulk) {
|
|
137
137
|
if (bulk[i].type === 'set') {
|
|
138
|
-
sql += `REPLACE INTO store VALUES (${escape(bulk[i].key)}, ${escape(bulk[i].value)});\n`;
|
|
138
|
+
sql += `REPLACE INTO store VALUES (${escape(bulk[i].key)}, ${escape(bulk[i].value as string)});\n`;
|
|
139
139
|
} else if (bulk[i].type === 'remove') {
|
|
140
140
|
sql += `DELETE FROM store WHERE key = ${escape(bulk[i].key)};\n`;
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
sql += 'END TRANSACTION;';
|
|
144
144
|
|
|
145
|
-
this.db.exec(sql, (err) => {
|
|
145
|
+
this.db&&this.db.exec(sql, (err:any) => {
|
|
146
146
|
if (err) {
|
|
147
147
|
console.error('ERROR WITH SQL: ');
|
|
148
148
|
console.error(sql);
|
|
@@ -152,7 +152,8 @@ exports.Database = class extends AbstractDatabase {
|
|
|
152
152
|
});
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
close(callback) {
|
|
156
|
-
|
|
155
|
+
close(callback: Function) {
|
|
156
|
+
callback()
|
|
157
|
+
this.db&&this.db.close((err:any) => callback(err));
|
|
157
158
|
}
|
|
158
159
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Docker compose setup for testing with multiple databases
|
|
2
|
+
version: '3.8'
|
|
3
|
+
services:
|
|
4
|
+
couchdb:
|
|
5
|
+
image: couchdb
|
|
6
|
+
ports:
|
|
7
|
+
- "5984:5984"
|
|
8
|
+
environment:
|
|
9
|
+
COUCHDB_USER: ueberdb
|
|
10
|
+
COUCHDB_PASSWORD: ueberdb
|
|
11
|
+
elasticsearch:
|
|
12
|
+
image: elasticsearch:7.17.3
|
|
13
|
+
ports:
|
|
14
|
+
- 9200:9200
|
|
15
|
+
environment:
|
|
16
|
+
discovery.type: single-node
|
|
17
|
+
mongo:
|
|
18
|
+
image: mongo
|
|
19
|
+
ports:
|
|
20
|
+
- 27017:27017
|
|
21
|
+
environment:
|
|
22
|
+
MONGO_INITDB_DATABASE: mydb_test
|
|
23
|
+
mysql:
|
|
24
|
+
image: mariadb
|
|
25
|
+
ports:
|
|
26
|
+
- 3306:3306
|
|
27
|
+
environment:
|
|
28
|
+
MYSQL_ROOT_PASSWORD: password
|
|
29
|
+
MYSQL_USER: ueberdb
|
|
30
|
+
MYSQL_PASSWORD: ueberdb
|
|
31
|
+
MYSQL_DATABASE: ueberdb
|
|
32
|
+
postgres:
|
|
33
|
+
image: postgres:14-alpine
|
|
34
|
+
ports:
|
|
35
|
+
- 5432:5432
|
|
36
|
+
environment:
|
|
37
|
+
POSTGRES_USER: ueberdb
|
|
38
|
+
POSTGRES_PASSWORD: ueberdb
|
|
39
|
+
POSTGRES_DB: ueberdb
|
|
40
|
+
POSTGRES_HOST_AUTH_METHOD: "trust"
|
|
41
|
+
redis:
|
|
42
|
+
image: redis
|
|
43
|
+
ports:
|
|
44
|
+
- "6379:6379"
|