Skip to content

Commit 020335e

Browse files
findQuery and searchQuery added.
1 parent b41c709 commit 020335e

File tree

3 files changed

+70
-18
lines changed

3 files changed

+70
-18
lines changed

docs/PuddySqlQuery.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,8 @@ Parses JOIN configuration into one or more SQL JOIN clauses.
881881
882882
Finds the **first** matching result and returns its position, page, and optionally its data.
883883
884+
Query only: `findQuery(searchData)`
885+
884886
#### Parameters:
885887
- `searchData` (`object`)
886888
- `q`: QueryGroup or object condition
@@ -900,6 +902,8 @@ Finds the **first** matching result and returns its position, page, and optional
900902
901903
Performs a complete filtered query with optional **pagination**, **joins**, and **tags**.
902904
905+
Query only: `searchQuery(searchData)`
906+
903907
#### Parameters:
904908
905909
* `searchData` (`object`)

src/PuddySqlQuery.mjs

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,8 @@ class PuddySqlQuery {
653653
return `${col} IN (${inList})`;
654654
});
655655
cases.push(`WHEN ${conditions.join(' OR ')} THEN ${weight}`);
656-
}
657-
656+
}
657+
658658
// Other modes
659659
else {
660660
if (typeof value !== 'string')
@@ -2056,12 +2056,10 @@ class PuddySqlQuery {
20562056
* @param {SelectQuery} [searchData.select='*'] - Which columns to select. Set to null to skip item data.
20572057
* @param {string} [searchData.order] - SQL ORDER BY clause. Defaults to configured order.
20582058
* @param {string|JoinObj|JoinObj[]} [searchData.join] - JOIN definitions with table, compare, and optional type.
2059-
* @returns {Promise<FindResult | null>}
2059+
* @returns {{ query: string; values: any[] | undefined; perPage: number; selectValue: SelectQuery; }}
20602060
* @throws {Error} If searchData has invalid structure or values.
20612061
*/
2062-
async find(searchData = {}) {
2063-
const db = this.getDb();
2064-
2062+
findQuery(searchData = {}) {
20652063
// --- Validate searchData types ---
20662064
if (!isJsonObject(searchData)) throw new TypeError(`'searchData' must be a object`);
20672065
const criteria = searchData.q || {};
@@ -2154,7 +2152,31 @@ class PuddySqlQuery {
21542152
WHERE rn = 1
21552153
`.trim();
21562154

2157-
const row = await db.get(query, pCache.values, 'find');
2155+
return { query, values: pCache.values, perPage, selectValue };
2156+
}
2157+
2158+
/**
2159+
* Finds the first item matching the filter, along with its position, page, and total info.
2160+
* Uses a single SQL query to calculate everything efficiently.
2161+
*
2162+
* If selectValue is null, it only returns the pagination/position data, not the item itself.
2163+
*
2164+
* @param {Object} [searchData={}] - Main search configuration.
2165+
* @param {QueryGroup} [searchData.q={}] - Nested criteria object.
2166+
* @param {TagCriteria[]|TagCriteria|null} [searchData.tagCriteria] - One or multiple tag criteria groups.
2167+
* @param {string[]} [searchData.tagCriteriaOps] - Optional logical operators between tag groups (e.g., ['AND', 'OR']).
2168+
* @param {number} [searchData.perPage] - Number of items per page.
2169+
* @param {SelectQuery} [searchData.select='*'] - Which columns to select. Set to null to skip item data.
2170+
* @param {string} [searchData.order] - SQL ORDER BY clause. Defaults to configured order.
2171+
* @param {string|JoinObj|JoinObj[]} [searchData.join] - JOIN definitions with table, compare, and optional type.
2172+
* @returns {Promise<FindResult | null>}
2173+
* @throws {Error} If searchData has invalid structure or values.
2174+
*/
2175+
async find(searchData = {}) {
2176+
const db = this.getDb();
2177+
const { query, values, perPage, selectValue } = this.findQuery(searchData);
2178+
2179+
const row = await db.get(query, values, 'find');
21582180
if (!row) return null;
21592181

21602182
const total = parseInt(row.total);
@@ -2198,7 +2220,7 @@ class PuddySqlQuery {
21982220
* @param {string|JoinObj|JoinObj[]} [searchData.join] - A string for single join or array of objects for multiple joins.
21992221
* Each object should contain `{ table: 'name', compare: 'ON clause' }`.
22002222
* @param {number} [searchData.limit] - Max number of results to return (ignored when `perPage` is used).
2201-
* @returns {Promise<FreeObj[]|PaginationResult>} - Result rows matching the query.
2223+
* @returns {{ query: string; perPage: number | null; values: any[]; page: number; }}
22022224
* @throws {Error} If searchData has invalid structure or values.
22032225
*
22042226
* @example
@@ -2235,9 +2257,7 @@ class PuddySqlQuery {
22352257
* order: 'created_at DESC'
22362258
* });
22372259
*/
2238-
2239-
async search(searchData = {}) {
2240-
const db = this.getDb();
2260+
searchQuery(searchData = {}) {
22412261
if (!isJsonObject(searchData)) throw new TypeError(`'searchData' must be a object`);
22422262
const order = searchData.order || this.#settings.order;
22432263
const join = searchData.join || this.#settings.join;
@@ -2340,6 +2360,34 @@ class PuddySqlQuery {
23402360
${orderClause}
23412361
${limitClause}`.trim();
23422362

2363+
return { query, perPage, values, page };
2364+
}
2365+
2366+
/**
2367+
* Perform a filtered search with advanced nested criteria, pagination, and customizable settings.
2368+
*
2369+
* Supports complex logical groupings (AND/OR), flat condition style, custom ordering, and single or multiple joins.
2370+
* Pagination can be enabled using `perPage`, and additional settings like `order`, `join`, and `limit` can be passed inside `searchData`.
2371+
*
2372+
* @param {Object} [searchData={}] - Main search configuration.
2373+
* @param {QueryGroup} [searchData.q={}] - Nested criteria object.
2374+
* Can be a flat object style or grouped with `{ group: 'AND'|'OR', conditions: [...] }`.
2375+
* @param {TagCriteria[]|TagCriteria|null} [searchData.tagsQ] - One or multiple tag criteria groups.
2376+
* @param {string[]} [searchData.tagsOpsQ] - Optional logical operators between tag groups (e.g., ['AND', 'OR']).
2377+
* @param {SelectQuery} [searchData.select='*'] - Defines which columns or expressions should be selected in the query.
2378+
* @param {number|null} [searchData.perPage=null] - Number of results per page. If set, pagination is applied.
2379+
* @param {number} [searchData.page=1] - Page number to retrieve when `perPage` is used.
2380+
* @param {string} [searchData.order] - Custom `ORDER BY` clause (e.g. `'created_at DESC'`).
2381+
* @param {string|JoinObj|JoinObj[]} [searchData.join] - A string for single join or array of objects for multiple joins.
2382+
* Each object should contain `{ table: 'name', compare: 'ON clause' }`.
2383+
* @param {number} [searchData.limit] - Max number of results to return (ignored when `perPage` is used).
2384+
* @returns {Promise<FreeObj[]|PaginationResult>} - Result rows matching the query.
2385+
* @throws {Error} If searchData has invalid structure or values.
2386+
*/
2387+
async search(searchData = {}) {
2388+
const db = this.getDb();
2389+
const { query, values, perPage, page } = this.searchQuery(searchData);
2390+
23432391
// Results
23442392
let results;
23452393

test/index.mjs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ const db = new PuddySql.Instance();
138138
console.log('\n🧠 Advanced Tag Search: cute AND not serious\n');
139139
console.table(
140140
await tagTable.search({
141-
tagsQ: { column: 'tags', include: ['cute', '!serious'] }
141+
tagsQ: { column: 'tags', include: ['cute', '!serious'] },
142142
}),
143143
);
144144

@@ -149,13 +149,13 @@ const db = new PuddySql.Instance();
149149
boost: {
150150
alias: 'p',
151151
value: [
152-
{ columns: ['tags'], value: 'deep', weight: 3 },
153-
{ columns: ['tags'], value: 'cute', weight: 2 },
154-
]
155-
}
152+
{ columns: ['tags'], value: 'deep', weight: 3 },
153+
{ columns: ['tags'], value: 'cute', weight: 2 },
154+
],
155+
},
156156
},
157-
tagsQ: {
158-
column: 'tags',
157+
tagsQ: {
158+
column: 'tags',
159159
include: ['cute', 'deep'],
160160
},
161161
}),

0 commit comments

Comments
 (0)