(
dialect: SQLDialect,
idKey: PropertyKey,
filter: readonly FilterResult[],
tableName: string,
defaultValues: Record<string, unknown>,
select?: NonEmptyReadonlyArray<
string | {
key: string
subKeys: readonly string[]
} | {
key: string
computed: ComputedProjectionIrExpression
} | {
key: string
path: string
} | {
key: string
aggregate: AggregateIrExpression
}
>,
order?: NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }>,
skip?: number,
limit?: number,
namespace?: string
)
| 152 | const sqlStringLiteral = (value: string) => `'${value.replaceAll("'", "''")}'` |
| 153 | |
| 154 | export function buildWhereSQLQuery( |
| 155 | dialect: SQLDialect, |
| 156 | idKey: PropertyKey, |
| 157 | filter: readonly FilterResult[], |
| 158 | tableName: string, |
| 159 | defaultValues: Record<string, unknown>, |
| 160 | select?: NonEmptyReadonlyArray< |
| 161 | string | { |
| 162 | key: string |
| 163 | subKeys: readonly string[] |
| 164 | } | { |
| 165 | key: string |
| 166 | computed: ComputedProjectionIrExpression |
| 167 | } | { |
| 168 | key: string |
| 169 | path: string |
| 170 | } | { |
| 171 | key: string |
| 172 | aggregate: AggregateIrExpression |
| 173 | } |
| 174 | >, |
| 175 | order?: NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }>, |
| 176 | skip?: number, |
| 177 | limit?: number, |
| 178 | namespace?: string |
| 179 | ) { |
| 180 | const params: unknown[] = [] |
| 181 | let paramIndex = 1 |
| 182 | |
| 183 | const addParam = (value: unknown): string => { |
| 184 | params.push(dialect.serializeScalar(value)) |
| 185 | return dialect.placeholder(paramIndex++) |
| 186 | } |
| 187 | |
| 188 | const fieldExpr = (path: string, relation?: string): string => { |
| 189 | if (path === idKey || path === "id") return "id" |
| 190 | if (relation && path.includes(".-1.")) { |
| 191 | const subPath = path.split(".-1.")[1]! |
| 192 | if (subPath.endsWith(".length")) { |
| 193 | // TODO: array length inside relation element |
| 194 | return dialect.jsonExtractElement(`_${relation}`, subPath.slice(0, -".length".length)) |
| 195 | } |
| 196 | return dialect.jsonExtractElement(`_${relation}`, subPath) |
| 197 | } |
| 198 | if (path.endsWith(".length")) { |
| 199 | const arrPath = dottedToJsonPath(path.slice(0, -".length".length)) |
| 200 | return dialect.arrayLength(arrPath) |
| 201 | } |
| 202 | const jsonPath = dottedToJsonPath(path) |
| 203 | const expr = dialect.jsonExtract(jsonPath) |
| 204 | const topKey = path.split(".")[0] |
| 205 | if (topKey in defaultValues) { |
| 206 | return `COALESCE(${expr}, ${addParam(defaultValues[topKey])})` |
| 207 | } |
| 208 | return expr |
| 209 | } |
| 210 | |
| 211 | const statement = (x: FilterR, relation?: string): string => { |
no test coverage detected
searching dependent graphs…