Project Files
docs / components / query-tools.md
[!ABSTRACT] Epigraf "Zaawansowane narzędzia zapytań — filtrowanie wielokryterialne, sortowanie, wyszukiwanie pełnotekstowe i agregacje. Rozszerza podstawowy CRUD o złożone operacje na danych."
| Pole | Wartość |
|---|---|
| Nazwa | Query Tools |
| Moduł | src/tools/query.tool.ts |
| Wersja | 1.0.0 |
| Status | Draft |
| Zależny od | CSV Engine |
| Używany przez | LM Studio (model LLM wywołuje narzędzia) |
Udostępnienie modelowi LLM zaawansowanych możliwości zapytań: filtrowanie po wielu kryteriach, sortowanie, wyszukiwanie substring, agregacje matematyczne.
query_table| Pole | Wartość |
|---|---|
| Nazwa | query_table |
| Opis | Zaawansowane zapytanie z filtrami, sortowaniem i wyszukiwaniem |
| Wywołuje | CSV Engine.parseCSV → pipeline: filter → search → sort → paginate |
Parametry:
| Parametr | Typ | Wymagany | Opis |
|---|---|---|---|
database | string | ✅ | Nazwa bazy |
table | string | ✅ | Nazwa tabeli |
filters | QueryFilter[] | ❌ | Lista filtrów (AND) |
search | SearchCondition | ❌ | Wyszukiwanie substring |
sort | SortCondition | ❌ | Sortowanie |
limit | number | ❌ | Max wierszy (domyślnie 100) |
offset | number | ❌ | Offset |
Zwraca:
| Pole | Typ | Opis |
|---|---|---|
rows | Record<string, any>[] | Wyniki |
total | number | Wszystkie wiersze |
filteredTotal | number | Po zastosowaniu filtrów |
page | number | Bieżąca strona |
totalPages | number | Liczba stron |
Błędy: TABLE_NOT_FOUND
aggregate_table| Pole | Wartość |
|---|---|
| Nazwa | aggregate_table |
| Opis | Wykonuje agregację na kolumnie: count, sum, avg, min, max |
| Wywołuje | CSV Engine.parseCSV → agregacja |
Parametry:
| Parametr | Typ | Wymagany | Opis |
| :---------- | :-------------------- | :------- | :------------------------- | ----- | ------ | --- | ------------- |
| database | string | ✅ | Nazwa bazy |
| table | string | ✅ | Nazwa tabeli |
| column | string | ✅ | Nazwa kolumny do agregacji |
| operation | "count" | "sum" | "avg" | "min" | "max" | ✅ | Typ agregacji |
| filter | Record<string, any> | ❌ | Opcjonalny filtr wstępny |
Zwraca:
| Pole | Typ | Opis |
|---|---|---|
operation | string | Typ agregacji |
column | string | Kolumna |
result | number | Wynik agregacji |
count | number | Liczba wierszy uwzględnionych |
Błędy: TABLE_NOT_FOUND, INVALID_AGGREGATION (jeśli kolumna nie jest numeryczna dla sum/avg)
| Komponent | Funkcja | Użycie |
|---|---|---|
engine/csv-engine | parseCSV | Wczytywanie danych do pipeline'u zapytań |
| Biblioteka | Wersja | Użycie |
|---|---|---|
@lmstudio/sdk | ^1.x | Rejestracja narzędzi |
| Scenariusz | Przykład |
|---|---|
| "Pokaż postacie powyżej 30 lat" | filters: [{ column: "age", operator: "gte", value: 30 }] |
| "Znajdź postacie z 'white' w nazwie" | search: { column: "name", query: "white" } |
| "Posortuj od najstarszej" | sort: { column: "age", direction: "desc" } |
| "Ile postaci żyje?" | aggregate: count z filter { isAlive: true } |
| "Jaka średnia wieku żyjących?" | aggregate: avg z filter { isAlive: true } |
| Scenariusz | Kod | Komunikat |
|---|---|---|
| Tabela nie istnieje | TABLE_NOT_FOUND | "Table '{table}' not found" |
| Kolumna nie istnieje | COLUMN_NOT_FOUND | "Column '{column}' not found in table" |
| Agregacja na stringu (sum/avg) | INVALID_AGGREGATION | "Cannot {op} on non-numeric column '{col}'" |
| Nieznany operator filtra | INVALID_OPERATOR | "Unknown operator '{op}'" |
| Given | When | Then |
|---|---|---|
| Tabela z 10 wierszami | queryTableTool.handler(...) | Zwraca wyniki z poprawną paginacją |
| Filtr eq pasujący | queryTableTool.handler(...) | Zwraca tylko pasujące wiersze |
| Filtr gte | queryTableTool.handler(...) | Zwraca wiersze >= wartość |
| Search substring | queryTableTool.handler(...) | Zwraca wiersze zawierające string |
| Sort asc | queryTableTool.handler(...) | Wyniki posortowane rosnąco |
| Sort desc | queryTableTool.handler(...) | Wyniki posortowane malejąco |
| Kolumna numeryczna | aggregateTableTool.handler({ op: "sum" }) | Zwraca poprawną sumę |
| Kolumna numeryczna | aggregateTableTool.handler({ op: "avg" }) | Zwraca poprawną średnią |
| Kolumna string + sum | aggregateTableTool.handler({ op: "sum" }) | Zwraca INVALID_AGGREGATION |
| Wszystkie filtry + search + sort | query_table z pełnymi params | Pipeline wykonany poprawnie |
parseCSV zwraca kontrolowaną tablicę../../TDD.md — §5.2 Query Toolscrud-tools.md — podstawowy CRUD, rozszerzany przez Querycsv-engine.md — źródło danych dla pipeline'uinterface QueryFilter {
column: string;
operator:
| "eq"
| "neq"
| "gt"
| "gte"
| "lt"
| "lte"
| "in"
| "contains"
| "startsWith"
| "endsWith";
value: any;
}
interface SearchCondition {
column: string;
query: string; // Substring do wyszukania
caseSensitive?: boolean; // Domyślnie false
}
interface SortCondition {
column: string;
direction: "asc" | "desc";
}
interface QueryParams {
database: string;
table: string;
filters?: QueryFilter[];
search?: SearchCondition;
sort?: SortCondition;
limit?: number;
offset?: number;
}
interface AggregateParams {
database: string;
table: string;
column: string;
operation: "count" | "sum" | "avg" | "min" | "max";
filter?: Record<string, any>;
}
interface QueryResult {
rows: Record<string, any>[];
total: number;
filteredTotal: number;
page: number;
totalPages: number;
}
interface AggregateResult {
operation: string;
column: string;
result: number;
count: number;
}
import { queryTableTool, aggregateTableTool } from "./query.tool";
// query_table — złożone zapytanie
const result = await queryTableTool.handler({
database: "breaking-bad",
table: "characters",
filters: [
{ column: "age", operator: "gte", value: 30 },
{ column: "isAlive", operator: "eq", value: true },
],
search: { column: "name", query: "white", caseSensitive: false },
sort: { column: "age", direction: "desc" },
limit: 20,
offset: 0,
});
// → { rows: [{ name: "Walter White", age: 50, isAlive: false }, ...],
// total: 12, filteredTotal: 2, page: 1, totalPages: 1 }
// aggregate_table — średnia wieku
const avg = await aggregateTableTool.handler({
database: "breaking-bad",
table: "characters",
column: "age",
operation: "avg",
});
// → { operation: "avg", column: "age", result: 38.5, count: 12 }
// aggregate_table — max wieku
const max = await aggregateTableTool.handler({
database: "breaking-bad",
table: "characters",
column: "age",
operation: "max",
});
// → { operation: "max", column: "age", result: 50, count: 12 }
stateDiagram-v2
[*] -→ Registered
Registered -→ Querying: query_table
Querying -→ Loading: parseCSV
Loading -→ Filtering: apply filters
Filtering -→ Searching: apply search
Searching -→ Sorting: apply sort
Sorting -→ Paginating: limit/offset
Paginating -→ Success: return results
Registered -→ Aggregating: aggregate_table
Aggregating -→ Loading
Loading -→ ApplyingFilter: optional filter
ApplyingFilter -→ Computing: count/sum/avg/min/max
Computing -→ Success