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 | 8x 8x 8x 8x 8x 39x 39x 43x 43x 43x 24x 19x 19x 19x 19x 199x 32x 32x 32x 32x 32x 32x 32x 32x 32x 12x 12x 32x 28x 28x 4x 4x 4x 4x 4x 116x 4x 4x | import { Sequence as Seq } from "./model/RamSequence"; import { InternalError, NotFoundError } from "@decaf-ts/db-decorators"; import { Sequence } from "../persistence"; import { SequenceOptions } from "../interfaces"; import { RamAdapter } from "./RamAdapter"; import { Repo, Repository } from "../repository"; export class RamSequence extends Sequence { protected repo: Repo<Seq>; constructor(options: SequenceOptions, adapter: RamAdapter) { super(options); this.repo = Repository.forModel(Seq, adapter.flavour); } async current(): Promise<string | number | bigint> { const { name, startWith } = this.options; try { const sequence: Seq = await this.repo.read(name as string); return this.parse(sequence.current as string | number); } catch (e: any) { if (e instanceof NotFoundError) { Iif (typeof startWith === "undefined") throw new InternalError( "Starting value is not defined for a non existing sequence" ); try { return this.parse(startWith); } catch (e: any) { throw new InternalError( `Failed to parse initial value for sequence ${startWith}: ${e}` ); } } throw new InternalError( `Failed to retrieve current value for sequence ${name}: ${e}` ); } } private parse(value: string | number | bigint): string | number | bigint { return Sequence.parseValue(this.options.type, value); } private async increment( current: string | number | bigint, count?: number ): Promise<string | number | bigint> { const { type, incrementBy, name } = this.options; let next: string | number | bigint; const toIncrementBy = count || incrementBy; Iif (toIncrementBy % incrementBy !== 0) throw new InternalError( `Value to increment does not consider the incrementBy setting: ${incrementBy}` ); switch (type) { case "Number": next = (this.parse(current) as number) + toIncrementBy; break; case "BigInt": next = (this.parse(current) as bigint) + BigInt(toIncrementBy); break; default: throw new InternalError("Should never happen"); } let seq: Seq; const repo = this.repo.override({ ignoredValidationProperties: ["updatedOn"], }); try { seq = await repo.update(new Seq({ id: name, current: next })); } catch (e: any) { Iif (!(e instanceof NotFoundError)) { throw e; } seq = await repo.create(new Seq({ id: name, current: next })); } return seq.current as string | number | bigint; } async next(): Promise<number | string | bigint> { const current = await this.current(); return this.increment(current); } async range(count: number): Promise<(number | string | bigint)[]> { const current = (await this.current()) as number; const incrementBy = this.parse(this.options.incrementBy) as number; const next: string | number | bigint = await this.increment( current, (this.parse(count) as number) * incrementBy ); const range: (number | string | bigint)[] = []; for (let i: number = 1; i <= count; i++) { range.push(current + incrementBy * (this.parse(i) as number)); } Iif (range[range.length - 1] !== next) throw new InternalError("Miscalculation of range"); return range; } } |