Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement eqContains #55

Merged
merged 2 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions __tests__/raw/selectFromRaw.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { selectFromRaw } from '../../lib';
import { eqGreaterThanOrEqual, eqIn } from '../../lib/EqualityBuilder';
import { selectFromRaw, eqGreaterThanOrEqual, eqIn, eqContains } from '../../lib';

// fix
it('Can insert a user into the database', async () => {
Expand All @@ -18,3 +17,7 @@ it('Can do number equality', async () => {
it('Can do in equality', async () => {
expect(selectFromRaw<{'users': {uid: number, username: string}}, 'users'>('scyllo', 'users', '*', {uid: 1, username: eqIn('antony', 'luc', 'jakob', 'elliot')}, 'ALLOW FILTERING')).toEqual({query: 'SELECT * FROM scyllo.users WHERE uid=? AND username in (?,?,?,?) ALLOW FILTERING', args: [1, 'antony', 'luc', 'jakob', 'elliot']});
})

it('Can do contains equality', async () => {
expect(selectFromRaw<{'users': {uid: number, roles: string[]}}, 'users'>('scyllo', 'users', '*', {uid: 1, roles: eqContains("admin")}, 'ALLOW FILTERING')).toEqual({query: 'SELECT * FROM scyllo.users WHERE uid=? AND roles contains ? ALLOW FILTERING', args: [1, 'admin']});
})
43 changes: 33 additions & 10 deletions src/EqualityBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,81 @@
export type EqualityExpression<T, Op extends string> = {
export type EqualityExpression<Op extends string> = {
// type-script
// .operation causes issues if op of e.g. 'contains' is assigned to 'in' because 'contains' contains 'in'
__opName: Op;
operation: `${string}${Op}${string}`;

values: any[];
};

// clean this up at some point
export type AllExpressions =
export type NumberExpressions =
| ReturnType<typeof eqLessThan>
| ReturnType<typeof eqLessThanOrEqual>
| ReturnType<typeof eqGreaterThan>
| ReturnType<typeof eqGreaterThanOrEqual>
| ReturnType<typeof eqIn>;

export type ExpressionByValue<Value> = Value extends number | bigint
? AllExpressions
// TODO: support for more values for collection-like expressions
export type ExpressionByValue<Value> = Value extends (
| string
| number
| bigint
)[]
? ReturnType<typeof eqContains>
: Value extends number | bigint
? NumberExpressions
: ReturnType<typeof eqIn>;

export const isEqualityExpression = (
object: any
): object is EqualityExpression<any, any> =>
): object is EqualityExpression<any> =>
typeof object === 'object' && object !== null && 'operation' in object;

// TODO: investigate how these things are compared and maybe add more types here
export const eqIn = <T extends (string | number | bigint)[]>(
...values: T
): EqualityExpression<T, 'in'> => ({
): EqualityExpression<'in'> => ({
__opName: 'in',
operation: ` in (${values.map((_) => '?').join(',')})`,
values,
});

export const eqContains = <T extends string | number | bigint>(
value: T
): EqualityExpression<'contains'> => ({
__opName: 'contains',
operation: ' contains ?',
values: [value],
});

export const eqLessThan = <T extends number | bigint>(
value: T
): EqualityExpression<T, '<'> => ({
): EqualityExpression<'<'> => ({
__opName: '<',
operation: '<?',
values: [value],
});

export const eqLessThanOrEqual = <T extends number | bigint>(
value: T
): EqualityExpression<T, '<='> => ({
): EqualityExpression<'<='> => ({
__opName: '<=',
operation: '<=?',
values: [value],
});

export const eqGreaterThan = <T extends number | bigint>(
value: T
): EqualityExpression<T, '>'> => ({
): EqualityExpression<'>'> => ({
__opName: '>',
operation: '>?',
values: [value],
});

export const eqGreaterThanOrEqual = <T extends number | bigint>(
value: T
): EqualityExpression<T, '>='> => ({
): EqualityExpression<'>='> => ({
__opName: '>=',
operation: '>=?',
values: [value],
});
Loading