( options: LoadSubsetOptions, compileOptions?: CompileSQLOptions, )
| 25 | } |
| 26 | |
| 27 | export function compileSQL<T>( |
| 28 | options: LoadSubsetOptions, |
| 29 | compileOptions?: CompileSQLOptions, |
| 30 | ): SubsetParams { |
| 31 | const { where, orderBy, limit } = options |
| 32 | const encodeColumnName = compileOptions?.encodeColumnName |
| 33 | |
| 34 | const params: Array<T> = [] |
| 35 | const compiledSQL: CompiledSqlRecord = { params } |
| 36 | |
| 37 | if (where) { |
| 38 | // TODO: this only works when the where expression's PropRefs directly reference a column of the collection |
| 39 | // doesn't work if it goes through aliases because then we need to know the entire query to be able to follow the reference until the base collection (cf. followRef function) |
| 40 | compiledSQL.where = compileBasicExpression(where, params, encodeColumnName) |
| 41 | } |
| 42 | |
| 43 | if (orderBy) { |
| 44 | compiledSQL.orderBy = compileOrderBy(orderBy, params, encodeColumnName) |
| 45 | } |
| 46 | |
| 47 | if (limit) { |
| 48 | compiledSQL.limit = limit |
| 49 | } |
| 50 | |
| 51 | // WORKAROUND for Electric bug: Empty subset requests don't load data |
| 52 | // Add dummy "true = true" predicate when there's no where clause |
| 53 | // This is always true so doesn't filter data, just tricks Electric into loading |
| 54 | if (!where) { |
| 55 | compiledSQL.where = `true = true` |
| 56 | } |
| 57 | |
| 58 | // Serialize the values in the params array into PG formatted strings |
| 59 | // and transform the array into a Record<string, string> |
| 60 | const paramsRecord = params.reduce( |
| 61 | (acc, param, index) => { |
| 62 | const serialized = serialize(param) |
| 63 | // Empty strings are valid query values (e.g., WHERE column = '') |
| 64 | // Only omit null/undefined values from params |
| 65 | if (param != null) { |
| 66 | acc[`${index + 1}`] = serialized |
| 67 | } |
| 68 | return acc |
| 69 | }, |
| 70 | {} as Record<string, string>, |
| 71 | ) |
| 72 | |
| 73 | return { |
| 74 | ...compiledSQL, |
| 75 | params: paramsRecord, |
| 76 | } |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * Quote PostgreSQL identifiers to handle mixed case column names correctly. |
no test coverage detected