@uwdata/mosaic-core 0.12.1 → 0.12.2
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/dist/mosaic-core.js +16 -10
- package/dist/mosaic-core.min.js +4 -4
- package/dist/types/Coordinator.d.ts +6 -5
- package/dist/types/MosaicClient.d.ts +5 -4
- package/dist/types/SelectionClause.d.ts +8 -8
- package/dist/types/index.d.ts +2 -0
- package/dist/types/types.d.ts +31 -0
- package/dist/types/util/field-info.d.ts +11 -1
- package/dist/types/util/js-type.d.ts +7 -1
- package/package.json +4 -4
- package/src/Coordinator.js +10 -5
- package/src/MosaicClient.js +3 -2
- package/src/SelectionClause.js +4 -6
- package/src/index.js +2 -0
- package/src/types.ts +48 -0
- package/src/util/field-info.js +40 -14
- package/src/util/js-type.js +6 -0
|
@@ -4,9 +4,6 @@
|
|
|
4
4
|
* @returns {Coordinator} the coordinator instance
|
|
5
5
|
*/
|
|
6
6
|
export function coordinator(instance?: Coordinator): Coordinator;
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {import('@uwdata/mosaic-sql').Query | string} QueryType
|
|
9
|
-
*/
|
|
10
7
|
/**
|
|
11
8
|
* A Mosaic Coordinator manages all database communication for clients and
|
|
12
9
|
* handles selection updates. The Coordinator also performs optimizations
|
|
@@ -91,7 +88,10 @@ export class Coordinator {
|
|
|
91
88
|
* or a SQL string.
|
|
92
89
|
* @param {object} [options] An options object.
|
|
93
90
|
* @param {'arrow' | 'json'} [options.type] The query result format type.
|
|
94
|
-
* @param {boolean} [options.cache=true] If true, cache the query result
|
|
91
|
+
* @param {boolean} [options.cache=true] If true, cache the query result
|
|
92
|
+
* client-side within the QueryManager.
|
|
93
|
+
* @param {boolean} [options.persist] If true, request the database
|
|
94
|
+
* server to persist a cached query server-side.
|
|
95
95
|
* @param {number} [options.priority] The query priority, defaults to
|
|
96
96
|
* `Priority.Normal`.
|
|
97
97
|
* @returns {QueryResult} A query result promise.
|
|
@@ -99,6 +99,7 @@ export class Coordinator {
|
|
|
99
99
|
query(query: QueryType, { type, cache, priority, ...options }?: {
|
|
100
100
|
type?: "arrow" | "json";
|
|
101
101
|
cache?: boolean;
|
|
102
|
+
persist?: boolean;
|
|
102
103
|
priority?: number;
|
|
103
104
|
}): QueryResult;
|
|
104
105
|
/**
|
|
@@ -162,7 +163,7 @@ export class Coordinator {
|
|
|
162
163
|
*/
|
|
163
164
|
disconnect(client: MosaicClient): void;
|
|
164
165
|
}
|
|
165
|
-
export type QueryType = import("@uwdata/mosaic-sql").Query | string;
|
|
166
|
+
export type QueryType = import("@uwdata/mosaic-sql").Query | import("@uwdata/mosaic-sql").DescribeQuery | string;
|
|
166
167
|
import { QueryManager } from './QueryManager.js';
|
|
167
168
|
import { PreAggregator } from './preagg/PreAggregator.js';
|
|
168
169
|
import { QueryResult } from './util/query-result.js';
|
|
@@ -33,15 +33,16 @@ export class MosaicClient {
|
|
|
33
33
|
get filterStable(): boolean;
|
|
34
34
|
/**
|
|
35
35
|
* Return an array of fields queried by this client.
|
|
36
|
-
* @returns {
|
|
36
|
+
* @returns {import('./types.js').FieldInfoRequest[] | null}
|
|
37
|
+
* The fields to retrieve info for.
|
|
37
38
|
*/
|
|
38
|
-
fields():
|
|
39
|
+
fields(): import("./types.js").FieldInfoRequest[] | null;
|
|
39
40
|
/**
|
|
40
41
|
* Called by the coordinator to set the field info for this client.
|
|
41
|
-
* @param {
|
|
42
|
+
* @param {import('./types.js').FieldInfo[]} info The field info result.
|
|
42
43
|
* @returns {this}
|
|
43
44
|
*/
|
|
44
|
-
fieldInfo(info:
|
|
45
|
+
fieldInfo(info: import("./types.js").FieldInfo[]): this;
|
|
45
46
|
/**
|
|
46
47
|
* Return a query specifying the data needed by this client.
|
|
47
48
|
* @param {*} [filter] The filtering criteria to apply in the query.
|
|
@@ -23,7 +23,7 @@ export function clausePoint(field: import("@uwdata/mosaic-sql").ExprValue, value
|
|
|
23
23
|
/**
|
|
24
24
|
* Generate a selection clause for multiple selected point values.
|
|
25
25
|
* @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
|
|
26
|
-
* @param {any[][] | undefined} value The selected values, as an array of
|
|
26
|
+
* @param {any[][] | null | undefined} value The selected values, as an array of
|
|
27
27
|
* arrays. Each subarray contains values for each *fields* entry.
|
|
28
28
|
* @param {object} options Additional clause properties.
|
|
29
29
|
* @param {*} options.source The source component generating this clause.
|
|
@@ -32,14 +32,14 @@ export function clausePoint(field: import("@uwdata/mosaic-sql").ExprValue, value
|
|
|
32
32
|
* cross-filtering contexts.
|
|
33
33
|
* @returns {SelectionClause} The generated selection clause.
|
|
34
34
|
*/
|
|
35
|
-
export function clausePoints(fields: import("@uwdata/mosaic-sql").ExprValue[], value: any[][] | undefined, { source, clients }: {
|
|
35
|
+
export function clausePoints(fields: import("@uwdata/mosaic-sql").ExprValue[], value: any[][] | null | undefined, { source, clients }: {
|
|
36
36
|
source: any;
|
|
37
37
|
clients?: Set<MosaicClient>;
|
|
38
38
|
}): SelectionClause;
|
|
39
39
|
/**
|
|
40
40
|
* Generate a selection clause for a selected 1D interval.
|
|
41
41
|
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
|
|
42
|
-
* @param {Extent} value The selected interval as a [lo, hi] array.
|
|
42
|
+
* @param {Extent | null | undefined} value The selected interval as a [lo, hi] array.
|
|
43
43
|
* @param {object} options Additional clause properties.
|
|
44
44
|
* @param {*} options.source The source component generating this clause.
|
|
45
45
|
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
@@ -50,7 +50,7 @@ export function clausePoints(fields: import("@uwdata/mosaic-sql").ExprValue[], v
|
|
|
50
50
|
* @param {number} [options.pixelSize=1] The interactive pixel size.
|
|
51
51
|
* @returns {SelectionClause} The generated selection clause.
|
|
52
52
|
*/
|
|
53
|
-
export function clauseInterval(field: import("@uwdata/mosaic-sql").ExprValue, value: Extent, { source, clients, bin, scale, pixelSize }: {
|
|
53
|
+
export function clauseInterval(field: import("@uwdata/mosaic-sql").ExprValue, value: Extent | null | undefined, { source, clients, bin, scale, pixelSize }: {
|
|
54
54
|
source: any;
|
|
55
55
|
clients?: Set<MosaicClient>;
|
|
56
56
|
scale?: Scale;
|
|
@@ -60,7 +60,7 @@ export function clauseInterval(field: import("@uwdata/mosaic-sql").ExprValue, va
|
|
|
60
60
|
/**
|
|
61
61
|
* Generate a selection clause for multiple selected intervals.
|
|
62
62
|
* @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
|
|
63
|
-
* @param {Extent[]} value The selected intervals, as an array of extents.
|
|
63
|
+
* @param {Extent[] | null | undefined} value The selected intervals, as an array of extents.
|
|
64
64
|
* @param {object} options Additional clause properties.
|
|
65
65
|
* @param {*} options.source The source component generating this clause.
|
|
66
66
|
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
@@ -72,7 +72,7 @@ export function clauseInterval(field: import("@uwdata/mosaic-sql").ExprValue, va
|
|
|
72
72
|
* @param {number} [options.pixelSize=1] The interactive pixel size.
|
|
73
73
|
* @returns {SelectionClause} The generated selection clause.
|
|
74
74
|
*/
|
|
75
|
-
export function clauseIntervals(fields: import("@uwdata/mosaic-sql").ExprValue[], value: Extent[], { source, clients, bin, scales, pixelSize }: {
|
|
75
|
+
export function clauseIntervals(fields: import("@uwdata/mosaic-sql").ExprValue[], value: Extent[] | null | undefined, { source, clients, bin, scales, pixelSize }: {
|
|
76
76
|
source: any;
|
|
77
77
|
clients?: Set<MosaicClient>;
|
|
78
78
|
scales?: Scale[];
|
|
@@ -82,7 +82,7 @@ export function clauseIntervals(fields: import("@uwdata/mosaic-sql").ExprValue[]
|
|
|
82
82
|
/**
|
|
83
83
|
* Generate a selection clause for text search matching.
|
|
84
84
|
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
|
|
85
|
-
* @param {string} value The selected text search query string.
|
|
85
|
+
* @param {string | null | undefined} value The selected text search query string.
|
|
86
86
|
* @param {object} options Additional clause properties.
|
|
87
87
|
* @param {*} options.source The source component generating this clause.
|
|
88
88
|
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
@@ -92,7 +92,7 @@ export function clauseIntervals(fields: import("@uwdata/mosaic-sql").ExprValue[]
|
|
|
92
92
|
* text matching method to use. Defaults to `'contains'`.
|
|
93
93
|
* @returns {SelectionClause} The generated selection clause.
|
|
94
94
|
*/
|
|
95
|
-
export function clauseMatch(field: import("@uwdata/mosaic-sql").ExprValue, value: string, { source, clients, method }: {
|
|
95
|
+
export function clauseMatch(field: import("@uwdata/mosaic-sql").ExprValue, value: string | null | undefined, { source, clients, method }: {
|
|
96
96
|
source: any;
|
|
97
97
|
clients?: Set<MosaicClient>;
|
|
98
98
|
method?: MatchMethod;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export { isArrowTable } from "./util/is-arrow-table.js";
|
|
|
9
9
|
export { synchronizer } from "./util/synchronizer.js";
|
|
10
10
|
export { throttle } from "./util/throttle.js";
|
|
11
11
|
export { toDataColumns } from "./util/to-data-columns.js";
|
|
12
|
+
export { queryFieldInfo } from "./util/field-info.js";
|
|
13
|
+
export { jsType } from "./util/js-type.js";
|
|
12
14
|
export type ClauseMetadata = import("./util/selection-types.js").ClauseMetadata;
|
|
13
15
|
export type PointMetadata = import("./util/selection-types.js").PointMetadata;
|
|
14
16
|
export type MatchMethod = import("./util/selection-types.js").MatchMethod;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ExprNode } from '@uwdata/mosaic-sql';
|
|
2
|
+
/** String indicating a JavaScript data type. */
|
|
3
|
+
export type JSType = 'number' | 'date' | 'boolean' | 'string' | 'array' | 'object';
|
|
4
|
+
/** String indicating a requested summary statistic. */
|
|
5
|
+
export type Stat = 'count' | 'nulls' | 'max' | 'min' | 'distinct';
|
|
6
|
+
/** A reference to a database column or expression. */
|
|
7
|
+
export type FieldRef = string | ExprNode;
|
|
8
|
+
/**
|
|
9
|
+
* A request for metadata information about a database column.
|
|
10
|
+
*/
|
|
11
|
+
export interface FieldInfoRequest {
|
|
12
|
+
table: string;
|
|
13
|
+
column: FieldRef;
|
|
14
|
+
stats?: Stat[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A response with metadata information about a database column.
|
|
18
|
+
*/
|
|
19
|
+
export interface FieldInfo extends Partial<Record<Stat, number>> {
|
|
20
|
+
table: string;
|
|
21
|
+
column: string;
|
|
22
|
+
sqlType: string;
|
|
23
|
+
type: JSType;
|
|
24
|
+
nullable: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** A result row from a DESCRIBE query. */
|
|
27
|
+
export interface ColumnDescription {
|
|
28
|
+
column_name: string;
|
|
29
|
+
column_type: string;
|
|
30
|
+
null: 'YES' | 'NO';
|
|
31
|
+
}
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Queries information about fields of a table.
|
|
3
|
+
* If the `fields` array contains a single field with the column set to '*',
|
|
4
|
+
* the function will retrieve and return the table information using `getTableInfo`.
|
|
5
|
+
* Otherwise, it will query individual field information using `getFieldInfo`
|
|
6
|
+
* for each field in the `fields` array.
|
|
7
|
+
* @param {import('../Coordinator.js').Coordinator} mc A Mosaic coordinator.
|
|
8
|
+
* @param {import('../types.js').FieldInfoRequest[]} fields
|
|
9
|
+
* @returns {Promise<import('../types.js').FieldInfo[]>}
|
|
10
|
+
*/
|
|
11
|
+
export function queryFieldInfo(mc: import("../Coordinator.js").Coordinator, fields: import("../types.js").FieldInfoRequest[]): Promise<import("../types.js").FieldInfo[]>;
|
|
2
12
|
export const Count: "count";
|
|
3
13
|
export const Nulls: "nulls";
|
|
4
14
|
export const Max: "max";
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Maps a SQL data type to its corresponding JavaScript type.
|
|
3
|
+
* @param {string} type The name of a SQL data type
|
|
4
|
+
* @returns {import('../types.js').JSType} The corresponding JavaScript type name
|
|
5
|
+
* @throws {Error} Throws an error if the given SQL type name is unsupported or unrecognized.
|
|
6
|
+
*/
|
|
7
|
+
export function jsType(type: string): import("../types.js").JSType;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uwdata/mosaic-core",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "Scalable and extensible linked data views.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mosaic",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@duckdb/duckdb-wasm": "^1.29.0",
|
|
34
34
|
"@uwdata/flechette": "^1.1.1",
|
|
35
|
-
"@uwdata/mosaic-sql": "^0.12.
|
|
35
|
+
"@uwdata/mosaic-sql": "^0.12.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@uwdata/mosaic-duckdb": "^0.12.
|
|
38
|
+
"@uwdata/mosaic-duckdb": "^0.12.2"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "0ca741d840b98039255f26a5ceedf10be66f790e"
|
|
41
41
|
}
|
package/src/Coordinator.js
CHANGED
|
@@ -6,6 +6,12 @@ import { voidLogger } from './util/void-logger.js';
|
|
|
6
6
|
import { MosaicClient } from './MosaicClient.js';
|
|
7
7
|
import { QueryManager, Priority } from './QueryManager.js';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {import('@uwdata/mosaic-sql').Query
|
|
11
|
+
* | import('@uwdata/mosaic-sql').DescribeQuery
|
|
12
|
+
* | string} QueryType
|
|
13
|
+
*/
|
|
14
|
+
|
|
9
15
|
/**
|
|
10
16
|
* The singleton Coordinator instance.
|
|
11
17
|
* @type {Coordinator}
|
|
@@ -26,10 +32,6 @@ export function coordinator(instance) {
|
|
|
26
32
|
return _instance;
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
/**
|
|
30
|
-
* @typedef {import('@uwdata/mosaic-sql').Query | string} QueryType
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
35
|
/**
|
|
34
36
|
* A Mosaic Coordinator manages all database communication for clients and
|
|
35
37
|
* handles selection updates. The Coordinator also performs optimizations
|
|
@@ -134,7 +136,10 @@ export class Coordinator {
|
|
|
134
136
|
* or a SQL string.
|
|
135
137
|
* @param {object} [options] An options object.
|
|
136
138
|
* @param {'arrow' | 'json'} [options.type] The query result format type.
|
|
137
|
-
* @param {boolean} [options.cache=true] If true, cache the query result
|
|
139
|
+
* @param {boolean} [options.cache=true] If true, cache the query result
|
|
140
|
+
* client-side within the QueryManager.
|
|
141
|
+
* @param {boolean} [options.persist] If true, request the database
|
|
142
|
+
* server to persist a cached query server-side.
|
|
138
143
|
* @param {number} [options.priority] The query priority, defaults to
|
|
139
144
|
* `Priority.Normal`.
|
|
140
145
|
* @returns {QueryResult} A query result promise.
|
package/src/MosaicClient.js
CHANGED
|
@@ -49,7 +49,8 @@ export class MosaicClient {
|
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Return an array of fields queried by this client.
|
|
52
|
-
* @returns {
|
|
52
|
+
* @returns {import('./types.js').FieldInfoRequest[] | null}
|
|
53
|
+
* The fields to retrieve info for.
|
|
53
54
|
*/
|
|
54
55
|
fields() {
|
|
55
56
|
return null;
|
|
@@ -57,7 +58,7 @@ export class MosaicClient {
|
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
60
|
* Called by the coordinator to set the field info for this client.
|
|
60
|
-
* @param {
|
|
61
|
+
* @param {import('./types.js').FieldInfo[]} info The field info result.
|
|
61
62
|
* @returns {this}
|
|
62
63
|
*/
|
|
63
64
|
fieldInfo(info) { // eslint-disable-line no-unused-vars
|
package/src/SelectionClause.js
CHANGED
|
@@ -40,7 +40,7 @@ export function clausePoint(field, value, {
|
|
|
40
40
|
/**
|
|
41
41
|
* Generate a selection clause for multiple selected point values.
|
|
42
42
|
* @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
|
|
43
|
-
* @param {any[][] | undefined} value The selected values, as an array of
|
|
43
|
+
* @param {any[][] | null | undefined} value The selected values, as an array of
|
|
44
44
|
* arrays. Each subarray contains values for each *fields* entry.
|
|
45
45
|
* @param {object} options Additional clause properties.
|
|
46
46
|
* @param {*} options.source The source component generating this clause.
|
|
@@ -75,7 +75,7 @@ export function clausePoints(fields, value, {
|
|
|
75
75
|
/**
|
|
76
76
|
* Generate a selection clause for a selected 1D interval.
|
|
77
77
|
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
|
|
78
|
-
* @param {Extent} value The selected interval as a [lo, hi] array.
|
|
78
|
+
* @param {Extent | null | undefined} value The selected interval as a [lo, hi] array.
|
|
79
79
|
* @param {object} options Additional clause properties.
|
|
80
80
|
* @param {*} options.source The source component generating this clause.
|
|
81
81
|
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
@@ -93,7 +93,6 @@ export function clauseInterval(field, value, {
|
|
|
93
93
|
scale,
|
|
94
94
|
pixelSize = 1
|
|
95
95
|
}) {
|
|
96
|
-
/** @type {ExprNode | null} */
|
|
97
96
|
const predicate = value != null ? isBetween(field, value) : null;
|
|
98
97
|
/** @type {import('./util/selection-types.js').IntervalMetadata} */
|
|
99
98
|
const meta = { type: 'interval', scales: scale && [scale], bin, pixelSize };
|
|
@@ -103,7 +102,7 @@ export function clauseInterval(field, value, {
|
|
|
103
102
|
/**
|
|
104
103
|
* Generate a selection clause for multiple selected intervals.
|
|
105
104
|
* @param {import('@uwdata/mosaic-sql').ExprValue[]} fields The table columns or expressions to select.
|
|
106
|
-
* @param {Extent[]} value The selected intervals, as an array of extents.
|
|
105
|
+
* @param {Extent[] | null | undefined} value The selected intervals, as an array of extents.
|
|
107
106
|
* @param {object} options Additional clause properties.
|
|
108
107
|
* @param {*} options.source The source component generating this clause.
|
|
109
108
|
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
|
@@ -122,7 +121,6 @@ export function clauseIntervals(fields, value, {
|
|
|
122
121
|
scales = [],
|
|
123
122
|
pixelSize = 1
|
|
124
123
|
}) {
|
|
125
|
-
/** @type {ExprNode | null} */
|
|
126
124
|
const predicate = value != null
|
|
127
125
|
? and(fields.map((f, i) => isBetween(f, value[i])))
|
|
128
126
|
: null;
|
|
@@ -136,7 +134,7 @@ const MATCH_METHODS = { contains, prefix, suffix, regexp: regexp_matches };
|
|
|
136
134
|
/**
|
|
137
135
|
* Generate a selection clause for text search matching.
|
|
138
136
|
* @param {import('@uwdata/mosaic-sql').ExprValue} field The table column or expression to select.
|
|
139
|
-
* @param {string} value The selected text search query string.
|
|
137
|
+
* @param {string | null | undefined} value The selected text search query string.
|
|
140
138
|
* @param {object} options Additional clause properties.
|
|
141
139
|
* @param {*} options.source The source component generating this clause.
|
|
142
140
|
* @param {Set<MosaicClient>} [options.clients] The Mosaic clients associated
|
package/src/index.js
CHANGED
|
@@ -22,6 +22,8 @@ export { isArrowTable } from './util/is-arrow-table.js';
|
|
|
22
22
|
export { synchronizer } from './util/synchronizer.js';
|
|
23
23
|
export { throttle } from './util/throttle.js';
|
|
24
24
|
export { toDataColumns } from './util/to-data-columns.js';
|
|
25
|
+
export { queryFieldInfo } from './util/field-info.js';
|
|
26
|
+
export { jsType } from './util/js-type.js';
|
|
25
27
|
|
|
26
28
|
/**
|
|
27
29
|
* @typedef {import('./util/selection-types.js').ClauseMetadata} ClauseMetadata
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ExprNode } from '@uwdata/mosaic-sql';
|
|
2
|
+
|
|
3
|
+
/** String indicating a JavaScript data type. */
|
|
4
|
+
export type JSType =
|
|
5
|
+
| 'number'
|
|
6
|
+
| 'date'
|
|
7
|
+
| 'boolean'
|
|
8
|
+
| 'string'
|
|
9
|
+
| 'array'
|
|
10
|
+
| 'object';
|
|
11
|
+
|
|
12
|
+
/** String indicating a requested summary statistic. */
|
|
13
|
+
export type Stat =
|
|
14
|
+
| 'count'
|
|
15
|
+
| 'nulls'
|
|
16
|
+
| 'max'
|
|
17
|
+
| 'min'
|
|
18
|
+
| 'distinct';
|
|
19
|
+
|
|
20
|
+
/** A reference to a database column or expression. */
|
|
21
|
+
export type FieldRef = string | ExprNode;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A request for metadata information about a database column.
|
|
25
|
+
*/
|
|
26
|
+
export interface FieldInfoRequest {
|
|
27
|
+
table: string;
|
|
28
|
+
column: FieldRef;
|
|
29
|
+
stats?: Stat[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* A response with metadata information about a database column.
|
|
34
|
+
*/
|
|
35
|
+
export interface FieldInfo extends Partial<Record<Stat, number>> {
|
|
36
|
+
table: string,
|
|
37
|
+
column: string,
|
|
38
|
+
sqlType: string,
|
|
39
|
+
type: JSType,
|
|
40
|
+
nullable: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** A result row from a DESCRIBE query. */
|
|
44
|
+
export interface ColumnDescription {
|
|
45
|
+
column_name: string,
|
|
46
|
+
column_type: string,
|
|
47
|
+
null: 'YES' | 'NO'
|
|
48
|
+
}
|
package/src/util/field-info.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AggregateNode, Query, asTableRef, count, isNull, max, min, sql } from '@uwdata/mosaic-sql';
|
|
1
|
+
import { AggregateNode, Query, asTableRef, count, isAggregateExpression, isNode, isNull, max, min, sql } from '@uwdata/mosaic-sql';
|
|
2
2
|
import { jsType } from './js-type.js';
|
|
3
3
|
|
|
4
4
|
export const Count = 'count';
|
|
@@ -9,7 +9,10 @@ export const Distinct = 'distinct';
|
|
|
9
9
|
export const Stats = { Count, Nulls, Max, Min, Distinct };
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* @type {Record<
|
|
12
|
+
* @type {Record<
|
|
13
|
+
* import('../types.js').Stat,
|
|
14
|
+
* (column: import('../types.js').FieldRef) => AggregateNode
|
|
15
|
+
* >}
|
|
13
16
|
*/
|
|
14
17
|
const statMap = {
|
|
15
18
|
[Count]: count,
|
|
@@ -20,18 +23,26 @@ const statMap = {
|
|
|
20
23
|
};
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
|
-
*
|
|
24
|
-
* @param {
|
|
25
|
-
* @
|
|
26
|
-
* @param {string[]|Set<string>} stats
|
|
27
|
-
* @returns
|
|
26
|
+
* Get summary stats of the given column
|
|
27
|
+
* @param {import('../types.js').FieldInfoRequest} field
|
|
28
|
+
* @returns {Query}
|
|
28
29
|
*/
|
|
29
|
-
function summarize(table, column, stats) {
|
|
30
|
+
function summarize({ table, column, stats }) {
|
|
30
31
|
return Query
|
|
31
32
|
.from(table)
|
|
32
|
-
.select(Array.from(stats, s => ({[s]: statMap[s](column)})));
|
|
33
|
+
.select(Array.from(stats, s => ({ [s]: statMap[s](column) })));
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Queries information about fields of a table.
|
|
38
|
+
* If the `fields` array contains a single field with the column set to '*',
|
|
39
|
+
* the function will retrieve and return the table information using `getTableInfo`.
|
|
40
|
+
* Otherwise, it will query individual field information using `getFieldInfo`
|
|
41
|
+
* for each field in the `fields` array.
|
|
42
|
+
* @param {import('../Coordinator.js').Coordinator} mc A Mosaic coordinator.
|
|
43
|
+
* @param {import('../types.js').FieldInfoRequest[]} fields
|
|
44
|
+
* @returns {Promise<import('../types.js').FieldInfo[]>}
|
|
45
|
+
*/
|
|
35
46
|
export async function queryFieldInfo(mc, fields) {
|
|
36
47
|
if (fields.length === 1 && fields[0].column === '*') {
|
|
37
48
|
return getTableInfo(mc, fields[0].table);
|
|
@@ -42,13 +53,21 @@ export async function queryFieldInfo(mc, fields) {
|
|
|
42
53
|
}
|
|
43
54
|
}
|
|
44
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Get information about a single field of a table.
|
|
58
|
+
* @param {import('../Coordinator.js').Coordinator} mc A Mosaic coordinator.
|
|
59
|
+
* @param {import('../types.js').FieldInfoRequest} field
|
|
60
|
+
* @returns {Promise<import('../types.js').FieldInfo>}
|
|
61
|
+
*/
|
|
45
62
|
async function getFieldInfo(mc, { table, column, stats }) {
|
|
46
63
|
// generate and issue a query for field metadata info
|
|
47
64
|
// use GROUP BY ALL to differentiate & consolidate aggregates
|
|
48
65
|
const q = Query
|
|
49
66
|
.from({ source: table })
|
|
50
67
|
.select({ column })
|
|
51
|
-
.groupby(column
|
|
68
|
+
.groupby(isNode(column) && isAggregateExpression(column) ? sql`ALL` : []);
|
|
69
|
+
|
|
70
|
+
/** @type {import('../types.js').ColumnDescription[]} */
|
|
52
71
|
const [desc] = Array.from(await mc.query(Query.describe(q)));
|
|
53
72
|
const info = {
|
|
54
73
|
table,
|
|
@@ -59,11 +78,11 @@ async function getFieldInfo(mc, { table, column, stats }) {
|
|
|
59
78
|
};
|
|
60
79
|
|
|
61
80
|
// no need for summary statistics
|
|
62
|
-
if (!
|
|
81
|
+
if (!stats?.length) return info;
|
|
63
82
|
|
|
64
83
|
// query for summary stats
|
|
65
84
|
const [result] = await mc.query(
|
|
66
|
-
summarize(table, column, stats),
|
|
85
|
+
summarize({ table, column, stats }),
|
|
67
86
|
{ persist: true }
|
|
68
87
|
);
|
|
69
88
|
|
|
@@ -71,9 +90,16 @@ async function getFieldInfo(mc, { table, column, stats }) {
|
|
|
71
90
|
return Object.assign(info, result);
|
|
72
91
|
}
|
|
73
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Get information about the fields of a table.
|
|
95
|
+
* @param {import('../Coordinator.js').Coordinator} mc A Mosaic coordinator.
|
|
96
|
+
* @param {string} table The table name.
|
|
97
|
+
* @returns {Promise<import('../types.js').FieldInfo[]>}
|
|
98
|
+
*/
|
|
74
99
|
async function getTableInfo(mc, table) {
|
|
75
|
-
|
|
76
|
-
|
|
100
|
+
/** @type {import('../types.js').ColumnDescription[]} */
|
|
101
|
+
const result = Array.from(await mc.query(`DESCRIBE ${asTableRef(table)}`));
|
|
102
|
+
return result.map(desc => ({
|
|
77
103
|
table,
|
|
78
104
|
column: desc.column_name,
|
|
79
105
|
sqlType: desc.column_type,
|
package/src/util/js-type.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps a SQL data type to its corresponding JavaScript type.
|
|
3
|
+
* @param {string} type The name of a SQL data type
|
|
4
|
+
* @returns {import('../types.js').JSType} The corresponding JavaScript type name
|
|
5
|
+
* @throws {Error} Throws an error if the given SQL type name is unsupported or unrecognized.
|
|
6
|
+
*/
|
|
1
7
|
export function jsType(type) {
|
|
2
8
|
switch (type) {
|
|
3
9
|
case 'BIGINT':
|