11import { BucketInclusionReason , ResolvedBucket } from './BucketDescription.js' ;
22import { BucketParameterQuerier , mergeBucketParameterQueriers , PendingQueriers } from './BucketParameterQuerier.js' ;
3- import { BucketDataSource , BucketParameterSource , BucketSourceType , ResultSetDescription } from './BucketSource.js' ;
3+ import {
4+ BucketDataSource ,
5+ BucketDataSourceDefinition ,
6+ BucketParameterSource ,
7+ BucketParameterSourceDefinition ,
8+ BucketSourceType ,
9+ CreateSourceParams ,
10+ ResultSetDescription
11+ } from './BucketSource.js' ;
412import { ColumnDefinition } from './ExpressionType.js' ;
513import { IdSequence } from './IdSequence.js' ;
614import { SourceTableInterface } from './SourceTableInterface.js' ;
@@ -32,9 +40,9 @@ export interface QueryParseResult {
3240 errors : SqlRuleError [ ] ;
3341}
3442
35- export class SqlBucketDescriptor implements BucketDataSource , BucketParameterSource {
43+ export class SqlBucketDescriptor implements BucketDataSourceDefinition , BucketParameterSourceDefinition {
3644 name : string ;
37- bucketParameters ? : string [ ] ;
45+ private bucketParametersInternal : string [ ] | null = null ;
3846
3947 constructor ( name : string ) {
4048 this . name = name ;
@@ -48,6 +56,10 @@ export class SqlBucketDescriptor implements BucketDataSource, BucketParameterSou
4856 return true ;
4957 }
5058
59+ public get bucketParameters ( ) : string [ ] {
60+ return this . bucketParametersInternal ?? [ ] ;
61+ }
62+
5163 /**
5264 * source table -> queries
5365 */
@@ -58,10 +70,10 @@ export class SqlBucketDescriptor implements BucketDataSource, BucketParameterSou
5870 parameterIdSequence = new IdSequence ( ) ;
5971
6072 addDataQuery ( sql : string , options : SyncRulesOptions , compatibility : CompatibilityContext ) : QueryParseResult {
61- if ( this . bucketParameters == null ) {
73+ if ( this . bucketParametersInternal == null ) {
6274 throw new Error ( 'Bucket parameters must be defined' ) ;
6375 }
64- const dataRows = SqlDataQuery . fromSql ( this . name , this . bucketParameters , sql , options , compatibility ) ;
76+ const dataRows = SqlDataQuery . fromSql ( this . name , this . bucketParametersInternal , sql , options , compatibility ) ;
6577
6678 this . dataQueries . push ( dataRows ) ;
6779
@@ -73,11 +85,12 @@ export class SqlBucketDescriptor implements BucketDataSource, BucketParameterSou
7385
7486 addParameterQuery ( sql : string , options : QueryParseOptions ) : QueryParseResult {
7587 const parameterQuery = SqlParameterQuery . fromSql ( this . name , sql , options , this . parameterIdSequence . nextId ( ) ) ;
76- if ( this . bucketParameters == null ) {
77- this . bucketParameters = parameterQuery . bucketParameters ;
88+ if ( this . bucketParametersInternal == null ) {
89+ this . bucketParametersInternal = parameterQuery . bucketParameters ;
7890 } else {
7991 if (
80- new Set ( [ ...parameterQuery . bucketParameters ! , ...this . bucketParameters ] ) . size != this . bucketParameters . length
92+ new Set ( [ ...parameterQuery . bucketParameters ! , ...this . bucketParametersInternal ] ) . size !=
93+ this . bucketParametersInternal . length
8194 ) {
8295 throw new Error ( 'Bucket parameters must match for each parameter query within a bucket' ) ;
8396 }
@@ -94,61 +107,71 @@ export class SqlBucketDescriptor implements BucketDataSource, BucketParameterSou
94107 } ;
95108 }
96109
97- evaluateRow ( options : EvaluateRowOptions ) : EvaluationResult [ ] {
98- let results : EvaluationResult [ ] = [ ] ;
99- for ( let query of this . dataQueries ) {
100- if ( ! query . applies ( options . sourceTable ) ) {
101- continue ;
110+ createDataSource ( params : CreateSourceParams ) : BucketDataSource {
111+ return {
112+ definition : this ,
113+ evaluateRow : ( options ) => {
114+ let results : EvaluationResult [ ] = [ ] ;
115+ for ( let query of this . dataQueries ) {
116+ if ( ! query . applies ( options . sourceTable ) ) {
117+ continue ;
118+ }
119+
120+ results . push ( ...query . evaluateRow ( options . sourceTable , options . record , params . bucketIdTransformer ) ) ;
121+ }
122+ return results ;
102123 }
103-
104- results . push ( ...query . evaluateRow ( options . sourceTable , options . record , options . bucketIdTransformer ) ) ;
105- }
106- return results ;
124+ } ;
107125 }
108126
109- evaluateParameterRow ( sourceTable : SourceTableInterface , row : SqliteRow ) : EvaluatedParametersResult [ ] {
110- let results : EvaluatedParametersResult [ ] = [ ] ;
111- for ( let query of this . parameterQueries ) {
112- if ( query . applies ( sourceTable ) ) {
113- results . push ( ...query . evaluateParameterRow ( row ) ) ;
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 ) ;
114173 }
115- }
116- return results ;
117- }
118-
119- /**
120- * @deprecated Use `pushBucketParameterQueriers` instead and merge at the top-level.
121- */
122- getBucketParameterQuerier ( options : GetQuerierOptions ) : BucketParameterQuerier {
123- const queriers : BucketParameterQuerier [ ] = [ ] ;
124- this . pushBucketParameterQueriers ( { queriers, errors : [ ] } , options ) ;
125-
126- return mergeBucketParameterQueriers ( queriers ) ;
127- }
128-
129- pushBucketParameterQueriers ( result : PendingQueriers , options : GetQuerierOptions ) {
130- const reasons = [ this . bucketInclusionReason ( ) ] ;
131- const staticBuckets = this . getStaticBucketDescriptions (
132- options . globalParameters ,
133- reasons ,
134- options . bucketIdTransformer
135- ) ;
136- const staticQuerier = {
137- staticBuckets,
138- hasDynamicBuckets : false ,
139- parameterQueryLookups : [ ] ,
140- queryDynamicBucketDescriptions : async ( ) => [ ]
141- } satisfies BucketParameterQuerier ;
142- result . queriers . push ( staticQuerier ) ;
143-
144- if ( this . parameterQueries . length == 0 ) {
145- return ;
146- }
147-
148- const dynamicQueriers = this . parameterQueries . map ( ( query ) =>
149- query . getBucketParameterQuerier ( options . globalParameters , reasons , options . bucketIdTransformer )
150- ) ;
151- result . queriers . push ( ...dynamicQueriers ) ;
174+ } ;
152175 }
153176
154177 getStaticBucketDescriptions (
0 commit comments