import { ShadowValue } from './shadow-value.model';
import { IClause } from './interfaces/i-clause.interface';
import { DbTable } from './structure/db-table.model';
import { QueryResult } from '../interfaces/query-result.interface';
import { ClauseGroup } from './queries/clause-group.model';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/Observable/from';
/**
 * @public
 * @abstract
 * @class DbHelperModel
 *
 * @description
 * This abstract class is the base of models managed by the orm
 * it provides base method and fields to do the query magic
 *
 * @author  Olivier Margarit
 * @since   0.1
 */
export declare abstract class DbHelperModel {
    /**
     * @public
     * @property {string} TABLE_NAME property is setted by the table annotation
     *           this property will be readonly in future release
     */
    TABLE_NAME: string;
    /**
     * @public
     * @property {number} $$rowid is the standard sqlite rowid, this property is used
     *           to check if the model is already save and is setted on select
     *           queries.
     */
    $$rowid: number | null;
    /**
     * @public
     * @property {boolean} $$inserted is a library helper to manage update or insert operation
     */
    $$inserted: boolean;
    /**
     * @public
     * @property {Array<string>} $$partialWithProjection is a reference to prevent to nullify fields not
     *           not retrieve field on a select projection.
     */
    $$partialWithProjection: string[] | undefined;
    /**
     * @public
     * @property {{[index: string]: ShadowValue}} $$shadow shadow model that map real values corresponding with database values
     *
     * @since 0.2
     */
    $$shadow: {
        [index: string]: ShadowValue;
    };
    /**
     * @public
     * @property {DbTable} $$dbTable the table matching to the model
     */
    $$dbTable: DbTable | undefined;
    /**
     * @public
     * @property {boolean} $$isModified flag updated on model change, in future version this value sould be observable
     *
     * @since 0.2
     */
    $$isModified: boolean;
    /**
     * @public
     * @property {boolean} $$isDbHelperModel flag to reflexive check if the model is a DbHelperModel
     *
     * @since 0.2
     */
    readonly $$isDbHelperModel: boolean;
    /**
     * @public
     * @constructor Create a model instance. Call to super() is mandatory. If super() is not called, magic will fail.
     *
     * @since 0.2
     */
    constructor();
    update(): Observable<any>;
    insert(): Observable<any>;
    /**
     * @public
     * @method save the model method to save it in database
     *
     * @return {Observable<any>} observable to subscribe to save operation
     */
    save(): Observable<any>;
    /**
     * @public
     * @method restoreFromStorage restore or reset the model data from database
     *
     * @return {Observable} observable to subscribe
     *
     * @since 0.2
     */
    restoreFromStorage(): Observable<any>;
    /**
     * @public
     * @method hasValidRowid check if model has a valid rowid
     *
     * @return {boolean} true if $$rowid is usable
     *
     * @since 0.2
     */
    hasValidRowid(): boolean;
    /**
     * @public
     * @method toClauseGroup convert model to clause group
     *
     * @return {ClauseGroup} the result clause group
     */
    toClauseGroup(): ClauseGroup;
    /**
     * @public
     * @method getPrimaryClause get composite clause of primary key to query model
     *
     * @return {IClause} clause object that could be where clause to requery or update stored data
     */
    getPrimaryClause(): IClause;
    /**
     * @public
     * @method hasValidPrimaryKey check if model has usable primary keys
     *
     * @return {boolean} return true if primary can be used
     */
    hasValidPrimaryKey(): boolean;
    /**
     * @public
     * @method getColumnValue get a column value by using the column name
     *
     * @param {string} columnName the column name
     *
     * @return {any} the column value stored in database
     */
    getColumnValue(columnName: string): any;
    /**
     * @public
     * @method setColumnValue set the column value and bypass the field filter
     *
     * @param {string} columnName   the column to update
     * @param {any} value           the value to set
     *
     * @since 0.2
     */
    setColumnValue(columnName: string, value: any): void;
    /**
     * @public
     * @method getFieldValue get the field value by its name
     *
     * @param {string} fieldName the field name from which retrieve the value
     *
     * @return {any} the field value
     */
    getFieldValue(fieldName: string): any;
    /**
     * @public
     * @method setFieldValue set the field value by its name
     *
     * @param {string} fieldName    the field to update
     * @param {any} value           the value to set
     */
    setFieldValue(fieldName: string, value: any): void;
    getCommonFieldType(fieldName: string): string;
    /**
     * @public
     * @method delete delete the object from database
     *
     * @return {Observable<any>} observable to subscribe to delete operation
     */
    delete(): Observable<any>;
    /**
     * @public
     * @method getLinkedModelClauses get linked model clauses
     *
     * @param {{new(): T}} model    the linked model
     * @param {string} key          the optional relation key
     *
     * @return {CompositeClause} the target model clause to retrieve it
     *
     * @since 0.2
     */
    private getLinkedModelClauses<T>(model, key?);
    /**
     * @public
     * @method getLinked get linked model whatever is the relation type
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {{new(): T}} model        the generic model to retrieve
     * @param {string} key              the relation key
     *
     * @throws {QueryError} generic error thrown if relation is invalid or query fail
     *
     * @return {Observable<QueryResult<>>} Observable to subscribe and manage linked result
     *
     * @since 0.2
     */
    getLinked<T extends DbHelperModel>(model: {
        new (): T;
    }, key?: string): Observable<QueryResult<T>>;
    /**
     * @private
     * @method getOneToManyClause get one to many clause for specific model
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {{new(): T}} model        Themodel clause wanted
     * @param {DbRelation} relation     the model relation
     *
     * @return {CompositeClause} the clause to retrieve model
     *
     * @since 0.2
     */
    private getOneToManyClause<T>(model, relation);
    /**
     * @private
     * @method getManyToOneClause get many to one clause for specific model
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {{new(): T}} model        Themodel clause wanted
     * @param {DbRelation} relation     the model relation
     *
     * @return {CompositeClause} the clause to retrieve model
     *
     * @since 0.2
     */
    private getManyToOneClause<T>(model, relation);
    /**
     * @private
     * @method getOneToOneClause get one to one clause for specific model
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {{new(): T}} model        Themodel clause wanted
     * @param {DbRelation} relation     the model relation
     *
     * @return {CompositeClause} the clause to retrieve model
     *
     * @since 0.2
     */
    private getOneToOneClause<T>(model, relation);
    /**
     * @private
     * @method getManyToManyClause get many to many clause for specific model
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {{new(): T}} model        Themodel clause wanted
     * @param {DbRelation} relation     the model relation
     *
     * @return {CompositeClause} the clause to retrieve model
     *
     * @throws {NotImplementedError} this method is not implemented yet
     *
     * @since 0.2
     */
    private getManyToManyClause<T>(model);
    checkIfShouldUpdateFromDatabase<T extends DbHelperModel>(): Observable<boolean>;
    /**
     * @public
     * @method linkModel link other model to this instance
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {Array<T>} model          The models to link
     * @param {string} key              the relation key
     *
     * @throws {QueryError} generic error thrown if relation is invalid or query fail.
     *                      Throw error if model array is empty
     *
     * @return {Observable<QueryResult<T>>} the new linked models
     *
     * @since 0.2
     */
    linkModels<T extends DbHelperModel>(models: T[], key?: string): Observable<QueryResult<T>>;
    /**
     * @public
     * @method linkModelsManyToMany link many to many model to this instance
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {Array<T>} model          The models to link
     * @param {string} key              the model relation
     * @param {boolean} remove          flag to unlink model or link it
     *
     * @throws {NotImplementedError} This method is not implemented yet
     *
     * @return {Observable<QueryResult<T>>} the new linked models
     *
     * @since 0.2
     */
    private linkModelsManyToMany<T>(models, key?, remove?);
    /**
     * @public
     * @method linkModelsStraight link model in the staight relation to this instance
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {Array<T>} model          The models to link
     * @param {string} key              the model relation
     * @param {boolean} remove          flag to unlink model or link it
     *
     * @throws {QueryError} generic error thrown if relation is invalid or query fail.
     *                      Throw error if model array is empty
     *
     * @return {Observable<QueryResult<T>>} the new linked models
     *
     * @since 0.2
     */
    private linkModelsStraight<T>(models, key?, remove?);
    /**
    * @public
    * @method linkModelsReverse reverse link model relation to this instance
    *
    * @param T @extends DbHelperModel  generic model managed by this framework
    * @param {Array<T>} model          The models to link
    * @param {string} key              the model relation
    * @param {boolean} remove          flag to unlink model or link it
    *
    * @throws {QueryError} generic error thrown if relation is invalid or query fail.
    *                      Throw error if model array is empty
    *
    * @return {Observable<QueryResult<T>>} the new linked models
    *
    * @since 0.2
    */
    private linkModelsReverse<T>(models, key?, remove?);
    /**
     * @public
     * @method unlinkModels unlink model relation to this instance
     *
     * @param T @extends DbHelperModel  generic model managed by this framework
     * @param {Array<T>} model          The models to unlink
     * @param {string} key              the model relation
     * @param {boolean} remove          flag to unlink model or link it
     *
     * @throws {QueryError} generic error thrown if relation is invalid or query fail.
     *                      Throw error if model array is empty
     *
     * @return {Observable<QueryResult<T>>} the new linked models
     *
     * @since 0.2
     */
    private unlinkModels<T>(models, key?);
}
