UNPKG

mvom

Version:

Multivalue Object Mapper

143 lines (142 loc) 6.99 kB
import type Connection from './Connection'; import type LogHandler from './LogHandler'; import type { DictionariesOption, DictionaryDefinition, DictionaryTypeDefinitionBoolean, DictionaryTypeDefinitionISOCalendarDate, DictionaryTypeDefinitionISOCalendarDateTime, DictionaryTypeDefinitionISOTime, DictionaryTypeDefinitionNumber, DictionaryTypeDefinitionString, FlattenDocument, SchemaDefinition, SchemaTypeDefinition } from './Schema'; import type Schema from './Schema'; import type { SchemaTypeDefinitionScalar } from './schemaType'; import type { DbDocument, DbSubroutineSetupOptions, ISOCalendarDate, ISOCalendarDateTime, ISOTime } from './types'; export interface QueryConstructorOptions<TSchema extends Schema | null> { /** Skip the first _n_ results */ skip?: number | null; /** Return only _n_ results */ limit?: number | null; /** Sort criteria */ sort?: SortCriteria<TSchema>; /** Return only the indicated properties */ projection?: readonly string[]; } export interface FilterOperators<TValue> { /** Equal */ $eq?: TValue; /** Greater than */ $gt?: NonNullable<TValue>; /** Greater than or equal to */ $gte?: NonNullable<TValue>; /** Less than */ $lt?: NonNullable<TValue>; /** Less than or equal to */ $lte?: NonNullable<TValue>; /** Not equal */ $ne?: TValue; /** String containing */ $contains?: TValue extends string ? string : never; /** String starts with */ $startsWith?: TValue extends string ? string : never; /** String ends with */ $endsWith?: TValue extends string ? string : never; /** In list */ $in?: readonly TValue[]; /** Not in list */ $nin?: readonly TValue[]; } export interface RootFilterOperators<TSchema extends Schema | null> { /** Used to combine conditions with an and */ $and?: readonly Filter<TSchema>[]; /** Used to combine conditions with an or */ $or?: readonly Filter<TSchema>[]; } export type Condition<TValue> = TValue | readonly TValue[] | FilterOperators<TValue>; /** Infer the type of a dictionary */ type InferDictionaryType<TDictionaryDefinition extends DictionaryDefinition> = TDictionaryDefinition extends string ? string : TDictionaryDefinition extends DictionaryTypeDefinitionString ? string : TDictionaryDefinition extends DictionaryTypeDefinitionNumber ? number : TDictionaryDefinition extends DictionaryTypeDefinitionBoolean ? boolean : TDictionaryDefinition extends DictionaryTypeDefinitionISOCalendarDate ? ISOCalendarDate : TDictionaryDefinition extends DictionaryTypeDefinitionISOTime ? ISOTime : TDictionaryDefinition extends DictionaryTypeDefinitionISOCalendarDateTime ? ISOCalendarDateTime : never; /** Infer the type of additional schema dictionaries */ type InferDictionariesType<TDictionariesOption extends DictionariesOption> = { [K in keyof TDictionariesOption]: InferDictionaryType<TDictionariesOption[K]> | null; }; /** Type which will produce a flattened document of only scalars with dictionaries */ type FlattenedDocumentDictionaries<TSchema extends Schema> = FlattenDocument<TSchema, Exclude<SchemaTypeDefinition, SchemaTypeDefinitionScalar> | { dictionary: string; }>; export type SchemaFilter<TSchema extends Schema | null> = (TSchema extends Schema<SchemaDefinition, infer TDictionariesOption> ? FlattenedDocumentDictionaries<TSchema> & InferDictionariesType<TDictionariesOption> extends infer O ? { [Key in keyof O]?: Condition<O[Key]>; } : never : Record<never, never>) & { _id?: Condition<string>; }; export type SchemaFilterKeys<TSchema extends Schema | null> = Extract<keyof SchemaFilter<TSchema>, string>; /** Query Filter */ export type Filter<TSchema extends Schema | null> = RootFilterOperators<TSchema> & SchemaFilter<TSchema>; /** Sort criteria */ export type SortCriteria<TSchema extends Schema | null> = readonly [ SchemaFilterKeys<TSchema>, -1 | 1 ][]; export type QueryExecutionOptions = DbSubroutineSetupOptions; export interface QueryExecutionResult { /** Number of documents returned */ count: number; /** Unformatted documents returned from database */ documents: DbDocument[]; } /** A query object */ declare class Query<TSchema extends Schema | null> { /** Connection instance to run query on */ private readonly connection; /** Schema used for query */ private readonly schema; /** File to run query against */ private readonly file; /** Log handler instance used for diagnostic logging */ private readonly logHandler; /** String to use as selection criteria in query */ private readonly selection; /** String to use as sort criteria in query */ private readonly sort; /** Sort criteria passed to constructor */ private readonly sortCriteria?; /** Limit the result set to this number of items */ private readonly limit?; /** Skip this number of items in the result set */ private readonly skip?; /** Specify the projection attribute in result set */ private readonly projection; /** Number of conditions in the query */ private conditionCount; constructor(connection: Connection, schema: TSchema, file: string, logHandler: LogHandler, selectionCriteria: Filter<TSchema>, options?: QueryConstructorOptions<TSchema>); /** Execute query */ exec(options?: QueryExecutionOptions): Promise<QueryExecutionResult>; /** * Format the selection criteria object into a string to use in multivalue query * @throws {@link TypeError} The value of the $or property must be an array * @throws {@link TypeError} Invalid conditional operator specified */ private formatSelectionCriteria; /** Format the sort criteria object into a string to use in multivalue query */ private formatSortCriteria; /** * Format a conditional expression which prohibits null values * @throws {@link InvalidParameterError} An invalid parameter was passed to the function */ private formatNonNullableCondition; /** Format a conditional expression */ private formatCondition; /** * Format a list of conditional expressions * @throws {@link InvalidParameterError} An invalid parameter was passed to the function */ private formatConditionList; /** * Format a constant for use in queries * @throws {@link Error} Passed constant parameter contains both single and double quotes */ private formatConstant; /** * Get a dictionary id at a given schema path * @throws {link InvalidParameterError} Nonexistent schema property or property does not have a dictionary specified */ private getDictionaryId; /** Transform query constant to internal u2 format (if applicable) */ private transformToQuery; /** Validate the query before execution */ private validateQuery; /** Validate that a "like" condition does not contain quotes and is not null */ private validateLikeCondition; } export default Query;