@@ -57,23 +57,16 @@ class SQLBuilder:
57
57
order_params : tuple [typing .Any , ...]
58
58
search_context : SearchContext
59
59
60
- @property
61
- def where_params_count (self ) -> int :
62
- """Number of parameters used by WHERE clause (for COUNT queries)"""
63
- return len (self .where_params )
64
-
65
- @property
66
- def all_params (self ) -> tuple [typing .Any , ...]:
67
- """All parameters for both WHERE and ORDER BY clauses"""
68
- return self .where_params + self .order_params
69
-
70
60
def build_complete_query (
71
- self , base_select : str , limit_offset : tuple [int , int ]
61
+ self ,
62
+ base_select : str ,
63
+ limit : int ,
64
+ offset : int ,
72
65
) -> tuple [str , tuple [typing .Any , ...]]:
73
66
"""Build complete query with LIMIT/OFFSET"""
74
67
where_part = f"WHERE { self .where_clause } " if self .where_clause else ""
75
68
query = f"{ base_select } { where_part } { self .order_clause } LIMIT ? OFFSET ?"
76
- return query , self .all_params + limit_offset
69
+ return query , self .where_params + self . order_params + ( limit , offset )
77
70
78
71
def with_where (self , clause : str , params : tuple [typing .Any , ...]) -> SQLBuilder :
79
72
"""Return new SQLBuilder with updated WHERE clause"""
@@ -84,11 +77,6 @@ def with_order(self, clause: str, params: tuple[typing.Any, ...]) -> SQLBuilder:
84
77
return dataclasses .replace (self , order_clause = clause , order_params = params )
85
78
86
79
87
- # Helper types
88
- _WhereClause = tuple [str , tuple [typing .Any , ...]]
89
- _OrderClause = tuple [str , tuple [typing .Any , ...]]
90
-
91
-
92
80
@dataclasses .dataclass (frozen = True )
93
81
class SearchContext :
94
82
"""Context collected during WHERE clause building."""
@@ -222,7 +210,6 @@ def handle_term_Not(
222
210
inner_sql , inner_params , _ = cls ._visit_term (term .term , context )
223
211
return f"(NOT { inner_sql } )" , inner_params , context
224
212
225
- # Field-specific filter handlers
226
213
@classmethod
227
214
def handle_filter_name (
228
215
cls , term : Filter , context : SearchContext
@@ -272,26 +259,18 @@ def handle_filter_name_or_summary(
272
259
return combined_sql , combined_params , name_context
273
260
274
261
@classmethod
275
- def _build_ordering_from_context (cls , context : SearchContext ) -> _OrderClause :
276
- """Build mixed ordering for exact names and fuzzy patterns."""
277
- if not context .exact_names and not context .fuzzy_patterns :
278
- return "ORDER BY canonical_name" , ()
279
-
280
- return cls ._build_mixed_ordering (
281
- list (context .exact_names ), context .fuzzy_patterns
282
- )
283
-
284
- @classmethod
285
- def _build_mixed_ordering (
286
- cls , exact_names : list [str ], fuzzy_patterns : set [str ]
287
- ) -> _OrderClause :
288
- """Build ordering that handles both exact names and fuzzy patterns.
262
+ def _build_ordering_from_context (
263
+ cls , context : SearchContext
264
+ ) -> tuple [str , tuple [typing .Any , ...]]:
265
+ """Build mixed ordering for exact names and fuzzy patterns.
289
266
290
267
For "scipy or scikit-*", the ordering is:
291
268
1. Exact matches get closeness-based priority (scipy, scipy2, etc.)
292
269
2. Fuzzy matches get length-based priority (scikit-learn, scikit-image, etc.)
293
270
3. Everything else alphabetical
294
271
"""
272
+
273
+ exact_names , fuzzy_patterns = context .exact_names , context .fuzzy_patterns
295
274
order_parts = []
296
275
all_params = []
297
276
0 commit comments