import { DEFAULT_PRIMARY_ID , ModelInterface , ModelKeysInterface , RelationTypes , TransactionModes } from "./model.interface.js" ; import { DEFAULT_SYNC_COLUMN_NAME , TableSchema } from "../migration/migration.interface.js" ; import { Connector } from "../connection/connector.js" ; import { FindOrCreateActions } from "./find-or-create-actions.js" ; import { HasOne } from "../relations/has-one.js" ; import { HasMany } from "../relations/has-many.js" ; import { HasManyMulti } from "../relations/has-many-multi.js" ; import { HasManyThroughMulti } from "../relations/has-many-through-multi.js" ; import { Relations } from "../relations/relations.js" ; import { mergeDeep as mergeDeepUtil } from "../utils.js" ; export class Model extends FindOrCreateActions implements ModelInterface { protected transaction : IDBTransaction | null = null ; public constructor ( public db , public table , public connector ) { super ( db , table ) ; } param id param data param mergeDeep public async sync < T > ( id , data , mergeDeep ? ) ; public async sync ( id , data , mergeDeep = true ) { await this . save ( id , this . syncObj ( data ) , mergeDeep ) ; return this . find ( id ) ; } param indexName param id param data param mergeDeep public async syncIndex < T > ( indexName , id , data , mergeDeep ? ) ; public async syncIndex ( indexName , id , data , mergeDeep = true ) { await this . saveIndex ( indexName , id , this . syncObj ( data ) , mergeDeep ) ; return this . findIndex ( indexName , id ) ; } param indexName param id param data param mergeDeep public async syncAllIndex < T > ( indexName , id , data , mergeDeep ? ) ; public async syncAllIndex ( indexName , id , data , mergeDeep = true ) { await this . saveAllIndex ( indexName , id , this . syncObj ( data ) , mergeDeep ) ; return ( this . resetBuilder ( ) . whereIndex ( indexName , id ) as Model ) . all ( ) ; } param mode public openTransaction ( mode ) { const transaction = this . db . transaction ( this . connector . migrationSchema . tables . map ( table => table . name ) ) ; const models = { } ; for ( const table of this . connector . migrationSchema . tables ) { Object . defineProperty ( models , table . name , { get : ( ) => { let model ; if ( this . table . ormClass ) { model = new this . table . ormClass ( < IDBDatabase > this . db , table , this . connector ) ; } else { model = new Model ( < IDBDatabase > this . db , table , this . connector ) ; } model . setTransaction ( transaction ) ; return model ; } } ) ; } return { models , transaction } ; } param results protected loadRelations ( results ) { const relationsArray = [ ] ; for ( const relation of this . relations ) { let loader ; switch ( relation . type ) { case RelationTypes . HasOne : loader = new HasOne ( this . db , this . connector , this , relation ) ; relationsArray . push ( loader . fetch ( results ) ) ; break ; case RelationTypes . HasMany : loader = new HasMany ( this . db , this . connector , this , relation ) ; relationsArray . push ( loader . fetch ( results ) ) ; break ; case RelationTypes . HasManyMultiEntry : loader = new HasManyMulti ( this . db , this . connector , this , relation ) ; relationsArray . push ( loader . fetch ( results ) ) ; break ; case RelationTypes . HasManyThroughMultiEntry : loader = new HasManyThroughMulti ( this . db , this . connector , this , relation ) ; relationsArray . push ( loader . fetch ( results ) ) ; break ; default : throw new Error ( `Unknown relation ${ relation . type }` ) ; } } return relationsArray . concat ( this . loadCustomRelations ( results ) ) ; } /**
     * The primary key of the model
     */ public get primaryId ( ) : string { return this . table . primary || DEFAULT_PRIMARY_ID ; } param results protected loadCustomRelations ( results ) { const relationPromises = [ ] ; for ( const customRelation of this . customRelations ) { if ( ! Reflect . has ( this , customRelation ) ) { throw new Error ( `Method ${ customRelation } not defined.` ) ; } const relation = < Relations > ( Reflect . get ( this , customRelation ) ( ) ) ; relationPromises . push ( relation . fetch ( results ) ) ; } return relationPromises ; } param data private syncObj ( data ) { if ( this . table . syncColumn ) { const attr = this . table . syncColumnName || DEFAULT_SYNC_COLUMN_NAME ; const obj = { } ; obj [ attr ] = new Date ( ) ; return mergeDeepUtil ( data , obj ) ; } return data ; } }