@nshiab/simple-data-analysis-core 2.0.4 → 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 +434 -263
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +441 -316
- 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/addCharacterCount.d.ts +3 -0
- package/esm/methods/addCharacterCount.d.ts.map +1 -0
- package/esm/methods/addCharacterCount.js +15 -0
- package/esm/methods/addColumn.d.ts +1 -1
- package/esm/methods/addColumn.d.ts.map +1 -1
- package/esm/methods/addGeoNoise.d.ts +7 -0
- package/esm/methods/addGeoNoise.d.ts.map +1 -0
- package/esm/methods/addGeoNoise.js +135 -0
- package/esm/methods/addNoise.d.ts +5 -0
- package/esm/methods/addNoise.d.ts.map +1 -0
- package/esm/methods/addNoise.js +53 -0
- package/esm/methods/addWordCount.d.ts +3 -0
- package/esm/methods/addWordCount.d.ts.map +1 -0
- package/esm/methods/addWordCount.js +15 -0
- 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/columnProportions.d.ts +1 -0
- package/esm/methods/columnProportions.d.ts.map +1 -1
- package/esm/methods/columnProportions.js +7 -2
- 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 +4 -2
- package/esm/methods/loadArray.d.ts.map +1 -1
- package/esm/methods/loadArray.js +182 -18
- package/esm/methods/loadData.js +3 -0
- package/esm/methods/loadYahooFinanceData.d.ts +10 -0
- package/esm/methods/loadYahooFinanceData.d.ts.map +1 -0
- package/esm/methods/loadYahooFinanceData.js +133 -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/rowProportions.d.ts +1 -0
- package/esm/methods/rowProportions.d.ts.map +1 -1
- package/esm/methods/rowProportions.js +5 -1
- 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 +600 -430
- 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 +434 -263
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +441 -316
- 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/addCharacterCount.d.ts +3 -0
- package/script/methods/addCharacterCount.d.ts.map +1 -0
- package/script/methods/addCharacterCount.js +21 -0
- package/script/methods/addColumn.d.ts +1 -1
- package/script/methods/addColumn.d.ts.map +1 -1
- package/script/methods/addGeoNoise.d.ts +7 -0
- package/script/methods/addGeoNoise.d.ts.map +1 -0
- package/script/methods/addGeoNoise.js +141 -0
- package/script/methods/addNoise.d.ts +5 -0
- package/script/methods/addNoise.d.ts.map +1 -0
- package/script/methods/addNoise.js +59 -0
- package/script/methods/addWordCount.d.ts +3 -0
- package/script/methods/addWordCount.d.ts.map +1 -0
- package/script/methods/addWordCount.js +21 -0
- 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/columnProportions.d.ts +1 -0
- package/script/methods/columnProportions.d.ts.map +1 -1
- package/script/methods/columnProportions.js +7 -2
- 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 +4 -2
- package/script/methods/loadArray.d.ts.map +1 -1
- package/script/methods/loadArray.js +181 -17
- package/script/methods/loadData.js +3 -0
- package/script/methods/loadYahooFinanceData.d.ts +10 -0
- package/script/methods/loadYahooFinanceData.d.ts.map +1 -0
- package/script/methods/loadYahooFinanceData.js +139 -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/rowProportions.d.ts +1 -0
- package/script/methods/rowProportions.d.ts.map +1 -1
- package/script/methods/rowProportions.js +5 -1
- 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
package/README.md
CHANGED
|
@@ -60,8 +60,28 @@ npx @nshiab/setup-data-project
|
|
|
60
60
|
bunx @nshiab/setup-data-project
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
+
## Running a data pipeline
|
|
64
|
+
|
|
65
|
+
Transformation methods are synchronous and chainable. SDA-core queues their work
|
|
66
|
+
and combines compatible operations into a single DuckDB statement. Async methods
|
|
67
|
+
such as `getData()`, `log()`, and `writeData()` execute pending work before
|
|
68
|
+
returning results, so only the final method in a chain needs to be awaited.
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
await table
|
|
72
|
+
.filter("salary > 50000")
|
|
73
|
+
.selectColumns(["name", "salary"])
|
|
74
|
+
.log();
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Use `await table.run()` or `await sdb.run()` to execute pending work without
|
|
78
|
+
reading or exporting a result. Both execute queued operations across all tables
|
|
79
|
+
in the database, in the order the methods were called.
|
|
80
|
+
|
|
63
81
|
## Performance benchmarks
|
|
64
82
|
|
|
83
|
+
These are end-to-end workflow comparisons.
|
|
84
|
+
|
|
65
85
|
These benchmarks compare SDA-core with raw DuckDB and popular Python and R
|
|
66
86
|
libraries, measuring duration and peak memory.
|
|
67
87
|
|
|
@@ -69,6 +89,14 @@ They were run on a MacBook Pro with an Apple M4 Max and 64 GB of memory.
|
|
|
69
89
|
|
|
70
90
|
<!-- benchmark-results:start -->
|
|
71
91
|
|
|
92
|
+
**Tabular versions:** @duckdb/node-api 1.5.5-r.4; DuckDB v1.5.5 (Deno 2.9.6);
|
|
93
|
+
SDA-core 2.0.5 (Deno 2.9.6); pandas 3.0.5 (Python 3.14.7); tidyverse 2.0.0 (R
|
|
94
|
+
4.6.1).
|
|
95
|
+
|
|
96
|
+
**Spatial versions:** @duckdb/node-api 1.5.5-r.4; DuckDB v1.5.5 (Deno 2.9.6);
|
|
97
|
+
SDA-core 2.0.5 (Deno 2.9.6); GeoPandas 1.1.4 (Python 3.14.7); sf 1.1.2 (R
|
|
98
|
+
4.6.1).
|
|
99
|
+
|
|
72
100
|
### Tabular workload
|
|
73
101
|
|
|
74
102
|
Using 22,051,025 temperature records (`ahccd.csv`, 1.77 GB, in
|
|
@@ -76,12 +104,12 @@ Using 22,051,025 temperature records (`ahccd.csv`, 1.77 GB, in
|
|
|
76
104
|
save the cleaned data, then calculate average temperatures by station and decade
|
|
77
105
|
and export the sorted results.
|
|
78
106
|
|
|
79
|
-
| Library
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
| SDA-core
|
|
83
|
-
| pandas
|
|
84
|
-
| tidyverse
|
|
107
|
+
| Library | Mean duration | Duration difference | Mean peak memory | Memory difference |
|
|
108
|
+
| --------- | -------------: | ------------------: | ---------------: | ----------------: |
|
|
109
|
+
| DuckDB | 1.30 ± 0.03 s | -9.7% | 2,457 MB | -2.7% |
|
|
110
|
+
| SDA-core | 1.44 ± 0.03 s | baseline | 2,524 MB | baseline |
|
|
111
|
+
| pandas | 30.08 ± 0.07 s | +1987.9% | 4,700 MB | +86.2% |
|
|
112
|
+
| tidyverse | 82.62 ± 0.22 s | +5634.4% | 8,178 MB | +224.0% |
|
|
85
113
|
|
|
86
114
|
### Spatial workload
|
|
87
115
|
|
|
@@ -91,15 +119,72 @@ in `benchmarks/data/`, we remove missing coordinates, create points, join trees
|
|
|
91
119
|
to neighbourhoods, then count trees per neighbourhood and export the sorted
|
|
92
120
|
results.
|
|
93
121
|
|
|
94
|
-
| Library
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
| SDA-core
|
|
98
|
-
| GeoPandas
|
|
99
|
-
| sf
|
|
122
|
+
| Library | Mean duration | Duration difference | Mean peak memory | Memory difference |
|
|
123
|
+
| --------- | ------------: | ------------------: | ---------------: | ----------------: |
|
|
124
|
+
| DuckDB | 0.78 ± 0.00 s | -5.1% | 255 MB | -5.8% |
|
|
125
|
+
| SDA-core | 0.82 ± 0.01 s | baseline | 271 MB | baseline |
|
|
126
|
+
| GeoPandas | 1.25 ± 0.01 s | +51.4% | 294 MB | +8.5% |
|
|
127
|
+
| sf | 1.80 ± 0.01 s | +118.9% | 490 MB | +81.1% |
|
|
100
128
|
|
|
101
129
|
<!-- benchmark-results:end -->
|
|
102
130
|
|
|
131
|
+
### Focused operation benchmarks
|
|
132
|
+
|
|
133
|
+
These additional benchmarks compare Core and DuckDB on data transfer, joins,
|
|
134
|
+
aggregations, and JavaScript geometry updates to help track and improve
|
|
135
|
+
performance over time. Run `deno task benchmark-core` to regenerate these
|
|
136
|
+
tables. See the [benchmark methodology](benchmarks/operations/README.md) for
|
|
137
|
+
fixture sizes, validation, and measurement details. Peak process memory includes
|
|
138
|
+
setup, warm-up, the measured operation, and validation.
|
|
139
|
+
|
|
140
|
+
<!-- benchmark-operations:start -->
|
|
141
|
+
|
|
142
|
+
#### Join followed by aggregation
|
|
143
|
+
|
|
144
|
+
| Operation | Rows | Batch size | Implementation | Mean duration ± SD | Mean peak process memory |
|
|
145
|
+
| ---------------- | --------: | ---------: | -------------- | -----------------: | -----------------------: |
|
|
146
|
+
| Join → aggregate | 1,000,000 | — | Core | 12.11 ± 0.25 ms | 123.1 MiB |
|
|
147
|
+
| Join → aggregate | 1,000,000 | — | DuckDB | 11.29 ± 0.33 ms | 134.2 MiB |
|
|
148
|
+
|
|
149
|
+
#### JavaScript data transfer
|
|
150
|
+
|
|
151
|
+
`loadArray()` measures JavaScript → DuckDB; `getData()` measures DuckDB →
|
|
152
|
+
JavaScript. `updateWithJS()` measures the round trip with a simple numeric
|
|
153
|
+
increment, including Core's staging and table replacement.
|
|
154
|
+
|
|
155
|
+
| Operation | Rows | Batch size | Implementation | Mean duration ± SD | Mean peak process memory |
|
|
156
|
+
| -------------- | ------: | ---------: | -------------- | -----------------: | -----------------------: |
|
|
157
|
+
| loadArray() | 100,000 | — | Core | 9.40 ± 0.68 ms | 202.3 MiB |
|
|
158
|
+
| loadArray() | 100,000 | — | DuckDB | 19.80 ± 0.94 ms | 230.8 MiB |
|
|
159
|
+
| getData() | 100,000 | — | Core | 9.29 ± 0.26 ms | 191.2 MiB |
|
|
160
|
+
| getData() | 100,000 | — | DuckDB | 12.54 ± 0.27 ms | 209.0 MiB |
|
|
161
|
+
| updateWithJS() | 100,000 | 1000 | Core | 92.45 ± 3.19 ms | 208.2 MiB |
|
|
162
|
+
| updateWithJS() | 100,000 | 1000 | DuckDB | 65.89 ± 1.13 ms | 239.6 MiB |
|
|
163
|
+
| updateWithJS() | 100,000 | 10000 | Core | 42.93 ± 1.05 ms | 218.6 MiB |
|
|
164
|
+
| updateWithJS() | 100,000 | 10000 | DuckDB | 41.76 ± 0.81 ms | 233.5 MiB |
|
|
165
|
+
|
|
166
|
+
#### JavaScript geometry updates
|
|
167
|
+
|
|
168
|
+
Points have one position per geometry; polygons have one ring with 1,001
|
|
169
|
+
positions. Both implementations transfer GeoJSON through JavaScript and stage
|
|
170
|
+
writes. These updates add a label and shift every longitude by 0.01 degrees. A
|
|
171
|
+
batch size of — means all input rows at once. Attribute-only updates are also
|
|
172
|
+
measured and retained in the raw results; their similar timings are omitted here
|
|
173
|
+
to keep the table concise.
|
|
174
|
+
|
|
175
|
+
| Operation | Rows | Batch size | Implementation | Mean duration ± SD | Mean peak process memory |
|
|
176
|
+
| ------------------------- | ------: | ---------: | -------------- | -----------------: | -----------------------: |
|
|
177
|
+
| Points: geometry update | 100,000 | — | Core | 182.59 ± 1.02 ms | 402.4 MiB |
|
|
178
|
+
| Points: geometry update | 100,000 | — | DuckDB | 180.20 ± 1.98 ms | 402.2 MiB |
|
|
179
|
+
| Points: geometry update | 100,000 | 1000 | Core | 252.07 ± 6.59 ms | 267.9 MiB |
|
|
180
|
+
| Points: geometry update | 100,000 | 1000 | DuckDB | 217.69 ± 2.43 ms | 245.4 MiB |
|
|
181
|
+
| Polygons: geometry update | 1,000 | — | Core | 403.35 ± 1.92 ms | 938.3 MiB |
|
|
182
|
+
| Polygons: geometry update | 1,000 | — | DuckDB | 408.62 ± 2.57 ms | 1104.8 MiB |
|
|
183
|
+
| Polygons: geometry update | 1,000 | 100 | Core | 418.45 ± 2.45 ms | 747.0 MiB |
|
|
184
|
+
| Polygons: geometry update | 1,000 | 100 | DuckDB | 416.90 ± 2.54 ms | 714.6 MiB |
|
|
185
|
+
|
|
186
|
+
<!-- benchmark-operations:end -->
|
|
187
|
+
|
|
103
188
|
## Building extensions
|
|
104
189
|
|
|
105
190
|
The full
|
|
@@ -115,6 +200,10 @@ chainable, define them on a `SimpleTable` subclass, give them a return type of
|
|
|
115
200
|
create tables should always use `this.sdb.newTable()` so they also return your
|
|
116
201
|
extended table type.
|
|
117
202
|
|
|
203
|
+
Builders return `this` synchronously; their queued work runs when an observer
|
|
204
|
+
such as `getData()`, `log()`, or `run()` is called. Observers execute pending
|
|
205
|
+
work across the database in program order.
|
|
206
|
+
|
|
118
207
|
```ts
|
|
119
208
|
import {
|
|
120
209
|
SimpleDB as CoreDB,
|
|
@@ -172,3 +261,20 @@ The callback must await all asynchronous work that can queue builders. If it
|
|
|
172
261
|
rejects, captured builders that have not already run are discarded. Builders
|
|
173
262
|
already drained by an observer inside the callback remain applied;
|
|
174
263
|
`queueAsyncBarrier()` does not provide database rollback.
|
|
264
|
+
|
|
265
|
+
This differs from a failure while executing queued builders: during replay, the
|
|
266
|
+
failing table's remaining chain is aborted, but unexecuted work for other tables
|
|
267
|
+
is requeued for their next observation.
|
|
268
|
+
|
|
269
|
+
Other useful helpers, imported from `@nshiab/simple-data-analysis-core/helpers`:
|
|
270
|
+
|
|
271
|
+
- `updateColumnsWithJS()`: enrich selected columns asynchronously in bounded
|
|
272
|
+
batches inside `queueAsyncBarrier()`, preserving untouched columns, including
|
|
273
|
+
geometry. Return one result per input row, in the same order.
|
|
274
|
+
- `queryDB()` with `mergeOptions()`: execute SQL with the library's logging and
|
|
275
|
+
diagnostic settings. Queries flush queued work before running.
|
|
276
|
+
- `quoteIdentifier()`: quote table and column names safely when constructing
|
|
277
|
+
SQL.
|
|
278
|
+
|
|
279
|
+
See the [exported helpers](src/helpers/index.ts) for the complete list and links
|
|
280
|
+
to their documentation and examples. Helpers outside that list are internal.
|
package/esm/class/Simple.d.ts
CHANGED
|
@@ -18,9 +18,15 @@ export default class Simple {
|
|
|
18
18
|
*/
|
|
19
19
|
typesToLog: boolean;
|
|
20
20
|
/**
|
|
21
|
-
* The maximum number of characters to display for text
|
|
21
|
+
* The maximum number of characters to display for text and stringified nested cells, including the truncation marker. This does not control column width. Set to Infinity to show the entire text.
|
|
22
22
|
*
|
|
23
|
-
* @
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* const sdb = new SimpleDB({ charsToLog: 150 });
|
|
26
|
+
* await sdb.newTable().loadArray([{ text: "x".repeat(200) }]).log();
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @defaultValue `75`
|
|
24
30
|
*/
|
|
25
31
|
charsToLog: number | undefined;
|
|
26
32
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Simple.d.ts","sourceRoot":"","sources":["../../src/class/Simple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB
|
|
1
|
+
{"version":3,"file":"Simple.d.ts","sourceRoot":"","sources":["../../src/class/Simple.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,MAAM;IACzB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;OAUG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;OAEG;IACH,EAAE,EAAG,cAAc,CAAC;IACpB;;OAEG;IACH,UAAU,EAAG,gBAAgB,CAAC;IAC9B;;;;OAIG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,QAAQ,EAAG,CACT,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,gBAAgB,EAC5B,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,UAAU,EAAE;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;SAAE,GAAG,IAAI,CAAC;QAC9C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;QACvB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC;KACrB,KACE,OAAO,CACR;QACA,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,EAAE,GACD,IAAI,CACP,CAAC;gBAGA,OAAO,GAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACjB;CAOT"}
|
package/esm/class/Simple.js
CHANGED
|
@@ -28,9 +28,15 @@ export default class Simple {
|
|
|
28
28
|
value: void 0
|
|
29
29
|
});
|
|
30
30
|
/**
|
|
31
|
-
* The maximum number of characters to display for text
|
|
31
|
+
* The maximum number of characters to display for text and stringified nested cells, including the truncation marker. This does not control column width. Set to Infinity to show the entire text.
|
|
32
32
|
*
|
|
33
|
-
* @
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const sdb = new SimpleDB({ charsToLog: 150 });
|
|
36
|
+
* await sdb.newTable().loadArray([{ text: "x".repeat(200) }]).log();
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @defaultValue `75`
|
|
34
40
|
*/
|
|
35
41
|
Object.defineProperty(this, "charsToLog", {
|
|
36
42
|
enumerable: true,
|
|
@@ -100,7 +106,7 @@ export default class Simple {
|
|
|
100
106
|
value: void 0
|
|
101
107
|
});
|
|
102
108
|
this.rowsToLog = options.rowsToLog ?? 10;
|
|
103
|
-
this.charsToLog = options.charsToLog;
|
|
109
|
+
this.charsToLog = options.charsToLog ?? 75;
|
|
104
110
|
this.typesToLog = options.typesToLog ?? false;
|
|
105
111
|
this.defaultTableName = false;
|
|
106
112
|
}
|
package/esm/class/SimpleDB.d.ts
CHANGED
|
@@ -36,6 +36,73 @@ import Simple from "./Simple.js";
|
|
|
36
36
|
*/
|
|
37
37
|
export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends Simple {
|
|
38
38
|
#private;
|
|
39
|
+
/**
|
|
40
|
+
* The operator syntax used by expressions and custom queries in this database.
|
|
41
|
+
* `"js"` translates JavaScript-style operators (`&&`, `||`, `==`, `===`,
|
|
42
|
+
* `!==`) and null comparisons within SQL expressions. It does not evaluate
|
|
43
|
+
* arbitrary JavaScript. `||` remains concatenation when string literals, list
|
|
44
|
+
* literals, explicit text casts, or `concat()` results make that intent clear.
|
|
45
|
+
* Otherwise `||` becomes OR; column types are not inferred. Use `concat()`
|
|
46
|
+
* when concatenation would otherwise be ambiguous, such as `first || last`.
|
|
47
|
+
* `"sql"` passes SQL through unchanged, including `||` and null comparisons.
|
|
48
|
+
* Choose the syntax when constructing the database; it applies to all tables.
|
|
49
|
+
*
|
|
50
|
+
* @defaultValue `"js"`
|
|
51
|
+
* @category Properties
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const sdb = new SimpleDB({ expressionSyntax: "js" }); // The default mode
|
|
55
|
+
* // || becomes SQL OR: keep rows where at least one condition is true.
|
|
56
|
+
* await sdb.newTable().loadArray([{ active: true, admin: false }])
|
|
57
|
+
* .filter("active || admin").log();
|
|
58
|
+
* ```
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* const sdb = new SimpleDB({ expressionSyntax: "js" });
|
|
62
|
+
* // && becomes SQL AND: both conditions must be true.
|
|
63
|
+
* // === becomes SQL =: compare the age with 18.
|
|
64
|
+
* await sdb.newTable().loadArray([{ active: true, age: 18 }])
|
|
65
|
+
* .filter("active && age === 18").log();
|
|
66
|
+
* ```
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const sdb = new SimpleDB({ expressionSyntax: "js" });
|
|
70
|
+
* // SQL AND and OR also work in JS mode; they pass through unchanged.
|
|
71
|
+
* // Keep active adults, or anyone who is an admin.
|
|
72
|
+
* await sdb.newTable().loadArray([{ active: true, age: 18, admin: false }])
|
|
73
|
+
* .filter("(active AND age >= 18) OR admin").log();
|
|
74
|
+
* ```
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const sdb = new SimpleDB({ expressionSyntax: "js" });
|
|
78
|
+
* // Bare column names do not establish concatenation. Use concat() explicitly.
|
|
79
|
+
* await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
|
|
80
|
+
* .addColumn("name", "string", "concat(first, ' ', last)").log();
|
|
81
|
+
* ```
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const sdb = new SimpleDB(); // JS mode is the default
|
|
85
|
+
* // The string literal ' ' makes concatenation clear, so both || stay unchanged.
|
|
86
|
+
* await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
|
|
87
|
+
* .addColumn("name", "string", "first || ' ' || last").log();
|
|
88
|
+
* ```
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* const sdb = new SimpleDB({ expressionSyntax: "sql" });
|
|
92
|
+
* // SQL mode preserves || as concatenation: the name becomes "Jane Doe".
|
|
93
|
+
* await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
|
|
94
|
+
* .addColumn("name", "string", "first || ' ' || last").log();
|
|
95
|
+
* ```
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const sdb = new SimpleDB({ expressionSyntax: "sql" });
|
|
99
|
+
* // Use SQL AND and OR for logical conditions; && and || are not translated.
|
|
100
|
+
* // Both active and adult must be true, unless admin is true.
|
|
101
|
+
* await sdb.newTable().loadArray([{ active: true, age: 18, admin: false }])
|
|
102
|
+
* .filter("(active AND age >= 18) OR admin").log();
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
readonly expressionSyntax: "js" | "sql";
|
|
39
106
|
/**
|
|
40
107
|
* Whether to log each SQL statement immediately before execution.
|
|
41
108
|
*
|
|
@@ -255,9 +322,10 @@ export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends S
|
|
|
255
322
|
* @param options.readOnly - Opens an existing DuckDB file read-only. Defaults to false. Requires a file and cannot be combined with overwrite.
|
|
256
323
|
* @param options.logDuration - A flag indicating whether to log the total execution duration.
|
|
257
324
|
* @param options.rowsToLog - The number of rows to display when logging a table.
|
|
258
|
-
* @param options.charsToLog - The maximum
|
|
325
|
+
* @param options.charsToLog - The maximum characters to display for text and stringified nested cells, including truncation markers (default: 75). Independent of column width. Use Infinity for unlimited text.
|
|
259
326
|
* @param options.typesToLog - A flag indicating whether to include data types when logging a table.
|
|
260
327
|
* @param options.cacheVerbose - Whether to log cache hits and misses, code and input changes, TTL status, and cache read/write timing.
|
|
328
|
+
* @param options.expressionSyntax - Operator syntax for expressions and custom queries: `"js"` (default) translates JavaScript-style operators in SQL expressions; `"sql"` preserves SQL unchanged.
|
|
261
329
|
* @param options.logSQL - A flag indicating whether to log SQL immediately before execution.
|
|
262
330
|
* @param options.explainSQL - A flag indicating whether to log DuckDB query plans for supported statements.
|
|
263
331
|
* @param options.duckDbCache - A flag indicating whether to use DuckDB's external file cache.
|
|
@@ -283,6 +351,7 @@ export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends S
|
|
|
283
351
|
charsToLog?: number;
|
|
284
352
|
typesToLog?: boolean;
|
|
285
353
|
cacheVerbose?: boolean;
|
|
354
|
+
expressionSyntax?: "js" | "sql";
|
|
286
355
|
logSQL?: boolean;
|
|
287
356
|
explainSQL?: boolean;
|
|
288
357
|
duckDbCache?: boolean | null;
|
|
@@ -300,6 +369,7 @@ export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends S
|
|
|
300
369
|
start(): Promise<SimpleDB>;
|
|
301
370
|
/**
|
|
302
371
|
* Creates a new SimpleTable instance within the database.
|
|
372
|
+
* The name must be unique among registered tables, ignoring ASCII letter case.
|
|
303
373
|
*
|
|
304
374
|
* @param name - The name of the new table. If not provided, a default name is generated (e.g., "table1").
|
|
305
375
|
* @returns A new table instance.
|
|
@@ -486,6 +556,7 @@ export default class SimpleDB<Table extends SimpleTable = SimpleTable> extends S
|
|
|
486
556
|
}[]>;
|
|
487
557
|
/**
|
|
488
558
|
* Executes a custom SQL query directly against the DuckDB instance.
|
|
559
|
+
* With the default `SimpleDB.expressionSyntax: "js"`, queries support JavaScript-style operators (`&&`, `||`, `===`, `!==`). Set `expressionSyntax: "sql"` for unchanged SQL.
|
|
489
560
|
* Queries run in UTC. When data is returned, temporal values use the same
|
|
490
561
|
* JavaScript representations as `SimpleTable.getData()`.
|
|
491
562
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SimpleDB.d.ts","sourceRoot":"","sources":["../../src/class/SimpleDB.ts"],"names":[],"mappings":"AAGA,OAAO,WAAW,MAAM,kBAAkB,CAAC;AAG3C,OAAO,MAAM,MAAM,aAAa,CAAC;AA6BjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,CAAC,OAAO,OAAO,QAAQ,CAAC,KAAK,SAAS,WAAW,GAAG,WAAW,CACnE,SAAQ,MAAM;;IACd;;;;;;;;;OASG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;;;;;;;OASG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;;OAOG;IACH,YAAY,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAInC;;;;OAIG;IACH,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC9C;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;;OAaG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,UAAU,EAAE,KACV,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,QAAQ,EACb,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,KACE,KAAK,CAQC;IAEX
|
|
1
|
+
{"version":3,"file":"SimpleDB.d.ts","sourceRoot":"","sources":["../../src/class/SimpleDB.ts"],"names":[],"mappings":"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"}
|
package/esm/class/SimpleDB.js
CHANGED
|
@@ -89,9 +89,10 @@ class SimpleDB extends Simple {
|
|
|
89
89
|
* @param options.readOnly - Opens an existing DuckDB file read-only. Defaults to false. Requires a file and cannot be combined with overwrite.
|
|
90
90
|
* @param options.logDuration - A flag indicating whether to log the total execution duration.
|
|
91
91
|
* @param options.rowsToLog - The number of rows to display when logging a table.
|
|
92
|
-
* @param options.charsToLog - The maximum
|
|
92
|
+
* @param options.charsToLog - The maximum characters to display for text and stringified nested cells, including truncation markers (default: 75). Independent of column width. Use Infinity for unlimited text.
|
|
93
93
|
* @param options.typesToLog - A flag indicating whether to include data types when logging a table.
|
|
94
94
|
* @param options.cacheVerbose - Whether to log cache hits and misses, code and input changes, TTL status, and cache read/write timing.
|
|
95
|
+
* @param options.expressionSyntax - Operator syntax for expressions and custom queries: `"js"` (default) translates JavaScript-style operators in SQL expressions; `"sql"` preserves SQL unchanged.
|
|
95
96
|
* @param options.logSQL - A flag indicating whether to log SQL immediately before execution.
|
|
96
97
|
* @param options.explainSQL - A flag indicating whether to log DuckDB query plans for supported statements.
|
|
97
98
|
* @param options.duckDbCache - A flag indicating whether to use DuckDB's external file cache.
|
|
@@ -111,6 +112,78 @@ class SimpleDB extends Simple {
|
|
|
111
112
|
constructor(options = {}) {
|
|
112
113
|
super(options);
|
|
113
114
|
_SimpleDB_instances.add(this);
|
|
115
|
+
/**
|
|
116
|
+
* The operator syntax used by expressions and custom queries in this database.
|
|
117
|
+
* `"js"` translates JavaScript-style operators (`&&`, `||`, `==`, `===`,
|
|
118
|
+
* `!==`) and null comparisons within SQL expressions. It does not evaluate
|
|
119
|
+
* arbitrary JavaScript. `||` remains concatenation when string literals, list
|
|
120
|
+
* literals, explicit text casts, or `concat()` results make that intent clear.
|
|
121
|
+
* Otherwise `||` becomes OR; column types are not inferred. Use `concat()`
|
|
122
|
+
* when concatenation would otherwise be ambiguous, such as `first || last`.
|
|
123
|
+
* `"sql"` passes SQL through unchanged, including `||` and null comparisons.
|
|
124
|
+
* Choose the syntax when constructing the database; it applies to all tables.
|
|
125
|
+
*
|
|
126
|
+
* @defaultValue `"js"`
|
|
127
|
+
* @category Properties
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* const sdb = new SimpleDB({ expressionSyntax: "js" }); // The default mode
|
|
131
|
+
* // || becomes SQL OR: keep rows where at least one condition is true.
|
|
132
|
+
* await sdb.newTable().loadArray([{ active: true, admin: false }])
|
|
133
|
+
* .filter("active || admin").log();
|
|
134
|
+
* ```
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* const sdb = new SimpleDB({ expressionSyntax: "js" });
|
|
138
|
+
* // && becomes SQL AND: both conditions must be true.
|
|
139
|
+
* // === becomes SQL =: compare the age with 18.
|
|
140
|
+
* await sdb.newTable().loadArray([{ active: true, age: 18 }])
|
|
141
|
+
* .filter("active && age === 18").log();
|
|
142
|
+
* ```
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* const sdb = new SimpleDB({ expressionSyntax: "js" });
|
|
146
|
+
* // SQL AND and OR also work in JS mode; they pass through unchanged.
|
|
147
|
+
* // Keep active adults, or anyone who is an admin.
|
|
148
|
+
* await sdb.newTable().loadArray([{ active: true, age: 18, admin: false }])
|
|
149
|
+
* .filter("(active AND age >= 18) OR admin").log();
|
|
150
|
+
* ```
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* const sdb = new SimpleDB({ expressionSyntax: "js" });
|
|
154
|
+
* // Bare column names do not establish concatenation. Use concat() explicitly.
|
|
155
|
+
* await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
|
|
156
|
+
* .addColumn("name", "string", "concat(first, ' ', last)").log();
|
|
157
|
+
* ```
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* const sdb = new SimpleDB(); // JS mode is the default
|
|
161
|
+
* // The string literal ' ' makes concatenation clear, so both || stay unchanged.
|
|
162
|
+
* await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
|
|
163
|
+
* .addColumn("name", "string", "first || ' ' || last").log();
|
|
164
|
+
* ```
|
|
165
|
+
* @example
|
|
166
|
+
* ```ts
|
|
167
|
+
* const sdb = new SimpleDB({ expressionSyntax: "sql" });
|
|
168
|
+
* // SQL mode preserves || as concatenation: the name becomes "Jane Doe".
|
|
169
|
+
* await sdb.newTable().loadArray([{ first: "Jane", last: "Doe" }])
|
|
170
|
+
* .addColumn("name", "string", "first || ' ' || last").log();
|
|
171
|
+
* ```
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* const sdb = new SimpleDB({ expressionSyntax: "sql" });
|
|
175
|
+
* // Use SQL AND and OR for logical conditions; && and || are not translated.
|
|
176
|
+
* // Both active and adult must be true, unless admin is true.
|
|
177
|
+
* await sdb.newTable().loadArray([{ active: true, age: 18, admin: false }])
|
|
178
|
+
* .filter("(active AND age >= 18) OR admin").log();
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
Object.defineProperty(this, "expressionSyntax", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
configurable: true,
|
|
184
|
+
writable: true,
|
|
185
|
+
value: void 0
|
|
186
|
+
});
|
|
114
187
|
/**
|
|
115
188
|
* Whether to log each SQL statement immediately before execution.
|
|
116
189
|
*
|
|
@@ -423,6 +496,11 @@ class SimpleDB extends Simple {
|
|
|
423
496
|
writable: true,
|
|
424
497
|
value: SimpleTable
|
|
425
498
|
});
|
|
499
|
+
if (options.expressionSyntax !== undefined &&
|
|
500
|
+
!["js", "sql"].includes(options.expressionSyntax)) {
|
|
501
|
+
throw new Error('expressionSyntax must be "js" or "sql".');
|
|
502
|
+
}
|
|
503
|
+
this.expressionSyntax = options.expressionSyntax ?? "js";
|
|
426
504
|
this.file = options.file ?? ":memory:";
|
|
427
505
|
this.logSQL = options.logSQL ?? false;
|
|
428
506
|
this.explainSQL = options.explainSQL ?? false;
|
|
@@ -475,6 +553,7 @@ class SimpleDB extends Simple {
|
|
|
475
553
|
}
|
|
476
554
|
/**
|
|
477
555
|
* Creates a new SimpleTable instance within the database.
|
|
556
|
+
* The name must be unique among registered tables, ignoring ASCII letter case.
|
|
478
557
|
*
|
|
479
558
|
* @param name - The name of the new table. If not provided, a default name is generated (e.g., "table1").
|
|
480
559
|
* @returns A new table instance.
|
|
@@ -728,6 +807,7 @@ class SimpleDB extends Simple {
|
|
|
728
807
|
}
|
|
729
808
|
/**
|
|
730
809
|
* Executes a custom SQL query directly against the DuckDB instance.
|
|
810
|
+
* With the default `SimpleDB.expressionSyntax: "js"`, queries support JavaScript-style operators (`&&`, `||`, `===`, `!==`). Set `expressionSyntax: "sql"` for unchanged SQL.
|
|
731
811
|
* Queries run in UTC. When data is returned, temporal values use the same
|
|
732
812
|
* JavaScript representations as `SimpleTable.getData()`.
|
|
733
813
|
*
|