-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathBucketParameterQuerier.ts
88 lines (78 loc) · 2.95 KB
/
BucketParameterQuerier.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { BucketDescription } from './BucketDescription.js';
import { RequestParameters, SqliteJsonRow, SqliteJsonValue } from './types.js';
import { normalizeParameterValue } from './utils.js';
/**
* Represents a set of parameter queries for a specific request.
*/
export interface BucketParameterQuerier {
/**
* These buckets do not change for the lifetime of the connection.
*
* This includes parameter queries such as:
*
* select request.user_id() as user_id()
* select value as project_id from json_each(request.jwt() -> 'project_ids')
*/
readonly staticBuckets: BucketDescription[];
/**
* True if there are dynamic buckets, meaning queryDynamicBucketDescriptions() should be used.
*
* If this is false, queryDynamicBucketDescriptions() will always return an empty array,
* and parameterQueryLookups.length == 0.
*/
readonly hasDynamicBuckets: boolean;
readonly parameterQueryLookups: ParameterLookup[];
/**
* These buckets depend on parameter storage, and needs to be retrieved dynamically for each checkpoint.
*
* The ParameterLookupSource should perform the query for the current checkpoint - that is not passed
* as a parameter.
*
* This includes parameter queries such as:
*
* select id as user_id from users where users.id = request.user_id()
*/
queryDynamicBucketDescriptions(source: ParameterLookupSource): Promise<BucketDescription[]>;
}
export interface ParameterLookupSource {
getParameterSets: (lookups: ParameterLookup[]) => Promise<SqliteJsonRow[]>;
}
export interface QueryBucketDescriptorOptions extends ParameterLookupSource {
parameters: RequestParameters;
}
export function mergeBucketParameterQueriers(queriers: BucketParameterQuerier[]): BucketParameterQuerier {
const parameterQueryLookups = queriers.flatMap((q) => q.parameterQueryLookups);
return {
staticBuckets: queriers.flatMap((q) => q.staticBuckets),
hasDynamicBuckets: parameterQueryLookups.length > 0,
parameterQueryLookups: parameterQueryLookups,
async queryDynamicBucketDescriptions(source: ParameterLookupSource) {
let results: BucketDescription[] = [];
for (let q of queriers) {
if (q.hasDynamicBuckets) {
results.push(...(await q.queryDynamicBucketDescriptions(source)));
}
}
return results;
}
};
}
/**
* Represents an equality filter from a parameter query.
*
* Other query types are not supported yet.
*/
export class ParameterLookup {
// bucket definition name, parameter query index, ...lookup values
readonly values: SqliteJsonValue[];
static normalized(bucketDefinitionName: string, queryIndex: string, values: SqliteJsonValue[]): ParameterLookup {
return new ParameterLookup([bucketDefinitionName, queryIndex, ...values.map(normalizeParameterValue)]);
}
/**
*
* @param values must be pre-normalized (any integer converted into bigint)
*/
constructor(values: SqliteJsonValue[]) {
this.values = values;
}
}