UNPKG

puddysql

Version:

๐Ÿฎ Powerful SQL toolkit for Node.js, built with flexibility and structure in mind. Easily manage SQLite3/PostgreSQL, advanced queries, smart tag systems, and full JSON-friendly filters.

954 lines (664 loc) โ€ข 27 kB
# ๐Ÿ“Š PuddySqlQuery `PuddySqlQuery` is a high-level query builder class for managing SQL tables using flexible filters, tag-based conditions, JOINs, pagination, and result validation. It supports complex nested logic (AND/OR), dynamic tag filtering, composable JOIN structures, and automatic SQL clause generation โ€” all while keeping the API intuitive and extensible. Perfect for advanced search interfaces, dashboards, data exploration tools, or any project that needs powerful yet readable SQL control. --- ## ๐Ÿ—ƒ๏ธ Core Types & Initialization ### ๐Ÿงฉ SqlTableConfig Defines the schema structure for programmatic SQL table creation or modification. Each array entry represents a single column with this 4-item tuple format: `[columnName, columnType, columnOptions, columnMeta]` - **columnName** (`string`): Name of the column, e.g., `"id"`, `"username"`. - **columnType** (`string`): SQL data type, e.g., `"TEXT"`, `"INTEGER"`. - **columnOptions** (`string`): SQL options like `NOT NULL`, `PRIMARY KEY`, `DEFAULT`. - **columnMeta** (`any`): Arbitrary metadata (UI hints, descriptions, tags). --- ### ๐Ÿ”Ž FindResult Result of a paginated SQL query locating a specific item: - **page** (`number`): Current page number (starting at 1). - **pages** (`number`): Total pages available. - **total** (`number`): Total items in dataset. - **position** (`number`): Exact item index (starting at 0). - **item** (`FreeObj` | optional): The actual found item, if returned. --- ### ๐Ÿท๏ธ TagCriteria Definition for tag group filtering in SQL clauses: - **group.column** (`string` | optional): SQL column for tag data (default: `this.getColumnName()`). - **group.tableName** (`string` | optional): Table name used (default: `this.defaultTableName`). - **group.allowWildcards** (`boolean` | optional): Allow wildcards in matching (default: `false`). - **group.include** (`Array<string|string[]>`): Tag values or OR-groups to include in filtering. --- ### ๐Ÿ“„ PaginationResult Result object for paginated queries: - **items** (`any[]`): Array of items returned for current page. - **totalPages** (`number`): Total available pages. - **totalItems** (`number`): Total matching items without pagination. --- ### ๐ŸŽฏ SelectQuery Flexible input for SELECT clause: Can be a `string`, array of strings, or object with: - `aliases` (mapping display names to real columns) - `values` (array of columns to select) - `boost` (weighted ranking configuration with alias and boost rules) Can also be `null` for defaults. --- ### ๐Ÿงฐ Pcache Parameter cache for building WHERE clauses: - `index` (`number`): Starting index for SQL placeholders (`$1`, `$2`, ...). Defaults to `1`. - `values` (`any[]`): Values collected for parameter binding. --- ### ๐Ÿ“ฆ FreeObj Generic object with arbitrary keys and unknown values: - Keys can be `string`, `number`, or `symbol`. - Values are of unknown type. Useful for flexible data containers. --- ### โš–๏ธ WhereConditions Conditions used in SQL WHERE clause: - `group` (`'AND'|'OR'|'and'|'or'` | optional): Logical operator for condition groups. - `conditions` (array of `WhereConditions` or `QueryGroup` | optional): Nested logical conditions. - `funcName`, `operator`, `value`, `valType`, `lPos`, `newOp`, `column` (various optional fields for SQL expressions and chaining). --- ### ๐Ÿงฉ QueryGroup Flexible group of WHERE conditions, supporting either: 1. Single condition object: ```js { column: 'name', operator: '=', value: 'pudding' } ```` 2. Named group of conditions: ```js { searchByName: { column: 'name', operator: 'ILIKE', value: '%fluttershy%' }, searchByType: { column: 'type', operator: '=', value: 'pegasus' } } ``` Enables dynamic grouping for advanced filters and scoped searches. --- ### ๐Ÿš€ BoostValue Rule for weighted query boosting: * `columns` (optional array): Columns to apply boost on. * `operator`: Condition operator, e.g., `'='`, `'LIKE'`. * `value`: Value or array of values to match. * `weight`: Numeric factor to boost matched results. --- ### ๐Ÿ”— JoinObj Object defining SQL JOIN clauses: * `table` (`string`): Table name to join. * `compare` (`string`): ON clause condition. * `type` (`string` | optional): JOIN type, defaults to `'left'`. --- ### ๐Ÿ›๏ธ TableSettings Settings for SQL table/entity configuration: * `name` (optional string): Table or view name. * `select` (`SelectQuery`): SELECT clause config. Defaults to `"*"`. * `join` (optional string): JOIN table name. * `joinCompare` (optional string): JOIN condition, e.g. `'t.key = j.key'`. * `order` (optional string): ORDER BY clause. * `id` (`string`): Primary key column. Defaults to `'key'`. * `subId` (optional string): Secondary key column (composite key or scope). --- ### โš™๏ธ Settings Configuration for SQL entity querying and joining: * `select` (`string`): Default columns to select. * `name` (`string`): Main table/view name. * `id` (`string`): Primary key column name. * `joinCompare` (optional string): JOIN matching condition. * `order` (optional string): Default ordering clause. * `subId` (optional string): Secondary ID column. * `join` (optional string): JOIN clause (e.g., `"LEFT JOIN profiles ON ..."`). --- ### ๐Ÿ”ง WhereConditionsFunc Function type that takes and returns a `WhereConditions` object. Used for SQL WHERE clause transformations or appends. --- ### ๐Ÿ—‚๏ธ SqlConditions Map of named condition identifiers to their transformation functions (`WhereConditionsFunc`). --- ### ๐Ÿ—๏ธ PuddySqlQuery Class Overview The main query engine for operating on a specific SQL table with support for dynamic conditions, tags, joins, and advanced query building. #### Private fields: * `#conditions`: Registered SQL conditions map. * `#customValFunc`: Custom value transformation functions. * `#db`: The internal `PuddySqlEngine` database instance. * `#settings`: Current table/query settings. * `#table`: Table schema and column metadata. * `#tagColumns`: Tag filtering helpers per column. --- #### Method: `getDb()` Safely retrieves the internal database instance. Throws if the internal DB is not a valid `PuddySqlEngine` instance. ```js const db = instance.getDb(); ``` **Throws:** `Error` if DB is invalid or uninitialized. --- ## โš™๏ธ Constructor & Condition Management ### ๐Ÿš€ Constructor: Initial Condition Setup Initializes the query instance with a set of predefined SQL condition operators and function-based conditions. - Adds common operators like `'LIKE'`, `'NOT'`, `'='`, `'!='`, `'>='`, `'<='`, `'>'`, `'<'`. - Registers advanced SQL functions using `addConditionV2` for phonetic, string, math, and date/time functions: - Phonetic: `SOUNDEX` - Case conversion: `LOWER`, `UPPER` - Trim whitespace: `TRIM`, `LTRIM`, `RTRIM` - String length: `LENGTH` - Math: `ABS`, `ROUND`, `CEIL`, `FLOOR` - Null handling: `COALESCE` - String formatting: `HEX`, `QUOTE` - Unicode: `UNICODE`, `CHAR` - Type inspection: `TYPEOF` - Date/time extraction: `DATE`, `TIME`, `DATETIME`, `JULIANDAY` --- ### ๐Ÿ” Method: `hasCondition(key)` Checks if a condition is registered under the given key. - **Parameters:** - `key` (`string`): Condition identifier. - **Returns:** - `boolean`: `true` if condition exists, else `false`. --- ### ๐Ÿ› ๏ธ Method: `getCondition(key)` Retrieves the condition function registered with the given key. - **Parameters:** - `key` (`string`): Condition identifier. - **Returns:** - `WhereConditionsFunc`: The condition function. - **Throws:** - `Error` if condition key is not found. --- ### ๐Ÿ“‹ Method: `getConditions()` Returns a shallow copy of all registered condition functions. - **Returns:** - `SqlConditions` โ€” Object mapping keys to condition functions. --- ### โž• Method: `addCondition(key, conditionHandler, valueHandler = null)` Registers a new condition type for query generation. - **Parameters:** - `key` (`string`): Unique identifier for the condition. - `conditionHandler` (`string` | `WhereConditions` | `WhereConditionsFunc`): Defines the condition logic. - String: SQL operator (e.g., `'='`, `'LIKE'`) - Object: Must include `.operator` (e.g., `{ operator: '>=' }`) - Function: Custom condition builder function. - `valueHandler` (`function(string): string` | `null`): Optional function transforming parameter values (e.g., for `SOUNDEX`). - **Validation:** - Throws if `key` is not a non-empty string. - Throws if `key` already exists in conditions or value handlers. - Throws if `conditionHandler` is not valid type. - Throws if `valueHandler` is provided but not a function. - **Behavior:** - Stores `conditionHandler` internally (function wrapped if string or object). - Stores `valueHandler` if provided. --- ### ๐ŸŽฏ Method: `addConditionV2(funcName, editParamByDefault = false, operator = '=')` Registers a SQL function-based condition with optional parameter transformation. - **Purpose:** Wraps a SQL column in a function (e.g., `LOWER(column)`) and optionally applies the same function to the parameter (`LOWER($1)`). - **Parameters:** - `funcName` (`string`): SQL function name (must be non-empty). - `editParamByDefault` (`boolean`, default `false`): If `true`, applies function to the query parameter by default. - `operator` (`string`, default `'='`): SQL comparison operator. - **Runtime Behavior:** - Uses `group.newOp` if provided to override operator. - Uses `group.funcName` if provided to override function name in SQL and value transformation. - Final SQL resembles: `FUNC(column) OP FUNC($n)` or `FUNC(column) OP $n` depending on `editParamByDefault`. - **Throws:** - `TypeError` if parameters are invalid types or empty strings. - **Example Usages:** - Registering ROUND with operator `!=`: ```js addConditionV2('ROUND', false, '!='); ``` - Registering LOWER with parameter function: ```js addConditionV2('LOWER', true); // Parses: LOWER(username) = LOWER($1) ``` - Registering UPPER without parameter function: ```js addConditionV2('UPPER'); // Parses: UPPER(username) = $1 ``` - Overriding operator at runtime: ```js addConditionV2('CEIL', true); parse({ column: 'price', value: 3, newOp: '>', operator: 'CEIL', funcName: null }); // Result: CEIL(price) > 3 ``` --- ## ๐Ÿงฉ selectGenerator & JSON Helpers ### ๐ŸŽฏ Method: `selectGenerator(input = '*')` Generates a SQL SELECT clause from flexible input formats, supporting aliases, complex expressions, and weighted boosts via CASE statements. #### Supported input types: - `null` / `undefined`: returns `'*'` - `string`: returns the parsed column or SQL expression (supports aliases with `AS`) - `string[]`: returns a comma-separated list of parsed columns - `object`: supports structured input with: - `aliases`: key-value pairs for columns and aliases - `values`: array of column names or expressions - `boost`: weighted relevance using CASE, with rules for columns, operators, values, and weights #### Boost rules support: - `columns` (optional): single string or array of strings (target columns) - `value`: string or array (value(s) to compare) or raw SQL condition if `columns` omitted - `operator`: SQL operator (default `'LIKE'`, supports `'IN'`, `'='`, etc.) - `weight`: numeric weight applied on match (default `1`) > All values are escaped using `pg.escapeLiteral()` for PostgreSQL safety. #### Throws: - `TypeError` for invalid input types - `Error` if `boost.alias` is missing or invalid - `Error` if `boost.value` exists but is not an array #### Examples: ```js selectGenerator(); // returns '*' selectGenerator('COUNT(*) AS total'); // returns 'COUNT(*) AS total' selectGenerator(['id', 'username']); // returns 'id, username' selectGenerator({ aliases: { id: 'image_id', uploader: 'user_name' }, values: ['created_at', 'score'] }); // returns 'id AS image_id, uploader AS user_name, created_at, score' selectGenerator({ aliases: { id: 'image_id', uploader: 'user_name' }, values: ['created_at'], boost: { alias: 'relevance', value: [ { columns: ['tags', 'description'], value: 'fluttershy', weight: 2 }, { columns: 'tags', value: 'pinkie pie', operator: 'LIKE', weight: 1.5 }, { columns: 'tags', value: 'oc', weight: -1 }, { value: "score > 100 AND views < 1000", weight: 5 } ] } }); // returns CASE statement boosting relevance + other columns ``` --- ### ๐Ÿงฉ Method: `parseColumn(column, alias)` Parses an individual column or SQL expression, optionally applying an alias. * `column` (`string`): Column name or SQL expression * `alias` (`string`, optional): Alias name **Returns:** SQL snippet like `"column"` or `"column AS alias"` **Throws:** * `TypeError` if inputs are not strings --- ### ๐Ÿ”ง JSON SQL Helpers These methods help generate SQLite-compatible JSON queries: #### `#sqlOpStringVal(value)` Internal helper that asserts the input is a string and returns it. --- #### `getJsonExtract(where, name)` Generates SQLite JSON extraction snippet: ```sql json_extract(where, '$.name') ``` * `where` (`string`): JSON column or expression * `name` (`string`): Key or JSON path --- #### `getJsonEach(source)` Generates SQLite `json_each` call to expand JSON arrays or objects into rows: ```sql json_each(source) ``` * `source` (`string`): JSON column or expression --- #### `getArrayExtract(where, name)` Combines `getJsonExtract` and `getJsonEach` to expand a JSON array from a specific key: ```sql json_each(json_extract(where, '$.name')) ``` * `where` (`string`): JSON column * `name` (`string`): Key containing array --- #### `getJsonCast(where, name, type)` Extracts a JSON value and casts it to a specified SQLite type: ```sql CAST(json_extract(where, '$.name') AS TYPE) ``` * `where` (`string`): JSON column * `name` (`string`): Key to extract * `type` (`string`): SQLite type to cast to (e.g., `'INTEGER'`, `'TEXT'`, `'REAL'`) --- ## ๐Ÿ› ๏ธ Table Schema Management & Tag Editors ### ๐Ÿ”„ Method: `async updateTable(changes)` Updates a SQL table schema by adding, removing, modifying, or renaming columns. #### Parameters: - `changes` (`SqlTableConfig`): Array of change commands, each an array: - `['ADD', columnName, columnType, columnOptions?]` - `['REMOVE', columnName]` - `['MODIFY', columnName, newColumnType, newOptions?]` - `['RENAME', oldColumnName, newColumnName]` #### Behavior: - Executes corresponding `ALTER TABLE` SQL statements. - Uses `this.getDb()` for DB access. - Throws on invalid input. - Logs errors if DB operations fail but continues. #### Throws: - `TypeError` if `changes` is not an array of arrays or invalid action. - `Error` if required parameters for each action are missing or invalid. --- ### ๐Ÿ’ฅ Method: `async dropTable()` Drops the current table if it exists. #### Returns: - `Promise<boolean>`: resolves `true` on success, `false` on failure (except connection errors, which reject). #### Behavior: - Runs `DROP TABLE {tableName}`. - Uses connection error detection to reject or resolve accordingly. --- ### ๐Ÿ—๏ธ Method: `async createTable(columns)` Creates a SQL table based on column definitions. #### Parameters: - `columns` (`SqlTableConfig`): Array of column definitions, each an array: - `[name, type, options?]` - Custom type `"TAGS"` is converted internally to `"JSON"` and registered for tag management. #### Behavior: - Builds a `CREATE TABLE IF NOT EXISTS` statement. - Stores the column schema in `this.#table` with uppercase types and options. - Creates `PuddySqlTags` instances for `"TAGS"` columns stored in `this.#tagColumns`. - Throws on invalid definitions or missing table name. --- ### ๐Ÿ”– Method: `hasTagEditor(name)` Checks if a column has an associated tag editor (`PuddySqlTags` instance). #### Parameters: - `name` (`string`): Column name. #### Returns: - `boolean` โ€” `true` if tag editor exists, `false` otherwise. --- ### ๐Ÿ” Method: `getTagEditor(name)` Retrieves the `PuddySqlTags` instance for a specific tag column. #### Parameters: - `name` (`string`): Column name. #### Returns: - `PuddySqlTags` instance. #### Throws: - `Error` if the column has no associated tag editor or invalid input. --- ### ๐Ÿ“‹ Method: `getTagEditors()` Returns all tag editors as a shallow copy object mapping column names to their `PuddySqlTags`. #### Returns: - `Record<string, PuddySqlTags>` โ€” All tag editors by column. --- ## ๐Ÿงช Data Conversion, Escaping & Settings ### ๐Ÿ”ƒ `#jsonEscape` โ€” Type Conversion Utilities A private map of functions that convert raw SQL values into native JavaScript types. | Key | Description | |----------|-------------| | `boolean` | Returns `true` for: `true`, `"true"`, `1`, `"1"`. | | `bigInt` | Converts values to `BigInt`. Returns `null` on failure. | | `int` | Parses to integer (`parseInt`). Returns `null` if NaN. | | `float` | Parses to float (`parseFloat`). Returns `null` if NaN. | | `json` | Parses JSON strings. Returns original if already object/array. | | `tags` | Parses strings to arrays of strings. Invalid elements become `null`. | | `text` | Returns the string if it's valid. Otherwise `null`. | | `date` | Converts to valid `Date` object. Returns `null` if invalid. | --- ### ๐Ÿงฌ `#jsonEscapeAlias` โ€” SQL Type Mappings Maps SQL types (e.g., `INTEGER`, `TEXT`, `TAGS`) to their corresponding `#jsonEscape` functions. Supported aliases include: - `BOOLEAN`, `BOOL` - `BIGINT`, `DECIMAL`, `NUMERIC` - `INTEGER`, `INT`, `SMALLINT`, `TINYINT` - `REAL`, `FLOAT`, `DOUBLE` - `TEXT`, `CHAR`, `VARCHAR`, `CLOB` - `JSON`, `TAGS` - `DATE`, `DATETIME`, `TIMESTAMP`, `TIME` --- ### โœ… Method: `resultChecker(result)` Converts result rows from raw SQL types into properly typed JavaScript values based on `this.#table`. #### Parameters: - `result` (`object`) โ€” A result row from the database. #### Returns: - `FreeObj` โ€” The same object, converted. --- ### ๐Ÿ›ก๏ธ Method: `escapeValues(valueObj)` Converts values for writing back to the database using type definitions from `this.#table`. #### Parameters: - `valueObj` (`FreeObj`) โ€” Object of raw input values. #### Returns: - `FreeObj` โ€” The same object, with values sanitized or transformed. --- ### โš™๏ธ Method: `setDb(settings, db)` Merges new settings with existing internal config and sets the database instance. #### Parameters: - `settings` (`Partial<TableSettings>`) โ€” Any new values to apply. - `db` (`PuddySqlEngine`) โ€” Reference to the main database engine. #### Behavior: - Validates and fills default values (`select`, `join`, `id`, etc.) - Uses `selectGenerator` for advanced select clause handling. #### Throws: - `TypeError` if `settings` is not an object. - `Error` if `db` is not an instance of `PuddySqlEngine`. --- ### ๐Ÿ“Š Private: `#resultCounts` Maps driver types to the field used to count affected rows: - `"sqlite3"` โ†’ `"changes"` - `"postgre"` โ†’ `"rowCount"` Used internally to abstract SQL dialect differences. --- ## ๐Ÿ”ง Updates, Inserts & Transformations ### ๐Ÿ“Š Method: `getResultCount(result)` Returns the number of affected rows from a database result, abstracting engine-specific fields. | Engine | Field | |--------------|---------------| | `sqlite3` | `changes` | | `postgre` | `rowCount` | | Fallback | `rowsAffected` | #### Parameters: - `result` (`object|null`) โ€” Result from `run()` or query execution. #### Returns: - `number` โ€” Affected rows, or `0`. --- ### ๐Ÿ”Ž Method: `has(id, subId?)` Checks if a row exists using primary key (and optional `subId` for composite keys). #### Parameters: - `id` (`string|number`) โ€” Primary ID. - `subId` (`string|number`) โ€” Optional secondary ID. #### Returns: - `Promise<boolean>` โ€” `true` if exists. --- ### ๐Ÿ› ๏ธ Private: `#jsonEscapeFix` โ€” Output Transformers Used when saving data back to SQL. | Type | Behavior | |-------|----------| | `JSON` | `JSON.stringify(value)` | | `TAGS` | Ensures all entries are strings before stringifying | --- ### ๐Ÿ” Method: `escapeValuesFix(v, name)` Applies the appropriate fix function for a specific column type before writing. #### Parameters: - `v` (`any`) โ€” Value to transform. - `name` (`string`) โ€” Column name. #### Returns: - `any` โ€” Escaped value or original. --- ### ๐Ÿงฌ Method: `advancedUpdate(valueObj, filter)` Updates one or more rows using a filter object instead of direct IDs. #### Parameters: - `valueObj` (`FreeObj`) โ€” Fields to update. - `filter` (`QueryGroup`) โ€” WHERE clause object. #### Returns: - `Promise<number>` โ€” Rows updated. --- ### ๐Ÿ”„ Method: `update(id, valueObj)` Updates a row using its primary key (`subId` supported if available). #### Parameters: - `id` (`string|number`) โ€” Primary ID. - `valueObj` (`FreeObj`) โ€” Fields to update. #### Returns: - `Promise<number>` โ€” Rows updated. --- ### ๐Ÿ“ฅ Method: `set(id, valueObj, onlyIfNew = false)` Inserts or updates one or more rows. Automatically escapes values and handles generated IDs. #### Parameters: - `id` (`string|number|string[]|number[]`) โ€” Primary key(s). - `valueObj` (`FreeObj|FreeObj[]`) โ€” One or many objects with fields. - `onlyIfNew` (`boolean`) โ€” If `true`, skips update on conflict. #### Behavior: - Uses `ON CONFLICT DO UPDATE` (or `DO NOTHING`) - Detects auto-generated or primary key columns and returns them. - Ensures all entries in `valueObj[]` are uniform in keys. #### Returns: - `Promise<FreeObj|FreeObj[]|null>` โ€” Inserted or updated row(s), or `null`. --- ### ๐Ÿ“Œ Method: `get(id, subId?)` Fetches a single record using its primary key (and optional `subId` if defined). #### Parameters: - `id` (`string|number`) โ€” Primary key. - `subId?` (`string|number`) โ€” Optional composite key. #### Returns: - `Promise<FreeObj|null>` โ€” Record if found, else `null`. --- ### ๐Ÿ—‘๏ธ Method: `advancedDelete(filter)` Deletes records matching a complex filter condition. #### Parameters: - `filter` (`QueryGroup`) โ€” Object representing WHERE conditions. #### Returns: - `Promise<number>` โ€” Number of rows deleted. --- ### โŒ Method: `delete(id, subId?)` Deletes a record by primary key (and optional `subId`). #### Parameters: - `id` (`string|number`) - `subId?` (`string|number`) #### Returns: - `Promise<number>` โ€” Number of rows deleted. --- ### ๐Ÿ”ข Method: `getAmount(count, filterId?, selectValue?)` Returns up to `count` items. Optionally filter by ID and control selected columns. #### Parameters: - `count` (`number`) - `filterId?` (`string|number|null`) - `selectValue?` (`SelectQuery`) โ€” Default: `"*"` #### Returns: - `Promise<FreeObj[]>` --- ### ๐Ÿ“„ Method: `getAll(filterId?, selectValue?)` Fetches all records in the table or filtered by a specific ID. #### Parameters: - `filterId?` (`string|number|null`) - `selectValue?` (`SelectQuery`) โ€” Default: `"*"` #### Returns: - `Promise<FreeObj[]>` --- ### ๐Ÿ“š Method: `execPagination(query, params, perPage, page, queryName?)` Runs a paginated query and returns total items and total pages. #### Parameters: - `query` (`string`) - `params` (`any[]`) - `perPage` (`number`) - `page` (`number`) - `queryName?` (`string`) โ€” Optional label for debugging. #### Returns: - `Promise<{ items: FreeObj[], totalPages: number, totalItems: number }>` โ€” Paginated result set. --- ### ๐Ÿงฉ Method: `parseWhere(pCache, group)` Parses a flexible query condition group into a SQL WHERE clause. #### Supports: - Logical groups (`AND`, `OR`) - Custom condition handlers (`this.#conditions`) - Nested or flat filters - Placeholders via `pCache` #### Parameters: - `pCache` (`Pcache`) โ€” Placeholder manager: `{ index: number, values: any[] }` - `group` (`QueryGroup`) โ€” Group or single condition object. #### Returns: - `string` โ€” SQL WHERE clause string (without `WHERE`) #### Example: ```js const p = { index: 1, values: [] }; const clause = this.parseWhere(p, { group: 'OR', conditions: [ { column: 'status', value: 'active' }, { column: 'type', value: 'admin', operator: '=' }, ], }); // clause: "(status = $1) OR (type = $2)" // p.values: ['active', 'admin'] ``` --- ### ๐Ÿ”„ Method: `insertJoin()` Returns a default `LEFT JOIN` clause if configured in `#settings`. #### Returns: - `string` โ€” SQL JOIN clause or empty string. --- ### ๐Ÿ”— `#joinTypes` (private) Internal object with predefined JOIN types: - `inner`: `'INNER JOIN'` - `left`: `'LEFT JOIN'` - `right`: `'RIGHT JOIN'` - `full`: `'FULL JOIN'` - `cross`: `'CROSS JOIN'` - `join`: `'JOIN'` (shorthand for inner) --- ### ๐Ÿงฉ Method: `parseJoin(join)` Parses JOIN configuration into one or more SQL JOIN clauses. #### Parameters: - `join` (`JoinObj | JoinObj[] | string | null`) #### Returns: - `string` โ€” JOIN clauses string. --- ### ๐Ÿ” Method: `find(searchData)` Finds the **first** matching result and returns its position, page, and optionally its data. Query only: `findQuery(searchData)` #### Parameters: - `searchData` (`object`) - `q`: QueryGroup or object condition - `tagCriteria`: Single or multiple tag filters - `tagCriteriaOps`: Logical ops between tag filters - `perPage`: Required, results per page - `select`: Columns to select (`'*'` by default, or `null` to skip data) - `order`: Custom `ORDER BY` - `join`: JOIN configs (string, object or array) #### Returns: - `Promise<FindResult|null>` --- ### ๐Ÿ”Ž Method: `search(searchData)` Performs a complete filtered query with optional **pagination**, **joins**, and **tags**. Query only: `searchQuery(searchData)` #### Parameters: * `searchData` (`object`) * `q`: QueryGroup or flat condition object * `tagsQ`: Tags filter (array or object) * `tagsOpsQ`: Logical ops between tags (`['AND', 'OR']`) * `select`: Select clause (`'*'`, array, object or `null`) * `perPage`: Items per page * `page`: Page number (default: 1) * `order`: Custom ORDER BY clause * `join`: JOINs configuration * `limit`: Max number of rows (ignored if `perPage` is used) #### Returns: * `Promise<FreeObj[] | PaginationResult>` #### Example: ```js await table.search({ q: { group: 'AND', conditions: [ { column: 'status', value: 'active' }, { group: 'OR', conditions: [ { column: 'type', value: 'admin' }, { column: 'type', value: 'mod' } ] } ] }, tagsQ: [{ column: 'tags', value: 'featured' }], select: '*', perPage: 15, page: 1, order: 'created_at DESC', join: [ { type: 'left', table: 'profiles', compare: 't.profile_id = j1.id' }, { type: 'left', table: 'roles', compare: 'j1.role_id = j2.id' } ] }); ```