* Builds SQL conditions for a single field based on the provided condition. * * Supports both simple equality checks (using JSONB containment) and complex * operators like comparison, membership, and pattern matching. Field names are * validated to prevent SQL injection, and operators are valida
( tableName: string, field: string, condition: JsonValue | ConditionOperators, columnType: ColumnType | undefined )
| 302 | * @throws {TableQueryValidationError} if field name is invalid or operator is not allowed |
| 303 | */ |
| 304 | function buildFieldCondition( |
| 305 | tableName: string, |
| 306 | field: string, |
| 307 | condition: JsonValue | ConditionOperators, |
| 308 | columnType: ColumnType | undefined |
| 309 | ): SQL[] { |
| 310 | validateFieldName(field) |
| 311 | |
| 312 | const conditions: SQL[] = [] |
| 313 | |
| 314 | if (typeof condition === 'object' && condition !== null && !Array.isArray(condition)) { |
| 315 | for (const [op, value] of Object.entries(condition)) { |
| 316 | // Validate operator to ensure only allowed operators are used |
| 317 | validateOperator(op) |
| 318 | |
| 319 | switch (op) { |
| 320 | case '$eq': |
| 321 | conditions.push(buildContainmentClause(tableName, field, value as JsonValue)) |
| 322 | break |
| 323 | |
| 324 | case '$ne': |
| 325 | conditions.push( |
| 326 | sql`NOT (${buildContainmentClause(tableName, field, value as JsonValue)})` |
| 327 | ) |
| 328 | break |
| 329 | |
| 330 | case '$gt': |
| 331 | conditions.push( |
| 332 | buildComparisonClause(tableName, field, '>', value as number | string, columnType) |
| 333 | ) |
| 334 | break |
| 335 | |
| 336 | case '$gte': |
| 337 | conditions.push( |
| 338 | buildComparisonClause(tableName, field, '>=', value as number | string, columnType) |
| 339 | ) |
| 340 | break |
| 341 | |
| 342 | case '$lt': |
| 343 | conditions.push( |
| 344 | buildComparisonClause(tableName, field, '<', value as number | string, columnType) |
| 345 | ) |
| 346 | break |
| 347 | |
| 348 | case '$lte': |
| 349 | conditions.push( |
| 350 | buildComparisonClause(tableName, field, '<=', value as number | string, columnType) |
| 351 | ) |
| 352 | break |
| 353 | |
| 354 | case '$in': |
| 355 | if (Array.isArray(value) && value.length > 0) { |
| 356 | if (value.length === 1) { |
| 357 | // Single value then use containment clause |
| 358 | conditions.push(buildContainmentClause(tableName, field, value[0])) |
| 359 | } else { |
| 360 | // Multiple values then use OR clause |
| 361 | const inConditions = value.map((v) => buildContainmentClause(tableName, field, v)) |
no test coverage detected