UNPKG

20.2 kBTypeScriptView Raw
1/// <reference path="../../../adonis-typings/index.d.ts" />
2import { Hooks } from '@poppinss/hooks';
3import { IocContract } from '@ioc:Adonis/Core/Application';
4import { QueryClientContract, TransactionClientContract } from '@ioc:Adonis/Lucid/Database';
5import { LucidRow, CacheNode, LucidModel, CherryPick, EventsList, ModelObject, HooksHandler, ModelOptions, ColumnOptions, ComputedOptions, AdapterContract, CherryPickFields, ModelColumnOptions, ModelKeysContract, ModelAssignOptions, ModelAdapterOptions, ModelRelationOptions, ModelRelations, RelationOptions, RelationshipsContract, ThroughRelationOptions, ManyToManyRelationOptions } from '@ioc:Adonis/Lucid/Orm';
6import { SnakeCaseNamingStrategy } from '../NamingStrategies/SnakeCase';
7import { LazyLoadAggregates } from '../Relations/AggregatesLoader/LazyLoad';
8/**
9 * Abstract class to define fully fledged data models
10 */
11export declare class BaseModel implements LucidRow {
12 /**
13 * The adapter to be used for persisting and fetching data.
14 *
15 * NOTE: Adapter is a singleton and share among all the models, unless
16 * a user wants to swap the adapter for a given model
17 */
18 static $adapter: AdapterContract;
19 /**
20 * Naming strategy for model properties
21 */
22 static namingStrategy: SnakeCaseNamingStrategy;
23 /**
24 * The container required to resolve hooks
25 *
26 * NOTE: Container is a singleton and share among all the models, unless
27 * a user wants to swap the container for a given model
28 */
29 static $container: IocContract;
30 /**
31 * Primary key is required to build relationships across models
32 */
33 static primaryKey: string;
34 /**
35 * Whether or not the model has been booted. Booting the model initializes it's
36 * static properties. Base models must not be initialized.
37 */
38 static booted: boolean;
39 /**
40 * Query scopes defined on the model
41 */
42 static $queryScopes: any;
43 /**
44 * A set of properties marked as computed. Computed properties are included in
45 * the `toJSON` result, else they behave the same way as any other instance
46 * property.
47 */
48 static $computedDefinitions: Map<string, ComputedOptions>;
49 /**
50 * Columns makes it easier to define extra props on the model
51 * and distinguish them with the attributes to be sent
52 * over to the adapter
53 */
54 static $columnsDefinitions: Map<string, ModelColumnOptions>;
55 /**
56 * Registered relationships for the given model
57 */
58 static $relationsDefinitions: Map<string, RelationshipsContract>;
59 /**
60 * The name of database table. It is auto generated from the model name, unless
61 * specified
62 */
63 static table: string;
64 /**
65 * Self assign the primary instead of relying on the database to
66 * return it back
67 */
68 static selfAssignPrimaryKey: boolean;
69 /**
70 * A custom connection to use for queries. The connection defined on
71 * query builder is preferred over the model connection
72 */
73 static connection?: string;
74 /**
75 * Storing model hooks
76 */
77 static $hooks: Hooks;
78 /**
79 * Keys mappings to make the lookups easy
80 */
81 static $keys: {
82 attributesToColumns: ModelKeysContract;
83 attributesToSerialized: ModelKeysContract;
84 columnsToAttributes: ModelKeysContract;
85 columnsToSerialized: ModelKeysContract;
86 serializedToColumns: ModelKeysContract;
87 serializedToAttributes: ModelKeysContract;
88 };
89 /**
90 * Creates a new model instance with payload and adapter options
91 */
92 private static newUpWithOptions;
93 /**
94 * Helper method for `fetchOrNewUpMany`, `fetchOrCreateMany` and `createOrUpdate`
95 * many.
96 */
97 private static newUpIfMissing;
98 /**
99 * Returns the model query instance for the given model
100 */
101 static query(options?: ModelAdapterOptions): any;
102 /**
103 * Create a model instance from the adapter result. The result value must
104 * be a valid object, otherwise `null` is returned.
105 */
106 static $createFromAdapterResult(adapterResult: ModelObject, sideloadAttributes?: ModelObject, options?: ModelAdapterOptions): any | null;
107 /**
108 * Creates an array of models from the adapter results. The `adapterResults`
109 * must be an array with valid Javascript objects.
110 *
111 * 1. If top level value is not an array, then an empty array is returned.
112 * 2. If row is not an object, then it will be ignored.
113 */
114 static $createMultipleFromAdapterResult<T extends LucidModel>(this: T, adapterResults: ModelObject[], sideloadAttributes?: ModelObject, options?: ModelAdapterOptions): InstanceType<T>[];
115 /**
116 * Define a new column on the model. This is required, so that
117 * we differentiate between plain properties vs model attributes.
118 */
119 static $addColumn(name: string, options: Partial<ColumnOptions>): ModelColumnOptions;
120 /**
121 * Returns a boolean telling if column exists on the model
122 */
123 static $hasColumn(name: string): boolean;
124 /**
125 * Returns the column for a given name
126 */
127 static $getColumn(name: string): ModelColumnOptions | undefined;
128 /**
129 * Adds a computed node
130 */
131 static $addComputed(name: string, options: Partial<ComputedOptions>): ComputedOptions;
132 /**
133 * Find if some property is marked as computed
134 */
135 static $hasComputed(name: string): boolean;
136 /**
137 * Get computed node
138 */
139 static $getComputed(name: string): ComputedOptions | undefined;
140 /**
141 * Register has one relationship
142 */
143 protected static $addHasOne(name: string, relatedModel: () => LucidModel, options: RelationOptions<ModelRelations>): void;
144 /**
145 * Register has many relationship
146 */
147 protected static $addHasMany(name: string, relatedModel: () => LucidModel, options: RelationOptions<ModelRelations>): void;
148 /**
149 * Register belongs to relationship
150 */
151 protected static $addBelongsTo(name: string, relatedModel: () => LucidModel, options: RelationOptions<ModelRelations>): void;
152 /**
153 * Register many to many relationship
154 */
155 protected static $addManyToMany(name: string, relatedModel: () => LucidModel, options: ManyToManyRelationOptions<ModelRelations>): void;
156 /**
157 * Register many to many relationship
158 */
159 protected static $addHasManyThrough(name: string, relatedModel: () => LucidModel, options: ThroughRelationOptions<ModelRelations>): void;
160 /**
161 * Adds a relationship
162 */
163 static $addRelation(name: string, type: ModelRelations['__opaque_type'], relatedModel: () => LucidModel, options: ModelRelationOptions): void;
164 /**
165 * Find if some property is marked as a relation or not
166 */
167 static $hasRelation(name: any): boolean;
168 /**
169 * Returns relationship node for a given relation
170 */
171 static $getRelation(name: any): any;
172 /**
173 * Define a static property on the model using the inherit or
174 * define strategy.
175 *
176 * Inherit strategy will clone the property from the parent model
177 * and will set it on the current model
178 */
179 static $defineProperty<Model extends LucidModel, Prop extends keyof Model>(this: Model, propertyName: Prop, defaultValue: Model[Prop], strategy: 'inherit' | 'define' | ((value: Model[Prop]) => Model[Prop])): void;
180 /**
181 * Boot the model
182 */
183 static boot(): void;
184 /**
185 * Register before hooks
186 */
187 static before(event: EventsList, handler: HooksHandler<any, EventsList>): typeof BaseModel;
188 /**
189 * Register after hooks
190 */
191 static after(event: EventsList, handler: HooksHandler<any, EventsList>): typeof BaseModel;
192 /**
193 * Returns a fresh persisted instance of model by applying
194 * attributes to the model instance
195 */
196 static create(values: any, options?: ModelAssignOptions): Promise<any>;
197 /**
198 * Same as [[BaseModel.create]], but persists multiple instances. The create
199 * many call will be wrapped inside a managed transaction for consistency.
200 * If required, you can also pass a transaction client and the method
201 * will use that instead of create a new one.
202 */
203 static createMany(values: any, options?: ModelAssignOptions): Promise<any[]>;
204 /**
205 * Find model instance using the primary key
206 */
207 static find(value: any, options?: ModelAdapterOptions): Promise<any>;
208 /**
209 * Find model instance using the primary key
210 */
211 static findOrFail(value: any, options?: ModelAdapterOptions): Promise<any>;
212 /**
213 * Find model instance using a key/value pair
214 */
215 static findBy(key: string, value: any, options?: ModelAdapterOptions): Promise<any>;
216 /**
217 * Find model instance using a key/value pair
218 */
219 static findByOrFail(key: string, value: any, options?: ModelAdapterOptions): Promise<any>;
220 /**
221 * Same as `query().first()`
222 */
223 static first(options?: ModelAdapterOptions): Promise<any>;
224 /**
225 * Same as `query().firstOrFail()`
226 */
227 static firstOrFail(options?: ModelAdapterOptions): Promise<any>;
228 /**
229 * Find model instance using a key/value pair
230 */
231 static findMany(value: any[], options?: ModelAdapterOptions): Promise<any>;
232 /**
233 * Find model instance using a key/value pair or create a
234 * new one without persisting it.
235 */
236 static firstOrNew(searchPayload: any, savePayload?: any, options?: ModelAssignOptions): Promise<any>;
237 /**
238 * Same as `firstOrNew`, but also persists the newly created model instance.
239 */
240 static firstOrCreate(searchPayload: any, savePayload?: any, options?: ModelAssignOptions): Promise<any>;
241 /**
242 * Updates or creates a new row inside the database
243 */
244 static updateOrCreate(searchPayload: any, updatedPayload: any, options?: ModelAssignOptions): Promise<any>;
245 /**
246 * Find existing rows or create an in-memory instances of the missing ones.
247 */
248 static fetchOrNewUpMany(uniqueKeys: any, payload: any, options?: ModelAssignOptions): Promise<any[]>;
249 /**
250 * Find existing rows or create missing one's. One database call per insert
251 * is invoked, so that each insert goes through the lifecycle of model
252 * hooks.
253 */
254 static fetchOrCreateMany(uniqueKeys: any, payload: any, options?: ModelAssignOptions): Promise<any[]>;
255 /**
256 * Update existing rows or create missing one's. One database call per insert
257 * is invoked, so that each insert and update goes through the lifecycle
258 * of model hooks.
259 */
260 static updateOrCreateMany(uniqueKeys: any, payload: any, options?: ModelAssignOptions): Promise<any>;
261 /**
262 * Returns all rows from the model table
263 */
264 static all(options?: ModelAdapterOptions): Promise<any>;
265 /**
266 * Truncate model table
267 */
268 static truncate(cascade?: boolean): any;
269 constructor();
270 /**
271 * Custom options defined on the model instance that are
272 * passed to the adapter
273 */
274 private modelOptions?;
275 /**
276 * Reference to transaction that will be used for performing queries on a given
277 * model instance.
278 */
279 private modelTrx?;
280 /**
281 * The transaction listener listens for the `commit` and `rollback` events and
282 * cleansup the `$trx` reference
283 */
284 private transactionListener;
285 /**
286 * When `fill` method is called, then we may have a situation where it
287 * removed the values which exists in `original` and hence the dirty
288 * diff has to do a negative diff as well
289 */
290 private fillInvoked;
291 /**
292 * A copy of cached getters
293 */
294 private cachedGetters;
295 /**
296 * Raises exception when mutations are performed on a delete model
297 */
298 private ensureIsntDeleted;
299 /**
300 * Invoked when performing the insert call. The method initiates
301 * all `datetime` columns, if there are not initiated already
302 * and `autoCreate` or `autoUpdate` flags are turned on.
303 */
304 protected initiateAutoCreateColumns(): void;
305 /**
306 * Invoked when performing the update call. The method initiates
307 * all `datetime` columns, if there have `autoUpdate` flag
308 * turned on.
309 */
310 protected initiateAutoUpdateColumns(): void;
311 /**
312 * Preparing the object to be sent to the adapter. We need
313 * to create the object with the property names to be
314 * used by the adapter.
315 */
316 protected prepareForAdapter(attributes: ModelObject): {};
317 /**
318 * Returns true when the field must be included
319 * inside the serialized object.
320 */
321 private shouldSerializeField;
322 /**
323 * A type only reference to the columns
324 */
325 $columns: any;
326 /**
327 * A copy of attributes that will be sent over to adapter
328 */
329 $attributes: ModelObject;
330 /**
331 * Original represents the properties that already has been
332 * persisted or loaded by the adapter.
333 */
334 $original: ModelObject;
335 /**
336 * Preloaded relationships on the model instance
337 */
338 $preloaded: {
339 [relation: string]: LucidRow | LucidRow[];
340 };
341 /**
342 * Extras are dynamic properties set on the model instance, which
343 * are not serialized and neither casted for adapter calls.
344 *
345 * This is helpful when adapter wants to load some extra data conditionally
346 * and that data must not be persisted back the adapter.
347 */
348 $extras: ModelObject;
349 /**
350 * Sideloaded are dynamic properties set on the model instance, which
351 * are not serialized and neither casted for adapter calls.
352 *
353 * This is helpful when you want to add dynamic meta data to the model
354 * and it's children as well.
355 *
356 * The difference between [[extras]] and [[sideloaded]] is:
357 *
358 * - Extras can be different for each model instance
359 * - Extras are not shared down the hierarchy (example relationships)
360 * - Sideloaded are shared across multiple model instances created via `$createMultipleFromAdapterResult`.
361 * - Sideloaded are passed to the relationships as well.
362 */
363 $sideloaded: ModelObject;
364 /**
365 * Persisted means the model has been persisted with the adapter. This will
366 * also be true, when model instance is created as a result of fetch
367 * call from the adapter.
368 */
369 $isPersisted: boolean;
370 /**
371 * Once deleted the model instance cannot make calls to the adapter
372 */
373 $isDeleted: boolean;
374 /**
375 * `$isLocal` tells if the model instance was created locally vs
376 * one generated as a result of fetch call from the adapter.
377 */
378 $isLocal: boolean;
379 /**
380 * Returns the value of primary key. The value must be
381 * set inside attributes object
382 */
383 get $primaryKeyValue(): any | undefined;
384 /**
385 * Opposite of [[this.isPersisted]]
386 */
387 get $isNew(): boolean;
388 /**
389 * Returns dirty properties of a model by doing a diff
390 * between original values and current attributes
391 */
392 get $dirty(): any;
393 /**
394 * Finding if model is dirty with changes or not
395 */
396 get $isDirty(): boolean;
397 /**
398 * Returns the transaction
399 */
400 get $trx(): TransactionClientContract | undefined;
401 /**
402 * Set the trx to be used by the model to executing queries
403 */
404 set $trx(trx: TransactionClientContract | undefined);
405 /**
406 * Get options
407 */
408 get $options(): ModelOptions | undefined;
409 /**
410 * Set options
411 */
412 set $options(options: ModelOptions | undefined);
413 /**
414 * Set options on the model instance along with transaction
415 */
416 $setOptionsAndTrx(options?: ModelAdapterOptions): void;
417 /**
418 * A chainable method to set transaction on the model
419 */
420 useTransaction(trx: TransactionClientContract): this;
421 /**
422 * A chainable method to set transaction on the model
423 */
424 useConnection(connection: string): this;
425 /**
426 * Set attribute
427 */
428 $setAttribute(key: string, value: any): void;
429 /**
430 * Get value of attribute
431 */
432 $getAttribute(key: string): any;
433 /**
434 * Returns the attribute value from the cache which was resolved by
435 * the mutated by a getter. This is done to avoid re-mutating
436 * the same attribute value over and over again.
437 */
438 $getAttributeFromCache(key: string, callback: CacheNode['getter']): any;
439 /**
440 * Returns the related model or default value when model is missing
441 */
442 $getRelated(key: any): any;
443 /**
444 * A boolean to know if relationship has been preloaded or not
445 */
446 $hasRelated(key: any): boolean;
447 /**
448 * Sets the related data on the model instance. The method internally handles
449 * `one to one` or `many` relations
450 */
451 $setRelated(key: any, models: LucidRow | LucidRow[]): void;
452 /**
453 * Push related adds to the existing related collection
454 */
455 $pushRelated(key: any, models: LucidRow | LucidRow[]): void;
456 /**
457 * Merges the object with the model attributes, assuming object keys
458 * are coming the database.
459 *
460 * 1. If key is unknown, it will be added to the `extras` object.
461 * 2. If key is defined as a relationship, it will be ignored and one must call `$setRelated`.
462 */
463 $consumeAdapterResult(adapterResult: ModelObject, sideloadedAttributes?: ModelObject): void;
464 /**
465 * Sync originals with the attributes. After this `isDirty` will
466 * return false
467 */
468 $hydrateOriginals(): void;
469 /**
470 * Set bulk attributes on the model instance. Setting relationships via
471 * fill isn't allowed, since we disallow setting relationships
472 * locally
473 */
474 fill(values: any, allowExtraProperties?: boolean): this;
475 /**
476 * Merge bulk attributes with existing attributes.
477 *
478 * 1. If key is unknown, it will be added to the `extras` object.
479 * 2. If key is defined as a relationship, it will be ignored and one must call `$setRelated`.
480 */
481 merge(values: any, allowExtraProperties?: boolean): this;
482 /**
483 * Preloads one or more relationships for the current model
484 */
485 load(relationName: any, callback?: any): Promise<void>;
486 /**
487 * @deprecated
488 */
489 preload(relationName: any, callback?: any): Promise<void>;
490 /**
491 * Lazy load the relationship aggregate value
492 */
493 loadAggregate(relationName: any, callback?: any): LazyLoadAggregates<this>;
494 /**
495 * Lazy load the relationship count value
496 */
497 loadCount(relationName: any, callback?: any): LazyLoadAggregates<this>;
498 /**
499 * Perform save on the model instance to commit mutations.
500 */
501 save(): Promise<this>;
502 /**
503 * Perform delete by issuing a delete request on the adapter
504 */
505 delete(): Promise<void>;
506 /**
507 * Serializes model attributes to a plain object
508 */
509 serializeAttributes(fields?: CherryPickFields, raw?: boolean): ModelObject;
510 /**
511 * Serializes model compute properties to an object.
512 */
513 serializeComputed(fields?: CherryPickFields): ModelObject;
514 /**
515 * Serializes relationships to a plain object. When `raw=true`, it will
516 * recurisvely serialize the relationships as well.
517 */
518 serializeRelations(cherryPick?: CherryPick['relations'], raw?: boolean): ModelObject | {
519 [key: string]: LucidRow | LucidRow[];
520 };
521 /**
522 * Converting model to it's JSON representation
523 */
524 serialize(cherryPick?: CherryPick): any;
525 /**
526 * Convert model to a plain Javascript object
527 */
528 toObject(): {
529 $extras: ModelObject;
530 };
531 /**
532 * Returns the serialize method output. However, any model can overwrite
533 * it to define it's custom serialize output
534 */
535 toJSON(): any;
536 /**
537 * Returns the query for `insert`, `update` or `delete` actions.
538 * Since the query builder for these actions are not exposed to
539 * the end user, this method gives a way to compose queries.
540 */
541 $getQueryFor(action: 'insert' | 'update' | 'delete' | 'refresh', client: QueryClientContract): any;
542 /**
543 * Returns an instance of relationship on the given model
544 */
545 related(relationName: any): any;
546 /**
547 * Reload/Refresh the model instance
548 */
549 refresh(): Promise<this>;
550}
551
\No newline at end of file