@nshiab/simple-data-analysis-core 2.0.5 → 2.0.6
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 +118 -12
- package/esm/class/Simple.d.ts +8 -2
- package/esm/class/Simple.d.ts.map +1 -1
- package/esm/class/Simple.js +9 -3
- package/esm/class/SimpleDB.d.ts +72 -1
- package/esm/class/SimpleDB.d.ts.map +1 -1
- package/esm/class/SimpleDB.js +81 -1
- package/esm/class/SimpleTable.d.ts +251 -274
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +248 -325
- package/esm/helpers/LogValue.d.ts +8 -0
- package/esm/helpers/LogValue.d.ts.map +1 -0
- package/esm/helpers/LogValue.js +23 -0
- package/esm/helpers/cacheTableDependencies.d.ts +9 -0
- package/esm/helpers/cacheTableDependencies.d.ts.map +1 -1
- package/esm/helpers/cacheTableDependencies.js +131 -21
- package/esm/helpers/cleanSQL.d.ts +1 -1
- package/esm/helpers/cleanSQL.d.ts.map +1 -1
- package/esm/helpers/cleanSQL.js +268 -23
- package/esm/helpers/flushAllTables.d.ts.map +1 -1
- package/esm/helpers/flushAllTables.js +23 -28
- package/esm/helpers/foldIdentifier.d.ts +3 -0
- package/esm/helpers/foldIdentifier.d.ts.map +1 -0
- package/esm/helpers/foldIdentifier.js +4 -0
- package/esm/helpers/geometryFromJSON.d.ts +3 -0
- package/esm/helpers/geometryFromJSON.d.ts.map +1 -0
- package/esm/helpers/geometryFromJSON.js +4 -0
- package/esm/helpers/index.d.ts +1 -0
- package/esm/helpers/index.d.ts.map +1 -1
- package/esm/helpers/index.js +1 -0
- package/esm/helpers/logData.d.ts.map +1 -1
- package/esm/helpers/logData.js +45 -44
- package/esm/helpers/makeLogConverter.d.ts +5 -0
- package/esm/helpers/makeLogConverter.d.ts.map +1 -0
- package/esm/helpers/makeLogConverter.js +64 -0
- package/esm/helpers/osmFiles.d.ts.map +1 -1
- package/esm/helpers/parseTypes.d.ts +1 -1
- package/esm/helpers/parseTypes.d.ts.map +1 -1
- package/esm/helpers/parseTypes.js +4 -0
- package/esm/helpers/pendingOps.d.ts +4 -2
- package/esm/helpers/pendingOps.d.ts.map +1 -1
- package/esm/helpers/prepareGeometry.d.ts +3 -0
- package/esm/helpers/prepareGeometry.d.ts.map +1 -0
- package/esm/helpers/prepareGeometry.js +99 -0
- package/esm/helpers/prepareJSON.d.ts +3 -0
- package/esm/helpers/prepareJSON.d.ts.map +1 -0
- package/esm/helpers/prepareJSON.js +50 -0
- package/esm/helpers/printTable.d.ts +5 -4
- package/esm/helpers/printTable.d.ts.map +1 -1
- package/esm/helpers/printTable.js +32 -36
- package/esm/helpers/queryDB.js +1 -1
- package/esm/helpers/queueAsyncBarrier.d.ts +4 -0
- package/esm/helpers/queueAsyncBarrier.d.ts.map +1 -1
- package/esm/helpers/queueAsyncBarrier.js +4 -0
- package/esm/helpers/queueOp.d.ts.map +1 -1
- package/esm/helpers/queueOp.js +5 -3
- package/esm/helpers/readMutationRows.d.ts +9 -0
- package/esm/helpers/readMutationRows.d.ts.map +1 -0
- package/esm/helpers/readMutationRows.js +94 -0
- package/esm/helpers/referencedTables.d.ts +9 -0
- package/esm/helpers/referencedTables.d.ts.map +1 -0
- package/esm/helpers/referencedTables.js +22 -0
- package/esm/helpers/runQuery.d.ts.map +1 -1
- package/esm/helpers/runQuery.js +11 -13
- package/esm/helpers/scanSQL.d.ts +7 -0
- package/esm/helpers/scanSQL.d.ts.map +1 -0
- package/esm/helpers/scanSQL.js +71 -0
- package/esm/helpers/tableRegistry.d.ts +2 -0
- package/esm/helpers/tableRegistry.d.ts.map +1 -1
- package/esm/helpers/tableRegistry.js +12 -4
- package/esm/helpers/updateColumnsWithJS.d.ts +52 -0
- package/esm/helpers/updateColumnsWithJS.d.ts.map +1 -0
- package/esm/helpers/updateColumnsWithJS.js +139 -0
- package/esm/methods/addColumn.d.ts +1 -1
- package/esm/methods/addColumn.d.ts.map +1 -1
- package/esm/methods/bm25.d.ts.map +1 -1
- package/esm/methods/bm25.js +1 -2
- package/esm/methods/cache.d.ts.map +1 -1
- package/esm/methods/cache.js +4 -6
- package/esm/methods/convert.d.ts +2 -2
- package/esm/methods/convert.d.ts.map +1 -1
- package/esm/methods/convert.js +5 -0
- package/esm/methods/getBottom.d.ts +1 -1
- package/esm/methods/getBottom.d.ts.map +1 -1
- package/esm/methods/getBottom.js +2 -2
- package/esm/methods/getData.d.ts +1 -1
- package/esm/methods/getData.d.ts.map +1 -1
- package/esm/methods/getData.js +2 -2
- package/esm/methods/join.d.ts.map +1 -1
- package/esm/methods/join.js +8 -16
- package/esm/methods/joinGeo.d.ts.map +1 -1
- package/esm/methods/joinGeo.js +10 -19
- package/esm/methods/loadArray.d.ts +1 -1
- package/esm/methods/loadArray.d.ts.map +1 -1
- package/esm/methods/loadArray.js +74 -19
- package/esm/methods/loadData.js +3 -0
- package/esm/methods/log.d.ts +7 -0
- package/esm/methods/log.d.ts.map +1 -0
- package/esm/methods/log.js +58 -0
- package/esm/methods/logBottom.d.ts +5 -0
- package/esm/methods/logBottom.d.ts.map +1 -0
- package/esm/methods/logBottom.js +9 -0
- package/esm/methods/removeTable.d.ts.map +1 -1
- package/esm/methods/removeTable.js +2 -0
- package/esm/methods/removeTables.d.ts.map +1 -1
- package/esm/methods/removeTables.js +7 -0
- package/esm/methods/renameTable.d.ts.map +1 -1
- package/esm/methods/renameTable.js +4 -0
- package/esm/methods/rowToText.js +2 -2
- package/esm/methods/selectTables.d.ts.map +1 -1
- package/esm/methods/selectTables.js +6 -0
- package/esm/methods/setTypes.d.ts +1 -1
- package/esm/methods/setTypes.d.ts.map +1 -1
- package/esm/methods/stream.d.ts.map +1 -1
- package/esm/methods/stream.js +2 -1
- package/esm/methods/updateWithJS.d.ts +1 -3
- package/esm/methods/updateWithJS.d.ts.map +1 -1
- package/esm/methods/updateWithJS.js +123 -37
- package/llm.md +337 -444
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/script/class/Simple.d.ts +8 -2
- package/script/class/Simple.d.ts.map +1 -1
- package/script/class/Simple.js +9 -3
- package/script/class/SimpleDB.d.ts +72 -1
- package/script/class/SimpleDB.d.ts.map +1 -1
- package/script/class/SimpleDB.js +81 -1
- package/script/class/SimpleTable.d.ts +251 -274
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +248 -325
- package/script/helpers/LogValue.d.ts +8 -0
- package/script/helpers/LogValue.d.ts.map +1 -0
- package/script/helpers/LogValue.js +26 -0
- package/script/helpers/cacheTableDependencies.d.ts +9 -0
- package/script/helpers/cacheTableDependencies.d.ts.map +1 -1
- package/script/helpers/cacheTableDependencies.js +170 -20
- package/script/helpers/cleanSQL.d.ts +1 -1
- package/script/helpers/cleanSQL.d.ts.map +1 -1
- package/script/helpers/cleanSQL.js +271 -23
- package/script/helpers/flushAllTables.d.ts.map +1 -1
- package/script/helpers/flushAllTables.js +24 -29
- package/script/helpers/foldIdentifier.d.ts +3 -0
- package/script/helpers/foldIdentifier.d.ts.map +1 -0
- package/script/helpers/foldIdentifier.js +7 -0
- package/script/helpers/geometryFromJSON.d.ts +3 -0
- package/script/helpers/geometryFromJSON.d.ts.map +1 -0
- package/script/helpers/geometryFromJSON.js +7 -0
- package/script/helpers/index.d.ts +1 -0
- package/script/helpers/index.d.ts.map +1 -1
- package/script/helpers/index.js +3 -1
- package/script/helpers/logData.d.ts.map +1 -1
- package/script/helpers/logData.js +45 -44
- package/script/helpers/makeLogConverter.d.ts +5 -0
- package/script/helpers/makeLogConverter.d.ts.map +1 -0
- package/script/helpers/makeLogConverter.js +70 -0
- package/script/helpers/osmFiles.d.ts.map +1 -1
- package/script/helpers/parseTypes.d.ts +1 -1
- package/script/helpers/parseTypes.d.ts.map +1 -1
- package/script/helpers/parseTypes.js +4 -0
- package/script/helpers/pendingOps.d.ts +4 -2
- package/script/helpers/pendingOps.d.ts.map +1 -1
- package/script/helpers/prepareGeometry.d.ts +3 -0
- package/script/helpers/prepareGeometry.d.ts.map +1 -0
- package/script/helpers/prepareGeometry.js +102 -0
- package/script/helpers/prepareJSON.d.ts +3 -0
- package/script/helpers/prepareJSON.d.ts.map +1 -0
- package/script/helpers/prepareJSON.js +53 -0
- package/script/helpers/printTable.d.ts +5 -4
- package/script/helpers/printTable.d.ts.map +1 -1
- package/script/helpers/printTable.js +32 -36
- package/script/helpers/queryDB.js +1 -1
- package/script/helpers/queueAsyncBarrier.d.ts +4 -0
- package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
- package/script/helpers/queueAsyncBarrier.js +4 -0
- package/script/helpers/queueOp.d.ts.map +1 -1
- package/script/helpers/queueOp.js +4 -2
- package/script/helpers/readMutationRows.d.ts +9 -0
- package/script/helpers/readMutationRows.d.ts.map +1 -0
- package/script/helpers/readMutationRows.js +97 -0
- package/script/helpers/referencedTables.d.ts +9 -0
- package/script/helpers/referencedTables.d.ts.map +1 -0
- package/script/helpers/referencedTables.js +28 -0
- package/script/helpers/runQuery.d.ts.map +1 -1
- package/script/helpers/runQuery.js +11 -13
- package/script/helpers/scanSQL.d.ts +7 -0
- package/script/helpers/scanSQL.d.ts.map +1 -0
- package/script/helpers/scanSQL.js +74 -0
- package/script/helpers/tableRegistry.d.ts +2 -0
- package/script/helpers/tableRegistry.d.ts.map +1 -1
- package/script/helpers/tableRegistry.js +16 -4
- package/script/helpers/updateColumnsWithJS.d.ts +52 -0
- package/script/helpers/updateColumnsWithJS.d.ts.map +1 -0
- package/script/helpers/updateColumnsWithJS.js +145 -0
- package/script/methods/addColumn.d.ts +1 -1
- package/script/methods/addColumn.d.ts.map +1 -1
- package/script/methods/bm25.d.ts.map +1 -1
- package/script/methods/bm25.js +1 -2
- package/script/methods/cache.d.ts.map +1 -1
- package/script/methods/cache.js +3 -5
- package/script/methods/convert.d.ts +2 -2
- package/script/methods/convert.d.ts.map +1 -1
- package/script/methods/convert.js +5 -0
- package/script/methods/getBottom.d.ts +1 -1
- package/script/methods/getBottom.d.ts.map +1 -1
- package/script/methods/getBottom.js +2 -2
- package/script/methods/getData.d.ts +1 -1
- package/script/methods/getData.d.ts.map +1 -1
- package/script/methods/getData.js +2 -2
- package/script/methods/join.d.ts.map +1 -1
- package/script/methods/join.js +8 -16
- package/script/methods/joinGeo.d.ts.map +1 -1
- package/script/methods/joinGeo.js +10 -19
- package/script/methods/loadArray.d.ts +1 -1
- package/script/methods/loadArray.d.ts.map +1 -1
- package/script/methods/loadArray.js +74 -19
- package/script/methods/loadData.js +3 -0
- package/script/methods/log.d.ts +7 -0
- package/script/methods/log.d.ts.map +1 -0
- package/script/methods/log.js +64 -0
- package/script/methods/logBottom.d.ts +5 -0
- package/script/methods/logBottom.d.ts.map +1 -0
- package/script/methods/logBottom.js +15 -0
- package/script/methods/removeTable.d.ts.map +1 -1
- package/script/methods/removeTable.js +2 -0
- package/script/methods/removeTables.d.ts.map +1 -1
- package/script/methods/removeTables.js +7 -0
- package/script/methods/renameTable.d.ts.map +1 -1
- package/script/methods/renameTable.js +4 -0
- package/script/methods/rowToText.js +2 -2
- package/script/methods/selectTables.d.ts.map +1 -1
- package/script/methods/selectTables.js +6 -0
- package/script/methods/setTypes.d.ts +1 -1
- package/script/methods/setTypes.d.ts.map +1 -1
- package/script/methods/stream.d.ts.map +1 -1
- package/script/methods/stream.js +2 -1
- package/script/methods/updateWithJS.d.ts +1 -3
- package/script/methods/updateWithJS.d.ts.map +1 -1
- package/script/methods/updateWithJS.js +122 -36
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printTable.d.ts","sourceRoot":"","sources":["../../src/helpers/printTable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"printTable.d.ts","sourceRoot":"","sources":["../../src/helpers/printTable.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,EAClC,OAAO,CAAC,EAAE;IACR,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,IAAI,CAgNN"}
|
|
@@ -4,18 +4,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.default = printTable;
|
|
7
|
+
const LogValue_js_1 = __importDefault(require("./LogValue.js"));
|
|
7
8
|
const wrapString_js_1 = __importDefault(require("./wrapString.js"));
|
|
8
9
|
/**
|
|
9
10
|
* Prints a formatted table to the console with support for word wrapping
|
|
10
|
-
* within cells. Unlike `console.table()`, this function properly
|
|
11
|
-
* multi-line content
|
|
12
|
-
*
|
|
11
|
+
* within headers and cells. Unlike `console.table()`, this function properly
|
|
12
|
+
* handles multi-line content, making it ideal for displaying data with long
|
|
13
|
+
* column names and text values.
|
|
13
14
|
*
|
|
14
15
|
* @param data - An array of objects representing the rows of the table. Each
|
|
15
16
|
* object should have string keys.
|
|
16
17
|
* @param options - Optional configuration for table rendering.
|
|
17
18
|
* @param options.maxColumnWidth - The maximum width for any column (default:
|
|
18
|
-
* `75`).
|
|
19
|
+
* `75`). Headers and values exceeding this width will be wrapped at word
|
|
20
|
+
* boundaries.
|
|
19
21
|
* @param options.minColumnWidth - The minimum width for any column (default:
|
|
20
22
|
* `3`).
|
|
21
23
|
* @param options.typesRowIndex - The index of a row that contains type
|
|
@@ -53,8 +55,12 @@ function printTable(data, options) {
|
|
|
53
55
|
const minColumnWidth = options?.minColumnWidth ?? 3;
|
|
54
56
|
// Helper function to format values for display
|
|
55
57
|
const formatValue = (value) => {
|
|
58
|
+
if (value instanceof LogValue_js_1.default)
|
|
59
|
+
return value.text;
|
|
56
60
|
if (value instanceof Date) {
|
|
57
|
-
return value.
|
|
61
|
+
return Number.isNaN(value.getTime())
|
|
62
|
+
? "Invalid Date"
|
|
63
|
+
: value.toISOString();
|
|
58
64
|
}
|
|
59
65
|
return String(value);
|
|
60
66
|
};
|
|
@@ -68,7 +74,7 @@ function printTable(data, options) {
|
|
|
68
74
|
// First, seed widths from header names.
|
|
69
75
|
const columnWidths = {};
|
|
70
76
|
for (const col of columns) {
|
|
71
|
-
columnWidths[col] = col.length;
|
|
77
|
+
columnWidths[col] = Math.max(...col.split("\n").map((line) => line.length));
|
|
72
78
|
}
|
|
73
79
|
// Format every cell, track the longest raw line per column, and
|
|
74
80
|
// store the formatted strings for the wrapping step that follows.
|
|
@@ -96,31 +102,16 @@ function printTable(data, options) {
|
|
|
96
102
|
for (const col of columns) {
|
|
97
103
|
columnWidths[col] = Math.min(Math.max(columnWidths[col], minColumnWidth), maxColumnWidth);
|
|
98
104
|
}
|
|
99
|
-
//
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const allWrappedLines = [];
|
|
110
|
-
for (const line of lines) {
|
|
111
|
-
if (line.length <= width) {
|
|
112
|
-
allWrappedLines.push(line);
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
// Wrap long lines at word boundaries
|
|
116
|
-
const wrapped = (0, wrapString_js_1.default)(line, width);
|
|
117
|
-
allWrappedLines.push(...wrapped.split("\n"));
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
wrappedRow[col] = allWrappedLines.length > 0 ? allWrappedLines : [""];
|
|
121
|
-
}
|
|
122
|
-
wrappedData.push(wrappedRow);
|
|
123
|
-
}
|
|
105
|
+
// Use the same newline and word wrapping rules for headers and cells.
|
|
106
|
+
const wrapCell = (value, width) => {
|
|
107
|
+
const lines = value.split("\n").flatMap((line) => line.length <= width ? [line] : (0, wrapString_js_1.default)(line, width).split("\n"));
|
|
108
|
+
return lines.length > 0 ? lines : [""];
|
|
109
|
+
};
|
|
110
|
+
const wrappedHeaders = columns.map((col) => wrapCell(col, columnWidths[col]));
|
|
111
|
+
const wrappedData = formattedData.map((row) => Object.fromEntries(columns.map((col, c) => [
|
|
112
|
+
col,
|
|
113
|
+
wrapCell(row[c], columnWidths[col]),
|
|
114
|
+
])));
|
|
124
115
|
// ANSI color codes (matching Deno's console colors)
|
|
125
116
|
const colors = {
|
|
126
117
|
reset: "\x1b[0m",
|
|
@@ -136,6 +127,8 @@ function printTable(data, options) {
|
|
|
136
127
|
const getColorForValue = (value, isTypeRow) => {
|
|
137
128
|
if (isTypeRow)
|
|
138
129
|
return colors.grey;
|
|
130
|
+
if (value instanceof LogValue_js_1.default)
|
|
131
|
+
return colors[value.category];
|
|
139
132
|
if (value === null || value === undefined)
|
|
140
133
|
return colors.null;
|
|
141
134
|
if (value instanceof Date)
|
|
@@ -163,11 +156,14 @@ function printTable(data, options) {
|
|
|
163
156
|
};
|
|
164
157
|
// Print top border
|
|
165
158
|
console.log(createTopBorder());
|
|
166
|
-
// Print header
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
headerParts.
|
|
170
|
-
colors.reset
|
|
159
|
+
// Print each header line in bold, padding shorter headers to the same height.
|
|
160
|
+
const headerHeight = Math.max(...wrappedHeaders.map((lines) => lines.length));
|
|
161
|
+
for (let lineIdx = 0; lineIdx < headerHeight; lineIdx++) {
|
|
162
|
+
const headerParts = columns.map((col, c) => ` ${colors.bold}${pad(wrappedHeaders[c][lineIdx] ?? "", columnWidths[col])}${colors.reset} `);
|
|
163
|
+
console.log(colors.grey + "│" + colors.reset +
|
|
164
|
+
headerParts.join(colors.grey + "│" + colors.reset) + colors.grey + "│" +
|
|
165
|
+
colors.reset);
|
|
166
|
+
}
|
|
171
167
|
// Detect if any row has word wrapping (spans multiple lines)
|
|
172
168
|
let hasWordWrapping = false;
|
|
173
169
|
for (const wrappedRow of wrappedData) {
|
|
@@ -66,7 +66,7 @@ async function queryDB(simple, query, options) {
|
|
|
66
66
|
// operations queued by sync builder methods, preserving program order.
|
|
67
67
|
await (0, flushAllTables_js_1.default)(simple instanceof SimpleTable_js_1.default ? simple.sdb : simple);
|
|
68
68
|
if (options.noClean !== true) {
|
|
69
|
-
query = (0, cleanSQL_js_1.default)(query);
|
|
69
|
+
query = (0, cleanSQL_js_1.default)(query, sdb.expressionSyntax);
|
|
70
70
|
}
|
|
71
71
|
const executionOptions = {
|
|
72
72
|
...options,
|
|
@@ -11,6 +11,10 @@ import type SimpleTable from "../class/SimpleTable.js";
|
|
|
11
11
|
* drained are discarded. Operations drained by an observer inside `execute`
|
|
12
12
|
* remain applied; an asynchronous barrier does not provide database rollback.
|
|
13
13
|
*
|
|
14
|
+
* This differs from a failure while executing queued builders: during replay,
|
|
15
|
+
* the failing table's remaining chain is aborted, but unexecuted work for other
|
|
16
|
+
* tables is requeued for their next observation.
|
|
17
|
+
*
|
|
14
18
|
* @param simpleTable - The table whose chain owns the asynchronous work.
|
|
15
19
|
* @param operation - The asynchronous extension operation to queue.
|
|
16
20
|
* @param operation.method - The public method name used for diagnostics.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queueAsyncBarrier.d.ts","sourceRoot":"","sources":["../../src/helpers/queueAsyncBarrier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD
|
|
1
|
+
{"version":3,"file":"queueAsyncBarrier.d.ts","sourceRoot":"","sources":["../../src/helpers/queueAsyncBarrier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE;IACT,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,GACA,IAAI,CAKN"}
|
|
@@ -17,6 +17,10 @@ const queueOp_js_1 = __importDefault(require("./queueOp.js"));
|
|
|
17
17
|
* drained are discarded. Operations drained by an observer inside `execute`
|
|
18
18
|
* remain applied; an asynchronous barrier does not provide database rollback.
|
|
19
19
|
*
|
|
20
|
+
* This differs from a failure while executing queued builders: during replay,
|
|
21
|
+
* the failing table's remaining chain is aborted, but unexecuted work for other
|
|
22
|
+
* tables is requeued for their next observation.
|
|
23
|
+
*
|
|
20
24
|
* @param simpleTable - The table whose chain owns the asynchronous work.
|
|
21
25
|
* @param operation - The asynchronous extension operation to queue.
|
|
22
26
|
* @param operation.method - The public method name used for diagnostics.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queueOp.d.ts","sourceRoot":"","sources":["../../src/helpers/queueOp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"queueOp.d.ts","sourceRoot":"","sources":["../../src/helpers/queueOp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAWtD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAC7B,WAAW,EAAE,WAAW,EACxB,EAAE,EAAE,cAAc,GACjB,IAAI,CAgDN;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,QAAQ,GACZ;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAa7C"}
|
|
@@ -12,14 +12,15 @@ const asyncOperationContext_js_1 = require("./asyncOperationContext.js");
|
|
|
12
12
|
* @internal
|
|
13
13
|
*/
|
|
14
14
|
function queueOp(simpleTable, op) {
|
|
15
|
+
(0, cacheTableDependencies_js_1.assertCacheTableMutation)(simpleTable);
|
|
15
16
|
const sdb = simpleTable.sdb;
|
|
16
17
|
if (sdb.lifecycleState !== "open") {
|
|
17
18
|
throw new Error(`${op.method} cannot queue work because its SimpleDB is ${sdb.lifecycleState}.`);
|
|
18
19
|
}
|
|
19
|
-
let capturedOp = {
|
|
20
|
+
let capturedOp = (0, cacheTableDependencies_js_1.captureCacheTableOperation)({
|
|
20
21
|
...op,
|
|
21
22
|
parameters: op.parameters === null ? null : structuredClone(op.parameters),
|
|
22
|
-
};
|
|
23
|
+
});
|
|
23
24
|
if (capturedOp.kind === "fusable" || capturedOp.kind === "source") {
|
|
24
25
|
capturedOp = {
|
|
25
26
|
...capturedOp,
|
|
@@ -48,6 +49,7 @@ function queueOp(simpleTable, op) {
|
|
|
48
49
|
...capturedOp,
|
|
49
50
|
sequence: sdb.opSequence++,
|
|
50
51
|
};
|
|
52
|
+
(0, cacheTableDependencies_js_1.recordCacheTableOperation)(simpleTable, queuedOp);
|
|
51
53
|
if ((0, asyncOperationContext_js_1.captureAsyncOperation)(sdb, { table: simpleTable, op: queuedOp })) {
|
|
52
54
|
return;
|
|
53
55
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type DuckDBConnection, type DuckDBType, type DuckDBValue } from "@duckdb/node-api";
|
|
2
|
+
/** Reads mutation values, optionally keeping a pagination cursor out of rows. */
|
|
3
|
+
export default function readMutationRows(connection: DuckDBConnection, query: string, cursorColumn?: string): Promise<{
|
|
4
|
+
rows: Record<string, unknown>[];
|
|
5
|
+
types: Map<string, DuckDBType>;
|
|
6
|
+
lastCursorValue: DuckDBValue | undefined;
|
|
7
|
+
toNative: (value: unknown, type: DuckDBType) => DuckDBValue;
|
|
8
|
+
}>;
|
|
9
|
+
//# sourceMappingURL=readMutationRows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readMutationRows.d.ts","sourceRoot":"","sources":["../../src/helpers/readMutationRows.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EAKrB,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAC;AAE1B,iFAAiF;AACjF,wBAA8B,gBAAgB,CAC5C,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM;;;;sBAwDI,OAAO,QAAQ,UAAU,KAAG,WAAW;GA0DjE"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = readMutationRows;
|
|
4
|
+
const node_api_1 = require("@duckdb/node-api");
|
|
5
|
+
/** Reads mutation values, optionally keeping a pagination cursor out of rows. */
|
|
6
|
+
async function readMutationRows(connection, query, cursorColumn) {
|
|
7
|
+
const result = await connection.run(query);
|
|
8
|
+
const names = result.deduplicatedColumnNames();
|
|
9
|
+
const types = result.columnTypes();
|
|
10
|
+
const cursorIndex = cursorColumn === undefined
|
|
11
|
+
? -1
|
|
12
|
+
: names.indexOf(cursorColumn);
|
|
13
|
+
let lastCursorValue;
|
|
14
|
+
const dates = new WeakMap();
|
|
15
|
+
const convert = (value) => {
|
|
16
|
+
if (value instanceof node_api_1.DuckDBDateValue || value instanceof node_api_1.DuckDBTimestampValue) {
|
|
17
|
+
const millis = value instanceof node_api_1.DuckDBDateValue
|
|
18
|
+
? value.days * 86400000
|
|
19
|
+
: Number(value.micros >= 0n
|
|
20
|
+
? value.micros / 1000n
|
|
21
|
+
: (value.micros - 999n) / 1000n);
|
|
22
|
+
const date = new Date(millis);
|
|
23
|
+
// Infinite/out-of-range dates retain their native representation.
|
|
24
|
+
if (!Number.isFinite(date.getTime()))
|
|
25
|
+
return value;
|
|
26
|
+
dates.set(date, { millis, value });
|
|
27
|
+
return date;
|
|
28
|
+
}
|
|
29
|
+
if (value instanceof node_api_1.DuckDBArrayValue || value instanceof node_api_1.DuckDBListValue) {
|
|
30
|
+
return value.items.map(convert);
|
|
31
|
+
}
|
|
32
|
+
if (value instanceof node_api_1.DuckDBStructValue) {
|
|
33
|
+
return Object.fromEntries(Object.entries(value.entries).map(([key, item]) => [key, convert(item)]));
|
|
34
|
+
}
|
|
35
|
+
// In particular, decimals and high-resolution temporal values stay native.
|
|
36
|
+
return value;
|
|
37
|
+
};
|
|
38
|
+
const rows = [];
|
|
39
|
+
while (true) {
|
|
40
|
+
const chunk = await result.fetchChunk();
|
|
41
|
+
if (!chunk || chunk.rowCount === 0)
|
|
42
|
+
break;
|
|
43
|
+
const offset = rows.length;
|
|
44
|
+
for (let i = 0; i < chunk.rowCount; i++)
|
|
45
|
+
rows.push({});
|
|
46
|
+
for (let i = 0; i < names.length; i++) {
|
|
47
|
+
if (i === cursorIndex) {
|
|
48
|
+
lastCursorValue = chunk.getColumnVector(i).getItem(chunk.rowCount - 1);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
chunk.visitColumnValues(i, (value, row) => {
|
|
52
|
+
rows[offset + row][names[i]] = convert(value);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const toNative = (value, type) => {
|
|
57
|
+
if (value === null || value === undefined)
|
|
58
|
+
return null;
|
|
59
|
+
if (value instanceof Date) {
|
|
60
|
+
const original = dates.get(value);
|
|
61
|
+
if (original && value.getTime() === original.millis &&
|
|
62
|
+
type.toString() ===
|
|
63
|
+
(original.value instanceof node_api_1.DuckDBDateValue ? "DATE" : "TIMESTAMP")) {
|
|
64
|
+
return original.value;
|
|
65
|
+
}
|
|
66
|
+
if (type.toString() === "DATE") {
|
|
67
|
+
if (value.getTime() % 86400000 !== 0) {
|
|
68
|
+
throw new Error("DATE values must represent midnight UTC.");
|
|
69
|
+
}
|
|
70
|
+
return new node_api_1.DuckDBDateValue(value.getTime() / 86400000);
|
|
71
|
+
}
|
|
72
|
+
return new node_api_1.DuckDBTimestampValue(BigInt(value.getTime()) * 1000n);
|
|
73
|
+
}
|
|
74
|
+
if (Array.isArray(value) && "valueType" in type) {
|
|
75
|
+
if ("length" in type && value.length !== type.length) {
|
|
76
|
+
throw new Error(`Expected ${type.length} array elements for ${type}.`);
|
|
77
|
+
}
|
|
78
|
+
const items = value.map((item) => toNative(item, type.valueType));
|
|
79
|
+
return "length" in type
|
|
80
|
+
? new node_api_1.DuckDBArrayValue(items)
|
|
81
|
+
: new node_api_1.DuckDBListValue(items);
|
|
82
|
+
}
|
|
83
|
+
if (typeof value === "object" && "entryNames" in type && "entryTypes" in type) {
|
|
84
|
+
return new node_api_1.DuckDBStructValue(Object.fromEntries(type.entryNames.map((name, i) => [
|
|
85
|
+
name,
|
|
86
|
+
toNative(value[name], type.entryTypes[i]),
|
|
87
|
+
])));
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
};
|
|
91
|
+
return {
|
|
92
|
+
rows,
|
|
93
|
+
types: new Map(names.flatMap((name, i) => i === cursorIndex ? [] : [[name, types[i]]])),
|
|
94
|
+
lastCursorValue,
|
|
95
|
+
toNative,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type SimpleDB from "../class/SimpleDB.js";
|
|
2
|
+
import type SimpleTable from "../class/SimpleTable.js";
|
|
3
|
+
/**
|
|
4
|
+
* Finds registered table identifiers in SQL, excluding literals and comments.
|
|
5
|
+
* Matching is conservative: column names and aliases also count as references.
|
|
6
|
+
* DuckDB folds ASCII letters in both quoted and unquoted identifiers.
|
|
7
|
+
*/
|
|
8
|
+
export default function referencedTables(sql: readonly string[], sdb: SimpleDB): SimpleTable[];
|
|
9
|
+
//# sourceMappingURL=referencedTables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"referencedTables.d.ts","sourceRoot":"","sources":["../../src/helpers/referencedTables.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAKvD;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,GAAG,EAAE,SAAS,MAAM,EAAE,EACtB,GAAG,EAAE,QAAQ,GACZ,WAAW,EAAE,CAkBf"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = referencedTables;
|
|
7
|
+
const scanSQL_js_1 = __importDefault(require("./scanSQL.js"));
|
|
8
|
+
const foldIdentifier_js_1 = __importDefault(require("./foldIdentifier.js"));
|
|
9
|
+
const tableRegistry_js_1 = require("./tableRegistry.js");
|
|
10
|
+
/**
|
|
11
|
+
* Finds registered table identifiers in SQL, excluding literals and comments.
|
|
12
|
+
* Matching is conservative: column names and aliases also count as references.
|
|
13
|
+
* DuckDB folds ASCII letters in both quoted and unquoted identifiers.
|
|
14
|
+
*/
|
|
15
|
+
function referencedTables(sql, sdb) {
|
|
16
|
+
const identifiers = new Set();
|
|
17
|
+
for (const fragment of sql) {
|
|
18
|
+
for (const token of (0, scanSQL_js_1.default)(fragment)) {
|
|
19
|
+
if (token.kind === "quoted" && token.text.startsWith('"')) {
|
|
20
|
+
identifiers.add((0, foldIdentifier_js_1.default)(token.text.slice(1, -1).replaceAll('""', '"')));
|
|
21
|
+
}
|
|
22
|
+
else if (token.kind === "sql" && /^[\p{L}_][\p{L}\p{N}_$]*$/u.test(token.text)) {
|
|
23
|
+
identifiers.add((0, foldIdentifier_js_1.default)(token.text));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return (0, tableRegistry_js_1.getRegisteredTables)(sdb).filter((table) => identifiers.has((0, foldIdentifier_js_1.default)(table.name)));
|
|
28
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runQuery.d.ts","sourceRoot":"","sources":["../../src/helpers/runQuery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runQuery.d.ts","sourceRoot":"","sources":["../../src/helpers/runQuery.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAIrB,KAAK,UAAU,EAEf,KAAK,WAAW,EAIjB,MAAM,kBAAkB,CAAC;AAI1B,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AA8CF,wBAAgB,aAAa,CAC3B,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAM,GAAG,IAAW,GAC9B,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAoCjC;AAED,wBAA8B,QAAQ,CACpC,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,gBAAgB,EAC5B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,eAAe,GACvB,OAAO,CACN;IACA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,EAAE,GACD,IAAI,CACP,CAoEA"}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.makeConverter = makeConverter;
|
|
7
7
|
exports.default = runQuery;
|
|
8
|
+
const makeLogConverter_js_1 = __importDefault(require("./makeLogConverter.js"));
|
|
8
9
|
const quoteIdentifier_js_1 = __importDefault(require("./quoteIdentifier.js"));
|
|
9
10
|
const node_api_1 = require("@duckdb/node-api");
|
|
10
11
|
const SDAError_js_1 = __importDefault(require("../class/SDAError.js"));
|
|
@@ -12,20 +13,14 @@ const observeQuery_js_1 = __importDefault(require("./observeQuery.js"));
|
|
|
12
13
|
const msPerDay = 24 * 60 * 60 * 1000;
|
|
13
14
|
const maxSafeInteger = BigInt(Number.MAX_SAFE_INTEGER);
|
|
14
15
|
const minSafeInteger = BigInt(Number.MIN_SAFE_INTEGER);
|
|
15
|
-
// Columns already warned about for precision loss (keyed by table and
|
|
16
|
-
// column), so each column warns only once.
|
|
17
|
-
const warnedUnsafeIntegerColumns = new Set();
|
|
18
16
|
function makeIntegerConverter(columnName, tableName) {
|
|
19
|
-
const warnKey = `${tableName ?? ""}\0${columnName}`;
|
|
20
17
|
return (value) => {
|
|
21
18
|
if (value === null) {
|
|
22
19
|
return null;
|
|
23
20
|
}
|
|
24
21
|
const bigintValue = value;
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
warnedUnsafeIntegerColumns.add(warnKey);
|
|
28
|
-
console.warn(`SDA: Column ${(0, quoteIdentifier_js_1.default)(columnName)}${tableName === null ? "" : ` of table ${(0, quoteIdentifier_js_1.default)(tableName)}`} has at least one value exceeding Number.MAX_SAFE_INTEGER. Converted numbers may lose precision.`);
|
|
22
|
+
if (bigintValue > maxSafeInteger || bigintValue < minSafeInteger) {
|
|
23
|
+
throw new RangeError(`SDA: Column ${(0, quoteIdentifier_js_1.default)(columnName)}${tableName === null ? "" : ` of table ${(0, quoteIdentifier_js_1.default)(tableName)}`} contains ${bigintValue} outside JavaScript's safe integer range (Number.MIN_SAFE_INTEGER to Number.MAX_SAFE_INTEGER). Cast the column to VARCHAR to retrieve exact digits.`);
|
|
29
24
|
}
|
|
30
25
|
return Number(bigintValue);
|
|
31
26
|
};
|
|
@@ -48,10 +43,6 @@ function makeConverter(type, columnName, tableName = null) {
|
|
|
48
43
|
const placeholder = `GEOM(${typeString.replace("GEOMETRY('", "").replace("')", "")})`;
|
|
49
44
|
return (value) => (value === null ? null : placeholder);
|
|
50
45
|
}
|
|
51
|
-
if (typeString.includes("FLOAT[")) {
|
|
52
|
-
const placeholder = `<${typeString}>`;
|
|
53
|
-
return (value) => (value === null ? null : placeholder);
|
|
54
|
-
}
|
|
55
46
|
switch (type.typeId) {
|
|
56
47
|
case node_api_1.DuckDBTypeId.DATE:
|
|
57
48
|
return (value) => value === null
|
|
@@ -72,6 +63,8 @@ function makeConverter(type, columnName, tableName = null) {
|
|
|
72
63
|
return utcTimestampTzValue;
|
|
73
64
|
case node_api_1.DuckDBTypeId.BIGINT:
|
|
74
65
|
case node_api_1.DuckDBTypeId.HUGEINT:
|
|
66
|
+
case node_api_1.DuckDBTypeId.UBIGINT:
|
|
67
|
+
case node_api_1.DuckDBTypeId.UHUGEINT:
|
|
75
68
|
return makeIntegerConverter(columnName, tableName);
|
|
76
69
|
default:
|
|
77
70
|
return (value) => utcJsonValueConverter(value, type, utcJsonValueConverter);
|
|
@@ -91,7 +84,12 @@ async function runQuery(query, connection, returnData, options) {
|
|
|
91
84
|
columnTypes.some((type) => type.toString().toLowerCase().includes("geometry"))) {
|
|
92
85
|
throw new Error("The query returns geometry columns. Use getGeoData() instead.");
|
|
93
86
|
}
|
|
94
|
-
const
|
|
87
|
+
const logging = options.method === "log()" ||
|
|
88
|
+
options.method === "logBottom()";
|
|
89
|
+
const converters = columnTypes.map((type, i) => {
|
|
90
|
+
const converter = makeConverter(type, columnNames[i], options.table ?? null);
|
|
91
|
+
return logging ? (0, makeLogConverter_js_1.default)(type, converter) : converter;
|
|
92
|
+
});
|
|
95
93
|
const columnCount = columnNames.length;
|
|
96
94
|
// The result is converted chunk by chunk, so no intermediate row-major
|
|
97
95
|
// copy of the whole result is materialized.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanSQL.d.ts","sourceRoot":"","sources":["../../src/helpers/scanSQL.ts"],"names":[],"mappings":"AAAA,KAAK,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAA;CAAE,CAAC;AAIjE,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,CA0DtD"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = scanSQL;
|
|
4
|
+
// Keep opaque SQL regions byte-for-byte intact. Only SQL tokens participate in
|
|
5
|
+
// normalization; parameter values never enter this module.
|
|
6
|
+
function scanSQL(query) {
|
|
7
|
+
const tokens = [];
|
|
8
|
+
let i = 0;
|
|
9
|
+
while (i < query.length) {
|
|
10
|
+
const start = i;
|
|
11
|
+
let kind = "sql";
|
|
12
|
+
const rest = query.slice(i);
|
|
13
|
+
if (/\s/.test(query[i])) {
|
|
14
|
+
kind = "trivia";
|
|
15
|
+
while (i < query.length && /\s/.test(query[i]))
|
|
16
|
+
i++;
|
|
17
|
+
}
|
|
18
|
+
else if (rest.startsWith("--")) {
|
|
19
|
+
kind = "trivia";
|
|
20
|
+
while (i < query.length && !/[\r\n]/.test(query[i]))
|
|
21
|
+
i++;
|
|
22
|
+
}
|
|
23
|
+
else if (rest.startsWith("/*")) {
|
|
24
|
+
kind = "trivia";
|
|
25
|
+
i += 2;
|
|
26
|
+
let depth = 1;
|
|
27
|
+
while (i < query.length && depth > 0) {
|
|
28
|
+
if (query.startsWith("/*", i)) {
|
|
29
|
+
depth++;
|
|
30
|
+
i += 2;
|
|
31
|
+
}
|
|
32
|
+
else if (query.startsWith("*/", i)) {
|
|
33
|
+
depth--;
|
|
34
|
+
i += 2;
|
|
35
|
+
}
|
|
36
|
+
else
|
|
37
|
+
i++;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
else if (/^[eE]'/.test(rest) || query[i] === "'" || query[i] === '"') {
|
|
41
|
+
kind = "quoted";
|
|
42
|
+
const escaped = /^[eE]'/.test(rest);
|
|
43
|
+
if (escaped)
|
|
44
|
+
i++;
|
|
45
|
+
const quote = query[i++];
|
|
46
|
+
while (i < query.length) {
|
|
47
|
+
if (escaped && query[i] === "\\")
|
|
48
|
+
i = Math.min(i + 2, query.length);
|
|
49
|
+
else if (query[i++] === quote) {
|
|
50
|
+
if (query[i] === quote)
|
|
51
|
+
i++;
|
|
52
|
+
else
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// DuckDB permits non-ASCII characters in dollar tags, including
|
|
59
|
+
// combining marks and characters outside the Unicode letter categories.
|
|
60
|
+
const dollar = rest.match(/^\$(?:[A-Za-z_\u0080-\uFFFF][A-Za-z_0-9\u0080-\uFFFF]*)?\$/)?.[0];
|
|
61
|
+
if (dollar) {
|
|
62
|
+
kind = "quoted";
|
|
63
|
+
const end = query.indexOf(dollar, i + dollar.length);
|
|
64
|
+
i = end === -1 ? query.length : end + dollar.length;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const token = rest.match(/^(?:[\p{L}_][\p{L}\p{N}_$]*|\$(?:[0-9]+|[\p{L}_][\p{L}\p{N}_]*)|!==|===|==|!=|<>|<=|>=|&&|\|\||::)/u)?.[0];
|
|
68
|
+
i += token?.length ?? 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
tokens.push({ text: query.slice(start, i), kind });
|
|
72
|
+
}
|
|
73
|
+
return tokens;
|
|
74
|
+
}
|
|
@@ -5,5 +5,7 @@ export declare function getRegisteredTables<Table extends SimpleTable>(simpleDB:
|
|
|
5
5
|
export declare function listRegisteredTables<Table extends SimpleTable>(simpleDB: SimpleDB<Table>): readonly Table[];
|
|
6
6
|
export declare function registerTable<Table extends SimpleTable>(simpleDB: SimpleDB<Table>, table: Table): void;
|
|
7
7
|
export declare function ensureTableRegistered<Table extends SimpleTable>(simpleDB: SimpleDB<Table>, table: Table): void;
|
|
8
|
+
/** Prevents distinct handles from owning the same DuckDB table name. */
|
|
9
|
+
export declare function assertTableNameAvailable(simpleDB: SimpleDB, name: string, renamedTable?: SimpleTable): void;
|
|
8
10
|
export declare function retainRegisteredTables<Table extends SimpleTable>(simpleDB: SimpleDB<Table>, predicate: (table: Table) => boolean): void;
|
|
9
11
|
//# sourceMappingURL=tableRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tableRegistry.d.ts","sourceRoot":"","sources":["../../src/helpers/tableRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"tableRegistry.d.ts","sourceRoot":"","sources":["../../src/helpers/tableRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAiBvD,wBAAgB,uBAAuB,CAAC,KAAK,SAAS,WAAW,EAC/D,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,GACxB,IAAI,CAEN;AAED,wBAAgB,mBAAmB,CAAC,KAAK,SAAS,WAAW,EAC3D,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,GACxB,SAAS,KAAK,EAAE,CAElB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,SAAS,WAAW,EAC5D,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,GACxB,SAAS,KAAK,EAAE,CAElB;AAED,wBAAgB,aAAa,CAAC,KAAK,SAAS,WAAW,EACrD,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,EACzB,KAAK,EAAE,KAAK,GACX,IAAI,CAYN;AAED,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,WAAW,EAC7D,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,EACzB,KAAK,EAAE,KAAK,GACX,IAAI,CAKN;AAED,wEAAwE;AACxE,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,WAAW,GACzB,IAAI,CASN;AAED,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,WAAW,EAC9D,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,EACzB,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,GACnC,IAAI,CAUN"}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.initializeTableRegistry = initializeTableRegistry;
|
|
4
7
|
exports.getRegisteredTables = getRegisteredTables;
|
|
5
8
|
exports.listRegisteredTables = listRegisteredTables;
|
|
6
9
|
exports.registerTable = registerTable;
|
|
7
10
|
exports.ensureTableRegistered = ensureTableRegistered;
|
|
11
|
+
exports.assertTableNameAvailable = assertTableNameAvailable;
|
|
8
12
|
exports.retainRegisteredTables = retainRegisteredTables;
|
|
9
13
|
const tableGeneration_js_1 = require("./tableGeneration.js");
|
|
14
|
+
const cacheTableDependencies_js_1 = require("./cacheTableDependencies.js");
|
|
15
|
+
const foldIdentifier_js_1 = __importDefault(require("./foldIdentifier.js"));
|
|
10
16
|
const registries = new WeakMap();
|
|
11
17
|
function getMutableTables(simpleDB) {
|
|
12
18
|
const tables = registries.get(simpleDB);
|
|
@@ -30,15 +36,21 @@ function registerTable(simpleDB, table) {
|
|
|
30
36
|
throw new Error(`The table must be an instance of ${TableClass.name}.`);
|
|
31
37
|
}
|
|
32
38
|
const tables = getMutableTables(simpleDB);
|
|
33
|
-
|
|
34
|
-
throw new Error(`Table ${table.name} already exists.`);
|
|
35
|
-
}
|
|
39
|
+
assertTableNameAvailable(simpleDB, table.name);
|
|
36
40
|
tables.push(table);
|
|
41
|
+
(0, cacheTableDependencies_js_1.recordCacheTableCreation)(table);
|
|
37
42
|
}
|
|
38
43
|
function ensureTableRegistered(simpleDB, table) {
|
|
39
44
|
const tables = getMutableTables(simpleDB);
|
|
40
45
|
if (!tables.includes(table)) {
|
|
41
|
-
|
|
46
|
+
registerTable(simpleDB, table);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Prevents distinct handles from owning the same DuckDB table name. */
|
|
50
|
+
function assertTableNameAvailable(simpleDB, name, renamedTable) {
|
|
51
|
+
const normalizedName = (0, foldIdentifier_js_1.default)(name);
|
|
52
|
+
if (getRegisteredTables(simpleDB).some((table) => table !== renamedTable && (0, foldIdentifier_js_1.default)(table.name) === normalizedName)) {
|
|
53
|
+
throw new Error(`Table ${name} already exists.`);
|
|
42
54
|
}
|
|
43
55
|
}
|
|
44
56
|
function retainRegisteredTables(simpleDB, predicate) {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type SimpleTable from "../class/SimpleTable.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generates columns from selected input columns, keeping other SQL values in
|
|
4
|
+
* DuckDB. Call from an asynchronous extension barrier. The callback must return
|
|
5
|
+
* one row per input row in the same order; only the declared output columns are
|
|
6
|
+
* stored. Existing output columns are replaced, with types inferred from the
|
|
7
|
+
* generated values. Generation runs sequentially in bounded batches (1,000 rows
|
|
8
|
+
* by default); callbacks must not depend on receiving the whole table. Non-null
|
|
9
|
+
* output types must agree across batches. All-null batches defer type inference.
|
|
10
|
+
* Only one batch of inputs and outputs is retained by this helper in JavaScript;
|
|
11
|
+
* callers must also bound their own buffering. Reads finish before callbacks or
|
|
12
|
+
* writes use the shared connection. The original table is replaced only after
|
|
13
|
+
* staging succeeds. Empty tables are unchanged and do not invoke the callback;
|
|
14
|
+
* outputs that remain null in every batch use VARCHAR.
|
|
15
|
+
*
|
|
16
|
+
* Untouched geometry columns remain in DuckDB, preserving their values, types
|
|
17
|
+
* and CRS without GeoJSON conversion. Geometry columns cannot be selected as
|
|
18
|
+
* inputs or overwritten as outputs; use updateWithJS() for editable GeoJSON.
|
|
19
|
+
* This SQL-only preservation path accepts any source CRS.
|
|
20
|
+
*
|
|
21
|
+
* @param table - Table to enrich.
|
|
22
|
+
* @param inputColumns - Columns available to the callback.
|
|
23
|
+
* @param outputColumns - Generated columns to add or replace.
|
|
24
|
+
* @param generate - Produces one result per input row, in input order.
|
|
25
|
+
* @param options - Controls the maximum rows read, generated, and staged at once.
|
|
26
|
+
* @returns Resolves after merging the generated columns into the table.
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* queueAsyncBarrier(table, {
|
|
30
|
+
* method: "label()",
|
|
31
|
+
* parameters: null,
|
|
32
|
+
* execute: () => updateColumnsWithJS(table, ["name"], ["label"], async (rows) =>
|
|
33
|
+
* rows.map((row) => ({ label: String(row.name).toUpperCase() })),
|
|
34
|
+
* { batchSize: 500 }),
|
|
35
|
+
* });
|
|
36
|
+
* await table.log();
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export default function updateColumnsWithJS(table: SimpleTable, inputColumns: string[], outputColumns: string[], generate: (rows: {
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}[]) => Promise<{
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}[]>, options?: {
|
|
44
|
+
/** Maximum rows per callback and transfer batch. Defaults to 1,000.
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* { batchSize: 500 }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
batchSize?: number;
|
|
51
|
+
}): Promise<void>;
|
|
52
|
+
//# sourceMappingURL=updateColumnsWithJS.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updateColumnsWithJS.d.ts","sourceRoot":"","sources":["../../src/helpers/updateColumnsWithJS.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAMvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAA8B,mBAAmB,CAC/C,KAAK,EAAE,WAAW,EAClB,YAAY,EAAE,MAAM,EAAE,EACtB,aAAa,EAAE,MAAM,EAAE,EACvB,QAAQ,EAAE,CACR,IAAI,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,KAC/B,OAAO,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,CAAC,EAC1C,OAAO,GAAE;IACP;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACf,GACL,OAAO,CAAC,IAAI,CAAC,CAoJf"}
|