@@ -71,90 +71,16 @@ export class EventRepository implements IEventRepository {
7171 const queries = filters . map ( ( currentFilter ) => {
7272 const builder = this . readReplicaDbClient < DBEvent > ( 'events' )
7373
74- forEachObjIndexed ( ( tableFields : string [ ] , filterName : string | number ) => {
75- builder . andWhere ( ( bd ) => {
76- cond ( [
77- [ isEmpty , ( ) => void bd . whereRaw ( '1 = 0' ) ] ,
78- [
79- complement ( isNil ) ,
80- pipe (
81- groupByLengthSpec ,
82- evolve ( {
83- exact : ( pubkeys : string [ ] ) =>
84- tableFields . forEach ( ( tableField ) => bd . orWhereIn ( tableField , pubkeys . map ( toBuffer ) ) ) ,
85- even : forEach ( ( prefix : string ) =>
86- tableFields . forEach ( ( tableField ) =>
87- bd . orWhereRaw ( `substring("${ tableField } " from 1 for ?) = ?` , [
88- prefix . length >> 1 ,
89- toBuffer ( prefix ) ,
90- ] ) ,
91- ) ,
92- ) ,
93- odd : forEach ( ( prefix : string ) =>
94- tableFields . forEach ( ( tableField ) =>
95- bd . orWhereRaw ( `substring("${ tableField } " from 1 for ?) BETWEEN ? AND ?` , [
96- ( prefix . length >> 1 ) + 1 ,
97- `\\x${ prefix } 0` ,
98- `\\x${ prefix } f` ,
99- ] ) ,
100- ) ,
101- ) ,
102- } as any ) ,
103- ) ,
104- ] ,
105- ] ) ( currentFilter [ filterName ] as string [ ] )
106- } )
107- } ) ( {
108- authors : [ 'event_pubkey' ] ,
109- ids : [ 'event_id' ] ,
110- } )
111-
112- if ( Array . isArray ( currentFilter . kinds ) ) {
113- builder . whereIn ( 'event_kind' , currentFilter . kinds )
114- }
115-
116- if ( typeof currentFilter . since === 'number' ) {
117- builder . where ( 'event_created_at' , '>=' , currentFilter . since )
118- }
119-
120- if ( typeof currentFilter . until === 'number' ) {
121- builder . where ( 'event_created_at' , '<=' , currentFilter . until )
122- }
74+ const isTagQuery = this . applyFilterConditions ( builder , currentFilter )
12375
12476 if ( typeof currentFilter . limit === 'number' ) {
12577 builder . limit ( currentFilter . limit ) . orderBy ( 'event_created_at' , 'DESC' ) . orderBy ( 'event_id' , 'asc' )
12678 } else {
12779 builder . limit ( 500 ) . orderBy ( 'event_created_at' , 'asc' ) . orderBy ( 'event_id' , 'asc' )
12880 }
12981
130- const andWhereRaw = invoker ( 1 , 'andWhereRaw' )
131- const orWhereRaw = invoker ( 2 , 'orWhereRaw' )
132-
133- let isTagQuery = false
134- pipe (
135- toPairs ,
136- filter ( pipe ( nth ( 0 ) as ( ) => string , isGenericTagQuery ) ) as any ,
137- forEach ( ( [ filterName , criteria ] : [ string , string [ ] ] ) => {
138- isTagQuery = true
139- builder . andWhere ( ( bd ) => {
140- ifElse (
141- isEmpty ,
142- ( ) => andWhereRaw ( '1 = 0' , bd ) ,
143- forEach (
144- ( criterion : string ) =>
145- void orWhereRaw (
146- 'event_tags.tag_name = ? AND event_tags.tag_value = ?' ,
147- [ filterName [ 1 ] , criterion ] ,
148- bd ,
149- ) ,
150- ) ,
151- ) ( criteria )
152- } )
153- } ) ,
154- ) ( currentFilter as any )
155-
15682 if ( isTagQuery ) {
157- builder . leftJoin ( 'event_tags' , 'events.event_id' , 'event_tags.event_id' ) . select ( 'events.*' )
83+ builder . select ( 'events.*' )
15884 }
15985
16086 return builder
@@ -180,78 +106,14 @@ export class EventRepository implements IEventRepository {
180106 const queries = filters . map ( ( currentFilter ) => {
181107 const builder = this . readReplicaDbClient < DBEvent > ( 'events' ) . select ( 'events.event_id' )
182108
183- forEachObjIndexed ( ( tableFields : string [ ] , filterName : string | number ) => {
184- builder . andWhere ( ( bd ) => {
185- cond ( [
186- [ isEmpty , ( ) => void bd . whereRaw ( '1 = 0' ) ] ,
187- [
188- complement ( isNil ) ,
189- pipe (
190- groupByLengthSpec ,
191- evolve ( {
192- exact : ( pubkeys : string [ ] ) =>
193- tableFields . forEach ( ( tableField ) => bd . orWhereIn ( tableField , pubkeys . map ( toBuffer ) ) ) ,
194- even : forEach ( ( prefix : string ) =>
195- tableFields . forEach ( ( tableField ) =>
196- bd . orWhereRaw ( `substring("${ tableField } " from 1 for ?) = ?` , [ prefix . length >> 1 , toBuffer ( prefix ) ] ) ,
197- ) ,
198- ) ,
199- odd : forEach ( ( prefix : string ) =>
200- tableFields . forEach ( ( tableField ) =>
201- bd . orWhereRaw ( `substring("${ tableField } " from 1 for ?) BETWEEN ? AND ?` , [
202- ( prefix . length >> 1 ) + 1 ,
203- `\\x${ prefix } 0` ,
204- `\\x${ prefix } f` ,
205- ] ) ,
206- ) ,
207- ) ,
208- } as any ) ,
209- ) ,
210- ] ,
211- ] ) ( currentFilter [ filterName ] as string [ ] )
212- } )
213- } ) ( { authors : [ 'event_pubkey' ] , ids : [ 'event_id' ] } )
214-
215- if ( Array . isArray ( currentFilter . kinds ) ) {
216- builder . whereIn ( 'event_kind' , currentFilter . kinds )
217- }
218-
219- if ( typeof currentFilter . since === 'number' ) {
220- builder . where ( 'event_created_at' , '>=' , currentFilter . since )
221- }
222-
223- if ( typeof currentFilter . until === 'number' ) {
224- builder . where ( 'event_created_at' , '<=' , currentFilter . until )
225- }
109+ const isTagQuery = this . applyFilterConditions ( builder , currentFilter )
226110
227111 if ( typeof currentFilter . limit === 'number' ) {
228112 builder . limit ( currentFilter . limit ) . orderBy ( 'event_created_at' , 'DESC' ) . orderBy ( 'event_id' , 'asc' )
229113 }
230114
231- const andWhereRaw = invoker ( 1 , 'andWhereRaw' )
232- const orWhereRaw = invoker ( 2 , 'orWhereRaw' )
233-
234- let isTagQuery = false
235- pipe (
236- toPairs ,
237- filter ( pipe ( nth ( 0 ) as ( ) => string , isGenericTagQuery ) ) as any ,
238- forEach ( ( [ filterName , criteria ] : [ string , string [ ] ] ) => {
239- isTagQuery = true
240- builder . andWhere ( ( bd ) => {
241- ifElse (
242- isEmpty ,
243- ( ) => andWhereRaw ( '1 = 0' , bd ) ,
244- forEach (
245- ( criterion : string ) =>
246- void orWhereRaw ( 'event_tags.tag_name = ? AND event_tags.tag_value = ?' , [ filterName [ 1 ] , criterion ] , bd ) ,
247- ) ,
248- ) ( criteria )
249- } )
250- } ) ,
251- ) ( currentFilter as any )
252-
253115 if ( isTagQuery ) {
254- builder . leftJoin ( 'event_tags' , 'events.event_id' , 'event_tags.event_id' ) . select ( 'events.event_id' )
116+ builder . select ( 'events.event_id' )
255117 }
256118
257119 builder . whereNull ( 'events.deleted_at' ) . andWhere ( ( bd ) => {
@@ -271,6 +133,80 @@ export class EventRepository implements IEventRepository {
271133 return Number ( result ?. count ?? 0 )
272134 }
273135
136+ private applyFilterConditions ( builder : any , currentFilter : SubscriptionFilter ) : boolean {
137+ forEachObjIndexed ( ( tableFields : string [ ] , filterName : string | number ) => {
138+ builder . andWhere ( ( bd ) => {
139+ cond ( [
140+ [ isEmpty , ( ) => void bd . whereRaw ( '1 = 0' ) ] ,
141+ [
142+ complement ( isNil ) ,
143+ pipe (
144+ groupByLengthSpec ,
145+ evolve ( {
146+ exact : ( pubkeys : string [ ] ) =>
147+ tableFields . forEach ( ( tableField ) => bd . orWhereIn ( tableField , pubkeys . map ( toBuffer ) ) ) ,
148+ even : forEach ( ( prefix : string ) =>
149+ tableFields . forEach ( ( tableField ) =>
150+ bd . orWhereRaw ( `substring("${ tableField } " from 1 for ?) = ?` , [ prefix . length >> 1 , toBuffer ( prefix ) ] ) ,
151+ ) ,
152+ ) ,
153+ odd : forEach ( ( prefix : string ) =>
154+ tableFields . forEach ( ( tableField ) =>
155+ bd . orWhereRaw ( `substring("${ tableField } " from 1 for ?) BETWEEN ? AND ?` , [
156+ ( prefix . length >> 1 ) + 1 ,
157+ `\\x${ prefix } 0` ,
158+ `\\x${ prefix } f` ,
159+ ] ) ,
160+ ) ,
161+ ) ,
162+ } as any ) ,
163+ ) ,
164+ ] ,
165+ ] ) ( currentFilter [ filterName ] as string [ ] )
166+ } )
167+ } ) ( { authors : [ 'event_pubkey' ] , ids : [ 'event_id' ] } )
168+
169+ if ( Array . isArray ( currentFilter . kinds ) ) {
170+ builder . whereIn ( 'event_kind' , currentFilter . kinds )
171+ }
172+
173+ if ( typeof currentFilter . since === 'number' ) {
174+ builder . where ( 'event_created_at' , '>=' , currentFilter . since )
175+ }
176+
177+ if ( typeof currentFilter . until === 'number' ) {
178+ builder . where ( 'event_created_at' , '<=' , currentFilter . until )
179+ }
180+
181+ const andWhereRaw = invoker ( 1 , 'andWhereRaw' )
182+ const orWhereRaw = invoker ( 2 , 'orWhereRaw' )
183+
184+ let isTagQuery = false
185+ pipe (
186+ toPairs ,
187+ filter ( pipe ( nth ( 0 ) as ( ) => string , isGenericTagQuery ) ) as any ,
188+ forEach ( ( [ filterName , criteria ] : [ string , string [ ] ] ) => {
189+ isTagQuery = true
190+ builder . andWhere ( ( bd ) => {
191+ ifElse (
192+ isEmpty ,
193+ ( ) => andWhereRaw ( '1 = 0' , bd ) ,
194+ forEach (
195+ ( criterion : string ) =>
196+ void orWhereRaw ( 'event_tags.tag_name = ? AND event_tags.tag_value = ?' , [ filterName [ 1 ] , criterion ] , bd ) ,
197+ ) ,
198+ ) ( criteria )
199+ } )
200+ } ) ,
201+ ) ( currentFilter as any )
202+
203+ if ( isTagQuery ) {
204+ builder . leftJoin ( 'event_tags' , 'events.event_id' , 'event_tags.event_id' )
205+ }
206+
207+ return isTagQuery
208+ }
209+
274210 public async create ( event : Event ) : Promise < number > {
275211 return this . insert ( event ) . then ( prop ( 'rowCount' ) as ( ) => number , ( ) => 0 )
276212 }
0 commit comments