import * as TopSinError from "topsin.error";
declare namespace TopSinDatabase {
    export var DbType: { pg: 'pg', mysql:'mysql', mssql:'mssql',oracle:'oracle',sqlite:'sqlite'};
    export type DbType = "pg" | "mysql" | "mssql" | "oracle" | "sqlite";
    export type DbEncrypt = "" | "EB642";
    export type FieldFormat = '' | 'string' | 'json' | 'array' | 'yyyy-MM' |'yyyy-MM-dd' | 'yyyy-MM-dd hh:mm' | 'yyyy-MM-dd hh:mm:ss';
    export type UpdatePolicy = '' | 'json_merge' | 'array_append';
    export interface SqlConnectionParam {
        database_host:string,
        database_name:string,
        database_type:DbType,
        database_user:string,
        database_pwd:string,
        database_encrypt?:DbEncrypt,
        database_options?:string,
        auto_close_timeout?:number,
    }

    export interface SqlSelectorMap {
        table:string,
        field?:string | Array<string>,
        where?:string | Array<any> | Map<string,any>,
        group?:string | Array<string>,
        order?:string | Array<string>,
        offset?:number,
        limit?:number,
        unique_field?:string,
        value_field?:string,
        field_format?:Map<string,FieldFormat>,
    }

    export interface SqlInserterMap {
        table:string,
        field?:string | Array<string>,
        data:Map<string,any>,
        unique_field?:string | Array<string>,
        return_field?:string,
        update_policy?:Map<string, UpdatePolicy>
    }

    export interface SqlUpdaterMap {
        table:string,
        data:Map<string, any>,
        field?:string | Array<string>,
        where?:string | Array<string> | Map<string,any>,
        update_policy?:Map<string, UpdatePolicy>
    }

    export interface SqlDeleterMap {
        table:string,
        where?:string | Array<any> | Map<string,any>,
    }


    export interface SelectArrayDataResult {
        field:Array<string>,
        data: Array<Array<any>>
    }

    export class SqlQuery {
        /**
         * 查询一行数据,返回为一个Array<any>数组;
         * 
         * @param iSelectorMap 查询参数
         * @returns 返回Array<any>结构
         * @example
         * query.selectArray({
         *   table:'sys_user',
         *   field:['id','username','fullname','tags','attr_data'],
         *   field_format:{tags:'array','attr_data':'json'},
         *   where:{username:'admin'}
         * });
         */
        selectArray(iSelectorMap:SqlSelectorMap):Array<any>;

        /**
         * 查询一行数据,返回为一个Array<any>数组;
         * 
         * @param iSql Sql语句
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回Array<any>结构
         * @example
         * query.selectArray(
         *   "SELECT id,username,fullname,tags,attr_data FROM sys_user where username=:username",
         *   {tags:'array', attr_data:'json'},
         *  {username:'admin'}
         * );
         */
        selectArray(iSql:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):Array<any>;


        /**
         * 查询一行数据,返回为一个Map<string,any>数组;
         * 
         * @param iSelectorMap 查询参数
         * @returns 返回Map<string,any>结构
         * @example
         * query.selectMap({
         *   table:'sys_user',
         *   field:['id','username','fullname','tags','attr_data'],
         *   field_format:{tags:'array','attr_data':'json'},
         *   where:{username:'admin'}
         * });
         */
        selectMap(iSelectorMap:SqlSelectorMap):Map<string,any>;

        /**
         * 查询一行数据,返回为一个Map<string,any>数组;
         * 
         * @param iSql Sql语句
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回Map<string,any>结构
         * @example
         * query.selectMap(
         *   "SELECT id,username,fullname,tags,attr_data FROM sys_user where username=:username",
         *   {tags:'array', attr_data:'json'},
         *  {username:'admin'}
         * );
         */
        selectMap(iSql:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):Map<string,any>;


        /**
         * 查询数据,返回第一行第一列;
         * 
         * @param iSelector 查询参数
         * @returns 返回第一行第一列数据
         * @example
         * query.selectValue({ table:'sys_user', field:'id',where:{username:'admin'}});
         */
        selectValue(iSelector:SqlSelectorMap):any;

        /**
         * 查询数据,返回第一行第一列;
         * 
         * @param iSql Sql语句
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回第一行第一列数据
         * @example
         * query.selecValue( "SELECT id FROM sys_user where username=:username", {}, {username:'admin'});
         */
        selectValue(iSql:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):any;

        /**
         * 查询数据,返回Array<Array<any>>结构;
         * 
         * @param iSelectorMap 查询参数
         * @returns 返回Array<Array<any>>结构
         * @example
         * query.selectArraryArray({
         *   table:'sys_user',
         *   field:['id','username','fullname','tags','attr_data'],
         *   field_format:{tags:'array','attr_data':'json'},
         *   order:'id ASC',
         *   limit:10,
         * });
         */
        selectArrayArray(iSelectorMap:SqlSelectorMap):Array<Array<any>>;

        /**
         * 查询数据,返回Array<Array<any>>结构;
         * 
         * @param iSql Sql语句
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回Array<Array<any>>结构
         * @example
         * query.selectArraryArray(
         *   "SELECT id,username,fullname,tags,attr_data FROM sys_user where id < :maxid",
         *   {tags:'array', attr_data:'json'},
         *   {maxid:1000}
         * );
         */
        selectArrayArray(iSql:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):Array<Array<any>>;

        /**
         * 查询数据,返回Array<Map<string,any>>结构;
         * 
         * @param iSelectorMap 查询参数
         * @returns 返回Array<Map<string,any>>结构
         * @example
         * query.selectArraryMap({
         *   table:'sys_user',
         *   field:['id','username','fullname','tags','attr_data'],
         *   field_format:{tags:'array','attr_data':'json'},
         *   order:'id ASC',
         *   limit:10,
         * });
         */
        selectArrayMap(iSelectorMap:SqlSelectorMap):Array<Map<string,any>>;

        /**
         * 查询数据,返回Array<Map<string,any>结构;
         * 
         * @param iSql Sql语句
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回Array<Map<string,any>结构
         * @example
         * query.selectArrayMap(
         *   "SELECT id,username,fullname,tags,attr_data FROM sys_user where id < :maxid",
         *   {tags:'array', attr_data:'json'},
         *   {maxid:1000}
         * );
         */
        selectArrayMap(iSql:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):Array<Map<string,any>>;

        /**
         * 查询数据,返回{field:Array<string>, data:Array<Array<any>>}结构;
         * 
         * @param iSelectorMap 查询参数
         * @returns 返回{field:Array<string>, data:Array<Array<any>>}结构
         * @example
         * query.selectArraryData({
         *   table:'sys_user',
         *   field:['id','username','fullname','tags','attr_data'],
         *   field_format:{tags:'array','attr_data':'json'},
         *   order:'id ASC',
         *   limit:10,
         * });
         */
        selectArrayData(iSelectorMap:SqlSelectorMap):SelectArrayDataResult;

        /**
         * 查询数据,返回{field:Array<string>, data:Array<Array<any>>}结构;
         * 
         * @param iSql Sql语句
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回{field:Array<string>, data:Array<Array<any>>}}结构
         * @example
         * query.selectArrayData(
         *   "SELECT id,username,fullname,tags,attr_data FROM sys_user where id < :maxid",
         *   {tags:'array', attr_data:'json'},
         *   {maxid:1000}
         * );
         */
        selectArrayData(iSql:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):SelectArrayDataResult;

       /**
         * 查询数据,返回Map<string,Map<string,any>>结构;
         * 
         * @param iSelectorMap 查询参数
         * @returns 返回Map<string,Map<string,any>>结构
         * @example
         * query.selectMapMap({
         *   table:'sys_user',
         *   field:['id','username','fullname','tags','attr_data'],
         *   field_format:{tags:'array','attr_data':'json'},
         *   unique_field:'id'
         * });
         */
        selectMapMap(iSelectorMap:SqlSelectorMap):Map<string,Map<string,any>>;

        /**
         * 查询数据,返回Map<string,Map<string,any>>结构;
         * 
         * @param iSql Sql语句
         * @param iUniqueField 唯一字段名 
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回Map<string,Map<string,any>>结构
         * @example
         * query.selectMapMap(
         *   "SELECT id,username,fullname,tags,attr_data FROM sys_user where id < :maxid",
         *   "id",
         *   {tags:'array', attr_data:'json'},
         *   {maxid:1000}
         * );
         */
        selectMapMap(iSql:string, iUniqueField:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):Map<string,Map<string,any>>;

         /**
         * 查询数据,返回Map<string,any>结构;
         * 
         * @param iSelectorMap 查询参数
         * @returns 返回Map<string,any>结构
         * @example
         * query.selectMapValue({
         *   table:'sys_user',
         *   field:['id','username','fullname','tags','attr_data'],
         *   field_format:{tags:'array','attr_data':'json'},
         *   unique_field:'id',
         *   value_field:'username',
         * });
         */
        selectMapValue(iSelectorMap:SqlSelectorMap):Map<string,any>;

        /**
         * 查询数据,返回Map<string,any>结构;
         * 
         * @param iSql Sql语句
         * @param iUniqueField 唯一字段名 
         * @param iValueField 值字段名
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回Map<string,any>结构
         * @example
         * query.selectMapValue(
         *   "SELECT id,username,fullname,tags,attr_data FROM sys_user where id < :maxid",
         *   "id", "username",
         *   {tags:'array', attr_data:'json'},
         *   {maxid:1000}
         * );
         */
        selectMapValue(iSql:string, iUniqueField:string, iValueField:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):Map<string,any>;

        /**
         * 查询数据,返回Array<any>结构;
         * 
         * @param iSelectorMap 查询参数
         * @returns 返回Array<any>结构
         * @example
         * query.selectArrayValue({
         *   table:'sys_user',
         *   field:['id','username','fullname','tags','attr_data'],
         *   field_format:{tags:'array','attr_data':'json'},
         *   value_field:'username',
         * });
         */
        selectArrayValue(iSelectorMap:SqlSelectorMap):Array<any>;

        /**
         * 查询数据,返回Array<any>结构;
         * @param iSql Sql语句
         * @param iValueField 值字段名
         * @param iFieldFormat 字段数据类型定义
         * @param iValues Sql语句变量替换
         * @returns 返回Array<any>结构
         * @example
         * query.selectArrayValue(
         *   "SELECT id,username,fullname,tags,attr_data FROM sys_user where id < :maxid",
         *   "username",
         *   {tags:'array', attr_data:'json'},
         *   {maxid:1000}
         * );
         */
        selectArrayValue(iSql:string, iValueField:string, iFieldFormat?:Map<string, FieldFormat>, iValues?:Map<string,any>):Array<any>;


        /**
         * 查询数据的行数;
         * @param iSelectorMap 查询参数
         * @returns 返回行数
         * @example
         * query.selectCount({
         *   table:'sys_user',
         *   where:'id < 100',
         * });
         */
        selectCount(iSelectorMap:SqlSelectorMap):number;

        /**
         * 插入一行
         * 
         * @param iInserterMap 插入参数
         * @returns 返回定义的return_field列数据；
         * @example
         * var id = query.insertRow({
         *   table:'sys_user',
         *   data:{username:'tony', fullname:'Tony Guo', status:'active'},
         *   return_field:'id',
         * }); 
         */
        insertRow(iInserterMap:SqlInserterMap):any;

        /**
         * 批量插入数据
         * 
         * @param iTable 表名 
         * @param iField 字段
         * @param iData 数据
         * @example
         * query.batchInsert('sys_user',['username','fullname'], [{username:'user1',fullname:'User 1'},{username:'user2',fullname:'User2'}])
         */
        batchInsert(iTable:string, iField:Array<string>, iData:Array<Map<string, any>>);

        /**
         * 更新数据;
         * @param iUpdaterMap 更新参数
         * @returns 影响行数
         * @example
         * query.updateRow({
         *   table:'sys_user',
         *   field:['tags'],
         *   data:{tags:'{a,b}']},
         *   where:{username:'admin'},
         * })
         */
        updateRow(iUpdaterMap:SqlUpdaterMap):number;


        /**
         * 更新数据;
         * 
         * @param iTable 表名
         * @param iData 更新数据
         * @param iWhere Where条件
         * @param iUpdatePolicy 更新策略
         * @param iField 更新字段
         * @returns 返回影响行数
         */
        updateRow(iTable:string, iData:Map<string,any>,
            iWhere:string|Array<string>|Map<string,any>,
            iUpdatePolicy?:Map<string,any>,
            iField?:Array<string>
        ):number;

        /**
         * 替换行(存在则更新,不存在则插入)
         * @param iReplacerMap 更新参数
         * @returns 返回指定的字段数据
         * @example
         * query.replaceRow({
         *   talbe:'sys_user',
         *   data:{username:'tony',fullname:'Tony GUO'},
         *   unique_field:['username'],
         *   return_field:'id'
         * });
         */
        replaceRow(iReplacerMap:SqlInserterMap):any;

         /**
         * 替换行(存在则更新,不存在则插入)
         * @param iTable 表名
         * @param iData 替换数据
         * @param iUniqueField 只一字段
         * @param iUpdatePolicy 更新策略
         * @param iReturnField 返回字段
         * @returns 返回指定的字段数据
         * @example
         * query.replaceRow({
         *   talbe:'sys_user',
         *   data:{username:'tony',fullname:'Tony GUO'},
         *   unique_field:['username'],
         *   return_field:'id'
         * });
         */
        replaceRow(iTable:string, iData:Map<string,any>, 
            iUniqueField:Array<string>, iUpdatePolicy?:Map<string,UpdatePolicy>,
            iReturnField?:string
        ):any;


        /**
         * 删除行;
         * 
         * @param iDeleterMap 删除参数
         * @returns 返回影响行数
         * @example
         * query.deleteRow({table:'sys_user', where: {username:'tony'}});
         */
        deleteRow(iDeleterMap:SqlDeleterMap):number;

         /**
         * 删除行;
         * 
         * @param iTable 表名
         * @param iWhere Where条件
         * @returns 返回影响行数
         * @example
         * query.deleteRow('sys_user'{username:'tony'});
         */
        deleteRow(iTable:string, iWhere:string|Array<any>|Map<string,any>):number;

        /**
         * 执行SQL语句;
         * 
         * @param iSql sql语句
         * @returns 返回执行是否成功
         */
        execSql(iSql:string):boolean;

        /**
         * 判断表是否存在;
         * 
         * @param iTable 表名
         * @returns 返回表是否存在
         */
        isTableExists(iTable:string):boolean

        /**
         * 获取表列表;
         * 
         * @returns 返回表列表
         */
        getTableList():Array<string>

        /**
         * 判断字段是否存在;
         * 
         * @param iTable 表名 
         * @param iField 字段名
         * @returns 返回字段是否存在
         */
        isFieldExists(iTable:string, iField:string):boolean;
        
        /**
         * 获取字段列表;
         * 
         * @param iTable 表名
         * @returns 返回字段列表
         */
        getFieldList(iTable:string):Array<string>;

        /**
         * 设置在新增数据时,是否可以设置自增长字段;（仅对Sql Server有效);
         * 
         * @param iTable 表名
         * @param iStatus 状态
         * 
         */
        setAutoIncrementStatus(iTable:string, iStatus:string):boolean;

        /**
         * 获取数据库当前时间,格式为yyyy-MM-dd hh:mm:ss
         */
        getNow():string;

        /**
         * 获取数据库当前日期,格式为yyyy-MM-dd
         */
        getToday():string;


        /**
         * 获取错误文本信息;
         */
        errorString():string;

        /**
         * 获取最后一次错误消息;
         */
        lastError():TopSinError;

        /**
         * 清除错误;
         */
        clearError():void;

        /**
         * 事务开始;
         * @param iCheckConnection 是否检查连接是否正常;
         */
        begin(iCheckConnection?:boolean):boolean;

        /**
         * 提交事务;返回当前事务嵌套层级;
         */
        commit():number;

        /**
         * 回滚事务;返回当前事务的嵌套层级;
         */
        rollback():number;

        /**
         * 打开数据库连接;
         * @param iCheckConnection 是否检查连接是否正常;
         */
        open(iCheckConnection?:boolean):boolean;

        /**
         * 关闭数据库连接;
         */
        close():boolean

        /**
         * 判断数据库是否连接上;
         */
        isConnected():boolean;

        /**
         * 返回数据库类型;
         */
        databaseType():string;
    }
    /**
     * 添加数据库连接;
     *
     * @param iCntParam 连接参数
     * @param iCntName 连接名称,默认为空;为空时代表默认连接
     * @example 
     *db.addConnection({databse_type:db.DbType.pg,
     *  database_host:'127.0.0.1:5433',
     *  database_name:'TOPMES_SNAPSHOT_V6',
     *  database_user:'toplinker',
     *  database_pwd:'Password'
     *});
     */
    export function addConnection(iCntParam:SqlConnectionParam, iCntName?:string):void;

   /**
    * 移除已添加的连接;
    * @param iCntName 连接名称
    */
    export function removeConnection(iCntName:string):void
    
    /**
     * 获取一个数据库操作对象;
     * @param iCntName 连接名称
     */
    export function query(iCntName?:string):SqlQuery

    /**
     * 获取一个数据库操作对象并执行回调函数;
     * @param iCntName 连接名称
     * @param iCallback 回调函数
     */
    export function query(iCntName:string, iCallback:(query:SqlQuery) => any):any

}

export = TopSinDatabase;


