- Abstract shared sql code to a new drizzle package - Adds sqlite package, not ready to publish until drizzle patches some issues - Add `transactionOptions` to allow customizing or disabling db transactions - Adds "experimental" label to the `schemaName` property until drizzle patches an issue
88 lines
1.9 KiB
TypeScript
88 lines
1.9 KiB
TypeScript
import { convertPathToJSONTraversal } from './convertPathToJSONTraversal.js'
|
|
import { formatJSONPathSegment } from './formatJSONPathSegment.js'
|
|
|
|
const operatorMap = {
|
|
contains: '~*',
|
|
equals: '=',
|
|
like: '~*',
|
|
}
|
|
|
|
type FromArrayArgs = {
|
|
isRoot?: true
|
|
operator: string
|
|
pathSegments: string[]
|
|
treatAsArray?: string[]
|
|
value: unknown
|
|
}
|
|
|
|
const fromArray = ({ isRoot, operator, pathSegments, treatAsArray, value }: FromArrayArgs) => {
|
|
const newPathSegments = pathSegments.slice(isRoot ? 1 : 2)
|
|
const alias = `${pathSegments[isRoot ? 0 : 1]}_alias_${newPathSegments.length}`
|
|
|
|
newPathSegments.unshift(alias)
|
|
|
|
const arrayElements = isRoot
|
|
? pathSegments[0]
|
|
: `${pathSegments[0]} -> ${formatJSONPathSegment(pathSegments[1])}`
|
|
|
|
return `EXISTS (
|
|
SELECT 1
|
|
FROM jsonb_array_elements(${arrayElements}) AS ${alias}
|
|
WHERE ${createJSONQuery({
|
|
operator,
|
|
pathSegments: newPathSegments,
|
|
treatAsArray,
|
|
value,
|
|
})}
|
|
)`
|
|
}
|
|
|
|
type CreateConstraintArgs = {
|
|
operator: string
|
|
pathSegments: string[]
|
|
treatAsArray?: string[]
|
|
value: unknown
|
|
}
|
|
|
|
const createConstraint = ({ operator, pathSegments, value }: CreateConstraintArgs): string => {
|
|
const jsonQuery = convertPathToJSONTraversal(pathSegments)
|
|
return `${pathSegments[0]}${jsonQuery} ${operatorMap[operator]} '${value}'`
|
|
}
|
|
|
|
type Args = {
|
|
operator: string
|
|
pathSegments: string[]
|
|
treatAsArray?: string[]
|
|
treatRootAsArray?: boolean
|
|
value: unknown
|
|
}
|
|
|
|
export const createJSONQuery = ({
|
|
operator,
|
|
pathSegments,
|
|
treatAsArray,
|
|
treatRootAsArray,
|
|
value,
|
|
}: Args): string => {
|
|
if (treatRootAsArray) {
|
|
return fromArray({
|
|
isRoot: true,
|
|
operator,
|
|
pathSegments,
|
|
treatAsArray,
|
|
value,
|
|
})
|
|
}
|
|
|
|
if (treatAsArray.includes(pathSegments[1])) {
|
|
return fromArray({
|
|
operator,
|
|
pathSegments,
|
|
treatAsArray,
|
|
value,
|
|
})
|
|
}
|
|
|
|
return createConstraint({ operator, pathSegments, treatAsArray, value })
|
|
}
|