Skip to content

Commit 240fbea

Browse files
committed
Refine the implementation
1 parent a27c710 commit 240fbea

File tree

3 files changed

+23
-33
lines changed

3 files changed

+23
-33
lines changed

simple_repository_browser/_search.py

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,16 @@ class SQLBuilder:
5757
order_params: tuple[typing.Any, ...]
5858
search_context: SearchContext
5959

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-
7060
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,
7265
) -> tuple[str, tuple[typing.Any, ...]]:
7366
"""Build complete query with LIMIT/OFFSET"""
7467
where_part = f"WHERE {self.where_clause}" if self.where_clause else ""
7568
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)
7770

7871
def with_where(self, clause: str, params: tuple[typing.Any, ...]) -> SQLBuilder:
7972
"""Return new SQLBuilder with updated WHERE clause"""
@@ -84,11 +77,6 @@ def with_order(self, clause: str, params: tuple[typing.Any, ...]) -> SQLBuilder:
8477
return dataclasses.replace(self, order_clause=clause, order_params=params)
8578

8679

87-
# Helper types
88-
_WhereClause = tuple[str, tuple[typing.Any, ...]]
89-
_OrderClause = tuple[str, tuple[typing.Any, ...]]
90-
91-
9280
@dataclasses.dataclass(frozen=True)
9381
class SearchContext:
9482
"""Context collected during WHERE clause building."""
@@ -222,7 +210,6 @@ def handle_term_Not(
222210
inner_sql, inner_params, _ = cls._visit_term(term.term, context)
223211
return f"(NOT {inner_sql})", inner_params, context
224212

225-
# Field-specific filter handlers
226213
@classmethod
227214
def handle_filter_name(
228215
cls, term: Filter, context: SearchContext
@@ -272,26 +259,18 @@ def handle_filter_name_or_summary(
272259
return combined_sql, combined_params, name_context
273260

274261
@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.
289266
290267
For "scipy or scikit-*", the ordering is:
291268
1. Exact matches get closeness-based priority (scipy, scipy2, etc.)
292269
2. Fuzzy matches get length-based priority (scikit-learn, scikit-image, etc.)
293270
3. Everything else alphabetical
294271
"""
272+
273+
exact_names, fuzzy_patterns = context.exact_names, context.fuzzy_patterns
295274
order_parts = []
296275
all_params = []
297276

simple_repository_browser/model.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ async def project_query(
148148
# Main query uses the builder's complete query method
149149
query, params = sql_builder.build_complete_query(
150150
"SELECT canonical_name, summary, release_version, release_date FROM projects",
151-
(page_size, offset),
151+
page_size,
152+
offset,
152153
)
153154
results = cursor.execute(query, params).fetchall()
154155

simple_repository_browser/tests/test_search.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,16 @@ async def test_empty_results(test_model):
427427
assert result["results_count"] == 0
428428

429429

430+
@pytest.mark.asyncio
431+
async def test_summary_search(test_model):
432+
"""Test queries that return no results."""
433+
result = await test_model.project_query("summary:numpy", page_size=1000, page=1)
434+
names = [item.canonical_name for item in result["results"]]
435+
assert "scipy" not in names
436+
assert "numpy" not in names
437+
assert "abc" in names
438+
439+
430440
@pytest.mark.asyncio
431441
async def test_injected_results_when_not_in_db(test_model):
432442
assert isinstance(test_model.source, MockSimpleRepository)

0 commit comments

Comments
 (0)