UNPKG

@palmares/databases

Version:

Add support for working with databases with palmares framework

468 lines 37.8 kB
import type { DatabaseAdapter } from '../engine'; import type { AutoField, BigAutoField, BigIntegerField, BooleanField, CharField, DateField, DecimalField, EnumField, Field, ForeignKeyField, IntegerField, TextField, UuidField } from '../models/fields'; import type { BaseModel, Model, ModelType } from '../models/model'; import type { ModelFields } from '../models/types'; export type ModelsFields<TModel> = TModel extends ModelType<{ fields: infer TFields; }, any> | { fields: infer TFields; } ? TFields : never; type ForeignKeyFieldNameByRelationOrRelatedName<in out TModel, in out TRelationOrRelatedName> = { [TKey in keyof ModelsFields<TModel> as ModelsFields<TModel>[TKey] extends ForeignKeyField<any, infer TDefinitions, any> ? TDefinitions['relatedName'] extends TRelationOrRelatedName ? TKey : TDefinitions['relationName'] extends TRelationOrRelatedName ? TKey : never : never]: any; }; export type ForeignKeyModelsRelationName<in out TModel, in out TIncludedModel> = { [TKey in keyof ModelsFields<TModel> as ModelsFields<TModel>[TKey] extends ForeignKeyField<any, infer TDefinitions, any> ? TDefinitions['relatedTo'] extends ((_: any) => infer TRelatedToModel) | (() => infer TRelatedToModel) | infer TRelatedToModel ? TIncludedModel extends abstract new (...args: any) => any ? InstanceType<TRelatedToModel extends abstract new (...args: any) => any ? TRelatedToModel : never> extends InstanceType<TIncludedModel> ? TDefinitions['relationName'] : never : InstanceType<TRelatedToModel extends abstract new (...args: any) => any ? TRelatedToModel : never> extends TIncludedModel ? TDefinitions['relationName'] : never : never : never]: { originalKey: TKey; returnType: ModelsFields<TModel>[TKey] extends ForeignKeyField<any, infer TDefinitions, any> ? TDefinitions['allowNull'] extends true ? 'optionalObject' : 'object' : 'object'; }; }; export type ForeignKeyModelsRelatedName<TModel, TIncludedModel> = { [TKey in keyof ModelsFields<TModel> as ModelsFields<TModel>[TKey] extends ForeignKeyField<any, infer TDefinitions, any> ? TDefinitions['relatedTo'] extends ((_: any) => infer TRelatedToModel) | (() => infer TRelatedToModel) | infer TRelatedToModel ? TIncludedModel extends abstract new (...args: any) => any ? InstanceType<TRelatedToModel extends abstract new (...args: any) => any ? TRelatedToModel : never> extends InstanceType<TIncludedModel> ? TDefinitions['relatedName'] : never : InstanceType<TRelatedToModel extends abstract new (...args: any) => any ? TRelatedToModel : never> extends TIncludedModel ? TDefinitions['relatedName'] : never : never : never]: { originalKey: TKey; returnType: ModelsFields<TModel>[TKey] extends ForeignKeyField<any, infer TDefinitions, any> ? TDefinitions['allowNull'] extends true ? TDefinitions['unique'] extends true ? 'optionalObject' : 'optionalArray' : TDefinitions['unique'] extends true ? 'object' : 'array' : 'array'; }; }; type _GetDataFromModel<in out TModel, TType extends 'create' | 'update' | 'read' = 'read', TIsSearch = false, TModelFields = ModelsFields<TModel>> = { [TKey in keyof TModelFields]: TModelFields[TKey] extends Field<infer TTypeOfField, any, infer TAllowedQueryOperations> | AutoField<infer TTypeOfField, any, infer TAllowedQueryOperations> | BigAutoField<infer TTypeOfField, any, infer TAllowedQueryOperations> | BooleanField<infer TTypeOfField, any, infer TAllowedQueryOperations> | TextField<infer TTypeOfField, any, infer TAllowedQueryOperations> | CharField<infer TTypeOfField, any, infer TAllowedQueryOperations> | UuidField<infer TTypeOfField, any, infer TAllowedQueryOperations> | IntegerField<infer TTypeOfField, any, infer TAllowedQueryOperations> | DecimalField<infer TTypeOfField, any, infer TAllowedQueryOperations> | DateField<infer TTypeOfField, any, infer TAllowedQueryOperations> | EnumField<infer TTypeOfField, any, infer TAllowedQueryOperations> | ForeignKeyField<infer TTypeOfField, any, infer TAllowedQueryOperations> | BigIntegerField<infer TTypeOfField, any, infer TAllowedQueryOperations> ? TType extends 'create' ? TTypeOfField['create'] : TType extends 'update' ? TTypeOfField['update'] : TIsSearch extends true ? TAllowedQueryOperations | TTypeOfField['read'] : TTypeOfField['read'] : never; }; export type GetDataFromModel<TModel, TType extends 'create' | 'update' | 'read' = 'read', TIsSearch = false, TDataFromModel = _GetDataFromModel<TModel, TType, TIsSearch>> = Omit<{ [TKey in keyof TDataFromModel as undefined extends TDataFromModel[TKey] ? TKey : never]?: TDataFromModel[TKey]; } & { [TKey in keyof TDataFromModel as undefined extends TDataFromModel[TKey] ? never : TKey]: TDataFromModel[TKey]; }, never>; type OrderingOfFields<TFields extends string> = readonly (TFields extends string ? TFields | `-${TFields}` : never)[]; type QuerySetQueryData = { fields?: () => { toIncludeAfterQuery: string[]; toLazyRemoveAfterQuery: string[]; }; orderBy?: () => string[]; limit?: () => number; offset?: () => number; data?: () => [Set<string>, Record<string, any>[]]; where?: () => Record<string, any | OrderingOfFields<any>>; joins?: () => Record<string, { model: any; querySet: QuerySet<any, any, any, any, any, any, any>; }>; }; type ReturnTypeOfBaseQuerySetMethods<TType extends 'get' | 'set' | 'remove', TModel, TResult = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'read'>, TUpdate = Partial<GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'update'>>, TCreate = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'create'>, TSearch = Partial<GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'read', true>>, TOrder = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel>, THasSearch extends boolean = false, THasData extends boolean = false, THasRemove extends boolean = false, TIsJoin extends boolean = false, TAlreadyDefinedRelations = never> = TType extends 'set' ? SetQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> : TType extends 'remove' ? RemoveQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> : TIsJoin extends true ? THasSearch extends true ? GetQuerySetIfSearchOnJoin<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> : GetQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> : GetQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations>; export declare class QuerySet<TType extends 'get' | 'set' | 'remove', TModel, _TResult = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'read'>, _TUpdate = Partial<GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'update'>>, _TCreate = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'create'>, _TSearch = Partial<GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'read', true>>, _TOrder = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel>, THasSearch extends boolean = false, _THasData extends boolean = false, _THasRemove extends boolean = false, TIsJoin extends boolean = false, _TAlreadyDefinedRelations = never> { protected __isJoin: TIsJoin; protected __hasSearch: THasSearch; protected __markToRemove: boolean; protected __markToCreateOrUpdate: boolean; protected __type: TType; protected __query: QuerySetQueryData; protected __cachedData: any; protected __model: TModel; constructor(model: TModel, type: TType); static new<TModel, TType extends 'set' | 'remove' | 'get' = 'get'>(model: TModel, type?: TType): TType extends 'remove' ? RemoveQuerySet<'remove', TModel> : TType extends 'set' ? SetQuerySet<'set', TModel> : GetQuerySet<'get', TModel>; protected _makeQuery(): any; /** * The problem: A user select the fields `name` and `address` to be included on the query. * * When we send the query to the engine, we will get just the fields `name` and `address`, as expected. * But if we have a relation, we might need to include the field that relates the data. Let's use the `id` field as * an example. * * So the actual query should include the fields * `name`, `address` and `id`. * * The problem is that the user don't want the `id` field to be included on the query, but we need it to relate the * data. * * What do we do? We lazy remove the field after we use it to relate the data. * * Notice: We just need this if the user is selecting the fields to be included on the query, if the user selected * the field we need to make the relation, that's unnecessary. * * @param queryset - The query set instance that we are going to append the field to be lazy removed on each record * of the retrieved data. * @param fieldName - The name of the field that we are going to lazy remove after the query. */ protected __duringQueryAppendFieldToBeLazyRemovedAfterQuery(queryset: QuerySet<any, any, any, any, any, any, any, any, any, any, any, any>, fieldName: string): void; protected __duringQueryFormatWhereClauseAndDoABasicValidation(model: typeof BaseModel & typeof Model & ModelType<any, any>, translatedModel: any, engine: DatabaseAdapter, search: any): Promise<any[]>; protected __duringQueryAppendInsertedOrUpdatedDataToQuery(queryset: QuerySet<any, any, any, any, any, any, any, any, any, any, any, any>, dataInsertedOnParent: any[], fieldNameOnRelationToFilter: string): void; /** * The model might not be properly because it's lazy loaded, so we need to check if * we have input and output parsers for all of the fields that we are trying to save or retrieve. * * We load the input and output parsers as we need to use on the fields. This gets appended on searches, * data insertion and data retrieval. It's lazy loaded, this means, we just get the parsers when we are * using the fields. If the search is searching for the 'id' field, we will cache JUST the 'id' field * input and output parsers. You understand? Its progressively adding more data, the more data you need. * * Because of that we need to check if all the data we are trying to save or retrieve has a parser cached. * If not we guarantee to retrieve and cache it. */ protected __duringQueryCompareObjectWithInputAndOutputParsersOnModelCache(engine: DatabaseAdapter, model: typeof BaseModel & typeof Model & ModelType<any, any>, keysYouAreTryingToSaveOrRetrieve: Set<string>, inputOrOutput: 'input' | 'output'): Set<string>; protected __duringQueryActuallyQueryTheDatabase(model: typeof BaseModel & typeof Model & ModelType<any, any>, engine: DatabaseAdapter, queryset: QuerySet<any, any, any, any, any, any, any, any, any, any, any, any>, args: { cachedData: any; relations?: { /** * When the join contains a queryset WITHOUT a where clause, we should query the parent * first and then query the Child. * * There are two maps: * ```newMap``` - This assigns each data to the value of `fieldNameToGetRelationData` from each record. * ```mapTo``` - On the related model, this assigns each data to the array or object value of * `relationOrRelatedName` */ mappingsFromJoinsWithoutWhereClause: { newMap?: Map<string, any[]>; mapTo?: Map<string, any[]>; }; /** * When the join contains a queryset WITH a where clause, we should query the child first and then query the * parent. */ relationsFromJoinsWithWhereClause: { newMap?: Map<string, Map<string, any>>; mapTo?: Map<string, Map<string, any>>; }; /** * The actual relationName or relatedName from the ForeignKeyField. */ relationOrRelatedName: string; /** * If isUnique is true we append an object, otherwise we append an array. For direct relation this should * always be true. */ isUnique: boolean; /** * The name of the field on the current model that relates the data. For example if we have a `User` model * that relates to the `Company` model, through the `companyId` field that exists on the `User` model. * * For a query like: * ``` * const company = await Company.default.get((qs) => qs.join(User, 'usersOfCompany', (qs) => qs.where({ * name: 'test' * })); * ``` * * Notice that we have a `where` clause on the join. This means we should query User first, and after * we should query Company. So the `fieldNameToGetRelationData` should be `companyId`. * * If we have a query like: * ``` * const company = await Company.default.get((qs) => qs.join(User, 'usersOfCompany')); * ``` * * We should query Company first, and after we should query User. So the `fieldNameToGetRelationData` should * be `id`. */ fieldNameToGetRelationData: string; /** * Kinda the same as `fieldNameToGetRelationData`, but the other way around. * * On the example gave on `fieldNameToGetRelationData`, the * `fieldNameThatMustBeIncludedInTheQueryToRelateTheData`would be `id` on the first example, and `companyId` * on the second example. */ fieldNameThatMustBeIncludedInTheQueryToRelateTheData: string; /** * This set is transformed to an array and appended to an `in` clause on the query. */ valuesToFilterOnRelatedModelAsSet?: Set<any>; }; }): Promise<any>; /** * To Query the database we need to do the hard work ourselves. * * Because the way palmares work, we can't rely on native relations of the database. At the same * time we need to minimize the number of hits we do the database. To do that we do the hardwork ourselves. * This hardwork involves doing a inner join-like query in memory. What we do is: * * - If there is a search on the join we need to fetch first the data from the join before we fetch the data from * the parent model. * - If there is no search on the join we query the parent model first and then we query the joins. * * This is recursive, so more joins you have, more queries will be made. In order to minimize the number of queries * we use the `in` clause on the query to filter the data. At the same time we need to minimize the number of loops * we do on the retrieved data. For that we rely on Maps, there are 2 types: * * - Mappings - Those are used when you query the parent first and then the child. * - Relations - Those are used when you query the child first and then the parent. */ protected __queryTheData(model: { new (...args: any[]): any; }, engine: DatabaseAdapter, args?: { relations: Parameters<QuerySet<any, any, any, any, any, any, any, any, any, any>['__duringQueryActuallyQueryTheDatabase']>[3]['relations']; }): Promise<any>; } export declare class CommonQuerySet<in out TType extends 'get' | 'set' | 'remove', in out TModel, in out TResult = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'read'>, in out TUpdate = Partial<GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'update'>>, in out TCreate = ModelFields<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel>, in out TSearch = Partial<GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'read', true>>, in out TOrder = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel>, in out THasSearch extends boolean = false, in out THasData extends boolean = false, in out THasRemove extends boolean = false, in out TIsJoin extends boolean = false, in out TAlreadyDefinedRelations = never> extends QuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> { /** * Join a model with another model, you can also pass a callback to make nested queries. * * @param model - The model you want to join with. * @param relationName - The name of the relation you want to join. Let's say the model * you are joining with is called `Profile` on the `User` model, and there are two foreignKeyFields on * the `User` model that points to the `Profile` model, one called `profileId` and the other called `profileId2`. * The relationName would be `profileId` or `profileId2`. * IMPORTANT: If the relationName is not inferred from typescript it's invalid and you cannot relate the data. * @param queryCallback - A callback to make nested queries or to filter through a nested relation */ join<TIncludedModel, TRelationName extends keyof TAllRelationNames, TAllRelationNames extends ForeignKeyModelsRelationName<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, TIncludedModel extends abstract new (...args: any) => any ? InstanceType<TIncludedModel> : TIncludedModel> & ForeignKeyModelsRelatedName<TIncludedModel extends abstract new (...args: any) => any ? InstanceType<TIncludedModel> : TIncludedModel, TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel> = ForeignKeyModelsRelationName<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, TIncludedModel extends abstract new (...args: any) => any ? InstanceType<TIncludedModel> : TIncludedModel> & ForeignKeyModelsRelatedName<TIncludedModel extends abstract new (...args: any) => any ? InstanceType<TIncludedModel> : TIncludedModel, TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel>, TNestedQuerySet extends (querySet: ReturnTypeOfBaseQuerySetMethods<TType, TIncludedModel, GetDataFromModel<TIncludedModel>, Omit<Partial<GetDataFromModel<TIncludedModel, 'update'>>, keyof ForeignKeyFieldNameByRelationOrRelatedName<TModel, TRelationName> | keyof ForeignKeyFieldNameByRelationOrRelatedName<TIncludedModel, TRelationName>>, Omit<GetDataFromModel<TIncludedModel, 'create'>, keyof ForeignKeyFieldNameByRelationOrRelatedName<TModel, TRelationName> | keyof ForeignKeyFieldNameByRelationOrRelatedName<TIncludedModel, TRelationName>>, Partial<GetDataFromModel<TIncludedModel, 'read', true>>, GetDataFromModel<TIncludedModel>, THasSearch, THasData, THasRemove, true, never>) => ReturnTypeOfBaseQuerySetMethods<TType, TIncludedModel, GetDataFromModel<TIncludedModel>, Omit<Partial<GetDataFromModel<TIncludedModel, 'update'>>, keyof ForeignKeyFieldNameByRelationOrRelatedName<TModel, TRelationName> | keyof ForeignKeyFieldNameByRelationOrRelatedName<TIncludedModel, TRelationName>>, Omit<GetDataFromModel<TIncludedModel, 'create'>, keyof ForeignKeyFieldNameByRelationOrRelatedName<TModel, TRelationName> | keyof ForeignKeyFieldNameByRelationOrRelatedName<TIncludedModel, TRelationName>>, Partial<GetDataFromModel<TIncludedModel, 'read', true>>, GetDataFromModel<TIncludedModel>, boolean, boolean, boolean, boolean, never> | QuerySet<TType, TIncludedModel, GetDataFromModel<TIncludedModel>, Omit<Partial<GetDataFromModel<TIncludedModel, 'update'>>, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Omit<GetDataFromModel<TIncludedModel, 'create'>, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Partial<GetDataFromModel<TIncludedModel, 'read', true>>, GetDataFromModel<TIncludedModel>, boolean, boolean, boolean, boolean, never> = (querySet: ReturnTypeOfBaseQuerySetMethods<TType, TIncludedModel, GetDataFromModel<TIncludedModel>, Omit<Partial<GetDataFromModel<TIncludedModel, 'update'>>, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Omit<GetDataFromModel<TIncludedModel, 'create'>, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Partial<GetDataFromModel<TIncludedModel, 'read', true>>, GetDataFromModel<TIncludedModel>, THasSearch, THasData, THasRemove, true, never>) => ReturnTypeOfBaseQuerySetMethods<TType, TIncludedModel, GetDataFromModel<TIncludedModel>, Omit<Partial<GetDataFromModel<TIncludedModel, 'update'>>, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Omit<GetDataFromModel<TIncludedModel, 'create'>, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Partial<GetDataFromModel<TIncludedModel, 'read', true>>, GetDataFromModel<TIncludedModel>, THasSearch, THasData, THasRemove, true, never> | QuerySet<TType, TIncludedModel, GetDataFromModel<TIncludedModel>, Omit<Partial<GetDataFromModel<TIncludedModel, 'update'>>, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Omit<GetDataFromModel<TIncludedModel, 'create'>, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Partial<GetDataFromModel<TIncludedModel, 'read', true>>, GetDataFromModel<TIncludedModel>, THasSearch, THasData, THasRemove, true, never>, TToJoin = TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never], TReturnFromNestedQuerySet = ReturnType<TNestedQuerySet> extends QuerySet<any, any, infer TResult, any, any, any, any, any, any, any, any, any> | CommonQuerySet<any, any, infer TResult, any, any, any, any, any, any, any, any, any> ? TResult : never, THasNestedSearchDataAndRemove extends { hasNestedSearch: boolean; hasNestedData: boolean; hasNestedRemove: boolean; } = ReturnType<TIncludedModel extends abstract new (...args: any[]) => any ? InstanceType<TIncludedModel> : never> extends CommonQuerySet<any, any, any, any, any, any, any, infer THasNestedSearch, infer THasNestedData, infer THasNestedRemove, any, any> | QuerySet<any, any, any, any, any, any, any, infer THasNestedSearch, infer THasNestedData, infer THasNestedRemove, any, any> ? { hasNestedSearch: THasNestedSearch; hasNestedData: THasNestedData; hasNestedRemove: THasNestedRemove; } : { hasNestedSearch: false; hasNestedData: false; hasNestedRemove: false; }>(model: TIncludedModel, relationName: TRelationName, queryCallback?: TNestedQuerySet): ReturnTypeOfBaseQuerySetMethods<TType, TModel, TResult & { [TKey in TRelationName]: TToJoin extends { returnType: infer TReturnType; } ? TReturnType extends 'optionalObject' ? TReturnFromNestedQuerySet | undefined : TToJoin['returnType'] extends 'array' | 'optionalArray' ? TReturnFromNestedQuerySet[] : TToJoin['returnType'] extends 'object' ? TReturnFromNestedQuerySet : TReturnFromNestedQuerySet[] : never; }, Omit<TUpdate, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, Omit<TCreate, TAllRelationNames[TRelationName extends keyof TAllRelationNames ? TRelationName : never] extends { originalKey: infer TOriginalKey extends string; } ? TOriginalKey : never>, TSearch, TOrder, THasNestedSearchDataAndRemove['hasNestedSearch'], THasNestedSearchDataAndRemove['hasNestedData'], THasNestedSearchDataAndRemove['hasNestedRemove'], TIsJoin, TAlreadyDefinedRelations | TRelationName>; /** * Used for filtering the data on the database. It will guarantee only a subset of the data is returned. * You can chain as many `.where()` methods as you want. This will append the new data to the previous `.where()` * clause. * * @example * ```ts * const users = await User.objects.get((qs) => qs.where({ age: 20 }).where({ name: 'John' })); * ``` * * This will return all users that have the age of '20' and the name of 'John'. * * You can also use some special operators like `in`, `greaterThan`, `lessThan`, * `greaterThanEqual`, etc depending on the data type of the field. * * @example * ```ts * const users = await User.objects.get((qs) => qs.where({ age: { greaterThan: 20 } })); * ``` * * When used in a join, it will do a InnerJoin-like query in memory. For example * * @example * ```ts * const users = await User.objects.get((qs) => * qs.join(Profile, 'profile', (qs) => qs.where({ type: 'admin' })) * ); * ``` * This will return all Users that have the Profile type of 'admin'. * * @param search - The search object to filter the data. * * @returns - A new QuerySet with the search appended. */ where(search: TSearch): ReturnTypeOfBaseQuerySetMethods<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, true, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations>; } export declare class GetQuerySetIfSearchOnJoin<TType extends 'get' | 'set' | 'remove', TModel, TResult = GetDataFromModel<TModel, 'read'>, TUpdate = Partial<GetDataFromModel<TModel, 'update'>>, TCreate = GetDataFromModel<TModel, 'create'>, TSearch = Partial<GetDataFromModel<TModel, 'read', true>>, TOrder = GetDataFromModel<TModel>, THasSearch extends boolean = false, THasData extends boolean = false, THasRemove extends boolean = false, TIsJoin extends boolean = false, TAlreadyDefinedRelations = never> extends CommonQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> { /** * Selects only the fields you want to retrieve from the database. This will probably improve the performance * of your query. This can be chained with other `select` clauses. * * @example * ```ts * const users = await User.objects.get((qs) => qs.select('id', 'name')); * * const users = await User.objects.get((qs) => qs.select('id').select('name')); * * // Both of the above examples are the same thing * ``` * * @param fields - The fields you want to retrieve from the database. * * @returns - A new QuerySet with the fields selected. */ select<const TFields extends (keyof GetDataFromModel<TModel>)[]>(...fields: TFields): ReturnTypeOfBaseQuerySetMethods<TType, TModel, Pick<TResult, TFields[number] | TAlreadyDefinedRelations extends keyof TResult ? TFields[number] | TAlreadyDefinedRelations : never>, TUpdate, TCreate, TSearch, Pick<TOrder, TFields[number] extends keyof TOrder ? TFields[number] : never>, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations>; /** * Allows you to order the data you are retrieving from the database. This can be chained * with other `orderBy` clauses. * * A clause with a `-` in front of the field name means it will order in descending order. * Otherwise it will order in ascending order. * * @example * ```ts * const users = await User.objects.get((qs) => qs.orderBy('-name', 'age')); * ``` * * @param ordering - The fields you want to order by. * * @returns - A new QuerySet with the ordering appended. */ orderBy(...ordering: OrderingOfFields<keyof TOrder extends string ? keyof TOrder : never>): GetQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations>; } export declare class GetQuerySet<TType extends 'get' | 'set' | 'remove', TModel, TResult = GetDataFromModel<TModel, 'read'>, TUpdate = Partial<GetDataFromModel<TModel, 'update'>>, TCreate = GetDataFromModel<TModel, 'create'>, TSearch = Partial<GetDataFromModel<TModel, 'read', true>>, TOrder = GetDataFromModel<TModel>, THasSearch extends boolean = false, THasData extends boolean = false, THasRemove extends boolean = false, TIsJoin extends boolean = false, TAlreadyDefinedRelations = never> extends GetQuerySetIfSearchOnJoin<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> { limit(limit: number): GetQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations>; offset(offset: number): GetQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations>; } export declare class SetQuerySet<TType extends 'get' | 'set' | 'remove', TModel, TResult = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'read'>, TUpdate = Partial<GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'update'>>, TCreate = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'create'>, TSearch = Partial<GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel, 'read', true>>, TOrder = GetDataFromModel<TModel extends abstract new (...args: any) => any ? InstanceType<TModel> : TModel>, THasSearch extends boolean = false, THasData extends boolean = false, THasRemove extends boolean = false, TIsJoin extends boolean = false, TAlreadyDefinedRelations = never> extends CommonQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> { /** * This method is used to set the data to be created or updated. As you've probably seen, we doesn't * offer you too many options, you have `.set`, `remove` and `get` on the Managers. This covers the * `.set` part. A `set` operation creates or updates the data on the database. * * Now you might be asking: How do we know how to differentiate? Easy, by the presence of a `.where()` * clause anywhere on your query (even nested ones). * * If you have a `.where()` clause, it will update the data. If you don't, it will create the data. * * Other differences between the two operations are: * ### Create * - You can set as many data as you want. * - You can set the same data multiple times, it will create multiple entries. * - Obligatory data is required. * * ### Update * - Just one data can be set. * - All fields are optional. * * Here is simple examples: * * @example * ```typescript * // CREATING A USER * const user = await User.objects.set((qs) => qs.data({ name: 'John Doe', email: 'johndoe@example.com' })); * * // CREATING MULTIPLE USERS * const user = await User.objects.set((qs) => qs.data( * { name: 'John Doe', email: 'johndoe@example.com' }, * { name: 'Victor Baptista', email: 'victor@example.com' } * )); * * // UPDATING A USER * const user = await User.objects.set((qs) => qs.where({ id: 1 }).data({ name: 'John Doe' })); * ``` * * Great, now comes the cool part: Relations! * Relations are for querying purposes, most of the time, but you can also set data through them. Palmares * takes care of the rest for you. Let's see an example: * * @example * ```typescript * * // CREATING A PROFILE TYPE WITH TWO ASSOCIATED USERS AND ASSIGNING BOTH USERS TO ONE COMPANY * const company = await Company.default.set((qs) => * qs * .join(User, 'usersOfCompany', (qs) => * qs * .join(ProfileType, 'profileType', (qs) => * qs.data({ * name: 'admin2' * }) * ) * .data({ * age: 10, * name: 'test1', * uuid: 'a417f723-ddb7-4f8c-a42c-0b5975e4cf5f', * userType: 'admin' * }, { * age: 11, * name: 'test2', * uuid: '77ac0c15-09c7-425e-9d77-97c0f973e8e6', * userType: 'user' * }) * ) * .data({ * address: 'test', * name: 'test5' * }) * ); * * // UPDATING A COMPANY, AND ONLY THE COMPANY BY QUERYING BY THE PROFILE TYPE * const company = await Company.default.set((qs) => * qs * .join(User, 'usersOfCompany', (qs) => * qs * .join(ProfileType, 'profileType', (qs) => * qs.where({ id: 5 }) * ) * ) * .data({ * name: 'hello' * }) * ); * ``` * * @param data - The data to be set on the database. * * @returns - Returns a new QuerySet. You cannot set any more chaining method after this one. */ data(...data: THasSearch extends true ? [TUpdate] : TCreate[]): QuerySet<'set', TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, TIsJoin, true, THasRemove, TAlreadyDefinedRelations>; } /** * Responsible for holding and managing the 'remove' query. This is not necessarily when removing an item from the * database using the `.remove()` operation on the manager. The `remove()` makes it explicit that you are removing an * item from the database and you can force the removal if you want by passing `true` as the first argument. * * By default it will prevent you from removing an item without a `.where()` clause. */ export declare class RemoveQuerySet<TType extends 'get' | 'set' | 'remove', TModel, TResult = GetDataFromModel<TModel, 'read'>, TUpdate = Partial<GetDataFromModel<TModel, 'update'>>, TCreate = GetDataFromModel<TModel, 'create'>, TSearch = Partial<GetDataFromModel<TModel, 'read', true>>, TOrder = GetDataFromModel<TModel>, THasSearch extends boolean = false, THasData extends boolean = false, THasRemove extends boolean = false, TIsJoin extends boolean = false, TAlreadyDefinedRelations = never> extends CommonQuerySet<TType, TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, THasRemove, TIsJoin, TAlreadyDefinedRelations> { /** * This methods sets the data to be removed from the database. You must always use * this, otherwise it will not remove the data. We know it's kinda redundant sometimes * but this makes it explicit that you are removing the data from the database. Sometimes * something being a little more verbose is actually a nice thing! * * A simple example: * * @example * ```typescript * const user = await User.objects.remove((qs) => qs.where({ id: 1 }).remove()); * ``` * * This will remove all users with the id of 1. Now let's go to a more complex example: * * @example * ```typescript * const companies = await Company.default.remove((qs) => * qs * .join(User, 'usersOfCompany', (qs) => * qs * .join(ProfileType, 'profileType', (qs) => * qs.where({ * id: 5 * }) * ) * .remove() * ) * .remove() * ); * ``` * * This will remove all companies that have a user with a profile type of 5. And all * the companies related with that user. * * "Will ProfileType be removed?" No, it will not. Because you haven't set .remove() on it's * queryset. So ProfileType is just there for querying purposes but will not be removed, * how cool is that? * * Usually you will want to use this method just on the root queryset, not on its children. * * @returns - Returns a new QuerySet. You cannot set any more chaining method after this one. */ remove(): QuerySet<'remove', TModel, TResult, TUpdate, TCreate, TSearch, TOrder, THasSearch, THasData, true, TIsJoin, TAlreadyDefinedRelations>; } export {}; //# sourceMappingURL=queryset.d.ts.map