# db-connector-types - 数据库连接器扩展指南

/**
 * 此文件专门用于定义数据库连接器扩展的相关类型。
 */

/**
 * 数据库连接的配置信息。
 * 
 * 1. 此配置文件是用户新增一个数据源时的配置,通常一个SuccBI部署环境可以连接多个数据源,每个数据源都有一个配置。
 * 2. 此配置的设置项需要和后端的`JdbcConfigPropertyName.java`保持一致。
 */
interface JdbcConfigInfo {
	/**
	 * 名称。
	 * 
	 * 名称是用于唯一标识一个数据源的。
	 * 
	 * 此属性通常可以不配置,它实际上就等于配置文件的文件名。
	 */
	name?: string;
	/**
	 * 描述。
	 */
	desc?: string;
	/**
	 * 此数据库连接器的标识ID,表示此数据源通过哪个连接器进行连接,如果没有配置,系统将系统根据
	 * {@link url}找到一个合适的连接器进行连接。
	 *
	 * 此属性通常不需要用户手工配置,当用户选择使用某个连接器连接数据库时,系统会自动将这个标识ID记
	 * 录到用户的数据源配置文件中,用于告诉系统这个数据源使用指定的连接器连接数据库,为了兼容以前的
	 * 配置文件,当数据源配置文件中没有连接器标识时系统也支持通过url匹配模式找到合适的连接器,见
	 * {@link DbCapabilities.matchJdbcURL}。
	 */
	dbConnector?: string;
	/**
	 * 数据库的驱动,如`com.ibm.db2.jcc.DB2Driver`。
	 * 
	 * 默认空,无需配置,系统会自动获取对应的{@link dbConnector}中配置的默认的驱动。
	 */
	driver?: string;
	/**
	 * 数据库所在服务器的地址
	 */
	host?: string;
	/**
	 * 数据库端口号
	 * 
	 * @TJS-type integer
	 */
	port?: number;
	/**
	 * 数据库名。
	 */
	databaseName?: string;
	/**
	 * 数据库连接用户
	 */
	user?: string;
	/**
	 * 数据库连接密码。
	 * 
	 * 如果通过图形化UI配置的数据库连接,那么密码会加密存储。
	 */
	password?: string;
	/**
	 * jdbc连接的URL。
	 */
	url?: string;

	/**
	 * 指定默认schema(当{@link DbSupportsConf.supportsSchema}为true时有效)。
	 *
	 * 类似{@link defaultCatalog},通常数据库连接的默认schema是在jdbc的url或其他连接属性中指定的,当
	 * 通过url无法指定时,或使用jdbc标准api无法获取到当前schema、通过
	 * {@link DbSQLTemplates.getSchema}也无法获取时,需要配置此参数(例如连接数据库的用户无相关权
	 * 限,或者数据库的JDBC驱动API不支持相关api调用),此参数非常重要,它决定了判断表是否存在,用户
	 * 能访问的数据表列表等。
	 *
	 * 1. 此参数配置的是数据库用户连接数据库后的当前schema,主要用于告诉系统,数据库连接默认是哪个
	 *    Schema。
	 * 2. 当配置此参数后,用户通常也需要确保系统通过jdbc的url、connectionProperties等属性建立的数据
	 *    库连接的当前schema和当前配置的defaultSchema一致,需要特别注意的是,如果配置了此参数,那么
	 *    系统在新建一个数据库连接时也会主动调用一次{@link Connection.setSchema(String)}函数,确保连
	 *    接使用这里设置的schema。
	 * 3. 未设置此参数时系统会自动用用户配置的SQL模板(见{@link DbSQLTemplates#getSchema})获取当前
	 *    schema。如果用户未配置模板,那么自动使用jdbc的api获取。
	 */
	defaultSchema?: string;

	/**
	 * 指定默认catalog(当{@link DbSupportsConf.supportsCatalog}为true时有效)。
	 *
	 * 类似{@link defaultSchema},通常数据库连接的默认catalog是在jdbc的url或其他连接属性中指定的,当
	 * 通过url无法指定时,或使用jdbc标准api无法获取到当前catalog、通过
	 * {@link DbSQLTemplates.getCatalog}也无法获取时,需要配置此参数(例如连接数据库的用户无相关权
	 * 限,或者数据库的JDBC驱动API不支持相关api调用),此参数非常重要,它决定了判断表是否存在,用户
	 * 能访问的数据表列表等。
	 *
	 * 1. 此参数配置的是数据库用户连接数据库后的当前Catalog,主要用于告诉系统,数据库连接默认是哪个
	 *    Catalog。
	 * 2. 当配置此参数后,用户通常也需要确保系统通过jdbc的url、connectionProperties等属性建立的数据
	 *    库连接的当前Catalog和当前配置的defaultCatalog一致,需要特别注意的是,如果配置了此参数,那
	 *    么系统在新建一个数据库连接时也会主动调用一次{@link Connection.setCatalog(String)}函数,确
	 *    保连接使用这里设置的Catalog。
	 * 3. 未设置此参数时系统会自动用用户配置的SQL模板(见{@link DbSQLTemplates#getCatalog})获取当前
	 *    Catalog。如果用户未配置模板,那么自动使用jdbc的api获取。
	 */
	defaultCatalog?: string;

	/**
	 * 设置建立JDBC连接时的连接属性。
	 *
	 * 此设置只会作用到`java.sql.Driver.connect()` 函数的第二个参数需要的参数,不会作用到URL中的参
	 * 数,有些数据库的参数必须通过Properties进行设置,设置到URL中无效。
	 * 
	 * 可以设置一个字符串,包含`&`分割的多个参数值,如oracle可以设置网络传输压缩参数:
	 *
	 * `connectionProperties=oracle.net.networkCompression=on&oracle.net.networkCompressionLevels=high`。
	 * 
	 * 也可以设置一个json。
	 *
	 * 默认空。
	 */
	connectionProperties?: { [name: string]: string | number } | string;

	/**
	 * 对连接器的部分特性重载。
	 * 
	 * 当使用某个连接器连接数据库时,可能有一些特性选项希望能修改一下,比如某个函数模版。
	 */
	capabilities?: DbVersionCapabilities;

	/**
	 * 连接池的最大连接数。
	 * 
	 * 默认50。
	 * 
	 * @TJS-type integer
	 */
	poolSize?: number;

	/**
	 * 连接池最小连接数。
	 * 
	 * 连接池在初始化时会尽量提前准备好最小连接数的连接。
	 * 
	 * 默认5。
	 * 
	 * @TJS-type integer
	 */
	minPoolSize?: number;

	/**
	 * 最大空闲时间。当连接长时间未使用后将被关闭。
	 *
	 * 连接池中的连接在长时间不使用时可能会由于某种原因而失效,但连接池并不知道,此时可以设置此选项
	 * 以丢弃长时间未使用的连接:
	 *
	 * 1. 有些数据库的连接长时间不使用时,数据库会自动回收并失效,但是连接池并不知道,比如mysql的连
	 *    接就有默认8小时的有效时间。
	 * 2. 有些网络环境防火墙有一个TCP超时时间,比如半小时,对于通过防火墙的所有TCP连接,如果在半小时
	 *    内没有任何活动,就会被防火墙拆除,这样就会导致连接中断。
	 *
	 * 支持数值和字符串两种类型,若为数值则取默认单位秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时。
	 * 
	 * 默认1800秒,即30分钟,0表示无限制。
	 */
	maxIdleTime?: number | string;

	/**
	 * 最大存活时间。
	 *
	 * 当连接自最初创建到现在的时间长度超过了这个最大存活时间,那么连接会被销毁(物理关闭),重新获
	 * 取新的连接,保持连接池连接的新鲜度。主要为了解决长时间持有连接,可能出现的各种问题。
	 *
	 * 支持数值和字符串两种类型,若为数值则取默认单位秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时。
	 * 
	 * 默认7200秒,即2小时,不能设置小于60,0表示无限制。
	 */
	maxLifeTime?: number | string;

	/**
	 * 获取连接最大等待时间,单位秒。
	 *
	 * 不同数据库由于网络条件不同,建立一个新的连接需要的时间也不同,有些数据库可能没有启动、或者数
	 * 据库连接信息配置地址错了,导致无法连接,此时可能会等待很久。
	 *
	 * 此设置保证获取数据库连接时的最大等待时间:
	 *
	·	 * 1. 第一次连接时,系统会在后台线程进行连接,如果没有正确配置连接超时{@link connectTimeout},
	 *    那么可能会阻塞很久,但是只是在异步线程中阻塞,不会导致当前调用获取连接的线程阻塞。当前线程
	 *    只会最多等待这里设置的时间。
	 * 2. 不是第一次连接时,比如数据库没有空闲连接了,需要获取一个新的连接时,此时不会在异步线程建立
	 *    连接,此时由于之前已经成功连接过,通常不会阻塞太久。
	 *
	 * 支持数值和字符串两种类型,若为数值则取默认单位秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时。
	 * 
	 * 默认5秒。
	 */
	waitTime?: number | string;

	/**
	 * 建立数据库连接时的超时。
	 *
	 * 此设置时应用发起一个新的数据库连接时的超时,有时候不同的网络设置,可能某些数据库无法连接时会
	 * 等待很长时间,此设置可以确保最多等待指定的时间,如果还未完成连接则抛出超时错误。
	 *
	 * 不同的数据库在进行连接建立时需要指定不同的参数表示超时时间,这里用户可以统一配置此属性,数据
	 * 库的连接器会将这个设置“翻译”为数据库自己特有的设置。
	 *
	 * 支持数值和字符串两种类型,若为数值则取默认单位毫秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时。
	 * 
	 * 默认6000(即6秒),单位毫秒。
	 */
	connectTimeout?: number | string;

	/**
	 * 执行sql网络超时参数(也即socket读写时的timeout)。
	 *
	 * 此设置是应用和数据库之间的网络通信读写超时,比如应用端从数据库段读取数据,如果超过这个时间没
	 * 有返回任何数据则出现超时错误。
	 *
	 * 不同的数据库在进行连接建立时需要指定不同的参数表示超时时间,这里用户可以统一配置此属性,数据
	 * 库的连接器会将这个设置“翻译”为数据库自己特有的设置。
	 *
	 * 考虑到有些SQL执行需要的时间很长,此设置通常不能太短,默认为6小时。
	 *
	 * 支持数值和字符串两种类型,若为数值则取默认单位毫秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时。
	 * 
	 * 默认21600000(6小时),单位毫秒。
	 */
	socketTimeout?: number | string;

	/**
	 * 此参数设置批量写入数据时,每次提交的行数,决定了写入效率;
	 * 此参数不能设置过大,超过50已经没有效率提升,经测试,设置10-30是比较合理的值。
	 * Oracle的驱动一直有一个bug,就是一次提交的数据的字节数,如果超过驱动里的一个cache数组,就会抛出数组越界异常,
	 * 根据BI@Report的经验,Oracle 此参数设置10是比较合理的。
	 * 还有如果写入的表中有大字段,则每行提交速度快,此时此参数不起作用。
	 * 
	 * 默认20。
	 * 
	 * @TJS-type integer
	 */
	batchSize?: number;

	/**
	 * 设置是否自动检查连接池健康状态。
	 *
	 * 启用时将会定时检查连接池的状态,包括数据库是否能连接、释放超出{@link maxIdleTime}或
	 * {@link maxLifeTime}的连接、自动侦测是否存在连接漏洞并自动回收。
	 *
	 * 默认=true。
	 */
	enableHealthCheck?: boolean;

	/**
	 * 设置自动检查连接池健康状态的周期。
	 *
	 * 当{@link enableHealthCheck}启用后生效。
	 * 
	 * 支持数值和字符串两种类型,若为数值则取默认单位秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时。
	 * 
	 * 默认600秒(即10分钟),单位秒,不能小于3。
	 */
	healthCheckPeriod?: number | string;

	/**
	 * 设置当健康检查出错后最多尝试几次。
	 *
	 * 有些数据库可能关闭了,或者某些集群节点就是无法连接有些数据库,此时可以不用不断的检查,最多尝
	 * 试多少次就不再检查了,需要用户手工在数据源管理界面上点击“刷新”。
	 *
	 * 根据{@link healthCheckPeriod}的设置不同,可以知道最多尝试多久,默认检查周期是10分钟,如果设
	 * 置6,那么最多尝试检查1小时后就不再尝试检查了。
	 *
	 * 默认10。
	 */
	healthCheckMaxTryTimes?: number;

	/**
	 * 设置连接有效性的测试时长。
	 *
	 * 每次从连接池获取连接后,如果连接的最近一次连接测试早于这里设定的时长,那么将自动测试一下连接
	 * 的有效性。
	 *
	 * 此设置只有在{@link testConnectionOnCheckout}启用时才生效。
	 *
	 * 支持数值和字符串两种类型,若为数值则取默认单位秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时。
	 * 
	 * 默认0秒,0表示总是检查。
	 */
	testConnectionPeriod?: number | string;

	/**
	 * 从连接池获取连接时,进行连接有效性测试,如果连接不可用,将重新获取新的连接返回。
	 *
	 * 1. 进行连接有效性测试对性能有负面影响,只有在网络很不稳定,确实需要的情况下才启用。
	 * 2. 默认每次获取连接时都会进行检查,设置{@link testConnectionPeriod}后将只在最近一次检查时间
	 *    距离现在的时长大于指定的周期时才会进行检查。
	 * 3. 测试时优先使用{@link testQuery},如果没有配置,则执行连接器的默认测试语句,如果也没有,
	 *    那么执行jdbc标准的api{@link Connection#isValid(int)}。
	 *
	 * 默认=false。
	 */
	testConnectionOnCheckout?: boolean;

	/**
	 * 设置一个查询语句,每次检查连接有效性的时候将执行这个查询语句,以判断连接是否有效。
	 *
	 * 1. 这里配置的SQL必须总是能成功执行,如果配置错误(比如配置了一个总是执行错误的sql,查询一个不
	 *    存在的表),将会导致连接池无法获取到连接。
	 * 2. 此属性设置的检查SQL,优先级高于连接器默认的检查语句{@link DbSQLTemplates.testQuery}。
	 * 3. 检查连接有效性是在连接池启用了{@link testConnectionOnCheckout}才会真正的执行检查。
	 *
	 * 默认=null,如果没有配置,则执行连接器的默认测试语句,如果也没有,那么执行jdbc标准的
	 * api{@link Connection#isValid(int)}。
	 */
	testQuery?: string;

	/**
	 * 连接被获取后如果超过这个时间(秒)设置没有任何动作(比如执行SQL),且也没有关闭连接,那么这个
	 * 连接将会被认为疑似连接漏洞,并打印日志。常常和{@link logConnectionTrace}参数一起,用来找到那
	 * 些没有"关闭"的连接漏洞;
	 *
	 * 设置一个大于0的正整数(单位秒),系统会定时进行检查,检查结果将以logback的WARN级别输出到技术
	 * 日志上。
	 *
	 * 支持数值和字符串两种类型,若为数值则取默认单位秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时。
	 *
	 * 默认600秒,即10分钟,表示使用超过10分钟的连接会被诊断为疑似漏洞。
	 */
	leakDetectionThreshold?: number | string;

	/**
	 * 设置为true,将记录从连接池获取连接时的调用堆栈
	 * 
	 * 发现连接漏洞,会打印此连接的调用堆栈,找到调用位置;
	 * 
	 * 默认=false
	 */
	logConnectionTrace?: boolean;

	/**
	 * 设置一次读取到内存的最大数据行数;
	 *
	 * 读取缓慢变化父子维数据会用到此限制,广东卫生项目,有一个10w+的机构表,现在支持设置此参数;
	 * 
	 * 默认500000。
	 * 
	 * @TJS-type integer
	 */
	maxResultSize?: number;
	/**
	 * 默认false,表示是否启用监听物理表的表结构变化
	 */
	enableMonitorMetadata?: boolean;
	/**
	 * 是否定时统计数据库的运行状态信息,默认为false。
	 */
	enableDatabaseStatistics?: boolean;
	/**
	 * 忽略哪些schema,字符串数组,如["sys*", "db*"] 表示忽略sys和db开头的schema
	 */
	monitorIgnoreSchemas?: Array<string>;
	/**
	 * 忽略哪些表,字符串数组,如["tmp*", "sys*"] 表示忽略sys和tmp开头的表
	 */
	monitorIgnoreTables?: Array<string>;
	/**
	 * 是否启用镜像
	 */
	enableMirror?: boolean;

	/**
	 * 镜像数据源的主数据源的名字。
	 * 每个镜像也会创建为一个数据源,名字是主数据源name-mirror-i
	 * 此属性记录主数据源的名字。
	 */
	masterName?: string;
	/**
	 * 可设置多个镜像库的url,其他选项如用户名密码和主库一致
	 */
	mirrors?: Array<string>;

	/**
	 * 获取镜像同步延迟时间,用于修改模型数据后,是否延迟读取从库数据。
	 *
	 * 支持数值和字符串两种类型,若为数值则取默认单位秒,也可以输入以`s`、`ms`、`m`、`h`结尾的字符
	 * 串,如`12m`,表示指定明确的单位秒、毫秒、分钟或小时,比如:期望修改后5分钟内,只从主库查,则
	 * 设置为`5m`。
	 * 
	 * 默认0秒,表示不延迟,总是查从库。
	 */
	mirrorDelay?: number | string;

	/**
	 * 标识这个数据源是哪个项目中进行创建的
	 *
	 * 说明:
	 * 1.为空则代表这个数据源是系统全局添加的。
	 * 2. 如果这个数据源被其他项目引用,将被提到系统全局,这个属性将被清空 (TODO)
	 */
	projectBorn?: string;

	/**
	 * 配置和当前数据源能一起在一个SQL发起查询的其他数据源。
	 *
	 * 此属性用于判断跨库分析查询时是否需要提取迁移数据。由于实际使用时,不同的数据库配置差异较大,
	 * 是不是一个库不容易自动判断,而且用户既然配置了2个数据源,那肯定是有分开的原因的,此时用户又希
	 * 望涉及到2个源的分析能一个sql查询的话,需要用户主动自己配置才行。
	 *
	 * 注意,此配置是一个单向配置,比如对于数据源A和B,如果在A中配置了sameSources是B,那么说明:
	 *
	 * 1. 当加工需要从B到A提取数据数据时,可以直接使用一个SQL进行提取,比如insert into as select。
	 * 2. 当一个query需要同时查询A和B的数据时,也能一起关联查询。
	 *
	 * 配置此属性后,还需要确保下面的必要条件是满足的才行:
	 *
	 * 1. 驱动相同。
	 * 2. 如果配置中有配置了host,那么host相同。
	 *
	 * 默认空,可以配置一个字符串数组,数组成员是同源的数据源的名称({@link name}),或者直接配置一
	 * 个逗号分隔的字符串。
	 */
	sameSources?: Array<string> | string;

	/**
	 * 定义新建一个数据库连接时需要执行的初始化SQL。
	 *
	 * 这里配置的SQL会在第一次新建一个物理数据库连接时执行一次(只是新建物理连接时执行一次,从连接池
	 * 中获取已存在的连接时不会重复执行),通常用于初始化数据库连接的一些属性设置。
	 *
	 * 默认空,可以配置一个字符串数组,数组成员是一个可以独立执行的SQL,或者直接配置一个分号+换行分
	 * 隔的SQL字符串,每个SQL用分号结尾并换行。
	 */
	initialSQLs?: Array<string> | string;

	/**
	 * 数据库是否只读,只读状态下只能读取数据,不能修改表结构和数据
	 */
	readonly?: boolean;

	/**
	 * 数据库的版本号,由三位数字组成,如`8.0.16`。
	 *
	 * 版本号用于连接器决定选择哪个版本的配置,默认的系统会读取数据库的jdbc api函数返回的版本号,但
	 * 是有些数据库的版本号不规范,或者调用api出现错误(比如达梦),此时可以连接数据库时自己配置一下
	 * 版本号。
	 * 
	 * 默认读取jdbc api返回的版本号。
	 */
	databaseProductVersion?: string;

	/**
	 * 配置此连接的数据库表的命名空间结构。
	 *
	 * 默认情况下,系统将调用{@link DbSQLTemplates.getSchemas}或{@link DbSQLTemplates.getCatalogs}获
	 * 取表的命名空间层次结构,当它们无法返回需要的结构时可以配置此属性,此时系统将直接返回这里配置
	 * 的层次结构,不再调用相关模版或JDBC API。
	 *
	 * 通常只有需要限制某些schema或catalog的访问、或者希望能添加一个dblink在schema列表时才需要配置此
	 * 属性。
	 * 
	 * 配置空数组表示不能范围任何schema,只能使用默认schema。
	 */
	schemas?: Array<{
		/**schema或catalog的名字 */
		name?: string,
		/**如果同时支持schema和catalog,那么{@link name}属性表示schema,此属性表示catalog */
		catalog?: string,
		/**一个表示此schema的完整路径,如`server1.catalog1.schema1`,不配置时将默认使用
		 * {@link catalog}+{@link name} */
		qualifiedName?: string,
	}>;

	/**
	 * 用户自定义属性
	 */
	[customProperty: string]: any;

}

/**
 * 与{@link JdbcConfigInfo}中参数名一致
 */
declare const enum JdbcConfigPropertyName {
	/**
	 * {@link JdbcConfigInfo#name}
	 */
	name = "name",

	/**
	 * {@link JdbcConfigInfo#databaseName}
	 */
	databaseName = "databaseName",

	/**
	 * {@link JdbcConfigInfo#desc}
	 */
	desc = "desc",

	/**
	 * {@link JdbcConfigInfo#host}
	 */
	host = "host",

	/**
	 * {@link JdbcConfigInfo#port}
	 */
	port = "port",

	/**
	 * {@link JdbcConfigInfo#readonly}
	 */
	readonly = "readonly",

	/**
	 * {@link JdbcConfigInfo#url}
	 */
	url = "url",

	/**
	 * {@link JdbcConfigInfo#user}
	 */
	user = "user",

	/**
	 * {@link JdbcConfigInfo#password}
	 */
	password = "password",

	/**
	 * {@link JdbcConfigInfo#poolSize}
	 */
	poolSize = "poolSize",

	/**
	 * {@link JdbcConfigInfo#waitTime}
	 */
	waitTime = "waitTime",

	/**
	 * {@link JdbcConfigInfo#testConnectionOnCheckout}
	 */
	testConnectionOnCheckout = "testConnectionOnCheckout",

	/**
	 * {@link JdbcConfigInfo#testConnectionPeriod}
	 */
	testConnectionPeriod = "testConnectionPeriod",

	/**
	 * {@link JdbcConfigInfo#enableMirror}
	 */
	enableMirror = "enableMirror",

	/**
	 * {@link JdbcConfigInfo#mirrors}
	 */
	mirrors = "mirrors",

	/**
	 * {@link JdbcConfigInfo#mirrorDelay}
	 */
	mirrorDelay = "mirrorDelay",

	/**
	 * {@link JdbcConfigInfo#minPoolSize}
	 */
	minPoolSize = "minPoolSize",

	/**
	 * {@link JdbcConfigInfo#maxIdleTime}
	 */
	maxIdleTime = "maxIdleTime",

	/**
	 * {@link JdbcConfigInfo#maxLifeTime}
	 */
	maxLifeTime = "maxLifeTime",

	/**
	 * {@link JdbcConfigInfo#connectTimeout}
	 */
	connectTimeout = "connectTimeout",

	/**
	 * {@link JdbcConfigInfo#socketTimeout}
	 */
	socketTimeout = "socketTimeout",

	/**
	 * {@link JdbcConfigInfo#batchSize}
	 */
	batchSize = "batchSize",

	/**
	 * {@link JdbcConfigInfo#enableHealthCheck}
	 */
	enableHealthCheck = "enableHealthCheck",

	/**
	 * {@link JdbcConfigInfo#healthCheckPeriod}
	 */
	healthCheckPeriod = "healthCheckPeriod",

	/**
	 * {@link JdbcConfigInfo#healthCheckMaxTryTimes}
	 */
	healthCheckMaxTryTimes = "healthCheckMaxTryTimes",

	/**
	 * {@link JdbcConfigInfo#testQuery}
	 */
	testQuery = "testQuery",

	/**
	 * {@link JdbcConfigInfo#leakDetectionThreshold}
	 */
	leakDetectionThreshold = "leakDetectionThreshold",

	/**
	 * {@link JdbcConfigInfo#logConnectionTrace}
	 */
	logConnectionTrace = "logConnectionTrace",

	/**
	 * {@link JdbcConfigInfo#maxResultSize}
	 */
	maxResultSize = "maxResultSize",

	/**
	 * {@link JdbcConfigInfo#enableMonitorMetadata}
	 */
	enableMonitorMetadata = "enableMonitorMetadata",

	/**
	 * {@link JdbcConfigInfo#enableDatabaseStatistics}
	 */
	enableDatabaseStatistics = "enableDatabaseStatistics",

	/**
	 * {@link JdbcConfigInfo#monitorIgnoreSchemas}
	 */
	monitorIgnoreSchemas = "monitorIgnoreSchemas",

	/**
	 * {@link JdbcConfigInfo#monitorIgnoreTables}
	 */
	monitorIgnoreTables = "monitorIgnoreTables",
}

/**
 * 数据库兼容扩展。
 * 
 * 如果要兼容一个新的数据库,实现这个扩展点。
 */
declare interface DbConnectorContributeInfo extends ExtensionContributeInfo {

	/**
	 * 此数据库连接器的标识ID。
	 *
	 * 1. 系统中所有支持的数据库的名称是不能冲突的。
	 * 2. 通常是有字母组成的标识符,用db的品牌名称代替,如Oracle、MySql……,大小写敏感,与db品牌本身
	 *    的logo保持一致。
	 * 2. 当用户选择使用某个连接器连接数据库时,系统会自动将这个标识ID记录到用户的数据源配置文件中,
	 *    用于告诉系统这个数据源使用指定的连接器连接数据库,为了兼容以前的配置文件,当数据源配置文件
	 *    中没有连接器标识时也支持通过url匹配模式找到合适的连接器,见
	 *    {@link DbCapabilities.matchJdbcURL}。
	 *
	 * 关于数据库的标题:
	 *
	 * 1. 有些数据库可能有中文名,比如GBase叫“南大通用”,所以需要使用国际化信息配置,具体见
	 *    {@link ExtensionInfo.i18n}。
	 * 2. 默认的系统将从国际化key: `db.name.${dbType}.caption`中找标题,从`db.name.${dbType}.desc`中
	 *    找描述。
	 * 3. 如果国际化中不存在,那么将直接使用{@link dbType}当作标题。
	 */
	name: string,

	/**
	 * 数据库的类别。用于在新建数据源的对话框中将数据库logo分组显示。
	 */
	dbKind?: DbKind,

	/**
	 * 数据库的显示时的排名。是一个0~100的整数,数值越大越靠前,通常用在新建数据源的对话框中logo的排序。
	 * 
	 * 如:
	 * 
	 * 1. MySql  = 100
	 * 2. Oracle = 90
	 * 3. Vertica = 60
	 * 4. GBase = 30
	 */
	dbDisplayOrder?: number,

	/**
	 * 配置一些关于db的个性化选项,用于在数据库连接设置页面中提供一些个性化的能力。比如提供一些个性化的
	 * 连接选项、构造个性化的连接URL等。
	 * 
	 * 更多信息见{@link JDBCConfigHelper}
	 */
	jdbcConfigHelper?: JDBCConfigHelper,

	/**
	 * 指定一个相对于当前扩展目录的文件,用于描述和配置数据库的功能、兼容性选项。
	 * 
	 * 1. 默认使用`capabilities.json`文件。
	 * 2. 文件中应该配置多个不同数据库版本的兼容性描述,具体格式参考{@link DbCapabilities}。
	 */
	capabilities?: ExtensionFilePath;
}

/**
 * 描述一个数据库连接器所能连接的数据库(可以多个版本)的兼容性选项。
 *
 * SuccBI需要兼容很多数据库,不同数据库有自己的特性和SQL语法等,兼容时通过配置一个这样的json文件即可
 * 对数据库进行适配。
 *
 */
declare interface DbCapabilities extends DbVersionCapabilities {
	/**
	 * 设置当前配置继承另一个Connector的配置。
	 *
	 * 比如TiDb语法是兼容Mysql的,不需要过多的重复配置,设置此属性为`MySQL`然后配置一些与MySql不兼容
	 * 的选项即可。系统也提供了默认的通用JDBC连接器,定义了一些通用的常见选项,比如sql模板中的`drop
	 * table ?`模板、窗口函数模版等,通常应该至少配置继承JDBC,如`"inheritConnector": "JDBC"`。
	 *
	 * 当设置此属性后,当前连接器的默认配置会先继承这里指定的连接器的配置,如果当前连接器配置了不同
	 * 版本的选项(见{@link compitableVersions}),那么在版本继承时也自然继承了`inheritConnector`指
	 * 定的连接器配置,即继承的顺序是:`高版本 <- 低版本 <- 默认版本 <- inheritConnector`。
	 *
	 * 1. 此属性配置的是Connector的标识ID,即{@link DbConnectorContributeInfo.name},不是扩展的id,
	 *    以继承Mysql为例,应该是`MySQL`,而不是`succ-dbconnector-mysql`,大小写敏感。
	 * 2. 如果只配置id,那么默认继承的是连接器的基础版本,如配置`MySQL`,继承的是`5.0.0`版本的配置,
	 *    如果想设置继承特定的版本,可以用`@`符号,如 `"inheritConnector": "MySQL@8.0.0"`。
	 *
	 * 默认为空,不继承任何连接器。
	 */
	inheritConnector?: string;

	/**
	 * 匹配的数据库版本,如果指定了此参数,那么只有当数据库的版本号符合指定的版本时才能使用此扩展点
	 * 连接。
	 *
	 * 1. 这里通常描述的是一个兼容范围,比如对于mysql来说,兼容5.0及以后的设置为">=5.0.0"。
	 * 2. 不同的版本也可以有不同的兼容性配置,具体见{@link DbCapabilities}。
	 * 3. 版本是一个字符串,使用semver规范(见<https://docs.npmjs.com/cli/v6/using-npm/semver>)
	 *
	 * 系统会自动调用jdbc驱动的api去获取数据库的版本,但有些数据库不是Mysql却使用的是Mysql的驱动,此
	 * 时驱动api返回的版本信息不是真实的数据库的版本,如StarRocks,通过驱动获取的版本号是`5.1.0`,此
	 * 时如果希望得到系统能绕开驱动API获取真实版本号,可以配置
	 * {@link DbSQLTemplates.getDatabaseProductVersion}。
	 *
	 * 版本号必须是3位数字,以Mysql为例,几个常见示例如下:
	 *
	 * 1. ">=5.0.0"  表示兼容5.0.0及以后版本的数据库
	 * 2. "5.0.0 - 5.7.0"   表示兼容5.0.0和5.7.0之间的版本
	 * 2. "~5.6.0"     表示兼容5.6.x版本的数据库,包括5.6.0,5.6.2,但不包括5.7、6.0等以后版本的数据
	 *    库
	 * 3. "^5.6.0"     表示兼容5.x.x版本的数据库,包括5.6.0、5.7.0、5.8.0,单不包括6.0及以后的版本
	 */
	matchDbVersion?: VersionRange;

	/**
	 * 配置一个正则表达式(用斜线括起来表示正则表达式),判断是否兼容某个jdbc url。
	 *
	 * 当用户选择使用某个连接器连接数据库时,系统会自动将这个标识ID记录到用户的数据源配置文件中,见
	 * {@link JdbcConfigInfo.dbConnector},用于告诉系统这个数据源使用指定的连接器连接数据库,此时可
	 * 以通过它获取连接器的实现。4.0及之前的配置没有记录连接器ID,为了兼容以前的配置文件,当数据源配
	 * 置文件中没有连接器标识时也支持通过url匹配模式找到合适的连接器。
	 *
	 * 如果系统内有多个连接器都匹配某个url,那么将使用匹配规则长度较长的那个。
	 *
	 * 如mysql可以配置: `/^jdbc:mysql:.+$/`或`jdbc:mysql:`,如果没有用斜线括起来,那么将判断url是否
	 * 以这里的配置开头。
	 */
	matchJdbcURL?: RegexString | string,

	/**
	 * 连接器默认的驱动,当数据源的配置文件中没有driver时,将使用这里的配置。
	 * 
	 * 配置驱动的完整java classpath,如`com.ibm.db2.jcc.DB2Driver`。
	 */
	driver?: string;

	/**
	 * 定义java的jdbc连接时需要用的一些默认链接参数,包括URL中的参数或`java.sql.Driver.connect()` 函
	 * 数的第二个参数需要的参数。
	 *
	 * 具体用途见{@link JDBCConnectionProperties}。
	 */
	connectionProperties?: JDBCConnectionProperties;

	/**
	 * 指定一个相对于当前扩展目录的脚本文件(后端脚本,.action结尾的文件),脚本文件的具体接口见
	 * {@link DbConnectorExt},用于通过脚本代码实现一些数据库底层相关的逻辑,比如:
	 *
	 * 1. 使用数据库本地的jdbc api去流式导入数据。
	 */
	script?: string | null;

	/**
	 * 类似{@link script},定义一个java类,用于扩展db连接器的能力。
	 * 
	 * 提供的java类需要实现`com.succez.commons.jdbc.connector.DbConnectorExt`接口。
	 */
	javaClass?: string | null;

	/**
	 * 可以描述多个不同版本数据库的兼容性选项。
	 *
	 * 连接器的默认配置是直接配置在配置文件的根属性上的,当确实有多个版本的配置不同,那么可以把默认
	 * 配置外的其他版本的选项配置在此属性中。`compitableVersions`中配置的顺序要保证高版本在前、低版
	 * 本在后,系统会从上至下优先选用匹配的高版本的配置。`compitableVersions`最后面的那个版本会默认
	 * 继承连接的默认配置。
	 *
	 * 高版本的配置会自动继承低版本的配置,不需要在高版本中将低版本一致的配置重复配置一次,只需要配
	 * 置不一样的或新增的即可。
	 *
	 * 继承的顺序是:`高版本 <- 低版本 <- 默认版本 <- inheritConnector`。inheritConnector见
	 * {@link inheritConnector}。
	 *
	 * key是一个符合semver规范的版本(见{@link VersionRange}),版本号必须是3位数字,具体的示例见
	 * {@link DbCapabilities.matchDbVersion}。
	 *
	 * 默认空,此时表示所有版本都可以使用一个配置。
	 */
	compitableVersions?: {
		[semver: string]: DbVersionCapabilities;
	}
}

/**
 * 配置某个数据库版本的功能、兼容性选项。
 */
declare interface DbVersionCapabilities {

	/**
	 * 配置一些禁止用户通过此连接器执行的SQL。
	 *
	 * 由于数据库连接是有连接池管理的,连接池中的连接是复用的,有些SQL的执行会修改当前连接的状态,导
	 * 致下次复用此连接时状态错乱,这些sql就需要被禁止,比如:
	 *
	 * 1. `/^\s*USE\s/` 表示禁用mysql中的`USE xxx`语句。
	 * 2. `/^\s*ALTER\s+SESSIONS\s+SET\s/` 表示禁用达梦的`ALTER SESSIONS SET CURRENT_SCHEMA=模式名`
	 *    语句。
	 */
	forbiddenSQLs?: Array<RegexString>;

	/**
	 * 数据库的兼容级别。
	 *
	 * 此属性决定了系统的某些功能配置能否使用这个数据库,比如元数据存储只能选择兼容级别是
	 * {@link DbCompatibilityLevel.All}或{@link DbCompatibilityLevel.OLTP}的数据库。
	 * 
	 * 默认的兼容级别是{@link DbCompatibilityLevel.All}。
	 */
	compatibilityLevel?: DbCompatibilityLevel,

	/**
	 * 配置一系列数据库异常信息的“识别规则”,用于将各个数据库的各种异常进行归一化。
	 *
	 * 不同的数据库有不同的异常编码,比如主键冲突、表不存在等,SuccBI需要把这些异常信息归一化,用一
	 * 套错误编码进行解释并提示给最终用户。
	 *
	 * !!!WARNING!!!
	 *
	 * 1. 错误编码配置决定了遇到数据错误时系统如何提示用户,不合理的配置会对用户使用造成困惑。
	 * 2. 那些严重的可能导致Connection不可用的错误(如网络通信错误)需要配置
	 *    {@link SQLExceptionIdentifyConf.isFatalError}=true,此时连接池会自动丢弃这个连接,否则连接
	 *    池可能持续返回错误的连接导致系统不可用。
	 * 3. 数据不合法的错误,比如主键冲突、长度超长、数据被截断、字段不允许为空、无效的数字等,这类错
	 *    误决定了系统是否会进行重试,必需正确配置,否则可能会导致系统某些功能无法正常使用。
	 * 4. 通常应该必须至少有一个属性规则配置,如果所有属性都没有配置,那么会总是匹配这条规则。
	 * 5. 系统会按照数组中配置的顺序逐一进行匹配,推荐将最常见的异常配置在最前面提高系统效率。
	 * 6. 不同数据库版本配置文件继承时新版本的配置中的匹配条件和旧版本完全一致的将覆盖旧版本的规则,
	 *    新版本匹配规则在旧版本不存在时将优先匹配新版本的规则。
	 */
	errorIdentifyConfs?: Array<SQLExceptionIdentifyConf>;

	/**
	 * 关键字列表。
	 *
	 * 在生成SQL的时候,如果某个字段或表名是关键字,那么会需要转义,另外,有些场景下,用户新建的表和
	 * 字段不能使用关键字。如达梦数据库中,COMMENT必需配置为关键字,否则如果用户的表中有一个字段名叫
	 * COMMENT就会导致SQL出错。
	 *
	 * 系统会自动读取JDBC驱动API提供的关键字列表,但不是所有数据库的驱动都能正确返回所有关键字(如达
	 * 梦,COMMENT就没返回),此时就需要自己按需在这里进行配置。
	 *
	 * 1. 系统默认会读取JDBC驱动API提供的关键字列表,在这里的列表中加上
	 *    `DONT_AUTO_INCLUDE_DRIVER_KEYWORDS`可禁用此功能。
	 * 2. 系统也会自动加上SQL 常用的一些关键字,在这里的列表中加上
	 *    `DONT_AUTO_INCLUDE_SQLCOMMON_KEYWORDS`可禁用此功能。
	 * 3. 系统也会自动加上SQL 2003标准中的相关关键字,在这里的列表中加上
	 *    `DONT_AUTO_INCLUDE_SQL2003_KEYWORDS`可禁用此功能。
	 * 4. 基于上面2步的关键字,系统会再继续补上这里定义的关键字,最终形成一个完整的关键字列表。
	 */
	sqlKeyWords?: Array<string>;

	/**
	 * 定义此数据库支持的所有支持的字段类型。
	 *
	 * 这里定义的字段类型描述,主要是将当前数据库支持的字段类型描述清楚:
	 *
	 * 1. 告诉系统不同的字段在系统中是什么数据类型({@link FieldDataType})
	 * 2. 当跨库复制数据的时候,系统也许兼容识别java JDBC的字段类型定义,见{@link JavaSQLTypeName},
	 *    这样在跨库迁移数据时能更准确的还原字段数据类型。
	 *
	 * 当多个类型都是同一个系统内的数据类型(见{@link DbDataTypeDefine.dataType},比如mysql有DECIMAL
	 * 和NUMERIC,在系统中都是浮点数),那么系统在创建物理表时将自动使用配置了
	 * {{@link DbDataTypeDefine.preffered}}=true的字段,如果没有,那么自动使用顺序排在前面的字段。
	 *
	 * 需要特别注意的是对于'X'(即Blob{@link FieldDataType.X})应该配置当前数据库最适合存储文件的字
	 * 段类型,不一定总是BLOB,也许是LONGVARBINARY类型的字段(如pg的bytea类型)。对于'M'(即
	 * Clob{@link FieldDataType.X})也类似。
	 *
	 * 如果当前数据库继承了其他数据库的配置(见{@link DbCapabilities.inheritConnector}),或者继承了
	 * 当前数据库的其他版本,但其中包含了当前数据库不支持的字段类型,那么可以在当前数据库配置不支持
	 * 的字段类型为`null`即可覆盖继承的字段类型。
	 */
	dataTypes?: {
		[type: string]: DbDataTypeDefine | null
	};

	/**
	 * 描述数据库的一个对象(表、视图、存储过程之类的)的类型信息。
	 *
	 * 每个数据库的对象类型可能会有不同,比如视图可能有物化视图和普通视图之分,此处将各个数据库本地
	 * 的类型映射为SuccBI系统内的类型。此配置帮助系统正确识别从jdbc驱动中查询出来的对象类型、是否忽
	 * 略哪些类型等。
	 *
	 * 1. type是从jdbc驱动中查询出来的对象类型,统一大写。
	 * 2. 有些数据库,如达梦,从jdbc驱动中查询出来的对象类型可能是空,默认系统会忽略他们,如果需要将
	 *    其识别为表或其他类型,那么可以定义一个特殊的type: `_NULL`。
	 * 3. {@link DbIdentifierTypeDefine.ignore}为true的对象将被忽略。
	 */
	identifierTypes?: {
		[type: string]: DbIdentifierTypeDefine
	};

	/**
	 * 用于配置表达式函数“翻译”成SQL语句的规则模板。
	 *
	 * 系统提供了很多表达式函数,具体见<https://docs.succbi.com/exp/funcs/>,在不同的数据库中都可以
	 * 使用这些函数,有些时候需要将这些表达式函数“翻译”成SQL在数据库中执行,这就需要用到此处的配置
	 * 了。
	 *
	 * 模板内容可以是字符串或json,具体格式见
	 * {@link SQLFunctionTemplateString}、{@link SQLFunctionTemplateAdv}。
	 */
	functionTemplates?: {
		[expFuncName: string]: SQLFunctionTemplateString | SQLFunctionTemplateAdv
	};

	/**
	 * 定义某些表达式的操作符,比如求余的`%`,有些数据库是`%`,有些是`mod`
	 */
	operatorTemplates?: {
		[expFuncName: string]: string
	};

	/**
	 * 设置SQL模板,更多详细信息见{@link DbSQLTemplates}。
	 */
	sqlTemplates?: DbSQLTemplates;

	/**
	 * 定义SuccBI的“显示格式”(包括表达式函数tostr的格式)所对应的数据库的显示模式。
	 */
	dateDisplayFormats?: DbDateDisplayFormatMappings;

	/**
	 * 定义SuccBI的“显示格式”(包括表达式函数tostr的格式)所对应的数据库的显示模式。
	 */
	numericDisplayFormats?: DbNumericDisplayFormatMappings;

	/**
	 * 定义从数据库元数据信息中提取字段默认值表达式的规则。
	 *
	 * 更多信息见{@link ColumnDefExtractorDef}。
	 */
	columnDefExtractors?: Array<ColumnDefExtractorDef>;

	/**
	 * 数据库特性及SQL方言配置。
	 */
	supports?: DbSupportsConf;
}

/**
 * 配置一些关于db的个性化选项,用于在数据库连接设置页面中提供一些个性化的能力。比如提供一些个性化的
 * 连接选项、构造个性化的连接URL等。
 */
declare interface JDBCConfigHelper {
	/**
	 * 脚本文件在扩展目录下的地址
	 * 
	 * 脚本接口定义参见{@link IDbConfScript}
	 */
	script?: ExtensionFilePath;

	/**
	 * 新建数据库连接时默认的配置。
	 */
	defConf?: JdbcConfigInfo,

	/**
	 * 个性的数据库连接配置项。
	 * 
	 * 如果配置的表单输入项的id与已有的输入项相同,那么将自动将这里配置的合并到原来的输入项上去。
	 */
	confItems?: DsFormItemArgs[];

	/**
	 * JdbcURL模板。
	 *
	 * 用于在新建或编辑数据库连接的表单中,修改了连接属性时,能自动构造jdbcUrl,也用于当用户直接填写
	 * 或修改jdbcUrl时,系统能自动根据url解析出相关属性,如修改数据库地址、端口等,系统自动更新jdbc
	 * Url,反之亦然。
	 *
	 * 模版中的 问号(也许不是问号,见{@link jdbcURLQuerySeparator})之前的部分引用的参数必须存在才
	 * 会更新url,而问号后面的参数部分如果引用的参数不存在,则会自动删除对应的参数。
	 *
	 * 如果需要构造的`URL`比较复杂,模版配置不足以支持,可以通过脚本实现,
	 * {@link IDbConfScript.onFormChanged}。
	 *
	 * 比如Oracle数据库,不同的选项可能构造不同的url:
	 *
	 * 1. `jdbc:oracle:thin:@//{host}/{databaseName}`
	 * 2. `jdbc:oracle:thin:@{host}:{sid}`
	 *
	 * 模版示例:
	 *
	 * - `jdbc:mysql://${host}:${port}/${databaseName}?useUnicode=${useUnicode}&characterEncoding=utf8`
	 * - `jdbc:ots:https://${host}.cn-hangzhou.ots.aliyuncs.com/${databaseName}`
	 * - `jdbc:xmla:Server=http://${host}/OLAP/msmdpump.dll;Catalog=${databaseName};`
	 * - `jdbc:odps:http://${host}?project=${databaseName}`  -- MaxCompute
	 */
	jdbcURLTemplate?: string;

	/**
	 * JDBC URL参数分隔符
	 *
	 * 通常为`&`,但有些数据库比如`SQL Server`使用`;`作为分隔符。
	 *
	 * 默认为`&`。
	 */
	jdbcURLParamsSeparator?: string;

	/**
	 * JDBC URL 中Host和参数列表之间的分隔符。
	 *
	 * 通常为`?`,但有些数据库比如`SQL Server`使用`;`作为分隔符。
	 *
	 * 默认为`?`。
	 */
	jdbcURLQuerySeparator?: string;
}

/**
 * 描述一个自定数据库配置项信息
 * 
 * 由于新建数据源时,会加载{@link JDBCConfigHelper#defConf}中配置的默认值,控件中设置的默认值会被数据源默认配
 * 置覆盖,若需要设置自定义配置项默认值,请在默认值配置中进行设置。
 */
interface DsFormItemArgs extends CommonExtesionPropertyFormItemInfo {

	/**
	 * 自定义属性的配置参数,参见`FormArgs`
	 */
	[formArgument: string]: any;

	/**
	 * 数据库属性还是连接池属性,数据库属性位于左侧,连接池属性位于右侧
	 * 
	 * 默认为`"DB"`
	 */
	propertyType?: "DB" | "CONN",

}

/**
 * 新建或编辑数据源连接时的表单对象。
 * 
 * 用于在脚本{@link IDbConfScript}中能让扩展开发者调用表单的一些功能。
 */
declare interface JdbcConfForm {
	/**
	 * 显示或隐藏某个表单项。
	 * 
	 * @param name 表单项的id,见{@link JdbcConfigPropertyName}
	 * @param visible 显示还是隐藏
	 */
	showFormItem(name: string, visible: boolean): void;
	/**
	 * 返回指定的表单项的值。
	 * 
	 * @param name 表单项的id,见{@link JdbcConfigPropertyName}
	 */
	getFormItemValue(name: string): any;
	/**
	 * 设置指定的表单项的值。
	 * 
	 * @param name 表单项的id,见{@link JdbcConfigPropertyName}
	 * @param value 要设置的值
	 */
	setFormItemValue(name: string, value: any): void;
}

/**
 * 指定一个相对于当前扩展目录的脚本文件(前端脚本,.js结尾的文件),用于在数据库连接设置页面中提
 * 供一些个性化的能力。
 */
declare interface IDbConfScript {
	/**
	 * 当表单中有值发生变化时调用。可以用于动态修改一些配置项。
	 *
	 * @param id 修改项`Id`,见{@link JdbcConfigPropertyName}
	 * @param newValue 新值
	 * @param jdbcConf 当前的jdbc配置
	 * @param jdbcConfForm 数据源配置面板对象
	 */
	onFormChanged?: (id: string, newValue: any, jdbcConf: JdbcConfigInfo, jdbcConfForm: JdbcConfForm) => void;

	/**
	 * 数据源配置界面加载数据源信息后调用。
	 * 
	 * 通常用于在加载完毕后个性化一下配置界面,
	 *
	 * @param jdbcConf 当前的jdbc配置
	 * @param jdbcConfForm 数据源配置面板对象
	 */
	onFormLoaded?: (jdbcConf: JdbcConfigInfo, jdbcConfForm: JdbcConfForm) => void;

	/**
	 * 获取一个运行时的{@link JDBCConfigHelper}对象。
	 *
	 * {@link JDBCConfigHelper.jdbcURLTemplate}、{@link JDBCConfigHelper.jdbcURLParamsSeparator}和
	 * {@link JDBCConfigHelper.jdbcURLQuerySeparator}是可能根据用户在配置数据库连接的表单上选择不同
	 * 的选项而不同的。
	 *
	 * 比如oracle,当用户选择sid模式时{@link JDBCConfigHelper.jdbcURLTemplate}需要是
	 * "jdbc:oracle:thin:@${host}:${port}:${sid}",否则是
	 * "jdbc:oracle:thin:@//${host}:${port}/${databaseName}";
	 *
	 * @returns 
	 */
	getJDBCConfigHelper?: (jdbcConf: JdbcConfigInfo, jdbcConfForm: JdbcConfForm) => JDBCConfigHelper;
}

/**
 * 定义java的jdbc连接时需要用的一些默认链接参数,包括URL中的参数或`java.sql.Driver.connect()` 函数的
 * 第二个参数需要的参数。
 *
 * 1. 此参数在服务器端第一次连接数据库时使用,用于构造合适的url和连接参数,比如连接超时、网络读写超
 *    时等。当用户在浏览器端新建数据源时,在对话框中输入服务器地址和数据库名等信息时不会立即使用此参
 *    数构造url,数据库连接参数设置页面会使用{@link JDBCConfigHelper}提供个性化能力。
 * 2. 如果有极个性化的数据库连接要求,无法使用此配置满足时,可以使用脚本
 *    {@link DbConnectorExt.initConnectProperties}。
 */
declare interface JDBCConnectionProperties {
	/**
	 * 设置此链接的默认链接参数,包括URL中的参数或`java.sql.Driver.connect()` 函数的第二个参数需要的
	 * 参数。
	 *
	 * 1. key是连接数据库时可以指定的参数名,参数可以用于jdbcurl中,也可以用于
	 *    `java.sql.Driver.connect()` 函数的第二个参数。
	 * 2. value是参数值,可以直接设置默认的参数值,也可以设置一个json,见
	 *    {@link JDBCConnectionPropertyDef},此时可以指定参数是否来自用户的设置、参数是否用于
	 *    jdbcurl。
	 *
	 * 注意:连接一个数据库时,用户可以在2个地方配置连接属性,如果这2个地方用户都没有配置,那么会使
	 * 用这里的默认值,这2个地方是:
	 *
	 * 1. {@link JdbcConfigInfo.url}的参数中。
	 * 2. {@link JdbcConfigInfo.connectionProperties}中。
	 *
	 * 如果用户在url中定义了,那么会优先使用url中的。如果用户定义的url中没有指定这些参数,那么在进行
	 * jdbc连接时会使用这里的默认属性,具体需求见:
	 *
	 * 实际例子:
	 *
	 * 1. oracle的连接超时属性是`oracle.net.CONNECT_TIMEOUT`,可以设置它为key,value是
	 *    `{"configProperty":"connectTimeout"}`,此时系统将自动读取
	 *    {@link JdbcConfigInfo.connectTimeout}属性的值设置给oracle的jdbc连接参
	 *    数:`oracle.net.CONNECT_TIMEOUT`。
	 * 2. 同样的,MySQL的连接超时属性是`connectTimeout`,单位毫秒;db2是
	 *    `connectionTimeout`;SQLServer和Vertica是`loginTimeout`,单位秒。
	 * 3. 另一个常见的属性配置是网络读写超时,见 {@link JdbcConfigInfo.socketTimeout}。
	 * 4. vertica需要自动补上ResultBufferSize=819200 见 https://jira.succez.com/browse/BI-31187
	 * 5. mysql需要自动补上serverTimezone=Asia/Shanghai https://jira.succez.com/browse/BI-33813
	 *
	 */
	[propertyName: string]: JDBCConnectionPropertyDef | string | number | boolean;
}

/**
 * 描述一个数据库支持的jdbc连接属性,具体用途见{@link JDBCConnectionProperties}的注释。
 */
declare interface JDBCConnectionPropertyDef {
	/**
	 * 当jdbcurl中、用户的jdbcconf中都没有找到配置值时使用此处设置的默认值。
	 * 
	 * 默认空,此时如果最终都找不到属性值时将不在jdbcurl(或`java.sql.Driver.connect()` 函数的第二个参数)中使用此参数。
	 */
	defaultValue?: any;

	/**
	 * 配置此属性的值来自一个配置,见{@link JdbcConfigInfo},常用的包括:
	 * 
	 * 1. {@link JdbcConfigInfo.connectTimeout}
	 * 2. {@link JdbcConfigInfo.socketTimeout}
	 */
	configProperty?: string;

	/**
	 * 如果属性是时间参数,此参数表示时间的单位是毫秒还是秒。
	 * 
	 * 默认ms。
	 */
	timeUnit?: "ms" | "s";

	/**
	 * true时将参数设置到jdbc url中,false则用于 `java.sql.Driver.connect()` 函数的第二个参数。
	 * 
	 * 默认`true`,参数通常是在`URL`中直接传递的,用户输入的`URL`往往也是带参数的,此处默认为`true`,是一种更通用的做法。
	 */
	inURL?: boolean;
}

/**
 * 定义SuccBI的“日期显示格式”(包括表达式函数tostr的格式)所对应的数据库的显示模式,比如对mysql来
 * 说,`yyyymmdd` 转换成 `%Y%m%d` 。
 *
 * SuccBI的显示格式是参考Excel规范的。
 *
 * @see https://support.microsoft.com/zh-cn/office/%E5%B0%86%E6%95%B0%E5%AD%97%E8%AE%BE%E7%BD%AE%E4%B8%BA%E6%97%A5%E6%9C%9F%E6%88%96%E6%97%B6%E9%97%B4-418bd3fe-0577-47c8-8caa-b4d30c528309#bm2
 * @see https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-format
 */
declare interface DbDateDisplayFormatMappings {
	/**将年显示为 00–99 */
	yy: string;
	/**将年显示为 1900–9999 */
	yyyy: string;
	/**将月份显示为 1–12 */
	m: string;
	/**将月份显示为 01–12 */
	mm: string;
	/**将月份显示为 Jan–Dec */
	mmm: string;
	/**将月份显示为 January–December */
	mmmm: string;
	/**将日期显示为 1–31 */
	d: string;
	/**将日期显示为 01–31 */
	dd: string;
	/**将日期显示为 Sun–Sat */
	ddd: string;
	/**将日期显示为 Sunday–Saturday */
	dddd: string;
	/**小时为 0-23 */
	h: string;
	/**小时数为 00–23 */
	hh: string;
	/**分钟为 0-59, 这里用mi1表示是为了和月份的m区分,实际显示格式中还是用m,"m"或"mm"代码必须紧
	 * 接在"h"或"hh"代码之后或紧接在"ss"代码之前;否则,Excel显示月份而不是分钟*/
	mi1: string;
	/**分钟为 00-59, 这里用mi1表示是为了和月份的mm区分,实际显示格式中还是用mm,"m"或"mm"代码必须
	 * 紧接在"h"或"hh"代码之后或紧接在"ss"代码之前;否则,Excel显示月份而不是分钟 */
	mi2: string;
	/**秒数为 0-59 */
	s: string;
	/**秒为 00–59 */
	ss: string;
	/**毫秒数,必须出现在ss.后面 */
	"000": string;
	/**AM 和 PM 如果格式包含 AM 或 PM,则小时基于 12 小时制,其中"AM"或"A"表示午夜到中午的时
	 * 间,"PM"或"P"表示从中午到午夜的时间。 否则,小时基于 24 小时制。 */
	"am/pm": string;
	/**A或P */
	"a/p": string;
	/** ISO 8601标准周的年份,详见:{@link iw}*/
	"iyyy": string;
	/** 
	 * ISO 8601标准周
	 * 
	 * 新年第一天是周一、周二、周三、周四,属于新年第一周,因此上年末尾的周一,周二,周三,属于下年第一周。
	 * 新年第一天是周五、周六、周日,属于上年的最后一周,新年第一周从下周一开始。
	 * 
	 * 特点:
	 * 1. 每周第一天为周一。
	 * 2. 第一周最少4天,在当前年度。
	 */
	"iw": string;
	/**
	 * 定义其它希望转义的字符
	 *
	 * 比如mysql,百分号是特殊字符,如果用户输入了百分号,需要变成2个百分号,此时可以设置`"%":"%%"`
	 *
	 * 此配置项还可定义为正则表达式,用于转义可能出现的分隔符
	 *
	 * 使用场景:
	 * 达梦数据库日期中想要将中文作为分隔符需要用双引号转义,此时可配置配置`"/[\\u4e00-\\u9fa5]+/": ""$0""`,
	 * 表示将所用能匹配到的中文转换为被引号包含,比如输入的日期格式串为`yyyy年mm月dd日 hh:mm`,经过格式转换后会
	 * 得到`"yyyy\"年\"mm\"月\"dd\"日\" hh:mm"`。
	 *
	 */
	[s: string]: string;
}

/**
 * 定义SuccBI的“数字显示格式”(包括表达式函数tostr的格式)所对应的数据库的显示模式,比如对mysql来
 * 说,`yyyymmdd` 转换成 `%Y%m%d` 。
 *
 * 并不是所有数据库都支持完整的数字显示格式,系统在处理用户输入的表达式和显示格式时,尽量会在内存计
 * 算中完成,只有确实需要使用计算的时候才会转换成数据库的计算方式。
 *
 * SuccBI的显示格式是参考Excel规范的。
 *
 * @see <https://www.postgresql.org/docs/current/functions-formatting.html>
 * @see <https://eco.dameng.com/document/dm/zh-cn/pm/function.html>
 * @see
 * <https://support.microsoft.com/en-au/office/number-format-codes-5026bbd6-04bc-48cd-bf33-80f18b4eae68>
 */
declare interface DbNumericDisplayFormatMappings {
	/**将年显示为 00–99 */
	"0": string;
	/**将年显示为 1900–9999 */
	"#": string;
	/**将月份显示为 1–12 */
	".": string;
	/**将月份显示为 01–12 */
	",": string;
	/**定义其它希望转义的字符,比如mysql,百分号是特殊字符,如果用户输入了百分号,需要变成2个百分号,此时可以设置`"%":"%%"` */
	[s: string]: string;
}


/**
 * 此接口描述系统支持哪些SQL模板,每个SQL模板用于在数据库中实现一个特定的功能。
 *
 * 兼容各个数据库时会对不同的数据库配置一系列SQL模板,比如mysql的jdbc驱动不支持setSchema,就需要配置
 * 一个模板`"setSchema": "USE ?"`,表示使用此模板实现setSchema功能,同样的还有很多类似功能需要SQL模
 * 版。
 * 
 * 此接口需要和后端的`SQLTemplateNames.java`保持一致。
 */
declare interface DbSQLTemplates {

	/**
	 * 一个表(含视图)的“qualified name”模板。
	 *
	 * 不同的数据库在对象标识符规则上有所不同,如mysql是2级结构`database.table`,presto是3级结构
	 * `catalog.schema.table`,此模版定义一个表对象的“qualified name”模板,用于构造一个能准确的引用
	 * 到对象标识符路径,根据当前所在的默认catalog和schema,此模版返回的不是“fully-qualified name”,
	 * 只需要带上必要的命名空间信息即可。
	 *
	 * 模板中可用参数(已按按需根据数据库规范统一大小写):
	 *
	 * 1. name 对象的名称(已按需quote,仅名称,不含schema、catalog)。
	 * 2. schema 对象所在的schema,已按需quote,为空时表示是当前schema或者db不支持schema概念(如
	 *    mysql)。
	 * 3. catalog 对象所在的catalog,已按需quote,为空时表示是当前catalog或者db不支持catalog概念(如
	 *    oracle)。
	 * 4. metaName 对象的名称(未quote)
	 * 5. metaSchema 对象所在的schema,未quote,即便表所在的schema是当前的默认schema,此属性也不会为
	 *    空。
	 * 6. metaCatalog 对象所在的catalog,未quote,即便表所在的catalog是当前的默认catalog,此属性也不
	 * 7. qualifiedParts 对象的”fully-qualified name“路径分段,是一个数组,倒序的,数组的长度可能是2
	 *    为或更长,如对于表`catalog1.schema1.table1`,此属性是`["table1","schema1","catalog1"]`,注
	 *    意数组中不会存在空值,已按需quote,例如,schema是默认的,那么会是当前schema的名字,如果db
	 *    不支持schema,那么数组中不会有schema。
	 * 8. metaParts 类似qualifiedParts,区别是未quote。
	 * 9. dbserver 对象所在的server,已按需quote,通常只对sqlserver有效。会为空。
	 * 10. dialect {@link DbDialect}。
	 *
	 * 已知的一些数据库的表名规则如下:
	 *
	 * 1. mysql:2级结构database.table,catalog对应database,没有schema概念。
	 *    - <https://dev.mysql.com/doc/refman/8.0/en/identifier-qualifiers.html>
	 * 2. sqlserver:4级结构 server.database.schema.table,对应database,schema对应schema,SQL中可以
	 *    使用3级结构的标识符查询数据。
	 *    - <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/transact-sql-syntax-conventions-transact-sql?view=sql-server-ver16#multipart-names>
	 * 3. informix:4级结构 database@service:ownername.table,其中用到了AT和冒号。
	 *    - <https://www.ibm.com/docs/en/informix-servers/14.10?topic=segments-database-object-name#ids_sqs_1649>
	 * 4. oracle:3级结构 schema.table@databaselink。
	 *    - <https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Database-Object-Names-and-Qualifiers.html#GUID-3C59E44A-5140-4BCA-B9E1-3039C8050C49>,
	 *    - <https://docs.oracle.com/cd/B13789_01/server.101/b10759/statements_5005.htm>
	 * 5. presto:3级结构 catalog.schema.table, When addressing a table in Presto, the
	 *    fully-qualified table name is always rooted in a catalog. For example, a fully-qualified
	 *    table name of hive.test_data.test would refer to the test table in the test_data schema in
	 *    the hive catalog.
	 *    - <https://prestodb.io/docs/current/overview/concepts.html#catalog>
	 * 6. vertica:2级结构 schema.table。
	 *    - <https://www.vertica.com/docs/10.0.x/HTML/Content/Authoring/AdministratorsGuide/ConfiguringTheDB/SettingSchemaSearchPaths.htm>
	 *
	 * 默认空,此时会根据{@link java.sql.DatabaseMetaData#getCatalogSeparator()}和
	 * {@link java.sql.DatabaseMetaData#isCatalogAtStart()}的返回值进行拼接,默认使用点号按顺序拼
	 * 接。
	 */
	qualifiedTableName?: SQLTemplateString;

	/**
	 * 获取数据库的版本信息。
	 *
	 * 通常不需要配置这个模版,系统会自动调用jdbc驱动的api去获取,但有些数据库使用的是Mysql的驱动,
	 * 返回的版本信息不是真实的数据库的版本,数据库本身不是Mysql,如StarRocks,通过驱动获取的版本号
	 * 是`5.1.0`,这个版本对应的Mysql很老,也许dbconnector都不能很好支持,实际上StarRocks的版本可能
	 * 是`3.2.0-rc01-9d64ad2`(用`select current_version()`获取)。
	 *
	 * 当配置此模版后系统会自动使用此模版获取数据库的版本信息,此模版需要确保返回的版本信息符合
	 * `x.y.z...`的模式,即开头需要是3个点号分割的数字,表示数据库的主版本号、次版本号和补丁号,版本
	 * 信息后面可以有更多其他信息,如`3.2.0-rc01-9d64ad2`。
	 * 
	 * @see https://docs.oracle.com/javase/8/docs/api/java/sql/DatabaseMetaData.html#getDatabaseProductVersion--
	 *
	 * 默认空,此时系统调用jdbc驱动api获取数据库版本信息。
	 */
	getDatabaseProductVersion?: SQLTemplateString;

	/**
	 * 查询当前会话(链接)的ID。
	 * 
	 * 如mysql是`SELECT CONNECTION_ID()`。
	 */
	getSessionID?: SQLTemplateString;
	/**
	 * 强行杀死一个会话,断开链接。
	 *
	 * 模板中可用参数:
	 *
	 * 1. sessionId 会话的id。
	 * 2. user 当前用户id。
	 * 
	 * 如mysql是`KILL CONNECTION ?`。
	 */
	killSession?: SQLTemplateString;

	getSessions?: SQLTemplateString;

	/**
	 * 获取所有的catalog列表(含qualified name)。
	 *
	 * {@link DbSupportsConf.supportsCatalog}为true时有效,用户通常不需要配置此模版,
	 * 系统会自动使用驱动的`getCatalogs()`API函数。
	 *
	 * 返回的列和驱动的`getCatalogs()`类似:
	 *
	 * 1. TABLE_CAT String => catalog name (may be null)
	 * 2. QUALIFIED_NAME String => catalog的完整路径,点号分隔,中括号转义,不存在此字段时表示直接使
	 *    用字段TABLE_CAT,如果存在此字段,那么将使用点号分隔的层次结构显示表的命名空间目录层次,关
	 *    于qualified name的更多信息见{@link qualifiedTableName}说明。
	 * 
	 * TABLE_CATALOG是标准jdbc接口的字段列,必需要返回的,后面的列根据需要返回,根据这
	 * 些信息组合为一个{@link qualifiedTableName}。
	 */
	getCatalogs?: SQLTemplateString;

	/**
	 * 查询当前的Catalog(当{@link DbSupportsConf.supportsCatalog}为true时有效)。查询结果应该只有一行
	 * 一列,结果就是当前的Catalog名称。
	 *
	 * 模板中可用参数:
	 *
	 * 1. user 登录当前数据库的数据库的账号id。
	 */
	getCatalog?: SQLTemplateString;

	/**
	 * 用于设置当前Catalog的语句(当{@link DbSupportsConf.supportsCatalog}为true时有效)。
	 *
	 * 当db支持Catalog概念,但其jdbc驱动的setCatalog API函数存在问题或不满足需要时可配置此模版,未配
	 * 置模版时将使用jdbc默认API。
	 *
	 * 模板中可用参数:
	 *
	 * 1. catalog 要设置的Catalog,不能为空,见{@link SQLTemplateParam_Identifier}。
	 * 2. user 登录当前数据库的数据库的账号id。
	 */
	setCatalog?: SQLTemplateString;

	/**
	 * 查询当前catalog下的schema列表(含qualified name)。
	 *
	 * 当{@link DbSupportsConf.supportsSchema}为true时有效,通常不需要配置此模版,系统会使用JDBC的
	 * API获取schema,当驱动默认的API不能满足需要时才考虑配置模版。
	 *
	 * 1. 当{@link DbSupportsConf.supportsCatalog}为true时
	 *     - 如果{@link DbSupportsConf.supportsGetAllSchemas}为true,那么系统会直接获取所有可用
	 *       schema返回给调用者。
	 *     - 否则系统会先调用{@link getCatalogs}获取所有可用的catalog,然后按需调用此函数获取catalog
	 *       下的可用schema。
	 * 2. 若db不支持catalog,那么会直接获取所有可用的Schema返回。
	 *
	 * 模板中可用参数:
	 *
	 * 1. catalog 如果db不支持catalog则为空,当{@link DbSupportsConf.supportsGetAllSchemas}为true时
	 *    也可能为空,表示要获取所有schema,否则表示要获取指定catalog下的schema,见
	 *    {@link SQLTemplateParam_Identifier}。
	 * 2. user 登录当前数据库的数据库的账号id。
	 *
	 * 返回的列和驱动的`getSchemas()`类似:
	 *
	 * 1. TABLE_SCHEM String => schema name
	 * 2. TABLE_CATALOG String => catalog name (may be null)
	 * 3. QUALIFIED_NAME String => schema的完整路径,点号分隔,中括号转义,不存在此字段时默认使用
	 *    TABLE_CATALOG+'.'+TABLE_SCHEM,如果存在此字段,那么将使用点号分隔的层次结构显示表的命名空
	 *    间目录层次,关于qualified name的更多信息见{@link qualifiedTableName}说明。
	 */
	getSchemas?: SQLTemplateString;

	/**
	 * 查询当前的schema。
	 *
	 * 当{@link DbSupportsConf.supportsSchema}为true时有效,通常不需要配置此模版,系统会自动使用驱动
	 * 的`getSchema()`API获取,查询结果应该只有一行一列,结果就是当前的schema名称。
	 *
	 * 模板中可用参数:
	 *
	 * 1. user 登录当前数据库的数据库的账号id。
	 */
	getSchema?: SQLTemplateString;

	/**
	 * 用于设置当前schema的语句。
	 *
	 * 当{@link DbSupportsConf.supportsSchema}为true时有效,通常不需要配置此模版,系统会自动使用驱动
	 * 的`getSchema()`API获取。
	 *
	 * 模板中可用参数:
	 *
	 * 1. schema 要设置的schema,不能为空,见{@link SQLTemplateParam_Identifier}。
	 * 2. user 登录当前数据库的数据库的账号id。
	 */
	setSchema?: SQLTemplateString;

	/**
	 * 查询当前的“fully-qualified schema”。
	 *
	 * 配置此模版时应同时配置{@link setQualifiedSchema}。
	 *
	 * 默认的,系统使用{@link getCatalog}和{@link getSchema}来获取当前连接的默认表命名空间,如果数据
	 * 库比较特别,除了catalog、schema还有别的概念,那么可以使用此模版来返回一个自定义的
	 * “fully-qualified schema”。
	 *
	 * 查询结果应该只有一行一列,结果就是当前的“fully-qualified schema”,点号分隔,中括号转义,如
	 * `xxxx.yyy.[catalog1].schema1`。
	 *
	 * 模板中可用参数:
	 *
	 * 1. user 登录当前数据库的数据库的账号id。
	 */
	getQualifiedSchema?: SQLTemplateString;

	/**
	 * 用于设置当前连接的默认表命名空间路径。
	 *
	 * 配置此模版时应同时配置{@link getQualifiedSchema}。
	 *
	 * 当没有配置此模版时,默认系统使用{@link setCatalog}和{@link setSchema}来设置当前连接的默认表命
	 * 名空间。如果数据库比较特别,除了catalog、schema还有别的概念,那么可以使用此模版来设置自定义的
	 * 默认命名空间,此时,系统将使用模版定义的SQL完成切换命名空间,不再调用{@link setCatalog}和
	 * {@link setSchema}。
	 *
	 * 模板中可用参数(已按按需根据数据库规范统一大小写):
	 *
	 * 1. schema 对象所在的schema,为空时表示是当前schema或者db不支持schema概念(如mysql)。
	 * 2. catalog 对象所在的catalog,为空时表示是当前catalog或者db不支持catalog概念(如oracle)。如
	 *    果数据库支持catalog,且当指定的catalog就是当前catalog时,此属性会传null,表示不需要修改
	 *    catalog。此时qualifiedParts中会有指定的catalog,不会为null。
	 * 3. dbserver 对象所在的server,通常只对sqlserver有效。
	 * 4. qualifiedParts 对象的”fully-qualified name“路径分段,是一个数组,倒序的,数组的长度可能是2
	 *    为或更长,如对于表`catalog1.schema1.table1`,此属性是`["table1","schema1","catalog1"]`,注
	 *    意数组中不会存在空值,例如,schema是默认的,那么会是当前schema的名字,如果db不支持schema,
	 *    那么数组中不会有schema。
	 * 5. dialect {@link DbDialect}。
	 */
	setQualifiedSchema?: SQLTemplateString;

	/**
	 * 查询当前数据库的所有关键字。
	 *
	 * !!!WARNING!!! 配置SQL查询关键字存在权限风险,如果连接数据库的账户没有权限执行配置的SQL,那么
	 * 系统可能由于缺少关键字配置,而导致SQL中出现不合法的关键字使用问题,如达梦数据库中,COMMENT必
	 * 需配置为关键字,否则如果用户的表中有一个字段名叫COMMENT就会导致SQL出错。
	 *
	 * 见{@link DbVersionCapabilities.sqlKeyWords},关键字在sql中系统会自动转义,有些数据库(如达梦
	 * 和oracle是`SELECT KEYWORD FROM V$RESERVED_WORDS WHERE RESERVED='Y' AND RES_SQL='Y')可以通过
	 * 一个sql查询出关键字来,这样可以减少一些配置。
	 *
	 * 此模版无参数,模版的sql应该返回一列字符串,每行是一个关键字,系统会将这些关键字记录下来作用类
	 * 似{@link DbVersionCapabilities.sqlKeyWords}。
	 */
	getReservedWords?: SQLTemplateString;

	/**
	 * 查询某个schema下的所有表或指定表的信息,包括视图、同义词。
	 *
	 * 当标准的JDBC API接口无法获取到需要的表列表时,可以定义一个sql语句,自定义表信息的查询逻辑,比
	 * 如有些数据库的标准API接口无法获取到表的注释,而有些数据库的标准API接口获取到的表包含了一些无
	 * 用的表信息等。
	 *
	 * 当定义了此SQL模板后,系统不会调用jdbc标准的`getTables` API获取表列表,而是调用此SQL获取表信
	 * 息。
	 *
	 * 返回的字段列:
	 *
	 * 1. TABLE_CAT String 必须,Catalog
	 * 2. TABLE_SCHEMA String 必须,SCHEMA
	 * 3. TABLE_NAME String 必须,表名,可能是其他类型,比如视图
	 * 4. TABLE_TYPE String 必须,表类型
	 * 5. TABLE_COMMENT String 必须,注释信息
	 *
	 * 模板中可用参数与模版{@link qualifiedTableName}参数一致,其中参数`name`和`metaName`表示要查询
	 * 的表的名称,若为空,则表示查询schema下的所有表。
	 *
	 * 以tidb为例如下,注意sql模板中的`[ and table_name=?]`部分,表示如果没有第二个参数时SQL就不包括
	 * 方括号的所有内容:
	 *
	 * ```sql
	 * SELECT TABLE_SCHEMA, 
	 *   TABLE_NAME, 
	 *   case when table_type='BASE TABLE' then 'TABLE' else table_type end as TABLE_TYPE, 
	 *   table_comment as TABLE_COMMENT
	 * from information_schema.tables
	 * where [table_name=? and ]table_schema=?
	 * ```
	 *
	 * 默认空,表示通过jdbc标准的`getTables` API获取。
	 */
	getTables?: SQLTemplateString;

	/**
	 * 查询某个schema下的所有表或指定表的注释,包括视图、同义词。
	 *
	 * 有些数据库通过标准的jdbc api无法获取到表的注释,需要通过另外的sql查询表注释(表注释是单独存储
	 * 在一个表的),比如oracle、sqlserver2005、oceabase、tidb,其他大部分数据库驱动都实现了
	 * REMARKS,比如:mysql,vertica,gaussdb等。
	 *
	 * 与{@link getTables}不同,此模板是对系统标准API的补充,系统会先通过jdbc标准的`getTables` API获
	 * 取表列表,然后再查询这里定义的SQL获取到表的注释,如果确实标准API不能获取注释才需要配置此模
	 * 版,且如果自定义模版可以很容易实现获取表列表的所有信息,那么建议直接配置{@link getTables},这
	 * 样可以一次查询就获取了表列表了。
	 *
	 * 返回的字段列:
	 *
	 * 1. TABLE_SCHEMA String 可选,SCHEMA
	 * 2. TABLE_NAME String 必须,表名,可能是其他类型,比如视图
	 * 3. TABLE_TYPE String 可选,表类型
	 * 4. TABLE_COMMENT String 必须,注释信息
	 *
	 * 以oracle9i为例如下,注意sql模板中的`[ and TABLE_NAME=?]`部分,表示如果没有第二个参数时SQL就不
	 * 包括方括号的所有内容:
	 *
	 * ```sql
	 * select OWNER AS TABLE_SCHEMA,TABLE_NAME, TABLE_TYPE, TABLE_COMMENT
	 * from all_tab_comments
	 * where OWNER=?[ and TABLE_NAME=?]
	 * ```
	 *
	 * 模板中可用参数与模版{@link qualifiedTableName}参数一致,其中参数`name`和`metaName`表示要查询
	 * 的表的名称,若为空,则表示查询schema下的所有表。
	 *
	 * 默认空,表示通过jdbc标准的`getTables` API获取。
	 */
	getTableComments?: SQLTemplateString;

	/**
	 * 查询某个指定的表的字段列表。
	 *
	 * 当标准的JDBC API接口无法获取到需要的表的字段时,可以定义一个sql语句,自定义字段信息的查询逻
	 * 辑,比如有些数据库的标准API接口无法获取到的注释。
	 *
	 * 当定义了此SQL模板后,系统不会调用jdbc标准的`getColumns` API获取表列表,而是调用此模版获取。
	 *
	 * 返回的字段列:
	 *
	 * 1. TABLE_NAME String 必须,表名,可能是其他类型,比如视图
	 * 2. COLUMN_NAME String 必须,字段名
	 * 3. DATA_TYPE int 必须,字段数据类型,见{@link JavaSQLTypeName},或java.sql.Types。
	 * 4. TYPE_NAME String 必须,字段类型,如`VARCHAR`
	 * 5. COLUMN_COMMENT 或 REMARKS String 可选,表备注
	 * 6. COLUMN_SIZE int 必须,字段长度
	 * 7. DECIMAL_DIGITS int 必须,字段小数位数
	 * 8. NULLABLE int 必须,是否可为空,0不可空、1可空、2不知道
	 * 9. COLUMN_DEF String 必须,字段默认值
	 * 10. IS_AUTOINCREMENT String 必须,`YES`时表示是自增长的
	 *
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 * 
	 * 默认空,表示通过jdbc标准的`getColumns` API获取。
	 */
	getColumns?: SQLTemplateString;

	/**
	 * 查询某个指定的表的主键信息。
	 *
	 * 当标准的JDBC API接口无法获取到需要的表的主键时,可以定义一个sql语句,自定义主键信息的查询逻
	 * 辑。
	 *
	 * 当定义了此SQL模板后,系统不会调用jdbc标准的`getPrimaryKeys` API获主键,而是调用此模版获取。
	 *
	 * 返回的字段列:
	 *
	 * 1. TABLE_CAT String 必须,catalog
	 * 2. TABLE_SCHEM String 必须,schema
	 * 3. TABLE_NAME String 必须,表名
	 * 4. COLUMN_NAME String 必须,字段名
	 * 5. KEY_SEQ int 必须,sequence number within primary key( a value of 1 represents the first
	 *    column of the primary key, a value of 2 would represent the second column within the
	 *    primary key
	 * 6. PK_NAME String 必须,对应的索引名,可能空
	 *
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 *
	 * 默认空,表示通过jdbc标准的`getPrimaryKeys` API获取。
	 */
	getPrimaryKeys?: SQLTemplateString;

	/**
	 * 查询某个指定的表的索引信息。
	 *
	 * 当标准的JDBC API接口无法获取到需要的表的索引时,可以定义一个sql语句,自定义索引信息的查询逻
	 * 辑。
	 *
	 * 当定义了此SQL模板后,系统不会调用jdbc标准的`getIndexInfo` API获索引,而是调用此模版获取。
	 *
	 * 返回的字段列与jdbc标准的`getIndexInfo` API一致:
	 *
	 * 1. TABLE_CAT String 必须,catalog
	 * 2. TABLE_SCHEM String 必须,schema
	 * 3. TABLE_NAME String 必须,表名
	 * 4. NON_UNIQUE boolean 必须,Can index values be non-unique. false when TYPE is
	 *      tableIndexStatistic
	 * 5. INDEX_NAME String 必须,对应的索引名
	 * 6. TYPE int 必须,索引类型,0: tableIndexStatistic, 1: tableIndexClustered, 2:
	 *    tableIndexHashed, 3: tableIndexOther
	 * 7. ORDINAL_POSITION int 必须,多字段索引,返回字段位置序号
	 * 8. COLUMN_NAME String 必须,字段索引,返回字段名
	 * 9. ASC_OR_DESC 必须,返回D表示降序,A表示升序
	 * 10. CARDINALITY
	 * 11. PAGES
	 * 12. FILTER_CONDITION
	 * 13. COLUMN_EXPRESSION 如果是表达式索引,返回此列。jdbc标准的`getIndexInfo`没有此列,需要配置
	 *     sql模板或者脚本模板来实现。
	 *
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 *
	 * 默认空,表示通过jdbc标准的`getIndexInfo` API获取。
	 */
	getIndexInfo?: SQLTemplateString;

	/**
	 * 查询指定数据表的所有字段的注释。
	 *
	 * 系统在获取字段列表时,会调用驱动的`getColumns`,顺便从结果中的`REMARKS`列获取字段注释。但有些
	 * 数据库的驱动没有实现`REMARKS`的读取,比如Oralce,这时需要额外的查询来获取字段注释。如果驱动能
	 * 通过`REMARKS`读取字段注释,也配置了此sql模板,那么sql模板的结果会覆盖从`REMARKS`获取的字段注
	 * 释。
	 * 
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 *
	 * 返回的字段列:
	 *
	 * 1. COLUMN_NAME String 必须,字段名
	 * 2. COLUMN_COMMENT String 必须,注释信息
	 *
	 * 以Oracle为例:
	 *
	 * ```sql
	 * select COLUMN_NAME,COMMENTS as COLUMN_COMMENT  from ALL_COL_COMMENTS Where OWNER=? and TABLE_NAME=?
	 * ```
	 *
	 * 模板接收参数schema、tableName,没有quote,已经按数据库元数据的存储规范进行过大小写统一化处
	 * 理。
	 *
	 * 默认空,表示通过jdbc标准的`getColumns`API获取。
	 */
	getColumnComments?: SQLTemplateString;

	/**
	 * 返回一个查询存储过程列表的sql。
	 *
	 * 当标准的JDBC API接口无法获取到存储过程时,可以定义一个sql语句,去通过此sql查询存储过程。
	 *
	 * 返回的字段列:
	 *
	 * 1. PROCEDURE_CAT String
	 * 2. PROCEDURE_SCHEM String
	 * 3. PROCEDURE_NAME String
	 * 4. REMARKS String 备注
	 * 5. PROCEDURE_TYPE int :
	 *     1. 0: Indicates that it is not known whether the procedure returns a result.
	 *     2. 1: Indicates that the procedure does not return a result.
	 *     3. 2: Indicates that the procedure returns a result.
	 * 6. SPECIFIC_NAME  The name which uniquely identifies this procedure within its schema.
	 *
	 * 模板中可用参数与模版{@link qualifiedTableName}参数一致,其中参数`name`和`metaName`表示要查询
	 * 的存储过程的名称,若为空,则表示查询schema下的所有存储过程。
	 * 
	 * 默认空,表示通过jdbc标准的API获取。
	 */
	getProcedures?: SQLTemplateString;

	/**
	 * 返回一个查询存储过程的DDL的sql,字段列:
	 *
	 * 1. TEXT 
	 *
	 * 模板中可用参数:
	 *
	 * 1. object 目标存储过程名,见{@link SQLTemplateParam_Identifier}。
	 * 2. 其他参数与模版{@link qualifiedTableName}参数一致。
	 */
	getProcedureDDL?: SQLTemplateString;

	/**
	 * 返回一个查询存储过程参数的sql,
	 *
	 * 当定义了此SQL模板后,系统不会调用jdbc标准的`getProcedureParams` API获取表列表,而是调用此模版获取,字段列:
	 *
	 * 1. PROCEDURE_CAT String 必须,Catalog
	 * 2. PROCEDURE_SCHEM 必须 String => 过程架构(可以是 null)
	 * 3. PROCEDURE_NAME 必须 String => 过程名称
	 * 4. COLUMN_NAME 必须 String => 列/参数名称
	 * 5. COLUMN_TYPE 必须 Shot => 列/参数的类型:
	 *      procedureColumnUnknown - 不确定
	 *      procedureColumnIn - IN 参数
	 *      procedureColumnInOut - INOUT 参数
	 *      procedureColumnOut - OUT 参数
	 *      procedureColumnReturn - 过程返回值
	 *      procedureColumnResult - 结果列 ResultSet
	 * 6. DATA_TYPE 必须 int => java.sql.types
	 * 7. TYPE_NAME 必须 String => SQL 类型名称,对于 UDT 类型,类型名称是完全限定的
	 *
	 * 模板中可用参数类似{@link getProcedureDDL}.
	 */
	getProcedureParams?: SQLTemplateString;

	/**
	 * 返回一个表(不包括视图)的定义语句,通常应该是`CREATE TABLE ....`的一段语句。
	 *
	 * 1. 如果配置了模板,就用模板的结果当作ddl。
	 * 2. 如果返回了多列那么自动找到内容,以Create开头的哪个列(比如mysql),否则默认将第一列的值当
	 *    作ddl。
	 * 3. 实在不行可以配置脚本模板。
	 * 4. 如果没有配置此模板,则用{@link createTable}模板返回建表的ddl。
	 *
	 * 模板中可用参数:
	 *
	 * 1. table 目标表名,见{@link SQLTemplateParam_Identifier}。
	 * 2. 其他参数与模版{@link qualifiedTableName}参数一致。
	 * 3. schemaPattern schema的匹配模式,会将metaSchema中的特殊字符,统一变为下划线,当
	 *    getTables,getColumns用于脚本模板时,调用同名驱动方法传递的匹配参数。对于一些特殊字符的匹配
	 *    规则,不同数据库有不同的处理逻辑,统一转换为下划线匹配,然后对查询结果进行一次精确匹配。
	 * 4. tableNamePattern 表名的匹配模式,同schemaPattern。
	 *
	 * 举例:
	 * ```sql
	 * --mysql, 第二列返回建表语句,列名为`Create Table`。
	 * ftl:SHOW CREATE TABLE ${table.fullName}
	 *
	 * --oracle,第一列返回建表语句。
	 * ftl:SELECT DBMS_METADATA.GET_DDL('TABLE','${dialect.escapeSQL(metaSchema.name)}','${dialect.escapeSQL(metaName)}') FROM DUAL
	 * ```
	 */
	getTableDDL?: SQLTemplateString;

	/**
	 * 返回一个视图的定义语句,,通常应该是`CREATE VIEW ....`的一段语句。
	 * 说明参考{@link getTableDDL}。
	 *
	 * 模板参数与模版{@link getTableDDL}一致。
	 *
	 */
	getViewDDL?: SQLTemplateString;

	/**
	 * 返回一个同义词的定义语句,通常应该是`CREATE Synonym ....`的一段语句。
	 *
	 * 模板中可用参数类似{@link getProcedureDDL}.
	 */
	getSynonymDDL?: SQLTemplateString;

	/**
	 * 返回一个用于查询同义词的sql,sql中选取的字段有:
	 * 
	 * 1. SYNONYM_SCHEMA String 同义词的schema
	 * 2. SYNONYM_NAME String 同义词的名称
	 * 3. TABLE_OWNER String 表的所有者
	 * 4. TABLE_NAME String  表的名称
	 * 
	 * 注意返回的字段顺序和字段名称必须与上述说明一致。
	 * 
	 * 模板中可用参数类似{@link getProcedureDDL}.
	 */
	getSynonymMeta?: SQLTemplateString;

	/**
	 * 删除一个表。
	 *
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 */
	dropTable?: SQLTemplateString;

	/**
	 * 删除一个临时表。
	 * 
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 */
	dropTempTable?: SQLTemplateString;

	/**
	 * 删除一个临时表。
	 * 
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 */
	dropTempTableIfExists?: SQLTemplateString;

	/**
	 * 删除一个视图表。
	 * 
	 * 模板中可用参数类似{@link getViewDDL}.
	 */
	dropView?: SQLTemplateString;

	/**
	 * 删除一个物化视图表。
	 * 
	 * 模板中可用参数类似{@link getViewDDL}.
	 */
	dropMaterializedView?: SQLTemplateString;

	/**
	 * 删除一个表(如果存在的话)。
	 *
	 * 有些数据库不支持if exists语法,比如oracle,可以不配置这个模版,系统会自动使用
	 * {@link dropTable}模版模拟if exists功能(并自动抓住{@link DbErrorCodes.ERR_OBJECT_NOTFOUND}错
	 * 误,需要配置好这个错误编码的映射)。
	 *
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 */
	dropTableIfExists?: SQLTemplateString;

	/**
	 * 删除一个视图表(如果存在的话)。
	 *
	 * 有些数据库不支持if exists语法,比如oracle,可以不配置这个模版,系统会自动使用{@link dropView}
	 * 模版模拟if exists功能(并自动抓住{@link DbErrorCodes.ERR_OBJECT_NOTFOUND}错误,需要配置好这个
	 * 错误编码的映射)。
	 *
	 * 模板中可用参数类似{@link getViewDDL}.
	 */
	dropViewIfExists?: SQLTemplateString;

	/**
	 * 删除一个物化视图表(如果存在的话)。
	 *
	 * 有些数据库不支持if exists语法,比如oracle,可以不配置这个模版,系统会自动使用
	 * {@link dropMaterializedView}模版模拟if exists功能(并自动抓住
	 * {@link DbErrorCodes.ERR_OBJECT_NOTFOUND}错误,需要配置好这个错误编码的映射)。
	 *
	 * 模板中可用参数类似{@link getViewDDL}.
	 */
	dropMaterializedViewIfExists?: SQLTemplateString;

	/**
	 * 截断一个表。清空其所有数据且不可回滚。
	 * 
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 */
	truncateTable?: SQLTemplateString;

	/**
	 * 截断一个表。清空其所有数据且不可回滚。
	 *
	 * 同时重置表里的自增长字段序列。
	 *
	 * mysql下执行truancate语句会自动重置自增长字段序列,pg数据库则需要执行`TRUNCATE TABLE
	 * your_table RESTART IDENTITY;` 对于sqlserver和oracle则需要额外执行一个SQL语句将自增长序列重
	 * 置。
	 *
	 * sqlserver:
	 *
	 * TRUNCATE TABLE your_table;  -- 删除数据
	 * DBCC CHECKIDENT ('your_table', RESEED, 1);  -- 重置自增长序列
	 *
	 * @see https://stackoverflow.com/questions/472578/dbcc-checkident-sets-identity-to-0
	 *
	 * oracle:
	 *
	 * oracle12c之前的版本使用`SEQUENCE`来实现自增长序列,之后的版本引入了`IDENTITY `,创建表时声明
	 * 后oralce会自己创建出一个序列,两种方式在重置序列时都需要先查询出序列ID,可能需要配合序列查询模板来使用。
	 * 
	 * @see https://stackoverflow.com/questions/51470/how-do-i-reset-a-sequence-in-oracle
	 * 
	 * 接受`schema`和`table`两个参数。
	 *
	 */
	truncateTableAndRestartSequence?: SQLTemplateString;

	/**
	 * 清空表语句。
	 *
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 *
	 * 如果不配置,那么默认将使用标准的 `delete from` 进行删除。
	 *
	 * 对于某些数据库,如Doris数据库就不支持不带where条件的delete语句。需要配置truncate进行替代。
	 * https://jira.succez.com/browse/BI-45496
	 */
	deleteAllFromTable?: SQLTemplateString;

	/**
	 * 检查一个表是否有数据(否则就是空表)的sql。
	 *
	 * sql查询的结果必须在第一个字段的第一行中用Number字段返回是否存在数据,1表示存在,0或空表示不存
	 * 在。
	 *
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 *
	 * 如果不配置,那么默认将使用标准的 `select` 进行判断。
	 */
	existsTableData?: SQLTemplateString;

	/**
	 * 返回数据表更名的sql模板。
	 * 
	 * 将指定schema下的表,更名为另一个表名,新的表也在指定的schema下。
	 * 
	 * 接收三个参数,分别为:
	 * 
	 * 1. oldTable 目标表名,见{@link SQLTemplateParam_Identifier}。
	 * 2. newTable 新表名,见{@link SQLTemplateParam_Identifier}。
	 * 3. schema 对象所在的schema,已按需quote,为空时表示是当前schema或者db不支持schema概念(如
	 *    mysql)。
	 * 4. catalog 对象所在的catalog,已按需quote,为空时表示是当前catalog或者db不支持catalog概念(如
	 *    oracle)。
	 * 5. originalName 原表名(已按需quote,仅名称,不含schema、catalog)。
	 * 6. newName 新表名(已按需quote,仅名称,不含schema、catalog)。
	 * 
	 * 参数都需要处理好特殊字符转义。比如:表名是关键字:rename table test."SELECT" to test.SELECT1
	 * 
	 * 举例:
	 * 
	 * ```sql
	 * --mysql,新表名必须带上schema,如果不带,会被更名,并移动到当前默认schema下。
	 * RENAME TABLE ? TO ?
	 * --oracle,新表名不能带schema,语法不允许。ORA-01765: 不允许指定表的所有者名。
	 * RENAME TABLE ? TO ?
	 * ```
	 */
	renameTable?: SQLTemplateString;

	/**
	 * 设置表注释的模板。
	 *
	 * {@link alterTable}也可以修改表的注释,主要用于整个表结构的调整。此模板更加轻量,用于只需要修
	 * 改表注释的场景。如果没有配置此模板,将会调用{@link alterTable}模板执行。
	 *
	 * 接收参数:
	 *
	 * 1. table 目标表名,见{@link SQLTemplateParam_Identifier}。
	 * 2. comment 目标表注释,可以为null。
	 *
	 * 举例:
	 *
	 * ```sql
	 * --mysql
	 * ALTER TABLE ?1 COMMENT '?2'
	 * ```
	 */
	setTableComment?: SQLTemplateString;

	/**
	 * 启用表的指定的约束。
	 *
	 * 通常用于在批量写入数据前先禁用约束以便提升插入数据的性能。目前已知的是pg支持启用/禁用约束。对
	 * 于不支持的db系统会自动删除约束,并在结束时再恢复约束。
	 *
	 * 接收参数:
	 *
	 * 1. table 目标表名,见{@link SQLTemplateParam_Identifier}。
	 * 2. constraintName 要禁用或启用的约束的名称。
	 */
	enableTableConstraint?: SQLTemplateString;

	/**
	 * 禁用表的指定的约束。类似{@link enableTableConstraint}
	 */
	disableTableConstraint?: SQLTemplateString;

	/**
	 * ?1 is null desc, ?1 desc
	 *
	 * sql 中需要一个参数: 排序字段名
	 */
	nullFirstDescOrder?: SQLTemplateString;

	/**
	 * 返回一个用于查询触发器信息的sql,sql中选取的字段必须要有下面这几个字段:
	 *
	 * 1. TRIGGER_NAME String 触发器的名称
	 * 2. TRIGGER_BODY String 触发器的定义
	 * 3. TABLE_NAME String  表的名称
	 *
	 * 模板中可用参数与模版{@link getTableDDL}参数一致。
	 *
	 * 如mysql是:
	 *
	 * select TRIGGER_NAME,ACTION_STATEMENT TRIGGER_BODY,EVENT_OBJECT_TABLE
	 * TABLE_NAME,TRIGGER_SCHEMA,EVENT_OBJECT_SCHEMA from information_schema.TRIGGERS Where
	 * EVENT_OBJECT_SCHEMA='?1' and EVENT_OBJECT_TABLE='?2'
	 */
	getTableTriggers?: SQLTemplateString;

	/**
	 * 返回一个用于查询触发器信息的sql,sql中选取的字段有:
	 * 
	 * 1. RIGGER_NAME String 触发器的名称
	 * 1. RIGGER_BODY String 触发器的定义
	 * 1. ABLE_NAME String  表的名称
	 * 
	 * 模板中可用参数类似{@link getProcedureDDL}。
	 * 
	 * 注意返回的字段顺序和字段名称必须与上述说明一致,此模板接收两个参数schema、tbname,并未转义,也并未用单引号括起来。
	 */
	getTriggerMeta?: SQLTemplateString;

	/**
	 * 查询一个表的占用的存储空间大小,sql查询结果应该是一行一列,返回指定表的占用的存储空间大小,单
	 * 位byte。
	 *
	 * 模板中可用参数类似{@link getTableDDL}。
	 *
	 * 比如mysql是:
	 *
	 * select data_length as TABLE_SPACE from information_schema.tables where TABLE_SCHEMA=? and
	 * TABLE_NAME=?
	 */
	getTableStorageSpace?: SQLTemplateString;

	/**
	 * oracle早期版本(12g以前)分页需要使用rownum,db2早期版本也类似。
	 * 
	 * 此属性配置rownum的字段名称。
	 */
	rownum?: SQLTemplateString;

	/**
	 * 设置一个查询语句,每次检查连接有效性的时候将执行这个查询语句,以判断连接是否有效。
	 *
	 * 1. 这里配置的SQL必须总是能成功执行,如果配置错误(比如配置了一个总是执行错误的sql,查询一个不
	 *    存在的表),将会导致连接池无法获取到连接。
	 * 2. 此属性设置的是连接器默认的检查连接有效性SQL,用户在配置数据库连接时还可以通过设置
	 *    {@link JdbcConfigInfo.testQuery}来设置新的检查语句。
	 * 3. 检查连接有效性是在连接池启用了{@link JdbcConfigInfo.testConnectionOnCheckout}才会真正的执
	 *    行检查。
	 *
	 * 默认=null,如果没有配置,则执行连接器的默认测试语句,如果也没有,那么执行jdbc标准的
	 * api{@link Connection#isValid(int)}。
	 */
	testQuery?: SQLTemplateString;

	/**
	 * 返回insert into 语法的语句。
	 *
	 * 此模版处理普通的insert into语句,包括insert into select语句,但不包括
	 * {@link insertOnDuplicate}。
	 *
	 * 模板中可用参数:
	 *
	 * 1. tableName 目标表,见{@link SQLTemplateParam_Identifier}。
	 * 2. insertFields insert写入的字段名列表,见{@link SQLTemplateParam_ColumnNames}。
	 * 3. insertValues insertFields字段列表对应的值,可能为空,表示使用`selectStatement`插入数据,见
	 *    {@link SQLTemplateParam_ColumnValues}。
	 * 4. selectStatement 查询sql,sql查询出来的字段和insertFields参数中指定的字段一一对应。
	 * 5. ignore 是否忽略主键冲突,默认false。
	 * 6. append 是否使用append模式写入,默认为false。为true时,insert数据会直接加到表的最后面,而不
	 *    会在表的空闲块中插入数据,使用append=true在批量插入数据时会提升数据插入的速度。
	 * 7. comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出
	 *       到合适的地方,在SQL开头或结尾都可以。
	 * 8. logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
	 * 9. parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * 10. dialect {@link DbDialect}。
	 *
	 * 示例SQL:
	 *
	 * ```
	 * INSERT INTO t1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; -- mysql
	 *
	 * INSERT INTO table2 (column1, column2, column3, ...) 
	 * SELECT column1, column2, column3, ...
	 * FROM table1
	 * WHERE condition;
	 * ```
	 */
	insertIntoTable?: SQLTemplateString;

	/**
	 * 返回upsert 支持 on duplicate key 语法的语句。
	 *
	 * 用于保存一行数据,根据主键判断,不存在insert,存在则update,需要配置
	 * {@link DbSupportsConf.supportsUpsert}为true时此模版才生效。
	 *
	 * 有些数据库不支持upsert语句,可以考虑使用merge语句替代,比如oracle,但需要注意数据库本身对
	 * merge语句的使用推荐情况,是否存在性能问题、是否merge语句只是适合批量数据的merge、是否推荐大并
	 * 发的单条数据的merge语句操作,如果有性能问题,可以配置{@link DbSupportsConf.supportsUpsert}为
	 * false,这样系统会自动使用一条insert+一条update语句模拟upsert的效果。
	 *
	 * 模板中可用参数:
	 *
	 * 1. table 目标表,见{@link SQLTemplateParam_Identifier}。
	 * 2. insertFields insert写入的字段名列表,见{@link SQLTemplateParam_ColumnNames}。
	 * 3. insertValues insertFields字段列表对应的值,见{@link SQLTemplateParam_ColumnValues}。
	 * 4. uniqueKeys 合并所依据的字段列表。见{@link SQLTemplateParam_ColumnNames}。
	 * 5. updateFields 当数据已存在时执行的更新,见{@link SQLTemplateParam_ColumnValuePairs}。
	 * 6. comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出
	 *       到合适的地方,在SQL开头或结尾都可以。
	 * 7. logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
	 * 8. parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * 9. dialect {@link DbDialect}。
	 *
	 * 示例SQL:
	 *
	 * ```
	 * INSERT INTO t1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; -- mysql
	 * ```
	 */
	insertOnDuplicate?: SQLTemplateString;

	/**
	 * 用于构造merge into语句。
	 *
	 * 此模板支持构造一个将表或SQL查询结果插入或更新到目标表的merge into(存在参数`usingTable`或
	 * `usingSql`),也支持构造一个将特定values插入或更新到目标表的merge Into语句。
	 *
	 * `merge into`语句较复杂,此模板配置应该使用Freemarker文件独立配置,并在这里指定文件路径,如
	 * `templates/merge.ftl`,有些数据库不支持merge into,可以配置类似功能的insert into语句。
	 *
	 * Freemarker模板规范,见{@link SQLTemplateString}中的相关说明。
	 *
	 * 模板中可用参数:
	 *
	 * - table 目标表,见{@link SQLTemplateParam_Identifier}。
	 * - tableAlias 目标表的别名。
	 * - insertFields 插入的字段名列表,不为空。见{@link SQLTemplateParam_ColumnNames}。
	 * - insertValues insertFields字段列表对应的值,见{@link SQLTemplateParam_ColumnValues}。
	 * - updateFields 当数据已存在时执行的更新,见{@link SQLTemplateParam_ColumnValuePairs},如果不
	 *       存在此参数,表示忽略已存在的数据。 
	 * - usingTable 数据来源表表名,(见{@link SQLTemplateParam_Identifier},类似参数tableName),此
	 *   参数存在,表示需要将此表的数据合并到目标表,要求表中的字段名与目标表保持一致。别名通过usingTable.alias获取。
	 * - usingFilter 当数据来源表是一个数据表时,可以指定一个此数据表的过滤条件。
	 * - usingSql 执行merge的数据来源sql,当usingTable为空,取这个值。详见:{@link SQLTemplateParam_SQLElement},别名通过usingSql.alias获取。
	 * - on 目的表和来源表或者sql的关联关系,大多数时候是主键的关联。
	 * - uniqueKeys 合并所依据的字段列表。
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出
	 *       到合适的地方,在SQL开头或结尾都可以。
	 * - logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
	 * - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * - dialect {@link DbDialect}。
	 *
	 * 如果不配置,那么默认将使用标准的merge into语句。
	 */
	mergeInto?: SQLTemplateString;

	/**
	 * 用于构造`CREATE TABLE`语句。
	 *
	 * 此模板也支持create table xxx like yyy和create table xxx as select ...语句,但如果定义了
	 * {@link createTableAsSelect}或{@link createTableLike}那么优先使用它们。
	 *
	 * `CREATE TABLE`语句较复杂,此模板配置应该使用Freemarker文件独立配置,并在这里指定文件路径,如
	 * `templates/create-table.ftl`。
	 *
	 * Freemarker模板规范,见{@link SQLTemplateString}中的相关说明。
	 *
	 * 模板中可用参数:
	 *
	 * - table 目标表,见{@link SQLTemplateParam_Identifier}。
	 * - createIfNotExists 为`IF NOT EXISTS`,表示当表不存在时执行创建,表存在时什么都不做。
	 * - selectStatement 查询sql,存在此参数就表示要构造`create table xxx as select ...`语句,可能为
	 *       null,为空表示普通的创建语句,不为空表示根据查询结果创建表。
	 * - likeTableName 要复制表结构的源表,已按需quote,存在此参数就表示要构造`create table xxx like
	 *       ...`语句,此参数类似tableName参数是一个完整的表名。
	 * - tableComment 表注释,为null表示没有,见{@link SQLTemplateParam_Comment}
	 * - tableType 表类型,TABLE、LOCAL_TEMPTABLE、GLOBAL_TEMPTABLE
	 * - columns 字段列表,是一个数组对象,每个元素都是一个字段,字段有如下属性:
	 *     - name 字段名,见{@link SQLTemplateParam_Identifier}
	 *     - comment 字段描述,为null表示没有,见{@link SQLTemplateParam_Comment}
	 *     - length 字段长度
	 *          - 对于字符型字段,此长度大于0。
	 *          - 对于整形,如果长度=0,那么使用数据库对应 `int`类型。
	 *          - 对于浮点,如果长度=0,表示不知道精度,使用数据库默认的double类型;如果长度>0,scale=0,则会定义为整形。
	 *          - 其他字段类型可以暂时不支持长度设置,忽略此属性。
	 *     - scale 小数位数,仅对浮点型有效,且如果小数位数大于0,那么`length`也必须大于0且大于小数
	 *           位数。
	 *     - dbType 字段类型,如`VARCHAR`,此值是系统根据一定的规则从连接器的
	 *           {@link DbVersionCapabilities.dataTypes}配置找到的合适的数据库字段。
	 *     - typeDeclaration  字段类型定义(只带长度),如`VARCHAR(12)`
	 *     - autoInc 为true表示自增长
	 *     - nullable 为true表示可为空
	 *     - unsigned 为true表示无符号
	 *     - defaultValue 默认值,是一个单引号括起来的字符串或者是表达式
	 *     - primaryKey 为true表示是主键
	 * - primaryKey 主键字段设置,是一个索引对象,可访问的属性和下面的indexes的索引对象一致。
	 * - indexes 索引列表,是一个数组对象,每个元素都是一个索引,索引有如下属性:
	 *     - name 推荐索引名,已按需quote,可能空,这是一个建议的名称,不强制使用,如果元数据信息是
	 *            从别的库读取出来的,那么这个name可能是索引在源库中的索引名,不一定能用到当前库中,
	 *            不同的数据库对索引名要求不同,大部分数据库要求索引名在schema内唯一,不能和其他对象
	 *            包括表名冲突(如pg),实现者创建表时可根据数据库的需要用其他的名称。
	 *     - uname 强制索引名,已按需quote,可能空,当此属性存在时创建表应直接使用这里指定的索引名,
	 *            调用者自己保障索引名的合法性。
	 *     - aname 自动索引名,已按需quote,不为空,由于索引名在不同的数据库上要求不同,但是其实索引
	 *            名并不十分重要,当上面指定的name不能使用时可以使用此处的aname,aname是系统自动产生
	 *            的,考虑了表名、字段等,不会和其他对象名称冲突。
	 *     - unique 是否唯一
	 *     - cluster 是否是聚集索引
	 *     - enable 是否启用了
	 *     - parts 索引的字段数组
	 *         - name 字段名,已按需quote
	 *         - sort 排序设置,空(默认)、DESC或ASC
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出
	 *       到合适的地方,在SQL开头或结尾都可以。
	 * - dialect {@link DbDialect}。
	 * - xxx 表的更多属性
	 */
	createTable?: SQLTemplateString;

	/**
	 * 用于构造`ALTER TABLE`语句。
	 *
	 * `ALTER TABLE`语句较复杂,此模板配置应该使用Freemarker文件独立配置,并在这里指定文件路径,如
	 * `templates/alter-table.ftl`。
	 *
	 * 模板规范:
	 *
	 * 1. Freemarker模板规范,见{@link SQLTemplateString}中的相关说明。
	 * 2. 模板应该只生成需要执行的SQL,做到增量的高效的修改表结构。
	 *
	 * 模板中可用参数:
	 *
	 * - table 目标表,见{@link SQLTemplateParam_Identifier}。
	 * - tableType 表类型,TABLE、LOCAL_TEMPTABLE、GLOBAL_TEMPTABLE
	 * - originAttributes 修改前的表属性,包括表注释,存储引擎,分布列等,表的更多属性,详
	 *   见:{@link TableMetaData}
	 * - alterAttributes 修改后的数据表属性,有修改才有相关值。
	 * - attributes 修改后的完整的表属性,结构同`originAttributes`。
	 * - newColumns 新增的字段列表,是一个数组对象,每个元素都是一个字段,字段属性与模板
	 *    {@link createTable}中的字段对象一致。
	 * - dropColumns 删除的字段列表,是一个字段名数组,字段名已按需quote。
	 * - alterColumns 修改的字段列表,是一个字段的修改信息的对象数组,有如下属性:
	 *     - alterAttributes 有修改的字段属性,是一个map,key是属性名,value是修改的值,与
	 *       {@link createTable}中的字段对象一致。
	 *         - 修改了长度,那么就有{length:100}。
	 *         - 修改了类型:{typeDeclaration:varchar(50),dbType:varchar},同创建表typeDeclaration带
	 *           类型和长度。
	 *         - 字段更名:{name:新字段名,originalName:原始字段名}。
	 *         - 修改字段注释:{comment: "新注释"} 
	 *     - originAttributes 修改前的字段的属性,与{@link createTable}中的字段对象一致。
	 *     - attributes 修改后的完整的字段属性,与originAttributes结构一致。
	 * - dropPrimaryKey 是否删除目标表主键,此属性总是存在。
	 * - originPrimaryKey 目标表修改前主键,主键有修改,才会有此属性。此对象与{@link createTable}中
	 *       的索引对象可以访问的属性一致。主要用于删除主键,有的数据库(比如sqlserver,vertica)删除
	 *       主键需要主键的约束名,originPrimaryKey.name返回约束名。
	 * - primaryKey 此属性存在,表示主键有修改,此对象与索引对象可以访问的属性一致。
	 * - newIndexes 新增的索引,是一个数组对象,每个元素都是一个索引,可访问的属性与
	 *    {@link createTable}中的索引对象一致。
	 * - dropIndexes 要删除的索引列表,是一个数组对象,每个元素是要删除的索引的名称
	 * - storageType 模型的存储方式,ROW:行存储,COLUMN:列存储
	 * - distributeType 分布式数据库模型的分布方式,REPLICATION:复制表,HASH:散列分布式
	 * - distributeColumn 分布式存储时的分布列
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置
	 *       时可以将其输出到合适的地方,在SQL开头或结尾都可以。
	 * - dialect {@link DbDialect}。
	 */
	alterTable?: SQLTemplateString;

	/**
	 * 用于创建视图的语句(包括物化视图)。
	 *
	 * `CREATE VIEW`语句较复杂,此模板配置应该使用Freemarker文件独立配置,并在这里指定文件路径,如
	 * `templates/create-view.ftl`。
	 *
	 * 模板的规范见{@link createTable},模板中可用参数也与其类似,有如下不同之处:
	 *
	 * - selectStatement ?3 参数总是存在。
	 * - tableType 视图类型,可能为 VIEW、MATERIALIZED_VIEW。
	 * - createOrReplace ?2 多了这个参数,为`OR REPLACE`表示如果视图存在就重新创建它。
	 * 
	 * 当然也可以使用参数模板配置:`CREATE[ ?2] VIEW ?1 AS ?3`。
	 */
	createView?: SQLTemplateString;

	/**
	 * 生成单表删除语句。
	 * 
	 * 注意:单表删除使用此模板,关联删除使用{@link deleteJoin}。
	 * 
	 * 模板规范:
	 *
	 * 1. Freemarker模板规范,见{@link SQLTemplateString}中的相关说明。
	 *
	 * 模板中可用参数:
	 *
	 * - table 目标表,见{@link SQLTemplateParam_Identifier}。
	 * - filter 过滤条件,即sql中的where段落,见{@link SQLTemplateParam_SQLElement}。
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出
	 *       到合适的地方,在SQL开头或结尾都可以。
	 * - logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
	 * - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * - dialect {@link DbDialect}。
	 * 
	 */
	deleteTable?: SQLTemplateString;

	/**
	 * 生成关联删除语句。
	 * 
	 * 注意:普通的删除语句(没有join其他表的)不会使用此模版!
	 *
	 * 模板规范:
	 *
	 * 1. Freemarker模板规范,见{@link SQLTemplateString}中的相关说明。
	 *
	 * 模板中可用参数:
	 *
	 * - table 目标表,见{@link SQLTemplateParam_Identifier}。
	 * - joinTables 关联的表信息,是一个数组,每个元素代表一个要关联的表,有如下信息:
	 *   	- table join的表或者子sql,见{@link SQLTemplateParam_SQLElement}。别名通过table.alias获取。
	 *   	- condition 关联条件,见{@link SQLTemplateParam_SQLElement}。
	 * - filter 过滤条件,即sql中的where段落,见{@link SQLTemplateParam_SQLElement}。
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出
	 *       到合适的地方,在SQL开头或结尾都可以。
	 * - logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
	 * - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * - dialect {@link DbDialect}。
	 */
	deleteJoin?: SQLTemplateString;

	/**
	 * 生成单表更新语句。
	 * 
	 * 注意:单表更新使用此模板,关联更新使用{@link updateJoin}。
	 * 
	 * 模板规范:
	 * 
	 * 1. Freemarker模板规范,见{@link SQLTemplateString}中的相关说明。
	 * 
	 * 模板可用参数:
	 * 
	 * - table 目标表,见{@link SQLTemplateParam_Identifier}。
	 * - updateFields 要更新的字段,见{@link SQLTemplateParam_ColumnValuePairs}。
	 * - filter 过滤条件,即sql中的where段落,见{@link SQLTemplateParam_SQLElement}。
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出
	 *       到合适的地方,在SQL开头或结尾都可以。
	 * - logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
	 * - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * - dialect {@link DbDialect}。
	 */
	updateTable?: SQLTemplateString;

	/**
	 * 生成关联更新语句。
	 * 
	 * 注意:普通的更新语句(没有join其他表的)不会使用此模版!
	 *
	 * 模板规范:
	 *
	 * 1. Freemarker模板规范,见{@link SQLTemplateString}中的相关说明。
	 *
	 * 模板中可用参数:
	 *
	 * - table 目标表,见{@link SQLTemplateParam_Identifier}。
	 * - updateFields 要更新的字段,见{@link SQLTemplateParam_ColumnValuePairs}。
	 * - joinTables 关联的表信息,是一个数组,每个元素代表一个要关联的表,有如下信息:
	 *   	- table join的表或者子sql,见{@link SQLTemplateParam_SQLElement}。别名通过table.alias获取。
	 *   	- condition 关联条件,见{@link SQLTemplateParam_SQLElement}。
	 * - filter 过滤条件,即sql中的where段落,见{@link SQLTemplateParam_SQLElement}。
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出
	 *       到合适的地方,在SQL开头或结尾都可以。
	 * - logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
	 * - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * - dialect {@link DbDialect}。
	 * 
	 */
	updateJoin?: SQLTemplateString;

	/**
	 * 生成查询语句。
	 *
	 * 注意:此为查询的的模板,除了union的相关语法,其他包括join、orderBy、having、groupBy、分页都需
	 * 要在这里配置。
	 *
	 * 模板规范:
	 *
	 * 1. Freemarker模板规范,见{@link SQLTemplateString}中的相关说明。
	 *
	 * 模板中可用参数:
	 *
	 * - withTables with语句中的子查询,为空表示没有,是一个{@link SQLTemplateParam_SQLElement}数组。
	 * - distinct 是否去重。
	 * - selectFields 要查询的字段列表,是一个{@link SQLTemplateParam_SQLElement}数组。
	 * - mainTable 要查询的表或子查询,见{@link SQLTemplateParam_SQLElement}。
	 * - joinTables 关联的表信息,是一个数组,每个元素代表一个要关联的表,有如下信息:
	 *   	- table join的表或子查询,见{@link SQLTemplateParam_SQLElement}。别名通过table.alias获取。
	 *     	- joinType 关联方式,left、inner、right
	 *     	- condition 关联条件,见{@link SQLTemplateParam_SQLElement}。
	 * - filter 过滤条件,即sql中的where段落,见{@link SQLTemplateParam_SQLElement}。
	 * - groupBy 分组字段列表。是一个{@link SQLTemplateParam_SQLElement}数组,可能包含字段、表达式或
	 *       者是已有的选择字段的一个序号。
	 * - having hvaing条件,sql中的having段落,见{@link SQLTemplateParam_SQLElement}。
	 * - orderBy 排序方式,是一个{@link SQLTemplateParam_SQLElement}数组,可能包含字段、表达式或者已有的选择字段的序号。
	 *   	- orderType 属性可以获取排序类型(ASC/DESC)。
	 *   	- nullsOrder 获取null的排序规则(FIRST/LAST)。
	 * - limit 返回的最大行数,见{@link SQLTemplateParam_SQLElement}。可是具体的值,也可能是参数。
	 * - offset 跳过行数,见{@link SQLTemplateParam_SQLElement}。可能是具体值,也可能是参数。 
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出到合适的地
	 *       方,在SQL开头或结尾都可以。
	 * - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * - dialect {@link DbDialect}。
	 */
	selectTable?: SQLTemplateString;

	/**
	 * 生成union查询语句。
	 *
	 * 注意:普通的查询语句(没有union其他查询的)不会使用此模版!
	 *
	 * 模板中可用参数:
	 * - withTables with语句中的子查询,为空表示没有,是一个{@link SQLTemplateParam_SQLElement}数组。
	 * - unionType 全局的union方式: union、unionAll、minus、intersect
	 * - sqls union的子sql. {@link SQLTemplateParam_SQLElement}。
	 *   	- unionType 每个子sql的unionType,如果没有设置,则取全局unionType。 
	 * - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置时可以将其输出到合适的地
	 *       方,在SQL开头或结尾都可以。
	 * - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
	 * - dialect {@link DbDialect}。
	 */
	selectUnion?: SQLTemplateString;

}

/**
 * 这里配置db的一些兼容性特性,这里每个选项都是描述的db支持什么、db能做到什么,而不是描述是否启用系
 * 统的某个功能,系统会自动根据db能做到什么、能支持什么,自动选择应该怎么调用db的功能。
 */
declare interface DbSupportsConf {
	/**
	 * 是否支持数据库本地的、高性能的数据批量读写方式。
	 *
	 * 当配置true时,系统在读写数据时会尝试使用{@link DbConnectorExt.createDbTableBulkSource}。
	 *
	 * 默认false
	 */
	supportsBulkLoad?: boolean;
	/**
	 * 是否通用的基于jdbc的insert/update语句的数据导入方式。
	 *
	 * 支持时
	 *
	 * 默认取{@link supportsInsert}和{@link supportsUpdate}。
	 */
	supportsCommonLoad?: boolean;
	/**
	 * 是否支持Oltp事务型应用。
	 * 
	 * 对于一些分析型的数据库通常返回false,比如一些大数据数据库,Impala等。
	 * 
	 * 默认true
	 */
	supportsOLTP?: boolean;

	/**
	 * 是否支持对lob字段进行聚集,比如max等。
	 *
	 * 目前已知: mysql,vertcia,sqlserver 可以, oracle,postgresql,达梦 不可以
	 *
	 * 默认true
	 */
	supportsAggregationForLob?: boolean;

	/**
	 * 表是否支持列存储
	 * 
	 * 默认为false
	 */
	supportsColumnStore?: boolean;

	/**
	 * 表是否支持行存储
	 * 
	 * 默认为true,对于纯列式数据库,需要配置为false
	 */
	supportsRowStore?: boolean;

	/**
	 * 是否是分布式数据库,比如高斯、vertica。
	 * 
	 * 分布式数据库才能进一步的设置更多分布式属性。
	 * 
	 * 默认false
	 */
	supportsDistributed?: boolean;

	/**
	 * 是否支持分布列。
	 * 
	 * 支持分布列的数据库为分布式存储的数据库,用Hash(分布列)来决定数据写入到哪个数据节点。
	 * 
	 * 默认false
	 */
	supportsDistributionColumn?: boolean;

	/**
	 * 是否支持分布复制表(Replication),将表中的全量数据在集群的每一个实例上保留一份。
	 *
	 * 主要适用于数据量较小的表。这种存储方式的优点是每个DN上都有此表的全量数据,在Join操作中可以避
	 * 免数据重分布操作,从而减小网络开销。缺点是每个DN都保留了表的完整数据,造成数据的冗余。一般情
	 * 况下只有较小的维度表才会定义为Replication表。
	 * 
	 * 启用这个属性后,在模型的属性设置中可以进行选用,比如把某些小维表设置成复制表模式。
	 * 
	 * 默认false
	 */
	supportsDistributionReplication?: boolean;

	/**
	 * 是否支持full join。
	 * 
	 * 无默认值,默认取jdbc驱动提供的值,若手动配置了,则就用配置的。通常不需要配置。
	 */
	supportsFullOuterJoins?: boolean;

	/**
	 * 是否支持with语法。
	 * 
	 * 使用with语法,某些情况下,会提高查询效率,比如oracle。
	 * 首先需要数据库本身支持。
	 * 
	 * 默认true
	 */
	supportsWith?: boolean;

	/**
	 * 是否使用union实现fulljoin。
	 * 
	 * 默认false
	 */
	supportsUnionForFullJoin?: boolean;

	/**
	 * 是否支持sql99标准
	 * 
	 * 默认为jdbc标准`metaData::getSQLStateType`的返回值是否为DatabaseMetaData.sqlStateSQL99
	 */
	supportsSQL99?: boolean;

	/**
	 * 是否支持mergeinto
	 *  
	 * 默认false
	 */
	supportsMergeInto?: boolean;

	/**
	 * 是否支持upsert语法。
	 *
	 * 用于保存一行数据,根据主键判断,不存在insert,存在则update,比如,mysql支持 insert into
	 * tablename ... on duplicate key update ...语法,是upsert的一种。
	 *
	 * 配置为true时,需要同时配置{@link DbSQLTemplates.insertOnDuplicate}模版。
	 *
	 * 有些数据库不支持upsert语句,可以考虑使用merge语句替代,比如oracle,但需要注意数据库本身对
	 * merge语句的使用推荐情况,是否存在性能问题、是否merge语句只是适合批量数据的merge、是否推荐大并
	 * 发的单条数据的merge语句操作,如果有性能问题,可以配置{@link DbSupportsConf.supportsUpsert}为
	 * false,这样系统会自动使用一条insert+一条update语句模拟upsert的效果。
	 *
	 * 不支持的数据库,采用两条语句实现:insert冲突后执行update。
	 *
	 * 默认false
	 */
	supportsUpsert?: boolean;

	/**
	 * 是否支持Insert语法。
	 * 
	 * 有些大数据类型数据库,数据写入不是通过insert,不支持insert语句。
	 * 
	 * 默认true
	 */
	supportsInsert?: boolean;

	/**
	 * 是否支持Update语法。
	 * 
	 * 有些大数据类型数据库是只读的,不支持修改数据,不支持update语句。
	 * 
	 * 默认true
	 */
	supportsUpdate?: boolean;

	/**
	 * 是否支持insert ignore忽略插入语法。
	 *
	 * 默认true
	 */
	supportsInsertIgnore?: boolean;

	/**
	 * 是否支持在mergeInto的时候设置on条件。
	 *
	 * mysql 是用on duplicate key实现,不支持。
	 * 
	 * 默认false
	 */
	supportsMergeFilter?: boolean;

	/**
	 * 是否支持批量提交数据
	 * 
	 * 默认true
	 */
	supportsBatchCommit?: boolean;

	/**
	 * 是否支持对blob,clob类型字段执行批量处理。
	 * 
	 * 默认true
	 */
	supportsBatchCommitForLob?: boolean;

	/**
	 * 是否支持修改表注释。
	 * clickhouse不支持修改。
	 * 
	 * 默认true
	 */
	supportsAlterTableComment?: boolean;

	/**
	 * 是否支持修改字段注释。
	 * 
	 * @return 默认true
	 */
	supportsAlterColumnComment?: boolean;

	/**
	 * 是否支持修改主键
	 * 
	 * 默认true
	 */
	supportsAlterTablePrimaryKey?: boolean;

	/**
	 * 是否支持字段的约束定义,比如:
	 * not null,unique,default等。
	 * 
	 * 默认true
	 */
	supportsColumnConstraint?: boolean;

	/**
	 * 自定义函数知否支持进行分组。
	 * derby的自定义函数不支持用于group by语句。
	 * 
	 * 默认true
	 */
	supportsGroupForCustomFunc?: boolean;

	/**
	 * insert时是否支持自增长主键
	 *
	 *
	 * 默认false
	 */
	supportsGetGeneratedKeys?: boolean;

	/**
	 * insert时是否支持获得所有字段的值
	 *
	 * 默认false
	 */
	supportsGetGeneratedValues?: boolean;

	/**
	 * 是否支持主键
	 * 
	 * 默认true
	 */
	supportsPrimaryKey?: boolean;

	/**
	 * 是否支持使用查询字段别名分组
	 *
	 * 默认true
	 */
	supportsGroupByAlias?: boolean;

	/**
	 * 是否支持使用查询字段别名排序
	 *
	 * 默认true
	 */
	supportsOrderByAlias?: boolean;

	/**
	 * 是否支持使用查询字段的索引分组
	 *
	 * 默认true
	 */
	supportsGroupByColumnIndex?: boolean;

	/**
	 * 是否支持使用拆线呢字段的索引排序
	 *
	 * 默认true
	 */
	supportsOrderByColumnIndex?: boolean;

	/**
	 * 是否支持字段唯一属性
	 * 
	 * 默认true
	 */
	supportsUnique?: boolean;

	/**
	 * 设置字段唯一时,是否支持可空。
	 * 目前支持的数据库,只有DB2不支持可空。
	 * 
	 * 默认true
	 */
	supportsNullInUniqueColumn?: boolean;

	/**
	 * 是否支持创建、修改索引
	 * 
	 * 默认true
	 */
	supportsIndex?: boolean;

	/**
	 * 数据库是否支持定义自增长字段;
	 * 
	 * 目前主流数据库,只有Oracle不支持;需要使用触发器解决。
	 * 
	 * 默认true
	 */
	supportsAutoIncrementColumn?: boolean;

	/**
	 * 是否自增长字段可以不是主键。
	 * 
	 * 默认true
	 */
	supportsAutoIncrementNotKey?: boolean;

	/**
	 * 判断数据库是否支持序列;
	 * 
	 * 默认false
	 */
	supportsSequences?: boolean;

	/**
	 * 默认false
	 */
	supportsTrigger?: boolean;

	/**
	 * 是否支持SQL中的注释
	 * 
	 * 默认true
	 */
	supportsSQLComments?: boolean;

	/**
	 * 是否支持给表设置注释
	 * 
	 * 默认true
	 */
	supportsTableComments?: boolean;

	/**
	 * 是否支持字段设置注释
	 * 
	 * 默认true
	 */
	supportsColumnComments?: boolean;

	/**
	 * 是否支持Clob及其类似的字段类型;
	 * 
	 * 默认true
	 */
	supportsCLOB?: boolean;

	/**
	 * 是否支持Blob及其类似的字段类型;
	 * 
	 * 默认true
	 */
	supportsBLOB?: boolean;

	/**
	 * 是否支持boolean类型的值作为查询返回值。
	 *
	 * 默认false。
	 */
	supportsBoolean?: boolean;


	/**
	 * db是否支持整数值除法能得到精确结果,即得出有小数点的浮点数
	 *
	 * 大部分数据库都支持,比如mysql中`3/2`得到`1.5`,但pg、sql server、dm不支持,它们只能整除得到
	 * `1`,当配置为`false`时,系统会自动将2个整数的除法表达式进行变换,以确保得到精确的结果,如
	 * `field1 / field2`会翻译成SQL:`field1 * 1.0 /field2` 来保证精度,如果除号一边是常量,那么会自
	 * 动补上`.0`,如`field1/2`变成`field1/2.0`。
	 *
	 * @see https://docs.qq.com/doc/DRkpkRG9raGxuT09k
	 *
	 * 默认true。
	 */
	supportsIntDivAccurately?: boolean;

	/**
	 * 是否支持除0操作。
	 *
	 * 比如mysql就支持,除0将返回null。
	 * 其他大部分数据库不支持,直接抛出sqlState=22012的异常。
	 *
	 * @return 默认为false
	 */
	supportsDivZero?: boolean;

	/**
	 * 数据库默认的null的升序规则。
	 *
	 * 数据库中null的排序,会影响查询结果,还会影响排名的计算,默认为`first`。比如:mysql默认就是升
	 * 序在前,与默认一致,不需要配置;oracle和postgresql默认是升序再后,需要配置为`last`。生成sql
	 * 时,会将此属性和系统设置的排序属性比较,如果不一致,则会生成nulls first/last语句。
	 *
	 * 1. `first` 在前
	 * 2. `last` 在后
	 *
	 * 默认为first
	 */
	nullSortAsc?: SQLNullsSortType;

	/**
	 * 数据库默认的null的降序规则。
	 *
	 * 参考:{@link nullSortAsc}
	 * 
	 * 定义此参数,是因为有的数据库升序和降序的null规则不一致,比如达梦数据库,默认升序在前,降序也在前。
	 *
	 * 1. `first` 在前
	 * 2. `last` 在后
	 *
	 * 默认为last
	 */
	nullSortDesc?: SQLNullsSortType;

	/**
	 * 是否支持增加字段
	 * 
	 * 默认true
	 */
	supportsAddColumn?: boolean;

	/**
	 * 是否支持删除字段。
	 * 
	 * 默认true
	 */
	supportsDropColumn?: boolean;

	/**
	 * 是否支持字段更名。
	 * 
	 * db2不支持更名。
	 * 
	 * 默认true
	 */
	supportsRenameColumn?: boolean;

	/**
	 * 是否支持多个活动的结果集。
	 *
	 * 对于同一个连接对象,如果这个连接正在执行sql,或者遍历{@link java.sql.ResultSet},此时需要执行
	 * 另一个sql,有些数据库不允许,比如:
	 *
	 * 1. mysql流式读取
	 * 2. Vertica
	 * 3. SqlServer
	 *
	 * 默认true。
	 */
	supportsMultipleActiveResultSets?: boolean;

	/**
	 * 返回true表示创建表时数据库默认会将用户输入的字段名和表名(没有转义符括起来的)转大写,此时从
	 * 元数据相关API获取的表名和字段名默认都是大写的。
	 *
	 * Retrieves whether this database treats mixed case unquoted SQL identifiers as case
	 * insensitive and stores them in upper case.
	 * 
	 * 无默认值,默认取jdbc驱动提供的值,若手动配置了,则就用配置的。通常不需要配置。
	 */
	storesUpperCaseIdentifiers?: boolean;

	/**
	 * 返回true表示创建表时数据库默认会将用户输入的字段名和表名(没有转义符括起来的)转小写,此时从
	 * 元数据相关API获取的表名和字段名默认都是小写的。
	 * 
	 * Retrieves whether this database treats mixed case unquoted SQL identifiers as
	 * case insensitive and stores them in lower case.
	 * 
	 * 无默认值,默认取jdbc驱动提供的值,若手动配置了,则就用配置的。通常不需要配置。
	 */
	storesLowerCaseIdentifiers?: boolean;

	/**
	 * 返回true表示创建表时数据库默认会将用户输入的字段名和表名(没有转义符括起来的)不统一大写或小
	 * 写,而是存储原始值,此时从元数据相关API获取的表名和字段名默认都是用户输入的大小写。
	 *
	 * Retrieves whether this database treats mixed case unquoted SQL identifiers as case
	 * insensitive and stores them in mixed case.
	 *
	 * 无默认值,默认取jdbc驱动提供的值,若手动配置了,则就用配置的。通常不需要配置。
	 */
	storesMixedCaseIdentifiers?: boolean;

	/**
	 * 返回true表示创建表时用转义符括起来的字段和表名也会统一用大写存储,此时通常sql查询中也会忽略大小写。
	 * 
	 * Retrieves whether this database treats mixed case quoted SQL identifiers as
	 * case insensitive and stores them in upper case.
	 *
	 * 返回true表示创建表时用转义符括起来的字段和表名也会统一用大写存储,此时通常sql查询中也会忽略大小写。
	 */
	storesUpperCaseQuotedIdentifiers?: boolean;

	/**
	 * 返回true表示创建表时用转义符括起来的字段和表名也会统一用小写存储,此时通常sql查询中也会忽略大小写。
	 * 
	 * Retrieves whether this database treats mixed case quoted SQL identifiers as
	 * case insensitive and stores them in lower case.
	 * 
	 * 返回true表示创建表时用转义符括起来的字段和表名也会统一用大写存储,此时通常sql查询中也会忽略大小写。
	 */
	storesLowerCaseQuotedIdentifiers?: boolean;

	/**
	 * 返回true表示创建表时用转义符括起来的字段和表名不会统一大小写,但SQL查询中会忽略大小写。
	 * 
	 * Retrieves whether this database treats mixed case quoted SQL identifiers as
	 * case insensitive and stores them in mixed case.
	 * 
	 * 返回true表示创建表时用转义符括起来的字段和表名也会统一用大写存储,此时通常sql查询中也会忽略大小写。
	 */
	storesMixedCaseQuotedIdentifiers?: boolean;

	/**
	 * 表示是否sql中的标识符(没有quote的)是大小写敏感的。
	 *
	 * 此选项暂未启用!
	 *
	 * 一般数据库的SQL中都是大小写不敏感的,但也有敏感的(比如mysql在linux上表名、表的别名是大小写敏
	 * 感的,但是字段名不是)。
	 *
	 * 系统在构造SQL时严格按照用户在模型逻辑层设定的字段名来构造的,用户设置的是大写就是大写是小写就
	 * 是小写,如果底层数据库要求SQL中的标识符大小写敏感,那么用户需要自己在逻辑层设置正确。
	 *
	 * Retrieves whether this database treats mixed case unquoted SQL identifiers as case sensitive
	 * and as a result stores them in mixed case.
	 *
	 * 默认读取jdbc驱动提供的值,通常是false。
	 */
	supportsMixedCaseIdentifiers?: boolean;

	/**
	 * 表示是否sql中的标识符(有quote的)是大小写敏感的。
	 *
	 * 如果此选项为true,那么系统中的表名或字段名如果是中括号括起来的(中括号是SuccBI系统的quote符
	 * 号),那么在“翻译“SQL时会保留quote中的大小写,而且数据库在查询表或字段的时候也会准确的查询对
	 * 应大小写的表名或字段名。
	 * 
	 * PostgreSQL是true,Mysql是false。
	 *
	 * Retrieves whether this database treats mixed case quoted SQL identifiers as case sensitive
	 * and as a result stores them in mixed case.
	 *
	 * 默认读取jdbc驱动提供的值。
	 */
	supportsMixedCaseQuotedIdentifiers?: boolean;

	/**
	 * 配置新建表名、字段名等对象时禁用的字符。这些字符即便用括号转义也不能用。
	 *
	 * 此配置只用于系统创建表或修改表结构的时候判断新的字段名或表名的合法性,不用于构造SQL时判断标识
	 * 符是否需要quote。
	 *
	 * 比如oracle中,双引号、null character (\0)是不能用的,mysql中似乎没有这个限制,\r、\n、撇号都
	 * 是可以用的。
	 *
	 * 默认空,表示没有禁止使用的字符。
	 */
	forbiddenIdentifiersChars?: string;

	/**
	 * 标识符可以包含这些字符是正常的,不需要因为有这些字符而quote。
	 *
	 * 默认空,只允许下划线、字母、数字,是否支持unciode,取决于
	 * {@link supportsIdentifiersContainUnicode}。
	 */
	supportsIdentifiersContainChars?: string;

	/**
	 * 标识符可以以这些字符开头,不需要因为有这些字符而quote。
	 * 
	 * 默认空,只允许下划线和字母。
	 */
	supportsIdentifiersContainInitials?: string;

	/**
	 * 配置false时,标识符如果包含或开头是Unicode字符(比如中文、日文等)是需要quote的。
	 * 
	 * 默认true。
	 */
	supportsIdentifiersContainUnicode?: boolean;

	/**
	 * 配置一个正则表达式字符串(忽略大小写),用于判断哪些表名不需要括起来查询。
	 *
	 * 表名中有特殊符号时通常需要用用引号或其它符号括起来查询(见{@link identifiersQuoteChar}),如
	 * 果配置了此属性,且标识符匹配指定的模式,那么将不需要quote,否则将继续根据其他规则判断是否需要
	 * quote。
	 *
	 * 此配置对关键字无效,关键字总是需要quote。
	 *
	 * 默认空,使用默认规则判断:不是关键字、且不是数字开头、且只有字幕数字下划线的表名不括起来。
	 */
	supportsIdentifiersMatchPattern?: RegexString;

	/**
	 * 用于转义关键字的字符,一般情况下都是'"'、mysql是'`'、sqlserver是'[]'
	 *
	 * 默认从jdbc的API接口获取(见DatabaseMetaData.getIdentifierQuoteString()),获取不到则为null,
	 * 表示不支持quote。
	 */
	identifiersQuoteChar?: string;

	/**
	 * 数据库是否支持斜线转义符号,目前已知的数据库是MySQL, PostgreSQL。
	 *
	 * 1. 几乎所有的数据库都支持字符串中的单引号用两个单引号转义。
	 * 2. 有些数据库支持斜线转义,如MySQL,虽然他们也支持单引号用两个单引号转义,但此时
	 *    需要将字符串中的斜线转义成2个斜线,支持斜线转义的数据库可以将回车换行转义为`\r\n`。
	 * 3. 不支持斜线转义的数据库遇到回车换行可启用{@link supportsCharFuncEscape},此时会用函数进行转
	 *    义,如`'First line.'+ CHAR(13) + 'Second line.'`。
	 *
	 * 默认false。
	 */
	supportsBackslashEscape?: boolean;

	/**
	 * 当不支持{@link supportsBackslashEscape}时,可以设置使用char函数转义回车换行符,如'First
	 * line.'+ CHAR(13) + 'Second line.'`。
	 *
	 * 需要同时配置{@link concatenationOperator}和{@link DbVersionCapabilities.functionTemplates}中
	 * 的`CHAR`函数模板。
	 *
	 * 默认false。
	 */
	supportsCharFuncEscape?: boolean;

	/**
	 * 字符串连加使用的操作符,如`||`、`+`。
	 *
	 * 默认null,表示不支持字符串连加符。为null时,会使用concat拼接字符串。
	 */
	concatenationOperator?: string;

	/**
	 * sql中单行注释的开头.
	 * 
	 * 默认`--`。
	 */
	SQLSingleLineCommentsStart?: string;

	/**
	 * sql中多行注释的开头.
	 * 
	 * 默认`/*`。
	 */
	SQLMultiLineCommentsStart?: string;

	/**
	 * sql中多行注释的开头.
	 * 
	 * 默认`*`+`/`。
	 */
	SQLMultiLineCommentsEnd?: string;

	/**
	 * 配置数据库的SQL like语句的默认的escape字符。
	 *
	 * 在SQL语句中,如`select * from table1 where id like 'xxx'`,当like语句后面没有指定escape关键字
	 * 时,db是可能有默认的escape字符的,例如Mysql,like语句的默认escape字符是'\',见
	 * <https://dev.mysql.com/doc/refman/8.0/en/string-comparison-functions.html#operator_like>。
	 *
	 * 在系统自动构造SQL语句时,如果需要的escape字符和db默认的escape字符是一样的,那么构造的SQL语句
	 * 将不包含`ESCAPE`关键字,否则将构造`xxx like '...' escape '\'`语句。
	 *
	 * 默认: null,表示如果SQL中不明确设置like语句的escape字符,那么db也没有默认的。
	 */
	likeEscapeChar?: string;

	/**
	 * 支持宽松的strToDate规则。
	 *
	 * 使用场景:
	 *
	 * 在一些数据库中,可以直接将年月,年等直接通过strToDate转换成合法的日期型值。而有些数据库
	 * (mysql)只能接受严格意义上的日期才能转换成合法的日期型值。在mysql中,str_to_date('202301',
	 * '%Y%m')会返回一个2023-01-00的非法日期值。这种非法值无法继续参与日期计算。
	 *
	 * 此方法返回false时,系统会自动将年(月)值补充完整。
	 *
	 * 默认false
	 */
	supportsLooseStrToDate?: boolean;

	/**
	 * 配置是否支持对指定schema或catalog的表进行DDL操作。比如drop 另一个schema的表。
	 *
	 * 大部分数据库都支持,在表名前面带上schema就行了,但是有些数据库不支持,比如informix,不支持比
	 * 如`drop table schema1:table1`,此时需要先切换schema再操作。
	 *
	 * 默认从jdbc的API接口获取(见`DatabaseMetaData.supportsSchemasInTableDefinitions()`)。
	 */
	supportsQualifiedNameInDDL?: boolean;

	/**
	 * 表示当前数据库是否支持通过调用jdbc驱动的`setFetchSize`函数来执行并读取大数据集的查询,不会出
	 * 现性能问题或内存溢出问题。
	 *
	 * 大部分db都是支持的,但是vertica就不支持,在vertica上如果用户手工输入了一个sql查询了一个大的数
	 * 据集,那么只能用limit语句才能有比较好的效果,否则可能会很慢,setFetchSize、 setMaxRows、
	 * resultBufferSize都没用。此时对vertica可以设置此属性为false,那么系统在执行sql时先分析下是不是
	 * select类型的sql,如果是,那么会自动包裹一个limit,如果包裹后执行出现错误,那么去掉包裹,直接
	 * 执行原始的SQL。
	 *
	 * 当此属性为true(默认为true),当系统在执行大查询时(导出数据、执行未知的SQL等),系统会调用
	 * `setFetchSize`函数,并传递{@link largeQueryFetchSize}设置的值,系统会尽量执行原汁原味的用户输
	 * 入的SQL,不加修改,也不会包装一层select语句。即便设置了此属性为false,对于大查询,如果设置了
	 * {@link largeQueryFetchSize},那么系统依然会尝试调用`setFetchSize`函数,并传递设置的值。
	 *
	 * 由于系统自动产生的SQL都会加入合适的limit语句,所以这个选项基本上就只对执行用户手工输入的SQL有
	 * 影响。
	 *
	 * 默认true。
	 *
	 * @see https://docs.qq.com/doc/DWnJXeHZ5RGtUeFZP#分页limit语句
	 */
	supportsLargeQueryFetchSize?: boolean;

	/**
	 * 定义在执行“大查询”(比如导出100w行数据的查询)时的系统应该设置的fetchSize。
	 *
	 * fetchSize是一次数据库网络往返返回的数据行数,相当于fetchSize只限制一次网络请求的数据,如果超
	 * 出了那么在获取到最后一行后会继续网络请求获取数据,在执行“大查询”时如果不设置正确的fetchSize,
	 * 那么jdbc驱动(比如mysql)会把所有数据都读取到java内存来,数据量大的时候就会OOM。
	 *
	 * 提示:对于不是“大查询”的查询(比如报表查询,通常不会太多,都会很小要么也有分页),应该使用
	 * maxRows,maxRows是JDBC的ResultSet对象返回的最大行数,超过的直接丢弃,相当于加了limit。
	 *
	 * 不同的数据库在执行“大查询”时需要设置的fetchsize可能会有不同,比如Mysql它其实就需要设置
	 * Integer.MIN_VALUE,即-2147483648,设置这个值时mysql会用流式数据读取。
	 *
	 * 默认空,表示不需要设置fetchSize即可支持最大查询,配置null表示覆盖继承的设置(相当于还原成空
	 * 值)。
	 */
	largeQueryFetchSize?: number | null;

	/**
	 * 定义在执行“大查询”(比如导出100w行数据的查询)时的系统应该设置的autoCommit。
	 *
	 * 默认的autocommit是true,有些数据库(如pg,见
	 * <https://jdbc.postgresql.org/documentation/query/>)在执行大查询时需要设置为false,此时可以设
	 * 置此属性为false。
	 *
	 * 默认空,表示不需要设置autoCommit即可支持最大查询。
	 */
	largeQueryAutoCommit?: boolean;

	/**
	 * dual表是一个“特殊”的表,在oracle中,它其实是一个只有一行一列的表,往往用于在没有特定的表时放
	 * 到from后面构成一个完整的select语句,比如`select 1+1 from dual`。
	 * 
	 * @see https://www.w3resource.com/sql/sql-dual-table.php :
	 * The DUAL is special one row, one column table present by default in all Oracle databases. The
	 * owner of DUAL is SYS (SYS owns the data dictionary, therefore DUAL is part of the data
	 * dictionary.) but DUAL can be accessed by every user. The table has a single VARCHAR2(1)
	 * column called DUMMY that has a value of 'X'. MySQL allows DUAL to be specified as a table in
	 * queries that do not need data from any tables. In SQL Server DUAL table does not exist, but
	 * you could create one. The DUAL table was created by Charles Weiss of Oracle corporation to
	 * provide a table for joining in internal views.
	 *
	 * 默认是空:`""`。
	 */
	dualTable?: string;

	/**
	 * local临时表的固定前缀。
	 *
	 * sqlserver应该配置`#`,它创建临时表不是CREATE temp table,而是用表名区分的,井号开头的是临时
	 * 表,2个井号是全局临时表。
	 *
	 * 默认null
	 */
	localTempTablePrefix?: string;

	/**
	 * global临时表的固定前缀。
	 *
	 * sqlserver应该配置`##`,它创建临时表不是CREATE temp table,而是用表名区分的,井号开头的是临时
	 * 表,2个井号是全局临时表。
	 *
	 * 默认null
	 */
	globalTempTablePrefix?: string;

	/**
	 * 忽略这些前缀的表。
	 *
	 * 比如oracle中,在调用jdbc API获取表列表时,`BIN$`开头的表就是被删除的表,是回收站中的表的前
	 * 缀。
	 *
	 * 默认null
	 */
	ignoreTablePrefix?: string;

	/**
	 * 是否支持catalog概念。
	 *
	 * 比如oracle就不支持catalog,只支持schema。
	 *
	 * 此属性和{@link supportsSchema}应该至少有一个是true,当此属性为true且{@link supportsSchema}为
	 * false时,系统将调用{@link DbSQLTemplates.getCatalogs}获取表的命名空间层次结构。
	 *
	 * 默认取决于JDBC API java.sql.DatabaseMetaData.getCatalogTerm() 和
	 * java.sql.Connection.getCatalog是否为空。
	 */
	supportsCatalog?: boolean;

	/**
	 * 如果数据库支持catalog,返回catalog参与拼接一个fully qualified table name时的连接符。
	 * 和{@link catalogAtStart}配合作用。
	 *
	 * 只有{@link supportsCatalog}为true时才有起作用。如果配置了
	 * {@link DbSQLTemplates.qualifiedTableName},则此属性无效,此时命名空间的构造,被
	 * {@link DbSQLTemplates.qualifiedTableName}接管。
	 *
	 * 默认取决于 JDBC API java.sql.DatabaseMetaData.getCatalogSeparator()返回值。
	 */
	catalogSeparator?: string;

	/**
	 * 如果数据库支持catalog,返回catalog参与拼接一个fully qualified table name时,在
	 * schema.tablename的前面还是后面。和{@link catalogSeparator}配合作用。
	 * 
	 * 只有{@link supportsCatalog}为true时才有起作用。如果配置了
	 * {@link DbSQLTemplates.qualifiedTableName},则此属性无效,此时命名空间的构造,被
	 * {@link DbSQLTemplates.qualifiedTableName}接管。
	 *
	 * 默认取决于 JDBC API java.sql.DatabaseMetaData.isCatalogAtStart()返回值。
	 */
	catalogAtStart?: boolean;

	/**
	 * 是否支持schema概念。
	 *
	 * 比如mysql、ob就不支持schema,只支持catalog。
	 *
	 * 此属性和{@link supportsCatalog}应该至少有一个是true,当此属性为true时,系统将调用
	 * {@link DbSQLTemplates.getSchemas}获取表的命名空间层次结构,如果{@link supportsCatalog}同时为
	 * true,那么将使用{@link DbSQLTemplates.getSchemas}查询中返回的`TABLE_CATALOG`字段当中schema所
	 * 在的Catalog。
	 *
	 * 默认取决于JDBC API java.sql.DatabaseMetaData.getSchemaTerm()  和
	 * java.sql.Connection.getSchema是否为空。
	 */
	supportsSchema?: boolean;

	/**
	 * 是否支持一次性获取所有可用的schema。
	 *
	 * 如果db支持catalog({@link supportsCatalog}为true)也同时支持schema({@link supportsSchema}为
	 * true)那么此参数表示是否可以一次性获取所有catalog下的schema。
	 *
	 * 若支持一次性获取所有schema,那么系统会一次性查询所有可用schema发送给用户,否则会按需分catalog
	 * 查询。如果配置了{@link getSchemas}模版,那么模版应支持获取所有schema,若没有配置,那么表示
	 * JDBC驱动的API支持获取全部schema。
	 *
	 * 如果db不支持一次性获取所有schema(比如sqlserver),或者虽然支持,但是一次性获取性能很差(比如
	 * presto)那么配置为false,此时系统会分次按需获取。
	 *
	 * 默认true。
	 */
	supportsGetAllSchemas?: boolean;

	/**
	 * 数据库是否支持{@link PreparedStatement#setArray}的方式。
	 * 
	 * 比如Oracle和PostgreSQL支持,mysql不支持。
	 * 
	 * 默认为false,不支持
	 */
	supportsSetArray?: boolean;

	/**
	 * 是否支持在一个JDBC API的execute函数调用中可以执行多条sql。
	 *
	 * 比如pg执行创建表、然后给每个字段添加注释的语句可以一起执行,为true时系统会尽量将语句一次调用
	 * 执行,为false时系统会自动逐个SQL执行。
	 *
	 * 默认false,表示不支持。
	 */
	supportsExecuteMultiStatements?: boolean;

	/**
	 * 是否支持视图
	 * 
	 * 默认true。
	 */
	supportsView?: boolean;

	/**
	 * 是否支持给视图表添加注释。
	 * 
	 * mysql就不支持,配置false避免从jdbc驱动读取到不正确的信息。
	 * 
	 * 默认true。
	 */
	supportsViewComment?: boolean;

	/**
	 * 是否支持物化视图。
	 * 
	 * 比如pg、oracle支持,但mysql不支持。
	 * 
	 * 默认false。
	 */
	supportsMeterializedView?: boolean;

	/**
	 * 是否支持物化视图的rewrite功能。
	 * 
	 * 如果数据库支持此特性,那么数据库会自动优化sql的查询,把能用物化视图查询的用物化视图查询。
	 * 
	 * 默认false。
	 */
	supportsMeterializedViewRewrite?: boolean;

	/**
	 * sql中的`field1 in (...)`语句中数组长度的最大限制。
	 * 
	 * 当配置了最大限制后,系统会尽量使用合适的等价语法进行查询。
	 * 
	 * 默认无限制。
	 * 
	 * @TJS-type integer
	 */
	maxInArrayElementsCount?: number;

	/**
	 * JDBC连接是否支持setReadOnly。
	 *
	 * Puts this connection in read-only mode as a hint to the driver to enable database
	 * optimizations. 如果支持,对于只读的数据源,系统可能会利用这个机制。
	 *
	 * @see https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#setReadOnly-boolean-
	 *
	 * 默认false
	 */
	supportsConnectionReadOnly?: boolean;

	/**
	 * JDBC连接是否支持setTransactionIsolation。
	 *
	 * Attempts to change the transaction isolation level for this Connection object to the one
	 * given. The constants defined in the interface Connection are the possible transaction
	 * isolation levels.
	 *
	 * @see
	 * https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#setTransactionIsolation-int-
	 *
	 * 默认true
	 */
	supportsTransactionIsolation?: boolean;

	/**
	 * 是否支持事务
	 *
	 * 大部分数据库支持事务,但是一些纯分析性数据库,不支持事务,比如MaxCompute,它的驱动有关事务的
	 * 方法,conn.setAutoComit(false), conn.commit(), conn.rollback()等都没有实现。
	 * 
	 * 如果此参数设置为false,上述驱动的事务相关方法将不会调用,避免抛出驱动中的异常。
	 * 
	 * 默认为Jdbc驱动DatabaseMetaData.supportsTransactions()返回值。
	 */
	supportsTransactions?: boolean;

	/**
	 * JDBC连接是否支持setHoldability。
	 *
	 * Changes the default holdability of ResultSet objects created using this Connection object to
	 * the given holdability.
	 *
	 * @see https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#getHoldability--
	 *
	 * 默认false
	 */
	supportsResultHoldability?: boolean;

	/**
	 * 数据库一行数据的最大长度(不含clob、blob)。
	 *
	 * 考虑到字段的长度有多个理解,比如`VARCHAR(20)`,长度定义为20,但在mysql上如果编码是utf8mb4,那
	 * 么一个汉字最多可能占4个字节,而mysql本身是按字节来限制整行长度的,见
	 * <https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html>,考虑到在不同数据库上长度的
	 * 理解不同,此处的定义值需要定义者自己做一下转换处理,比如mysql innodb存储整行长度最大65535,那
	 * 么需要除以4来定义,设置为65535/4=16384,系统只自会把它和字段的定义长度来比较,不会考虑具体db
	 * 的存储长度。
	 *
	 * 默认取jdbc的默认值(`DatabaseMetaData.getMaxRowSize()`),0表示不知道或未知。
	 *
	 * @TJS-type integer
	 */
	maxRowSize?: number;
}

/**
 * 配置一个数据库异常信息的“识别规则”,用于将各个数据库的各种错误信息的编码进行统一。
 *
 * 不同的数据库有不同的异常编码,比如主键冲突、表不存在等,SuccBI需要把这些异常信息归一化,用一套错
 * 误编码进行解释并提示给最终用户。
 *
 * 可以通过错误信息的多种属性进行匹配,包括类名、错误信息、错误编码、sqlstate等,当配置了多个属性匹
 * 配规则后,需要所有配置的属性都匹配才算匹配这条规则,也就是说属性之间是`AND`关系。
 *
 * !!!WARNING!!!
 *
 * 1. 错误编码配置决定了遇到数据错误时系统如何提示用户,不合理的配置会对用户使用造成困惑。
 * 2. 那些严重的可能导致Connection不可用的错误(如网络通信错误)需要配置{@link isFatalError}=true,
 *    此时连接池会自动丢弃这个连接,否则连接池可能持续返回错误的连接导致系统不可用。
 * 3. 数据不合法的错误,比如主键冲突、长度超长、数据被截断、字段不允许为空、无效的数字等,这类错误决
 *    定了系统是否会进行重试,必需正确配置,否则可能会导致系统某些功能无法正常使用。
 * 4. 通常每个规则应该必须至少有一个属性配置有值,如果所有属性都没有配置值,那么会总是匹配这条规则。
 * 5. SQLSTATE是一个跨db的相对标准的编码,见{@link sqlState},系统已在JDBC通用连接器中自带了部分针对
 *    SQLSTATE的规则(考虑到更多数据库支持的是ANSI SQLSTATE,所以默认规则是ANSI SQLSTATE)。在配置错
 *    误编码映射时应该优先使用SQLSTATE进行配置,当SQLSTATE无法准确识别异常信息时才需要考虑使用
 *    errorCode。
 * 6. 若SQLSTATE能够与{@link DbErrorCodes}中的异常一一对应,应该优先使用SQLSTATE进行配置,这是更通
 *    用的异常匹配规则,比如PostGreSQL数据库;但也有一些数据库中一条SQLState对应产品中的多个异常,比
 *    如MySQL、Oracle和达梦数据库,一个SQLState往往是一类异常,具体的异常使用errorCode进行区别,此时
 *    才考虑配置errorCode。
 */
declare interface SQLExceptionIdentifyConf {
	/**
	 * 用异常信息的类名(类名简称就行了,不是完整路径)进行识别,支持逗号分隔的多个类名,比
	 * 如:`SQLRecoverableException,SQLRecoverableException`。
	 */
	className?: string;
	/**
	 * 用`SQLException#getErrorCode()`的编码进行识别,支持如下形式:
	 * 
	 * 1. 具体的一个编码,只含有数字,如`1042`
	 * 2. 一个编码数组,如`[1042, 1043]`,等价于逗号的多个错误编码
	 * 3. 一个编码范围,如`-10000~-9000`,注意中间用波浪线分隔,包含边界值
	 */
	errorCode?: number | string | number[];
	/**
	 * 用`SQLException#getSQLState()`的结果进行识别,支持如下形式:
	 *
	 * 1. 具体的一个值,如`"0838384"`,此时会使用“startWiths”进行匹配,也就是说只要
	 *    `SQLException#getSQLState()`以指定的内容开头就算匹配。
	 * 2. 一个编码数组,如`[42701, 42702, 42703]`,等价于逗号的多个错误编码,
	 * 3. 一个编码范围,如`"42701~42710"`,注意中间用波浪线分隔,包含边界值,
	 * 4. 正则表达式,用/括起来,如`"/08\\d+/"`,此时会使用正则表达式匹配,需要SQLState完全匹配指定
	 *    的正则表达式内容,才认为是匹配的,注意,正则表达式匹配是忽略大小写的。
	 *
	 * 关于SQLSTATE:
	 *
	 * `SQLException#getSQLState()`返回的是一个标准编码,但可能存在两种编码(见
	 * `DatabaseMetaData#getSQLStateType()`的返回值),可能是ANSI SQLSTATE
	 * value(<https://www.ibm.com/support/knowledgecenter/en/SS6NHC/com.ibm.swg.im.dashdb.messages.doc/doc/rdb2stt.html>),
	 * 或可能是X/Open (now know as Open Group) SQL CLI SQLSTATE value(见
	 * <https://pubs.opengroup.org/onlinepubs/9695959099/toc.pdf>的203页Appendix B)。
	 *
	 * 大部分数据库都是用的是ANSI SQLSTATE,有些数据库可能还支持通过JDBC URL参数来动态控制使用哪种
	 * SQLSTATE(如ob)。
	 *
	 * ANSI SQLSTATE由2部分组成,Class Code和Sub Code,比如`01002 A DISCONNECT error occurred.`,其
	 * 编码前2位`01`是Class Code,后3位`002`是Sub Code。
	 *
	 * 所有的Class Code如下(更多信息见
	 * <https://www.ibm.com/docs/en/db2woc?topic=messages-sqlstate>):
	 *
	 * - 00 Unqualified Successful Completion
	 * - 01 Warning
	 *   - 01001 cursor operation conflict
	 *   - 01002 disconnect error
	 *   - 01003 null value eliminated in set function
	 *   - 01004 string data, right truncation
	 *   - 01005 insufficient item descriptor areas
	 *   - 01006 privilege not revoked
	 *   - 01007 privilege not granted
	 *   - 01008 implicit zero-bit padding
	 *   - 01009 search condition too long for information schema
	 *   - 0100A query expression too long for information schema
	 * - 02 No Data
	 * - 07 Dynamic SQL Error
	 *   - 07001 using clause does not match dynamic parameter specifications
	 *   - 07002 using clause does not match target specifica-tions
	 *   - 07003 cursor specification cannot be executed
	 *   - 07004 using clause required for dynamic parameters
	 *   - 07005 prepared statement not a cursor specification
	 *   - 07006 restricted data type attribute violation 
	 *   - 07007 using clause required for result fields
	 *   - 07008 invalid descriptor count
	 *   - 07009 invalid descriptor index
	 * - 08 Connection Exception
	 *   - 08001 SQL-client unable to establish SQL-connection
	 *   - 08002 connection name in use
	 *   - 08003 connection does not exist
	 *   - 08004 SQL-server rejected establishment of SQL-connection
	 *   - 08006 connection failure
	 *   - 08007 transaction resolution unknown
	 * - 09 Triggered Action Exception
	 * - 0A Feature Not Supported
	 *   - 0A001 multiple server transactions
	 * - 0D Invalid Target Type Specification
	 * - 0F Invalid Token
	 * - 0K Invalid RESIGNAL Statement
	 * - 0N SQL/XML mapping error
	 * - 20 Case Not Found for CASE Statement
	 * - 21 Cardinality Violation
	 * - 22 Data Exception
	 *   - 22001 string data, right truncation
	 *   - 22002 null value, no indicator parameter
	 *   - 22003 numeric value out of range
	 *   - 22005 error in assignment
	 *   - 22007 invalid datetime format
	 *   - 22008 datetime field overflow
	 *   - 22009 invalid time zone displacement value
	 *   - 22011 substring error
	 *   - 22012 division by zero
	 *   - 22015 interval field overflow
	 *   - 22018 invalid character value for cast
	 *   - 22019 invalid escape character
	 *   - 22021 character not in repertoire
	 *   - 22022 indicator overflow
	 *   - 22023 invalid parameter value
	 *   - 22024 unterminated C string
	 *   - 22025 invalid escape sequence
	 *   - 22026 string data, length mismatch
	 *   - 22027 trim error
	 * - 23 Constraint Violation
	 * - 24 Invalid Cursor State
	 * - 25 Invalid Transaction State
	 * - 26 Invalid SQL Statement Identifier
	 * - 27 Triggered data change violation
	 * - 28 Invalid Authorization Specification
	 * - 2A syntax error or access rule violation in direct SQL statement
	 * - 2B Dependent privilege descriptors still exist
	 * - 2C Invalid character set name
	 * - 2D Invalid Transaction Termination
	 * - 2E Invalid Connection Name
	 * - 33 Invalid SQL descriptor name
	 * - 34 Invalid Cursor Name
	 * - 35 Invalid condition number
	 * - 36 Cursor Sensitivity Exception
	 * - 37 Syntax error or access rule violation in dynamic SQL statement
	 * - 38 External Function Exception
	 * - 39 External Function Call Exception
	 * - 3B Invalid SAVEPOINT
	 * - 3D Invalid catalog name
	 * - 3F Invalid schema name
	 * - 40 Transaction Rollback
	 *   - 40001 serialization failure
	 *   - 40002 integrity constraint violation
	 *   - 40003 statement completion unknown
	 * - 42 Syntax Error or Access Rule Violation
	 * - 44 WITH CHECK OPTION Violation
	 * - 45 Unhandled User-Defined Exception
	 * - 46 Java DDL
	 * - 51 Invalid Application State
	 * - 53 Invalid Operand or Inconsistent Specification
	 * - 54 SQL or Product Limit Exceeded
	 * - 55 Object Not in Prerequisite State
	 * - 56 Miscellaneous SQL or Product Error
	 * - 57 Resource Not Available or Operator Intervention
	 * - 58 System Error
	 * - 5U Utilities
	 * - HZ Remote Database Access
	 *
	 * 参考:
	 *
	 * 1. https://www.wikiwand.com/en/SQLSTATE
	 * 2. https://stackoverflow.com/questions/1399574/what-are-all-the-possible-values-for-sqlexception-getsqlstate
	 * 3. https://www.ibm.com/support/knowledgecenter/en/SS6NHC/com.ibm.swg.im.dashdb.messages.doc/doc/rdb2stt.html
	 * 4. https://pubs.opengroup.org/onlinepubs/9695959099/toc.pdf
	 * 5. https://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
	 */
	sqlState?: RegexString | string | string[];
	/**
	 * 用错误的message进行匹配,支持如下形式:
	 *
	 * 1. 具体的一个值,如`"0838384"`,此时使用“包含”进行匹配,也就是说只要数据库的错误信息中包含这
	 *    里指定的内容,就认为是匹配的,注意“包含”匹配是大小写敏感的
	 * 2. 正则表达式,用/括起来,如`"/08\\d+/"`,此时会使用正则表达式匹配,只要错误信息中包含符合条
	 *    件的正则表达式内容,就认为是匹配的,注意,正则表达式匹配是忽略大小写的。
	 */
	errorMessage?: RegexString | string;

	/**
	 * 符合以上条件的数据库异常的归一化错误编码。见{@link DbErrorCodes}。
	 * 
	 * 默认{@link DbErrorCodes.baseError}。
	 */
	unifiedErrorCode: string;

	/**
	 * 异常属性信息提取正则表达式。
	 * 
	 * 用于从错误信息中提取一些异常提示属性,这些属性会按需提示给用户,以便告诉用户具体的错误位置和
	 * 信息,比如具体哪个表、哪个字段、哪个数据有问题。比如从Mysql的主键冲突`Duplicate entry 'aa'
	 * for key 'IT_TEST99'`中提取数据的ID和索引名。
	 * 
	 * 对于某些异常中不稳定的属性(比如`GBase`数据库的索引名称总是随机生成),可以选择不提取,因为
	 * 业务用户往往也看不懂这些信息;即使提取了也不会出现在异常对话框中,只会出现在详细信息中,供研
	 * 发人员查看并解决相关问题。
	 *
	 * 这里配置的正则表达式需要使用到“分组匹配捕获”,正则表达式中的每个组对应一个异常属性,属性名按顺序定
	 * 义在{@link regexCaptureProperties},相关技术说明见下文链接:
	 *
	 * 1. https://www.liaoxuefeng.com/wiki/1252599548343744/1306046706483233
	 * 2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Backreferences
	 *
	 * 示例,从Mysql的主键冲突错误信息中提取主键的数据值和对应的索引名:
	 * 
	 * ```
	 *  "errorIdentifyConfs": [{
	 *      "errorCode": 1062, //Duplicate entry 'aa' for key 'IT_TEST99'
	 *      "unifiedErrorCode": "err.db.duplicateKey",
	 *      "regex": "/Duplicate entry '([\\S]+)' for key '([\\S]+)'/",
	 *      "propertyNames": ["dataId", "indexName"]//正则表达式中的第一个`'([\\S]+)'`匹配`dataId`,第二个`'([\\S]+)'`匹配`indexName`。
	 *  }]
	 * ```
	 */
	extractPropertiesRegex?: RegexString,

	/**
	 * 异常属性名列表
	 *
	 * 属性顺序与{@link extractRegex}中被`()`包含的表达式一一对应,如果有些表达式中的`()`匹配的内容
	 * 只是为了搜索需要,并不需要纪录属性,那么可以在此属性数组对应的序号位置配置null,表示忽略这个
	 * 匹配分组。
	 */
	regexCaptureProperties?: string[] | string;

	/**
	 * 此数据库异常是否是一个“严重”异常,为true时,此数据库连接将被丢弃,不再回收到连接池继续使用,
	 * 并且系统会自动将连接池中的所有连接标记为待检查,下次使用时需要先检查有效性才能使用。
	 *
	 * !!!WARNING!!!:那些严重的可能导致Connection不可用的错误(如网络通信错误)需要配置
	 * {@link isFatalError}=true,此时连接池会自动丢弃这个连接,否则连接池可能持续返回错误的连接导致
	 * 系统不可用。
	 *
	 * 默认自动,系统将自动根据{@link unifiedErrorCode}决定是否是严重错误。
	 */
	isFatalError?: boolean;
}

/**
 * 描述数据库的一个字段类型的属性。
 */
declare interface DbDataTypeDefine {
	/**
	 * 字段的定义,可以是一个带有长度参数的模板字符串,如:
	 * 
	 * 1. SMALLINT
	 * 2. VARCHAR(?)
	 * 3. VARCHAR(?) BINARY  
	 * 4. DECIMAL(?,?)      -- 第一个问号表示长度,第二个表示小数位数。
	 */
	type: string;

	/**
	 * 定义匹配的java JDBC规范中的数据类型,见{@link JavaSQLTypeName}(或java.sql.Types)。
	 *
	 * 这里配置的类型决定了:
	 *
	 * 1. 系统以什么方式调用JDBC api更新数据库的字段,字符串、日期、时间戳、数值等,如果配置了数组,
	 *    那么取数组中的第一个
	 * 2. 需要特别注意的是BLOB和LONGVARBINARY的配置,不同的数据库对这2个类型的支持不
	 *    同,LONGVARBINARY通常是一种inline的存储,和其他字段数据存储在一起的,应该用
	 *    getBytes/getBinaryStream函数读取、用setBytes/setBinaryStream函数写入的,而BLOB是offline存
	 *    储的,即行内只是一个id,数据存储在别处,应该用get/setBlob读写。
	 * 3. 通常不需要配置多个,但有时候有些{@link JavaSQLTypeName}类型在数据库中没有合适的类型对应时
	 *    可能需要配置一个数组,做一些兼容性对应,比如mysql,没有专门的NVARCHAR字段类型,它的VARCHAR
	 *    就是NVARCHAR,所以就需要配置VARCHAR类型对应2个类型。这样当从其他数据库迁移NVARCHAR字段类型
	 *    数据到Mysql时,会VARCHAR字段类型。
	 */
	javaTypes?: JavaSQLTypeName | JavaSQLTypeName[];

	/**
	 * 定义当前字段类型可以修改为哪些其它数据类型。
	 *
	 * 用户在模型管理界面上可以修改已有字段的数据类型,比如将smallint修改为number,如果一个类型可以
	 * 直接用数据库的alter语法修改那么就可以在这里把类型定义清楚。
	 *
	 * 此属性为空或未定义时如果用户修改这个类型的字段的数据类型,那么系统将自动判断是否能修改类型,
	 * 规则如下:
	 *
	 * 1. 当表中存在数据时,blob、clob的字段类型总是不能修改为其他类型,其他类型也不能修改为blob或
	 *    clob
	 * 2. 其他字段类型认为可以互相修改
	 *
	 * 对于不能修改的类型,如果用户确实要修改类型,那么系统将新建一个字段并尽量迁移老字段的数据过
	 * 去。
	 */
	alterTypes?: JavaSQLTypeName[];

	/**
	 * 定义这个字段类型在SuccBI中的数据类型是什么。
	 *
	 * 1. SuccBI中,字段的类型是用字母如'C'、'N'表示的,见{@link FieldDataType}。当SuccBI连接第三方
	 *    已存在的数据库时,会根据这个属性的设置决定第三方数据库的字段在SuccBI中是什么数据类型。
	 * 2. 当用户在SuccBI中定义了一个新的模型时,系统也会根据这里的配置去考虑应该选择哪个具体的字段类
	 *    型创建表,具体见{@link matchLen}。
	 */
	dataType?: FieldDataType;

	/**
	 * 表示`DATE`或`DATETIME`类型的字段是否包含时间(如Oracle)。
	 *
	 * 用于在从Oracle迁移数据到其他数据库时,不能丢失Date字段类型中的时间信息。
	 * 
	 * 默认false。
	 */
	includeTime?: boolean;

	/**
	 * 当用户在SuccBI中定义了一个新的模型时,通常需要创建对应的物理数据库表,此时系统就要考虑具体选
	 * 择哪个字段类型进行创建,此时会优先使用定义了preffered=true的字段。
	 *
	 * 当一个数据库对应有多个字符类型的字段类型,那么最好设置其中一个为preffered=true,否则系统可能
	 * 会选取其中排序靠前的那个使用。
	 *
	 * 对于整形字段,如果定义了{@link matchLen}属性,那么会依据{@link matchLen}属性找到匹配的字段类
	 * 型,找不到时会使用定义了preffered=TRUE的整形字段。
	 */
	preffered?: boolean;

	/**
	 * 用于配置当整数长度匹配时选择此字段类型创建字段,格式是形如"1~4"的字符串,表示匹配范围(包含边
	 * 界),此属性仅对整数({@link FieldDataType.I})字段有效。
	 *
	 * 当用户在SuccBI中定义了一个新的模型时,通常需要创建对应的物理数据库表,此时系统就要考虑具体选
	 * 择哪个字段类型进行创建,规则是: 
	 *
	 * 1. 字符类型的优先选择NVARCHAR,其次是VARCHAR。
	 * 2. 数字类型(有小数),选择NUMERIC
	 * 3. 整数根据这里的匹配长度选择具体的类型,比如有时候是SMALLINT,没有合适的匹配的选择NUMERIC。
	 * 4. 整数字段类型没有配置此属性(或配置null)的字段类型将不会被系统使用。
	 *
	 * 系统在创建整数字段时会尽量使用长度刚好够用的类型,这样通常性能更好,比如长度是1的整数,在
	 * mysql中可以使用tinyint。但是用户是可能修改字段长度的,如果修改的长度超出了原来类型的最大长
	 * 度,那么系统会自动修改字段的类型,如果数据库不支持修改字段类型,或者即便支持但是修改成本很
	 * 大,那可以不配置此属性,此时系统不会使用此类型创建表。
	 *
	 * 示例:
	 *
	 * 1. 比如对mysql的 TINYINT 类型可以配置 "1~2" 表示当整数长度小于等于2时,用TINYINT创建字段。
	 */
	matchLen?: string;

	/**
	 * 是否是无符号的。
	 * 
	 * 默认false。
	 */
	unsigned?: boolean;

	/**
	 * 此类型占用的字节数。
	 *
	 * 用于设置某些固定存储空间的字段类型的存储空间大小,例如mysql的SMALLINT,存储的字节数是2,见
	 * <https://dev.mysql.com/doc/refman/8.0/en/integer-types.html>。
	 *
	 * 这个属性会用于当从其他数据库迁移数据过来时选择合适的字段类型。
	 * 
	 * @TJS-type integer
	 */
	storageBytes?: number;

	/**
	 * 为true表示此字段类型的长度单位是字符,否则是字节。
	 *
	 * 长度单位是字符的字段(通常NVARCHAR是字符,而VARCHAR是字节),一个长度可以存储一个汉字,否则由
	 * 于汉字要编码存储,可能就需要4个字节的长度才能存储一个汉字。
	 *
	 * 虽然通常NVARCHAR是字符,而VARCHAR是字节,但是有些数据库比如mysql,没有NVARCHAR,它的VARCHAR存
	 * 储的就是字符。
	 *
	 * 创建表时,如果期望是字符长度存储的,但是数据库不支持这样的字段类型,那么会自动使用字节长度的
	 * 类型,并将字段长度扩充4倍。跨库迁移数据时,字节长度的字段迁移到字符长度时长度不变,字符长度迁
	 * 移到字节长度时创建的字段的长度会是原来的4倍。
	 *
	 * 系统默认会自动使用unicode类型的字段,这样用户更容易理解长度的概念和设置、国际化兼容性更好、而
	 * 且现代的数据库内部的对象多半都是unicode的、有些数据库(GBase)如果在Varchar中存储中文排序可能
	 * 也不对,所以我们默认用这个性能应该是更可以接受的。但如果用户需要控制,可以在模型字段的“存储设
	 * 置”中修改。
	 *
	 * 有些数据库比如达梦,VARCHAR类型具体是不是unicode的取决于创建数据库时的配置
	 * (LENGTH_IN_CHAR),无法准确确定是否是unicode的,此时可以考虑使用脚本动态确定,见
	 * {@link DbConnectorExt.initRuntimeCapabilitiesConf}。
	 *
	 * 类型是NVARCHAR、NCHAR、NCLOB时默认true,其他默认false。
	 */
	unicode?: boolean;

	/**
	 * 设置此字段类型允许使用的最大长度,仅对字符类型字段有效。
	 *
	 * 考虑到字段的长度有多个理解,比如`VARCHAR(20)`,长度定义为20,但在mysql上如果编码是utf8mb4,那
	 * 么一个汉字最多可能占4个字节,而mysql本身是按字节来限制整行长度的,见
	 * <https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html>,考虑到在不同数据库上长度的
	 * 理解不同,此处的定义值需要定义者自己做一下转换处理,系统自会把它和字段的定义长度来比较,不会
	 * 考虑具体db的存储长度。
	 *
	 * 如果没有设置,那么表示可以使用{@link maxLen}允许的最大长度。
	 *
	 * @TJS-type integer
	 */
	limitLen?: number;

	/**
	 * 此字段类型支持的最大长度,数字(固定精度的数字,如NUMBERIC)、字符串字段有效。
	 *
	 * 考虑到字段的长度有多个理解,比如`VARCHAR(20)`,长度定义为20,但在mysql上如果编码是utf8mb4,那
	 * 么一个汉字最多可能占4个字节,而mysql本身是按字节来限制整行长度的,考虑到在不同数据库上长度的
	 * 理解不同,此处的定义值需要定义者自己做一下转换处理,系统自会把它和字段的定义长度来比较,不会
	 * 考虑具体db的存储长度。
	 *
	 * @TJS-type integer
	 */
	maxLen?: number;

	/**
	 * 此字段类型支持的最大小数位数,数字(固定精度的数字,如NUMBERIC)字段有效,
	 * 当小数位数超过最大值时,若设置了此参数,则将小数位数自动调整为该值
	 */
	maxDecimal?: string;

	/**
	 * 配置将null转换为此列类型的一个sql语法,如` cast(null as char) `。
	 * 
	 * null在数据库中通常可以适用到所有类型,但是有些时候需要一个明确类型的null值。比如在构造union
	 * all语句时,有些查询需要构造null列,在vertica中null列也必须要有明确的类型才行。
	 */
	castNull?: string;
}

/**
 * 描述数据库的一个对象(表、视图、存储过程之类的)的类型信息
 */
interface DbIdentifierTypeDefine {
	/**
	 * 对应的在系统内的对象类型。
	 *
	 * 每个数据库的对象类型可能会有不同,比如视图可能有物化视图和普通视图之分,此处将各个数据库本地
	 * 的类型映射为SuccBI系统内的类型。
	 */
	type: DbObjectType;

	/**
	 * 配置为true,则系统会忽略这种类型的对象。
	 * 
	 * 默认false。
	 */
	ignore?: boolean;
}

/**
 * 定义从数据库元数据信息中提取字段默认值表达式的规则。
 *
 * 系统模型逻辑层上定义的字段默认值并未在创建表时同步到物理层来,主要是考虑到有些表达式物理层无法计
 * 算、而且从物理层反查默认值表达式和逻辑层也不容易对比差异,所以,逻辑层定义的字段默认值主要是应用
 * 层处理的,需要利用物理层的地方(如当前时间),会在构造insert语句时准备好。
 *
 * 从db元数据库中获取的默认值可能是表达式,也可能就是一个常量,对于字符型的常量,按规范应该返回一个
 * 单引号引起来的字符串,但有些数据库(比如mysql)不会包含,系统分不清楚是不是表达式,此函数负责区分
 * 出表达式和字符串常量,如果是字符串常量,那么就返回一个单引号引起来的字符串。
 *
 * 如果定义了此规则,那么系统将依次按照规则进行匹配,知道遇到第一个匹配的规则。
 *
 * 目前已知需要处理的问题包括:
 *
 * 1. mysql、gbase等默认值是字符串常量时没有用引号引起来。
 * 2. sqlserver 字符类型读取格式:('xxx') ,数值类型:((123))
 * 3. kingbase、postgre的默认值后面总是跟了一个`::character varying`,如`'19000101'::character
 *    varying`。
 */
interface ColumnDefExtractorDef extends RegexExtractorDef {
	/**
	 * 返回的内容是否需要用单引号扩起来。
	 */
	quote?: boolean;

	/**
	 * 当{@link quote}是true时,是否需要进行转义后再扩起来。
	 */
	escape?: boolean;
}

/**
 * 定义函数模板的格式,用于将表达式函数翻译成对应的SQL表达式,支持如下几种格式:
 *
 * 1. 参数模板,如`SUBSTRING(?1, ?2, ?3)`,规则如下:
 *     1. 问号代表参数,问号后面如果有数字表示引用第几个参数,从1开始,如果没有数字表示引用问号的出
 *        现序号所在的参数。
 *     2. 问号后面如果有3个点号,代表引用所有剩下的参数,此时会将当前问号和前一个问号之间的内容当作
 *        分隔符,输出所有剩下的参数,如对于concat函数模板`CONCAT(?, ?...)`。
 *     3. 支持中括号括起来的可选参数,如`SUBSTRING(?1, ?2[, ?3-?2])`,当不传递第三个参数的时候就忽略
 *        其中的中括号括起来的部分`[, ?3-?2]`。
 *     4. 其它功能,比如根据参数的个数、类型匹配不同的模板可使用{@link SQLFunctionTemplateAdv}或者
 *        Freemarker模板(见下文)。
 * 2. Freemarker模板,支持条件判断等复杂逻辑,可以做到根据不同的参数、数据库版本等生成不同的SQL内
 *    容,类似{@link SQLTemplateString}中的Freemarker模板,`ftl:`开头的或者`.ftl`结尾的文件是
 *    Freemarker模板,在模板中支持如下参数:
 *     1. args 所有参数的数组,其中的参数可能是常量也可能是子表达式,通过`args[0]`访问第一个参
 *        数、`args?size`获取参数个数,每个参数都是类型{@link SQLTemplateParam_SQLElement}。
 *     2. 窗口函数的参数比较复杂,系统会自动进行分析,如
 *        `https://docs.succbi.com/exp/func/group_concat/#grammar`,系统会自动分析参数并可以在ftl中
 *        通过参数名直接访问到,如`field`, `partitionfield`, `orderfield`, `ordertype`, `separator`,
 *        `maxlength`。
 *     3. dialect {@link DbDialect}。
 * 3. `...`,表示此函数使用系统默认实现,规则是:
 *     1. 如果是ifnull、if、decode函数,那么默认翻译成case when表达式
 *     2. 其他函数将使用标准实现,即把用户输入的函数名和参数直接用到SQL中
 * 4. `__NOT_SUPPORTED__`,表示此函数在当前数据库不支持,使用此函数会抛出异常
 * 5. `__SCRIPT__`,表示此函数使用脚本翻译SQL,具体见{@link DbConnectorExt.expFunctionToSQL()}函
 *    数。
 *
 * window函数的模板
 *
 * window函数比较特殊,函数参数的形式不固定,比如:
 * 1. `RUNNING_SUM([销售表].[销售数量],ORDERBY([销售表].[季度],'asc'))`
 * 2. `RUNNING_SUM([销售表].[销售数量],PARTITIONBY([销售表].[年],[销售表].[季度]),ORDERBY([销售
 *    表].[月份],'asc'))`
 * 其中第二个参数可能是order参数,也可能是partition参数,给直接定义widnow函数模板带来不便,因此对于
 * window函数在交给模板翻译前,会做参数规整,固定参数的顺序,具体规则如下:
 *
 * 1. window开头的函数,比如:`SUM(?1) OVER ([PARTITION BY ?2])` 其中?1表示统计字段,?2表示分组字段
 *    列表。
 * 2. running开头的函数,比如:`SUM(?1) OVER ([PARTITION BY ?2 ][ORDER BY ?3])` 其中?1表示统计字段,?2
 *    表示分组字段列表,?3表示排序字段列表,内部包含排序字段,排序类型,null排序类型。
 * 3. 排名函数,比如:`RANK() OVER ([PARTITION BY ?2 ][ORDER BY ?1])` 其中?1表示排序字段列表,?2表示
 *    分组字段列表。
 * 4. LAG和LEAD函数,比如:`LAG(?1, ?2, ?3) OVER ([PARTITION BY ?4 ][ORDER BY ?5])` 其中?1表示取值字
 *    段,?2表示偏移量,?3表示默认值,?4表示分组字段列表,?5表示排序字段列表。
 *
 */
type SQLFunctionTemplateString = string | null;

/**
 * SQL模板。
 *
 * 每个SQL模板用于在数据库中实现一个特定的功能,比如mysql的jdbc驱动不支持setSchema,就需要配置一个模
 * 板`"setSchema": "USE ?"`,表示使用此模板实现setSchema功能,同样的还有很多类似功能需要SQL模板,比
 * 如如drop、merge into、drop if exists、create xxx等。
 *
 * 模板的可用参数:
 *
 * 不同的SQL模板有自己“规定的参数”,比如{@link DbSQLTemplates.setSchema}就会接受一个参数即schema,有
 * 些sql模板会有多个参数,而有些SQL模板比如创建表的参数会比较复杂,具体的参数说明见
 * {@link DbSQLTemplates}中各个模板的说明。参数有不同的类型,具体如下:
 *
 * 1. 普通参数,是一个布尔值、字符串、SQL片段、数字等,可以直接输出到模板。
 * 2. 表名标识,见{@link SQLTemplateParam_Identifier}。
 * 3. 字符串常量,如字段备注、表备注,见{@link SQLTemplateParam_Comment}。
 * 4. 字段名列表,见{@link SQLTemplateParam_ColumnNames}。
 * 5. 字段更新列表,见{@link SQLTemplateParam_ColumnValuePairs}。
 *
 * 特殊符号处理:
 *
 * 系统会自动处理标识符(表名、字段名)、字符串常量(如字段备注、表备注)中的特殊符号或关键字,对于
 * 标识符需要根据数据库需要两边加上引号(双引号或撇号等),字符串常量需要将其中的单引号替换为2个单引
 * 号。
 *
 * 模板的语法类型:
 *
 * 1. 参数模板,往往用于配置比较简单的模板,类似{@link SQLFunctionTemplateString},支持问号表示的参
 *    数,如`RENAME TABLE ? to ?`、`INSERT INTO ?1 (?2) VALUES (?3) ON DUPLICATE KEY UPDATE ?5`。
 *     1. 问号代表参数,问号后面如果有数字表示引用第几个参数,从1开始,如果没有数字表示引用问号的出
 *        现序号所在的参数。
 *     2. 支持中括号括起来的可选参数,如`SUBSTRING(?1, ?2[, ?3-?2])`,当不传递第三个参数的时候就忽略
 *        其中的中括号括起来的部分`[, ?3-?2]`。
 *     3. 表名标识如果两边没有单引号,那么输出为一个按需quote的表名,如果有schema会带上。如果两边有
 *        引号,那么输出为数据库元数据存储规范的大小写表名(不含schema)。
 *     4. 字段名、schema名等标识符输出和表名标识类似。
 *     5. 字符串常量输出为两边不带引号的处理过转义的字符串。
 *     6. 如果sql比较复杂,可以写在独立的sql文件中,文件后缀需要是`.sql`,然后把文件名配置在这里。
 * 2. Freemarker模板,支持条件判断等复杂逻辑,往往用于构造很复杂的SQL,比如创建表的SQL。`ftl:`开头的
 *    模板是Freemarker模板,如`ftl:<#if arg1 == null>...</#if>`,如果模板比较复杂可以写在独立的ftl文
 *    件中,比如`create-table.ftl`,此时文件后缀需要是`.ftl`且不需要以`ftl:`开头。
 *     1. ftl模板输出的可以是多条SQL,每条SQL分号结尾,且分号后面必须换行。
 *     2. 产出的SQL中只能使用单行注释,如`--xxxxx`,且只能占据一整行,不要在SQL中产出多行注释,如果
 *        需要多行注释,请使用freemarker注释,确保最后产出的SQL是干净的。
 *     3. 标识符、字符串常量的的输出规则和参数模板一致,表名标识有一些详细属性可以访问,见
 *        {@link SQLTemplateParam_Identifier}。
 *     4. 支持通过`dialect`参数访问一些关于数据库方言处理的api函数,通常不需要用到,见
 *        {@link DbDialect}。
 *
 * `PreparedStatement`规则: 
 *
 * 1. `SELECT`、`INSERT`、`UPDATE`、`DELETE`等dml语句会尽量使用`PreparedStatement`,其他语句,如DDL
 *    不会使用。
 * 2. 当使用`PreparedStatement`时,问号标识的参数会当作`PreparedStatement`的动态参数对待,单引号扩起
 *    来的参数会直接将参数值融入SQL语句中执行。
 * 3. 参数模板中的问号如果两边没有引号且它不是标识符对象,通常会当做PreparedStatement的参数。
 * 4. ftl模版中用pp函数输出的内容会当做PreparedStatement的参数,如`p.proname = ${pp(metaName)}
 *    and n.nspname = ${pp(metaSchema)}`。
 */
type SQLTemplateString = string | null;


/**
 * 这是一个SQL模板({@link DbSQLTemplates})的扩展实现,用于替代那些用SQL模版不方便实现的功能。
 *
 * 参数中的表名、schema,没有经过quote处理,如果有关键字或者特殊符号,脚本开发者需要自己处理,见
 * {@link DbDialect}对象中的相应方法。
 *
 * @param args 可用参数与ftl模板中的一致,但总是存在`conn`、`dbInstance`、`dialect`参数,其他参数根
 *        据不同的模板会有不同,具体见{@link DbSQLTemplates}中的定义。
 * @returns 根据具体的操作,返回结果,具体见上文注释。
 */
type SQLTemplateExtFunc = (args: {
	/**数据库连接 */
	conn: Connection;
	dbInstance: any;
	dialect: DbDialect;
	/**其他参数,不同的操作会有不同的参数 */
	[otherArg: string]: any;
}) => any;

/**
 * 模版参数类型:数据库对象标识,如表名、存储过程名、字段名。
 *
 * 此类型直接输出在模版中(如ftl模版中`${table}`,或参数模版中使用问号),会在模板中输出为一个
 * “qualified name”,是一个能准确的引用到对象标识符路径,如果是表或试图,那么路径是按模版
 * {@link DbSQLTemplates.qualifiedTableName}进行格式化的,字段对象返回别名+name。都已按需quote。
 *
 * 在参数模板中,如果参数两边有单引号,那么此参数输出为`metaName`,不含schema。
 *
 * 在ftl或脚本模板中还可以通过如下属性访问到更多信息:
 *
 * 1. name 对象的名称(已按需quote,仅名称,不含schema、catalog)。
 * 2. alias 对象的别名,通常在DML、DQL语句中会有别名,如关联更新、删除数据。
 * 3. metaName 对象的名称(未quote,大小写和数据库规范一致)
 *
 * 以下属性只对表或试图对象有效(已按按需根据数据库规范统一大小写):
 *
 * 1. schema 对象所在的schema,已按需quote,为空时表示是当前schema或者db不支持schema概念(如
 *    mysql)。
 * 2. catalog 对象所在的catalog,已按需quote,为空时表示是当前catalog或者db不支持catalog概念(如
 *    oracle)。
 * 3. dbserver 对象所在的server,已按需quote,通常只对sqlserver有效。
 * 4. qualifiedParts 对象的”fully-qualified name“路径分段,是一个数组,倒序的,数组的长度可能是2为或
 *    更长,如对于表`catalog1.schema1.table1`,此属性是`["table1","schema1","catalog1"]`,注意数组中
 *    不会存在空值,已按需quote,例如,schema是默认的,那么会是当前schema的名字,如果db不支持
 *    schema,那么数组中不会有schema。
 * 4. metaParts 类似qualifiedParts,区别是未quote。
 * 5. metaSchema 对象所在的schema,即便表所在的schema是当前的默认schema,此属性也不会为空。
 * 6. metaCatalog 对象所在的catalog,即便表所在的catalog是当前的默认catalog,此属性也不会为空。
 * 7. qualifiedName qualified name,一个能准确的引用到对象标识符路径,路径是按模版
 *    {@link DbSQLTemplates.qualifiedTableName}进行格式化的,此属性只对表或试图有效,字段对象返回
 *    null。
 *
 * 示例见:
 *
 * 1. {@link DbSQLTemplates.createTable}的`tableName`参数和字段名参数。
 */
type SQLTemplateParam_Identifier = string;

/**
 * 模版参数类型:字段备注、表备注。
 *
 * 表达式中的字符串也已按需转义(但不包含两边的引号),在ftl模板中通过`.value`属性可以访问到原值,即
 * 未经转义的原值。
 *
 * 如{@link DbSQLTemplates.createTable}的`tableComment`参数。
 */
type SQLTemplateParam_Comment = string;

/**
 * 模版参数类型:字段名列表。
 *
 * 1. 在ftl模版中,是一个数组,每个成员都是一个字段名,已按需quote,通过成员的`.name`属性可以访问到
 *    原值。
 * 2. 在参数模板中或ftl中,直接引用此参数可以输出逗号分割的字段名如`field1,field2...`。
 *
 * 如{@link DbSQLTemplates.mergeInto}的`insertFields`参数。
 */
type SQLTemplateParam_ColumnNames = string;

/**
 * 模版参数类型:字段名列表。
 *
 * 1. 在ftl模版中,是一个数组,每个成员都是一个值或表达式。
 * 2. 在参数模板中或ftl中,直接引用此参数可以输出逗号分割的值列表如`value1,value2...`。
 *
 * 如{@link DbSQLTemplates.insertOnDuplicate}的`insertValues`参数。
 */
type SQLTemplateParam_ColumnValues = string;

/**
 * 模版参数类型:字段更新列表。
 *
 * 1. 在ftl模版中,是一个数组,包含以下成员:
 *    1. name 更新的字段名(已按需quote)。
 *    2. value name对应的值。
 *    3. sameInsert 返回true表示当前字段的更新值和插入值都一样,可以使用同一个问号表达式。可以用于简
 *       化upsert语句,如mysql可以使用`values(fieldName)`去引用插入字段表达式的值,可以减少问号参数
 *       的个数。
 *    4. insertValue 当前字段名对应的插入字段的值。
 * 2. 在参数模板中或ftl中,直接引用此参数可以输出逗号字段名=对应的值,如
 *    `field1=value1,field2=value2...`。
 *
 * 如{@link DbSQLTemplates.mergeInto}的`updateFields`参数。
 */
type SQLTemplateParam_ColumnValuePairs = string;

/**
 * 模版参数类型,表示sql段落中的各种元素。
 * 
 * 1. 一个sql,用于with子句,此时可以访问alias属性,表示with子sql的别名。
 *    此时输出的sql会自动带上括号括起。
 *    - sql 返回原始sql,不带括号,用于某些不需要括号的场景,比如union的子sql。
 * 2. 一个sql,用于from子句,此时可能时一个数据表,也可能时一个子sql。
 *    此时输出的sql会自动带上括号括起。
 * 3. 查询字段列表中的字段,此时可以访问alias属性,表示字段的别名。
 * 4. 分组字段、过滤条件、having条件,表示一个表达式。
 * 5. 排序字段,此时可以访问:
 *    - orderType属性,获取排序类型(ASC/DESC),默认ASC。
 *    - nullsOrder属性,获取null的排序规则(FIRST/LAST)。
 * 6. limit和offset,分页信息,可能是具体值,也可能是参数。
 * 7. 可访问的共同属性:
 *    - type sql段落类型,可能是:SQL、TABLE、FIELD、FILTER
 *
 * 如{@link DbSQLTemplates.updateJoin}的`joinTables`参数的`condition`属性。
 */
type SQLTemplateParam_SQLElement = string;

/**
 * 描述一个表达式函数在特定的数据库中的SQL语句的模板配置。通过配置的描述,系统可以自动将用户输入的表
 * 达式函数“翻译”成特定数据库中可以执行的SQL语句。
 *
 * 通过为不同的数据库配置函数模板,可以简化数据库兼容工作的开发。
 *
 * 使用场景:
 *
 * 1. 兼容具体的数据库时,表达式函数需要翻译成具体的数据库的函数才能执行,使用此类为不同的数据库配置
 *    每个表达式函数的模板,并在产生sql的时候产生正确的sql。
 * 2. 表达式中的RAWSQL_STR,具体执行时也需要使用此类去产生SQL。
 *
 * 实际例子:
 *
 * 1. mid函数在mysql中的模板是`SUBSTRING(?1 , ?2, ?3)`
 * 2. `RAWSQL_STR('first_value(%1) over (partition by %2 order by %3 desc)', [fact].[userid],
 *    [fact].[swjgid], [fact].[tzze])`
 *
 */
declare interface SQLFunctionTemplateAdv {
	/**
	 * 默认SQL模板。
	 *
	 * 1. 模板字符串中可以使用`?`引用参数,问号后可以用数字表示引用第几个参数,如`?1`表示第1个参
	 *    数、`?2`表示第2个参数。如果问号后没有数字,那么问号出现在模板中第几次就是引用第几个参数。
	 * 2. 模板中也可以没有任何动态参数,就是一个固定的字符串也行。
	 * 3. 如果同时配置了条件模板(见{@link templates}),那么将优先使用符合条件的模板,最后再使用默
	 *    认模板。如果没有找到匹配的条件模板,又没有定义默认模板,那么就意味着当前数据库不支持这个表
	 *    达式函数。
	 */
	template?: SQLFunctionTemplateString;

	/**
	 * 条件模板,当参数个数或某个参数满足匹配的条件时使用对应的模板。
	 *
	 * 配置条件模板后,将优先使用符合条件的模板,最后再使用默认模板。如果没有找到匹配的条件模板,又
	 * 没有定义默认模板,那么就意味着当前数据库不支持这个表达式函数。
	 */
	templates?: Array<{
		/**
		 * 匹配的参数个数,如果指定了此参数,那么只有参数个数等于指定的参数个数时才使用此模板。
		 * 
		 * 例如函数date可以匹配参数是1时的情况,在mysql中使用FROM_UNIXTIME将毫秒数转换为日期对象。
		 * 
		 * @TJS-type integer
		 */
		matchArgsLen?: number;

		/**
		 * 匹配参数的设置
		 */
		matchArg?: {
			/**
			 * 匹配某个参数(参数序号,从0开始,默认0),只有指定的参数等于特定的值或是特定的类型时
			 * 才使用此模板。
			 *
			 * 例如datedif/adddate函数可以分别匹配y、m、d等,使用不同的sql模板。
			 * 
			 * @TJS-type integer
			 */
			index?: number;
			/**
			 * 匹配值,用于匹配参数是常量时的值,当参数是变量时总是认为不匹配,默认是等于,可以通过
			 * 配置comparator来选择大于或小于比较。
			 */
			value?: string | boolean | number;
			/**
			 * 用于value比较时的比较符,默认`=`.
			 *
			 * 支持`=`、`<`、`>`,分别表示参数等于指定的value、小于指定的value、大于指定的value,。
			 */
			comparator?: string;
			/**匹配类型 */
			type?: FieldDataType;

			/**是否忽略大小写,默认忽略 */
			ignoreCase?: boolean
		}


		/**当满足匹配条件后使用此模板,具体格式参考{@link SQLFunctionTemplateAdv.template}的注释描述。 */
		template: SQLFunctionTemplateString | SQLFunctionTemplateAdv;
	}>
}

/**
 * 数据库的兼容级别。
 *
 * 此属性决定了系统的某些功能配置能否使用这个数据库,比如元数据存储只能选择兼容级别是
 * {@link DbCompatibilityLevel.All}或{@link DbCompatibilityLevel.OLTP}的数据库。
 */
declare const enum DbCompatibilityLevel {
	/**完全兼容 */
	All = "All",
	/**事务型,比如低代码应用、元数据存储、日志记录等使用场景可用 */
	OLTP = "OLTP",
	/**分析型,比如作为数据仓库使用、报表或仪表板的数据源 */
	OLAP = "OLAP",
	/**仅用于数据提取的源头,是兼容级别最低的一种,通常只能执行最简单的查询 */
	OdsSource = "OdsSource",
}

/**
 * 数据库的类别。用于在新建数据源的对话框中将数据库logo分组显示。
 */
declare const enum DbKind {
	/**事务型数据库 */
	TransactionalDB = "TransactionalDB",
	/**分析型数据库*/
	AnalyticalDB = "AnalyticalDB",
	/**Hadoop类 */
	HadoopDB = "HadoopDB",
	/**列式数据库 */
	ColumnarDB = "ColumnarDB",
	/**nosql */
	NoSQL = "NoSQL",
	/**立方体数据库 */
	Cube = "Cube",
	/**检索服务,比如ES */
	Search = "Search",
	/**其他 */
	Other = "Other",
}

/**
 * 定义一个扩展接口,以便让数据库连接器的开发者能通过脚本或java做一些高度个性化的逻辑,比如实现流式
 * 数据导入。
 *
 * 如果使用脚本实现,那么脚本中需要有这个接口定义的函数,如果是java实现,那么需要实现接口
 * `com.succez.commons.jdbc.connector.DbConnectorExt`。
 *
 * @see DbCapabilities.script
 * @see DbCapabilities.javaClass
 */
declare interface DbConnectorExt {

	/**
	 * 构造连接数据库的jdbcURL和属性列表。
	 *
	 * 一个数据源实例(即产品的数据源管理中的一个数据源)只会在最开始准备进行第一次连接时调用一次此
	 * 函数,后续再次连接时不会重复调用,此函数可以用于进行一次初始化工作,包括动态产生连接数据库的
	 * 属性列表、jdbcurl、甚至是为数据库驱动程序做一些特定的初始化工作。
	 *
	 * 简单的构造连接参数的需求推荐使用{@link DbCapabilities.connectionProperties}完成。
	 *
	 * @param url 将要连接的数据库的jdbc URL。
	 * @param connectProperties 可以直接修改或增加属性选项,此属性用于`java.sql.Driver.connect()` 函
	 *        数的第二个参数需要的参数。
	 * @param jdbcConf 数据库连接的相关配置选项。
	 * @return 如果需要,返回新的jdbc连接的url
	 */
	initConnectProperties?(url: string, connectProperties: JSONObject, jdbcConf: JdbcConfigInfo): string;

	/**
	 * 当数据库第一次连接成功时,初始化一些兼容性设置项。
	 *
	 * 数据库连接器的配置通常都是静态配置的,比如VARCHAR字段是不是unicode的、数据库是不是支持某些特
	 * 性等等,但有时候数据库的这些兼容性选项是和数据库本身创建时的配置项有关的,比如达梦数据库,不
	 * 同的数据库创建参数会影响VARCHAR字段是不是unicode的。这里的回调函数给连接器一个产生动态兼容性
	 * 选项的机会。
	 *
	 * 脚本函数可以返回一些增量的配置项,这些配置项会覆盖连接器中的同名的静态配置项,覆盖规则类似
	 * {@link DbCapabilities.compitableVersions}中高版本覆盖低版本的配置项,此函数返回的配置优先级低
	 * 于{@link JdbcConfigInfo.capabilities}。
	 *
	 * @param conn 数据库连接对象(驱动的原始连接对象)。
	 * @param jdbcConf 当前连接配置
	 * @returns 返回空或增量配置项。
	 */
	initRuntimeCapabilitiesConf?(conn: Connection, jdbcConf: JdbcConfigInfo): DbVersionCapabilities;

	/**
	 * 创建一个数据库本地的、高性能的数据批量读写工具类。
	 *
	 * 更多业务信息说明见{@link ExtBulkDataSource}。
	 *
	 * 只有当配置了{@link DbSupportsConf.supportsBulkLoad}时,系统才会调用此函数。
	 */
	createDbTableBulkSource?(): ExtBulkDataSource;

	/**
	 * 将一个表达式函数翻译成对应的SQL语句,用于在数据库中执行。
	 *
	 * 通常表达式的翻译是通过函数模板配置的,见{@link DbCapabilities.functionTemplates},但有些函数
	 * 的逻辑比较复杂,通过模板配置无法实现,此时可以选择使用脚本进行翻译,此时需要在函数模板配置中
	 * 配置函数的模板是`__SCRIPT__`。
	 *
	 * 此函数对操作符的翻译也有效。
	 *
	 * @param func 函数名或操作符名称,统一大写。
	 * @param args 参数,可能为null,表示没有,参数中如果有字符串,那么已经用单引号括起来了,且需要
	 *             转义的已经转义过。
	 * @param node 表达式节点对象,通过这个对象可以知道参数的更多详细信息,比如数据类型
	 *             `node.getNode(i).getDataType()`。
	 */
	expFunctionToSQL?(func: string, args: string[], node: any): string;

	/**
	 * 这是一个SQL模板({@link DbSQLTemplates})的扩展实现。
	 *
	 * 每个函数名为`tempate_+模版名`的函数对应一个{@link DbSQLTemplates}中的模板,系统会自动找到这样
	* 的函数无需额外的配置,通常用于用脚本或java实现的特定的数据库功能,替代那些用SQL模版不方便实现
	* 的功能。需要注意的是如果{@link DbVersionCapabilities.sqlTemplates}中已经配置了同名模版,那么将
	* 优先使用那里配置的,忽略函数模版。
	 *
	 * 如果函数脚本遇到错误,比如对象不存在,那么可以直接抛出异常,系统会直接继续抛出提示给用户。
	 *
	 * 脚本的返回值根据模板定义决定,主要有三种类型:
	 *
	 * 1. 单个值 比如{@link DbSQLTemplates.getCatalog}
	 * 2. 一个查询结果集,比如{@link DbSQLTemplates.getColumns},结果集返回值是个json,结构如下:
	 *    ```json
	 *    {
	 *        "fields":[{
	 *            "name": "columnName",
	 *            "type": 12, //sqlType
	 *            "length": 10,
	 *            "precision": 0
	 *            "scale": 0
	 *        }],
	 *        "data": [[]]
	 *    }
	 *    ```
	 * 3. 无返回值,比如{@link DbSQLTemplates.setCatalog}
	 *
	 * @see SQLTemplateExtFunc
	 */
	[func: string]: any;
}

/**
 * 跨库迁移数据,或从文件导入数据的API函数的参数选项。
 */
interface MigrateDataArgs {
	/**
	 * 项目名,用于权限判断
	 */
	projectName?: string;

	/**
	 * 传递一个uuid当作任务id,前端可以通过这个id轮询任务的执行进度和日志信息。
	 */
	taskId?: string;

	/**默认同步,是否异步,异步时函数调用直接返回,任务在线程池执行,否则是同步等待迁移完成才返回函数 */
	async?: boolean;

	/**
	 * 给此参数传递no,可以禁用线程池,所有数据迁移都是用串行模式。
	 * 
	 * 默认yes。
	 */
	threadPool?: "no" | "yes";

	/**
	 * 导出时用于将导出的文件合并成一个压缩文件,导入时用于从这个zip导入多个表的数据。
	 *
	 * 属性值是一个文件路径,此属性对导出导入都有效,导出时用于将导出的文件合并成一个压缩文件,此时
	 * {@link BulkDataOptions.zipEntry} 将用作为压缩文件内部的相对路径,文件名和路径需要有业务意义。
	 *
	 * 导入时用于从这个zip导入多个表的数据。
	 *
	 */
	zipFile?: string;

	/**
	 * The encoding to use for file names and the file comment.
	 *
	 * <p>For a list of possible values see <a
	 * href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.
	 * Defaults to UTF-8.</p>
	 *
	 * use null for the platform's default encoding
	 */
	zipFileEncoding?: string;

	/**
	 * 当源表是空表时,自动忽略,不进行数据拷贝。
	 *
	 * 启用此选项后将总是先查询源表的总行数,相当于{@link queryTableRowcount}设置为true。
	 *
	 * 默认为false。
	 */
	ignoreBlankTable?: boolean;

	/**
	 * 是否遇到有错误的表,忽略它并继续下一个表。
	 * 
	 * 为false时,遇到任何表的错误都将终止整个迁移过程并退出。
	 * 
	 * 默认false。
	 */
	ignoreErrorTable?: boolean;

	/**
	 * 启用统计和计算迁移进度
	 *
	 * 内部实现上:
	 *
	 * 1. 数据库迁移到数据库,估算写入到数据库的数据量
	 * 2. 数据库数据导出到文件,根据写出的行数,估算进度
	 * 3. 文件导入到数据库中,根据已经从文件中读取到的字节数,估算写入的进度
	 * 4. 复杂的导入,比如说同时将文件和一个数据库表中的数据,一起写入到同一个数据库表中的情况,暂时不支持数据量的估算
	 *
	 * 计算过程或多或少的都会占用一些计算资源
	 *
	 * 默认false
	 */
	enableProgress?: boolean;

	/**
	 * 启用流量统计,TODD 功能未实现
	 * 
	 * 开启后,会尝试收集:
	 
	 * 1. 统计数据读取进度,与读取速度
	 * 2. 统计数据写出的字节数,计算写出流量的速率
	 * 3. 读取数据阻塞与写入数据阻塞的等待时长
	 *
	 * 统计过程或多或少的都会占用一些计算资源
	 *
	 * 默认false
	 */
	enableFlowStatistics?: boolean;

	/**
	 * 设置要复制哪些表。
	 *
	 * 当设置{@link zipFile}后表示要从zip文件中导入数据,或者导出数到zip文件。导出和导入都支持zip中
	 * 的多个文件,导出数据到zip时{@link MigrateTableInfo.target.zipEntry}表示要导出的zip文件中的文
	 * 件名,而导入zip时{@link MigrateTableInfo.source.zipEntry}表示要导入zip中的哪个文件,此时可以
	 * 使用通配符表示导入zip中的一批文件,如`*` 表示导入所有文件(不会递归到子目录下)、`*.csv` 表示
	 * 导入csv文件。
	 * 
	 * 几个示例:
	 * 
	 * ```jsonc
	 * [
	 *     {
	 *         "source": { "zipEntry": "*" }, //导入zip中所有文件,文件类型取文件后缀
	 *         "target": { "datasource": "ds1" } //到数据源ds1,表名同文件名。
	 *     }
	 * ]
	 * ```
	 * 
	 * ```jsonc
	 * [
	 *     {
	 *         "source": { "zipEntry": "*.csv" },//导入zip中所有csv文件,文件类型取文件后缀
	 *         "target": { "datasource": "ds1" }//到数据源ds1,表名同文件名。
	 *     }
	 * ]
	 * ```
	 * 
	 * ```jsonc
	 * [
	 *     {
	 *         "source": { "zipEntry": "a", "fileFormat": "csv" },//指定文件格式
	 *         "target": { "datasource": "ds1",  "tableName": "tablea" }//指定表名
	 *     },
	 *     {
	 *         "source": { "zipEntry": "b.csv" },
	 *         "target": { "datasource": "ds1" }//表名同源文件名
	 *     }
	 * ]
	 * ```
	 */
	tables: Array<MigrateTableInfo>;
}

/**
 * 描述需要迁移的一个”表“信息。
 * 
 */
interface MigrateTableInfo {

	/** 来源信息 */
	source: BulkDataOptions,

	/** 目标信息 */
	target: BulkDataOptions,

}

/**
 * 一个数据的“源”(对应后端的BulkDataSource.java)的相关选项。
 *
 * “BulkData”理解为数据,泛指结构化的、多行多列的、数据量可能会很大的数据,而“Source”理解为
 * “源”,“BulkDataSource”理解为“结构化数据源”,一个“源”是一个可能可读也可能可写的数据的“所在地”。
 *
 * “BulkDataSource”并不强依赖数据迁移机制,本质上,“BULKDATASOURCE”是一个工具类型的类,可以用于任何
 * 目的的批量读取数据和写入数据。
 *
 * 虽然此对象也叫“源”,但和系统的数据库源不同,此类通常只对一一个具体的表或文件,有一个明确的元数据
 * 结构的源。而系统的数据库源则内部有很多表。
 * 
 * 重要:需与后端`BulkDataOptionNames.java`保持一致。
 */
interface BulkDataOptions {
	/**
	 * 读写模式。
	 * 
	 * 一个“BulkDataSource”只能有一个模式,要么读,要么写。
	 * 
	 * 默认w。
	 */
	iomode?: "r" | "w";

	/**
	 * 将多个{@link BulkDataSource}Union成一个。
	 *
	 * 被联合的多个源的数据结构时一致的,通常用于读取一批文件为一个数据源,或者分库分表时读取多个表为一
	 * 个表。
	 * 
	 * 见{@link BulkDataSourceUnionAll}。
	 */
	unionAll?: BulkDataOptions[];

	/**
	 * 读取数据时的过滤条件。
	 *
	 * 此设置对数据库表和其他类型的数据源都有效,如果是数据库表,那么系统会尽量将过滤条件“下沉”到查
	 * 询SQL中,如果来源是文件,那么系统会自动使用内存计算的方式进行数据过滤。
	 *
	 * 默认空。
	 */
	filter?: string;

	/**
	 * 设置要读取的字段。
	 *
	 * 此设置对数据库表和其他类型的数据源都有效,如果是数据库表,那么系统会尽量将字段查询逻辑“下沉”
	 * 到查询SQL中,如果来源是文件,那么系统会自动使用内存计算的方式进行数据获取。
	 *
	 * 在迁移数据时,如果源头结构和目标结构不一致,可以设置此属性明确要导入的字段,忽略不需要的字
	 * 段,如果来源字段名和目标字段名不一致,那么要通过设置字段别名使其一致。
	 *
	 * 对于自增长字段,只要用户没有明确指定不要自增长字段,系统不再自动忽略它。当明确设置了
	 * {@link selectFields},且包含了自增长字段那么就说明用户希望导入,如果没有设定,那么系统自动根
	 * 据字段名建立映射关系,如果自增长字段存在同名字段,那么也导入不忽略,如果用户不希望导入,那么
	 * 应该从源头忽略这个字段,或者自己设置{@link selectFields}。
	 *
	 * 默认空,表示查询来源的所有字段。
	 */
	selectFields?: Array<string | {
		/**输出字段的别名 */
		alias?: string;
		/**查询表达式,此属性、{@link fieldName}和{@link constValue}必须要有一个设置。 */
		exp?: string;
		/**来源的字段名,此属性、{@link exp}和{@link constValue}必须要有一个设置。 */
		fieldName?: string;
		/**常量,此属性、{@link exp}和{@link fieldName}必须要有一个设置。 */
		constValue?: any;
	}>;

	/**
	 * 当前源的元数据结构。
	 *
	 * 当读写某些特殊的文件时,数据源自己可能无法自己获取元数据信息,此时可以由调用者传递元数据信
	 * 息,便于特定数据源能读写元数据信息。也可能虽然文件有元数据,但是不够好,用户自己编辑了元数
	 * 据,比如数据加工中,用户可以设置文件的元数据结构。
	 *
	 * 默认空,数据源会自己读取元数据(不一定有)
	 */
	metaInfo?: TableMetaInfo;

	//===============================文件源相关属性=======================================//

	/**
	 * 文件路径。
	 * 
	 * 表示要读写的文件的路径。如果没有设置{@link fileFormat},那么将自动取文件后缀作为格式。
	 *
	 * 在导出数据为文件时,如果设置了{@link MigrateDataArgs.zipFile},那么表示导出文件时将所有
	 * 文件压缩为一个文件,此时{@link BulkDataOptions.file} 将用作为压缩文件内部的相对路径,文件
	 * 名和路径需要有业务意义。 
	 */
	file?: string;

	/**
	 * 指定读写压缩文件中的特定文件。
	 *
	 * 此属性只有在设置了{@link MigrateDataArgs.zipFile}之后才有效,此时,导出时表示将所有文件压缩为
	 * 一个文件,此时此属性表示要写入到zip中的文件名。而导入时表示要从zipFile中导入1个或多个表的数
	 * 据,此时此属性可以使用通配符表示导入zip中的一批文件,如`*` 表示导入所有文件(不会递归到子目录
	 * 下)、`*.csv` 表示导入csv文件。
	 *
	 * 相对路径表示,/分隔,不以/开头和结尾。
	 *
	 * 默认空,导出时自动取source的表名当做文件名,导入时表示导入所有文件。
	 */
	zipEntry?: string;

	/** 
	 * 文件格式,通常就是文件的后缀,如`csv`。
	 * 
	 * 默认为{@link file}的后缀。
	 */
	fileFormat?: FileType | string;

	/** 
	 * 文件编码。
	 * 
	 * {@link fileFormat}为`csv`时有效。
	 * 
	 * 默认为`utf-8`
	 */
	encoding?: string;

	/**
	 * 转义字符。
	 *
	 * {@link fileFormat}为`csv`时有效。传统的标准的CSV是不需要转义的,只需要quote,所以默认转义字符
	 * 为0(ASCII 0),表示不需要转义。
	 *
	 * 有时候需要输出非标准的CSV,比如用于数据库导入数据(见pg的copy命令或mysql的load data命令支持的
	 * 格式),数据库导入数据时通常传统的标准CSV在极端情况下会有歧义,比如Mysql会把`NULL`当作null
	 * 值,明确设置转义规则,见{@link BulkDataOptions.escapeCharMappings}。
	 *
	 * 默认为0(ASCII 0),表示不需要转义,如果需要转义,通常应该设置为`\`,需要注意的是,当设置为转
	 * 义时,会自动设置{@link quoteChar}为0(ASCII 0),禁用quote。
	 */
	escapeChar?: string;

	/**
	 * 空字符串(即"")值输出的内容。
	 *
	 * {@link fileFormat}为`csv`时有效。空串不同于空值(即NULL),空字符串不是NULL,它是没有任何内容
	 * 的字符串,有些数据库区分空字符串和NULL,此属性专门用于设定空字符串值是否输出为`""`。
	 *
	 * 默认false,表示空字符串什么都不输出,设置为true则输出为`""`。
	 */
	quoteEmptyValue?: boolean,

	/**
	 * 转义设置,只对{@link escapeChar}存在时有效。
	 *
	 * 当{@link escapeChar}存在时,系统默认转义规则如下:
	 *
	 * - 0  -> "\\0"  -- ASCII 0  An ASCII NUL (X'00') character
	 * - 8  -> "\\b"  -- ASCII 8  backspace character
	 * - 9  -> "\\t"  -- ASCII 9  tab character.
	 * - 10 -> "\\n"  -- ASCII 10 newline (linefeed) character
	 * - 11 -> "\\v"  -- ASCII 11 Vertical tab
	 * - 12 -> "\\f"  -- ASCII 12 Form feed (ASCII 12)
	 * - 13 -> "\\r"  -- ASCII 13 carriage return character
	 * - 44 -> "\\,"  -- ASCII 44 comma character
	 * - 92 -> "\\\\" -- ASCII 92 backslash character
	 * - NULL -> "\\N"  -- NULL值的转义规则,空值(即NULL),不同于空字符串,有些数据库区分空字符串
	 *   和NULL,此属性专门用于设定NULL值输出的形式。
	 *
	 * 通过此参数,可以定制输出的内容的转义规则,设置的新的转义规则会按Ascii码覆盖默认的转义规
	 * 则,key是需要转义的字符的ascii码(NULL特殊,用单词NULL表示),value是转义结果。
	 */
	escapeCharMappings?: JSONObject,

	/**
	 * 设定Blob字段的格式。
	 *
	 * 默认根据文件格式来,csz格式或读取zip中的csv默认为{@link BlobValueFormat.FILE},其他情况为
	 * {@link BlobValueFormat.BASE64}。
	 */
	blobValueFormat?: BlobValueFormat,

	/**
	 * Blob字段的前缀。当{@link blobValueFormat}为{@link BlobValueFormat.BASE64}或
	 * {@link BlobValueFormat.HEX}时有效。
	 *
	 * 比如pg中如果要在文件中包含bytea(在pg中系统使用bytea来存储文件内容)字段的数据,那么它的前缀
	 * 应该是`\x`,考虑到\是转义符,所以文件中可能需要是`\\x`。
	 *
	 * 默认空,表示Blob字段的值直接输出。
	 */
	blobValuePrefix?: string;

	/**
	 * csv格式的列的分隔符。
	 * 
	 * {@link fileFormat}为`csv`时有效。
	 * 
	 * 默认逗号。
	 */
	columnDelimiter?: string;

	/**
	 * 首行是不是列头。
	 * 
	 * {@link fileFormat}为`csv`时有效。
	 *
	 * 如果首行为列头,则在load data的时候,将会skip 1。比如导入带有列头的csv文件等.
	 * 有些类型的文件时先读程csv,用csv的处理逻辑进行导入,比如DBF,此时读取的数据不会包含列头,
	 * 需要在reader中将此属性改为false。
	 *
	 * 导出时,若指定首行不为列头,则仅导出数据,不导出列头。
	 *
	 * 对文件源默认true。
	 */
	firstRowIsColumnName?: boolean;

	/**
	 * 首行格式。
	 * 
	 * {@link fileFormat}为`csv`时有效。可能为以下值:
	 *
	 * 1. `metaInfo`: 元数据完整信息
	 * 2. `columnName`: 逻辑字段名,不存在时使用物理字段名
	 * 3. `dbfield`: 物理字段名
	 *
	 * 默认取`metaInfo`,保证字段信息完整性,避免再次导入时推测字段类型
	 */
	firstRowMetaFormat?: string,

	/**
	 * 文件最开头输出的内容。{@link fileFormat}为`csv`时有效。
	 *
	 * 用于输出一些个性化的文件头,系统在输出beginOfFile后会自动再输出一个换行符,所以调用者不需要在
	 * beginOfFile后面带上行分隔符。
	 *
	 * {@link fileFormat}为`csv`时有效。
	 */
	beginOfFile?: string,

	/**
	 * 文件末尾输出的内容。{@link fileFormat}为`csv`时有效。
	 *
	 * 用于输出一些个性化的文件尾,比如pg从STD导入数据时,需要一个特殊的结束标记`\.`。在输出
	 * endOfFile前,系统会自动输出一个换行符,但系统不会自动在endOfFile后面输出换行符,如果需要,调
	 * 用者可以自己将换行符包含在endOfFile字符串中。
	 *
	 * {@link fileFormat}为`csv`时有效。
	 */
	endOfFile?: string,

	/**
	 * csv格式默认引用符。{@link fileFormat}为`csv`时有效。
	 * 
	 * 当设置了{@link escapeChar}后,此属性会自动设置为0(ASCII 0),表示禁用quote
	 *
	 * 默认为双引号 '"'
	 */
	quoteChar?: string,

	/**
	 * 设置自动文本型数值进行处理(如身份证号),确保使用Excel打开时,不会被Excel自动规整为其他值,不
	 * 会自动自动显示为科学计数法。{@link fileFormat}为`csv`时有效。
	 *
	 * 1. Excel的数字精度只有15位,在显示全数字的身份证号时,会用科学计数法表示,后三位会变成0
	 * 2. Excel会将"001"等自动转为数值,显示为"1"
	 * 3. Excel中会自动将12位以上的文本型整数显示为科学计数法
	 *
	 * 通常在生成导入、校验等报告文件时才需要设置,确保用户用Excel打开csv报告时,能正常看到`身份证号
	 * `,`001`等值。
	 *
	 * 默认false。
	 */
	fixExcelCSVNumber?: boolean;

	/**
	 * 文件的时间戳字段的格式。
	 *
	 * 此选项只作用于读写文件(如csv)时,即便没有设置,系统也会尝试自动推测。
	 *
	 * 写入数据到db不受此选项影响,如果使用通用方式写入数据,那么会直接使用JDBC设置时间戳的相关api函
	 * 数,如果是使用的扩展实现,见{@link BulkDataReader.getCSVStream()},日期格式和时间戳格式都是固
	 * 定的,不受参数设置影响。
	 *
	 * 与日期显示格式一致,使用excel风格的格式串,默认为yyyy-mm-dd hh:mm:ss.000
	 */
	timestampFormat?: string;

	/**
	 * 文件的日期字段的格式
	 *
	 * 此选项只作用于读写文件(如csv)时,即便没有设置,系统也会尝试自动推测。
	 *
	 * 写入数据到db不受此选项影响,如果使用通用方式写入数据,那么会直接使用JDBC设置时间戳的相关api函
	 * 数,如果是使用的扩展实现,见{@link BulkDataReader.getCSVStream()},日期格式和时间戳格式都是固
	 * 定的,不受参数设置影响。
	 *
	 * 与日期显示格式一致,使用excel风格的格式串,默认为yyyy-mm-dd
	 */
	dateFormat?: string;

	//======================== E X C E L 文 件 源 相 关 属 性 ============================//

	/**
	 * 设置excel的列头范围。
	 * 
	 * 1. "1",表示第一行是列头,数据行从0开始
	 * 2. "1~3",表示第一到第三行是列头
	 * 3. "none",表示无列头
	 * 4. "auto", 表示自动推测
	 * 
	 * 为空时自动推测。
	 */
	excelDataHeader?: string;

	/**
	 * 要读写的excel中的sheet。
	 * 
	 * 支持sheet序号(0开始)或sheet名称
	 * 
	 * 为空表示默认读取第一个。
	 */
	excelSheetName?: string | number;

	excelSheetMatch?: string;

	/**
	 * 是否要导出多个sheet。
	 *
	 * 只会导出excel文件有效,比如将多个数据库表文件导出到一个excel文件中,每个数据库表一个sheet,当
	 * 设置true时,{@link MigrateTableInfo.source}应该配置为{@link BulkDataOptions.unionAll}多个表,
	 * 此时每个表都会导出为一个独立的sheet。
	 *
	 * 默认会自动判断,如果多个表的结构都一致,会直接合并成一个sheet,否则自动多个sheet。
	 */
	exportMultiSheet?: boolean;

	//===============================数据库源相关属性=======================================//

	/** 数据源名称,datasource和{@link connection}必须至少指定一个 */
	datasource?: string;

	/**
	 * 数据库连接。
	 *
	 * 如果传递了数据库连接,那么调用者希望使用和调用者自己同一个数据库连接,共享一个事务会话,此时
	 * 通常不能并行读写。与{@link datasource}同时传递时,优先使用{@link datasource}。
	 */
	connection?: Connection;

	/** 
	 * 表所在的schema,null表示默认schema,未quote。
	 */
	schema?: string;

	/** 
	 * 表名,表名不含schema,未quote。
	 */
	tableName?: string;

	/**
	 * 要查询的SQL。
	 *
	 * 表示用户设置的一个自定义SQL。
	 */
	sql?: string;

	/**
	 * {@link sql}的参数。
	 * 
	 * 是一个数组,表示{@link sql}里?对应的参数,这里的参数用于设置给问号参数。
	 */
	sqlParams?: JSONObject;

	/**
	 * 用于查询数据总行数的SQL。
	 *
	 * 否则表示用户设置的一个自定义SQL,用于在源是sql类型时,查询sql的结果集行数。
	 *
	 * 如果不设置,那么系统将不统计总行数,此时可能无法显示一个相对精确的数据迁移进度。
	 */
	countSql?: string;

	/**
	 * {@link countSql}的参数。
	 * 
	 * 是一个数组,表示{@link countSql}里?对应的参数,这里的参数用于设置给问号参数。
	 */
	countSqlParams?: JSONObject;

	/**
	 * 当给来源是一个sql时,是否查询来源表的数据行数,默认true。
	 *
	 * 用于输出复制结果判断复制时是否存在数据丢失。如果仅是查询一个表的总行数,一般会比较快,但是指
	 * 定一个sql用于查询,就可能因为sql复杂度比较高,导致查询数据行数十分耗时的情况。
	 */
	queryTableRowcount?: boolean;

	/**
	 * 分片模式。
	 *
	 * 此属性只对从数据库表读取数据生效,即{@link tableName}存在时,读取文件、SQL都不能分片。
	 *
	 * 扩展开发时系统会自动进行分片,并将每个分片的查询单独传递给扩展,扩展只需要实现一个分区的读取
	 * 即可,具体见{@link ExtBulkDataSourceCtx.sql}属性。
	 *
	 * 默认空,不分片。
	 */
	sliceMode?: TableDataSliceMode;

	/**
	 * 按此字段分片并发读写。
	 *
	 * 此属性是否生效依赖{@link sliceMode}的设置,需要注意:
	 *
	 * 1. 分片字段必须是主键或索引字段,只有这样才能提高查询效率。
	 * 2. 支持整形、字符、日期字段类型,不支持浮点类型。
	 */
	sliceField?: string;

	/**
	 * 最多分片片数。
	 *
	 * 按{@link sliceField}进行分片时最大的分片片数。如果实际的数据比较少,那么分片可能会少一些,但
	 * 不会多于这个设置。
	 * 
	 * 默认100.
	 */
	sliceMaxCount?: number;

	/**
	 * 分片时每片的最小数据量。
	 *
	 * 期望分片的最小值,如果根据数据总行数和{@link sliceMaxCount}计算出来的每个分片数据行数小于这个设
	 * 置,则会尝试自动调整分片的数量。如果数据中行数太小,还不足以分2片,那就会放弃分片。
	 *
	 * 默认 30000
	 */
	sliceMinSize?: number;

	//========================== 数 据 迁 移 相 关 选 项 ==================================//

	/**
	 * 设置一个批次传输给数据库的数据行数。
	 *
	 * 该值可以极大减少应用与数据库的网络交互次数,并提升整体吞吐量。通常在512~5000之间,不宜太小、
	 * 也不宜太大(可能OOM)。
	 * 
	 * 此属性必须设置为大于1的整数。
	 * 
	 * 默认1024。
	 */
	batchSize?: number;

	/**
	 * 是否分批提交数据。
	 *
	 * 为true时每个批次都会独立的提交数据,在迁移海量数据时不会因为巨大事务导致失败,也不会因为因为
	 * 少量数据失败而导致所有数据导入回滚。
	 *
	 * 迁移海量数据时由于极少的数据不合法或者是偶尔的网络故障而导致迁移失败是很让人崩溃的,分批提交
	 * 可以让能成功导入的数据尽量成功导入。有些数据库不支持超大事务(比如TiDB),所以对于导入海量数
	 * 据的情况,如果不启用该选项可能无法导入数据。
	 *
	 * 数据是分批传递给数据库的(见{@link batchSize}),但事务可能并未提交,比如有100w行数据要导入到
	 * 目标表,每个批次是1000行,如果启用了该选项,那么每个批次都会执行提交事务(即数据库的
	 * commit),即便后面有错误没有完全导入,但是前面的批次都是入库了的。但如果没有启用该选项,那么
	 * 100w行数据将整体提交事务,如果有一行导入失败,那么所有行都会回滚,不会导入成功。
	 *
	 * 默认true。
	 */
	batchCommit?: boolean;

	/**
	 * 设置对目标表的数据清理模式。
	 *
	 * 此属性为{@link DataClearMode.TRUNCATETABLE}时或者为{@link DataClearMode.CLEARTABLE}且
	 * {@link batchCommit}==true,那么在调用dbconnector实现的扩展数据加载器{@link ExtBulkDataWriter}
	 * 时会自动先把表清空,扩展开发时不需要自己处理。
	 *
	 * 如果此属性为{@link DataClearMode.CLEARTABLE},且此时{@link batchCommit}==false,扩展开发者需
	 * 要自己清理表数据,并要和数据加载过程在一个事务完成。
	 *
	 * 默认{@link DataClearMode.NO},这最安全,不会覆盖用户的数据。
	 */
	dataClearMode?: DataClearMode;

	/**
	 * 设置对目标表的数据覆盖模式。
	 *
	 * 默认{@link DataOverwriteMode.APPEND},这最安全,不会覆盖用户的数据。
	 */
	dataOverwriteMode?: DataOverwriteMode;

	/**
	 * 设置目标表的创建模式。
	 *
	 * 在调用扩展提供的源时,对于需要重建、清空表的覆盖模式,系统会自动提前处理好,扩展开发者不需要
	 * 做处理。
	 *
	 * 默认{@link DataOverwriteMode.CREATEIFNOTEXISTS},这最安全,不会覆盖用户的数据。
	 */
	tableCreateMode?: TableCreateMode;

	/**
	 * 这个选项是上面2个选项{@link tableCreateMode}和{@link dataOverwriteMode}的一个组合,当没有传递
	 * 上面的选项时可以传递这个,更便捷一点。
	 *
	 * 默认null。
	 */
	dataImportMode?: DataImportMode;

	/**
	 * 当{@link dataOverwriteMode}为{@link DataOverwriteMode.MERGE}时,明确设定字段的插入和更新规
	 * 则。
	 *
	 * 默认的数据迁移时,在设置为合并模式时,如果数据不存在系统会自动按照同名字段的规则去插入目标表
	 * 的数据,如果数据存在,系统会忽略主键唯一索引等字段,更新其他同名字段,但有时候可能调用者希望
	 * 更新特定字段,此时可以传递此参数。
	 *
	 * 同一个目标字段可以在此数组中有2个,其{@link FieldUpdateMappingInfo.mode}不同,一个是INSERT,
	 * 一个是UPDATE,通常是用于定义当数据已存在时更新的值和插入的值不同的情况。
	 *
	 * 默认空,将按照同名字段的规则忽略唯一键的字段进行更新。
	 */
	columnMapping?: Array<FieldUpdateMappingInfo>,

	/**
	 * 当如果需要drop掉一个表时,不要真的drop它,而是把它rename为一个BAK开头的表。
	 *
	 * 默认true,设置为false时,如果数据覆盖模式是{@link TableCreateMode.RECREATETABLE}那么目标表将被drop
	 * 掉。
	 */
	backupTableRename?: boolean;

	/**
	 * 当遇到导入错误的数据行时,最多允许多少错误的行。
	 *
	 * 当使用JDBC+INSERT语句导入数据时,系统会使用JDBC的executeBatch机制,在遇到错误后,并不能知道具
	 * 体哪行错了,此时会尝试逐行插入,这是为了能更准确的定位错误的数据行且尽量多的导入能导入的数
	 * 据。所以此时此选项只有在{@link batchCommit}为true时有效。如果对太多错误的数据行进行尝试也会耗
	 * 费大量时间,需要设置一个合理的值,比如设置100。
	 *
	 * 当使用扩展提供的导入方式时,由扩展选择如何处理此选项,比如starrocks会通过一个url告诉调用者错
	 * 误的数据信息,而vertica会通过写入一个临时文件来告诉调用者,扩展实现者需要在获取到错误信息后,
	 * 调用{@link ExtBulkDataSourceCtx.notifyErrorRow()}函数来告诉系统错误的数据行信息。
	 *
	 * 默认0,表示导入过程中不接受一行失败,如果遇到错误,配置0会至少重试一次(JDBC+INSERT模式),这
	 * 样可以知道具体哪行错误了,如果设置为-1表示不进行尝试,遇到错误就退出。大于0则进行尝试直
	 * 到遇到错误行数大于等于设置的行数。
	 *
	 * 默认0。
	 */
	maxErrorRowCount?: number;

	/**
	 * upsert语句的依据字段列表。
	 *
	 * 如果传递该值,则直接使用,否则会从数据库中查找主键、索引进行筛选。
	 */
	uniqueKey?: string;

	/**
	 * 在并发迁移一个大表数据时,最开始添加到线程池中的最大数据读取的任务数量。
	 *
	 * 用于调节并合理利用线程资源,将一个大表进行分片操作分了100片,生产者就有100个,同时开100个线程
	 * 从数据库中读取数据,若是网络带宽仅支持30线程的并发,单位时间内生产的数据也没办法跟随生产者的
	 * 增加而加快,反倒因为线程池可能都被占满了,阻塞了其他任务的进行。
	 * 
	 * 此选项是每个表独立作用的,配置在source源。
	 *
	 * 默认5,不能设置小于1、不能大于线程池的最大线程数的1/2,也不能大于
	 * {@link maxTableParallelReaders}。
	 */
	initTableParallelReaders?: number;

	/**
	 * 在并发迁移一个大表数据的过程中最多同时运行的数据读取线程数。
	 *
	 * 并发迁移大表数据时,在并发模式下,系统会自动调节数据读取任务和数据写入任务之间的平衡,通过动
	 * 态增加数据读取线程和动态增减数据写入线程,尽量合理利用系统资源,保持读写能力平衡,尽量上数据
	 * 生产端减少阻塞、也尽量让数据消费端减少等待。
	 *
	 * 此选项是每个表独立作用的,配置在source源。
	 *
	 * 默认是线程池的最大线程数的1/2,不能设置小于1或大于线程池的最大线程数的1/2。
	 */
	maxTableParallelReaders?: number;

	/**
	 * 在并发迁移一个大表数据的过程中最多同时运行的数据写入线程数。
	 *
	 * 并发迁移大表数据时,在并发模式下,系统会自动调节数据读取任务和数据写入任务之间的平衡,通过动
	 * 态增加数据读取线程和动态增减数据写入线程,尽量合理利用系统资源,保持读写能力平衡,尽量上数据
	 * 生产端减少阻塞、也尽量让数据消费端减少等待。
	 *
	 * 此选项是每个表独立作用的,配置在target源。
	 *
	 * 默认是线程池的最大线程数的1/2,不能设置小于1或大于线程池的最大线程数的1/2。
	 */
	maxTableParallelWriters?: number;

	/**
	 * 在迁移一个大表数据时当来源数据最少有多少行时才会启动并行写入。
	 *
	 * 如果要写入的数据不多,那么单个数据写入线程就够了,通常当数据量大于一定量启动多线程并发写入才
	 * 会更有效率。对于导入文件或从其他数据库迁移表此参数都生效,来源是文件时会自动估算行数。
	 * 
	 * 此选项是每个表独立作用的,配置在target源。
	 *
	 * 默认是20000。
	 */
	minTableParallelWriteDataRowCount?: number;

	/**
	 * 是否禁用数据库本地的、高性能的数据批量读写方式。
	 *
	 * db是否支持数据库本地的、高性能的数据批量读写方式是由db自身和db-connector决定的,此处的选项只
	 * 是给了用户一个机会,让用户可以选择不用它。
	 * 
	 * 此选项是每个表独立作用的,配置在target源。
	 *
	 * true,表示调用者禁用,false或空表示根据db自身和dbconnector判断
	 */
	disableBulkLoad?: boolean;

	/**
	 * 禁用通用的基于JDBC+SQL的数据写入机制。
	 *
	 * 默认情况下如果dbconnector实现了自己的数据加载机制,则会优先使用它,当遇到错误后,只要db支持
	 * insert语句/upsert语句等系统会自动考虑使用JDBC+SQL机制写入,此选项用于在某些特殊场合下即便
	 * dbconnector的实现出现错误后也不用继续使用JDBC+SQL方式做尝试了。
	 *
	 * 在{@link ExtBulkDataSource.prepareCtx()}函数或其他数据读写过程中,如果实现类判断当前数据源不
	 * 支持通用的JDBC模式读写数据,可以主动设置传入的options参数的此属性,此时系统后续就不会继续尝试
	 * 使用jdbc+sql方式读写数据了。
	 *
	 * 类似 {@link disableCommonReader}
	 *
	 * 默认false。
	 */
	disableCommonWriter?: boolean;

	/**
	 * 禁用通用的基于JDBC+SQL的数据读取机制。
	 * 
	 * 类似 {@link disableCommonWriter}
	 * 
	 * 默认false。
	 */
	disableCommonReader?: boolean;

	/** 目标表的描述,新建目标表时使用,不传递时将自动取源表的描述。 */
	tableComment?: string;

	/**
	 * 拓展文件类型的数据迁移自定义属性。
	 *
	 * 这个属性在生成reader和writer时使用,读写工具可以读取这个配置来调整读写逻辑,例如:
	 *
	 * 1. 是否要输出列头;
	 * 2. 设置输出日期的格式;
	 * 3. 将数值型输出为千分符、科学计数法、中国大写等;
	 * 4. 自定义读取文件的模式,例如读取简历格式的pdf和读取表格型的pdf肯定会使用不同的算法;
	 * 5. 读取excel时,前几行需要合并为列头;
	 * 6. 其他定制逻辑...
	 *
	 * @see DataFileReaderExtensionContributorInfo.propertyItems
	 *
	 */
	[propertyName: string]: any;
}

/**
 * 读取数据库表时的分片模式。
 *
 * 从一个巨大的csv文件或一个巨大的数据库表迁移数据到另一个库表时可以使用并行模式,可以加快性能。
 */
declare const enum TableDataSliceMode {
	/**
	 * 自动切片。
	 *
	 * 根据总行数、主键字段,自动判断。必须存在主键,且数据行数必须大于
	 * {@link BulkDataOptions.sliceMinSize}的2倍。
	 */
	auto = "auto",

	/**
	 * 根据字段值的连续范围切片。
	 *
	 * 分析{@link BulkDataOptions.sliceField}的最大值和最小值,按{@link BulkDataOptions.sliceMaxCount}
	 * 设置的片数进行切片。
	 */
	fieldRange = "fieldRange",

	/**
	 * 根据字段值的离散值分片。
	 *
	 * 分析{@link BulkDataOptions.sliceField}的所有值,一个值一个分片,通常用于分片例如月份、地区、
	 * 产品类型等相对粗粒度的数据。
	 */
	fieldDistinct = "fieldDistinct",
}

/**
 * {@link ExtendPoint.dataFile} 拓展点。
 *
 * 拓展可以提供自定义的文件类型读取和写入的工具,用于支持产品原生不支持的文件类型,例如希望支持XML的
 * 读写,或是需要支持一种特殊样式的Excel文件读写。
 *
 * 增加拓展后可用于需要文件读的产品功能:
 *
 * 1. 导入文件到数据库;
 * 2. 数据加工的文件节点
 *
 * 约定在{@link ExtensionContributeInfo.main} 对应的脚本文件中定义脚本的写实现,实现接口参考
 * {@link ExtBulkDataSourceContributor}
 *
 */
declare interface DataFileExtensionContributorInfo extends ExtensionContributeInfo, CustomScriptClassInfo {

	/** 
	 * 文件类型。
	 *
	 * 通常是文件的后缀(小写,如`dat`),可以配置多个,如`["dat","data"]`,每当系统要打开这里设置的
	 * 类型的文件时都会尝试使用此扩展打开,见{@link ExtBulkDataSourceContributor}.
	 */
	fileFormat: string | string[];

	/** 
	 * 自定义属性。
	 *
	 * 配置后加工在拖入该文件类型时会自动显示这些自定义属性,用户可以在界面上修改设置来实现同一类型
	 * 文件的不同导入效果。
	 *
	 * 保存后的属性将以键值对的形式存储在元数据中。
	 *
	 * @see DataFileExtensionMigrateOptions
	 *
	 */
	optionItems?: CommonExtesionPropertyFormItemInfo[];
}

/**
 * {@link ExtendPoint.dataFile} 拓展点中提供的第三方开发者编写的贡献器。
 *
 * 此接口可以是纯脚本实现,此时只需要在{@link CustomScriptClassInfo.script}指定的脚本文件中存在接口
 * 约定的函数`createBulkDataSource`即可。
 *
 * 也可以是java实现,此时需要开发一个java类,并将类完整路径设置在
 * {@link CustomScriptClassInfo.javaClass},系统会自动创建一个它的实例,此实例对象会被长期使用,多线
 * 程调用。java类实现时必须实现`com.succez.commons.jdbc.migrate.BulkDataSourceContributor`接口。
 * 
 * 对应后端的`ExtBulkDataSourceContributor.java`
 */
declare interface ExtBulkDataSourceContributor {

	/**
	 * 尝试询问此贡献器是否支持这类源,如果支持则返回一个可用的实例。
	 *
	 * @param type 源类型,如果是文件,那么通常是文件的后缀(小写)。
	 * @param options 可为null,可能设置的属性见{@link BulkDataOptions},实现者需要直接引用这个对象,
	 *        在后续的执行过程中其中的一些选项可能会被修改或设置,实现者应该在需要用的时候从中获取,
	 *        不必提前获取(也许还不存在)。
	 * @return 如果不支持,返回null。
	 */
	createExtBulkDataSource(type: string, options: BulkDataOptions): ExtBulkDataSource;
}

/**
 * 下面这批选项是用于扩展开发时使用的。
 *
 * 用于传递给扩展开发的的相关读写函数,方便扩展开发者获取到足够的信息。
 * 
 * 重要:需与后端`ExtBulkDataSourceCtxNames.java`保持一致。
 */
declare interface ExtBulkDataSourceCtx {

	/**
	 * 所在的{@link BulkDataSource}的选项。
	 */
	options: BulkDataOptions;

	/** 
	 * 表所在的schema,null表示默认schema,等价于{@link BulkDataOptions.schema}。
	 */
	schema?: string;

	/** 
	 * 表名,表名不含schema,等价于{@link BulkDataOptions.tableName}。
	 */
	tableName?: string;

	/**
	 * 读写模式,等价于{@link BulkDataOptions.iomode}。
	 */
	iomode: "r" | "w";

	/**
	 * 是否是全表查询。
	 *
	 * 为true时不存在{@link BulkDataOptions.filter}或者{@link BulkDataOptions.selectFields}属性,且
	 * 不是一个切片查询,关于切片,见{@link sliceInfo}。
	 */
	isSelectFullTable: boolean;

	/**
	 * 为true,表示存在查询条件或切片条件。
	 */
	hasSelectFilter: boolean;

	/**
	 * 是否存在BLOB字段。
	 * 
	 * 对“读”模式有效,表示查询字段中有blob。
	 */
	hasSelectBlobs: boolean;

	/**
	 * 当前切片信息。
	 * 
	 * 如果存在此属性,表示当前查询是一个切片查询,关于切片见{@link BulkDataOptions.sliceMode}。
	 */
	sliceInfo: { field: string, maxValue: any, minValue: any, isNull: boolean };

	/**
	 * 要读取的字段列表。
	 *
	 * 此属性是读取并分析{@link BulkDataOptions.selectFields}后形成的结构化信息。不存在时表示查询的
	 * 是所有字段。
	 */
	selectFields: Array<{
		/**输出字段的别名 */
		alias?: string;
		/**查询表达式,此属性、{@link fieldName}和{@link constValue}只会有一个存在。 */
		exp?: string;
		/**来源的字段名,此属性、{@link exp}和{@link constValue}只会有一个存在。 */
		fieldName?: string;
		/**常量,此属性、{@link exp}和{@link fieldName}只会有一个存在。 */
		constValue?: any;
	}>;

	/**
	 * 要查询的SQL。
	 *
	 * 此属性不完全等价于{@link BulkDataOptions.sql},当要读取一个数据库表(不是SQL)时,为了方便扩
	 * 展开发,系统也会自动准备一个等价的SQL一起传给扩展。所以如果{@link tableName}存在,那么此属性
	 * 表示查询的是数据库表,而此时此属性就是融入了{@link BulkDataOptions.filter}、
	 * {@link BulkDataOptions.selectFields} 和切片条件(见{@link BulkDataOptions.sliceMode})的一个
	 * sql,即便没有这些设置,此属性也会生成,主要目的就是方便扩展开发。
	 *
	 * 当{@link tableName}不存在时,此属性表示用户设置的一个自定义SQL。
	 */
	sql?: string;

	/**
	 * {@link sql}的参数,等价于{@link BulkDataOptions.sqlParams}。
	 * 
	 * 是一个数组,表示{@link sql}里?对应的参数,这里的参数用于设置给问号参数。
	 */
	sqlParams?: JSONObject;

	/**
	 * 获取数据库连接。
	 *
	 * 1. 在脚本中,第一次访问此变量时才会进行数据库连接。有些dbconnector导入数据,不需要获取数据库
	 *    连接。
	 * 2. 返回的连接对象不是原始的db driver的驱动对象,而是系统包装了的一个对象,如果需要使用数据库
	 *    驱动的原始连接对象,可以使用`conn.unwrap(com.mysql.cj.jdbc.ConnectionImpl)`获取。
	 * 3. 开发者不要自己关闭此连接,系统会自动关闭的。
	 */
	conn?: Connection,
	/**
	 * 数据库连接配置
	 */
	jdbcConf?: JdbcConfigInfo,

	/**数据库的方言对象 */
	dialect?: DbDialect,

	/**
	 * 相关运行状态。
	 * 
	 * 用于放回数据交互状态,例如写入了多少行数据,也用于记录一些日志信息。
	 */
	runningState: IORunningState,

	/**
	 * [org.slf4j.Logger](https://www.slf4j.org/api/org/slf4j/Logger.html) 对象。
	 *
	 * 可以用于输出一些技术日志。
	 */
	log4j: any,

	/**
	 * 当前源的元数据结构。
	 *
	 * 此属性由调用者提供( {@link BulkDataOptions.metaInfo}),当数据源自己无法自己获取元数据信息
	 * 时可以使用,比如要写入一个excel文件时传递有意义的列头。
	 */
	metaInfo?: TableMetaInfo;

	/**
	 * 表示将使用{@link ExtBulkDataWriter.copy()}函数进行数据复制的来源数据。
	 *
	 * 可能为null,此时通常并不是在迁移数据过程中,而是准备通过{@link ExtBulkDataWriter#writeRow()}
	 * 逐行写入文件数据。
	 */
	copyFrom?: BulkDataSource;

	/**
	 * 是否分批提交数据。等价于{@link BulkDataOptions.batchCommit}。
	 */
	batchCommit: boolean;

	/**
	 * 数据清理模式,等价于{@link BulkDataOptions.dataClearMode}。
	 */
	dataClearMode: DataClearMode;

	/**
	 * 数据覆盖模式,等价于{@link BulkDataOptions.dataOverwriteMode}。
	 */
	dataOverwriteMode: DataOverwriteMode;

	/**
	 * {@link ExtBulkDataWriter.copy()}时的来源查询或文件的元数据信息。
	 *
	 * 通过此属性可以获取来源的相关信息,其中包括:
	 *
	 * 1. {@link BulkDataReader.getOptions()}返回来源的相关选项,如果是csv文件,还包括首行是否是列
	 *    头、编码等信息。
	 * 2. {@link BulkDataReader.getMetaInfo}返回来源的元数据信息。
	 *
	 * 如果是csv文件,且csv文件没有在列头指定字段列表,那么这个信息与 targetMetaInfo保持一致,默认
	 * csv文件格式就是根据目标表来构建的
	*/
	srcMetaInfo?: TableMetaData,

	/**
	 * {@link ExtBulkDataWriter.copy()}时的来源查询或文件的相关选项。
	 *
	 * 如果来源是csv文件,包括{@Link BulkDataOptions.firstRowIsColumnName}、
	 * {@Link BulkDataOptions.encoding}等信息。
	 */
	srcOptions?: BulkDataOptions,

	/**
	 * {@link ExtBulkDataWriter.copy()}时所有要导入数据字段的信息。
	 *
	 * 如果字段不需要导入,不会在此数组中。所以此数组的长度和{@link srcOptions.metaInfo}与
	 * {@link targetMetaInfo}中的可能不一致。当导入模式是合并时,可能同一个目标字段会在此数组中有2
	 * 个,其{@link FieldUpdateMappingInfo.mode}不同,一个是INSERT,一个是UPDATE,通常是用于定义当数
	 * 据已存在时更新的值和插入的值不同的情况。
	 *
	 * 对于自增长字段,只要用户没有明确指定不要自增长字段,系统不会自动忽略它。
	 *
	 * 当用户明确指定了{@link BulkDataOptions.selectFields}时,那如果包含了自增长字段那么就说明用户
	 * 希望导入,如果没有自定,那么系统自动根据字段名建立映射关系,如果自增长字段存在同名字段,那么
	 * 也导入不忽略,如果用户不希望导入,那么应该从源头忽略这个字段,或者自己设置
	 * {@link BulkDataOptions.selectFields}。
	 */
	targetFields?: Array<FieldUpdateMappingInfo>,
	/**
	 * {@link ExtBulkDataWriter.copy()}时要导入的字段中是否存在Blob字段。
	 */
	hasBlobTargetFields?: boolean,
	/**
	 * 有计算字段、常量字段或者当前时间戳字段要导入。
	 */
	hasExtraTargetFields?: boolean,
	/**
	 * {@link ExtBulkDataWriter.copy()}时忽略的不导入的且也没有默认值的目标表字段。
	 */
	hasIgnoredTargetFields?: boolean,

	/**
	 * 是否所有来源字段都被导入且与目标字段一一对应,没有计算字段、常量字段和当前时间戳字段。
	 *
	 * 为true时表示所有来源字段都导入了,没有忽略的,也没有多余的,但不保证目标表的所有字段都存在,
	 * 可能部分目标表的字段不需要导入数据。
	 */
	targetFieldsMatchAllSrcFields?: boolean,

	/**
	 * 提供给扩展开发调用的向系统反馈的事件接口。
	 * 
	 * 比如遇到了导入不了的数据行需要通知系统。
	 */
	monitor: ExtBulkDataMonitor,

	/**
	 * 拓展文件类型的数据迁移自定义属性。
	 *
	 * 这个属性在生成reader和writer时使用,读写工具可以读取这个配置来调整读写逻辑,例如:
	 *
	 * 1. 是否要输出列头;
	 * 2. 设置输出日期的格式;
	 * 3. 将数值型输出为千分符、科学计数法、中国大写等;
	 * 4. 自定义读取文件的模式,例如读取简历格式的pdf和读取表格型的pdf肯定会使用不同的算法;
	 * 5. 读取excel时,前几行需要合并为列头;
	 * 6. 其他定制逻辑...
	 *
	 * @see DataFileReaderExtensionContributorInfo.propertyItems
	 *
	 */
	[propertyName: string]: any;
}

/**
 * 提供给扩展开发调用的向系统反馈的事件接口。
 * 
 * 比如遇到了导入不了的数据行需要通知系统。
 */
interface ExtBulkDataMonitor {

	/**
	 * 方便扩展开发时通知系统错误的数据行。
	 * 
	 * @param args 
	 */
	notifyErrorRow(args: {
		/**错误描述信息 */
		rejectError: string,
		/**错误的数据行内容,如果行是从文件读取时就解析错误了,比如不合法的行格式,那么可能此属性为空或者只有一个行字符串,否则是一个一维数组,表示来源表的每列的数据 */
		rejectRow: any,
		/**错误的数据行号,0开始 */
		rejectRowIndex: number,
		/**当前累计的总错误行数 */
		rejectRowCount: number,
	}): void,
}

/**
 * 用于给扩展开发者实现一个结构化的、多行多列的、数据量可能会很大的数据表或文件对象的读写能力。
 *
 * "Ext"理解为扩展的,“BulkData”理解为数据,泛指一个结构化的、多行多列的、数据量可能会很大的数据表或
 * 文件,而“Source”理解为“源”,特指一个“表”级别的数据源,“ExtBulkDataSource”理解为“扩展的结构化数据
 * 源”,一个“源”是一个可能可读也可能可写的数据的“表”。
 *
 * 此接口与内部的{@link BulkDataSource}接口相似但不同,此接口主要定位给扩展开发实现使用,注意是扩展
 * 实现,也就是说当要开发一个自定义的数据读写器扩展“贡献”给系统时使用,此类接口更简单、更稳定、接口
 * 引用的其他对象更“朴实”,方便扩展开发者实现。
 *
 * 此接口通常用于扩展:
 *
 * 1. 高性能读写海量数据的接口,用于{@link ExtendPoint.dbConnector},以实现调用db最优的数据读写能
 *    力。
 * 2. 读写特定格式的数据文件的能力,如读写某个特殊格式的xml文件。
 *
 * 大部分db都支持select/insert into/update等语句写入数据,也能做到所有读写数据的功能需求,但是性能并
 * 不是最优的,而基本上所有的db都支持快速读写数据的相关API或工具,比如Mysql可以使用load data语句直接
 * 从csv文件读写数据,性能比较好。此接口的目的之一就是给dbconnector一个机会可以调用db自己最优的数据
 * 读写方式,以实现最优的数据读写性能体验。当然如果dbconnector不实现此接口,系统也会使用sql的
 * select/insert into/upsert/merge等语句取实现数据的读写。
 *
 * 也有些分析型db,如maxcompute,不支持update/upsert/insertinto等sql语句,此时dbconnector必须实现此
 * 接口,否则系统就不支持导入数据到db了,当然这不影响数据的查询分析等只读能力。
 *
 * 此接口可以完全用脚本实现,也可以提供java实现,通常脚本用于实现“胶水”代码,主体的耗费cpu的逻辑都在
 * 脚本调用的其他api中,此时用脚本更方便维护更容易迁移,但脚本不适合执行大了耗费cpu的逻辑,比如逐行
 * 遍历海量数据和字段,脚本性能不如java,此时java实现更好。如果用java类实则必须实现
 * `com.succez.commons.jdbc.migrate.ExtBulkDataSource`接口。
 *
 * 此接口的同一实例可能会被多线程使用,但系统会确保同一时刻只有一个线程调用此对象的api。
 *
 * 对应后端接口`ExtBulkDataSource.java`,需与其保持同步修改!!!
 */
declare interface ExtBulkDataSource {
	/**
	 * 返回元数据信息。
	 *
	 * 此函数用于扩展实现返回自定义数据源的元数据结构信息,比如一个特别的xml文件格式,如果当前数据源
	 * 是数据库表,那么可以不实现此函数,系统会自动使用JDBC的相关api获取元数据信息。
	 *
	 * 这里返回的是读取这个源时的数据结构,元数据信息需要和{@link ExtBulkDataReader.getRow()}读取的
	 * 数据结构严格一致,包括字段个数和字段顺序。需要注意的是,如果是读取的数据库表,则可能会首
	 * {@link BulkDataOptions.selectFields}选项影响,不一定与表结构完全一致。
	 *
	 * 返回的元数据信息可能会被用于数据迁移时创建目标表的表结构、或者建立来源和目标字段之间的映射关
	 * 系。
	 * 
	 * @param ctx 选项参数,对文件或数据库表参数会不同,具体见{@link ExtBulkDataSourceCtx}。
	 * @param inferIfMetaNotExist 是否在无法查询元数据信息的时候根据数据推断元数据结构。例如当源是
	 *        csv或excel文件时,文件中是没有元数据的,此时如果需要根据来源新建目标表的表结构,就需要
	 *        能自己推断结构了。推测元数据结构需要读取数据,可能会有一定代价。
	 * @return 返回来源的元数据结构,或推测的结构,是一个JSON结构,具体见前端接口定义
	 *        `TableMetaInfo`,可能返回null表示无法获取。
	 */
	getMetaInfo?(ctx: ExtBulkDataSourceCtx, inferIfMetaNotExist: boolean): TableMetaInfo;

	/**
	 * 做些读取数据前的准备工作。
	 *
	 * 通常不需要实现此函数。
	 */
	prepareRead?(ctx: ExtBulkDataSourceCtx): void;

	/**
	 * 做些数据写入前的准备工作。
	 *
	 * 在此函数中做一些准备工作,例如,做一些预编译工作。系统在调用{@link #openWriter()}或
	 * {@link #prepareCtx()}前,一定会先调用此函数。如果是在进行批量数据迁移,那么通常所有表的准备
	 * 工作都做完毕后才会开始提取。
	 */
	prepareWrite?(ctx: ExtBulkDataSourceCtx): void;

	/**
	 * 创建一个用于多线程并发读写数据共享的上下文对象。
	 *
	 * 一个超大表,可能会分片并发迁移数据,此时会有多个线程并发读写数据,每个线程负责一片数据,在有
	 * 些数据库上,并发分片读写数据时可以共享一些上下文对象来提升性能(比如在使用MacCompute数据库的
	 * Tunnel SDK时,UploadSession对象就是可以多线程共享的),{@link BulkDataOptions.parallel}选项表
	 * 示当前是否将要进行并发读写,此函数给了个实现者一个机会创建分片读写器之间共享信息的上下文对
	 * 象。
	 *
	 * 此函数需要判断{@link BulkDataOptions.iomode}中设置的读写模式,根据不同的模式准备相应的上下
	 * 文,当遇到不支持的情况时,比如只支持写模式不支持读模式、只支持数据的全量覆盖或追加但不支持按
	 * 主键合并、流式导入接口不支持blob字段等等,此函数应该抛出`unsupported:`开头的异常,并尽量在异
	 * 常对象中说明原因,此时系统会认为连接器不支持这种情况的高性能读写。如果异常不是`unsupported:`
	 * 开头,那么系统会直接抛出并终止执行。如果函数正常执行,则系统认为可以执行读写。
	 *
	 * 此函数由调用者自己选择是否调用,当调用者需要并发读或写这个对象的数据时通常应该调用,而如果只
	 * 是单线程读或写,则不需要调用。调用者会在最后不需要时会调用{@link releaseCtx}释放对象。
	 *
	 * 读如果读写操作都很简单,没有什么资源需要提前准备,也可以不实现此函数和{@link prepareCtx()}函
	 * 数。
	 *
	 * 整个读写过程的调用方式类似:
	 *
	 * ```ts
	 *     src.prepare(options);
	 *     try{
	 *         //src.openReader(options),
	 *         //src.openWriter(options...,可能会创建多个,并在不同线程写入数据
	 *         //wait all readers or writers finish and close.
	 *     }
	 *     catch(e){
	 *         error = e;
	 *     }
	 *     finally{
	 *         src.release(options, isCancelError(error));
	 *     }
	 * ```
	 *
	 * @param ctx 选项参数,对文件或数据库表参数会不同,具体见{@link ExtBulkDataSourceCtx}。
	 */
	prepareCtx?(ctx: ExtBulkDataSourceCtx): void;

	/**
	 * 结束读写,释放上下文资源。
	 *
	 * 具体业务使用场景见{@link prepareCtx()}。
	 *
	 * @param ctx 选项参数,对文件或数据库表参数会不同,具体见{@link ExtBulkDataSourceCtx}。
	 * @param canceled 为true时,表示用户执行了取消操作,此时需要执行回滚操作。
	 */
	releaseCtx?(ctx: ExtBulkDataSourceCtx, canceled?: boolean): void;

	/**
	 * 打开数据读取器。
	 *
	 * 此函数用于扩展实现读取一些自定义的数据源,如通过专用api高性能读取db的数据、读取一个自定义格式
	 * 的xml数据文件等。对于数据库表也可不实现此函数,此时系统会自动尝试使用JDBC+SQL方式读取数据。
	 *
	 * 如果过程中有一些日志需要输出,包括执行的sql,可以通过
	 * {@link ExtBulkDataSourceCtx.runningState}对象的{@link IORunningState.log}函数记录。也可以通过
	 * {@link IORunningState.set()}函数返回一些其他状态给系统。
	 *
	 * 通常一个源,可以多次调用{@link openReader()},就像同时并发查询一个表的数据或同时读取一个文件
	 * 的数据一样。但需要注意,一个openReader就是一个open,要对应一个
	 * {@link ExtBulkDataReader.close()}的,调用者需要确保自己关闭返回的对象。
	 *
	 * @param ctx 选项参数,对文件或数据库表参数会不同,具体见{@link ExtBulkDataSourceCtx}。
	 * @return 不会返回null,如果不支持,此函数应该抛出`unsupported:`开头的异常,并尽量在异常对象中
	 *         说明原因,此时系统会认为连接器不支持这种情况的高性能读写。如果异常不是`unsupported:`
	 *         开头,那么系统会直接抛出并终止执行。
	 */
	openReader?(ctx: ExtBulkDataSourceCtx): ExtBulkDataReader;

	/**
	 * 打开一个数据写入器。
	 *
	 * 此函数用于扩展实现写入一些自定义的数据源的数据,如通过专用api高性能导入db的数据、写入一个自定
	 * 义格式的xml数据文件等。对于数据库表也可不实现此函数,此时系统会自动尝试使用JDBC+SQL方式写入数
	 * 据。
	 *
	 * 如果过程中有一些日志需要就,包括执行的sql,可以通过{@link ExtBulkDataSourceCtx.runningState}
	 * 对象的{@link IORunningState.log}函数记录。也可以通过{@link IORunningState.set()}函数返回一些
	 * 其他状态给系统。
	 *
	 * 通常一个数据库表,可以多次调用{@link openWriter()}并发写入数据,但文件就不行。需要注意,一个
	 * openWriterr就是一个open,要对应一个{@link ExtBulkDataWriter#close()}的,调用者需要确保自己关
	 * 闭返回的对象。
	 *
	 * 如果当前数据源是数据库表,在options选项中存在一些选项影响写入的字段的值,主要包
	 * 括:{@link ExtBulkDataSourceCtx.targetFields},{@link ExtBulkDataSourceCtx.hasIgnoredTargetFields}。
	 *
	 * @param ctx 选项参数,对文件或数据库表参数会不同,具体见{@link ExtBulkDataSourceCtx}。
	 * @return 不会返回null,如果不支持,此函数应该抛出`unsupported:`开头的异常,并尽量在异常对象中
	 *         说明原因,此时系统会认为连接器不支持这种情况的高性能读写。如果异常不是`unsupported:`
	 *         开头,那么系统会直接抛出并终止执行。
	 */
	openWriter?(ctx: ExtBulkDataSourceCtx): ExtBulkDataWriter;
}

/**
 * 一个要导入的字段的信息
 *
 * 对应后端的java类 FieldUpdateMappingInfo.java
 */
declare interface FieldUpdateMappingInfo {
	/**目标字段在目标表元数据字段列表中的序号,从0开始 */
	toIndex: number,
	/**目标字段字段名 */
	toField: string,
	/**目标字段的元数据信息 */
	toFieldInfo: TableFieldMetaData,
	/**源字段在源表元数据字段列表中的序号,从0开始,不存在或-1时,表示可能希望写入当前时间或常量 */
	srcIndex?: number,
	/**源字段字段名,不存在时,表示可能希望写入当前时间或常量 */
	srcField?: string,
	/**源字段的元数据信息,不存在时,表示可能希望写入当前时间或常量 */
	srcFieldInfo?: TableFieldMetaData,
	/**
	 * 表示设置用于插入还是用于更新。
	 *
	 * 当{@link BulkDataOptions.dataOverwriteMode}设置为{@link DataOverwriteMode.MERGE}时,默认的,
	 * 如果数据不存在系统会自动按照同名字段的规则去插入目标表的数据,如果数据存在,系统会忽略主键唯
	 * 一索引等字段,更新其他同名字段,但有时候可能调用者希望插入和更新的值不同,或者插入时有效,数
	 * 据已存在时不进行更新,此参数就是用于定义当前MappingInfo是用于插入还是更新的,所以可能同一个目
	 * 标字段会有两个MappingInfo,其{@link mode}不同,一个是INSERT,一个是UPDATE。
	 *
	 * 1. INSERT: 用于插入新数据。
	 * 2. UPDATE: 用于覆盖已有数据时。
	 *
	 * 默认空,表示插入和更新时都是用。
	 */
	mode?: "INSERT" | "UPDATE";
	/**为true,表示在目标字段写入当前时间戳,比如模型设置了最后修改时间字段时 */
	currentTimestamp?: boolean,
	/**存在此属性表示在目标字段写入常量,比如模型设置了最后修改人字段时,需要写入用户id */
	constValue?: any
}

/**
 * 一个结构化的、多行多列的、数据量可能会很大的数据表或文件对象。
 *
 * “BulkData”理解为数据,泛指一个结构化的、多行多列的、数据量可能会很大的数据表或文件,而“Source”理
 * 解为“源”,特指一个“表”级别的数据源,“BulkDataSource”理解为“结构化数据源”,一个“源”是一个可能可读
 * 也可能可写的数据的“表”。
 *
 * 见后端的{@link com.succez.commons.jdbc.migrate.BulkDataSource}。
 */
declare interface BulkDataSource {

	/**
	 * 设置选项,见{@link BulkDataOptions}。
	 * 
	 * @param option 见{@link BulkDataOptions}
	 * @param value
	 */
	setOption(option: string, value: any): void;

	/**
	 * 返回数据总行数。
	 * 
	 * 通常只对数据库表有效,文件如csv文件无法知道行数。
	 * 
	 * @return -1表示未知
	 * @throws Exception 
	 */
	getDataRowCount?(): number;

	/**
	 * 返回元数据信息。
	 *
	 * 这里返回的是读取这个源时的数据结构,这里返回的元数据信息可能会被用于数据迁移时创建目标表的表
	 * 结构、或者建立来源和目标字段之间的映射关系。返回的元数据信息需要和{@link #openReader()}读取的
	 * 数据结构严格一致,包括字段个数和字段顺序。
	 *
	 * @param inferIfMetaNotExist 是否在无法查询元数据信息的时候根据数据推断元数据结构。例如当源是
	 *        csv或excel文件时,文件中是没有元数据的,此时如果需要根据来源新建目标表的表结构,就需要
	 *        能自己推断结构了。推测元数据结构需要读取数据,会有一定代价,最终会调用
	 *        {@link BulkDataReader#inferMeta()}来进行推测。
	 * @param throwIfMetaNotExist 是否在实在无法获取字段列表时抛出异常
	 * @return 返回来源的元数据结构,或推测的结构,可能返回null。
	 * @throws Exception
	 */
	getMetaInfo(inferIfMetaNotExist: boolean, throwIfMetaNotExist: boolean): TableMetaInfo;

	/**
	 * 打开数据读取器。
	 *
	 * 通常调用此函数不会有大代价,调用此函数并不会立即执行数据查询,也不会打开网络或大文件,因为有
	 * 时候获取reader只是为了获取元数据信息,reader的实现通常会确保在第一次
	 * {@link BulkDataReader#next()}或第一次调用{@link BulkDataReader#getCSVStream()}时才会真正的执
	 * 行具体资源的查询和读取。
	 *
	 * 通常一个源,可以多次调用{@link #openReader()},就像同时并发查询一个表的数据或同时读取一个文件
	 * 的数据一样。需要注意,一个openReader就是一个open,要对应一个{@link BulkDataReader#close()}
	 * 的,调用者需要确保自己关闭返回的对象。
	 *
	 * @return 不会返回null
	 */
	openReader?(): BulkDataReader;

	/**
	 * 打开一个数据写入器。
	 *
	 * 如果源是支持并发写入的({@link #canParallelWrite()}返回true),那么可以多次调用此函数返回N个
	 * writer多线程并发写入数据。
	 *
	 * 调用者需要自己关闭返回的对象。
	 *
	 * @return 总是会返回一个可用的writer,否则会抛出异常
	 */
	openWriter?(): BulkDataWriter;
}

/**
 * 一个抽象的批量读取数据集的接口,支持流式读取和一行一行读取。
 * 
 * 见后端的{@link com.succez.commons.jdbc.migrate.BulkDataReader}。
 */
declare interface BulkDataReader extends Closeable {

	/**
	 * 获取数据集的元数据信息。
	 *
	 * 此函数返回的是读取这个源时的数据结构,元数据信息可能会被用于数据迁移时创建目标表的表结构、或
	 * 者建立来源和目标字段之间的映射关系。返回的元数据信息需要和{@link getRow()}读取的数据结构严格
	 * 一致,包括字段个数和字段顺序。
	 *
	 * @param throwIfMetaNotExist 是否在实在无法获取字段列表时抛出异常
	 * @return 返回来源的元数据结构,可能返回null。
	 */
	getMetaInfo(throwIfMetaNotExist?: boolean): TableMetaInfo;

	/**
	 * 遍历下一行数据。
	 *
	 * 当调用此函数后,就不能再调用{@link getCSVStream()}以流式方式读取数据了。
	 *
	 * @return 返回true表示存在下一行数据,此时可以通过{@link getRow()}函数获取字段的值。
	 */
	next(): boolean;

	/**
	 * 获取当前行对象。
	 *
	 * 此函数用于高效的进行行遍历,不用做多余的内存复制。但需要特别注意的是,返回的行对象是内部复用
	 * 的,外界在读取完毕后不要修改它,遍历下一行数据时,此对象可能会发生改变。
	 *
	 * @return 返回的数组对象中有当前行的所有数据
	 */
	getRow(): Array<any>;

	/**
	 * 以文本流的方式读取数据。
	 *
	 * 用于将一个结构化的数据转换为csv或text内容,以便有些db的数据导入使用,比如mysql可以使用load
	 * DATA直接导入数据,此时就需要把来源表的一行一行的结构化的数据变成文本了,提升数据导入性能。
	 *
	 * 默认返回标准的csv格式内容:
	 *
	 * 1. 以逗号作为值的分隔符。
	 * 2. 编码`utf-8`。
	 * 3. 换行符是`\n`。
	 * 4. 第一行就是数据。没有列头行。
	 * 5. 当值中存在分隔符或者换行符时,用双引号把值括起来,两个双引号表示双引号本身。
	 * 6. 日期格式是`yyyy-mm-dd`,时间戳格式是`yyyy-mm-dd hh:mm:ss.000`。
	 *
	 * 大部分数据库都支持导入多种格式的数据文件,比如mysql、pg都支持标准的csv,但是csv格式并不是一个
	 * 严格的标准,有些极端的情况下导入数据可能有问题,比如:
	 *
	 * 1. Mysql会把`"NULL"`当作null值,见<https://dev.mysql.com/doc/refman/8.0/en/load-data.html>,
	 *    If FIELDS ENCLOSED BY is not empty, a field containing the literal word NULL as its value
	 *    is read as a NULL value. This differs from the word NULL enclosed within FIELDS ENCLOSED
	 *    BY characters, which is read as the string 'NULL'.
	 * 2. pg会把`\.`当作文件结尾,见<https://www.postgresql.org/docs/current/sql-copy.html>, Because
	 *    backslash is not a special character in the CSV format, \., the end-of-data marker, could
	 *    also appear as a data value. To avoid any misinterpretation, a \. data value appearing as
	 *    a lone entry on a line is automatically quoted on output, and on input, if quoted, is not
	 *    interpreted as the end-of-data marker. If you are loading a file created by another
	 *    application that has a single unquoted column and might have a value of \., you might need
	 *    to quote that value in the input file.
	 *
	 * 此函数除了支持返回标准的CSV文件流,还支持设置csv格式的具体格式、转义格式,通过传入参数设置返
	 * 回流的具体格式,其原理就相当于将数据导出为指定格式的文本文件,只是此函数并未真的导出文件,而
	 * 是通过类似管道流的技术,将数据以需要的格式输出给流对象:
	 *
	 * 1. 有列分隔符和行分隔符。默认列分隔符是`,`行分隔符是`\n`。
	 * 2. 字段值有特殊字符比如分隔符、换行符、转义符等需要转义,转义符默认是`\`,通过转义可以确保每
	 *    行数据就对应数据库的一行数据。
	 * 3. 每行的列都必须是齐整的,即每行都必须包含所有列的数据,不能多不能少。
	 * 4. NULL值有明确的表示方式,pg和mysql都是`\N`。
	 * 5. Blob字段的值可以用base64编码或hex编码。
	 *
	 * 通过参数{@link BulkDataOptions.selectFields},还可以选择具体的字段输出,比如只输出部分字段、
	 * 忽略某些字段、调整字段的顺序、甚至设置常量字段或者计算字段。
	 *
	 * 返回的流还可以进行数据的“切片”,这可以避免大事务,有些数据库不支持超大事务(比如TiDB),所以
	 * 对于导入海量数据的情况,如果不切片可能无法导入数据。返回的流对象默认不是切片的,调用其
	 * setSliceSize函数{@link BulkDataCSVInputStream#setSliceSize(long)}可以设置切片的每片数据行数,
	 * 对于需要切片的库,推荐10w~50w一片。当当前切片流读取完毕后,流对象已经标记为“EOF”了,此时可以
	 * 调用{@link BulkDataCSVInputStream#nextSlice()},如果返回true,那么可以继续用此流读取下一个切
	 * 片的数据。
	 *
	 * 返回的流不用关闭,在此类关闭时会自动关闭。返回的流通常不需要再用一个Bufferedreader包装了,调
	 * 用者可直接使用。
	 *
	 * @param options 设置输出流的选项,可以格式为csv或text,以及分隔符、转义方式、也可以设置要输出
	 *        的列(见{@link BulkDataOptions.selectFields})等等,具体见{@link BulkDataOptions}中文
	 *        本文件的相关选项。
	 * @return 返回完整未读取过的Stream({@link java.io.InputStream})。
	 */
	getCSVStream?(options?: BulkDataOptions): any;

}

/**
 * 用于给扩展开发者实现的一个结构化的、多行多列的、数据量可能会很大的数据表或文件对象的数据读取器。
 *
 * 更多关于此接口使用场景的描述见{@link ExtBulkDataSource},此接口与{@link BulkDataReader}接口相似但
 * 不同,此接口主要定位给扩展开发实现使用,注意是扩展实现,也就是说当要开发一个自定义的数据读取器扩
 * 展“贡献”给系统时使用,系统会将扩展提供的接口封装为{@link BulkDataReader}接口,提供给外部使用。
 *
 * 对应后端接口`ExtBulkDataReader.java`,需与其保持同步修改!!!
 */
declare interface ExtBulkDataReader extends Closeable {
	/**
	 * 执行初始化,只会执行一次。
	 * 
	 * @param mode 2表示调用的是{@link next()}。
	 */
	init?(mode: number): void;

	/**
	 * 获取数据集的元数据信息。
	 *
	 * 此函数根据数据内容获得元数据信息,如果没有就返回null。
	 *
	 * @return 可能返回null
	 */
	getMetaInfo?(): TableMetaInfo;

	/**
	 * 读取下一行数据。
	 *
	 * 只有调用此函数且返回true后,才能使用{@link getRow()}函数获取当前行的数据。
	 *
	 * @return 返回true表示存在下一行数据,此时可以通过{@link getRow()}函数获取字段的值。
	 */
	next(): boolean;

	/**
	 * 获取当前行对象。
	 *
	 * 此函数用于高效的进行行遍历,不用做多余的内存复制。需要特别注意的是,返回的行对象是内部复用
	 * 的,调用者在读取完毕后不要修改它,遍历下一行数据时,此对象可能会发生改变。
	 *
	 * @return 返回的数组对象中有当前行的所有数据,字段顺序与{@link getMetaInfo(boolean)}返回的元数
	 *         据结构严格一致。
	 */
	getRow(): Array<any>;

	/**
	 * 以文本流的方式读取数据。
	 *
	 * 用于扩展实现时能很方便的获取一个高速文本流的情况,比如pg的copy命令,此时如果扩展开发者要自己
	 * 实现使用{@link next()}函数读取数据会很不方便,性能也不好,通常此函数和{@link next()}函数只需
	 * 要实现其一即可。
	 *
	 * 返回的文本流可能是csv格式,也可能不是,但必须是文本的,以'\n'换行的,以特定字符分隔列,字段值
	 * 要么有转义规则要么像csv那样quote起来,具体格式配置需要通过{@link getCSVStreamOptions()}函数返
	 * 回。
	 *
	 * @returns 返回一个`java.io.InputStream`或`java.io.Reader`对象,系统会在读取完毕后自动关闭这个
	 *          返回的流对象。
	 */
	getCSVStream?(): any;

	/**
	 * 返回一个配置,用于告诉系统{@link getCSVStream()}函数的数据格式。
	 * 
	 * 返回值通常包括这些参数:
	 * 
	 * 1. 编码: {@link BulkDataOptions.encoding}
	 * 2. 列分隔符: {@link BulkDataOptions.columnDelimiter}
	 * 3. 转义规则: {@link BulkDataOptions.escapeChar}、{@link BulkDataOptions.escapeCharMappings}。
	 * 
	 * 如果扩展没有实现此函数,那么系统自动使用标准的CSV格式规范。
	 *
	 * @returns 返回一个`BulkDataOptions`对象。
	 */
	getCSVStreamOptions?(): BulkDataOptions;
}


/**
 * 一个抽象的批量读取数据集的接口,支持流式读取和一行一行读取。
 * 
 * 更多关于此接口使用场景的描述见{@link BulkDataSource},此类只负责数据写入,不负责创建和调整表结
 * 构。
 * 
 * 见后端的{@link com.succez.commons.jdbc.migrate.BulkDataWriter}。
 */
declare interface BulkDataWriter extends Closeable {

	/**
	 * 写入一行数据。
	 *
	 * 此函数通常用于在写入文件时使用。在写入大量数据时,{@link #copy(BulkDataReader)}函数通常性能更
	 * 好,推荐使用它。
	 *
	 * @param row 
	 */
	writeRow(row: any[]): void;
	/**
	 * 将数据导入到目标库或文件。
	 *
	 * 此函数使用最高效的方式将数据批量写入到目标源。
	 *
	 * 传入的reader提供了基于CSV结构的流式数据读取接口,也可以使用API一行一行遍历数据,CSV是标准的
	 * CSV文件格式:
	 *
	 * 1. 使用双引号扩起来转义,如果内部有双引号,那么用两个双引号转义
	 * 2. 不支持斜线转义,有些数据库(比如mysql)也许支持导入文件时用斜线转义,但其实标准csv都不支持
	 *
	 * @param reader 数据来源reader
	 * @return 返回导入的数据的行数。
	 */
	copy(reader: BulkDataReader): void;
}

/**
 * 用于给扩展开发者实现的一个结构化的、多行多列的、数据量可能会很大的数据表或文件对象的数据写入器。
 *
 * 更多关于此接口使用场景的描述见{@link ExtBulkDataSource},此接口与{@link BulkDataWriter}接口相似但
 * 不同,此接口主要定位给扩展开发实现使用,注意是扩展实现,也就是说当要开发一个自定义的数据写入器扩
 * 展“贡献”给系统时使用,系统会将扩展提供的接口封装为{@link BulkDataWriter}接口,提供给外部使用。
 *
 * 此类只负责数据写入,不负责创建和调整表结构。
 *
 * 对应后端接口`ExtBulkDataWriter.java`,需与其保持同步修改!!!
 */
declare interface ExtBulkDataWriter extends Closeable {

	/**
	 * 执行初始化,只会执行一次。
	 * 
	 * @param mode 1表示调用的是{@link writeRow()}, 2表示调用的是{@link copy()}。
	 */
	init?(mode: number): void;

	/**
	 * 写入一行数据。
	 *
	 * 此函数通常用于在写入文件时使用,系统不会对写入db数据时调用此函数。在写入大量数据
	 * 时,{@link copy()}函数通常性能更好,推荐实现它。
	 *
	 * @param row 
	 */
	writeRow?(row: Array<any>): void;

	/**
	 * 将数据导入到目标库或文件。
	 *
	 * 实现要点(以下实现要点,可以参考mysql、postgresql的连接器实现):
	 *
	 * 1. 此函数应该尽量使用最高效的方式将数据批量写入到目标源
	 * 2. 实现者需要自己判断`ctx.dataClearMode === "CLEARTABLE"`,如果是,那么需要自己在一个事务中清
	 *    理数据
	 * 3. 传入的reader提供了基于CSV结构的流式数据读取接口,也可以一行一行遍历数据。见
	 *    {@link BulkDataReader.getCSVStream()},{@link BulkDataReader.next()}。
	 * 4. 在{@link ExtBulkDataSourceCtx.targetFields}中定义了写入哪些列的数据、以及每列的数据来源,
	 *    应该按定义的映射关系进行数据写入。如果来源字段列表和目标字段列表并不完全一一对应,实现者需
	 *    要重新选择来源字段列,具体见{@link BulkDataReader.getCSVStream()}。
	 * 5. 实现者需要在导入完毕后设置必要的统计信息包括写入了多少行、错误了多少行等到
	 *    {@link ExtBulkDataSourceCtx.runningState}对象中。
	 * 6. 如果实现时是直接通过驱动底层的对象执行的sql,那么需要调用相关api告诉系统执行的sql,否则系
	 *    统无法输出相关sql日志。
	 * 
	 * 在分片并发写入数据时,系统会同时创建多个{@link ExtBulkDataWriter}对象,如果writer之间需要共享
	 * 一些上下文信息,可以通过{@link ExtBulkDataSource.prepareCtx()}实现。
	 *
	 * @param reader 数据来源reader
	 * @return 返回导入的数据的行数。
	 */
	copy?(reader: BulkDataReader): number;
}

/**
 * 复制数据表返回结果
 */
interface MigrateDataResult {

	/**任务id,如果传递了{@link MigrateDataArgs.taskId}那么将直接使用传入的id,否则将自动产生一个 */
	taskId?: string,

	state: IORunningState,

	options?: MigrateDataArgs,

	/**每个表的复制的信息*/
	tables?: Array<MigrateTableResult>,
}

/**一个表的结果 */
interface MigrateTableResult {

	state: IORunningState,

	/**来源 */
	source: BulkDataOptions & { state: IORunningState },

	/**目的 */
	target: BulkDataOptions & { state: IORunningState },

	/**执行器 */
	executor?: {

		state: IORunningState,
		starter?: IORunningState,

		/**生产端线程信息,为数组时表示是分片并行读取的 */
		reader: Array<IORunningState> | IORunningState,

		/**消费端线程信息,为数组时表示是分片并行写入的 */
		writer: Array<IORunningState> | IORunningState,
	}

	/**
	 * 扩展属性
	 *
	 * 1. 装载扩展时,存储扩展下不同扩展点的装载异常
	 */
	[key: string]: any;
}

/**
 * 规定所有的ErrorCodes,所有的数据库连接器都可以返回符合这些errorcode的异常。
 * 
 * 需要和后端的DbErrorCodes.java保持一致。
 */
declare const enum DbErrorCodes {
	/**
	 * 执行SQL的默认异常信息,数据库网络、集群等较复杂的部署问题可以直接显示默认异常。
	 */
	ERR_JDBC_ERROR = "err.db.jdbcError",

	/**
	 * 未知的严重错误,发生此类错误后通常连接要丢弃,重新发起数据库连接
	 */
	ERR_FATAL_ERROR = "err.db.fatalError",

	/**
	 * 违反唯一约定unique constraint violated
	 */
	ERR_DUPLICATE_KEY = "err.db.duplicateKey",

	/**
	 * 名称已由现有对象使用,比如创建一个已存在的表、索引、视图
	 */
	ERR_OBJECT_EXISTED = "err.db.objectExisted",

	/**
	 * 不存在的对象,表或视图不存在
	 */
	ERR_OBJECT_NOTFOUND = "err.db.objectNotFound",

	/**
	 * 无效列名 invalid column name
	 */
	ERR_INVALID_COLUMN = "err.db.columnInvalid",

	/**
	 * sql语法有错误
	 */
	ERR_SQL_SYNTAX = "err.db.sqlSyntax",

	/**
	 * 无权限访问数据库或表
	 */
	ERR_COMMAND_DENIED = "err.db.commandDenied",

	/**
	 * 数据库不存在。
	 */
	ERR_DATABSE_NOTEXIST = "err.db.databaseNotExist",

	/**
	 * 此用户无登录权限,可能是用户不存在。
	 */
	ERR_LOGIN_DENIED = "err.db.loginDenied",

	/**
	 * 没有该存储过程或自定义函数的执行权限。
	 */
	ERR_ROUTINE_DENIED = "err.db.routineDenied",

	/**
	 * 表名无效
	 */
	ERR_TABLE_NOTFOUND = "err.db.tableNotFound",

	/**
	 * 无效字符
	 */
	ERR_INVALID_CHARACTER = "err.db.invalidCharacter",

	/**
	 * 表名长度超过数据库允许最大长度
	 */
	ERR_TABLENAME_OUTOFBOUNDS = "err.db.tableNameOutOfBounds",

	/**
	 * 字段名长度超过数据库允许最大长度。
	 */
	ERR_COLUMNNAME_OUTOFBOUNDS = "err.db.columnNameOutOfBounds",

	/**
	 * 标识符超过数据库允许最大长度。
	 */
	ERR_OBJECTNAME_OUTOFBOUNDS = "err.db.objectNameOutOfBounds",

	/**
	 * 插入的数据长度超出字段的设置长度
	 */
	ERR_COLUMN_VALUETOOLONG = "err.db.columnValueTooLong",

	/**
	 * 字段不存在
	 */
	ERR_COLUMN_NOTFOUND = "err.db.columnNotFound",

	/**
	 * 数据类型不一致
	 */
	ERR_COLUMN_TYPE_DISACCORD = "err.db.columnTypeDisaccord",

	/**
	 * 字段类型不支持
	 */
	ERR_COLUMN_NOTSUPPORTED = "err.db.columnNotSupported",

	/**
	 * 无效的字段长度,字符和数值类型字段的长度不能小于等于`0`
	 */
	ERR_INVALID_COLUMN_LENGTH = "err.db.invalidColumnLength",

	/**
	 * 字段的长度定义,超出了数据库允许的范围。
	 *
	 * 比如:
	 * 1. oracle11g字符类型长度最大值是4000,超过这个长度抛出此异常提示。
	 *
	 */
	ERR_COLUMN_OVERLENLIMIT = "err.db.columnOverLenLimit",

	/**
	 * 数值类型小数位数超出精度范围。
	 *
	 * 比如:
	 * 1. 定义的数值类型:field(4,5) 小数位数5超出了总精度4的范围,数值类型第一个参数是精度应该包括小数位数。
	 *
	 */
	ERR_COLUMN_SCALEOVERLIMIT = "err.db.columnScaleOverLimit",

	/**
	 * 数据被截断,可能是类型不符,或是插入数据大于列的最大长度
	 */
	ERR_DATA_TRUNCATION = "err.db.dataTruncation",

	/**
	 * 无法将null写入到数据库表中,该字段可能是主键或唯一索引
	 */
	ERR_NOT_ALLOWED_NULL = "err.db.notAllowNull",

	/**
	 * 除数为0异常
	 * 
	 * 大部分数据库直接出异常,少数数据库(比如:mysql)直接返回null。
	 */
	DB_DIVBYZERO = "err.db.divByZero",

	/**
	 * sql中使用了非法数字,用整型字段与非整型数据进行比较或关联可能会导致该问题!
	 */
	ERR_INVALID_NUMBER = "err.db.invalidNumber",

	/**
	 * 无法将不同类型的数据进行比较转换
	 */
	ERR_TYPE_CONVENT = "err.db.differentTypeConvent",

	/**
	 * 建议在项目设置中勾选oracle使用join语句
	 */
	ERR_NOT_ALLOWED_JOIN = "err.db.notAllowedJoin",

	/**
	 * 用户 'temp01'无法执行‘regexp_replace',当前数据库版本不支持的系统函数,或用户没有该存储过程的执行权限。
	 */
	ERR_FUNCTION_NOT_EXIST = "err.db.functionNotExist",

	/**
	 * 不能批量导入数据
	 */
	DB_CANT_BULKLOAD = "err.db.cantBulkLoad",

	/**
	 * 密码过期异常。
	 */
	ERR_PASSWORD_EXPIRED = "err.db.passwordExpired",

	/**
	 * 连接失败
	 * 
	 * 可能是`URL`错误或者服务器没启动。
	 */
	ERR_CONNECT_REFUSED = "err.db.connectRefused",

	/**
	 * 连接超时
	 */
	ERR_CONNECT_TIMEOUT = "err.db.connectTimeout",

	/**
	 * 网络通信错误
	 */
	ERR_NEWWORK_COMMUNICATION = "err.db.networkCommunication",

	/**
	 * 磁盘空间满了
	 */
	ERR_DISK_FULL = "err.db.diskFull",

	/**
	 * 数据库其他空间满了
	 */
	ERR_SPACE_FULL = "err.db.spaceFull",
	/**
	 * 内存溢出了
	 */
	ERR_OUTOFMEMORY = "err.db.outOfMemory",
	/**
	 * 无法创建表
	 */
	ERR_CANT_CREATETABLE = "err.db.cantCreateTable",
	/**
	 * 无法锁定
	 */
	ERR_CANT_LOCK = "err.db.cantLock",

	/**
	 * 资源相关错误,包括无法创建文件、超过资源限制等等
	 */
	ERR_RESOURCE_OPERATE = "err.db.resourceOperate",

	/**
	 * 数据库表缺失主键设置。
	 */
	ERR_NO_PRIMARYKEY = "err.db.noPrimaryKey"
}
是否有帮助?
0条评论
评论