@nshiab/simple-data-analysis-core 2.0.3 → 2.0.5
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/esm/class/SimpleTable.d.ts +202 -8
- package/esm/class/SimpleTable.d.ts.map +1 -1
- package/esm/class/SimpleTable.js +211 -9
- 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/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/columnProportions.d.ts +1 -0
- package/esm/methods/columnProportions.d.ts.map +1 -1
- package/esm/methods/columnProportions.js +7 -2
- package/esm/methods/loadArray.d.ts +4 -2
- package/esm/methods/loadArray.d.ts.map +1 -1
- package/esm/methods/loadArray.js +113 -4
- 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/rowProportions.d.ts +1 -0
- package/esm/methods/rowProportions.d.ts.map +1 -1
- package/esm/methods/rowProportions.js +5 -1
- package/llm.md +291 -14
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/script/class/SimpleTable.d.ts +202 -8
- package/script/class/SimpleTable.d.ts.map +1 -1
- package/script/class/SimpleTable.js +211 -9
- 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/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/columnProportions.d.ts +1 -0
- package/script/methods/columnProportions.d.ts.map +1 -1
- package/script/methods/columnProportions.js +7 -2
- package/script/methods/loadArray.d.ts +4 -2
- package/script/methods/loadArray.d.ts.map +1 -1
- package/script/methods/loadArray.js +112 -3
- 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/rowProportions.d.ts +1 -0
- package/script/methods/rowProportions.d.ts.map +1 -1
- package/script/methods/rowProportions.js +5 -1
|
@@ -22,6 +22,8 @@ const removeMissing_js_1 = __importDefault(require("../methods/removeMissing.js"
|
|
|
22
22
|
const getColumns_js_1 = __importDefault(require("../methods/getColumns.js"));
|
|
23
23
|
const getRowCount_js_1 = __importDefault(require("../methods/getRowCount.js"));
|
|
24
24
|
const getCharacterCount_js_1 = __importDefault(require("../methods/getCharacterCount.js"));
|
|
25
|
+
const addCharacterCount_js_1 = __importDefault(require("../methods/addCharacterCount.js"));
|
|
26
|
+
const addWordCount_js_1 = __importDefault(require("../methods/addWordCount.js"));
|
|
25
27
|
const getTypes_js_1 = __importDefault(require("../methods/getTypes.js"));
|
|
26
28
|
const getHash_js_1 = __importDefault(require("../methods/getHash.js"));
|
|
27
29
|
const getValues_js_1 = __importDefault(require("../methods/getValues.js"));
|
|
@@ -123,6 +125,7 @@ const length_js_1 = __importDefault(require("../methods/length.js"));
|
|
|
123
125
|
const area_js_1 = __importDefault(require("../methods/area.js"));
|
|
124
126
|
const reproject_js_1 = __importDefault(require("../methods/reproject.js"));
|
|
125
127
|
const reducePrecision_js_1 = __importDefault(require("../methods/reducePrecision.js"));
|
|
128
|
+
const addGeoNoise_js_1 = __importDefault(require("../methods/addGeoNoise.js"));
|
|
126
129
|
const flipCoordinates_js_1 = __importDefault(require("../methods/flipCoordinates.js"));
|
|
127
130
|
const addGeoType_js_1 = __importDefault(require("../methods/addGeoType.js"));
|
|
128
131
|
const addGeoClosedStatus_js_1 = __importDefault(require("../methods/addGeoClosedStatus.js"));
|
|
@@ -137,6 +140,7 @@ const getSchema_js_1 = __importDefault(require("../methods/getSchema.js"));
|
|
|
137
140
|
const outliersIQR_js_1 = __importDefault(require("../methods/outliersIQR.js"));
|
|
138
141
|
const bins_js_1 = __importDefault(require("../methods/bins.js"));
|
|
139
142
|
const round_js_1 = __importDefault(require("../methods/round.js"));
|
|
143
|
+
const addNoise_js_1 = __importDefault(require("../methods/addNoise.js"));
|
|
140
144
|
const rowToText_js_1 = __importDefault(require("../methods/rowToText.js"));
|
|
141
145
|
const replaceNulls_js_1 = __importDefault(require("../methods/replaceNulls.js"));
|
|
142
146
|
const pad_js_1 = __importDefault(require("../methods/pad.js"));
|
|
@@ -158,6 +162,7 @@ const insertRows_js_1 = __importDefault(require("../methods/insertRows.js"));
|
|
|
158
162
|
const loadGeoData_js_1 = __importDefault(require("../methods/loadGeoData.js"));
|
|
159
163
|
const loadOpenStreetMap_js_1 = __importDefault(require("../methods/loadOpenStreetMap.js"));
|
|
160
164
|
const loadStatCanData_js_1 = __importDefault(require("../methods/loadStatCanData.js"));
|
|
165
|
+
const loadYahooFinanceData_js_1 = __importDefault(require("../methods/loadYahooFinanceData.js"));
|
|
161
166
|
const setTypes_js_1 = __importDefault(require("../methods/setTypes.js"));
|
|
162
167
|
const flushAllTables_js_1 = __importDefault(require("../helpers/flushAllTables.js"));
|
|
163
168
|
const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
|
|
@@ -341,7 +346,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
341
346
|
return this;
|
|
342
347
|
}
|
|
343
348
|
/**
|
|
344
|
-
* Loads an array of JavaScript objects into the table. This method queues the load; it runs when an async observer method (like `getData()` or `log()`) is awaited, or when `run()` is called.
|
|
349
|
+
* Loads an array of JavaScript objects into the table. Types can also be specified for individual columns instead of inferred from their values. This method queues the load; it runs when an async observer method (like `getData()` or `log()`) is awaited, or when `run()` is called.
|
|
345
350
|
*
|
|
346
351
|
* JavaScript `Date` values are inferred as DuckDB `TIMESTAMP` values. Their
|
|
347
352
|
* instant is preserved, but JavaScript `Date` does not retain the timezone or
|
|
@@ -349,6 +354,8 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
349
354
|
* use `convert()` to parse them as temporal values.
|
|
350
355
|
*
|
|
351
356
|
* @param rows - An array of objects, where each object represents a row and its properties represent columns.
|
|
357
|
+
* @param options - Options for loading the array, captured when called.
|
|
358
|
+
* @param options.columnTypes - Types for specific columns; omitted columns are inferred. Values must be compatible with the selected type without losing information.
|
|
352
359
|
* @returns The table, so methods can be chained.
|
|
353
360
|
* @category Importing Data
|
|
354
361
|
*
|
|
@@ -364,6 +371,15 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
364
371
|
*
|
|
365
372
|
* @example
|
|
366
373
|
* ```ts
|
|
374
|
+
* // Specify a numeric type for an all-null column
|
|
375
|
+
* await table.loadArray(
|
|
376
|
+
* [{ name: "A", value: null }, { name: "B", value: null }],
|
|
377
|
+
* { columnTypes: { value: "DOUBLE" } },
|
|
378
|
+
* ).log();
|
|
379
|
+
* ```
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* ```ts
|
|
367
383
|
* // The offset determines the instant; the loaded TIMESTAMP is returned as
|
|
368
384
|
* // the equivalent UTC JavaScript Date.
|
|
369
385
|
* await table.loadArray([{
|
|
@@ -371,8 +387,8 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
371
387
|
* }]).log();
|
|
372
388
|
* ```
|
|
373
389
|
*/
|
|
374
|
-
loadArray(rows) {
|
|
375
|
-
(0, loadArray_js_1.default)(this, rows);
|
|
390
|
+
loadArray(rows, options = {}) {
|
|
391
|
+
(0, loadArray_js_1.default)(this, rows, options);
|
|
376
392
|
return this;
|
|
377
393
|
}
|
|
378
394
|
/**
|
|
@@ -503,6 +519,70 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
503
519
|
(0, loadStatCanData_js_1.default)(this, pid, options);
|
|
504
520
|
return this;
|
|
505
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* Downloads historical market data from Yahoo Finance and loads it into this
|
|
524
|
+
* table as `datetime`, `open`, `high`, `low`, `close`, `adjustedClose`, and
|
|
525
|
+
* `volume` columns. `datetime` contains Yahoo's timestamps as JavaScript
|
|
526
|
+
* `Date` values. Unavailable values are preserved as `null`.
|
|
527
|
+
*
|
|
528
|
+
* All range boundaries are evaluated in UTC. Use ISO date-time strings ending
|
|
529
|
+
* in `Z`. Yahoo trading sessions may occur on a different UTC date from their
|
|
530
|
+
* exchange-local date, so choose the range appropriate for the market and
|
|
531
|
+
* interval. Avoid numeric constructors such as `new Date(2025, 2, 15)`, which
|
|
532
|
+
* use the runtime's local timezone.
|
|
533
|
+
*
|
|
534
|
+
* This method uses an undocumented Yahoo Finance endpoint and is not
|
|
535
|
+
* affiliated with or endorsed by Yahoo. It is provided for educational,
|
|
536
|
+
* research, and journalistic purposes. Before using it, review Yahoo's terms
|
|
537
|
+
* and any applicable data-provider restrictions.
|
|
538
|
+
*
|
|
539
|
+
* The method queues the download and load; they run when an async observer
|
|
540
|
+
* method (like `getData()` or `log()`) is awaited, or when `run()` is called.
|
|
541
|
+
*
|
|
542
|
+
* @param symbol - The stock or index symbol, such as `"AAPL"` or `"^GSPTSE"`.
|
|
543
|
+
* @param startDate - The inclusive UTC start of the requested range.
|
|
544
|
+
* @param endDate - The inclusive UTC end of the requested range. The UTC day,
|
|
545
|
+
* hour, or minute containing this instant is included, according to
|
|
546
|
+
* `interval`.
|
|
547
|
+
* @param interval - The interval between observations: daily, hourly, or every
|
|
548
|
+
* minute.
|
|
549
|
+
* @returns The table, so methods can be chained.
|
|
550
|
+
* @throws {RangeError} If either date is invalid or `endDate` is before `startDate`.
|
|
551
|
+
* @throws {Error} If Yahoo rejects the request or returns no data.
|
|
552
|
+
* @see https://legal.yahoo.com/us/en/yahoo/terms/otos/index.html
|
|
553
|
+
* @see https://help.yahoo.com/kb/finance/SLN2310.html
|
|
554
|
+
* @category Importing Data
|
|
555
|
+
*
|
|
556
|
+
* @example
|
|
557
|
+
* ```ts
|
|
558
|
+
* // Request daily observations using explicit UTC boundaries.
|
|
559
|
+
* await table
|
|
560
|
+
* .loadYahooFinanceData(
|
|
561
|
+
* "^GSPTSE",
|
|
562
|
+
* new Date("2025-03-01T00:00:00Z"),
|
|
563
|
+
* new Date("2025-03-15T00:00:00Z"),
|
|
564
|
+
* "1d",
|
|
565
|
+
* )
|
|
566
|
+
* .log();
|
|
567
|
+
* ```
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```ts
|
|
571
|
+
* // Include the UTC hours from 13:00 through 16:00.
|
|
572
|
+
* await table
|
|
573
|
+
* .loadYahooFinanceData(
|
|
574
|
+
* "AAPL",
|
|
575
|
+
* new Date("2025-03-14T13:00:00Z"),
|
|
576
|
+
* new Date("2025-03-14T16:00:00Z"),
|
|
577
|
+
* "1h",
|
|
578
|
+
* )
|
|
579
|
+
* .log();
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
loadYahooFinanceData(symbol, startDate, endDate, interval) {
|
|
583
|
+
(0, loadYahooFinanceData_js_1.default)(this, symbol, startDate, endDate, interval);
|
|
584
|
+
return this;
|
|
585
|
+
}
|
|
506
586
|
/**
|
|
507
587
|
* Loads geospatial data from an external file or URL into the table.
|
|
508
588
|
*
|
|
@@ -2695,6 +2775,37 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
2695
2775
|
(0, round_js_1.default)(this, columns, options);
|
|
2696
2776
|
return this;
|
|
2697
2777
|
}
|
|
2778
|
+
/**
|
|
2779
|
+
* Adds independently generated uniform random noise to numeric values in one or more columns.
|
|
2780
|
+
* Each changed value receives an offset between `-max` and `max`. Selected integer and decimal columns become `DOUBLE` columns so fractional noise is retained. This method adds random jitter; it does not provide anonymization or differential privacy guarantees.
|
|
2781
|
+
*
|
|
2782
|
+
* This method queues the operation; it runs when an async observer method (like `getData()` or `log()`) is awaited, or when `run()` is called.
|
|
2783
|
+
*
|
|
2784
|
+
* @param columns - The numeric column name or array of numeric column names to which noise will be added. When multiple columns are provided, each value receives an independent random offset.
|
|
2785
|
+
* @param max - The maximum absolute offset, expressed in each column's units. Must be a finite number greater than or equal to `0`.
|
|
2786
|
+
* @param options - An optional object with configuration options:
|
|
2787
|
+
* @param options.onlyDuplicates - If `true`, adds noise only to values that occur more than once in their column. Each selected column is evaluated independently, and every occurrence of a duplicated value is changed. Defaults to `false`.
|
|
2788
|
+
* @returns The table, so methods can be chained.
|
|
2789
|
+
* @category Updating Data
|
|
2790
|
+
*
|
|
2791
|
+
* @example
|
|
2792
|
+
* ```ts
|
|
2793
|
+
* // Add an offset between -0.01 and 0.01 to every value
|
|
2794
|
+
* await table.addNoise("measurement", 0.01).log();
|
|
2795
|
+
* ```
|
|
2796
|
+
*
|
|
2797
|
+
* @example
|
|
2798
|
+
* ```ts
|
|
2799
|
+
* // Add noise independently to duplicated x values and duplicated y values
|
|
2800
|
+
* await table.addNoise(["x", "y"], 0.1, {
|
|
2801
|
+
* onlyDuplicates: true,
|
|
2802
|
+
* }).log();
|
|
2803
|
+
* ```
|
|
2804
|
+
*/
|
|
2805
|
+
addNoise(columns, max, options = {}) {
|
|
2806
|
+
(0, addNoise_js_1.default)(this, columns, max, options);
|
|
2807
|
+
return this;
|
|
2808
|
+
}
|
|
2698
2809
|
/**
|
|
2699
2810
|
* Updates values in a specified column using a SQL expression.
|
|
2700
2811
|
*
|
|
@@ -2878,11 +2989,18 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
2878
2989
|
* | 2022 | 354 | 278 | 56 | 0.51 | 0.4 | 0.08 |
|
|
2879
2990
|
* | 2023 | 856 | 321 | 221 | 0.61 | 0.23 | 0.16 |
|
|
2880
2991
|
*
|
|
2992
|
+
* @example
|
|
2993
|
+
* ```ts
|
|
2994
|
+
* // Compute percentages that sum to 100 on each row before rounding
|
|
2995
|
+
* await table.rowProportions(["Men", "Women", "NonBinary"], { base: 100, decimals: 1 }).log();
|
|
2996
|
+
* ```
|
|
2997
|
+
*
|
|
2881
2998
|
* This method queues the operation; it runs when an async observer method (like `getData()` or `log()`) is awaited, or when `run()` is called.
|
|
2882
2999
|
*
|
|
2883
3000
|
* @param columns - An array of column names for which proportions will be computed on each row.
|
|
2884
3001
|
* @param options - An optional object with configuration options:
|
|
2885
3002
|
* @param options.suffix - A string suffix to append to the names of the new columns storing the computed proportions. Defaults to `"Perc"`.
|
|
3003
|
+
* @param options.base - A finite positive value that the proportions in each row sum to before rounding. Defaults to `1`.
|
|
2886
3004
|
* @param options.decimals - The number of decimal places to round the computed proportions. Defaults to `undefined` (no rounding).
|
|
2887
3005
|
* @returns The table, so methods can be chained.
|
|
2888
3006
|
* @category Analyzing Data
|
|
@@ -2947,6 +3065,7 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
2947
3065
|
* @param newColumn - The name of the new column where the proportions will be stored.
|
|
2948
3066
|
* @param options - An optional object with configuration options:
|
|
2949
3067
|
* @param options.by - The column name or an array of column names to partition by. Proportions are calculated independently within each group.
|
|
3068
|
+
* @param options.base - A finite positive value that the proportions in the column or each group sum to before rounding. Defaults to `1`.
|
|
2950
3069
|
* @param options.decimals - The number of decimal places to round the computed proportions. Defaults to `undefined` (no rounding).
|
|
2951
3070
|
* @returns The table, so methods can be chained.
|
|
2952
3071
|
* @category Analyzing Data
|
|
@@ -2965,6 +3084,12 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
2965
3084
|
*
|
|
2966
3085
|
* @example
|
|
2967
3086
|
* ```ts
|
|
3087
|
+
* // Compute percentages that sum to 100 before rounding
|
|
3088
|
+
* await table.columnProportions("sales", "sales_percentage", { base: 100, decimals: 1 }).log();
|
|
3089
|
+
* ```
|
|
3090
|
+
*
|
|
3091
|
+
* @example
|
|
3092
|
+
* ```ts
|
|
2968
3093
|
* // Compute proportions for 'sales' by 'region' and 'product_type'
|
|
2969
3094
|
* await table.columnProportions("sales", "sales_proportion", { by: ["region", "product_type"] }).log();
|
|
2970
3095
|
* ```
|
|
@@ -3475,17 +3600,15 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
3475
3600
|
*
|
|
3476
3601
|
* @example
|
|
3477
3602
|
* ```ts
|
|
3478
|
-
* //
|
|
3479
|
-
* const segmenter = new Intl.Segmenter(undefined, { granularity: "word" });
|
|
3603
|
+
* // Extract hostnames with JavaScript's URL parser.
|
|
3480
3604
|
* const table = await sdb
|
|
3481
3605
|
* .newTable()
|
|
3482
|
-
* .loadData("
|
|
3606
|
+
* .loadData("websites.csv")
|
|
3483
3607
|
* .updateWithJS((rows) => {
|
|
3484
3608
|
* return rows.map((row) => ({
|
|
3485
3609
|
* ...row,
|
|
3486
|
-
*
|
|
3487
|
-
* ?
|
|
3488
|
-
* .length
|
|
3610
|
+
* hostname: typeof row.url === "string"
|
|
3611
|
+
* ? new URL(row.url).hostname
|
|
3489
3612
|
* : null,
|
|
3490
3613
|
* }));
|
|
3491
3614
|
* })
|
|
@@ -3634,8 +3757,52 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
3634
3757
|
const result = (await (0, getColumns_js_1.default)(this)).length;
|
|
3635
3758
|
return result;
|
|
3636
3759
|
}
|
|
3760
|
+
/**
|
|
3761
|
+
* Adds a new column containing the number of characters in each string in the specified column.
|
|
3762
|
+
* Counts are based on Unicode code points, not grapheme clusters. A user-perceived character composed of multiple code points, such as some emoji or decomposed accented letters, counts as multiple characters.
|
|
3763
|
+
* `NULL` input values produce `NULL` counts.
|
|
3764
|
+
*
|
|
3765
|
+
* This method queues the operation; it runs when an async observer method (like `getData()` or `log()`) is awaited, or when `run()` is called.
|
|
3766
|
+
*
|
|
3767
|
+
* @param column - The name of the column containing the strings to count.
|
|
3768
|
+
* @param newColumn - The name of the new column where the character counts will be stored.
|
|
3769
|
+
* @returns The table, so methods can be chained.
|
|
3770
|
+
* @category Text Processing
|
|
3771
|
+
*
|
|
3772
|
+
* @example
|
|
3773
|
+
* ```ts
|
|
3774
|
+
* // Add a character count for each value in the 'name' column
|
|
3775
|
+
* await table.addCharacterCount("name", "nameCharacterCount").log();
|
|
3776
|
+
* ```
|
|
3777
|
+
*/
|
|
3778
|
+
addCharacterCount(column, newColumn) {
|
|
3779
|
+
(0, addCharacterCount_js_1.default)(this, column, newColumn);
|
|
3780
|
+
return this;
|
|
3781
|
+
}
|
|
3782
|
+
/**
|
|
3783
|
+
* Adds a new column containing the word count for each string in the specified column.
|
|
3784
|
+
* A word is any contiguous sequence of non-whitespace characters. Spaces, tabs, and line breaks separate words. Punctuation is not removed, so a standalone punctuation sequence counts as a word. Text without whitespace counts as one word, regardless of language. Empty or whitespace-only strings produce `0`, and `NULL` input values produce `NULL` counts.
|
|
3785
|
+
*
|
|
3786
|
+
* This method queues the operation; it runs when an async observer method (like `getData()` or `log()`) is awaited, or when `run()` is called.
|
|
3787
|
+
*
|
|
3788
|
+
* @param column - The name of the column containing the strings to count.
|
|
3789
|
+
* @param newColumn - The name of the new column where the word counts will be stored.
|
|
3790
|
+
* @returns The table, so methods can be chained.
|
|
3791
|
+
* @category Text Processing
|
|
3792
|
+
*
|
|
3793
|
+
* @example
|
|
3794
|
+
* ```ts
|
|
3795
|
+
* // Add a word count for each value in the 'article' column
|
|
3796
|
+
* await table.addWordCount("article", "wordCount").log();
|
|
3797
|
+
* ```
|
|
3798
|
+
*/
|
|
3799
|
+
addWordCount(column, newColumn) {
|
|
3800
|
+
(0, addWordCount_js_1.default)(this, column, newColumn);
|
|
3801
|
+
return this;
|
|
3802
|
+
}
|
|
3637
3803
|
/**
|
|
3638
3804
|
* Returns the total number of characters in a column storing strings.
|
|
3805
|
+
* Counts are based on Unicode code points, not grapheme clusters. A user-perceived character composed of multiple code points, such as some emoji or decomposed accented letters, counts as multiple characters.
|
|
3639
3806
|
*
|
|
3640
3807
|
* @param column - The name of the string column to count characters from.
|
|
3641
3808
|
* @returns A promise that resolves to the total number of characters across all rows in the specified column.
|
|
@@ -4465,6 +4632,41 @@ class SimpleTable extends Simple_js_1.default {
|
|
|
4465
4632
|
(0, flipCoordinates_js_1.default)(this, column);
|
|
4466
4633
|
return this;
|
|
4467
4634
|
}
|
|
4635
|
+
/**
|
|
4636
|
+
* Moves EPSG:4326 point geometries to random locations within a maximum great-circle distance of their original positions.
|
|
4637
|
+
*
|
|
4638
|
+
* Points are sampled uniformly within the requested distance using the spherical direct geodesic (destination-point) formula and the same spherical Earth model as DuckDB's `ST_Distance_Sphere()`. This accounts for longitude scale changing with latitude. This method adds random jitter; it does not provide anonymization or differential privacy guarantees.
|
|
4639
|
+
*
|
|
4640
|
+
* This method supports only `POINT` geometries in `EPSG:4326`. Null and empty geometries are preserved. It queues the operation; the operation runs when an async observer method (like `getData()` or `log()`) is awaited, or when `run()` is called.
|
|
4641
|
+
*
|
|
4642
|
+
* @param maxDistance - The maximum great-circle displacement in the selected unit. Must be a finite number greater than or equal to `0` and no greater than half Earth's circumference.
|
|
4643
|
+
* @param options - An optional object with configuration options:
|
|
4644
|
+
* @param options.column - The name of the EPSG:4326 point geometry column. If omitted, the method will automatically attempt to find a geometry column.
|
|
4645
|
+
* @param options.unit - The unit of `maxDistance`: `"m"` for metres or `"km"` for kilometres. Defaults to `"m"`.
|
|
4646
|
+
* @param options.onlyDuplicates - If `true`, moves only points whose complete original geometry occurs more than once in the selected geometry column. Every point in a duplicated group is moved. Defaults to `false`.
|
|
4647
|
+
* @returns The table, so methods can be chained.
|
|
4648
|
+
* @category Geospatial
|
|
4649
|
+
*
|
|
4650
|
+
* @example
|
|
4651
|
+
* ```ts
|
|
4652
|
+
* // Move every point by no more than 500 metres
|
|
4653
|
+
* await table.addGeoNoise(500).log();
|
|
4654
|
+
* ```
|
|
4655
|
+
*
|
|
4656
|
+
* @example
|
|
4657
|
+
* ```ts
|
|
4658
|
+
* // Separate duplicated points by up to 0.1 kilometres
|
|
4659
|
+
* await table.addGeoNoise(0.1, {
|
|
4660
|
+
* column: "geom",
|
|
4661
|
+
* unit: "km",
|
|
4662
|
+
* onlyDuplicates: true,
|
|
4663
|
+
* }).log();
|
|
4664
|
+
* ```
|
|
4665
|
+
*/
|
|
4666
|
+
addGeoNoise(maxDistance, options = {}) {
|
|
4667
|
+
(0, addGeoNoise_js_1.default)(this, maxDistance, options);
|
|
4668
|
+
return this;
|
|
4669
|
+
}
|
|
4468
4670
|
/**
|
|
4469
4671
|
* Reduces the precision of geometries in a specified column to a given number of decimal places.
|
|
4470
4672
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addCharacterCount.d.ts","sourceRoot":"","sources":["../../src/methods/addCharacterCount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAKvD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,QAclB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
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 = addCharacterCount;
|
|
7
|
+
const assertNewColumns_js_1 = __importDefault(require("../helpers/assertNewColumns.js"));
|
|
8
|
+
const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
|
|
9
|
+
const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
|
|
10
|
+
function addCharacterCount(simpleTable, column, newColumn) {
|
|
11
|
+
(0, queueOp_js_1.default)(simpleTable, {
|
|
12
|
+
kind: "fusable",
|
|
13
|
+
method: "addCharacterCount()",
|
|
14
|
+
parameters: { column, newColumn },
|
|
15
|
+
needsSchema: true,
|
|
16
|
+
buildSelect: (input, types) => {
|
|
17
|
+
(0, assertNewColumns_js_1.default)(types, [newColumn], "addCharacterCount()");
|
|
18
|
+
return `SELECT *, LENGTH(${(0, quoteIdentifier_js_1.default)(column)}) AS ${(0, quoteIdentifier_js_1.default)(newColumn)} FROM ${input}`;
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type SimpleTable from "../class/SimpleTable.js";
|
|
2
|
+
export default function addGeoNoise(simpleTable: SimpleTable, maxDistance: number, options?: {
|
|
3
|
+
column?: string;
|
|
4
|
+
unit?: "m" | "km";
|
|
5
|
+
onlyDuplicates?: boolean;
|
|
6
|
+
}): void;
|
|
7
|
+
//# sourceMappingURL=addGeoNoise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addGeoNoise.d.ts","sourceRoot":"","sources":["../../src/methods/addGeoNoise.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAKvD,MAAM,CAAC,OAAO,UAAU,WAAW,CACjC,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;CACrB,QA2CP"}
|
|
@@ -0,0 +1,141 @@
|
|
|
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 = addGeoNoise;
|
|
7
|
+
const findGeoColumnFromSchema_js_1 = __importDefault(require("../helpers/findGeoColumnFromSchema.js"));
|
|
8
|
+
const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
|
|
9
|
+
const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
|
|
10
|
+
// This is the mean Earth radius used by DuckDB's ST_Distance_Sphere().
|
|
11
|
+
const EARTH_RADIUS_METERS = 6_371_000;
|
|
12
|
+
function addGeoNoise(simpleTable, maxDistance, options = {}) {
|
|
13
|
+
// This validation doesn't need the database, so it stays at call time.
|
|
14
|
+
if (!Number.isFinite(maxDistance) || maxDistance < 0) {
|
|
15
|
+
throw new Error("addGeoNoise() maxDistance must be a finite number greater than or equal to 0.");
|
|
16
|
+
}
|
|
17
|
+
if (options.unit !== undefined && options.unit !== "m" && options.unit !== "km") {
|
|
18
|
+
throw new Error('addGeoNoise() options.unit must be "m" or "km".');
|
|
19
|
+
}
|
|
20
|
+
options = structuredClone(options);
|
|
21
|
+
const maxDistanceMeters = options.unit === "km"
|
|
22
|
+
? maxDistance * 1_000
|
|
23
|
+
: maxDistance;
|
|
24
|
+
if (maxDistanceMeters > Math.PI * EARTH_RADIUS_METERS) {
|
|
25
|
+
throw new Error("addGeoNoise() maxDistance cannot exceed half the Earth's circumference.");
|
|
26
|
+
}
|
|
27
|
+
(0, queueOp_js_1.default)(simpleTable, {
|
|
28
|
+
kind: "fusable",
|
|
29
|
+
method: "addGeoNoise()",
|
|
30
|
+
parameters: { maxDistance, options },
|
|
31
|
+
needsSchema: true,
|
|
32
|
+
needsSpatial: true,
|
|
33
|
+
preservesSchema: true,
|
|
34
|
+
buildSelect: (input, schema) => {
|
|
35
|
+
const column = options.column ??
|
|
36
|
+
(0, findGeoColumnFromSchema_js_1.default)(schema, "addGeoNoise()", simpleTable.name);
|
|
37
|
+
return addGeoNoiseSelect(input, schema, column, maxDistanceMeters, options.onlyDuplicates === true);
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function addGeoNoiseSelect(input, schema, column, maxDistanceMeters, onlyDuplicates) {
|
|
42
|
+
const type = schema[column];
|
|
43
|
+
if (type === undefined) {
|
|
44
|
+
throw new Error(`addGeoNoise() could not find column ${(0, quoteIdentifier_js_1.default)(column)}.`);
|
|
45
|
+
}
|
|
46
|
+
if (type !== "GEOMETRY('EPSG:4326')") {
|
|
47
|
+
throw new Error(`addGeoNoise() requires an EPSG:4326 geometry column, but ${(0, quoteIdentifier_js_1.default)(column)} has type ${type}. Reproject it to EPSG:4326 first.`);
|
|
48
|
+
}
|
|
49
|
+
const internalNames = makeInternalNames(schema, input);
|
|
50
|
+
const quotedColumn = (0, quoteIdentifier_js_1.default)(column);
|
|
51
|
+
const pointError = `error('addGeoNoise() requires POINT geometries in column ${column.replaceAll("'", "''")}.')`;
|
|
52
|
+
const coordinateGuard = (coordinate) => `CASE
|
|
53
|
+
WHEN ${quotedColumn} IS NULL OR ST_IsEmpty(${quotedColumn}) THEN NULL
|
|
54
|
+
WHEN CAST(ST_GeometryType(${quotedColumn}) AS VARCHAR) <> 'POINT'
|
|
55
|
+
THEN ${pointError}
|
|
56
|
+
ELSE radians(ST_${coordinate}(${quotedColumn}))
|
|
57
|
+
END`;
|
|
58
|
+
const duplicateCount = onlyDuplicates
|
|
59
|
+
? `COUNT(*) OVER (PARTITION BY ${quotedColumn})`
|
|
60
|
+
: "2";
|
|
61
|
+
const maxAngularDistance = maxDistanceMeters / EARTH_RADIUS_METERS;
|
|
62
|
+
const latitudeExpression = `asin(
|
|
63
|
+
sin(${(0, quoteIdentifier_js_1.default)(internalNames.latitude)}) * cos(${(0, quoteIdentifier_js_1.default)(internalNames.angularDistance)}) +
|
|
64
|
+
cos(${(0, quoteIdentifier_js_1.default)(internalNames.latitude)}) * sin(${(0, quoteIdentifier_js_1.default)(internalNames.angularDistance)}) * cos(${(0, quoteIdentifier_js_1.default)(internalNames.bearing)})
|
|
65
|
+
)`;
|
|
66
|
+
const longitudeExpression = `${(0, quoteIdentifier_js_1.default)(internalNames.longitude)} + atan2(
|
|
67
|
+
sin(${(0, quoteIdentifier_js_1.default)(internalNames.bearing)}) * sin(${(0, quoteIdentifier_js_1.default)(internalNames.angularDistance)}) * cos(${(0, quoteIdentifier_js_1.default)(internalNames.latitude)}),
|
|
68
|
+
cos(${(0, quoteIdentifier_js_1.default)(internalNames.angularDistance)}) -
|
|
69
|
+
sin(${(0, quoteIdentifier_js_1.default)(internalNames.latitude)}) * sin(${(0, quoteIdentifier_js_1.default)(internalNames.destinationLatitude)})
|
|
70
|
+
)`;
|
|
71
|
+
const replacement = `CASE
|
|
72
|
+
WHEN ${quotedColumn} IS NULL OR ST_IsEmpty(${quotedColumn}) THEN ${quotedColumn}
|
|
73
|
+
WHEN ${(0, quoteIdentifier_js_1.default)(internalNames.duplicateCount)} <= 1 THEN ${quotedColumn}
|
|
74
|
+
ELSE ST_Point(
|
|
75
|
+
degrees(atan2(
|
|
76
|
+
sin(${(0, quoteIdentifier_js_1.default)(internalNames.destinationLongitude)}),
|
|
77
|
+
cos(${(0, quoteIdentifier_js_1.default)(internalNames.destinationLongitude)})
|
|
78
|
+
)),
|
|
79
|
+
degrees(${(0, quoteIdentifier_js_1.default)(internalNames.destinationLatitude)})
|
|
80
|
+
)::GEOMETRY('EPSG:4326')
|
|
81
|
+
END AS ${quotedColumn}`;
|
|
82
|
+
const outputColumns = Object.keys(schema).map((outputColumn) => outputColumn === column ? replacement : (0, quoteIdentifier_js_1.default)(outputColumn)).join(", ");
|
|
83
|
+
return `WITH ${(0, quoteIdentifier_js_1.default)(internalNames.randomValues)} AS MATERIALIZED (
|
|
84
|
+
SELECT *,
|
|
85
|
+
random() AS ${(0, quoteIdentifier_js_1.default)(internalNames.distanceRandom)},
|
|
86
|
+
random() AS ${(0, quoteIdentifier_js_1.default)(internalNames.bearingRandom)},
|
|
87
|
+
${duplicateCount} AS ${(0, quoteIdentifier_js_1.default)(internalNames.duplicateCount)}
|
|
88
|
+
FROM ${input}
|
|
89
|
+
),
|
|
90
|
+
${(0, quoteIdentifier_js_1.default)(internalNames.start)} AS (
|
|
91
|
+
SELECT *,
|
|
92
|
+
${coordinateGuard("Y")} AS ${(0, quoteIdentifier_js_1.default)(internalNames.latitude)},
|
|
93
|
+
${coordinateGuard("X")} AS ${(0, quoteIdentifier_js_1.default)(internalNames.longitude)},
|
|
94
|
+
2 * pi() * ${(0, quoteIdentifier_js_1.default)(internalNames.bearingRandom)} AS ${(0, quoteIdentifier_js_1.default)(internalNames.bearing)},
|
|
95
|
+
2 * asin(
|
|
96
|
+
sqrt(${(0, quoteIdentifier_js_1.default)(internalNames.distanceRandom)}) *
|
|
97
|
+
sin(${maxAngularDistance} / 2)
|
|
98
|
+
) AS ${(0, quoteIdentifier_js_1.default)(internalNames.angularDistance)}
|
|
99
|
+
FROM ${(0, quoteIdentifier_js_1.default)(internalNames.randomValues)}
|
|
100
|
+
),
|
|
101
|
+
${(0, quoteIdentifier_js_1.default)(internalNames.destinationLatitudeCte)} AS (
|
|
102
|
+
SELECT *, ${latitudeExpression} AS ${(0, quoteIdentifier_js_1.default)(internalNames.destinationLatitude)}
|
|
103
|
+
FROM ${(0, quoteIdentifier_js_1.default)(internalNames.start)}
|
|
104
|
+
),
|
|
105
|
+
${(0, quoteIdentifier_js_1.default)(internalNames.destination)} AS (
|
|
106
|
+
SELECT *, ${longitudeExpression} AS ${(0, quoteIdentifier_js_1.default)(internalNames.destinationLongitude)}
|
|
107
|
+
FROM ${(0, quoteIdentifier_js_1.default)(internalNames.destinationLatitudeCte)}
|
|
108
|
+
)
|
|
109
|
+
SELECT ${outputColumns}
|
|
110
|
+
FROM ${(0, quoteIdentifier_js_1.default)(internalNames.destination)}`;
|
|
111
|
+
}
|
|
112
|
+
function makeInternalNames(schema, input) {
|
|
113
|
+
const used = new Set(Object.keys(schema));
|
|
114
|
+
if (input.startsWith('"') && input.endsWith('"')) {
|
|
115
|
+
used.add(input.slice(1, -1).replaceAll('""', '"'));
|
|
116
|
+
}
|
|
117
|
+
const next = (base) => {
|
|
118
|
+
let name = base;
|
|
119
|
+
let suffix = 2;
|
|
120
|
+
while (used.has(name)) {
|
|
121
|
+
name = `${base}_${suffix++}`;
|
|
122
|
+
}
|
|
123
|
+
used.add(name);
|
|
124
|
+
return name;
|
|
125
|
+
};
|
|
126
|
+
return {
|
|
127
|
+
randomValues: next("__sda_add_geo_noise_random_values"),
|
|
128
|
+
start: next("__sda_add_geo_noise_start"),
|
|
129
|
+
destinationLatitudeCte: next("__sda_add_geo_noise_latitude_result"),
|
|
130
|
+
destination: next("__sda_add_geo_noise_result"),
|
|
131
|
+
distanceRandom: next("__sda_add_geo_noise_distance_random"),
|
|
132
|
+
bearingRandom: next("__sda_add_geo_noise_bearing_random"),
|
|
133
|
+
duplicateCount: next("__sda_add_geo_noise_duplicate_count"),
|
|
134
|
+
latitude: next("__sda_add_geo_noise_latitude"),
|
|
135
|
+
longitude: next("__sda_add_geo_noise_longitude"),
|
|
136
|
+
bearing: next("__sda_add_geo_noise_bearing"),
|
|
137
|
+
angularDistance: next("__sda_add_geo_noise_angular_distance"),
|
|
138
|
+
destinationLatitude: next("__sda_add_geo_noise_destination_latitude"),
|
|
139
|
+
destinationLongitude: next("__sda_add_geo_noise_destination_longitude"),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addNoise.d.ts","sourceRoot":"","sources":["../../src/methods/addNoise.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,QAwC3C"}
|
|
@@ -0,0 +1,59 @@
|
|
|
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 = addNoise;
|
|
7
|
+
const assertColumnsExist_js_1 = __importDefault(require("../helpers/assertColumnsExist.js"));
|
|
8
|
+
const keepNumericalColumns_js_1 = __importDefault(require("../helpers/keepNumericalColumns.js"));
|
|
9
|
+
const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
|
|
10
|
+
const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
|
|
11
|
+
const stringToArray_js_1 = __importDefault(require("../helpers/stringToArray.js"));
|
|
12
|
+
function addNoise(simpleTable, columns, max, options = {}) {
|
|
13
|
+
// This validation doesn't need the database, so it stays at call time.
|
|
14
|
+
if (!Number.isFinite(max) || max < 0) {
|
|
15
|
+
throw new Error("addNoise() max must be a finite number greater than or equal to 0.");
|
|
16
|
+
}
|
|
17
|
+
const cols = (0, stringToArray_js_1.default)(columns);
|
|
18
|
+
if (cols.length === 0) {
|
|
19
|
+
throw new Error("addNoise() requires at least one column.");
|
|
20
|
+
}
|
|
21
|
+
const duplicateColumns = cols.filter((column, index) => cols.indexOf(column) !== index);
|
|
22
|
+
if (duplicateColumns.length > 0) {
|
|
23
|
+
const duplicates = [...new Set(duplicateColumns)];
|
|
24
|
+
throw new Error(`addNoise() received duplicate column${duplicates.length === 1 ? "" : "s"} ${duplicates.map(quoteIdentifier_js_1.default).join(", ")}. Include each column only once.`);
|
|
25
|
+
}
|
|
26
|
+
options = structuredClone(options);
|
|
27
|
+
(0, queueOp_js_1.default)(simpleTable, {
|
|
28
|
+
kind: "fusable",
|
|
29
|
+
method: "addNoise()",
|
|
30
|
+
parameters: { columns: cols, max, options },
|
|
31
|
+
needsSchema: true,
|
|
32
|
+
outputSchema: (schema) => ({
|
|
33
|
+
...schema,
|
|
34
|
+
...Object.fromEntries(cols.map((column) => [column, "DOUBLE"])),
|
|
35
|
+
}),
|
|
36
|
+
buildSelect: (input, schema) => addNoiseSelect(input, schema, cols, max, options.onlyDuplicates === true),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function addNoiseSelect(input, schema, columns, max, onlyDuplicates) {
|
|
40
|
+
(0, assertColumnsExist_js_1.default)(schema, columns, "addNoise()");
|
|
41
|
+
const numericalColumns = new Set((0, keepNumericalColumns_js_1.default)(schema));
|
|
42
|
+
const nonNumericalColumns = columns.filter((column) => !numericalColumns.has(column));
|
|
43
|
+
if (nonNumericalColumns.length > 0) {
|
|
44
|
+
throw new Error(`addNoise() requires numeric columns, but ${nonNumericalColumns.map((column) => `${(0, quoteIdentifier_js_1.default)(column)} has type ${schema[column]}`).join(", ")}. Convert ${nonNumericalColumns.length === 1 ? "it" : "them"} to a numeric type first.`);
|
|
45
|
+
}
|
|
46
|
+
const replacements = columns.map((column) => {
|
|
47
|
+
const quotedColumn = (0, quoteIdentifier_js_1.default)(column);
|
|
48
|
+
const duplicateCondition = onlyDuplicates
|
|
49
|
+
? `COUNT(*) OVER (PARTITION BY ${quotedColumn}) > 1`
|
|
50
|
+
: "TRUE";
|
|
51
|
+
return `CASE
|
|
52
|
+
WHEN ${quotedColumn} IS NULL THEN NULL
|
|
53
|
+
WHEN ${duplicateCondition}
|
|
54
|
+
THEN CAST(${quotedColumn} AS DOUBLE) + (random() * 2 - 1) * ${max}
|
|
55
|
+
ELSE CAST(${quotedColumn} AS DOUBLE)
|
|
56
|
+
END AS ${quotedColumn}`;
|
|
57
|
+
}).join(", ");
|
|
58
|
+
return `SELECT * REPLACE (${replacements}) FROM ${input}`;
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addWordCount.d.ts","sourceRoot":"","sources":["../../src/methods/addWordCount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAKvD,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,QAclB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
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 = addWordCount;
|
|
7
|
+
const assertNewColumns_js_1 = __importDefault(require("../helpers/assertNewColumns.js"));
|
|
8
|
+
const queueOp_js_1 = __importDefault(require("../helpers/queueOp.js"));
|
|
9
|
+
const quoteIdentifier_js_1 = __importDefault(require("../helpers/quoteIdentifier.js"));
|
|
10
|
+
function addWordCount(simpleTable, column, newColumn) {
|
|
11
|
+
(0, queueOp_js_1.default)(simpleTable, {
|
|
12
|
+
kind: "fusable",
|
|
13
|
+
method: "addWordCount()",
|
|
14
|
+
parameters: { column, newColumn },
|
|
15
|
+
needsSchema: true,
|
|
16
|
+
buildSelect: (input, types) => {
|
|
17
|
+
(0, assertNewColumns_js_1.default)(types, [newColumn], "addWordCount()");
|
|
18
|
+
return `SELECT *, ARRAY_LENGTH(REGEXP_EXTRACT_ALL(${(0, quoteIdentifier_js_1.default)(column)}, '[^[:space:]]+')) AS ${(0, quoteIdentifier_js_1.default)(newColumn)} FROM ${input}`;
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type SimpleTable from "../class/SimpleTable.js";
|
|
2
2
|
export default function columnProportions(simpleTable: SimpleTable, column: string, newColumn: string, options?: {
|
|
3
3
|
by?: string | string[];
|
|
4
|
+
base?: number;
|
|
4
5
|
decimals?: number;
|
|
5
6
|
}): void;
|
|
6
7
|
//# sourceMappingURL=columnProportions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"columnProportions.d.ts","sourceRoot":"","sources":["../../src/methods/columnProportions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACd,
|
|
1
|
+
{"version":3,"file":"columnProportions.d.ts","sourceRoot":"","sources":["../../src/methods/columnProportions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACd,QAqCP"}
|