6.4 KiB
6.4 KiB
Query Helper API Reference
This document provides a complete reference for the JSON-based database query helper.
Method Overview
| Method | Description | Notes |
|---|---|---|
select(options) |
Retrieve records from database | JSON-based query builder |
insert(options) |
Insert new record(s) | Single or batch insert |
update(options) |
Update existing records | Requires WHERE clause |
deleteRecord(options) |
Delete records | Requires WHERE clause |
execute(options) |
Execute transactions or custom queries | Transactions or raw builder |
Detailed Method Reference
SELECT
Retrieve records from database with filtering, sorting, and pagination.
const users = await select({
table: 'users',
where: { deleted: false, status: 'active' },
orderBy: { column: 'created_at', direction: 'desc' },
limit: 20
});
Options:
table(string, required): Table name (must be in whitelist)columns(string[] | '', optional): Columns to select (default: '')where(object, optional): WHERE conditionsorderBy(object, optional):{ column: string, direction: 'asc'|'desc' }limit(number, optional): Max records (capped at 100)offset(number, optional): Skip recordsjoins(array, optional): Join configurations
INSERT
Insert new record(s) into database.
const user = await insert({
table: 'users',
data: { name: 'John', phone: '+1234567890' },
returning: ['id', 'name']
});
Options:
table(string, required): Table namedata(object | object[], required): Data to insert (single object or array for batch)returning(string[] | '*', optional): Columns to return (PostgreSQL)
UPDATE
Update existing records in database.
const updated = await update({
table: 'users',
data: { name: 'Jane' },
where: { id: userId }
});
Options:
table(string, required): Table namedata(object, required): Data to updatewhere(object, required): WHERE conditions (required for safety)returning(string[] | '*', optional): Columns to return
DELETE
Delete records from database.
await deleteRecord({
table: 'users',
where: { id: userId }
});
Options:
table(string, required): Table namewhere(object, required): WHERE conditions (required for safety)returning(string[] | '*', optional): Columns to return
EXECUTE (Transaction)
Execute transactions or custom query builder logic.
await execute({
type: 'transaction',
handler: async (trx) => {
await trx('animals').insert(animalData);
await trx('listings').insert(listingData);
}
});
Options:
type(string, required): 'transaction' or 'raw-builder'handler(function, required): Handler function receiving knex/trx instance
WHERE Clause Operators
| Operator | Description | Example |
|---|---|---|
| Equality | Simple key-value match | where: { status: 'active' } |
> |
Greater than | where: { price: { op: '>', value: 100 } } |
< |
Less than | where: { age: { op: '<', value: 18 } } |
>= |
Greater than or equal | where: { price: { op: '>=', value: 100 } } |
<= |
Less than or equal | where: { age: { op: '<=', value: 65 } } |
!= or <> |
Not equal | where: { status: { op: '!=', value: 'deleted' } } |
in |
In array | where: { id: { op: 'in', value: [1, 2, 3] } } |
notIn |
Not in array | where: { id: { op: 'notIn', value: [1, 2, 3] } } |
like |
Case-sensitive LIKE | where: { name: { op: 'like', value: '%John%' } } |
ilike |
Case-insensitive LIKE | where: { name: { op: 'ilike', value: '%john%' } } |
between |
Between two values | where: { age: { op: 'between', value: [18, 65] } } |
isNull |
IS NULL | where: { deleted_at: { op: 'isNull' } } |
isNotNull |
IS NOT NULL | where: { deleted_at: { op: 'isNotNull' } } |
Supported Operators
| Operator | Description | Example |
|---|---|---|
> |
Greater than | { op: '>', value: 100 } |
< |
Less than | { op: '<', value: 100 } |
>= |
Greater than or equal | { op: '>=', value: 100 } |
<= |
Less than or equal | { op: '<=', value: 100 } |
!= or <> |
Not equal | { op: '!=', value: 'deleted' } |
in |
In array | { op: 'in', value: [1, 2, 3] } |
notIn |
Not in array | { op: 'notIn', value: [1, 2, 3] } |
like |
Case-sensitive LIKE | { op: 'like', value: '%test%' } |
ilike |
Case-insensitive LIKE | { op: 'ilike', value: '%test%' } |
between |
Between two values | { op: 'between', value: [10, 20] } |
isNull |
IS NULL | { op: 'isNull' } |
isNotNull |
IS NOT NULL | { op: 'isNotNull' } |
Naming Conventions
- Table names: lowercase, snake_case (e.g.,
users,listing_media) - Column names: lowercase, snake_case (e.g.,
created_at,user_id) - Options: camelCase (e.g.,
orderBy,returning) - Operators: lowercase (e.g.,
op: '>')
Type System
- JavaScript: JSON objects with runtime validation
- Runtime Validation: Descriptive errors for invalid inputs
- Type Safety: Structured JSON prevents SQL injection
Error Handling
- Runtime Validation: All inputs validated at runtime
- Descriptive Errors: Clear error messages for debugging
- Database Errors: Propagated with context
Transactions
await execute({
type: 'transaction',
handler: async (trx) => {
await trx('users').insert(userData);
await trx('listings').insert(listingData);
}
});
Migration Checklist
When migrating from raw SQL to queryHelper:
- Replace
pool.query()withselect(),insert(),update(), ordeleteRecord() - Convert SQL WHERE clauses to JSON objects
- Replace string concatenation with structured options
- Convert transactions to
execute({ type: 'transaction' }) - Update JOINs to use
joinsarray - Replace parameterized queries with JSON where conditions
- Test all queries to ensure same results
- Remove all raw SQL strings from service layer
Benefits
- Type Safety: Structured JSON prevents SQL injection
- Readability: Clear, self-documenting queries
- Maintainability: Easy to modify and extend
- Security: Table whitelist prevents unauthorized access
- Consistency: Uniform query interface across codebase
- Testing: Easier to mock and test