@sqlitecloud/drivers 1.0.417 → 1.0.438
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 +2 -2
- package/lib/drivers/connection-tls.d.ts +1 -1
- package/lib/drivers/connection-tls.js +10 -2
- package/lib/drivers/connection-ws.d.ts +1 -1
- package/lib/drivers/connection-ws.js +19 -8
- package/lib/drivers/database.d.ts +12 -9
- package/lib/drivers/database.js +124 -146
- package/lib/drivers/pubsub.js +2 -2
- package/lib/drivers/utilities.js +3 -1
- package/lib/sqlitecloud.drivers.dev.js +5 -5
- package/lib/sqlitecloud.drivers.js +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ let database = new Database('sqlitecloud://user:password@xxx.sqlite.cloud:8860/c
|
|
|
54
54
|
|
|
55
55
|
let name = 'Breaking The Rules'
|
|
56
56
|
|
|
57
|
-
let results = await database.sql
|
|
57
|
+
let results = await database.sql('SELECT * FROM tracks WHERE name = ?', name)
|
|
58
58
|
// => returns [{ AlbumId: 1, Name: 'Breaking The Rules', Composer: 'Angus Young... }]
|
|
59
59
|
```
|
|
60
60
|
|
|
@@ -82,7 +82,7 @@ await pubSub.listen(PUBSUB_ENTITY_TYPE.TABLE, 'albums', (error, results, data) =
|
|
|
82
82
|
}
|
|
83
83
|
})
|
|
84
84
|
|
|
85
|
-
await database.sql
|
|
85
|
+
await database.sql("INSERT INTO albums (Title, ArtistId) values ('Brand new song', 1)")
|
|
86
86
|
|
|
87
87
|
// Stop listening changes on the table
|
|
88
88
|
await pubSub.unlisten(PUBSUB_ENTITY_TYPE.TABLE, 'albums')
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* connection-tls.ts - connection via tls socket and sqlitecloud protocol
|
|
3
3
|
*/
|
|
4
|
-
import { type SQLiteCloudConfig, type ErrorCallback, type ResultsCallback, SQLiteCloudCommand } from './types';
|
|
5
4
|
import { SQLiteCloudConnection } from './connection';
|
|
5
|
+
import { type ErrorCallback, type ResultsCallback, SQLiteCloudCommand, type SQLiteCloudConfig } from './types';
|
|
6
6
|
/**
|
|
7
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.
|
|
@@ -37,10 +37,10 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.SQLiteCloudTlsConnection = void 0;
|
|
40
|
-
const types_1 = require("./types");
|
|
41
40
|
const connection_1 = require("./connection");
|
|
42
|
-
const utilities_1 = require("./utilities");
|
|
43
41
|
const protocol_1 = require("./protocol");
|
|
42
|
+
const types_1 = require("./types");
|
|
43
|
+
const utilities_1 = require("./utilities");
|
|
44
44
|
// explicitly importing buffer library to allow cross-platform support by replacing it
|
|
45
45
|
const buffer_1 = require("buffer");
|
|
46
46
|
const tls = __importStar(require("tls"));
|
|
@@ -101,6 +101,10 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
101
101
|
callback === null || callback === void 0 ? void 0 : callback.call(this, error);
|
|
102
102
|
});
|
|
103
103
|
});
|
|
104
|
+
this.socket.setKeepAlive(true);
|
|
105
|
+
// disable Nagle algorithm because we want our writes to be sent ASAP
|
|
106
|
+
// https://brooker.co.za/blog/2024/05/09/nagle.html
|
|
107
|
+
this.socket.setNoDelay(true);
|
|
104
108
|
this.socket.on('data', data => {
|
|
105
109
|
this.processCommandsData(data);
|
|
106
110
|
});
|
|
@@ -117,6 +121,10 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
117
121
|
this.close();
|
|
118
122
|
this.processCommandsFinish(new types_1.SQLiteCloudError('Connection closed', { errorCode: 'ERR_CONNECTION_CLOSED' }));
|
|
119
123
|
});
|
|
124
|
+
this.socket.on('timeout', () => {
|
|
125
|
+
this.close();
|
|
126
|
+
this.processCommandsFinish(new types_1.SQLiteCloudError('Connection ened due to timeout', { errorCode: 'ERR_CONNECTION_TIMEOUT' }));
|
|
127
|
+
});
|
|
120
128
|
return this;
|
|
121
129
|
}
|
|
122
130
|
/** Will send a command immediately (no queueing), return the rowset/result or throw an error */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* transport-ws.ts - handles low level communication with sqlitecloud server via socket.io websocket
|
|
3
3
|
*/
|
|
4
|
-
import { SQLiteCloudConfig, ErrorCallback, ResultsCallback, SQLiteCloudCommand } from './types';
|
|
5
4
|
import { SQLiteCloudConnection } from './connection';
|
|
5
|
+
import { ErrorCallback, ResultsCallback, SQLiteCloudCommand, SQLiteCloudConfig } from './types';
|
|
6
6
|
/**
|
|
7
7
|
* Implementation of TransportConnection that connects to the database indirectly
|
|
8
8
|
* via SQLite Cloud Gateway, a socket.io based deamon that responds to sql query
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.SQLiteCloudWebsocketConnection = void 0;
|
|
7
|
-
const types_1 = require("./types");
|
|
8
|
-
const rowset_1 = require("./rowset");
|
|
9
|
-
const connection_1 = require("./connection");
|
|
10
7
|
const socket_io_client_1 = require("socket.io-client");
|
|
8
|
+
const connection_1 = require("./connection");
|
|
9
|
+
const rowset_1 = require("./rowset");
|
|
10
|
+
const types_1 = require("./types");
|
|
11
11
|
/**
|
|
12
12
|
* Implementation of TransportConnection that connects to the database indirectly
|
|
13
13
|
* via SQLite Cloud Gateway, a socket.io based deamon that responds to sql query
|
|
@@ -17,7 +17,8 @@ const socket_io_client_1 = require("socket.io-client");
|
|
|
17
17
|
class SQLiteCloudWebsocketConnection extends connection_1.SQLiteCloudConnection {
|
|
18
18
|
/** True if connection is open */
|
|
19
19
|
get connected() {
|
|
20
|
-
|
|
20
|
+
var _a;
|
|
21
|
+
return !!(this.socket && ((_a = this.socket) === null || _a === void 0 ? void 0 : _a.connected));
|
|
21
22
|
}
|
|
22
23
|
/* Opens a connection with the server and sends the initialization commands. Will throw in case of errors. */
|
|
23
24
|
connectTransport(config, callback) {
|
|
@@ -30,8 +31,18 @@ class SQLiteCloudWebsocketConnection extends connection_1.SQLiteCloudConnection
|
|
|
30
31
|
const connectionstring = this.config.connectionstring;
|
|
31
32
|
const gatewayUrl = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.gatewayurl) || `${this.config.host === 'localhost' ? 'ws' : 'wss'}://${this.config.host}:4000`;
|
|
32
33
|
this.socket = (0, socket_io_client_1.io)(gatewayUrl, { auth: { token: connectionstring } });
|
|
34
|
+
this.socket.on('connect', () => {
|
|
35
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
36
|
+
});
|
|
37
|
+
this.socket.on('disconnect', (reason) => {
|
|
38
|
+
this.close();
|
|
39
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Disconnected', { errorCode: 'ERR_CONNECTION_ENDED', cause: reason }));
|
|
40
|
+
});
|
|
41
|
+
this.socket.on('error', (error) => {
|
|
42
|
+
this.close();
|
|
43
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Connection error', { errorCode: 'ERR_CONNECTION_ERROR', cause: error }));
|
|
44
|
+
});
|
|
33
45
|
}
|
|
34
|
-
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
35
46
|
}
|
|
36
47
|
catch (error) {
|
|
37
48
|
callback === null || callback === void 0 ? void 0 : callback.call(this, error);
|
|
@@ -71,14 +82,14 @@ class SQLiteCloudWebsocketConnection extends connection_1.SQLiteCloudConnection
|
|
|
71
82
|
}
|
|
72
83
|
/** Disconnect socket.io from server */
|
|
73
84
|
close() {
|
|
74
|
-
var _a;
|
|
85
|
+
var _a, _b;
|
|
75
86
|
console.assert(this.socket !== null, 'SQLiteCloudWebsocketConnection.close - connection already closed');
|
|
76
87
|
if (this.socket) {
|
|
77
|
-
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.
|
|
88
|
+
(_a = this.socket) === null || _a === void 0 ? void 0 : _a.removeAllListeners();
|
|
89
|
+
(_b = this.socket) === null || _b === void 0 ? void 0 : _b.close();
|
|
78
90
|
this.socket = undefined;
|
|
79
91
|
}
|
|
80
92
|
this.operations.clear();
|
|
81
|
-
this.socket = undefined;
|
|
82
93
|
return this;
|
|
83
94
|
}
|
|
84
95
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import EventEmitter from 'eventemitter3';
|
|
2
2
|
import { PubSub } from './pubsub';
|
|
3
3
|
import { Statement } from './statement';
|
|
4
|
-
import { ErrorCallback, ResultsCallback, RowCallback, RowCountCallback, RowsCallback, SQLiteCloudCommand, SQLiteCloudConfig } from './types';
|
|
4
|
+
import { ErrorCallback as ConnectionCallback, ResultsCallback, RowCallback, RowCountCallback, RowsCallback, SQLiteCloudCommand, SQLiteCloudConfig } from './types';
|
|
5
5
|
/**
|
|
6
6
|
* Creating a Database object automatically opens a connection to the SQLite database.
|
|
7
7
|
* When the connection is established the Database object emits an open event and calls
|
|
@@ -10,14 +10,17 @@ import { ErrorCallback, ResultsCallback, RowCallback, RowCountCallback, RowsCall
|
|
|
10
10
|
*/
|
|
11
11
|
export declare class Database extends EventEmitter {
|
|
12
12
|
/** Create and initialize a database from a full configuration object, or connection string */
|
|
13
|
-
constructor(config: SQLiteCloudConfig | string, callback?:
|
|
14
|
-
constructor(config: SQLiteCloudConfig | string, mode?: number, callback?:
|
|
13
|
+
constructor(config: SQLiteCloudConfig | string, callback?: ConnectionCallback);
|
|
14
|
+
constructor(config: SQLiteCloudConfig | string, mode?: number, callback?: ConnectionCallback);
|
|
15
15
|
/** Configuration used to open database connections */
|
|
16
16
|
private config;
|
|
17
|
-
/** Database
|
|
18
|
-
private
|
|
17
|
+
/** Database connection */
|
|
18
|
+
private connection;
|
|
19
|
+
/** Used to syncronize opening of connection and commands */
|
|
20
|
+
private operations;
|
|
19
21
|
/** Returns first available connection from connection pool */
|
|
20
|
-
private
|
|
22
|
+
private createConnection;
|
|
23
|
+
private enqueueCommand;
|
|
21
24
|
/** Handles an error by closing the connection, calling the callback and/or emitting an error event */
|
|
22
25
|
private handleError;
|
|
23
26
|
/**
|
|
@@ -114,7 +117,7 @@ export declare class Database extends EventEmitter {
|
|
|
114
117
|
* object. When no callback is provided and an error occurs, an error event
|
|
115
118
|
* will be emitted on the database object.
|
|
116
119
|
*/
|
|
117
|
-
exec(sql: string, callback?:
|
|
120
|
+
exec(sql: string, callback?: ConnectionCallback): this;
|
|
118
121
|
/**
|
|
119
122
|
* If the optional callback is provided, this function will be called when the
|
|
120
123
|
* database was closed successfully or when an error occurred. The first argument
|
|
@@ -123,7 +126,7 @@ export declare class Database extends EventEmitter {
|
|
|
123
126
|
* will be emitted on the database object. If closing succeeded, a close event with no
|
|
124
127
|
* parameters is emitted, regardless of whether a callback was provided or not.
|
|
125
128
|
*/
|
|
126
|
-
close(callback?:
|
|
129
|
+
close(callback?: ConnectionCallback): void;
|
|
127
130
|
/**
|
|
128
131
|
* Loads a compiled SQLite extension into the database connection object.
|
|
129
132
|
* @param path Filename of the extension to load.
|
|
@@ -133,7 +136,7 @@ export declare class Database extends EventEmitter {
|
|
|
133
136
|
* and an error occurred, an error event with the error object as the only parameter
|
|
134
137
|
* will be emitted on the database object.
|
|
135
138
|
*/
|
|
136
|
-
loadExtension(_path: string, callback?:
|
|
139
|
+
loadExtension(_path: string, callback?: ConnectionCallback): this;
|
|
137
140
|
/**
|
|
138
141
|
* Allows the user to interrupt long-running queries. Wrapper around
|
|
139
142
|
* sqlite3_interrupt and causes other data-fetching functions to be
|
package/lib/drivers/database.js
CHANGED
|
@@ -55,6 +55,7 @@ exports.Database = void 0;
|
|
|
55
55
|
// https://github.com/TryGhost/node-sqlite3/blob/master/lib/sqlite3.d.ts
|
|
56
56
|
const eventemitter3_1 = __importDefault(require("eventemitter3"));
|
|
57
57
|
const pubsub_1 = require("./pubsub");
|
|
58
|
+
const queue_1 = require("./queue");
|
|
58
59
|
const rowset_1 = require("./rowset");
|
|
59
60
|
const statement_1 = require("./statement");
|
|
60
61
|
const types_1 = require("./types");
|
|
@@ -70,9 +71,10 @@ const utilities_1 = require("./utilities");
|
|
|
70
71
|
class Database extends eventemitter3_1.default {
|
|
71
72
|
constructor(config, mode, callback) {
|
|
72
73
|
super();
|
|
73
|
-
/**
|
|
74
|
-
this.
|
|
74
|
+
/** Used to syncronize opening of connection and commands */
|
|
75
|
+
this.operations = new queue_1.OperationsQueue();
|
|
75
76
|
this.config = typeof config === 'string' ? { connectionstring: config } : config;
|
|
77
|
+
this.connection = null;
|
|
76
78
|
// mode is optional and so is callback
|
|
77
79
|
// https://github.com/TryGhost/node-sqlite3/wiki/API#new-sqlite3databasefilename--mode--callback
|
|
78
80
|
if (typeof mode === 'function') {
|
|
@@ -80,8 +82,8 @@ class Database extends eventemitter3_1.default {
|
|
|
80
82
|
mode = undefined;
|
|
81
83
|
}
|
|
82
84
|
// mode is ignored for now
|
|
83
|
-
// opens
|
|
84
|
-
this.
|
|
85
|
+
// opens the connection to the database automatically
|
|
86
|
+
this.createConnection(error => {
|
|
85
87
|
if (callback) {
|
|
86
88
|
callback.call(this, error);
|
|
87
89
|
}
|
|
@@ -91,60 +93,73 @@ class Database extends eventemitter3_1.default {
|
|
|
91
93
|
// private methods
|
|
92
94
|
//
|
|
93
95
|
/** Returns first available connection from connection pool */
|
|
94
|
-
|
|
95
|
-
var _a, _b
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
// connect using websocket if tls is not supported or if explicitly requested
|
|
102
|
-
const useWebsocket = utilities_1.isBrowser || ((_b = this.config) === null || _b === void 0 ? void 0 : _b.usewebsocket) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.gatewayurl);
|
|
103
|
-
if (useWebsocket) {
|
|
104
|
-
// socket.io transport works in both node.js and browser environments and connects via SQLite Cloud Gateway
|
|
96
|
+
createConnection(callback) {
|
|
97
|
+
var _a, _b;
|
|
98
|
+
// connect using websocket if tls is not supported or if explicitly requested
|
|
99
|
+
const useWebsocket = utilities_1.isBrowser || ((_a = this.config) === null || _a === void 0 ? void 0 : _a.usewebsocket) || ((_b = this.config) === null || _b === void 0 ? void 0 : _b.gatewayurl);
|
|
100
|
+
if (useWebsocket) {
|
|
101
|
+
// socket.io transport works in both node.js and browser environments and connects via SQLite Cloud Gateway
|
|
102
|
+
this.operations.enqueue(done => {
|
|
105
103
|
Promise.resolve().then(() => __importStar(require('./connection-ws'))).then(module => {
|
|
106
|
-
this.
|
|
104
|
+
this.connection = new module.default(this.config, (error) => {
|
|
107
105
|
if (error) {
|
|
108
|
-
this.handleError(
|
|
106
|
+
this.handleError(error, callback);
|
|
109
107
|
}
|
|
110
108
|
else {
|
|
111
|
-
|
|
112
|
-
callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);
|
|
109
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
113
110
|
this.emitEvent('open');
|
|
114
111
|
}
|
|
115
|
-
|
|
112
|
+
done(error);
|
|
113
|
+
});
|
|
116
114
|
})
|
|
117
115
|
.catch(error => {
|
|
118
|
-
this.handleError(
|
|
116
|
+
this.handleError(error, callback);
|
|
117
|
+
this.close();
|
|
118
|
+
done(error);
|
|
119
119
|
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
this.operations.enqueue(done => {
|
|
123
124
|
Promise.resolve().then(() => __importStar(require('./connection-tls'))).then(module => {
|
|
124
|
-
this.
|
|
125
|
+
this.connection = new module.default(this.config, (error) => {
|
|
125
126
|
if (error) {
|
|
126
|
-
this.handleError(
|
|
127
|
+
this.handleError(error, callback);
|
|
127
128
|
}
|
|
128
129
|
else {
|
|
129
|
-
|
|
130
|
-
callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);
|
|
130
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
131
131
|
this.emitEvent('open');
|
|
132
132
|
}
|
|
133
|
-
|
|
133
|
+
done(error);
|
|
134
|
+
});
|
|
134
135
|
})
|
|
135
136
|
.catch(error => {
|
|
136
|
-
this.handleError(
|
|
137
|
+
this.handleError(error, callback);
|
|
138
|
+
this.close();
|
|
139
|
+
done(error);
|
|
137
140
|
});
|
|
138
|
-
}
|
|
141
|
+
});
|
|
139
142
|
}
|
|
140
143
|
}
|
|
144
|
+
enqueueCommand(command, callback) {
|
|
145
|
+
this.operations.enqueue(done => {
|
|
146
|
+
let error = null;
|
|
147
|
+
// we don't wont to silently open a new connection after a disconnession
|
|
148
|
+
if (this.connection && this.connection.connected) {
|
|
149
|
+
this.connection.sendCommands(command, (error, results) => {
|
|
150
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, error, results);
|
|
151
|
+
done(error);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
error = new types_1.SQLiteCloudError('Connection unavailable. Maybe it got disconnected?', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' });
|
|
156
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, error, null);
|
|
157
|
+
done(error);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
141
161
|
/** Handles an error by closing the connection, calling the callback and/or emitting an error event */
|
|
142
|
-
handleError(
|
|
143
|
-
// an errored connection is thrown out
|
|
144
|
-
if (connection) {
|
|
145
|
-
this.connections = this.connections.filter(c => c !== connection);
|
|
146
|
-
connection.close();
|
|
147
|
-
}
|
|
162
|
+
handleError(error, callback) {
|
|
148
163
|
if (callback) {
|
|
149
164
|
callback.call(this, error);
|
|
150
165
|
}
|
|
@@ -198,10 +213,9 @@ class Database extends eventemitter3_1.default {
|
|
|
198
213
|
}
|
|
199
214
|
/** Enable verbose mode */
|
|
200
215
|
verbose() {
|
|
216
|
+
var _a;
|
|
201
217
|
this.config.verbose = true;
|
|
202
|
-
|
|
203
|
-
connection.verbose();
|
|
204
|
-
}
|
|
218
|
+
(_a = this.connection) === null || _a === void 0 ? void 0 : _a.verbose();
|
|
205
219
|
return this;
|
|
206
220
|
}
|
|
207
221
|
/** Set a configuration option for the database */
|
|
@@ -212,21 +226,14 @@ class Database extends eventemitter3_1.default {
|
|
|
212
226
|
run(sql, ...params) {
|
|
213
227
|
const { args, callback } = (0, utilities_1.popCallback)(params);
|
|
214
228
|
const command = { query: sql, parameters: args };
|
|
215
|
-
this.
|
|
216
|
-
if (error
|
|
217
|
-
this.handleError(
|
|
229
|
+
this.enqueueCommand(command, (error, results) => {
|
|
230
|
+
if (error) {
|
|
231
|
+
this.handleError(error, callback);
|
|
218
232
|
}
|
|
219
233
|
else {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
225
|
-
// context may include id of last row inserted, total changes, etc...
|
|
226
|
-
const context = this.processContext(results);
|
|
227
|
-
callback === null || callback === void 0 ? void 0 : callback.call(context || this, null, context ? context : results);
|
|
228
|
-
}
|
|
229
|
-
});
|
|
234
|
+
// context may include id of last row inserted, total changes, etc...
|
|
235
|
+
const context = this.processContext(results);
|
|
236
|
+
callback === null || callback === void 0 ? void 0 : callback.call(context || this, null, context ? context : results);
|
|
230
237
|
}
|
|
231
238
|
});
|
|
232
239
|
return this;
|
|
@@ -234,24 +241,17 @@ class Database extends eventemitter3_1.default {
|
|
|
234
241
|
get(sql, ...params) {
|
|
235
242
|
const { args, callback } = (0, utilities_1.popCallback)(params);
|
|
236
243
|
const command = { query: sql, parameters: args };
|
|
237
|
-
this.
|
|
238
|
-
if (error
|
|
239
|
-
this.handleError(
|
|
244
|
+
this.enqueueCommand(command, (error, results) => {
|
|
245
|
+
if (error) {
|
|
246
|
+
this.handleError(error, callback);
|
|
240
247
|
}
|
|
241
248
|
else {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
callback === null || callback === void 0 ? void 0 : callback.call(this, null, results[0]);
|
|
249
|
-
}
|
|
250
|
-
else {
|
|
251
|
-
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
});
|
|
249
|
+
if (results && results instanceof rowset_1.SQLiteCloudRowset && results.length > 0) {
|
|
250
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, null, results[0]);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
254
|
+
}
|
|
255
255
|
}
|
|
256
256
|
});
|
|
257
257
|
return this;
|
|
@@ -259,24 +259,17 @@ class Database extends eventemitter3_1.default {
|
|
|
259
259
|
all(sql, ...params) {
|
|
260
260
|
const { args, callback } = (0, utilities_1.popCallback)(params);
|
|
261
261
|
const command = { query: sql, parameters: args };
|
|
262
|
-
this.
|
|
263
|
-
if (error
|
|
264
|
-
this.handleError(
|
|
262
|
+
this.enqueueCommand(command, (error, results) => {
|
|
263
|
+
if (error) {
|
|
264
|
+
this.handleError(error, callback);
|
|
265
265
|
}
|
|
266
266
|
else {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
callback === null || callback === void 0 ? void 0 : callback.call(this, null, results);
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
});
|
|
267
|
+
if (results && results instanceof rowset_1.SQLiteCloudRowset) {
|
|
268
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, null, results);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
272
|
+
}
|
|
280
273
|
}
|
|
281
274
|
});
|
|
282
275
|
return this;
|
|
@@ -285,32 +278,25 @@ class Database extends eventemitter3_1.default {
|
|
|
285
278
|
// extract optional parameters and one or two callbacks
|
|
286
279
|
const { args, callback, complete } = (0, utilities_1.popCallback)(params);
|
|
287
280
|
const command = { query: sql, parameters: args };
|
|
288
|
-
this.
|
|
289
|
-
if (error
|
|
290
|
-
this.handleError(
|
|
281
|
+
this.enqueueCommand(command, (error, rowset) => {
|
|
282
|
+
if (error) {
|
|
283
|
+
this.handleError(error, callback);
|
|
291
284
|
}
|
|
292
285
|
else {
|
|
293
|
-
|
|
294
|
-
if (
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
else {
|
|
298
|
-
if (rowset && rowset instanceof rowset_1.SQLiteCloudRowset) {
|
|
299
|
-
if (callback) {
|
|
300
|
-
for (const row of rowset) {
|
|
301
|
-
callback.call(this, null, row);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
if (complete) {
|
|
305
|
-
;
|
|
306
|
-
complete.call(this, null, rowset.numberOfRows);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Invalid rowset'));
|
|
286
|
+
if (rowset && rowset instanceof rowset_1.SQLiteCloudRowset) {
|
|
287
|
+
if (callback) {
|
|
288
|
+
for (const row of rowset) {
|
|
289
|
+
callback.call(this, null, row);
|
|
311
290
|
}
|
|
312
291
|
}
|
|
313
|
-
|
|
292
|
+
if (complete) {
|
|
293
|
+
;
|
|
294
|
+
complete.call(this, null, rowset.numberOfRows);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Invalid rowset'));
|
|
299
|
+
}
|
|
314
300
|
}
|
|
315
301
|
});
|
|
316
302
|
return this;
|
|
@@ -336,20 +322,13 @@ class Database extends eventemitter3_1.default {
|
|
|
336
322
|
* will be emitted on the database object.
|
|
337
323
|
*/
|
|
338
324
|
exec(sql, callback) {
|
|
339
|
-
this.
|
|
340
|
-
if (error
|
|
341
|
-
this.handleError(
|
|
325
|
+
this.enqueueCommand(sql, (error, results) => {
|
|
326
|
+
if (error) {
|
|
327
|
+
this.handleError(error, callback);
|
|
342
328
|
}
|
|
343
329
|
else {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
this.handleError(connection, error, callback);
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
const context = this.processContext(results);
|
|
350
|
-
callback === null || callback === void 0 ? void 0 : callback.call(context ? context : this, null);
|
|
351
|
-
}
|
|
352
|
-
});
|
|
330
|
+
const context = this.processContext(results);
|
|
331
|
+
callback === null || callback === void 0 ? void 0 : callback.call(context ? context : this, null);
|
|
353
332
|
}
|
|
354
333
|
});
|
|
355
334
|
return this;
|
|
@@ -363,14 +342,14 @@ class Database extends eventemitter3_1.default {
|
|
|
363
342
|
* parameters is emitted, regardless of whether a callback was provided or not.
|
|
364
343
|
*/
|
|
365
344
|
close(callback) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
345
|
+
this.operations.enqueue(done => {
|
|
346
|
+
var _a;
|
|
347
|
+
(_a = this.connection) === null || _a === void 0 ? void 0 : _a.close();
|
|
348
|
+
callback === null || callback === void 0 ? void 0 : callback.call(this, null);
|
|
349
|
+
this.emitEvent('close');
|
|
350
|
+
this.operations.clear();
|
|
351
|
+
done(null);
|
|
352
|
+
});
|
|
374
353
|
}
|
|
375
354
|
/**
|
|
376
355
|
* Loads a compiled SQLite extension into the database connection object.
|
|
@@ -436,21 +415,14 @@ class Database extends eventemitter3_1.default {
|
|
|
436
415
|
throw new Error('Invalid sql');
|
|
437
416
|
}
|
|
438
417
|
return new Promise((resolve, reject) => {
|
|
439
|
-
this.
|
|
440
|
-
if (error
|
|
418
|
+
this.enqueueCommand(commands, (error, results) => {
|
|
419
|
+
if (error) {
|
|
441
420
|
reject(error);
|
|
442
421
|
}
|
|
443
422
|
else {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
else {
|
|
449
|
-
// metadata for operations like insert, update, delete?
|
|
450
|
-
const context = this.processContext(results);
|
|
451
|
-
resolve(context ? context : results);
|
|
452
|
-
}
|
|
453
|
-
});
|
|
423
|
+
// metadata for operations like insert, update, delete?
|
|
424
|
+
const context = this.processContext(results);
|
|
425
|
+
resolve(context ? context : results);
|
|
454
426
|
}
|
|
455
427
|
});
|
|
456
428
|
});
|
|
@@ -460,8 +432,7 @@ class Database extends eventemitter3_1.default {
|
|
|
460
432
|
* Returns true if the database connection is open.
|
|
461
433
|
*/
|
|
462
434
|
isConnected() {
|
|
463
|
-
|
|
464
|
-
return ((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0 && this.connections[0].connected;
|
|
435
|
+
return this.connection != null && this.connection.connected;
|
|
465
436
|
}
|
|
466
437
|
/**
|
|
467
438
|
* PubSub class provides a Pub/Sub real-time updates and notifications system to
|
|
@@ -474,12 +445,19 @@ class Database extends eventemitter3_1.default {
|
|
|
474
445
|
getPubSub() {
|
|
475
446
|
return __awaiter(this, void 0, void 0, function* () {
|
|
476
447
|
return new Promise((resolve, reject) => {
|
|
477
|
-
this.
|
|
478
|
-
|
|
479
|
-
|
|
448
|
+
this.operations.enqueue(done => {
|
|
449
|
+
let error = null;
|
|
450
|
+
try {
|
|
451
|
+
if (!this.connection) {
|
|
452
|
+
error = new types_1.SQLiteCloudError('Connection not established', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' });
|
|
453
|
+
reject(error);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
resolve(new pubsub_1.PubSub(this.connection));
|
|
457
|
+
}
|
|
480
458
|
}
|
|
481
|
-
|
|
482
|
-
|
|
459
|
+
finally {
|
|
460
|
+
done(error);
|
|
483
461
|
}
|
|
484
462
|
});
|
|
485
463
|
});
|
package/lib/drivers/pubsub.js
CHANGED
|
@@ -86,14 +86,14 @@ class PubSub {
|
|
|
86
86
|
*/
|
|
87
87
|
removeChannel(name) {
|
|
88
88
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
-
return this.connection.sql(
|
|
89
|
+
return this.connection.sql('REMOVE CHANNEL ?;', name);
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
93
|
* Send a message to the channel.
|
|
94
94
|
*/
|
|
95
95
|
notifyChannel(channelName, message) {
|
|
96
|
-
return this.connection.sql
|
|
96
|
+
return this.connection.sql('NOTIFY ? ?;', channelName, message);
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* Ask the server to close the connection to the database and
|
package/lib/drivers/utilities.js
CHANGED
|
@@ -194,7 +194,9 @@ function parseconnectionstring(connectionstring) {
|
|
|
194
194
|
url.searchParams.forEach((value, key) => {
|
|
195
195
|
options[key.toLowerCase().replace(/-/g, '_')] = value;
|
|
196
196
|
});
|
|
197
|
-
const config = Object.assign({ username: decodeURIComponent(url.username), password: decodeURIComponent(url.password),
|
|
197
|
+
const config = Object.assign(Object.assign({}, options), { username: decodeURIComponent(url.username), password: decodeURIComponent(url.password), password_hashed: options.password_hashed ? parseBoolean(options.password_hashed) : undefined, host: url.hostname,
|
|
198
|
+
// type cast values
|
|
199
|
+
port: url.port ? parseInt(url.port) : undefined, insecure: options.insecure ? parseBoolean(options.insecure) : undefined, timeout: options.timeout ? parseInt(options.timeout) : undefined, zerotext: options.zerotext ? parseBoolean(options.zerotext) : undefined, create: options.create ? parseBoolean(options.create) : undefined, memory: options.memory ? parseBoolean(options.memory) : undefined, compression: options.compression ? parseBoolean(options.compression) : undefined, non_linearizable: options.non_linearizable ? parseBoolean(options.non_linearizable) : undefined, noblob: options.noblob ? parseBoolean(options.noblob) : undefined, maxdata: options.maxdata ? parseInt(options.maxdata) : undefined, maxrows: options.maxrows ? parseInt(options.maxrows) : undefined, maxrowset: options.maxrowset ? parseInt(options.maxrowset) : undefined, usewebsocket: options.usewebsocket ? parseBoolean(options.usewebsocket) : undefined, verbose: options.verbose ? parseBoolean(options.verbose) : undefined });
|
|
198
200
|
// either you use an apikey or username and password
|
|
199
201
|
if (config.apikey) {
|
|
200
202
|
if (config.username || config.password) {
|