@sqlitecloud/drivers 1.0.122 → 1.0.193
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 +29 -0
- package/lib/drivers/connection-tls.d.ts +1 -1
- package/lib/drivers/connection-tls.js +3 -3
- package/lib/drivers/database.d.ts +10 -0
- package/lib/drivers/database.js +23 -0
- package/lib/drivers/protocol.d.ts +1 -0
- package/lib/drivers/protocol.js +4 -2
- package/lib/drivers/pubsub.d.ts +48 -0
- package/lib/drivers/pubsub.js +116 -0
- package/lib/drivers/types.d.ts +1 -0
- package/lib/drivers/utilities.js +16 -12
- package/lib/sqlitecloud.drivers.dev.js +16 -5
- package/lib/sqlitecloud.drivers.js +1 -1
- package/package.json +19 -16
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ npm install @sqlitecloud/drivers
|
|
|
18
18
|
import { Database } from '@sqlitecloud/drivers'
|
|
19
19
|
|
|
20
20
|
let database = new Database('sqlitecloud://user:password@xxx.sqlite.cloud:8860/chinook.sqlite')
|
|
21
|
+
// or use sqlitecloud://xxx.sqlite.cloud:8860?apikey=xxxxxxx
|
|
21
22
|
|
|
22
23
|
let name = 'Breaking The Rules'
|
|
23
24
|
|
|
@@ -31,6 +32,34 @@ We aim for full compatibility with the established [sqlite3 API](https://www.npm
|
|
|
31
32
|
|
|
32
33
|
The package is developed entirely in TypeScript and is fully compatible with JavaScript. It doesn't require any native libraries. This makes it a straightforward and effective tool for managing cloud-based databases in a familiar SQLite environment.
|
|
33
34
|
|
|
35
|
+
## Publish / Subscribe (Pub/Sub)
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { Database } from '@sqlitecloud/drivers'
|
|
39
|
+
import { PubSub, PUBSUB_ENTITY_TYPE } from '@sqlitecloud/drivers/lib/drivers/pubsub'
|
|
40
|
+
|
|
41
|
+
let database = new Database('sqlitecloud://user:password@xxx.sqlite.cloud:8860/chinook.sqlite')
|
|
42
|
+
// or use sqlitecloud://xxx.sqlite.cloud:8860?apikey=xxxxxxx
|
|
43
|
+
|
|
44
|
+
const pubSub: PubSub = await database.getPubSub()
|
|
45
|
+
|
|
46
|
+
await pubSub.listen(PUBSUB_ENTITY_TYPE.TABLE, 'albums', (error, results, data) => {
|
|
47
|
+
if (results) {
|
|
48
|
+
// Changes on albums table will be received here as JSON object
|
|
49
|
+
console.log('Received message:', results)
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
await database.sql`INSERT INTO albums (Title, ArtistId) values ('Brand new song', 1)`
|
|
54
|
+
|
|
55
|
+
// Stop listening changes on the table
|
|
56
|
+
await pubSub.unlisten(PUBSUB_ENTITY_TYPE.TABLE, 'albums')
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Pub/Sub is a messaging pattern that allows multiple applications to communicate with each other asynchronously. In the context of SQLiteCloud, Pub/Sub can be used to provide real-time updates and notifications to subscribed applications whenever data changes in the database or it can be used to send payloads (messages) to anyone subscribed to a channel.
|
|
60
|
+
|
|
61
|
+
Pub/Sub Documentation: [https://docs.sqlitecloud.io/docs/pub-sub](https://docs.sqlitecloud.io/docs/pub-sub)
|
|
62
|
+
|
|
34
63
|
## More
|
|
35
64
|
|
|
36
65
|
How do I deploy SQLite in the cloud?
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { type SQLiteCloudConfig, type ErrorCallback, type ResultsCallback } from './types';
|
|
5
5
|
import { SQLiteCloudConnection } from './connection';
|
|
6
6
|
/**
|
|
7
|
-
* Implementation of SQLiteCloudConnection that connects to the database using specific
|
|
7
|
+
* Implementation of SQLiteCloudConnection that connects to the database using specific tls APIs
|
|
8
8
|
* that connect to native sockets or tls sockets and communicates via raw, binary protocol.
|
|
9
9
|
*/
|
|
10
10
|
export declare class SQLiteCloudTlsConnection extends SQLiteCloudConnection {
|
|
@@ -33,7 +33,7 @@ const utilities_1 = require("./utilities");
|
|
|
33
33
|
const protocol_1 = require("./protocol");
|
|
34
34
|
const tls = __importStar(require("tls"));
|
|
35
35
|
/**
|
|
36
|
-
* Implementation of SQLiteCloudConnection that connects to the database using specific
|
|
36
|
+
* Implementation of SQLiteCloudConnection that connects to the database using specific tls APIs
|
|
37
37
|
* that connect to native sockets or tls sockets and communicates via raw, binary protocol.
|
|
38
38
|
*/
|
|
39
39
|
class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
@@ -65,7 +65,7 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
65
65
|
const connectionOptions = {
|
|
66
66
|
host: config.host,
|
|
67
67
|
port: config.port,
|
|
68
|
-
rejectUnauthorized:
|
|
68
|
+
rejectUnauthorized: config.host != 'localhost',
|
|
69
69
|
// Server name for the SNI (Server Name Indication) TLS extension.
|
|
70
70
|
// https://r2.nodejs.org/docs/v6.11.4/api/tls.html#tls_class_tls_tlssocket
|
|
71
71
|
servername: config.host
|
|
@@ -202,8 +202,8 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
202
202
|
}
|
|
203
203
|
if (this.processCallback) {
|
|
204
204
|
this.processCallback(error, result);
|
|
205
|
-
// this.processCallback = undefined
|
|
206
205
|
}
|
|
206
|
+
this.buffer = Buffer.alloc(0);
|
|
207
207
|
}
|
|
208
208
|
/** Disconnect immediately, release connection, no events. */
|
|
209
209
|
close() {
|
|
@@ -2,6 +2,7 @@ import { SQLiteCloudConfig, RowCountCallback } from './types';
|
|
|
2
2
|
import { Statement } from './statement';
|
|
3
3
|
import { ErrorCallback, ResultsCallback, RowCallback, RowsCallback } from './types';
|
|
4
4
|
import EventEmitter from 'eventemitter3';
|
|
5
|
+
import { PubSub } from './pubsub';
|
|
5
6
|
/**
|
|
6
7
|
* Creating a Database object automatically opens a connection to the SQLite database.
|
|
7
8
|
* When the connection is established the Database object emits an open event and calls
|
|
@@ -151,4 +152,13 @@ export declare class Database extends EventEmitter {
|
|
|
151
152
|
* metadata in case of insert, update, delete.
|
|
152
153
|
*/
|
|
153
154
|
sql(sql: TemplateStringsArray | string, ...values: any[]): Promise<any>;
|
|
155
|
+
/**
|
|
156
|
+
* PubSub class provides a Pub/Sub real-time updates and notifications system to
|
|
157
|
+
* allow multiple applications to communicate with each other asynchronously.
|
|
158
|
+
* It allows applications to subscribe to tables and receive notifications whenever
|
|
159
|
+
* data changes in the database table. It also enables sending messages to anyone
|
|
160
|
+
* subscribed to a specific channel.
|
|
161
|
+
* @returns {PubSub} A PubSub object
|
|
162
|
+
*/
|
|
163
|
+
getPubSub(): Promise<PubSub>;
|
|
154
164
|
}
|
package/lib/drivers/database.js
CHANGED
|
@@ -45,6 +45,7 @@ const utilities_1 = require("./utilities");
|
|
|
45
45
|
const statement_1 = require("./statement");
|
|
46
46
|
const eventemitter3_1 = __importDefault(require("eventemitter3"));
|
|
47
47
|
const utilities_2 = require("./utilities");
|
|
48
|
+
const pubsub_1 = require("./pubsub");
|
|
48
49
|
// Uses eventemitter3 instead of node events for browser compatibility
|
|
49
50
|
// https://github.com/primus/eventemitter3
|
|
50
51
|
/**
|
|
@@ -443,5 +444,27 @@ class Database extends eventemitter3_1.default {
|
|
|
443
444
|
});
|
|
444
445
|
});
|
|
445
446
|
}
|
|
447
|
+
/**
|
|
448
|
+
* PubSub class provides a Pub/Sub real-time updates and notifications system to
|
|
449
|
+
* allow multiple applications to communicate with each other asynchronously.
|
|
450
|
+
* It allows applications to subscribe to tables and receive notifications whenever
|
|
451
|
+
* data changes in the database table. It also enables sending messages to anyone
|
|
452
|
+
* subscribed to a specific channel.
|
|
453
|
+
* @returns {PubSub} A PubSub object
|
|
454
|
+
*/
|
|
455
|
+
getPubSub() {
|
|
456
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
457
|
+
return new Promise((resolve, reject) => {
|
|
458
|
+
this.getConnection((error, connection) => {
|
|
459
|
+
if (error || !connection) {
|
|
460
|
+
reject(error);
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
resolve(new pubsub_1.PubSub(connection));
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
}
|
|
446
469
|
}
|
|
447
470
|
exports.Database = Database;
|
|
@@ -14,6 +14,7 @@ export declare const CMD_BLOB = "$";
|
|
|
14
14
|
export declare const CMD_COMPRESSED = "%";
|
|
15
15
|
export declare const CMD_COMMAND = "^";
|
|
16
16
|
export declare const CMD_ARRAY = "=";
|
|
17
|
+
export declare const CMD_PUBSUB = "|";
|
|
17
18
|
export declare const ROWSET_CHUNKS_END = "/6 0 0 0 ";
|
|
18
19
|
/** Analyze first character to check if corresponding data type has LEN */
|
|
19
20
|
export declare function hasCommandLength(firstCharacter: string): boolean;
|
package/lib/drivers/protocol.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// protocol.ts - low level protocol handling for SQLiteCloud transport
|
|
4
4
|
//
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.formatCommand = exports.popData = exports.parseRowsetChunks = exports.bufferEndsWith = exports.bufferStartsWith = exports.parseRowsetHeader = exports.parseArray = exports.parseError = exports.decompressBuffer = exports.parseCommandLength = exports.hasCommandLength = exports.ROWSET_CHUNKS_END = exports.CMD_ARRAY = exports.CMD_COMMAND = exports.CMD_COMPRESSED = exports.CMD_BLOB = exports.CMD_NULL = exports.CMD_JSON = exports.CMD_ROWSET_CHUNK = exports.CMD_ROWSET = exports.CMD_FLOAT = exports.CMD_INT = exports.CMD_ERROR = exports.CMD_ZEROSTRING = exports.CMD_STRING = void 0;
|
|
6
|
+
exports.formatCommand = exports.popData = exports.parseRowsetChunks = exports.bufferEndsWith = exports.bufferStartsWith = exports.parseRowsetHeader = exports.parseArray = exports.parseError = exports.decompressBuffer = exports.parseCommandLength = exports.hasCommandLength = exports.ROWSET_CHUNKS_END = exports.CMD_PUBSUB = exports.CMD_ARRAY = exports.CMD_COMMAND = exports.CMD_COMPRESSED = exports.CMD_BLOB = exports.CMD_NULL = exports.CMD_JSON = exports.CMD_ROWSET_CHUNK = exports.CMD_ROWSET = exports.CMD_FLOAT = exports.CMD_INT = exports.CMD_ERROR = exports.CMD_ZEROSTRING = exports.CMD_STRING = void 0;
|
|
7
7
|
const types_1 = require("./types");
|
|
8
8
|
const rowset_1 = require("./rowset");
|
|
9
9
|
const lz4 = require('lz4js');
|
|
@@ -24,7 +24,7 @@ exports.CMD_COMPRESSED = '%';
|
|
|
24
24
|
exports.CMD_COMMAND = '^';
|
|
25
25
|
exports.CMD_ARRAY = '=';
|
|
26
26
|
// const CMD_RAWJSON = '{'
|
|
27
|
-
|
|
27
|
+
exports.CMD_PUBSUB = '|';
|
|
28
28
|
// const CMD_RECONNECT = '@'
|
|
29
29
|
// To mark the end of the Rowset, the special string /LEN 0 0 0 is sent (LEN is always 6 in this case)
|
|
30
30
|
// https://github.com/sqlitecloud/sdk/blob/master/PROTOCOL.md#scsp-rowset-chunk
|
|
@@ -268,6 +268,8 @@ function popData(buffer) {
|
|
|
268
268
|
return popResults(buffer.subarray(spaceIndex + 1, commandEnd - 1).toString('utf8'));
|
|
269
269
|
case exports.CMD_COMMAND:
|
|
270
270
|
return popResults(buffer.subarray(spaceIndex + 1, commandEnd).toString('utf8'));
|
|
271
|
+
case exports.CMD_PUBSUB:
|
|
272
|
+
return popResults(buffer.subarray(spaceIndex + 1, commandEnd).toString('utf8'));
|
|
271
273
|
case exports.CMD_JSON:
|
|
272
274
|
return popResults(JSON.parse(buffer.subarray(spaceIndex + 1, commandEnd).toString('utf8')));
|
|
273
275
|
case exports.CMD_BLOB:
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { SQLiteCloudConnection } from './connection';
|
|
2
|
+
import { PubSubCallback } from './types';
|
|
3
|
+
export declare enum PUBSUB_ENTITY_TYPE {
|
|
4
|
+
TABLE = "TABLE",
|
|
5
|
+
CHANNEL = "CHANNEL"
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Pub/Sub class to receive changes on database tables or to send messages to channels.
|
|
9
|
+
*/
|
|
10
|
+
export declare class PubSub {
|
|
11
|
+
constructor(connection: SQLiteCloudConnection);
|
|
12
|
+
private connection;
|
|
13
|
+
private connectionPubSub;
|
|
14
|
+
/**
|
|
15
|
+
* Listen for a table or channel and start to receive messages to the provided callback.
|
|
16
|
+
* @param entityType One of TABLE or CHANNEL'
|
|
17
|
+
* @param entityName Name of the table or the channel
|
|
18
|
+
* @param callback Callback to be called when a message is received
|
|
19
|
+
* @param data Extra data to be passed to the callback
|
|
20
|
+
*/
|
|
21
|
+
listen(entityType: PUBSUB_ENTITY_TYPE, entityName: string, callback: PubSubCallback, data?: any): Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Stop receive messages from a table or channel.
|
|
24
|
+
* @param entityType One of TABLE or CHANNEL
|
|
25
|
+
* @param entityName Name of the table or the channel
|
|
26
|
+
*/
|
|
27
|
+
unlisten(entityType: string, entityName: string): Promise<any>;
|
|
28
|
+
/**
|
|
29
|
+
* Create a channel to send messages to.
|
|
30
|
+
* @param name Channel name
|
|
31
|
+
* @param failIfExists Raise an error if the channel already exists
|
|
32
|
+
*/
|
|
33
|
+
createChannel(name: string, failIfExists?: boolean): Promise<any>;
|
|
34
|
+
/**
|
|
35
|
+
* Send a message to the channel.
|
|
36
|
+
*/
|
|
37
|
+
notifyChannel(channelName: string, message: string): Promise<any>;
|
|
38
|
+
/**
|
|
39
|
+
* Ask the server to close the connection to the database and
|
|
40
|
+
* to keep only open the Pub/Sub connection.
|
|
41
|
+
* Only interaction with Pub/Sub commands will be allowed.
|
|
42
|
+
*/
|
|
43
|
+
setPubSubOnly(): Promise<any>;
|
|
44
|
+
/** True if Pub/Sub connection is open. */
|
|
45
|
+
connected(): boolean;
|
|
46
|
+
/** Close Pub/Sub connection. */
|
|
47
|
+
close(): void;
|
|
48
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.PubSub = exports.PUBSUB_ENTITY_TYPE = void 0;
|
|
16
|
+
const connection_tls_1 = __importDefault(require("./connection-tls"));
|
|
17
|
+
var PUBSUB_ENTITY_TYPE;
|
|
18
|
+
(function (PUBSUB_ENTITY_TYPE) {
|
|
19
|
+
PUBSUB_ENTITY_TYPE["TABLE"] = "TABLE";
|
|
20
|
+
PUBSUB_ENTITY_TYPE["CHANNEL"] = "CHANNEL";
|
|
21
|
+
})(PUBSUB_ENTITY_TYPE = exports.PUBSUB_ENTITY_TYPE || (exports.PUBSUB_ENTITY_TYPE = {}));
|
|
22
|
+
/**
|
|
23
|
+
* Pub/Sub class to receive changes on database tables or to send messages to channels.
|
|
24
|
+
*/
|
|
25
|
+
class PubSub {
|
|
26
|
+
constructor(connection) {
|
|
27
|
+
this.connection = connection;
|
|
28
|
+
this.connectionPubSub = new connection_tls_1.default(connection.getConfig());
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Listen for a table or channel and start to receive messages to the provided callback.
|
|
32
|
+
* @param entityType One of TABLE or CHANNEL'
|
|
33
|
+
* @param entityName Name of the table or the channel
|
|
34
|
+
* @param callback Callback to be called when a message is received
|
|
35
|
+
* @param data Extra data to be passed to the callback
|
|
36
|
+
*/
|
|
37
|
+
listen(entityType, entityName, callback, data) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const entity = entityType === 'TABLE' ? 'TABLE ' : '';
|
|
40
|
+
const authCommand = yield this.connection.sql(`LISTEN ${entity}${entityName};`);
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
this.connectionPubSub.sendCommands(authCommand, (error, results) => {
|
|
43
|
+
if (error) {
|
|
44
|
+
callback.call(this, error, null, data);
|
|
45
|
+
reject(error);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// skip results from pubSub auth command
|
|
49
|
+
if (results !== 'OK') {
|
|
50
|
+
callback.call(this, null, results, data);
|
|
51
|
+
}
|
|
52
|
+
resolve(results);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Stop receive messages from a table or channel.
|
|
60
|
+
* @param entityType One of TABLE or CHANNEL
|
|
61
|
+
* @param entityName Name of the table or the channel
|
|
62
|
+
*/
|
|
63
|
+
unlisten(entityType, entityName) {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
const subject = entityType === 'TABLE' ? 'TABLE ' : '';
|
|
66
|
+
return this.connection.sql(`UNLISTEN ${subject}?;`, entityName);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create a channel to send messages to.
|
|
71
|
+
* @param name Channel name
|
|
72
|
+
* @param failIfExists Raise an error if the channel already exists
|
|
73
|
+
*/
|
|
74
|
+
createChannel(name, failIfExists = true) {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
let notExistsCommand = '';
|
|
77
|
+
if (!failIfExists) {
|
|
78
|
+
notExistsCommand = 'IF NOT EXISTS;';
|
|
79
|
+
}
|
|
80
|
+
return this.connection.sql(`CREATE CHANNEL ? ${notExistsCommand}`, name);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Send a message to the channel.
|
|
85
|
+
*/
|
|
86
|
+
notifyChannel(channelName, message) {
|
|
87
|
+
return this.connection.sql `NOTIFY ${channelName} ${message};`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Ask the server to close the connection to the database and
|
|
91
|
+
* to keep only open the Pub/Sub connection.
|
|
92
|
+
* Only interaction with Pub/Sub commands will be allowed.
|
|
93
|
+
*/
|
|
94
|
+
setPubSubOnly() {
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
this.connection.sendCommands('PUBSUB ONLY;', (error, results) => {
|
|
97
|
+
if (error) {
|
|
98
|
+
reject(error);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.connection.close();
|
|
102
|
+
resolve(results);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/** True if Pub/Sub connection is open. */
|
|
108
|
+
connected() {
|
|
109
|
+
return this.connectionPubSub.connected;
|
|
110
|
+
}
|
|
111
|
+
/** Close Pub/Sub connection. */
|
|
112
|
+
close() {
|
|
113
|
+
this.connectionPubSub.close();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.PubSub = PubSub;
|
package/lib/drivers/types.d.ts
CHANGED
|
@@ -108,6 +108,7 @@ export type ResultsCallback<T = any> = (error: Error | null, results?: T) => voi
|
|
|
108
108
|
export type RowsCallback<T = Record<string, any>> = (error: Error | null, rows?: T[]) => void;
|
|
109
109
|
export type RowCallback<T = Record<string, any>> = (error: Error | null, row?: T) => void;
|
|
110
110
|
export type RowCountCallback = (error: Error | null, rowCount?: number) => void;
|
|
111
|
+
export type PubSubCallback<T = any> = (error: Error | null, results?: T, extraData?: T) => void;
|
|
111
112
|
/**
|
|
112
113
|
* Certain responses include arrays with various types of metadata.
|
|
113
114
|
* The first entry is always an array type from this list. This enum
|
package/lib/drivers/utilities.js
CHANGED
|
@@ -34,19 +34,15 @@ function anonimizeError(error) {
|
|
|
34
34
|
exports.anonimizeError = anonimizeError;
|
|
35
35
|
/** Initialization commands sent to database when connection is established */
|
|
36
36
|
function getInitializationCommands(config) {
|
|
37
|
+
// we check the credentials using non linearizable so we're quicker
|
|
38
|
+
// then we bring back linearizability unless specified otherwise
|
|
39
|
+
let commands = 'SET CLIENT KEY NONLINEARIZABLE TO 1; ';
|
|
37
40
|
// first user authentication, then all other commands
|
|
38
|
-
let commands = '';
|
|
39
41
|
if (config.apikey) {
|
|
40
|
-
commands
|
|
42
|
+
commands += `AUTH APIKEY ${config.apikey}; `;
|
|
41
43
|
}
|
|
42
44
|
else {
|
|
43
|
-
commands
|
|
44
|
-
}
|
|
45
|
-
if (config.database) {
|
|
46
|
-
if (config.create && !config.memory) {
|
|
47
|
-
commands += `CREATE DATABASE ${config.database} IF NOT EXISTS; `;
|
|
48
|
-
}
|
|
49
|
-
commands += `USE DATABASE ${config.database}; `;
|
|
45
|
+
commands += `AUTH USER ${config.username || ''} ${config.password_hashed ? 'HASH' : 'PASSWORD'} ${config.password || ''}; `;
|
|
50
46
|
}
|
|
51
47
|
if (config.compression) {
|
|
52
48
|
commands += 'SET CLIENT KEY COMPRESSION TO 1; ';
|
|
@@ -54,9 +50,6 @@ function getInitializationCommands(config) {
|
|
|
54
50
|
if (config.zerotext) {
|
|
55
51
|
commands += 'SET CLIENT KEY ZEROTEXT TO 1; ';
|
|
56
52
|
}
|
|
57
|
-
if (config.non_linearizable) {
|
|
58
|
-
commands += 'SET CLIENT KEY NONLINEARIZABLE TO 1; ';
|
|
59
|
-
}
|
|
60
53
|
if (config.noblob) {
|
|
61
54
|
commands += 'SET CLIENT KEY NOBLOB TO 1; ';
|
|
62
55
|
}
|
|
@@ -69,6 +62,17 @@ function getInitializationCommands(config) {
|
|
|
69
62
|
if (config.maxrowset) {
|
|
70
63
|
commands += `SET CLIENT KEY MAXROWSET TO ${config.maxrowset}; `;
|
|
71
64
|
}
|
|
65
|
+
// we ALWAYS set non linearizable to 1 when we start so we can be quicker on login
|
|
66
|
+
// but then we need to put it back to its default value if "linearizable" unless set
|
|
67
|
+
if (!config.non_linearizable) {
|
|
68
|
+
commands += 'SET CLIENT KEY NONLINEARIZABLE TO 0; ';
|
|
69
|
+
}
|
|
70
|
+
if (config.database) {
|
|
71
|
+
if (config.create && !config.memory) {
|
|
72
|
+
commands += `CREATE DATABASE ${config.database} IF NOT EXISTS; `;
|
|
73
|
+
}
|
|
74
|
+
commands += `USE DATABASE ${config.database}; `;
|
|
75
|
+
}
|
|
72
76
|
return commands;
|
|
73
77
|
}
|
|
74
78
|
exports.getInitializationCommands = getInitializationCommands;
|