@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.
Files changed (280) hide show
  1. package/README.md +118 -12
  2. package/esm/class/Simple.d.ts +8 -2
  3. package/esm/class/Simple.d.ts.map +1 -1
  4. package/esm/class/Simple.js +9 -3
  5. package/esm/class/SimpleDB.d.ts +72 -1
  6. package/esm/class/SimpleDB.d.ts.map +1 -1
  7. package/esm/class/SimpleDB.js +81 -1
  8. package/esm/class/SimpleTable.d.ts +434 -263
  9. package/esm/class/SimpleTable.d.ts.map +1 -1
  10. package/esm/class/SimpleTable.js +441 -316
  11. package/esm/helpers/LogValue.d.ts +8 -0
  12. package/esm/helpers/LogValue.d.ts.map +1 -0
  13. package/esm/helpers/LogValue.js +23 -0
  14. package/esm/helpers/cacheTableDependencies.d.ts +9 -0
  15. package/esm/helpers/cacheTableDependencies.d.ts.map +1 -1
  16. package/esm/helpers/cacheTableDependencies.js +131 -21
  17. package/esm/helpers/cleanSQL.d.ts +1 -1
  18. package/esm/helpers/cleanSQL.d.ts.map +1 -1
  19. package/esm/helpers/cleanSQL.js +268 -23
  20. package/esm/helpers/flushAllTables.d.ts.map +1 -1
  21. package/esm/helpers/flushAllTables.js +23 -28
  22. package/esm/helpers/foldIdentifier.d.ts +3 -0
  23. package/esm/helpers/foldIdentifier.d.ts.map +1 -0
  24. package/esm/helpers/foldIdentifier.js +4 -0
  25. package/esm/helpers/geometryFromJSON.d.ts +3 -0
  26. package/esm/helpers/geometryFromJSON.d.ts.map +1 -0
  27. package/esm/helpers/geometryFromJSON.js +4 -0
  28. package/esm/helpers/index.d.ts +1 -0
  29. package/esm/helpers/index.d.ts.map +1 -1
  30. package/esm/helpers/index.js +1 -0
  31. package/esm/helpers/logData.d.ts.map +1 -1
  32. package/esm/helpers/logData.js +45 -44
  33. package/esm/helpers/makeLogConverter.d.ts +5 -0
  34. package/esm/helpers/makeLogConverter.d.ts.map +1 -0
  35. package/esm/helpers/makeLogConverter.js +64 -0
  36. package/esm/helpers/osmFiles.d.ts.map +1 -1
  37. package/esm/helpers/parseTypes.d.ts +1 -1
  38. package/esm/helpers/parseTypes.d.ts.map +1 -1
  39. package/esm/helpers/parseTypes.js +4 -0
  40. package/esm/helpers/pendingOps.d.ts +4 -2
  41. package/esm/helpers/pendingOps.d.ts.map +1 -1
  42. package/esm/helpers/prepareGeometry.d.ts +3 -0
  43. package/esm/helpers/prepareGeometry.d.ts.map +1 -0
  44. package/esm/helpers/prepareGeometry.js +99 -0
  45. package/esm/helpers/prepareJSON.d.ts +3 -0
  46. package/esm/helpers/prepareJSON.d.ts.map +1 -0
  47. package/esm/helpers/prepareJSON.js +50 -0
  48. package/esm/helpers/printTable.d.ts +5 -4
  49. package/esm/helpers/printTable.d.ts.map +1 -1
  50. package/esm/helpers/printTable.js +32 -36
  51. package/esm/helpers/queryDB.js +1 -1
  52. package/esm/helpers/queueAsyncBarrier.d.ts +4 -0
  53. package/esm/helpers/queueAsyncBarrier.d.ts.map +1 -1
  54. package/esm/helpers/queueAsyncBarrier.js +4 -0
  55. package/esm/helpers/queueOp.d.ts.map +1 -1
  56. package/esm/helpers/queueOp.js +5 -3
  57. package/esm/helpers/readMutationRows.d.ts +9 -0
  58. package/esm/helpers/readMutationRows.d.ts.map +1 -0
  59. package/esm/helpers/readMutationRows.js +94 -0
  60. package/esm/helpers/referencedTables.d.ts +9 -0
  61. package/esm/helpers/referencedTables.d.ts.map +1 -0
  62. package/esm/helpers/referencedTables.js +22 -0
  63. package/esm/helpers/runQuery.d.ts.map +1 -1
  64. package/esm/helpers/runQuery.js +11 -13
  65. package/esm/helpers/scanSQL.d.ts +7 -0
  66. package/esm/helpers/scanSQL.d.ts.map +1 -0
  67. package/esm/helpers/scanSQL.js +71 -0
  68. package/esm/helpers/tableRegistry.d.ts +2 -0
  69. package/esm/helpers/tableRegistry.d.ts.map +1 -1
  70. package/esm/helpers/tableRegistry.js +12 -4
  71. package/esm/helpers/updateColumnsWithJS.d.ts +52 -0
  72. package/esm/helpers/updateColumnsWithJS.d.ts.map +1 -0
  73. package/esm/helpers/updateColumnsWithJS.js +139 -0
  74. package/esm/methods/addCharacterCount.d.ts +3 -0
  75. package/esm/methods/addCharacterCount.d.ts.map +1 -0
  76. package/esm/methods/addCharacterCount.js +15 -0
  77. package/esm/methods/addColumn.d.ts +1 -1
  78. package/esm/methods/addColumn.d.ts.map +1 -1
  79. package/esm/methods/addGeoNoise.d.ts +7 -0
  80. package/esm/methods/addGeoNoise.d.ts.map +1 -0
  81. package/esm/methods/addGeoNoise.js +135 -0
  82. package/esm/methods/addNoise.d.ts +5 -0
  83. package/esm/methods/addNoise.d.ts.map +1 -0
  84. package/esm/methods/addNoise.js +53 -0
  85. package/esm/methods/addWordCount.d.ts +3 -0
  86. package/esm/methods/addWordCount.d.ts.map +1 -0
  87. package/esm/methods/addWordCount.js +15 -0
  88. package/esm/methods/bm25.d.ts.map +1 -1
  89. package/esm/methods/bm25.js +1 -2
  90. package/esm/methods/cache.d.ts.map +1 -1
  91. package/esm/methods/cache.js +4 -6
  92. package/esm/methods/columnProportions.d.ts +1 -0
  93. package/esm/methods/columnProportions.d.ts.map +1 -1
  94. package/esm/methods/columnProportions.js +7 -2
  95. package/esm/methods/convert.d.ts +2 -2
  96. package/esm/methods/convert.d.ts.map +1 -1
  97. package/esm/methods/convert.js +5 -0
  98. package/esm/methods/getBottom.d.ts +1 -1
  99. package/esm/methods/getBottom.d.ts.map +1 -1
  100. package/esm/methods/getBottom.js +2 -2
  101. package/esm/methods/getData.d.ts +1 -1
  102. package/esm/methods/getData.d.ts.map +1 -1
  103. package/esm/methods/getData.js +2 -2
  104. package/esm/methods/join.d.ts.map +1 -1
  105. package/esm/methods/join.js +8 -16
  106. package/esm/methods/joinGeo.d.ts.map +1 -1
  107. package/esm/methods/joinGeo.js +10 -19
  108. package/esm/methods/loadArray.d.ts +4 -2
  109. package/esm/methods/loadArray.d.ts.map +1 -1
  110. package/esm/methods/loadArray.js +182 -18
  111. package/esm/methods/loadData.js +3 -0
  112. package/esm/methods/loadYahooFinanceData.d.ts +10 -0
  113. package/esm/methods/loadYahooFinanceData.d.ts.map +1 -0
  114. package/esm/methods/loadYahooFinanceData.js +133 -0
  115. package/esm/methods/log.d.ts +7 -0
  116. package/esm/methods/log.d.ts.map +1 -0
  117. package/esm/methods/log.js +58 -0
  118. package/esm/methods/logBottom.d.ts +5 -0
  119. package/esm/methods/logBottom.d.ts.map +1 -0
  120. package/esm/methods/logBottom.js +9 -0
  121. package/esm/methods/removeTable.d.ts.map +1 -1
  122. package/esm/methods/removeTable.js +2 -0
  123. package/esm/methods/removeTables.d.ts.map +1 -1
  124. package/esm/methods/removeTables.js +7 -0
  125. package/esm/methods/renameTable.d.ts.map +1 -1
  126. package/esm/methods/renameTable.js +4 -0
  127. package/esm/methods/rowProportions.d.ts +1 -0
  128. package/esm/methods/rowProportions.d.ts.map +1 -1
  129. package/esm/methods/rowProportions.js +5 -1
  130. package/esm/methods/rowToText.js +2 -2
  131. package/esm/methods/selectTables.d.ts.map +1 -1
  132. package/esm/methods/selectTables.js +6 -0
  133. package/esm/methods/setTypes.d.ts +1 -1
  134. package/esm/methods/setTypes.d.ts.map +1 -1
  135. package/esm/methods/stream.d.ts.map +1 -1
  136. package/esm/methods/stream.js +2 -1
  137. package/esm/methods/updateWithJS.d.ts +1 -3
  138. package/esm/methods/updateWithJS.d.ts.map +1 -1
  139. package/esm/methods/updateWithJS.js +123 -37
  140. package/llm.md +600 -430
  141. package/llms.txt +1 -1
  142. package/package.json +1 -1
  143. package/script/class/Simple.d.ts +8 -2
  144. package/script/class/Simple.d.ts.map +1 -1
  145. package/script/class/Simple.js +9 -3
  146. package/script/class/SimpleDB.d.ts +72 -1
  147. package/script/class/SimpleDB.d.ts.map +1 -1
  148. package/script/class/SimpleDB.js +81 -1
  149. package/script/class/SimpleTable.d.ts +434 -263
  150. package/script/class/SimpleTable.d.ts.map +1 -1
  151. package/script/class/SimpleTable.js +441 -316
  152. package/script/helpers/LogValue.d.ts +8 -0
  153. package/script/helpers/LogValue.d.ts.map +1 -0
  154. package/script/helpers/LogValue.js +26 -0
  155. package/script/helpers/cacheTableDependencies.d.ts +9 -0
  156. package/script/helpers/cacheTableDependencies.d.ts.map +1 -1
  157. package/script/helpers/cacheTableDependencies.js +170 -20
  158. package/script/helpers/cleanSQL.d.ts +1 -1
  159. package/script/helpers/cleanSQL.d.ts.map +1 -1
  160. package/script/helpers/cleanSQL.js +271 -23
  161. package/script/helpers/flushAllTables.d.ts.map +1 -1
  162. package/script/helpers/flushAllTables.js +24 -29
  163. package/script/helpers/foldIdentifier.d.ts +3 -0
  164. package/script/helpers/foldIdentifier.d.ts.map +1 -0
  165. package/script/helpers/foldIdentifier.js +7 -0
  166. package/script/helpers/geometryFromJSON.d.ts +3 -0
  167. package/script/helpers/geometryFromJSON.d.ts.map +1 -0
  168. package/script/helpers/geometryFromJSON.js +7 -0
  169. package/script/helpers/index.d.ts +1 -0
  170. package/script/helpers/index.d.ts.map +1 -1
  171. package/script/helpers/index.js +3 -1
  172. package/script/helpers/logData.d.ts.map +1 -1
  173. package/script/helpers/logData.js +45 -44
  174. package/script/helpers/makeLogConverter.d.ts +5 -0
  175. package/script/helpers/makeLogConverter.d.ts.map +1 -0
  176. package/script/helpers/makeLogConverter.js +70 -0
  177. package/script/helpers/osmFiles.d.ts.map +1 -1
  178. package/script/helpers/parseTypes.d.ts +1 -1
  179. package/script/helpers/parseTypes.d.ts.map +1 -1
  180. package/script/helpers/parseTypes.js +4 -0
  181. package/script/helpers/pendingOps.d.ts +4 -2
  182. package/script/helpers/pendingOps.d.ts.map +1 -1
  183. package/script/helpers/prepareGeometry.d.ts +3 -0
  184. package/script/helpers/prepareGeometry.d.ts.map +1 -0
  185. package/script/helpers/prepareGeometry.js +102 -0
  186. package/script/helpers/prepareJSON.d.ts +3 -0
  187. package/script/helpers/prepareJSON.d.ts.map +1 -0
  188. package/script/helpers/prepareJSON.js +53 -0
  189. package/script/helpers/printTable.d.ts +5 -4
  190. package/script/helpers/printTable.d.ts.map +1 -1
  191. package/script/helpers/printTable.js +32 -36
  192. package/script/helpers/queryDB.js +1 -1
  193. package/script/helpers/queueAsyncBarrier.d.ts +4 -0
  194. package/script/helpers/queueAsyncBarrier.d.ts.map +1 -1
  195. package/script/helpers/queueAsyncBarrier.js +4 -0
  196. package/script/helpers/queueOp.d.ts.map +1 -1
  197. package/script/helpers/queueOp.js +4 -2
  198. package/script/helpers/readMutationRows.d.ts +9 -0
  199. package/script/helpers/readMutationRows.d.ts.map +1 -0
  200. package/script/helpers/readMutationRows.js +97 -0
  201. package/script/helpers/referencedTables.d.ts +9 -0
  202. package/script/helpers/referencedTables.d.ts.map +1 -0
  203. package/script/helpers/referencedTables.js +28 -0
  204. package/script/helpers/runQuery.d.ts.map +1 -1
  205. package/script/helpers/runQuery.js +11 -13
  206. package/script/helpers/scanSQL.d.ts +7 -0
  207. package/script/helpers/scanSQL.d.ts.map +1 -0
  208. package/script/helpers/scanSQL.js +74 -0
  209. package/script/helpers/tableRegistry.d.ts +2 -0
  210. package/script/helpers/tableRegistry.d.ts.map +1 -1
  211. package/script/helpers/tableRegistry.js +16 -4
  212. package/script/helpers/updateColumnsWithJS.d.ts +52 -0
  213. package/script/helpers/updateColumnsWithJS.d.ts.map +1 -0
  214. package/script/helpers/updateColumnsWithJS.js +145 -0
  215. package/script/methods/addCharacterCount.d.ts +3 -0
  216. package/script/methods/addCharacterCount.d.ts.map +1 -0
  217. package/script/methods/addCharacterCount.js +21 -0
  218. package/script/methods/addColumn.d.ts +1 -1
  219. package/script/methods/addColumn.d.ts.map +1 -1
  220. package/script/methods/addGeoNoise.d.ts +7 -0
  221. package/script/methods/addGeoNoise.d.ts.map +1 -0
  222. package/script/methods/addGeoNoise.js +141 -0
  223. package/script/methods/addNoise.d.ts +5 -0
  224. package/script/methods/addNoise.d.ts.map +1 -0
  225. package/script/methods/addNoise.js +59 -0
  226. package/script/methods/addWordCount.d.ts +3 -0
  227. package/script/methods/addWordCount.d.ts.map +1 -0
  228. package/script/methods/addWordCount.js +21 -0
  229. package/script/methods/bm25.d.ts.map +1 -1
  230. package/script/methods/bm25.js +1 -2
  231. package/script/methods/cache.d.ts.map +1 -1
  232. package/script/methods/cache.js +3 -5
  233. package/script/methods/columnProportions.d.ts +1 -0
  234. package/script/methods/columnProportions.d.ts.map +1 -1
  235. package/script/methods/columnProportions.js +7 -2
  236. package/script/methods/convert.d.ts +2 -2
  237. package/script/methods/convert.d.ts.map +1 -1
  238. package/script/methods/convert.js +5 -0
  239. package/script/methods/getBottom.d.ts +1 -1
  240. package/script/methods/getBottom.d.ts.map +1 -1
  241. package/script/methods/getBottom.js +2 -2
  242. package/script/methods/getData.d.ts +1 -1
  243. package/script/methods/getData.d.ts.map +1 -1
  244. package/script/methods/getData.js +2 -2
  245. package/script/methods/join.d.ts.map +1 -1
  246. package/script/methods/join.js +8 -16
  247. package/script/methods/joinGeo.d.ts.map +1 -1
  248. package/script/methods/joinGeo.js +10 -19
  249. package/script/methods/loadArray.d.ts +4 -2
  250. package/script/methods/loadArray.d.ts.map +1 -1
  251. package/script/methods/loadArray.js +181 -17
  252. package/script/methods/loadData.js +3 -0
  253. package/script/methods/loadYahooFinanceData.d.ts +10 -0
  254. package/script/methods/loadYahooFinanceData.d.ts.map +1 -0
  255. package/script/methods/loadYahooFinanceData.js +139 -0
  256. package/script/methods/log.d.ts +7 -0
  257. package/script/methods/log.d.ts.map +1 -0
  258. package/script/methods/log.js +64 -0
  259. package/script/methods/logBottom.d.ts +5 -0
  260. package/script/methods/logBottom.d.ts.map +1 -0
  261. package/script/methods/logBottom.js +15 -0
  262. package/script/methods/removeTable.d.ts.map +1 -1
  263. package/script/methods/removeTable.js +2 -0
  264. package/script/methods/removeTables.d.ts.map +1 -1
  265. package/script/methods/removeTables.js +7 -0
  266. package/script/methods/renameTable.d.ts.map +1 -1
  267. package/script/methods/renameTable.js +4 -0
  268. package/script/methods/rowProportions.d.ts +1 -0
  269. package/script/methods/rowProportions.d.ts.map +1 -1
  270. package/script/methods/rowProportions.js +5 -1
  271. package/script/methods/rowToText.js +2 -2
  272. package/script/methods/selectTables.d.ts.map +1 -1
  273. package/script/methods/selectTables.js +6 -0
  274. package/script/methods/setTypes.d.ts +1 -1
  275. package/script/methods/setTypes.d.ts.map +1 -1
  276. package/script/methods/stream.d.ts.map +1 -1
  277. package/script/methods/stream.js +2 -1
  278. package/script/methods/updateWithJS.d.ts +1 -3
  279. package/script/methods/updateWithJS.d.ts.map +1 -1
  280. package/script/methods/updateWithJS.js +122 -36
@@ -0,0 +1,64 @@
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 = log;
7
+ const logData_js_1 = __importDefault(require("../helpers/logData.js"));
8
+ const getData_js_1 = __importDefault(require("./getData.js"));
9
+ const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
10
+ const formatNumber_js_1 = __importDefault(require("../helpers/formatNumber.js"));
11
+ async function log(simpleTable, options = {}) {
12
+ if (simpleTable.connection === undefined) {
13
+ await simpleTable.sdb.start();
14
+ simpleTable.db = simpleTable.sdb.db;
15
+ simpleTable.connection = simpleTable.sdb.connection;
16
+ }
17
+ if (simpleTable.connection === undefined) {
18
+ throw new Error("simpleTable.connection is undefined");
19
+ }
20
+ let count;
21
+ if (typeof options === "number") {
22
+ count = options;
23
+ }
24
+ else if (options === "all") {
25
+ count = await simpleTable.getRowCount();
26
+ }
27
+ else if (typeof options === "object") {
28
+ if (options.count === "all") {
29
+ count = await simpleTable.getRowCount();
30
+ }
31
+ else if (typeof options.count === "number") {
32
+ count = options.count;
33
+ }
34
+ else {
35
+ count = simpleTable.rowsToLog;
36
+ }
37
+ }
38
+ else {
39
+ count = simpleTable.rowsToLog;
40
+ }
41
+ const types = typeof options === "object"
42
+ ? options.types ?? simpleTable.typesToLog
43
+ : simpleTable.typesToLog;
44
+ const conditions = typeof options === "object"
45
+ ? options.conditions ?? undefined
46
+ : undefined;
47
+ if (simpleTable.connection === undefined ||
48
+ !(await simpleTable.sdb.hasTable(simpleTable.name))) {
49
+ console.log(`\nTable ${simpleTable.name}: no data`);
50
+ }
51
+ else {
52
+ console.log(`\nTable ${simpleTable.name}:`);
53
+ conditions && console.log(`Conditions: ${conditions}`);
54
+ const data = await (0, getData_js_1.default)(simpleTable, { limit: count, conditions }, "log()");
55
+ (0, logData_js_1.default)(types ? await simpleTable.getTypes() : null, data, simpleTable.charsToLog);
56
+ const rowCount = conditions
57
+ ? parseInt((await simpleTable.sdb.customQuery(`select count(*) as count from ${(0, quoteIdentifier_js_1.default)(simpleTable.name)} where ${conditions}`, { returnData: true }))[0].count)
58
+ : await simpleTable.getRowCount();
59
+ console.log(`${(0, formatNumber_js_1.default)(rowCount)} rows in total ${`(count: ${count}${typeof simpleTable.charsToLog === "number"
60
+ ? `, charsToLog: ${simpleTable.charsToLog}`
61
+ : ""})`}`);
62
+ }
63
+ return;
64
+ }
@@ -0,0 +1,5 @@
1
+ import type SimpleTable from "../class/SimpleTable.js";
2
+ export default function logBottom(simpleTable: SimpleTable, count?: number, options?: {
3
+ originalOrder?: boolean;
4
+ }): Promise<void>;
5
+ //# sourceMappingURL=logBottom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logBottom.d.ts","sourceRoot":"","sources":["../../src/methods/logBottom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAIvD,wBAA8B,SAAS,CACrC,WAAW,EAAE,WAAW,EACxB,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,iBAW1C"}
@@ -0,0 +1,15 @@
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 = logBottom;
7
+ const logData_js_1 = __importDefault(require("../helpers/logData.js"));
8
+ const getBottom_js_1 = __importDefault(require("./getBottom.js"));
9
+ async function logBottom(simpleTable, count, options = {}) {
10
+ const rows = count ?? simpleTable.rowsToLog;
11
+ console.log(`\nTable ${simpleTable.name} (${rows} bottom rows):`);
12
+ const data = await (0, getBottom_js_1.default)(simpleTable, rows, options, "logBottom()");
13
+ (0, logData_js_1.default)(null, data, simpleTable.charsToLog);
14
+ return;
15
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"removeTable.d.ts","sourceRoot":"","sources":["../../src/methods/removeTable.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD,wBAA8B,WAAW,CACvC,WAAW,EAAE,WAAW,iBAgBzB"}
1
+ {"version":3,"file":"removeTable.d.ts","sourceRoot":"","sources":["../../src/methods/removeTable.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD,wBAA8B,WAAW,CACvC,WAAW,EAAE,WAAW,iBAiBzB"}
@@ -4,11 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = removeTable;
7
+ const cacheTableDependencies_js_1 = require("../helpers/cacheTableDependencies.js");
7
8
  const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
8
9
  const mergeOptions_js_1 = __importDefault(require("../helpers/mergeOptions.js"));
9
10
  const queryDB_js_1 = __importDefault(require("../helpers/queryDB.js"));
10
11
  const tableRegistry_js_1 = require("../helpers/tableRegistry.js");
11
12
  async function removeTable(simpleTable) {
13
+ (0, cacheTableDependencies_js_1.assertCacheTableMutation)(simpleTable);
12
14
  await (0, queryDB_js_1.default)(simpleTable, `DROP TABLE ${(0, quoteIdentifier_js_1.default)(simpleTable.name)};`, (0, mergeOptions_js_1.default)(simpleTable, {
13
15
  table: null,
14
16
  method: "removeTable()",
@@ -1 +1 @@
1
- {"version":3,"file":"removeTables.d.ts","sourceRoot":"","sources":["../../src/methods/removeTables.ts"],"names":[],"mappings":"AAGA,OAAO,WAAW,MAAM,yBAAyB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AAIjD,wBAA8B,YAAY,CACxC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC,EAAE,iBAkCxD"}
1
+ {"version":3,"file":"removeTables.d.ts","sourceRoot":"","sources":["../../src/methods/removeTables.ts"],"names":[],"mappings":"AAIA,OAAO,WAAW,MAAM,yBAAyB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AAIjD,wBAA8B,YAAY,CACxC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC,EAAE,iBA2CxD"}
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = removeTables;
7
+ const cacheTableDependencies_js_1 = require("../helpers/cacheTableDependencies.js");
7
8
  const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
8
9
  const mergeOptions_js_1 = __importDefault(require("../helpers/mergeOptions.js"));
9
10
  const queryDB_js_1 = __importDefault(require("../helpers/queryDB.js"));
@@ -17,6 +18,12 @@ async function removeTables(simpleDB, tables) {
17
18
  ? tables
18
19
  : [tables];
19
20
  (0, assertSameDatabase_js_1.default)(simpleDB, tablesToBeRemoved.filter((table) => table instanceof SimpleTable_js_1.default), "removeTables()");
21
+ const names = tablesToBeRemoved.map((table) => (table instanceof SimpleTable_js_1.default ? table.name : table).toLowerCase());
22
+ for (const table of simpleDB.getTables()) {
23
+ if (names.includes(table.name.toLowerCase())) {
24
+ (0, cacheTableDependencies_js_1.assertCacheTableMutation)(table);
25
+ }
26
+ }
20
27
  await (0, queryDB_js_1.default)(simpleDB, tablesToBeRemoved.map((d) => `DROP TABLE ${(0, quoteIdentifier_js_1.default)(d instanceof SimpleTable_js_1.default ? d.name : d)};`).join("\n"), (0, mergeOptions_js_1.default)(simpleDB, {
21
28
  table: null,
22
29
  method: "removeTable()",
@@ -1 +1 @@
1
- {"version":3,"file":"renameTable.d.ts","sourceRoot":"","sources":["../../src/methods/renameTable.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD,wBAA8B,WAAW,CACvC,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,MAAM,iBAcb"}
1
+ {"version":3,"file":"renameTable.d.ts","sourceRoot":"","sources":["../../src/methods/renameTable.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAIvD,wBAA8B,WAAW,CACvC,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,MAAM,iBAgBb"}
@@ -4,11 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = renameTable;
7
+ const cacheTableDependencies_js_1 = require("../helpers/cacheTableDependencies.js");
7
8
  const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
8
9
  const mergeOptions_js_1 = __importDefault(require("../helpers/mergeOptions.js"));
9
10
  const queryDB_js_1 = __importDefault(require("../helpers/queryDB.js"));
10
11
  const tableGeneration_js_1 = require("../helpers/tableGeneration.js");
12
+ const tableRegistry_js_1 = require("../helpers/tableRegistry.js");
11
13
  async function renameTable(simpleTable, name) {
14
+ (0, cacheTableDependencies_js_1.assertCacheTableMutation)(simpleTable);
15
+ (0, tableRegistry_js_1.assertTableNameAvailable)(simpleTable.sdb, name, simpleTable);
12
16
  await (0, queryDB_js_1.default)(simpleTable, `ALTER TABLE ${(0, quoteIdentifier_js_1.default)(simpleTable.name)} RENAME TO ${(0, quoteIdentifier_js_1.default)(name)};`, (0, mergeOptions_js_1.default)(simpleTable, {
13
17
  table: simpleTable.name,
14
18
  method: "renameTable()",
@@ -1,6 +1,7 @@
1
1
  import type SimpleTable from "../class/SimpleTable.js";
2
2
  export default function rowProportions(simpleTable: SimpleTable, columns: string[], options?: {
3
3
  suffix?: string;
4
+ base?: number;
4
5
  decimals?: number;
5
6
  }): void;
6
7
  //# sourceMappingURL=rowProportions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rowProportions.d.ts","sourceRoot":"","sources":["../../src/methods/rowProportions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACd,QAoCP"}
1
+ {"version":3,"file":"rowProportions.d.ts","sourceRoot":"","sources":["../../src/methods/rowProportions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACd,QA4CP"}
@@ -8,6 +8,10 @@ const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier
8
8
  const assertNewColumns_js_1 = __importDefault(require("../helpers/assertNewColumns.js"));
9
9
  const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
10
10
  function rowProportions(simpleTable, columns, options = {}) {
11
+ if (options.base !== undefined &&
12
+ (!Number.isFinite(options.base) || options.base <= 0)) {
13
+ throw new Error("rowProportions() options.base must be a finite number greater than 0.");
14
+ }
11
15
  columns = [...columns];
12
16
  options = structuredClone(options);
13
17
  (0, queueOp_js_1.default)(simpleTable, {
@@ -20,7 +24,7 @@ function rowProportions(simpleTable, columns, options = {}) {
20
24
  (0, assertNewColumns_js_1.default)(schema, columns.map((col) => `${col}${suffix}`), "rowProportions()");
21
25
  let query = `SELECT *,`;
22
26
  for (const col of columns) {
23
- const tempQuery = `${(0, quoteIdentifier_js_1.default)(col)} / (${columns.map((d) => `${(0, quoteIdentifier_js_1.default)(d)}`).join(" + ")})`;
27
+ const tempQuery = `${(0, quoteIdentifier_js_1.default)(col)} / (${columns.map((d) => `${(0, quoteIdentifier_js_1.default)(d)}`).join(" + ")}) * ${options.base ?? 1}`;
24
28
  if (typeof options.decimals === "number") {
25
29
  query += ` ROUND(${tempQuery}, ${options.decimals})`;
26
30
  }
@@ -25,8 +25,8 @@ function rowToText(simpleTable, columns, newColumn) {
25
25
  throw new Error(`The column ${col} is of type ${allTypes[col]}. The rowToText() method only works with string columns. Please convert the column to string first with the .convert() method.`);
26
26
  }
27
27
  }
28
- const parts = columns.map((col) => `? || COALESCE(${(0, quoteIdentifier_js_1.default)(col)}, ?)`);
29
- const concatenatedExpression = parts.join(" || ");
28
+ const parts = columns.map((col) => `concat(?, COALESCE(${(0, quoteIdentifier_js_1.default)(col)}, ?))`);
29
+ const concatenatedExpression = `concat(${parts.join(", ")})`;
30
30
  return `SELECT *, CAST(${concatenatedExpression} AS VARCHAR) AS ${(0, quoteIdentifier_js_1.default)(newColumn)} FROM ${input}`;
31
31
  },
32
32
  });
@@ -1 +1 @@
1
- {"version":3,"file":"selectTables.d.ts","sourceRoot":"","sources":["../../src/methods/selectTables.ts"],"names":[],"mappings":"AAGA,OAAO,WAAW,MAAM,yBAAyB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AAKjD,wBAA8B,YAAY,CACxC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC,EAAE,iBA+CxD"}
1
+ {"version":3,"file":"selectTables.d.ts","sourceRoot":"","sources":["../../src/methods/selectTables.ts"],"names":[],"mappings":"AAIA,OAAO,WAAW,MAAM,yBAAyB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AAKjD,wBAA8B,YAAY,CACxC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,WAAW,GAAG,MAAM,GAAG,CAAC,WAAW,GAAG,MAAM,CAAC,EAAE,iBAqDxD"}
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = selectTables;
7
+ const cacheTableDependencies_js_1 = require("../helpers/cacheTableDependencies.js");
7
8
  const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
8
9
  const mergeOptions_js_1 = __importDefault(require("../helpers/mergeOptions.js"));
9
10
  const queryDB_js_1 = __importDefault(require("../helpers/queryDB.js"));
@@ -15,6 +16,11 @@ async function selectTables(simpleDB, tables) {
15
16
  const selected = Array.isArray(tables) ? tables : [tables];
16
17
  (0, assertSameDatabase_js_1.default)(simpleDB, selected.filter((table) => table instanceof SimpleTable_js_1.default), "selectTables()");
17
18
  const tablesToBeSelected = selected.map((t) => t instanceof SimpleTable_js_1.default ? t.name : t);
19
+ for (const table of simpleDB.getTables()) {
20
+ if (!tablesToBeSelected.includes(table.name)) {
21
+ (0, cacheTableDependencies_js_1.assertCacheTableMutation)(table);
22
+ }
23
+ }
18
24
  const existingTables = await simpleDB.getTableNames();
19
25
  const missingTables = tablesToBeSelected.filter((table) => !existingTables.includes(table));
20
26
  if (missingTables.length > 0) {
@@ -1,5 +1,5 @@
1
1
  import type SimpleTable from "../class/SimpleTable.js";
2
2
  export default function setTypes(simpleTable: SimpleTable, types: {
3
- [key: string]: "integer" | "float" | "number" | "string" | "date" | "time" | "datetime" | "datetimeTz" | "bigint" | "double" | "varchar" | "timestamp" | "timestamp with time zone" | "boolean" | `geometry('${string}')` | `GEOMETRY('${string}')`;
3
+ [key: string]: "integer" | "float" | "number" | "string" | "date" | "time" | "datetime" | "datetimeTz" | "bigint" | "double" | "varchar" | "timestamp" | "timestamp with time zone" | "boolean" | "json" | "JSON" | `float[${number}]` | `FLOAT[${number}]` | `geometry('${string}')` | `GEOMETRY('${string}')`;
4
4
  }): void;
5
5
  //# sourceMappingURL=setTypes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setTypes.d.ts","sourceRoot":"","sources":["../../src/methods/setTypes.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE;IACL,CAAC,GAAG,EAAE,MAAM,GACR,SAAS,GACT,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,0BAA0B,GAC1B,SAAS,GACT,aAAa,MAAM,IAAI,GACvB,aAAa,MAAM,IAAI,CAAC;CAC7B,QAkCF"}
1
+ {"version":3,"file":"setTypes.d.ts","sourceRoot":"","sources":["../../src/methods/setTypes.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE;IACL,CAAC,GAAG,EAAE,MAAM,GACR,SAAS,GACT,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,UAAU,GACV,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,0BAA0B,GAC1B,SAAS,GACT,MAAM,GACN,MAAM,GACN,SAAS,MAAM,GAAG,GAClB,SAAS,MAAM,GAAG,GAClB,aAAa,MAAM,IAAI,GACvB,aAAa,MAAM,IAAI,CAAC;CAC7B,QAkCF"}
@@ -1 +1 @@
1
- {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/methods/stream.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD,wBAA+B,MAAM,CACnC,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,GACL,cAAc,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAmE7D"}
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/methods/stream.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAGvD,wBAA+B,MAAM,CACnC,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,GACL,cAAc,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAsE7D"}
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = stream;
7
+ const cleanSQL_js_1 = __importDefault(require("../helpers/cleanSQL.js"));
7
8
  const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
8
9
  const runQuery_js_1 = require("../helpers/runQuery.js");
9
10
  const SDAError_js_1 = __importDefault(require("../class/SDAError.js"));
@@ -23,7 +24,7 @@ async function* stream(simpleTable, options = {}) {
23
24
  ? [options.columns]
24
25
  : options.columns)
25
26
  : undefined;
26
- const query = `SELECT ${columns ? columns.map((d) => `${(0, quoteIdentifier_js_1.default)(d)}`).join(", ") : "*"} FROM ${(0, quoteIdentifier_js_1.default)(simpleTable.name)}${options.conditions ? ` WHERE ${options.conditions}` : ""};`;
27
+ const query = (0, cleanSQL_js_1.default)(`SELECT ${columns ? columns.map((d) => `${(0, quoteIdentifier_js_1.default)(d)}`).join(", ") : "*"} FROM ${(0, quoteIdentifier_js_1.default)(simpleTable.name)}${options.conditions ? ` WHERE ${options.conditions}` : ""};`, simpleTable.sdb.expressionSyntax);
27
28
  try {
28
29
  await (0, observeQuery_js_1.default)(simpleTable.connection, query, [], {
29
30
  logSQL: simpleTable.sdb.logSQL,
@@ -3,9 +3,7 @@ type Row = {
3
3
  [key: string]: unknown;
4
4
  };
5
5
  type DataModifier = (rows: Row[]) => Row[] | Promise<Row[]>;
6
- type UpdateWithJSOptions = {
7
- batchSize?: number;
8
- };
6
+ type UpdateWithJSOptions = NonNullable<Parameters<SimpleTable["updateWithJS"]>[1]>;
9
7
  export default function updateWithJS(simpleTable: SimpleTable, dataModifier: DataModifier, options?: UpdateWithJSOptions): void;
10
8
  export {};
11
9
  //# sourceMappingURL=updateWithJS.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"updateWithJS.d.ts","sourceRoot":"","sources":["../../src/methods/updateWithJS.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAKvD,KAAK,GAAG,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAEtC,KAAK,YAAY,GAAG,CAClB,IAAI,EAAE,GAAG,EAAE,KACR,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAE5B,KAAK,mBAAmB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,EAC1B,OAAO,GAAE,mBAAwB,GAChC,IAAI,CAeN"}
1
+ {"version":3,"file":"updateWithJS.d.ts","sourceRoot":"","sources":["../../src/methods/updateWithJS.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAQvD,KAAK,GAAG,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAEtC,KAAK,YAAY,GAAG,CAClB,IAAI,EAAE,GAAG,EAAE,KACR,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAE5B,KAAK,mBAAmB,GAAG,WAAW,CACpC,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3C,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,EAC1B,OAAO,GAAE,mBAAwB,GAChC,IAAI,CAeN"}
@@ -4,10 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.default = updateWithJS;
7
+ const prepareGeometry_js_1 = __importDefault(require("../helpers/prepareGeometry.js"));
8
+ const geometryFromJSON_js_1 = __importDefault(require("../helpers/geometryFromJSON.js"));
7
9
  const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
8
10
  const tableRegistry_js_1 = require("../helpers/tableRegistry.js");
9
11
  const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
10
12
  const loadArray_js_1 = require("./loadArray.js");
13
+ const node_api_1 = require("@duckdb/node-api");
14
+ const readMutationRows_js_1 = __importDefault(require("../helpers/readMutationRows.js"));
15
+ const parseDuckDBType_js_1 = __importDefault(require("../helpers/parseDuckDBType.js"));
11
16
  function updateWithJS(simpleTable, dataModifier, options = {}) {
12
17
  if (options.batchSize !== undefined &&
13
18
  (!Number.isInteger(options.batchSize) || options.batchSize < 1)) {
@@ -23,39 +28,35 @@ function updateWithJS(simpleTable, dataModifier, options = {}) {
23
28
  }
24
29
  async function executeUpdateWithJS(simpleTable, dataModifier, options) {
25
30
  const types = await simpleTable.getTypes();
26
- // Geometry columns are typed as GEOMETRY('<crs>'), not a bare "GEOMETRY".
27
- if (Object.values(types).some((d) => d.toUpperCase().startsWith("GEOMETRY"))) {
28
- throw new Error("updateWithJS doesn't work with tables containing geometries.");
29
- }
30
- if (options.batchSize === undefined) {
31
- const oldData = await simpleTable.getData();
32
- if (!oldData) {
33
- throw new Error("No data from getData.");
31
+ const geometryColumns = Object.keys(types).filter((key) => types[key].toUpperCase().startsWith("GEOMETRY"));
32
+ for (const column of geometryColumns) {
33
+ if (types[column].toUpperCase() !== "GEOMETRY('EPSG:4326')") {
34
+ throw new Error(`Column ${JSON.stringify(column)} has CRS ${types[column]}. Call .reproject("EPSG:4326", { column: ${JSON.stringify(column)} }) before updateWithJS().`);
34
35
  }
35
- const newData = await dataModifier(oldData);
36
- if (newData.length === 0) {
37
- if (oldData.length === 0) {
38
- // Empty table in, empty data out: nothing to update.
39
- return;
40
- }
41
- throw new Error("The dataModifier returned no rows. updateWithJS can't infer the table schema from zero rows.");
36
+ const name = (0, quoteIdentifier_js_1.default)(column);
37
+ // Compare the actual binary representation, including dimensions and double
38
+ // precision, rather than assuming GeoJSON serialization is lossless.
39
+ const result = await simpleTable.connection.runAndReadAll(`SELECT count(*) AS invalid FROM ${(0, quoteIdentifier_js_1.default)(simpleTable.name)}
40
+ WHERE ${name} IS NOT NULL AND
41
+ ST_AsWKB(${name}) != ST_AsWKB(${(0, geometryFromJSON_js_1.default)(`ST_AsGeoJSON(${name})`)})`);
42
+ if (result.getRows()[0][0] !== 0n) {
43
+ throw new Error(`Column ${JSON.stringify(column)} contains geometry that cannot round-trip through GeoJSON without losing precision or dimensions; unsupported representations cannot be updated with updateWithJS().`);
42
44
  }
43
- await (0, loadArray_js_1.executePreparedArray)(simpleTable, (0, loadArray_js_1.prepareArray)(newData));
44
- return;
45
45
  }
46
- const batchSize = options.batchSize;
47
- if (Object.keys(types).includes("__sda_rowid")) {
48
- throw new Error('The table has a column named "__sda_rowid", which conflicts with the internal column used by the batchSize option. Rename it or run updateWithJS without batchSize.');
46
+ for (const key of Object.keys(options.columnTypes ?? {})) {
47
+ if (Object.keys(types).some((name) => name.toLowerCase() === key.toLowerCase())) {
48
+ throw new Error(`updateWithJS() columnTypes may only declare new columns; ${JSON.stringify(key)} already exists.`);
49
+ }
49
50
  }
50
- const rowCount = await simpleTable.getRowCount();
51
- if (rowCount === 0) {
52
- // Same behavior as the non-batched path on an empty table.
53
- const newData = await dataModifier([]);
54
- if (newData.length === 0) {
55
- return;
51
+ const batchSize = options.batchSize;
52
+ const geometryBatch = batchSize !== undefined && geometryColumns.length > 0;
53
+ if (batchSize !== undefined) {
54
+ // DuckDB resolves identifiers case-insensitively, and a real rowid column
55
+ // shadows its hidden row identifier used for pagination.
56
+ const conflictingColumn = Object.keys(types).find((column) => ["rowid", "__sda_rowid"].includes(column.toLowerCase()));
57
+ if (conflictingColumn !== undefined) {
58
+ throw new Error(`The table has a column named "${conflictingColumn}", which conflicts with the internal column used by the batchSize option. Rename it or run updateWithJS without batchSize.`);
56
59
  }
57
- await (0, loadArray_js_1.executePreparedArray)(simpleTable, (0, loadArray_js_1.prepareArray)(newData));
58
- return;
59
60
  }
60
61
  // Rows are pulled in batches by rowid, passed through the modifier, and
61
62
  // accumulated in a temporary table, so only one batch of rows is
@@ -66,27 +67,112 @@ async function executeUpdateWithJS(simpleTable, dataModifier, options) {
66
67
  try {
67
68
  let first = true;
68
69
  let lastRowid = null;
70
+ let sawRows = false;
71
+ let outputOffset = 0;
72
+ let inputOffset = 0;
69
73
  while (true) {
70
- const batch = (await simpleTable.sdb.customQuery(`SELECT *, rowid AS __sda_rowid FROM ${(0, quoteIdentifier_js_1.default)(simpleTable.name)}${lastRowid === null ? "" : ` WHERE rowid > ${lastRowid}`} ORDER BY rowid LIMIT ${batchSize}`, { returnData: true }));
71
- if (batch.length === 0) {
74
+ const page = `${(0, quoteIdentifier_js_1.default)(simpleTable.name)}${lastRowid === null ? "" : ` WHERE rowid > ${lastRowid}`}${batchSize === undefined ? "" : ` ORDER BY rowid LIMIT ${batchSize}`}`;
75
+ // Select the batch before serializing geometry. Otherwise DuckDB can
76
+ // evaluate ST_AsGeoJSON on remaining rows before applying the LIMIT,
77
+ // repeatedly converting polygons that belong to later batches.
78
+ const from = geometryBatch
79
+ ? `(SELECT *, rowid AS __sda_rowid FROM ${page}) AS __sda_batch ORDER BY __sda_rowid`
80
+ : page;
81
+ const source = await (0, readMutationRows_js_1.default)(simpleTable.connection, `SELECT ${Object.keys(types).map((key) => geometryColumns.includes(key)
82
+ ? `ST_AsGeoJSON(${(0, quoteIdentifier_js_1.default)(key)})::VARCHAR AS ${(0, quoteIdentifier_js_1.default)(key)}`
83
+ : (0, quoteIdentifier_js_1.default)(key)).join(", ")}${batchSize === undefined
84
+ ? ""
85
+ : geometryBatch
86
+ ? ", __sda_rowid"
87
+ : ", rowid AS __sda_rowid"} FROM ${from}`, batchSize === undefined ? undefined : "__sda_rowid");
88
+ const batch = source.rows;
89
+ const inputCount = batch.length;
90
+ if (inputCount === 0 && sawRows)
72
91
  break;
92
+ sawRows ||= inputCount > 0;
93
+ if (batchSize !== undefined && batch.length > 0) {
94
+ // Keep the cursor separate: adding and deleting it on every row also
95
+ // makes ordinary callback operations such as object spread slower.
96
+ lastRowid = source.lastCursorValue;
73
97
  }
74
- lastRowid = batch[batch.length - 1].__sda_rowid;
75
- for (const row of batch) {
76
- delete row.__sda_rowid;
98
+ for (const [index, row] of batch.entries()) {
99
+ for (const key of geometryColumns) {
100
+ row[key] = row[key] === null ? null : JSON.parse(row[key]);
101
+ (0, prepareGeometry_js_1.default)(row[key], key, inputOffset + index + 1);
102
+ }
77
103
  }
104
+ inputOffset += inputCount;
78
105
  const modified = await dataModifier(batch);
79
106
  if (modified.length === 0) {
107
+ if (!sawRows)
108
+ return;
109
+ if (batchSize === undefined)
110
+ break;
80
111
  continue;
81
112
  }
82
- await (0, loadArray_js_1.executePreparedArray)(scratch, (0, loadArray_js_1.prepareArray)(modified));
113
+ const keys = Object.keys(modified[0]);
114
+ for (const key of Object.keys(options.columnTypes ?? {})) {
115
+ if (!keys.includes(key)) {
116
+ throw new Error(`Unknown column ${JSON.stringify(key)} in updateWithJS columnTypes.`);
117
+ }
118
+ }
119
+ const newKeys = keys.filter((key) => !source.types.has(key));
120
+ const added = newKeys.length === 0 ? undefined : (0, loadArray_js_1.prepareArray)(modified.map((row) => Object.fromEntries(newKeys.map((key) => [key, row[key]]))), options.columnTypes);
121
+ const outputGeometry = keys.filter((key) => geometryColumns.includes(key) ||
122
+ (added && added.types[newKeys.indexOf(key)] === "GEOMETRY('EPSG:4326')"));
123
+ const outputJSON = keys.filter((key) => types[key] === "JSON" ||
124
+ (added && added.types[newKeys.indexOf(key)] === "JSON"));
125
+ if (outputGeometry.length && !simpleTable.sdb.spatialLoaded) {
126
+ await simpleTable.sdb.customQuery("INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;");
127
+ simpleTable.sdb.spatialLoaded = true;
128
+ }
129
+ const geometryData = new Map(outputGeometry.map((key) => [
130
+ key,
131
+ geometryColumns.includes(key)
132
+ ? modified.map((row, i) => (0, prepareGeometry_js_1.default)(row[key], key, outputOffset + i + 1))
133
+ : added.columnsData[newKeys.indexOf(key)],
134
+ ]));
135
+ outputOffset += modified.length;
136
+ const columnTypes = keys.map((key) => outputGeometry.includes(key) || outputJSON.includes(key)
137
+ ? (0, parseDuckDBType_js_1.default)("VARCHAR")
138
+ : source.types.get(key) ??
139
+ (0, parseDuckDBType_js_1.default)(added.types[newKeys.indexOf(key)]));
140
+ await simpleTable.sdb.customQuery(`CREATE OR REPLACE TABLE ${(0, quoteIdentifier_js_1.default)(scratch.name)} (${keys.map((key, i) => `${(0, quoteIdentifier_js_1.default)(key)} ${columnTypes[i]}`)
141
+ .join(", ")})`);
142
+ const appender = await simpleTable.connection.createAppender(scratch.name);
143
+ try {
144
+ for (let start = 0; start < modified.length; start += 2000) {
145
+ const end = Math.min(start + 2000, modified.length);
146
+ const chunk = node_api_1.DuckDBDataChunk.create(columnTypes, end - start);
147
+ for (let i = 0; i < keys.length; i++) {
148
+ const key = keys[i];
149
+ chunk.setColumnValues(i, outputGeometry.includes(key)
150
+ ? geometryData.get(key).slice(start, end)
151
+ : source.types.has(key)
152
+ ? modified.slice(start, end).map((row) => source.toNative(row[key], columnTypes[i]))
153
+ : added.columnsData[newKeys.indexOf(key)].slice(start, end));
154
+ }
155
+ appender.appendDataChunk(chunk);
156
+ }
157
+ appender.flushSync();
158
+ }
159
+ finally {
160
+ appender.closeSync();
161
+ }
162
+ const projection = keys.map((key) => outputGeometry.includes(key)
163
+ ? `${(0, geometryFromJSON_js_1.default)((0, quoteIdentifier_js_1.default)(key))} AS ${(0, quoteIdentifier_js_1.default)(key)}`
164
+ : outputJSON.includes(key)
165
+ ? `${(0, quoteIdentifier_js_1.default)(key)}::JSON AS ${(0, quoteIdentifier_js_1.default)(key)}`
166
+ : (0, quoteIdentifier_js_1.default)(key)).join(", ");
83
167
  if (first) {
84
- await simpleTable.sdb.customQuery(`CREATE OR REPLACE TABLE ${(0, quoteIdentifier_js_1.default)(accumulator)} AS SELECT * FROM ${(0, quoteIdentifier_js_1.default)(scratch.name)}`);
168
+ await simpleTable.sdb.customQuery(`CREATE OR REPLACE TABLE ${(0, quoteIdentifier_js_1.default)(accumulator)} AS SELECT ${projection} FROM ${(0, quoteIdentifier_js_1.default)(scratch.name)}`);
85
169
  first = false;
86
170
  }
87
171
  else {
88
- await simpleTable.sdb.customQuery(`INSERT INTO ${(0, quoteIdentifier_js_1.default)(accumulator)} BY NAME SELECT * FROM ${(0, quoteIdentifier_js_1.default)(scratch.name)}`);
172
+ await simpleTable.sdb.customQuery(`INSERT INTO ${(0, quoteIdentifier_js_1.default)(accumulator)} BY NAME SELECT ${projection} FROM ${(0, quoteIdentifier_js_1.default)(scratch.name)}`);
89
173
  }
174
+ if (batchSize === undefined || inputCount === 0)
175
+ break;
90
176
  }
91
177
  if (first) {
92
178
  throw new Error("The dataModifier returned no rows. updateWithJS can't infer the table schema from zero rows.");