stimulsoft-data-adapter 2021.4.1
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/FirebirdAdapter.js +148 -0
- package/MSSQLAdapter.js +249 -0
- package/MySQLAdapter.js +208 -0
- package/PostgreSQLAdapter.js +246 -0
- package/README.md +21 -0
- package/app.js +89 -0
- package/package.json +50 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Stimulsoft.Reports.JS
|
|
3
|
+
Version: 2021.4.1
|
|
4
|
+
Build date: 2021.10.04
|
|
5
|
+
License: https://www.stimulsoft.com/en/licensing/reports
|
|
6
|
+
*/
|
|
7
|
+
exports.process = function (command, onResult) {
|
|
8
|
+
var end = function (result) {
|
|
9
|
+
try {
|
|
10
|
+
if (db) db.detach();
|
|
11
|
+
result.adapterVersion = "2021.4.1";
|
|
12
|
+
onResult(result);
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var onError = function (message) {
|
|
19
|
+
end({ success: false, notice: message });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
var connect = function () {
|
|
24
|
+
Firebird.attach(options, function (error, db1) {
|
|
25
|
+
db = db1;
|
|
26
|
+
if (error) onError(error.message);
|
|
27
|
+
else onConnect();
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
var query = function (queryString) {
|
|
32
|
+
db.query(queryString, undefined, function (error, recordset) {
|
|
33
|
+
if (error) onError(error.message);
|
|
34
|
+
else onQuery(recordset);
|
|
35
|
+
db.detach();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
var onConnect = function () {
|
|
40
|
+
if (command.queryString) query(command.queryString);
|
|
41
|
+
else end({ success: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var onQuery = function (recordset) {
|
|
45
|
+
var columns = [];
|
|
46
|
+
var rows = [];
|
|
47
|
+
var types = [];
|
|
48
|
+
var isColumnsFill = false;
|
|
49
|
+
for (var recordIndex in recordset) {
|
|
50
|
+
var row = [];
|
|
51
|
+
for (var columnName in recordset[recordIndex]) {
|
|
52
|
+
if (!isColumnsFill) columns.push(columnName);
|
|
53
|
+
var columnIndex = columns.indexOf(columnName);
|
|
54
|
+
types[columnIndex] = typeof recordset[recordIndex][columnName];
|
|
55
|
+
if (recordset[recordIndex][columnName] instanceof Uint8Array ||
|
|
56
|
+
recordset[recordIndex][columnName] instanceof Buffer) {
|
|
57
|
+
recordset[recordIndex][columnName] = recordset[recordIndex][columnName].toString();
|
|
58
|
+
types[columnIndex] = "string";
|
|
59
|
+
}
|
|
60
|
+
if (recordset[recordIndex][columnName] != null && typeof recordset[recordIndex][columnName].toISOString === "function") {
|
|
61
|
+
var dateTime = new Date(recordset[recordIndex][columnName].getTime() - (recordset[recordIndex][columnName].getTimezoneOffset() * 60000)).toISOString();
|
|
62
|
+
recordset[recordIndex][columnName] = dateTime.replace("Z", "");
|
|
63
|
+
types[columnIndex] = "datetime";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
row[columnIndex] = recordset[recordIndex][columnName];
|
|
67
|
+
}
|
|
68
|
+
isColumnsFill = true;
|
|
69
|
+
rows.push(row);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
end({ success: true, columns: columns, rows: rows, types: types });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var getConnectionStringInfo = function (connectionString) {
|
|
76
|
+
var info = { host: "localhost", port: "3050" };
|
|
77
|
+
var isCorrect = false;
|
|
78
|
+
for (var propertyIndex in connectionString.split(";")) {
|
|
79
|
+
var property = connectionString.split(";")[propertyIndex];
|
|
80
|
+
if (property) {
|
|
81
|
+
var match = property.split("=");
|
|
82
|
+
if (match && match.length >= 2) {
|
|
83
|
+
match[0] = match[0].trim().toLowerCase();
|
|
84
|
+
match[1] = match[1].trim();
|
|
85
|
+
|
|
86
|
+
switch (match[0]) {
|
|
87
|
+
case "server":
|
|
88
|
+
case "host":
|
|
89
|
+
case "location":
|
|
90
|
+
case "datasource":
|
|
91
|
+
case "data source":
|
|
92
|
+
info["host"] = match[1];
|
|
93
|
+
break;
|
|
94
|
+
|
|
95
|
+
case "port":
|
|
96
|
+
info["port"] = match[1];
|
|
97
|
+
break;
|
|
98
|
+
|
|
99
|
+
case "database":
|
|
100
|
+
info["database"] = match[1];
|
|
101
|
+
isCorrect = true;
|
|
102
|
+
break;
|
|
103
|
+
|
|
104
|
+
case "uid":
|
|
105
|
+
case "user":
|
|
106
|
+
case "user id":
|
|
107
|
+
info["userId"] = match[1];
|
|
108
|
+
break;
|
|
109
|
+
|
|
110
|
+
case "pwd":
|
|
111
|
+
case "password":
|
|
112
|
+
info["password"] = match[1];
|
|
113
|
+
break;
|
|
114
|
+
|
|
115
|
+
case "charset":
|
|
116
|
+
info["charset"] = match[1];
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (!isCorrect) {
|
|
123
|
+
onError("Connection String parse error");
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
return info;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
var Firebird = require('node-firebird');
|
|
130
|
+
command.connectionStringInfo = getConnectionStringInfo(command.connectionString);
|
|
131
|
+
if (command.connectionStringInfo) {
|
|
132
|
+
var options = {
|
|
133
|
+
host: command.connectionStringInfo.host,
|
|
134
|
+
port: command.connectionStringInfo.port,
|
|
135
|
+
database: command.connectionStringInfo.database,
|
|
136
|
+
user: command.connectionStringInfo.userId,
|
|
137
|
+
password: command.connectionStringInfo.password,
|
|
138
|
+
charset: command.connectionStringInfo.charset,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
connect();
|
|
142
|
+
var db;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (e) {
|
|
146
|
+
onError(e.stack);
|
|
147
|
+
}
|
|
148
|
+
}
|
package/MSSQLAdapter.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Stimulsoft.Reports.JS
|
|
3
|
+
Version: 2021.4.1
|
|
4
|
+
Build date: 2021.10.04
|
|
5
|
+
License: https://www.stimulsoft.com/en/licensing/reports
|
|
6
|
+
*/
|
|
7
|
+
exports.process = function (command, onResult) {
|
|
8
|
+
var end = function (result) {
|
|
9
|
+
try {
|
|
10
|
+
if (connection) connection.close();
|
|
11
|
+
result.adapterVersion = "2021.4.1";
|
|
12
|
+
onResult(result);
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var onError = function (message) {
|
|
19
|
+
end({ success: false, notice: message });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
var connect = function () {
|
|
24
|
+
connection = new sql.ConnectionPool(config, function (error) {
|
|
25
|
+
if (error) onError(error.message);
|
|
26
|
+
else onConnect();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var query = function (queryString) {
|
|
31
|
+
var request = connection.request();
|
|
32
|
+
request.query(queryString, function (error, recordset) {
|
|
33
|
+
if (error) onError(error.message);
|
|
34
|
+
else {
|
|
35
|
+
onQuery(recordset);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var onConnect = function () {
|
|
41
|
+
if (command.queryString) query(command.queryString);
|
|
42
|
+
else end({ success: true });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
var onQuery = function (recordset) {
|
|
46
|
+
recordset = recordset.recordset;
|
|
47
|
+
var columns = [];
|
|
48
|
+
var rows = [];
|
|
49
|
+
var types = [];
|
|
50
|
+
if (recordset.length > 0 && Array.isArray(recordset[0])) recordset = recordset[0];
|
|
51
|
+
for (var columnName in recordset.columns) {
|
|
52
|
+
var column = recordset.columns[columnName];
|
|
53
|
+
var columnIndex = columns.length;
|
|
54
|
+
columns.push(column.name);
|
|
55
|
+
|
|
56
|
+
switch (column.type) {
|
|
57
|
+
case sql.UniqueIdentifier:
|
|
58
|
+
case sql.BigInt:
|
|
59
|
+
case sql.timestamp:
|
|
60
|
+
case sql.Int:
|
|
61
|
+
case sql.SmallInt:
|
|
62
|
+
case sql.TinyInt:
|
|
63
|
+
types[columnIndex] = "int"; break;
|
|
64
|
+
|
|
65
|
+
case sql.Decimal:
|
|
66
|
+
case sql.Money:
|
|
67
|
+
case sql.SmallMoney:
|
|
68
|
+
case sql.Float:
|
|
69
|
+
case sql.Real:
|
|
70
|
+
types[columnIndex] = "number"; break;
|
|
71
|
+
|
|
72
|
+
case sql.DateTime:
|
|
73
|
+
case sql.Date:
|
|
74
|
+
case sql.DateTime2:
|
|
75
|
+
case sql.SmallDateTime:
|
|
76
|
+
types[columnIndex] = "datetime"; break;
|
|
77
|
+
|
|
78
|
+
case sql.DateTimeOffset:
|
|
79
|
+
types[columnIndex] = "datetimeZ"; break;
|
|
80
|
+
|
|
81
|
+
case sql.Time:
|
|
82
|
+
types[columnIndex] = "time"; break;
|
|
83
|
+
|
|
84
|
+
case sql.Bit:
|
|
85
|
+
types[columnIndex] = "boolean"; break;
|
|
86
|
+
|
|
87
|
+
case sql.Binary:
|
|
88
|
+
case sql.Image:
|
|
89
|
+
types[columnIndex] = "array"; break;
|
|
90
|
+
|
|
91
|
+
default:
|
|
92
|
+
types[columnIndex] = "string"; break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (recordset.length > 0 && Array.isArray(recordset[0])) recordset = recordset[0];
|
|
97
|
+
for (var recordIndex in recordset) {
|
|
98
|
+
var row = [];
|
|
99
|
+
for (var columnName in recordset[recordIndex]) {
|
|
100
|
+
var columnIndex = columns.indexOf(columnName);
|
|
101
|
+
if (recordset[recordIndex][columnName] instanceof Uint8Array ||
|
|
102
|
+
recordset[recordIndex][columnName] instanceof Buffer) {
|
|
103
|
+
types[columnIndex] = "array";
|
|
104
|
+
recordset[recordIndex][columnName] = Buffer.from(recordset[recordIndex][columnName]).toString('base64');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (recordset[recordIndex][columnName] != null && typeof recordset[recordIndex][columnName].toISOString === "function") {
|
|
108
|
+
var dateTime = recordset[recordIndex][columnName].toISOString();
|
|
109
|
+
if (types[columnIndex] == "time") {
|
|
110
|
+
recordset[recordIndex][columnName] = dateTime.substr(dateTime.indexOf("T") + 1).replace("Z", "");
|
|
111
|
+
}
|
|
112
|
+
else if (types[columnIndex] == "datetimeZ") {
|
|
113
|
+
var offset = "+00:00";
|
|
114
|
+
recordset[recordIndex][columnName] = dateTime.replace("Z", "") + offset;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
recordset[recordIndex][columnName] = dateTime.replace("Z", "");
|
|
118
|
+
types[columnIndex] = "datetime";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (columnName == "" && Array.isArray(recordset[recordIndex][columnName])) {
|
|
123
|
+
for (var i = 0; i < recordset[recordIndex][columnName].length; i++) {
|
|
124
|
+
if (columns.length <= columnIndex + i && columns[columnIndex + i] != ""){
|
|
125
|
+
columns.splice(columnIndex + i - 1, 0, columns[columnIndex]);
|
|
126
|
+
types.splice(columnIndex + i - 1, 0, types[columnIndex]);
|
|
127
|
+
}
|
|
128
|
+
row[columnIndex + i] = recordset[recordIndex][columnName][i];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else
|
|
132
|
+
row[columnIndex] = recordset[recordIndex][columnName];
|
|
133
|
+
}
|
|
134
|
+
rows.push(row);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
for (var typeIndex in types) {
|
|
138
|
+
if (types[typeIndex] == "datetimeZ") types[typeIndex] = "datetimeoffset";
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
end({ success: true, columns: columns, rows: rows, types: types });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
var getHostInfo = function (host) {
|
|
145
|
+
const info = {};
|
|
146
|
+
const regexPort = /(.*),([0-9]+)/;
|
|
147
|
+
const matchPort = regexPort.exec(host);
|
|
148
|
+
|
|
149
|
+
if (matchPort) {
|
|
150
|
+
info.port = matchPort[2].trim();
|
|
151
|
+
host = matchPort[1].trim();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const regexInstanceName = /(.*)\\(.*)/;
|
|
155
|
+
const matchInstanceName = regexInstanceName.exec(host);
|
|
156
|
+
if (matchInstanceName) {
|
|
157
|
+
info.instanceName = matchInstanceName[2].trim();
|
|
158
|
+
host = matchInstanceName[1].trim();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
info.host = host;
|
|
162
|
+
return info;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
var getConnectionStringConfig = function (connectionString) {
|
|
166
|
+
var config = {
|
|
167
|
+
options: {
|
|
168
|
+
trustServerCertificate: true,
|
|
169
|
+
cryptoCredentialsDetails: {
|
|
170
|
+
minVersion: 'TLSv1'
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
for (var propertyIndex in connectionString.split(";")) {
|
|
176
|
+
var property = connectionString.split(";")[propertyIndex];
|
|
177
|
+
if (property) {
|
|
178
|
+
var match = property.split("=");
|
|
179
|
+
if (match && match.length >= 2) {
|
|
180
|
+
match[0] = match[0].trim().toLowerCase();
|
|
181
|
+
match[1] = match[1].trim();
|
|
182
|
+
|
|
183
|
+
switch (match[0]) {
|
|
184
|
+
case "data source":
|
|
185
|
+
case "server":
|
|
186
|
+
var hostInfo = getHostInfo(match[1]);
|
|
187
|
+
config["server"] = hostInfo.host;
|
|
188
|
+
if ("port" in hostInfo) config["port"] = +hostInfo.port;
|
|
189
|
+
if ("instanceName" in hostInfo) config.options["instanceName"] = hostInfo.instanceName;
|
|
190
|
+
break;
|
|
191
|
+
|
|
192
|
+
case "database":
|
|
193
|
+
case "initial catalog":
|
|
194
|
+
config["database"] = match[1];
|
|
195
|
+
break;
|
|
196
|
+
|
|
197
|
+
case "uid":
|
|
198
|
+
case "user":
|
|
199
|
+
case "user id":
|
|
200
|
+
config["user"] = match[1];
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
case "pwd":
|
|
204
|
+
case "password":
|
|
205
|
+
config["password"] = match[1];
|
|
206
|
+
break;
|
|
207
|
+
|
|
208
|
+
case "domain":
|
|
209
|
+
config["domain"] = match[1];
|
|
210
|
+
break;
|
|
211
|
+
|
|
212
|
+
case "encrypt":
|
|
213
|
+
config.options["encrypt"] = !!match[1];
|
|
214
|
+
break;
|
|
215
|
+
|
|
216
|
+
case "connectiontimeout":
|
|
217
|
+
config.options["connectionTimeout"] = match[1];
|
|
218
|
+
break;
|
|
219
|
+
|
|
220
|
+
case "requesttimeout":
|
|
221
|
+
config.options["requestTimeout"] = match[1];
|
|
222
|
+
break;
|
|
223
|
+
|
|
224
|
+
case "tdsversion":
|
|
225
|
+
config.options["tdsVersion"] = match[1];
|
|
226
|
+
break;
|
|
227
|
+
|
|
228
|
+
case "trustservercertificate":
|
|
229
|
+
config.options["trustServerCertificate"] = !!match[1];
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return config;
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
var sql = require('mssql');
|
|
240
|
+
var config = getConnectionStringConfig(command.connectionString);
|
|
241
|
+
if (!("connectionTimeout" in config) && "timeout" in command) config.connectionTimeout = command.timeout;
|
|
242
|
+
if (!("requestTimeout" in config) && "timeout" in command) config.requestTimeout = command.timeout;
|
|
243
|
+
|
|
244
|
+
connect();
|
|
245
|
+
}
|
|
246
|
+
catch (e) {
|
|
247
|
+
onError(e.stack);
|
|
248
|
+
}
|
|
249
|
+
}
|
package/MySQLAdapter.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Stimulsoft.Reports.JS
|
|
3
|
+
Version: 2021.4.1
|
|
4
|
+
Build date: 2021.10.04
|
|
5
|
+
License: https://www.stimulsoft.com/en/licensing/reports
|
|
6
|
+
*/
|
|
7
|
+
exports.process = function (command, onResult) {
|
|
8
|
+
var end = function (result) {
|
|
9
|
+
try {
|
|
10
|
+
if (connection) {
|
|
11
|
+
connection.end();
|
|
12
|
+
}
|
|
13
|
+
result.adapterVersion = "2021.4.1";
|
|
14
|
+
onResult(result);
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
var onError = function (message) {
|
|
21
|
+
end({ success: false, notice: message });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
var connect = function () {
|
|
26
|
+
connection.connect(function (error) {
|
|
27
|
+
if (error) onError(error.message);
|
|
28
|
+
else onConnect();
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var query = function (queryString, timeout) {
|
|
33
|
+
connection.query("USE " + command.connectionStringInfo.database);
|
|
34
|
+
//queryString = queryString.replace(/\'/gi, "\"");
|
|
35
|
+
connection.query({ sql: queryString, timeout: timeout }, function (error, rows, fields) {
|
|
36
|
+
if (error) onError(error.message);
|
|
37
|
+
else {
|
|
38
|
+
onQuery(rows, fields);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var onConnect = function () {
|
|
44
|
+
if (command.queryString) query(command.queryString, command.timeout);
|
|
45
|
+
else end({ success: true });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var onQuery = function (recordset, fields) {
|
|
49
|
+
var columns = [];
|
|
50
|
+
var rows = [];
|
|
51
|
+
var types = [];
|
|
52
|
+
if (fields.length > 0 && Array.isArray(fields[0])) fields = fields[0];
|
|
53
|
+
|
|
54
|
+
for (var columnIndex in fields) {
|
|
55
|
+
var column = fields[columnIndex]
|
|
56
|
+
columns.push(column.name);
|
|
57
|
+
|
|
58
|
+
switch (column.type) {
|
|
59
|
+
case 16: // Bit
|
|
60
|
+
types[columnIndex] = "boolean"; break;
|
|
61
|
+
|
|
62
|
+
case 1: // Byte
|
|
63
|
+
case 2: // Int16
|
|
64
|
+
case 3: // Int32
|
|
65
|
+
case 5: // Double
|
|
66
|
+
case 8: // Int64
|
|
67
|
+
case 9: // Int24
|
|
68
|
+
case 13: // Year
|
|
69
|
+
case 501: // UByte
|
|
70
|
+
case 502: // UInt16
|
|
71
|
+
case 503: // UInt32
|
|
72
|
+
case 508: // UInt64
|
|
73
|
+
case 509: // UInt24
|
|
74
|
+
types[columnIndex] = "int"; break;
|
|
75
|
+
|
|
76
|
+
case 0: // Decimal
|
|
77
|
+
case 4: // Float
|
|
78
|
+
case 246: // NewDecimal
|
|
79
|
+
types[columnIndex] = "number"; break;
|
|
80
|
+
|
|
81
|
+
case 7: // Timestamp
|
|
82
|
+
case 10: // Date
|
|
83
|
+
case 12: // DateTime
|
|
84
|
+
case 14: // Newdate
|
|
85
|
+
types[columnIndex] = "datetime"; break;
|
|
86
|
+
|
|
87
|
+
case 11: // Time
|
|
88
|
+
types[columnIndex] = "time"; break;
|
|
89
|
+
|
|
90
|
+
case 15: // VarString
|
|
91
|
+
case 247: // Enum
|
|
92
|
+
case 248: // Set
|
|
93
|
+
case 249: // TinyBlob
|
|
94
|
+
case 250: // MediumBlob
|
|
95
|
+
case 251: // LongBlob
|
|
96
|
+
case 252: // Blob
|
|
97
|
+
case 253: // VarChar
|
|
98
|
+
case 254: // String
|
|
99
|
+
case 255: // Geometry
|
|
100
|
+
case 600: // Binary
|
|
101
|
+
case 601: // VarBinary
|
|
102
|
+
case 749: // TinyText
|
|
103
|
+
case 750: // MediumText
|
|
104
|
+
case 751: // LongText
|
|
105
|
+
case 752: // Text
|
|
106
|
+
case 800: // Guid
|
|
107
|
+
|
|
108
|
+
default:
|
|
109
|
+
types[columnIndex] = "string"; break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (recordset.length > 0 && Array.isArray(recordset[0])) recordset = recordset[0];
|
|
114
|
+
for (var recordIndex in recordset) {
|
|
115
|
+
var row = [];
|
|
116
|
+
for (var columnName in recordset[recordIndex]) {
|
|
117
|
+
var columnIndex = columns.indexOf(columnName);
|
|
118
|
+
if (recordset[recordIndex][columnName] instanceof Uint8Array ||
|
|
119
|
+
recordset[recordIndex][columnName] instanceof Buffer) {
|
|
120
|
+
types[columnIndex] = "array";
|
|
121
|
+
recordset[recordIndex][columnName] = Buffer.from(recordset[recordIndex][columnName]).toString('base64');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (recordset[recordIndex][columnName] != null && typeof recordset[recordIndex][columnName].toISOString === "function") {
|
|
125
|
+
var dateTime = new Date(recordset[recordIndex][columnName].getTime() - (recordset[recordIndex][columnName].getTimezoneOffset() * 60000)).toISOString();
|
|
126
|
+
recordset[recordIndex][columnName] = dateTime.replace("Z", "");
|
|
127
|
+
types[columnIndex] = "datetime";
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
row[columnIndex] = recordset[recordIndex][columnName];
|
|
131
|
+
}
|
|
132
|
+
rows.push(row);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
end({ success: true, columns: columns, rows: rows, types: types });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
var getConnectionStringInfo = function (connectionString) {
|
|
139
|
+
var info = { host: "localhost", port: "3306", charset: "utf8" };
|
|
140
|
+
|
|
141
|
+
for (var propertyIndex in connectionString.split(";")) {
|
|
142
|
+
var property = connectionString.split(";")[propertyIndex];
|
|
143
|
+
if (property) {
|
|
144
|
+
var match = property.split("=");
|
|
145
|
+
if (match && match.length >= 2) {
|
|
146
|
+
match[0] = match[0].trim().toLowerCase();
|
|
147
|
+
match[1] = match[1].trim();
|
|
148
|
+
|
|
149
|
+
switch (match[0]) {
|
|
150
|
+
case "server":
|
|
151
|
+
case "host":
|
|
152
|
+
case "location":
|
|
153
|
+
info["host"] = match[1];
|
|
154
|
+
break;
|
|
155
|
+
|
|
156
|
+
case "port":
|
|
157
|
+
info["port"] = match[1];
|
|
158
|
+
break;
|
|
159
|
+
|
|
160
|
+
case "database":
|
|
161
|
+
case "data source":
|
|
162
|
+
info["database"] = match[1];
|
|
163
|
+
break;
|
|
164
|
+
|
|
165
|
+
case "uid":
|
|
166
|
+
case "user":
|
|
167
|
+
case "username":
|
|
168
|
+
case "userid":
|
|
169
|
+
case "user id":
|
|
170
|
+
info["userId"] = match[1];
|
|
171
|
+
break;
|
|
172
|
+
|
|
173
|
+
case "pwd":
|
|
174
|
+
case "password":
|
|
175
|
+
info["password"] = match[1];
|
|
176
|
+
break;
|
|
177
|
+
|
|
178
|
+
case "charset":
|
|
179
|
+
info["charset"] = match[1];
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return info;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
var mysql = require('mysql');
|
|
190
|
+
command.connectionStringInfo = getConnectionStringInfo(command.connectionString);
|
|
191
|
+
|
|
192
|
+
var connection = mysql.createConnection({
|
|
193
|
+
host: command.connectionStringInfo.host,
|
|
194
|
+
user: command.connectionStringInfo.userId,
|
|
195
|
+
password: command.connectionStringInfo.password,
|
|
196
|
+
port: command.connectionStringInfo.port,
|
|
197
|
+
charset: command.connectionStringInfo.charset,
|
|
198
|
+
database: command.connectionStringInfo.database
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
connect();
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
onError(e.stack);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Stimulsoft.Reports.JS
|
|
3
|
+
Version: 2021.4.1
|
|
4
|
+
Build date: 2021.10.04
|
|
5
|
+
License: https://www.stimulsoft.com/en/licensing/reports
|
|
6
|
+
*/
|
|
7
|
+
exports.process = function (command, onResult) {
|
|
8
|
+
var end = function (result) {
|
|
9
|
+
try {
|
|
10
|
+
if (client) client.end();
|
|
11
|
+
result.adapterVersion = "2021.4.1";
|
|
12
|
+
onResult(result);
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var onError = function (message) {
|
|
19
|
+
end({ success: false, notice: message });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
var connect = function () {
|
|
24
|
+
client.connect(function (error) {
|
|
25
|
+
if (error) onError(error.message);
|
|
26
|
+
else onConnect();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var query = function (queryString) {
|
|
31
|
+
client.query(queryString, function (error, recordset) {
|
|
32
|
+
if (error) onError(error.message);
|
|
33
|
+
else {
|
|
34
|
+
onQuery(recordset);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
var onConnect = function () {
|
|
40
|
+
if (command.queryString) query(command.queryString);
|
|
41
|
+
else end({ success: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var onQuery = function (recordset) {
|
|
45
|
+
var columns = [];
|
|
46
|
+
var rows = [];
|
|
47
|
+
var types = [];
|
|
48
|
+
|
|
49
|
+
for (var columnIndex in recordset.fields) {
|
|
50
|
+
var column = recordset.fields[columnIndex]
|
|
51
|
+
columns.push(column.name);
|
|
52
|
+
|
|
53
|
+
switch (column.dataTypeID) {
|
|
54
|
+
case 16: // BOOL
|
|
55
|
+
types[columnIndex] = "boolean"; break;
|
|
56
|
+
|
|
57
|
+
case 20: // INT8
|
|
58
|
+
case 21: // INT2
|
|
59
|
+
case 23: // INT4
|
|
60
|
+
types[columnIndex] = "int"; break;
|
|
61
|
+
|
|
62
|
+
case 700: // FLOAT4
|
|
63
|
+
case 701: // FLOAT8
|
|
64
|
+
case 790: // MONEY
|
|
65
|
+
types[columnIndex] = "number"; break;
|
|
66
|
+
|
|
67
|
+
case 702: // ABSTIME
|
|
68
|
+
case 1082: // DATE
|
|
69
|
+
case 1114: // TIMESTAMP
|
|
70
|
+
types[columnIndex] = "datetime"; break;
|
|
71
|
+
|
|
72
|
+
case 1184: // TIMESTAMPTZ
|
|
73
|
+
types[columnIndex] = "datetimeZ"; break;
|
|
74
|
+
|
|
75
|
+
case 1083: // TIME
|
|
76
|
+
types[columnIndex] = "time"; break;
|
|
77
|
+
|
|
78
|
+
case 1266: // TIMETZ
|
|
79
|
+
types[columnIndex] = "timeZ"; break;
|
|
80
|
+
|
|
81
|
+
case 17: // BYTEA
|
|
82
|
+
case 18: // CHAR
|
|
83
|
+
case 19:
|
|
84
|
+
case 24: // REGPROC
|
|
85
|
+
case 25: // TEXT
|
|
86
|
+
case 26: // OID
|
|
87
|
+
case 27: // TID
|
|
88
|
+
case 28: // XID
|
|
89
|
+
case 29: // CID
|
|
90
|
+
case 114: // JSON
|
|
91
|
+
case 142: // XML
|
|
92
|
+
case 194: // PG_NODE_TREE
|
|
93
|
+
case 210: // SMGR
|
|
94
|
+
case 602: // PATH
|
|
95
|
+
case 604: // POLYGON
|
|
96
|
+
case 650: // CIDR
|
|
97
|
+
case 703: // RELTIME
|
|
98
|
+
case 704: // TINTERVAL
|
|
99
|
+
case 718: // CIRCLE
|
|
100
|
+
case 774: // MACADDR8
|
|
101
|
+
case 829: // MACADDR
|
|
102
|
+
case 869: // INET
|
|
103
|
+
case 1033: // ACLITEM
|
|
104
|
+
case 1042: // BPCHAR
|
|
105
|
+
case 1043: // VARCHAR
|
|
106
|
+
case 1186: // INTERVAL
|
|
107
|
+
case 1560: // BIT
|
|
108
|
+
case 1562: // VARBIT
|
|
109
|
+
case 1700: // NUMERIC
|
|
110
|
+
case 1790: // REFCURSOR
|
|
111
|
+
case 2202: // REGPROCEDURE
|
|
112
|
+
case 2203: // REGOPER
|
|
113
|
+
case 2204: // REGOPERATOR
|
|
114
|
+
case 2205: // REGCLASS
|
|
115
|
+
case 2206: // REGTYPE
|
|
116
|
+
case 2950: // UUID
|
|
117
|
+
case 2970: // TXID_SNAPSHOT
|
|
118
|
+
case 3220: // PG_LSN
|
|
119
|
+
case 3361: // PG_NDISTINCT
|
|
120
|
+
case 3402: // PG_DEPENDENCIES
|
|
121
|
+
case 3614: // TSVECTOR
|
|
122
|
+
case 3615: // TSQUERY
|
|
123
|
+
case 3642: // GTSVECTOR
|
|
124
|
+
case 3734: // REGCONFIG
|
|
125
|
+
case 3769: // REGDICTIONARY
|
|
126
|
+
case 3802: // JSONB
|
|
127
|
+
case 4089: // REGNAMESPACE
|
|
128
|
+
case 4096: // REGROLE
|
|
129
|
+
default:
|
|
130
|
+
types[columnIndex] = "string"; break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (recordset.rows.length > 0 && Array.isArray(recordset.rows[0])) recordset.rows = recordset.rows[0];
|
|
135
|
+
for (var recordIndex in recordset.rows) {
|
|
136
|
+
var row = [];
|
|
137
|
+
for (var columnName in recordset.rows[recordIndex]) {
|
|
138
|
+
var columnIndex = columns.indexOf(columnName);
|
|
139
|
+
if (recordset.rows[recordIndex][columnName] instanceof Uint8Array) {
|
|
140
|
+
types[columnIndex] = "array";
|
|
141
|
+
recordset.rows[recordIndex][columnName] = Buffer.from(recordset.rows[recordIndex][columnName]).toString('base64');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (recordset.rows[recordIndex][columnName] != null && typeof recordset.rows[recordIndex][columnName].toISOString === "function") {
|
|
145
|
+
if (types[columnIndex] == "datetimeZ") {
|
|
146
|
+
recordset.rows[recordIndex][columnName] = recordset.rows[recordIndex][columnName].toISOString();
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
var dateTime = new Date(recordset.rows[recordIndex][columnName].getTime() - (recordset.rows[recordIndex][columnName].getTimezoneOffset() * 60000)).toISOString();
|
|
150
|
+
recordset.rows[recordIndex][columnName] = dateTime.replace("Z", "");
|
|
151
|
+
types[columnIndex] = "datetime";
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (recordset.rows[recordIndex][columnName] != null && types[columnIndex] == "timeZ") {
|
|
156
|
+
var time = recordset.rows[recordIndex][columnName];
|
|
157
|
+
var offset = time.substr(time.indexOf("+"));
|
|
158
|
+
if (offset.indexOf(":") == -1) offset += ":00";
|
|
159
|
+
time = time.substr(0, time.indexOf("+"));
|
|
160
|
+
if (time.indexOf(".") == -1) time += ".000"
|
|
161
|
+
recordset.rows[recordIndex][columnName] = "0001-01-01T" + time + offset;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
row[columnIndex] = recordset.rows[recordIndex][columnName];
|
|
165
|
+
}
|
|
166
|
+
rows.push(row);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
for (var typeIndex in types) {
|
|
170
|
+
if (types[typeIndex] == "timeZ") types[typeIndex] = "datetimeoffset";
|
|
171
|
+
if (types[typeIndex] == "datetimeZ") types[typeIndex] = "datetime";
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
end({ success: true, columns: columns, rows: rows, types: types });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
var getConnectionStringInfo = function (connectionString) {
|
|
178
|
+
var info = { port: 5432 };
|
|
179
|
+
|
|
180
|
+
for (var propertyIndex in connectionString.split(";")) {
|
|
181
|
+
var property = connectionString.split(";")[propertyIndex];
|
|
182
|
+
if (property) {
|
|
183
|
+
var match = property.split(new RegExp('=|:'));
|
|
184
|
+
if (match && match.length >= 2) {
|
|
185
|
+
match[0] = match[0].trim().toLowerCase();
|
|
186
|
+
match[1] = match[1].trim();
|
|
187
|
+
|
|
188
|
+
switch (match[0]) {
|
|
189
|
+
case "data source":
|
|
190
|
+
case "server":
|
|
191
|
+
case "host":
|
|
192
|
+
info["host"] = match[1];
|
|
193
|
+
break;
|
|
194
|
+
|
|
195
|
+
case "port":
|
|
196
|
+
info["port"] = match[1];
|
|
197
|
+
break;
|
|
198
|
+
|
|
199
|
+
case "database":
|
|
200
|
+
case "location":
|
|
201
|
+
info["database"] = match[1];
|
|
202
|
+
break;
|
|
203
|
+
|
|
204
|
+
case "uid":
|
|
205
|
+
case "user":
|
|
206
|
+
case "user id":
|
|
207
|
+
info["userId"] = match[1];
|
|
208
|
+
break;
|
|
209
|
+
|
|
210
|
+
case "pwd":
|
|
211
|
+
case "password":
|
|
212
|
+
info["password"] = match[1];
|
|
213
|
+
break;
|
|
214
|
+
|
|
215
|
+
case "ssl":
|
|
216
|
+
info["ssl"] = match[1];
|
|
217
|
+
break;
|
|
218
|
+
case "sslmode":
|
|
219
|
+
if (match[1] == "require") info["ssl"] = 1;
|
|
220
|
+
else if (match[1] == "disable") info["ssl"] = 0;
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return info;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
var pg = require('pg');
|
|
231
|
+
if (command.connectionString.startsWith("postgres://")) command.postgreConnectionString = command.connectionString
|
|
232
|
+
else {
|
|
233
|
+
command.connectionStringInfo = getConnectionStringInfo(command.connectionString);
|
|
234
|
+
|
|
235
|
+
command.postgreConnectionString = "postgres://" + command.connectionStringInfo.userId + ":" + command.connectionStringInfo.password + "@" + command.connectionStringInfo.host;
|
|
236
|
+
if (command.connectionStringInfo.port != null) command.postgreConnectionString += ":" + command.connectionStringInfo.port;
|
|
237
|
+
command.postgreConnectionString += "/" + command.connectionStringInfo.database;
|
|
238
|
+
}
|
|
239
|
+
var client = new pg.Client(command.postgreConnectionString);
|
|
240
|
+
|
|
241
|
+
connect();
|
|
242
|
+
}
|
|
243
|
+
catch (e) {
|
|
244
|
+
onError(e.stack);
|
|
245
|
+
}
|
|
246
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
### Installation and running
|
|
3
|
+
Use npm to install requred modules:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install
|
|
7
|
+
```
|
|
8
|
+
Run:
|
|
9
|
+
```bash
|
|
10
|
+
node index
|
|
11
|
+
```
|
|
12
|
+
Then, in your code, you should specify the host and port.
|
|
13
|
+
|
|
14
|
+
index.html
|
|
15
|
+
```js
|
|
16
|
+
StiOptions.WebServer.url = "http://localhost:9615";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
In the app.js file, you can change all parameters passed from the JS client-side.
|
|
20
|
+
|
|
21
|
+
A [sample](https://github.com/stimulsoft/Samples-JS/tree/master/Node.js/04.%20Start%20SQL%20Adapters%20from%20Http%20Server) shows how to run an adapter.
|
package/app.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Stimulsoft.Reports.JS
|
|
3
|
+
Version: 2021.4.1
|
|
4
|
+
Build date: 2021.10.04
|
|
5
|
+
License: https://www.stimulsoft.com/en/licensing/reports
|
|
6
|
+
*/
|
|
7
|
+
var http = require('http');
|
|
8
|
+
var MySQLAdapter = require('./MySQLAdapter');
|
|
9
|
+
var FirebirdAdapter = require('./FirebirdAdapter');
|
|
10
|
+
var MSSQLAdapter = require('./MSSQLAdapter');
|
|
11
|
+
var PostgreSQLAdapter = require('./PostgreSQLAdapter');
|
|
12
|
+
|
|
13
|
+
var connectionStringBuilder;
|
|
14
|
+
var response;
|
|
15
|
+
function accept(req, res) {
|
|
16
|
+
response = res;
|
|
17
|
+
response.setHeader("Access-Control-Allow-Origin", "*");
|
|
18
|
+
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
|
19
|
+
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
|
|
20
|
+
response.setHeader("Cache-Control", "no-cache");
|
|
21
|
+
|
|
22
|
+
var data = "";
|
|
23
|
+
req.on('data', function (buffer) {
|
|
24
|
+
data += buffer;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
req.on('end', function () {
|
|
28
|
+
if (data.indexOf("{") != 0) {
|
|
29
|
+
data = Buffer.from(data.replace(/[A-Za-z]/g, function (c) {
|
|
30
|
+
return String.fromCharCode(c.charCodeAt(0) + (c.toUpperCase() <= "M" ? 13 : -13));
|
|
31
|
+
}), "base64").toString("ascii");
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
command = JSON.parse(data.toString());
|
|
36
|
+
|
|
37
|
+
command.queryString = applyQueryParameters(command.queryString, command.parameters, command.escapeQueryParameters);
|
|
38
|
+
|
|
39
|
+
if (command.database == "MySQL") MySQLAdapter.process(command, onProcess);
|
|
40
|
+
else if (command.database == "Firebird") FirebirdAdapter.process(command, onProcess);
|
|
41
|
+
else if (command.database == "MS SQL") MSSQLAdapter.process(command, onProcess);
|
|
42
|
+
else if (command.database == "PostgreSQL") PostgreSQLAdapter.process(command, onProcess);
|
|
43
|
+
else onResult({ success: false, notice: "Database '" + command.database + "' not supported!" });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
var applyQueryParameters = function (baseSqlCommand, parameters, escapeQueryParameters) {
|
|
48
|
+
if (baseSqlCommand == null || baseSqlCommand.indexOf("@") < 0) return baseSqlCommand;
|
|
49
|
+
|
|
50
|
+
var result = "";
|
|
51
|
+
while (baseSqlCommand.indexOf("@") >= 0 && parameters != null && parameters.length > 0) {
|
|
52
|
+
result += baseSqlCommand.substring(0, baseSqlCommand.indexOf("@"));
|
|
53
|
+
baseSqlCommand = baseSqlCommand.substring(baseSqlCommand.indexOf("@") + 1);
|
|
54
|
+
|
|
55
|
+
var parameterName = "";
|
|
56
|
+
|
|
57
|
+
while (baseSqlCommand.length > 0) {
|
|
58
|
+
var char = baseSqlCommand.charAt(0);
|
|
59
|
+
if (char.length === 1 && char.match(/[a-zA-Z0-9_-]/i)) {
|
|
60
|
+
parameterName += char;
|
|
61
|
+
baseSqlCommand = baseSqlCommand.substring(1);
|
|
62
|
+
}
|
|
63
|
+
else break;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var parameter = parameters.find(parameter => parameter.name.toLowerCase() == parameterName.toLowerCase());
|
|
67
|
+
if (parameter) {
|
|
68
|
+
if (parameter.typeGroup != "number") {
|
|
69
|
+
if (escapeQueryParameters)
|
|
70
|
+
result += "'" + parameter.value.toString().replace(/\\/gi, "\\\\").replace(/\'/gi, "\\\'").replace(/\"/gi, "\\\"") + "'";
|
|
71
|
+
else
|
|
72
|
+
result += "'" + parameter.value.toString() + "'";
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
result += parameter.value.toString();
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
result += "@" + parameterName;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return result + baseSqlCommand;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
var onProcess = function (result) {
|
|
85
|
+
result.handlerVersion = "2021.4.1";
|
|
86
|
+
response.end(JSON.stringify(result));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
http.createServer(accept).listen(9615);
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "stimulsoft-data-adapter",
|
|
3
|
+
"version": "2021.4.1",
|
|
4
|
+
"description": "Nodejs data adapter for Stimulsoft Reports.JS",
|
|
5
|
+
"main": "app.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node app.js"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/stimulsoft/DataAdapters.JS/tree/main/NodejsDataAdapters"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"mssql": "^6.2.1",
|
|
15
|
+
"mysql": "^2.15.0",
|
|
16
|
+
"node-firebird": "^0.9.8",
|
|
17
|
+
"pg": "^8.3.3",
|
|
18
|
+
"tzdata": "^1.0.25"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"package.json",
|
|
22
|
+
"README.md",
|
|
23
|
+
"app.js",
|
|
24
|
+
"FirebirdAdapter.js",
|
|
25
|
+
"MSSQLAdapter.js",
|
|
26
|
+
"MySQLAdapter.js",
|
|
27
|
+
"OracleAdapter.js",
|
|
28
|
+
"PostgreSQLAdapter.js"
|
|
29
|
+
],
|
|
30
|
+
"author": {
|
|
31
|
+
"name": "Stimulsoft",
|
|
32
|
+
"url": "http://www.stimulsoft.com"
|
|
33
|
+
},
|
|
34
|
+
"maintainers": [
|
|
35
|
+
{
|
|
36
|
+
"name": "Stimulsoft",
|
|
37
|
+
"email": "info@stimulsoft.com",
|
|
38
|
+
"url": "http://www.stimulsoft.com"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"contributors": [
|
|
42
|
+
{
|
|
43
|
+
"name": "Stimulsoft",
|
|
44
|
+
"email": "info@stimulsoft.com",
|
|
45
|
+
"url": "http://www.stimulsoft.com"
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
"license": "Closed Source",
|
|
49
|
+
"homepage": "https://github.com/stimulsoft/DataAdapters.JS/tree/main/NodejsDataAdapters"
|
|
50
|
+
}
|