@kineviz/ladybug-lite 0.15.3
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/LICENSE +21 -0
- package/README.md +84 -0
- package/connection.js +471 -0
- package/database.js +211 -0
- package/index.js +19 -0
- package/index.mjs +10 -0
- package/lbug.d.ts +399 -0
- package/lbug_native.js +25 -0
- package/package.json +27 -0
- package/prepared_statement.js +42 -0
- package/query_result.js +242 -0
- package/util/__pycache__/safe_ladybug_subprocess.cpython-314.pyc +0 -0
- package/util/build.js +248 -0
- package/util/build.md +90 -0
- package/util/buildLadybugExtensions.sh +79 -0
- package/util/buildLadybugWithDocker.sh +65 -0
- package/util/copy.js +24 -0
- package/util/dev.md +419 -0
- package/util/install.js +81 -0
- package/util/readme.md +23 -0
- package/util/safe_ladybug_subprocess.py +58 -0
- package/util/test.Ipynb +120 -0
- package/util/test.js +50 -0
- package/util/test.large.js +26 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const assert = require("assert");
|
|
4
|
+
|
|
5
|
+
class PreparedStatement {
|
|
6
|
+
/**
|
|
7
|
+
* Internal constructor. Use `Connection.prepare` to get a
|
|
8
|
+
* `PreparedStatement` object.
|
|
9
|
+
* @param {Connection} connection the connection object.
|
|
10
|
+
* @param {LbugNative.NodePreparedStatement} preparedStatement the native prepared statement object.
|
|
11
|
+
*/
|
|
12
|
+
constructor(connection, preparedStatement) {
|
|
13
|
+
assert(
|
|
14
|
+
typeof connection === "object" &&
|
|
15
|
+
connection.constructor.name === "Connection"
|
|
16
|
+
);
|
|
17
|
+
assert(
|
|
18
|
+
typeof preparedStatement === "object" &&
|
|
19
|
+
preparedStatement.constructor.name === "NodePreparedStatement"
|
|
20
|
+
);
|
|
21
|
+
this._connection = connection;
|
|
22
|
+
this._preparedStatement = preparedStatement;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Check if the prepared statement is successfully prepared.
|
|
27
|
+
* @returns {Boolean} true if the prepared statement is successfully prepared.
|
|
28
|
+
*/
|
|
29
|
+
isSuccess() {
|
|
30
|
+
return this._preparedStatement.isSuccess();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get the error message if the prepared statement is not successfully prepared.
|
|
35
|
+
* @returns {String} the error message.
|
|
36
|
+
*/
|
|
37
|
+
getErrorMessage() {
|
|
38
|
+
return this._preparedStatement.getErrorMessage();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
module.exports = PreparedStatement;
|
package/query_result.js
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const assert = require("assert");
|
|
4
|
+
|
|
5
|
+
class QueryResult {
|
|
6
|
+
/**
|
|
7
|
+
* Internal constructor. Use `Connection.query` or `Connection.execute`
|
|
8
|
+
* to get a `QueryResult` object.
|
|
9
|
+
* @param {Connection} connection the connection object.
|
|
10
|
+
* @param {LbugNative.NodeQueryResult} queryResult the native query result object.
|
|
11
|
+
*/
|
|
12
|
+
constructor(connection, queryResult) {
|
|
13
|
+
assert(
|
|
14
|
+
typeof connection === "object" &&
|
|
15
|
+
connection.constructor.name === "Connection"
|
|
16
|
+
);
|
|
17
|
+
assert(
|
|
18
|
+
typeof queryResult === "object" &&
|
|
19
|
+
queryResult.constructor.name === "NodeQueryResult"
|
|
20
|
+
);
|
|
21
|
+
this._connection = connection;
|
|
22
|
+
this._queryResult = queryResult;
|
|
23
|
+
this._isClosed = false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Reset the iterator of the query result to the beginning.
|
|
28
|
+
* This function is useful if the query result is iterated multiple times.
|
|
29
|
+
*/
|
|
30
|
+
resetIterator() {
|
|
31
|
+
this._checkClosed();
|
|
32
|
+
this._queryResult.resetIterator();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Check if the query result has more rows.
|
|
37
|
+
* @returns {Boolean} true if the query result has more rows.
|
|
38
|
+
*/
|
|
39
|
+
hasNext() {
|
|
40
|
+
this._checkClosed();
|
|
41
|
+
return this._queryResult.hasNext();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get the number of rows of the query result.
|
|
46
|
+
* @returns {Number} the number of rows of the query result.
|
|
47
|
+
*/
|
|
48
|
+
getNumTuples() {
|
|
49
|
+
this._checkClosed();
|
|
50
|
+
return this._queryResult.getNumTuples();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get the next row of the query result.
|
|
55
|
+
* @returns {Promise<Object>} a promise that resolves to the next row of the query result. The promise is rejected if there is an error.
|
|
56
|
+
*/
|
|
57
|
+
getNext() {
|
|
58
|
+
this._checkClosed();
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
this._queryResult.getNextAsync((err, result) => {
|
|
61
|
+
if (err) {
|
|
62
|
+
return reject(err);
|
|
63
|
+
}
|
|
64
|
+
return resolve(result);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get the next row of the query result synchronously.
|
|
71
|
+
* @returns {Object} the next row of the query result.
|
|
72
|
+
*/
|
|
73
|
+
getNextSync() {
|
|
74
|
+
this._checkClosed();
|
|
75
|
+
return this._queryResult.getNextSync();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Iterate through the query result with callback functions.
|
|
80
|
+
* @param {Function} resultCallback the callback function that is called for each row of the query result.
|
|
81
|
+
* @param {Function} doneCallback the callback function that is called when the iteration is done.
|
|
82
|
+
* @param {Function} errorCallback the callback function that is called when there is an error.
|
|
83
|
+
*/
|
|
84
|
+
each(resultCallback, doneCallback, errorCallback) {
|
|
85
|
+
this._checkClosed();
|
|
86
|
+
if (!this.hasNext()) {
|
|
87
|
+
return doneCallback();
|
|
88
|
+
}
|
|
89
|
+
this.getNext()
|
|
90
|
+
.then((row) => {
|
|
91
|
+
resultCallback(row);
|
|
92
|
+
this.each(resultCallback, doneCallback, errorCallback);
|
|
93
|
+
})
|
|
94
|
+
.catch((err) => {
|
|
95
|
+
errorCallback(err);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Get all rows of the query result.
|
|
101
|
+
* @returns {Promise<Array<Object>>} a promise that resolves to all rows of the query result. The promise is rejected if there is an error.
|
|
102
|
+
*/
|
|
103
|
+
async getAll() {
|
|
104
|
+
this._checkClosed();
|
|
105
|
+
this._queryResult.resetIterator();
|
|
106
|
+
const result = [];
|
|
107
|
+
while (this.hasNext()) {
|
|
108
|
+
result.push(await this.getNext());
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get all rows of the query result synchronously. Note that this function can block the main thread if the number of rows is large, so use it with caution.
|
|
115
|
+
* @returns {Array<Object>} all rows of the query result.
|
|
116
|
+
*/
|
|
117
|
+
getAllSync() {
|
|
118
|
+
this._checkClosed();
|
|
119
|
+
this._queryResult.resetIterator();
|
|
120
|
+
const result = [];
|
|
121
|
+
while (this.hasNext()) {
|
|
122
|
+
result.push(this.getNextSync());
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get all rows of the query result with callback functions.
|
|
129
|
+
* @param {Function} resultCallback the callback function that is called with all rows of the query result.
|
|
130
|
+
* @param {Function} errorCallback the callback function that is called when there is an error.
|
|
131
|
+
*/
|
|
132
|
+
all(resultCallback, errorCallback) {
|
|
133
|
+
this._checkClosed();
|
|
134
|
+
this.getAll()
|
|
135
|
+
.then((result) => {
|
|
136
|
+
resultCallback(result);
|
|
137
|
+
})
|
|
138
|
+
.catch((err) => {
|
|
139
|
+
errorCallback(err);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get the data types of the columns of the query result.
|
|
145
|
+
* @returns {Promise<Array<String>>} a promise that resolves to the data types of the columns of the query result. The promise is rejected if there is an error.
|
|
146
|
+
*/
|
|
147
|
+
getColumnDataTypes() {
|
|
148
|
+
this._checkClosed();
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
this._queryResult.getColumnDataTypesAsync((err, result) => {
|
|
151
|
+
if (err) {
|
|
152
|
+
return reject(err);
|
|
153
|
+
}
|
|
154
|
+
return resolve(result);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get the data types of the columns of the query result synchronously.
|
|
161
|
+
* @returns {Array<String>} the data types of the columns of the query result.
|
|
162
|
+
*/
|
|
163
|
+
getColumnDataTypesSync() {
|
|
164
|
+
this._checkClosed();
|
|
165
|
+
return this._queryResult.getColumnDataTypesSync();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get the names of the columns of the query result.
|
|
170
|
+
* @returns {Promise<Array<String>>} a promise that resolves to the names of the columns of the query result. The promise is rejected if there is an error.
|
|
171
|
+
*/
|
|
172
|
+
getColumnNames() {
|
|
173
|
+
this._checkClosed();
|
|
174
|
+
return new Promise((resolve, reject) => {
|
|
175
|
+
this._queryResult.getColumnNamesAsync((err, result) => {
|
|
176
|
+
if (err) {
|
|
177
|
+
return reject(err);
|
|
178
|
+
}
|
|
179
|
+
return resolve(result);
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Get the names of the columns of the query result synchronously.
|
|
186
|
+
* @returns {Array<String>} the names of the columns of the query result.
|
|
187
|
+
*/
|
|
188
|
+
getColumnNamesSync() {
|
|
189
|
+
this._checkClosed();
|
|
190
|
+
return this._queryResult.getColumnNamesSync();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Get the query summary (compiling and execution time) of the query result.
|
|
195
|
+
* @returns {Promise<Object>} a promise that resolves to the query summary of the query result. The promise is rejected if there is an error.
|
|
196
|
+
*/
|
|
197
|
+
getQuerySummary() {
|
|
198
|
+
this._checkClosed();
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
this._queryResult.getQuerySummaryAsync((err, result) => {
|
|
201
|
+
if (err) {
|
|
202
|
+
return reject(err);
|
|
203
|
+
}
|
|
204
|
+
return resolve(result);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get the query summary (compiling and execution time) of the query result synchronously.
|
|
211
|
+
* @returns {Object} the query summary of the query result.
|
|
212
|
+
*/
|
|
213
|
+
getQuerySummarySync() {
|
|
214
|
+
this._checkClosed();
|
|
215
|
+
return this._queryResult.getQuerySummarySync();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Close the query result.
|
|
220
|
+
*/
|
|
221
|
+
close() {
|
|
222
|
+
if (this._isClosed) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
this._queryResult.close();
|
|
226
|
+
delete this._queryResult;
|
|
227
|
+
this._connection = null;
|
|
228
|
+
this._isClosed = true;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Internal function to check if the query result is closed.
|
|
233
|
+
* @throws {Error} if the query result is closed.
|
|
234
|
+
*/
|
|
235
|
+
_checkClosed() {
|
|
236
|
+
if (this._isClosed) {
|
|
237
|
+
throw new Error("Query result is closed.");
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
module.exports = QueryResult;
|
|
Binary file
|
package/util/build.js
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Install packages
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const installPackage = (packageName, group = 'dev') => {
|
|
12
|
+
|
|
13
|
+
console.log(
|
|
14
|
+
`Install package ${packageName}...`
|
|
15
|
+
);
|
|
16
|
+
const childProcess = require("child_process");
|
|
17
|
+
childProcess.execSync(`npm install ${packageName} --save-dev`, {
|
|
18
|
+
cwd: rootDir,
|
|
19
|
+
stdio: "inherit",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Copies files from the 'node_modules/@ladybugdb/core' directory to the current directory.
|
|
27
|
+
* Excludes specific directories ('lbug-source', 'node_modules') and specific files ('lbugjs.node', 'package.json').
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
const copyDir = (src, dest, excludeEntries = []) => {
|
|
31
|
+
if (!fs.existsSync(dest)) {
|
|
32
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
36
|
+
|
|
37
|
+
for (const entry of entries) {
|
|
38
|
+
const srcPath = path.join(src, entry.name);
|
|
39
|
+
const destPath = path.join(dest, entry.name);
|
|
40
|
+
|
|
41
|
+
if (entry.isDirectory()) {
|
|
42
|
+
if (!excludeEntries.includes(entry.name)) {
|
|
43
|
+
copyDir(srcPath, destPath);
|
|
44
|
+
}
|
|
45
|
+
} else if (!excludeEntries.includes(entry.name)) {
|
|
46
|
+
fs.copyFileSync(srcPath, destPath);
|
|
47
|
+
console.log(`Copied: ${srcPath} -> ${destPath}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Deletes all files and directories in the current directory
|
|
54
|
+
* except for 'copy.js', 'package.json', and the 'node_modules' directory.
|
|
55
|
+
*/
|
|
56
|
+
const deleteFiles = (directory, excludeEntries = []) => {
|
|
57
|
+
const entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
58
|
+
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
const fullPath = path.join(directory, entry.name);
|
|
61
|
+
|
|
62
|
+
// Skip if the entry is in the exclusion list
|
|
63
|
+
if (excludeEntries.includes(entry.name)) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (entry.isDirectory()) {
|
|
68
|
+
// Recursively delete directory contents then the directory itself
|
|
69
|
+
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
70
|
+
console.log(`Deleted directory: ${fullPath}`);
|
|
71
|
+
} else {
|
|
72
|
+
// Delete file
|
|
73
|
+
fs.unlinkSync(fullPath);
|
|
74
|
+
console.log(`Deleted file: ${fullPath}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const npmPublish = (package) => {
|
|
80
|
+
console.log(
|
|
81
|
+
`Publishing package ${package.name}(${package.version})... to npm`
|
|
82
|
+
);
|
|
83
|
+
const npmrcPath = path.join(rootDir, ".npmrc");
|
|
84
|
+
fs.writeFileSync(
|
|
85
|
+
npmrcPath,
|
|
86
|
+
`//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}\n`,
|
|
87
|
+
{ encoding: "utf-8" }
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const childProcess = require("child_process");
|
|
91
|
+
try {
|
|
92
|
+
childProcess.execSync("npm publish --access public --registry https://registry.npmjs.org", {
|
|
93
|
+
cwd: rootDir,
|
|
94
|
+
stdio: "inherit",
|
|
95
|
+
});
|
|
96
|
+
} catch (err) {
|
|
97
|
+
console.error("npm publish failed:", err);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Fetches platform-specific prebuilt binaries from the scoped @ladybugdb/core-*
|
|
103
|
+
* packages and copies each one's lbugjs.node into ./prebuilt/, remapping x64
|
|
104
|
+
* filenames to amd64 so the runtime loader can find them.
|
|
105
|
+
*/
|
|
106
|
+
const copyPrebuiltBinaries = () => {
|
|
107
|
+
const corePackageJsonPath = path.join(srcDir, "package.json");
|
|
108
|
+
if (!fs.existsSync(corePackageJsonPath)) {
|
|
109
|
+
console.error("@ladybugdb/core package.json not found, skipping prebuilt fetch");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const lbugVersion = JSON.parse(fs.readFileSync(corePackageJsonPath, "utf8")).version;
|
|
113
|
+
|
|
114
|
+
const platformPackages = [
|
|
115
|
+
"core-darwin-arm64",
|
|
116
|
+
"core-linux-arm64",
|
|
117
|
+
"core-linux-x64",
|
|
118
|
+
"core-win32-x64",
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
const installArgs = platformPackages
|
|
122
|
+
.map((pkg) => `@ladybugdb/${pkg}@${lbugVersion}`)
|
|
123
|
+
.join(" ");
|
|
124
|
+
|
|
125
|
+
console.log(`Installing platform-specific prebuilt packages: ${installArgs}`);
|
|
126
|
+
const childProcess = require("child_process");
|
|
127
|
+
childProcess.execSync(`npm install --force --no-save ${installArgs}`, {
|
|
128
|
+
cwd: rootDir,
|
|
129
|
+
stdio: "inherit",
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const prebuiltDir = path.join(rootDir, "prebuilt");
|
|
133
|
+
if (!fs.existsSync(prebuiltDir)) {
|
|
134
|
+
fs.mkdirSync(prebuiltDir, { recursive: true });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
for (const pkg of platformPackages) {
|
|
138
|
+
const suffix = pkg.replace(/^core-/, "").replace(/-x64$/, "-amd64");
|
|
139
|
+
const srcBin = path.join(rootDir, "node_modules", "@ladybugdb", pkg, "lbugjs.node");
|
|
140
|
+
const destBin = path.join(prebuiltDir, `lbugjs-${suffix}.node`);
|
|
141
|
+
if (fs.existsSync(srcBin)) {
|
|
142
|
+
fs.copyFileSync(srcBin, destBin);
|
|
143
|
+
console.log(`Copied: ${srcBin} -> ${destBin}`);
|
|
144
|
+
} else {
|
|
145
|
+
console.warn(`Source binary not found: ${srcBin}`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const asyncVersion = () => {
|
|
151
|
+
// Copy version from node_modules/@ladybugdb/core/package.json to ./package.json
|
|
152
|
+
const lbugPackageJsonPath = path.join(srcDir, "package.json");
|
|
153
|
+
const projectPackageJsonPath = path.join(rootDir, "package.json");
|
|
154
|
+
|
|
155
|
+
if (
|
|
156
|
+
!fs.existsSync(lbugPackageJsonPath) ||
|
|
157
|
+
!fs.existsSync(projectPackageJsonPath)
|
|
158
|
+
) {
|
|
159
|
+
console.error("the package.json file not found");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
let lbugPackageJson = {};
|
|
163
|
+
let projectPackageJson = {};
|
|
164
|
+
try {
|
|
165
|
+
// Read both package.json files
|
|
166
|
+
lbugPackageJson = JSON.parse(fs.readFileSync(lbugPackageJsonPath, "utf8"));
|
|
167
|
+
projectPackageJson = JSON.parse(
|
|
168
|
+
fs.readFileSync(projectPackageJsonPath, "utf8")
|
|
169
|
+
);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
console.error("Can not parse the package.json version:", error);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (projectPackageJson.version != lbugPackageJson.version) {
|
|
175
|
+
projectPackageJson.version = lbugPackageJson.version;
|
|
176
|
+
projectPackageJson.devDependencies["@ladybugdb/core"] = lbugPackageJson.version;
|
|
177
|
+
// Write the updated package.json back
|
|
178
|
+
fs.writeFileSync(
|
|
179
|
+
projectPackageJsonPath,
|
|
180
|
+
JSON.stringify(projectPackageJson, null, 2)
|
|
181
|
+
);
|
|
182
|
+
console.log(`Updated package.json version to ${lbugPackageJson.version}`);
|
|
183
|
+
npmPublish(projectPackageJson);
|
|
184
|
+
} else {
|
|
185
|
+
console.log(
|
|
186
|
+
`Package.json version is already up to date: ${lbugPackageJson.version}`
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const rootDir = path.join(__dirname, "..");
|
|
192
|
+
|
|
193
|
+
// already install @ladybugdb/core with docker or action
|
|
194
|
+
// installPackage("@ladybugdb/core");
|
|
195
|
+
|
|
196
|
+
// Delete files before copying new ones
|
|
197
|
+
deleteFiles(rootDir, [
|
|
198
|
+
"package.json",
|
|
199
|
+
"util",
|
|
200
|
+
"node_modules",
|
|
201
|
+
"README.md",
|
|
202
|
+
"test",
|
|
203
|
+
".git",
|
|
204
|
+
".vscode",
|
|
205
|
+
".gitignore",
|
|
206
|
+
".github",
|
|
207
|
+
".dockerignore",
|
|
208
|
+
"Dockerfile",
|
|
209
|
+
".npmignore",
|
|
210
|
+
"docs",
|
|
211
|
+
"prebuilt"
|
|
212
|
+
]);
|
|
213
|
+
|
|
214
|
+
const srcDir = path.join(rootDir, "node_modules", "@ladybugdb", "core");
|
|
215
|
+
const destDir = path.join(rootDir);
|
|
216
|
+
|
|
217
|
+
if (fs.existsSync(srcDir)) {
|
|
218
|
+
copyDir(srcDir, destDir, [
|
|
219
|
+
"lbug-source",
|
|
220
|
+
"node_modules",
|
|
221
|
+
"lbugjs.node",
|
|
222
|
+
"package.json",
|
|
223
|
+
"install.js",
|
|
224
|
+
"README.md",
|
|
225
|
+
"test",
|
|
226
|
+
".gitignore",
|
|
227
|
+
".github",
|
|
228
|
+
".dockerignore",
|
|
229
|
+
".npmignore",
|
|
230
|
+
"Dockerfile",
|
|
231
|
+
"prebuilt",
|
|
232
|
+
]);
|
|
233
|
+
console.log("Copying completed!");
|
|
234
|
+
} else {
|
|
235
|
+
console.error("Source directory not found:", srcDir);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Fetch platform-specific prebuilt binaries only on linux-x64 so a single CI
|
|
239
|
+
// runner produces them (matches the former `if: matrix.arch == 'amd64'` gate).
|
|
240
|
+
if (process.platform === "win32" || (process.platform === "linux" && process.arch === "x64")) {
|
|
241
|
+
copyPrebuiltBinaries();
|
|
242
|
+
} else {
|
|
243
|
+
console.log(
|
|
244
|
+
`Skipping platform-specific prebuilt fetch on ${process.platform}-${process.arch}`
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
asyncVersion();
|
package/util/build.md
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# 1. 在宿主机(非容器内)安装 QEMU
|
|
2
|
+
# sudo apt-get install qemu-user-static # Debian/Ubuntu
|
|
3
|
+
|
|
4
|
+
# re-install @ladybugdb/core for clean all build info
|
|
5
|
+
yarn remove @ladybugdb/core
|
|
6
|
+
yarn add @ladybugdb/core --no-cache
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# 2. run qemu-aarch64-alpine and qemu-amd64-alpine
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
docker rm -f qemu-aarch64-alpine \
|
|
13
|
+
&& \
|
|
14
|
+
docker run -it \
|
|
15
|
+
--name qemu-aarch64-alpine \
|
|
16
|
+
-v ./:/app \
|
|
17
|
+
--platform linux/arm64 \
|
|
18
|
+
node:18-alpine
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
docker rm -f qemu-amd64-alpine \
|
|
23
|
+
&& \
|
|
24
|
+
docker run -it \
|
|
25
|
+
--platform linux/amd64 \
|
|
26
|
+
-v ./:/app \
|
|
27
|
+
--name qemu-amd64-alpine \
|
|
28
|
+
node:18-alpine
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# 3. go to ladybug source
|
|
33
|
+
|
|
34
|
+
cd /app/node_modules/@ladybugdb/core/lbug-source/tools/nodejs_api
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# 4. run ***yarn***
|
|
38
|
+
|
|
39
|
+
yarn install --no-cache
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# 5. install dependencies (alpine)
|
|
43
|
+
apk add --no-cache -X https://mirrors.aliyun.com/alpine/v3.21/main \
|
|
44
|
+
g++ \
|
|
45
|
+
gcompat \
|
|
46
|
+
libc6-compat \
|
|
47
|
+
build-base \
|
|
48
|
+
python3 \
|
|
49
|
+
libressl-dev \
|
|
50
|
+
make \
|
|
51
|
+
cmake \
|
|
52
|
+
zlib-dev \
|
|
53
|
+
musl-dev
|
|
54
|
+
|
|
55
|
+
# 5.1 install dependencies (ubuntu)
|
|
56
|
+
|
|
57
|
+
sudo apt update
|
|
58
|
+
sudo apt install -y \
|
|
59
|
+
g++ \
|
|
60
|
+
make \
|
|
61
|
+
cmake \
|
|
62
|
+
python3 \
|
|
63
|
+
libssl-dev \
|
|
64
|
+
zlib1g-dev \
|
|
65
|
+
musl-tools \
|
|
66
|
+
musl-dev \
|
|
67
|
+
gcc-aarch64-linux-gnu \
|
|
68
|
+
g++-aarch64-linux-gnu \
|
|
69
|
+
build-essential \
|
|
70
|
+
pkg-config \
|
|
71
|
+
wget \
|
|
72
|
+
curl
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# 6. yarn build
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
# 替换 build.js 文件中的 "THREADS =" 为 "THREADS = 2;//"
|
|
81
|
+
sed -i 's/THREADS =/THREADS = 2;\/\//' build.js
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
yarn build
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# 7. copy the lbugjs.node to lbugjs-alpine-arm64.node
|
|
90
|
+
cp -f /app/node_modules/@ladybugdb/core/lbug-source/tools/nodejs_api/build/lbugjs.node /app/node_modules/@ladybugdb/core/prebuilt/lbugjs-alpine-arm64.node
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Script that only compiles Ladybug extensions, supports LBUG_DIR environment variable
|
|
4
|
+
# apk add --no-cache openssl openssl-dev
|
|
5
|
+
APP_ROOT_DIR=$(cd $(dirname "${BASH_SOURCE[0]}")/..; pwd)
|
|
6
|
+
LBUG_SOURCE_DIR="$APP_ROOT_DIR/node_modules/@ladybugdb/core/lbug-source"
|
|
7
|
+
EXTENSION_DIR="${LBUG_SOURCE_DIR}/extension"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
SYSTEM="$(uname -o)"
|
|
11
|
+
if [ "$SYSTEM" = "Msys" ]; then
|
|
12
|
+
export MSYS2_ARG_CONV_EXCL="*"
|
|
13
|
+
echo "Msys"
|
|
14
|
+
APP_ROOT_DIR="$(cygpath -w $APP_ROOT_DIR)"
|
|
15
|
+
LBUG_SOURCE_DIR="$(cygpath -w $LBUG_SOURCE_DIR)"
|
|
16
|
+
EXTENSION_DIR="$(cygpath -w $EXTENSION_DIR)"
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
#EXTENSION_LIST="$(find "${EXTENSION_DIR}" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | grep -v '^duckdb$' | sort | tr '\n' ';' | sed 's/;$//')"
|
|
20
|
+
EXTENSION_LIST="httpfs;json;fts;vector;neo4j;algo"
|
|
21
|
+
echo "Automatically detected extension list: ${EXTENSION_LIST}"
|
|
22
|
+
|
|
23
|
+
if [ ! -f "${LBUG_SOURCE_DIR}/CMakeLists.txt" ] || [ ! -d "${LBUG_SOURCE_DIR}/extension" ]; then
|
|
24
|
+
echo "Error: Please run this script in the root directory of the ladybug repository, or set the LBUG_DIR environment variable to point to the ladybug source directory"
|
|
25
|
+
echo "Current LBUG_SOURCE_DIR: ${LBUG_SOURCE_DIR}"
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
BUILD_DIR="${LBUG_SOURCE_DIR}/build_extensions"
|
|
30
|
+
if [ ! -d "$BUILD_DIR" ]; then
|
|
31
|
+
mkdir "$BUILD_DIR"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
cd "$BUILD_DIR" || exit 1
|
|
35
|
+
|
|
36
|
+
# Check if already compiled, if so delete it
|
|
37
|
+
if [ -d "extension" ]; then
|
|
38
|
+
echo "Detected existing extension directory, deleting..."
|
|
39
|
+
rm -rf extension
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
echo "Configuring CMake to build only extensions..."
|
|
43
|
+
echo "Source directory: ${LBUG_SOURCE_DIR}"
|
|
44
|
+
cmake "${LBUG_SOURCE_DIR}" \
|
|
45
|
+
-DCMAKE_BUILD_TYPE=Release \
|
|
46
|
+
-DBUILD_EXTENSIONS="${EXTENSION_LIST}" \
|
|
47
|
+
-DOPENSSL_CRYPTO_LIBRARY=/usr/lib/libcrypto.so \
|
|
48
|
+
-DOPENSSL_SSL_LIBRARY=/usr/lib/libssl.so \
|
|
49
|
+
-DOPENSSL_USE_STATIC_LIBS=OFF \
|
|
50
|
+
-DBUILD_LBUG=FALSE
|
|
51
|
+
|
|
52
|
+
CORES=$(nproc --all)
|
|
53
|
+
echo "Using $CORES cores for compilation..."
|
|
54
|
+
|
|
55
|
+
# Use all target for compilation (more generic)
|
|
56
|
+
cmake --build . -- -j"$CORES"
|
|
57
|
+
|
|
58
|
+
echo "All extensions compiled successfully!"
|
|
59
|
+
|
|
60
|
+
#check cpu architecture
|
|
61
|
+
ARCH=$(uname -m)
|
|
62
|
+
if [ "$ARCH" = "x86_64" ]; then
|
|
63
|
+
echo "Detected x86_64 architecture"
|
|
64
|
+
ARCH="amd64"
|
|
65
|
+
elif [ "$ARCH" = "aarch64" ]; then
|
|
66
|
+
echo "Detected aarch64 architecture"
|
|
67
|
+
ARCH="arm64"
|
|
68
|
+
else
|
|
69
|
+
echo "Unsupported architecture: $ARCH"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
EXTENSION_DIST_DIR="${LBUG_SOURCE_DIR}/extension/alpine-${ARCH}"
|
|
74
|
+
mkdir -p $EXTENSION_DIST_DIR
|
|
75
|
+
find "${LBUG_SOURCE_DIR}/extension" -type f \( -path "*/build/*.lbug_extension" -o -path "*/build/*.kuzu_extension" \) -exec cp {} $EXTENSION_DIST_DIR \;
|
|
76
|
+
|
|
77
|
+
# find "/app/node_modules/@ladybugdb/core/lbug-source/extension" -type f -path "*/build/*.lbug_extension" -exec cp {} /app/extensions/alpine-amd64 \;
|
|
78
|
+
|
|
79
|
+
echo "All extensions have been copied to the $EXTENSION_DIST_DIR directory"
|