Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | 8x 8x 8x 8x 8x 8x 12x 4x 530x 530x 530x 530x 530x 530x 12x 518x 12x 550x 12x 12x 1x 1x 1x 44x 70x 70x 50x 50x 20x 20x 20x 20x 10x 10x | import { Condition, GroupOperator, Operator, Paginator, QueryError, } from "../query"; import { RawRamQuery } from "./types"; import { Model } from "@decaf-ts/decorator-validation"; import { RamPaginator } from "./RamPaginator"; import { InternalError } from "@decaf-ts/db-decorators"; import { Statement } from "../query/Statement"; import { Reflection } from "@decaf-ts/reflection"; import { RamAdapter } from "./RamAdapter"; export class RamStatement<M extends Model, R> extends Statement< RawRamQuery<M>, M, R > { constructor(adapter: RamAdapter) { super(adapter as any); } private getSort() { return (el1: Model, el2: Model) => { Iif (!this.orderBySelector) throw new InternalError( "orderBySelector not set. Should be impossible" ); const selector = this.orderBySelector; const [key, direction] = selector; const type = Reflection.getTypeFromDecorator(el1, key as string); Iif (!type) throw new QueryError(`type not compatible with sorting: ${type}`); switch (type) { case "string": case "String": return ( (direction === "asc" ? 1 : -1) * (el1[key as keyof Model] as unknown as string).localeCompare( el2[key as keyof Model] as unknown as string ) ); case "number": case "Number": return ( (direction === "asc" ? 1 : -1) * ((el1[key as keyof Model] as unknown as number) - (el2[key as keyof Model] as unknown as number)) ); case "object": case "Object": Iif ( el1[key as keyof Model] instanceof Date && el2[key as keyof Model] instanceof Date ) return ( (direction === "asc" ? 1 : -1) * ((el1[key as keyof Model] as unknown as Date).valueOf() - (el2[key as keyof Model] as unknown as Date).valueOf()) ); throw new QueryError(`Sorting not supported for not date classes`); default: throw new QueryError(`sorting not supported for type ${type}`); } }; } protected build(): RawRamQuery<M> { const result: RawRamQuery<M> = { select: this.selectSelector, from: this.fromSelector, where: this.whereCondition ? this.parseCondition(this.whereCondition).where : // eslint-disable-next-line @typescript-eslint/no-unused-vars (el: M) => { return true; }, limit: this.limitSelector, skip: this.offsetSelector, }; if (this.orderBySelector) result.sort = this.getSort(); return result; } async paginate(size: number): Promise<Paginator<M, R, RawRamQuery<M>>> { try { const query = this.build(); return new RamPaginator<M, R>( this.adapter, query, size, this.fromSelector ); } catch (e: any) { throw new InternalError(e); } } parseCondition<M extends Model>(condition: Condition<M>): RawRamQuery<M> { return { where: (m: Model) => { const { attr1, operator, comparison } = condition as unknown as { attr1: string | Condition<M>; operator: Operator | GroupOperator; comparison: any; }; if ( [GroupOperator.AND, GroupOperator.OR, Operator.NOT].indexOf( operator as GroupOperator ) === -1 ) { switch (operator) { case Operator.BIGGER: return m[attr1 as keyof Model] > comparison; case Operator.BIGGER_EQ: return m[attr1 as keyof Model] >= comparison; case Operator.DIFFERENT: return m[attr1 as keyof Model] !== comparison; case Operator.EQUAL: return m[attr1 as keyof Model] === comparison; case Operator.REGEXP: Iif (typeof m[attr1 as keyof Model] !== "string") throw new QueryError( `Invalid regexp comparison on a non string attribute: ${m[attr1 as keyof Model]}` ); return !!(m[attr1 as keyof Model] as unknown as string).match( new RegExp(comparison, "g") ); case Operator.SMALLER: return m[attr1 as keyof Model] < comparison; case Operator.SMALLER_EQ: return m[attr1 as keyof Model] <= comparison; default: throw new InternalError( `Invalid operator for standard comparisons: ${operator}` ); } } else Iif (operator === Operator.NOT) { throw new InternalError("Not implemented"); } else { const op1: RawRamQuery<any> = this.parseCondition( attr1 as Condition<M> ); const op2: RawRamQuery<any> = this.parseCondition( comparison as Condition<M> ); switch (operator) { case GroupOperator.AND: return op1.where(m) && op2.where(m); case GroupOperator.OR: return op1.where(m) || op2.where(m); default: throw new InternalError( `Invalid operator for And/Or comparisons: ${operator}` ); } } }, } as RawRamQuery<any>; } } |