Skip to content

Commit

Permalink
Modify types for special expressions, correct types for eqContains an…
Browse files Browse the repository at this point in the history
…d update tests
  • Loading branch information
Antony1060 committed Aug 11, 2023
1 parent de81228 commit 17f7b3a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 14 deletions.
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']});
})
40 changes: 28 additions & 12 deletions src/EqualityBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,65 +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<T, 'contains'> => ({
operation: ` contains ${value}`,
): 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],
});

0 comments on commit 17f7b3a

Please sign in to comment.