Skip to content

Commit 2b7787d

Browse files
committed
Refactor parameter queries.
1 parent 223ae3e commit 2b7787d

File tree

9 files changed

+230
-154
lines changed

9 files changed

+230
-154
lines changed

packages/sync-rules/src/BucketSource.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,24 +48,18 @@ export interface BucketParameterSourceDefinition {
4848
readonly name: string;
4949
readonly type: BucketSourceType;
5050
readonly subscribedToByDefault: boolean;
51+
/**
52+
* For debug use only.
53+
*/
54+
readonly bucketParameters: string[];
5155

5256
getSourceTables(): Set<TablePattern>;
5357
createParameterSource(params: CreateSourceParams): BucketParameterSource;
5458

55-
/**
56-
* Whether {@link pushBucketParameterQueriers} may include a querier where
57-
* {@link BucketParameterQuerier.hasDynamicBuckets} is true.
58-
*
59-
* This is mostly used for testing.
60-
*/
61-
hasDynamicBucketQueries(): boolean;
62-
6359
getSourceTables(): Set<TablePattern>;
6460

6561
/** Whether the table possibly affects the buckets resolved by this source. */
6662
tableSyncsParameters(table: SourceTableInterface): boolean;
67-
68-
debugRepresentation(): any;
6963
}
7064

7165
/**

packages/sync-rules/src/SqlBucketDescriptor.ts

Lines changed: 7 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,22 @@
1-
import { BucketInclusionReason, ResolvedBucket } from './BucketDescription.js';
2-
import { BucketParameterQuerier, mergeBucketParameterQueriers, PendingQueriers } from './BucketParameterQuerier.js';
31
import {
42
BucketDataSource,
53
BucketDataSourceDefinition,
6-
BucketParameterSource,
74
BucketParameterSourceDefinition,
85
BucketSourceType,
9-
CreateSourceParams,
10-
ResultSetDescription
6+
CreateSourceParams
117
} from './BucketSource.js';
128
import { ColumnDefinition } from './ExpressionType.js';
139
import { IdSequence } from './IdSequence.js';
1410
import { SourceTableInterface } from './SourceTableInterface.js';
1511
import { SqlDataQuery } from './SqlDataQuery.js';
1612
import { SqlParameterQuery } from './SqlParameterQuery.js';
17-
import { GetQuerierOptions, SyncRulesOptions } from './SqlSyncRules.js';
13+
import { SyncRulesOptions } from './SqlSyncRules.js';
1814
import { StaticSqlParameterQuery } from './StaticSqlParameterQuery.js';
1915
import { TablePattern } from './TablePattern.js';
2016
import { TableValuedFunctionSqlParameterQuery } from './TableValuedFunctionSqlParameterQuery.js';
21-
import { SqlRuleError } from './errors.js';
2217
import { CompatibilityContext } from './compatibility.js';
23-
import {
24-
BucketIdTransformer,
25-
EvaluatedParametersResult,
26-
EvaluateRowOptions,
27-
EvaluationResult,
28-
QueryParseOptions,
29-
RequestParameters,
30-
SourceSchema,
31-
SqliteRow
32-
} from './types.js';
18+
import { SqlRuleError } from './errors.js';
19+
import { EvaluationResult, QueryParseOptions, SourceSchema } from './types.js';
3320

3421
export interface QueryParseResult {
3522
/**
@@ -40,7 +27,7 @@ export interface QueryParseResult {
4027
errors: SqlRuleError[];
4128
}
4229

43-
export class SqlBucketDescriptor implements BucketDataSourceDefinition, BucketParameterSourceDefinition {
30+
export class SqlBucketDescriptor implements BucketDataSourceDefinition {
4431
name: string;
4532
private bucketParametersInternal: string[] | null = null;
4633

@@ -124,76 +111,8 @@ export class SqlBucketDescriptor implements BucketDataSourceDefinition, BucketPa
124111
};
125112
}
126113

127-
createParameterSource(params: CreateSourceParams): BucketParameterSource {
128-
return {
129-
definition: this,
130-
131-
evaluateParameterRow: (sourceTable: SourceTableInterface, row: SqliteRow): EvaluatedParametersResult[] => {
132-
let results: EvaluatedParametersResult[] = [];
133-
for (let query of this.parameterQueries) {
134-
if (query.applies(sourceTable)) {
135-
results.push(...query.evaluateParameterRow(row));
136-
}
137-
}
138-
return results;
139-
},
140-
pushBucketParameterQueriers: (result: PendingQueriers, options: GetQuerierOptions) => {
141-
const reasons = [this.bucketInclusionReason()];
142-
const staticBuckets = this.getStaticBucketDescriptions(
143-
options.globalParameters,
144-
reasons,
145-
params.bucketIdTransformer
146-
);
147-
const staticQuerier = {
148-
staticBuckets,
149-
hasDynamicBuckets: false,
150-
parameterQueryLookups: [],
151-
queryDynamicBucketDescriptions: async () => []
152-
} satisfies BucketParameterQuerier;
153-
result.queriers.push(staticQuerier);
154-
155-
if (this.parameterQueries.length == 0) {
156-
return;
157-
}
158-
159-
const dynamicQueriers = this.parameterQueries.map((query) =>
160-
query.getBucketParameterQuerier(options.globalParameters, reasons, params.bucketIdTransformer)
161-
);
162-
result.queriers.push(...dynamicQueriers);
163-
},
164-
165-
/**
166-
* @deprecated Use `pushBucketParameterQueriers` instead and merge at the top-level.
167-
*/
168-
getBucketParameterQuerier(options: GetQuerierOptions): BucketParameterQuerier {
169-
const queriers: BucketParameterQuerier[] = [];
170-
this.pushBucketParameterQueriers({ queriers, errors: [] }, options);
171-
172-
return mergeBucketParameterQueriers(queriers);
173-
}
174-
};
175-
}
176-
177-
getStaticBucketDescriptions(
178-
parameters: RequestParameters,
179-
reasons: BucketInclusionReason[],
180-
transformer: BucketIdTransformer
181-
): ResolvedBucket[] {
182-
let results: ResolvedBucket[] = [];
183-
for (let query of this.globalParameterQueries) {
184-
for (const desc of query.getStaticBucketDescriptions(parameters, transformer)) {
185-
results.push({
186-
...desc,
187-
definition: this.name,
188-
inclusion_reasons: reasons
189-
});
190-
}
191-
}
192-
return results;
193-
}
194-
195-
hasDynamicBucketQueries(): boolean {
196-
return this.parameterQueries.length > 0;
114+
getParameterSourceDefinitions(): BucketParameterSourceDefinition[] {
115+
return [...this.parameterQueries, ...this.globalParameterQueries];
197116
}
198117

199118
getSourceTables(): Set<TablePattern> {
@@ -210,10 +129,6 @@ export class SqlBucketDescriptor implements BucketDataSourceDefinition, BucketPa
210129
return result;
211130
}
212131

213-
private bucketInclusionReason(): BucketInclusionReason {
214-
return 'default';
215-
}
216-
217132
tableSyncsData(table: SourceTableInterface): boolean {
218133
for (let query of this.dataQueries) {
219134
if (query.applies(table)) {
@@ -223,15 +138,6 @@ export class SqlBucketDescriptor implements BucketDataSourceDefinition, BucketPa
223138
return false;
224139
}
225140

226-
tableSyncsParameters(table: SourceTableInterface): boolean {
227-
for (let query of this.parameterQueries) {
228-
if (query.applies(table)) {
229-
return true;
230-
}
231-
}
232-
return false;
233-
}
234-
235141
resolveResultSets(schema: SourceSchema, tables: Record<string, Record<string, ColumnDefinition>>) {
236142
for (let query of this.dataQueries) {
237143
query.resolveResultSets(schema, tables);

packages/sync-rules/src/SqlParameterQuery.ts

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ import {
55
BucketPriority,
66
DEFAULT_BUCKET_PRIORITY
77
} from './BucketDescription.js';
8-
import { BucketParameterQuerier, ParameterLookup, ParameterLookupSource } from './BucketParameterQuerier.js';
8+
import {
9+
BucketParameterQuerier,
10+
mergeBucketParameterQueriers,
11+
ParameterLookup,
12+
ParameterLookupSource,
13+
PendingQueriers
14+
} from './BucketParameterQuerier.js';
915
import { SqlRuleError } from './errors.js';
1016
import { SourceTableInterface } from './SourceTableInterface.js';
1117
import { AvailableTable, SqlTools } from './sql_filters.js';
@@ -31,6 +37,13 @@ import {
3137
} from './types.js';
3238
import { filterJsonRow, getBucketId, isJsonValue, isSelectStatement, normalizeParameterValue } from './utils.js';
3339
import { DetectRequestParameters } from './validators.js';
40+
import {
41+
BucketParameterSource,
42+
BucketParameterSourceDefinition,
43+
BucketSourceType,
44+
CreateSourceParams
45+
} from './BucketSource.js';
46+
import { GetQuerierOptions } from './index.js';
3447

3548
export interface SqlParameterQueryOptions {
3649
sourceTable: TablePattern;
@@ -55,7 +68,7 @@ export interface SqlParameterQueryOptions {
5568
* SELECT id as user_id FROM users WHERE users.user_id = token_parameters.user_id
5669
* SELECT id as user_id, token_parameters.is_admin as is_admin FROM users WHERE users.user_id = token_parameters.user_id
5770
*/
58-
export class SqlParameterQuery {
71+
export class SqlParameterQuery implements BucketParameterSourceDefinition {
5972
static fromSql(
6073
descriptorName: string,
6174
sql: string,
@@ -282,6 +295,10 @@ export class SqlParameterQuery {
282295
readonly queryId: string;
283296
readonly tools: SqlTools;
284297

298+
readonly type: BucketSourceType = BucketSourceType.SYNC_RULE;
299+
300+
readonly subscribedToByDefault: boolean = true;
301+
285302
readonly errors: SqlRuleError[];
286303

287304
constructor(options: SqlParameterQueryOptions) {
@@ -301,10 +318,46 @@ export class SqlParameterQuery {
301318
this.errors = options.errors ?? [];
302319
}
303320

304-
applies(table: SourceTableInterface) {
321+
tableSyncsParameters(table: SourceTableInterface): boolean {
305322
return this.sourceTable.matches(table);
306323
}
307324

325+
get name(): string {
326+
return this.descriptorName;
327+
}
328+
329+
getSourceTables(): Set<TablePattern> {
330+
return new Set([this.sourceTable]);
331+
}
332+
333+
createParameterSource(params: CreateSourceParams): BucketParameterSource {
334+
return {
335+
definition: this,
336+
337+
evaluateParameterRow: (sourceTable: SourceTableInterface, row: SqliteRow): EvaluatedParametersResult[] => {
338+
if (this.tableSyncsParameters(sourceTable)) {
339+
return this.evaluateParameterRow(row);
340+
} else {
341+
return [];
342+
}
343+
},
344+
pushBucketParameterQueriers: (result: PendingQueriers, options: GetQuerierOptions) => {
345+
const q = this.getBucketParameterQuerier(options.globalParameters, ['default'], params.bucketIdTransformer);
346+
result.queriers.push(q);
347+
},
348+
349+
/**
350+
* @deprecated Use `pushBucketParameterQueriers` instead and merge at the top-level.
351+
*/
352+
getBucketParameterQuerier(options: GetQuerierOptions): BucketParameterQuerier {
353+
const queriers: BucketParameterQuerier[] = [];
354+
this.pushBucketParameterQueriers({ queriers, errors: [] }, options);
355+
356+
return mergeBucketParameterQueriers(queriers);
357+
}
358+
};
359+
}
360+
308361
/**
309362
* Given a replicated row, results an array of bucket parameter rows to persist.
310363
*/

packages/sync-rules/src/SqlSyncRules.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ export class SqlSyncRules {
232232
});
233233
}
234234
rules.bucketDataSources.push(descriptor);
235-
rules.bucketParameterSources.push(descriptor);
235+
rules.bucketParameterSources.push(...descriptor.getParameterSourceDefinitions());
236236
}
237237

238238
for (const entry of streamMap?.items ?? []) {
@@ -400,10 +400,6 @@ export class SqlSyncRules {
400400
return applyRowContext(source, this.compatibility);
401401
}
402402

403-
hasDynamicBucketQueries() {
404-
return this.bucketParameterSources.some((s) => s.hasDynamicBucketQueries());
405-
}
406-
407403
getSourceTables(): TablePattern[] {
408404
const sourceTables = new Map<String, TablePattern>();
409405
for (const bucket of this.bucketDataSources) {

0 commit comments

Comments
 (0)