import * as Knex from 'knex';
import 'zone.js';
import { FieldInfo } from 'model-util-base';
interface ModelUtil<CU, MI> {
    tableFields: string[];
    modelFields: string[];
    createConditionUtil(): CU;
    select(...args: any[]): SelectStatement<CU, MI>;
    selectOne(...args: any[]): SelectStatement<CU, MI>;
    joinTables: JoinTable[];
    queryRaw(expression: string, ...args: any[]): Promise<any>;
    querySingleRaw(expression: string, ...args: any[]): Promise<any>;
    querySingleValueRaw(expression: string, ...args: any[]): Promise<any>;
    updateRaw(expression: string, ...args: any[]): Promise<any>;
}
declare abstract class ModelUtilImpl<CU, MI> implements ModelUtil<CU, MI> {
    abstract selectSQL: string;
    abstract tableFields: string[];
    abstract modelFields: string[];
    abstract createConditionUtil(): CU;
    abstract joinTables: JoinTable[];
    protected knex: Knex;
    constructor();
    select(...fields: any[]): SelectStatement<CU, MI>;
    selectOne(...fields: any[]): SelectStatement<CU, MI>;
    selectByParameters(parameters: SelectParameters): SelectStatement<CU, MI>;
    queryRaw(expression: string, ...args: any[]): Promise<any>;
    querySingleRaw(expression: string, ...args: any[]): Promise<any>;
    querySingleValueRaw(expression: string, ...args: any[]): Promise<any>;
    updateRaw(expression: string, ...args: any[]): Promise<any>;
}
interface ConditionSource {
    expression: string;
    args?: any[];
    isCount: boolean;
    limitN?: number;
    limitOffset?: number;
}
interface Statement<P> extends ConditionSource {
    type: string;
    asParameters(): P;
}
declare enum WhereType {
    None = 0,
    Where = 1,
    WhereAnd = 2,
    WrapWhere = 3
}
declare class SelectStatement<CU, MI> implements Statement<SelectParameters>, PromiseLike<any> {
    type: 'select';
    private knex?;
    expression: string;
    originalSQL: any;
    args?: any[];
    isCount: boolean;
    isWithCount: boolean;
    isSelectById: boolean;
    isSelectByIds: boolean;
    hasOrderBy: boolean;
    orderByExpression?: string;
    modelUtil: ModelUtil<CU, MI>;
    limitN?: number;
    limitOffset?: number;
    fields?: FieldUtil<CU>[];
    whereType: WhereType;
    onlyOne: boolean;
    private joinTables;
    private subTables;
    private manualJoinTables;
    private cancelJoinTables;
    private subTablesToFetch;
    private joinJobs;
    private finishedJoins;
    private subTableJobs;
    private finishedSubTables;
    constructor(sql: string, modelUtil: ModelUtil<CU, MI>, onlyOne: boolean, knex?: Knex, fields?: FieldUtil<CU>[]);
    then(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => any): any;
    doQuery(): Promise<any>;
    private executeCount;
    private executeQuery;
    private doResolve;
    private createSQL;
    private processSingleResult;
    private processArrayResult;
    private doJoinTables;
    private generateJoinFields;
    private generateJoinExpression;
    private generateKeyString;
    private fetchSubTables;
    initArgs(...initArgs: any[]): void;
    join(...joinTables: Function[]): SelectStatement<CU, MI>;
    notJoin(...joinTables: Function[]): SelectStatement<CU, MI>;
    withSubtables(...subTables: Function[]): SelectStatement<CU, MI>;
    where(builder: (cu: CU) => void): ConditionParenthesis<CU, SelectParameters>;
    where(builder: ConditionBuilder<any>): ConditionParenthesis<CU, SelectParameters>;
    where(builder: string, ...args: any[]): ConditionParenthesis<CU, SelectParameters>;
    whereAnd(builder: (cu: CU) => void): ConditionParenthesis<CU, SelectParameters>;
    whereAnd(builder: ConditionBuilder<any>): ConditionParenthesis<CU, SelectParameters>;
    whereAnd(builder: string, ...args: any[]): ConditionParenthesis<CU, SelectParameters>;
    wrapWhere(builder: (cu: CU) => void): ConditionParenthesis<CU, SelectParameters>;
    wrapWhere(builder: ConditionBuilder<any>): ConditionParenthesis<CU, SelectParameters>;
    wrapWhere(builder: string, ...args: any[]): ConditionParenthesis<CU, SelectParameters>;
    count(): SelectStatement<CU, MI>;
    limit(...args: any[]): SelectStatement<CU, MI>;
    limitAndCount(...args: any[]): SelectStatement<CU, MI>;
    orderBy(expression: string): SelectStatement<CU, MI>;
    asParameters(): SelectParameters;
}
declare class ConditionParenthesis<CU, P> {
    source: ConditionSource;
    args: any[];
    conditionBuilder: ConditionBuilder<CU>;
    conditionUtil: ConditionUtilImpl<CU>;
    constructor(source: ConditionSource, start: string, end: string, conditionBuilder: ConditionBuilder<CU>);
    then<TR = any, N = never>(onfulfilled?: (value: any) => TR | PromiseLike<TR>, onrejected?: (reason: any) => N | PromiseLike<N>): Promise<TR | N>;
    catch<N = never>(onrejected?: (reason: any) => N | PromiseLike<N>): Promise<N>;
    and(builder: (cu: CU) => void): ConditionParenthesis<CU, P>;
    and(builder: ConditionBuilder<CU>): ConditionParenthesis<CU, P>;
    or(builder: (cu: CU) => void): ConditionParenthesis<CU, P>;
    or(builder: ConditionBuilder<CU>): ConditionParenthesis<CU, P>;
    andNot(builder: (cu: CU) => void): ConditionParenthesis<CU, P>;
    andNot(builder: ConditionBuilder<CU>): ConditionParenthesis<CU, P>;
    orNot(builder: (cu: CU) => void): ConditionParenthesis<CU, P>;
    orNot(builder: ConditionBuilder<CU>): ConditionParenthesis<CU, P>;
    andExists(sql: string, ...args: any[]): ConditionParenthesis<CU, P>;
    andNotExists(sql: string, ...args: any[]): ConditionParenthesis<CU, P>;
    orExists(sql: string, ...args: any[]): ConditionParenthesis<CU, P>;
    orNotExists(sql: string, ...args: any[]): ConditionParenthesis<CU, P>;
    private appendConditionParenthesis;
    count(): Promise<any>;
    limit(limit: number, limitOffset?: number): Promise<any>;
    asParameters(): P;
}
interface ConditionBuilder<CU> {
    append(segment: string, ...args: any[]): ConditionBuilder<CU>;
    and(): CU;
    or(): CU;
}
declare class ConditionBuilderImpl<CU> implements ConditionSource, ConditionBuilder<CU>, Promise<any> {
    expression: string;
    args: any[];
    conditionUtil: CU;
    isCount: boolean;
    limitN?: number;
    limitOffset?: number;
    private promise;
    constructor(conditionUtil: CU);
    [Symbol.toStringTag]: string;
    then<TR = any, N = never>(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => any): Promise<any>;
    catch<N = never>(onrejected?: (reason: any) => N | PromiseLike<N>): Promise<N>;
    finally(onfinally?: () => void): Promise<any>;
    doThen(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => any): Promise<void>;
    append(segment: string, ...args: any[]): ConditionBuilder<CU>;
    and(): CU;
    or(): CU;
}
declare abstract class ConditionUtilImpl<CU> implements ConditionUtil<CU> {
    conditionBuilder: ConditionBuilderImpl<any>;
    constructor();
    newPar(builder: (cu: CU) => void): ConditionParenthesis<CU, any>;
    newPar(builder: ConditionBuilder<any>): ConditionParenthesis<CU, any>;
    notPar(builder: (cu: CU) => void): ConditionParenthesis<CU, any>;
    notPar(builder: ConditionBuilder<any>): ConditionParenthesis<CU, any>;
    exists(sql: string, ...args: any[]): void;
    notExists(sql: string, ...args: any[]): void;
    private appendConditionParenthesis;
    and(): CU;
    or(): CU;
    raw(expression: string, ...args: any[]): CU;
    abstract newInstance(): CU;
}
interface ConditionUtil<CU> {
    newPar(builder: (cu: CU) => void): ConditionParenthesis<CU, any>;
    newPar(builder: ConditionBuilder<any>): ConditionParenthesis<CU, any>;
    notPar(builder: (cu: CU) => void): ConditionParenthesis<CU, any>;
    notPar(builder: ConditionBuilder<any>): ConditionParenthesis<CU, any>;
    exists(sql: string, ...args: any[]): any;
    notExists(sql: string, ...args: any[]): any;
    and(): CU;
    or(): CU;
    raw(expression: string, ...args: any[]): any;
}
declare class FieldUtil<CU> extends FieldInfo {
    tableField: string;
    private conditionUtil;
    private conditionBuilder;
    constructor(tableField: string, modelField: string, title: string, conditionUtil: CU);
    toString(): string;
    equals(value: any): ConditionBuilder<CU>;
    notEquals(value: any): ConditionBuilder<CU>;
    moreThan(value: any): ConditionBuilder<CU>;
    moreThanOrEquals(value: any): ConditionBuilder<CU>;
    lessThan(value: any): ConditionBuilder<CU>;
    lessThanOrEqual(value: any): ConditionBuilder<CU>;
    in(...values: any): ConditionBuilder<CU>;
    notIn(...values: any): ConditionBuilder<CU>;
    isNull(): ConditionBuilder<CU>;
    notNull(): ConditionBuilder<CU>;
    between(from: any, to: any): ConditionBuilder<CU>;
    notBetween(from: any, to: any): ConditionBuilder<CU>;
    like(expression: string, value?: any): ConditionBuilder<CU>;
}
interface TableUtil<CU, MI> extends ModelUtil<CU, MI> {
    tableName: string;
    tableFields: string[];
    modelIdFields: string[];
    tableIdFields: string[];
    idType: IdType;
    insert(data: MI): InsertStatement<CU, MI>;
    insert(data: MI[]): InsertStatement<CU, MI>;
    insert(data: any): InsertStatement<CU, MI>;
    update(data?: any): UpdateStatement<CU, MI>;
    updateByParameters(parameters: UpdateParameters<MI>): UpdateStatement<CU, MI>;
    delete(data?: any): DeleteStatement<CU, MI>;
    deleteByParameters(parameters: DeleteParameters<MI>): DeleteStatement<CU, MI>;
    updateByState(data: any[]): UpdateByStateStatement;
}
declare abstract class TableUtilImpl<CU, MI> extends ModelUtilImpl<CU, MI> implements TableUtil<CU, MI> {
    abstract tableName: string;
    abstract tableFields: string[];
    abstract modelIdFields: string[];
    abstract tableIdFields: string[];
    abstract idType: IdType;
    selectSQL: any;
    joinTables: JoinTable[];
    subTables: SubTable[];
    private createSelectByIdQuery;
    selectByIds(...args: any[]): Promise<any>;
    insert(data: MI): InsertStatement<CU, MI>;
    insert(data: MI[]): InsertStatement<CU, MI>;
    insertSelective(data: MI): InsertStatement<CU, MI>;
    insertSelective(data: MI[]): InsertStatement<CU, MI>;
    insertOrUpdate(data: MI): InsertStatement<CU, MI>;
    insertOrUpdate(data: MI[]): InsertStatement<CU, MI>;
    update(data?: any): UpdateStatement<CU, MI>;
    updateSelective(data?: any): UpdateStatement<CU, MI>;
    updateByParameters(parameters: UpdateParameters<MI>): UpdateStatement<CU, MI>;
    delete(data?: any): DeleteStatement<CU, MI>;
    deleteByParameters(parameters: DeleteParameters<MI>): DeleteStatement<CU, MI>;
    getRows(data: any[], tableUtilClass: Function): any[];
    private getSubtableRows;
    getAllSubtables(): SubTable[];
    updateByState(data: any[]): UpdateByStateStatement;
}
declare enum IdType {
    UUID = 1,
    AutoIncrement = 2,
    CUSTOM = 3
}
declare class InsertStatement<CU, MI> implements PromiseLike<any> {
    private knex;
    private data;
    private tableUtil;
    private isWithSubtables;
    private isInsertOrUpdate;
    private subtablesMap;
    private isSelective;
    constructor(tableUtil: TableUtil<CU, MI>, data: any, knex: Knex, isInsertOrUpdate: boolean, selective?: boolean);
    withSubtables(...subtables: Function[]): InsertStatement<CU, MI>;
    then(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => any): Promise<any>;
    generateFiels(record?: any): string;
    generateBatchInsertSQL(records: MI[], args: any[]): string;
    generateSelectiveInsertSQL(record: MI, args: any[]): string;
    generateOnDuplicate(): string;
    private insertSubtables;
    private generateId;
    private setSubtablesFK;
    private generateArgs;
}
declare class UpdateStatement<CU, MI> implements Statement<UpdateParameters<MI>>, PromiseLike<any> {
    type: 'update';
    private knex?;
    data?: any;
    private tableUtil;
    expression: string;
    args: any[];
    isCount: boolean;
    limitN?: number;
    limitOffset?: number;
    isSelective: boolean;
    setFields: string[];
    updateType: UpdateType;
    sets: UpdateSet[];
    constructor(tableUtil: TableUtil<CU, MI>, data?: any, knex?: Knex, selective?: boolean);
    originalSQL: string;
    whereType?: WhereType;
    then(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => any): PromiseLike<any>;
    updateByData(): Promise<any>;
    private generateSetFields;
    private updateSingle;
    updateByWhere(): Promise<any>;
    protected createExpression(): void;
    set(field: any, value?: any): UpdateStatement<CU, MI>;
    where(builder: (cu: CU) => void): ConditionParenthesis<CU, UpdateParameters<MI>>;
    where(builder: ConditionBuilder<any>): ConditionParenthesis<CU, UpdateParameters<MI>>;
    where(builder: string, ...args: any[]): ConditionParenthesis<CU, UpdateParameters<MI>>;
    asParameters(): UpdateParameters<MI>;
}
declare class DeleteStatement<CU, MI> implements Statement<DeleteParameters<MI>>, PromiseLike<any> {
    type: "delete";
    private knex;
    data?: any;
    private tableUtil;
    expression: string;
    args: any[];
    isCount: boolean;
    limitN?: number;
    limitOffset?: number;
    private setFields;
    deleteType?: DeleteType;
    private isWithSubtables;
    private subtablesMap;
    constructor(knex: Knex, tableUtil: TableUtil<CU, MI>, data?: any);
    withSubtables(...subtables: Function[]): DeleteStatement<CU, MI>;
    then(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => any): PromiseLike<any>;
    deleteByData(): Promise<any>;
    private deleteRows;
    deleteByWhere(): Promise<any>;
    protected createExpression(): void;
    where(builder: (cu: CU) => void): ConditionParenthesis<CU, DeleteParameters<MI>>;
    where(builder: ConditionBuilder<any>): ConditionParenthesis<CU, DeleteParameters<MI>>;
    where(builder: string, ...args: any[]): ConditionParenthesis<CU, DeleteParameters<MI>>;
    asParameters(): DeleteParameters<MI>;
}
declare class UpdateByStateStatement implements PromiseLike<any> {
    private knex?;
    data: any[];
    private tableUtil;
    private isWithSubtables;
    private subtablesMap;
    private withSubtablesParams;
    constructor(knex: Knex, tableUtil: TableUtilImpl<any, any>, data: any[]);
    withSubtables(...subtables: Function[]): UpdateByStateStatement;
    then(onfulfilled?: (value: any) => any, onrejected?: (reason: any) => any): PromiseLike<any>;
    doUpdate(): Promise<any>;
    private getRowsByState;
}
declare function Transactional(target: Object, propertyName: string, descriptor: TypedPropertyDescriptor<(...args: any[]) => any>): void;
declare enum ParametersType {
    Select = 1,
    Insert = 2,
    Update = 3,
    Delete = 4
}
interface Parameters {
    type: ParametersType;
}
declare abstract class SelectParameters implements Parameters {
    type: ParametersType.Select;
    abstract fields?: FieldUtil<any>[];
    abstract where?: string;
    abstract whereType?: WhereType;
    abstract args?: any[];
    abstract isCount: boolean;
    abstract limit: {
        max: number;
        offset?: number;
    };
}
declare abstract class InsertParameters<Model> implements Parameters {
    type: ParametersType.Insert;
    data: Model[];
}
declare enum UpdateType {
    ByData = 1,
    ByWhere = 2
}
declare abstract class UpdateParameters<Model> implements Parameters {
    type: ParametersType.Update;
    updateType: UpdateType;
    data?: Model[];
    sets?: UpdateSet[];
    where?: string;
    args?: any[];
}
interface UpdateSet {
    field: string;
    value: any;
}
declare enum DeleteType {
    ByData = 1,
    ByWhere = 2
}
declare abstract class DeleteParameters<Model> implements Parameters {
    type: ParametersType.Delete;
    deleteType?: DeleteType;
    data?: Model[];
    where?: string;
    args?: any[];
}
declare abstract class BasicModelService<Model> {
    private modelUtil;
    private tableUtil;
    constructor(modelUtil: ModelUtil<any, Model>);
    service(parameters: Parameters): Promise<any>;
    select(parameters: SelectParameters): Promise<any>;
    insert(parameters: InsertParameters<Model>): Promise<any>;
    update(parameters: UpdateParameters<Model>): Promise<any>;
    delete(parameters: DeleteParameters<Model>): Promise<any>;
}
interface GeneratedField {
    fieldUtil: FieldInfo;
    alias: string;
}
interface JoinTable {
    joinByDefault: boolean;
    foreignKeyFields: FieldUtil<any>[];
    joinIdFields: FieldUtil<any>[];
    getTableUtil(): TableUtil<any, any>;
    fields: GeneratedField[];
}
interface SubTable {
    name: string;
    parentIdFields: FieldUtil<any>[];
    foreignKeyFields: FieldUtil<any>[];
    getTableUtil(): TableUtil<any, any>;
}
export { ModelUtil, ModelUtilImpl, SelectStatement, ConditionParenthesis, ConditionBuilder, ConditionBuilderImpl, ConditionUtil, ConditionUtilImpl, FieldUtil, TableUtil, TableUtilImpl, Transactional, BasicModelService, Parameters, IdType, JoinTable, SubTable };
