# db-connector-types - 数据库连接器扩展指南
/**
* 此文件专门用于定义数据库连接器扩展的相关类型。
*/
/**
* 数据库分词器的名称。
*
* 此类型是分词器的名称,即分词器的标识,在模型设置时选择分词器时需要使用,如果想有好的全文检索效
* 果,就需要有合适的分词器,db(包括ES)通常支持扩展分词器,默认自带的分词器通常也不适合中文,db连
* 接器扩展可以将db支持的分词器报告给系统使用。
*
* 对于ES数据库的连接器,它除了报告es内部的真实分词器,还需要几个虚拟的分词器,系统会使用这些虚拟的
* 分词器来实现一些特殊的ES字段类型,更多信息见{@link DbTokenizerNames}。
*
* @see JdbcConfigInfo.tokenizers
*/
type DbTokenizerName = DbTokenizerNames | string;
/**
* 定义一些约定的分词器的名称。
*
* 对于ES数据库的连接器,由于它支持了很多标准的RDB不支持的数据类型,比如`search-as-you-type`类似,标
* 准的RDB的数据类型不足以表达此类型,如果用户希望使用此类型,系统需要使用一些其他手段,通过给文本类
* 型字段设置合适的分词器来实现,所以对于ES连接器,它除了报告es内部的真实分词器,还需要几个虚拟的分
* 词器,系统会使用这些虚拟的分词器来实现一些特殊的ES字段类型。
*/
declare const enum DbTokenizerNames {
/**
* ES中的虚拟的用于创建keyword字段类型的分词器。
*
* 由于ES的文本字段如果设置类型为text支持全文检索,那么默认它就不能用作分组聚合、排序和精确匹
* 配,只有keyword类型的字段在es中才支持,如果希望一个字段既能做全文检索又能做精确匹配和分组,那
* 么需要给字段设置多个分词器,ES底层支持一个字段可以存储多个索引结果,这些字段的索引可以看作是
* 字段的一个子字段,它可以用来被查询,但写入时不需要直接操作子字段,主字段写入数据后子字段的数
* 据都会自动产生,比如一个产品名称,可以在es中存储keyword(用于精确匹配和分组的)、拼音分词、全
* 拼分词、全文分词等多种形式,但是它其实只是一个字段,写数据时,只需要写一个字段,存储方式是自
* 动完成的。
*
* 在dw层面的模型设置中,字段可以设置多个分词器,模型层面使用不同的分词器的设置来适配这个需求,
* 如果一个字段需要同时支持全文和精确匹配,那么需要配置多个分词器,其中就包括这个虚拟的分词器
* keyword,更多信息见模型字段的分词相关定义,检索时也要能当一个字段用,系统会根据用户对字段的使
* 用场景,比如进行比较时使用的比较符、进行分组聚合,系统自动选择使用哪个索引。
*
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/text.html
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/term-level-queries.html
*/
keyword = "keyword",
/**
* ES中的虚拟的用于创建search-as-you-type字段类型的分词器。
*
* 在ES中,search-as-you-type字段类型用于即时搜索,即用户边输入时边搜索,使用ES原生的
* search-as-you-type字段类型可以做到较好的即时搜索的效果,search-as-you-type默认并不支持拼音,
* 如果希望即时搜索能也兼容拼音,需要ES管理员在es中修改索引设置,通过 自定义分词器 结合 拼
* 音分词插件(如elasticsearch-analysis-pinyin)实现这一功能。
*
* 在dw层面的模型设置中,如果字段设置了此分词器,那么在创建表模型时会自动创建一个类型为
* search-as-you-type的子字段,一些需要即时搜索的场景中,如spg的快速搜索组件,会默认使用此子字段
* 进行检索。
*
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-as-you-type.html
* @see https://github.com/infinilabs/analysis-pinyin
*/
searchAsYouType = "searchAsYouType",
}
/**
* 数据库连接的配置信息。
*
* 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;
/**
* 批量插入或修改数据BatchSize大小。
*
* 批量修改数据时BatchSize非常影响性能,此参数将推荐应用端在使用JDBC的addBatch/executeBatch函数
* 批量插入或修改数据时,使用多大的BatchSize。
*
* 默认取连接器的推荐配置{@link DbSupportsConf.preferredBatchSize},用户可以在数据源的配置中提供
* 更个性化的设置。
*
* @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,
}>;
/**
* 配置此连接支持的分词器。
*
* 分词器是用于全文检索的,在模型的字段设置中,对于需要支持全文检索的字段,如果想有好的全文检索
* 效果,就需要设置合适的分词器,db(包括ES)通常支持扩展分词器,默认自带的分词器通常也不适合中
* 文,此配置用于在db连接器无法自动获取支持的分词器时手工配置支持的分词器,以将db支持的分词器报
* 告给系统使用,当配置了此设置时,系统将不再使用模版{@link DbSQLTemplates.getTokenizers}获取支
* 持的分词器。
*
* 对于ES数据库的连接器,它除了报告es内部的真实分词器,还需要几个虚拟的分词器,系统会使用这些虚
* 拟的分词器来实现一些特殊的ES字段类型,更多信息见{@link DbTokenizerNames}。
*
* 此选项只有在启用{@link DbSupportsConf#supportsDisableTableIndex}时才会生效。
*
* @see DbSQLTemplates.getTokenizers
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/keyword.html
*/
tokenizers?: Array<DbTokenizerName>;
/**
* 配置此连接的默认分词器。
*
* 一个db支持多种分词器,模型上也可以设置具体使用哪个分词器,但是如果没有明确设置,将默认使用此
* 处设置的默认分词器。
*
* @see DwTablePropertiesInfo.defaultTokenizer
* @see DwTableFieldInfo.tokenizers
*/
defaultTokenizer?: DbTokenizerName;
/**
* 用户自定义属性
*/
[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.${name}.caption`中找标题,从`db.name.${name}.desc`中找描
* 述。
* 3. 如果国际化中不存在,那么将直接使用{@link name}当作标题。
*/
name: string,
/**
* 数据库的类别。用于在新建数据源的对话框中将数据库logo分组显示。
*/
dbKind?: DbKind,
/**
* 配置一些关于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的驱动,此
* 时JDBC驱动返回的版本信息不是真实的数据库的版本,如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},用于告诉系统这个数据源使用指定的连接器连接数据库,此时可
* 以通过它获取连接器的实现。之前版本的一些配置没有记录连接器ID,为了兼容以前的配置文件,当数据
* 源配置文件中没有连接器标识时也支持通过url匹配模式找到合适的连接器。
*
* 当使用{@link inheritConnector}属性继承其它连接器配置时,此属性不会被继承,如果系统内有多个连
* 接器都匹配某个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},用于通过脚本代码实现一些数据库底层相关的逻辑,比如使用数据库本地的
* jdbc api去流式导入数据。
*
* 在连接器继承时(见{@link inheritConnector}),默认的子连接器会自动使用父连接器的脚本对象,但
* 如果子连接器需要自己个性化新的脚本对象,那么需要明确配置此属性,即便配置的脚本路径和父连接器
* 的一样也要明确定义一下,只有明确定义了脚本路径,系统才会加载子连接器内部自己的脚本文件。如果
* 子连接器不需要任何脚本,那么可以明确配置为null。
*/
serverScript?: ServerScriptPath | null;
/**
* 类似{@link serverScript},定义一个java类,用于扩展db连接器的能力。
*
* 在连接器继承时(见{@link inheritConnector}),默认的子连接器会自动使用父连接器的java对象,此
* 时此java扩展对象的类加载环境(即ClassLoader)还是在父连接器中,连接器是可以自带需要的java类和
* jar包的(见<https://docs.succbi.com/v5/dev/extension/faq/051be50>),类中需要用到的java类或
* jar都是来自父连接器而不会使用子连接器的。但如果子连接器需要自己个性化新的java对象,那么需要明
* 确配置此属性,即便配置的类路径和父连接器的一样也要明确定义一下,只有明确定义了类路径,系统才
* 会使用子连接器自己的java ClassLoader加载指定的类。如果子连接器不需要任何脚本,那么可以明确配
* 置为null。
*
* 提供的java类需要实现`com.succez.commons.jdbc.connector.DbConnectorExt`接口。
*/
javaClass?: JavaClassName | null;
/**
* 可以描述多个不同版本数据库的兼容性选项。
*
* 连接器的默认配置是直接配置在配置文件的根属性上的,当确实有多个版本的配置不同需要分别配置时,
* 可以把需要兼容的其他版本配置在此属性中。
*
* 1. 此配置中的版本的顺序要保证高版本在前、低版本在后,系统会从上至下优先选用匹配的高版本的配
* 置。最后面的那个版本会默认继承连接的默认配置,高版本的配置会自动继承低版本的配置,不需要在
* 高版本中将低版本一致的配置重复配置一次,只需要配置不一样的或新增的即可。
* 2. 版本继承的顺序是:`高版本 <- 低版本 <- 默认版本 <- inheritConnector`。inheritConnector见
* {@link inheritConnector}。
* 3. key是一个符合semver规范的版本(见{@link VersionRange}),版本号必须是3位数字,具体的示例见
* {@link DbCapabilities.matchDbVersion}。
* 4. 系统会自动调用jdbc驱动的api去获取数据库的版本,但有些数据库不是Mysql却使用的是Mysql的驱
* 动,此时JDBC驱动返回的版本信息不是真实的数据库的版本,如StarRocks,通过驱动获取的版本号是
* `5.1.0`,此时如果希望得到系统能绕开驱动API获取真实版本号,可以配置
* {@link DbSQLTemplates.getDatabaseProductVersion}。
*
* 默认空,此时表示所有版本都可以使用一个配置。
*/
compitableVersions?: {
[semver: string]: DbVersionCapabilities;
}
}
/**
* 配置某个数据库版本的功能、兼容性选项。
*/
declare interface DbVersionCapabilities {
/**
* 设置当前配置继承另一个Connector的配置。
*
* 类似{@link DbCapabilities.inheritConnector},主要解决不同版本的可能继承的数据库配置也不同。比
* 如:Greenplum6基于PostgreSQL9.4,Greenplum7基于PostgreSQL12.12,配置Greenplum7时需要从
* PostgreSQL12继承。YMatrixDB基于Greenplum7,期望能读取到PostgreSQL12的配置。
*
* 当配置了此属性,当前配置将从头开始继承,覆盖最开始的{@link DbCapabilities.inheritConnector}。
*
* 默认位空,表示从最基本版本开始继承。
*/
inheritConnector?: string;
/**
* 配置一些禁止用户通过此连接器执行的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`即可覆盖继承的字段类型。
*
* 特别的,有时候继承一个连接器,所有字段类型需要重新定义,且不期望继承父连接器任何字段类型。比
* 如ES的连接器,继承pg,但是字段定义完全不同,不希望继承pg的配置,一一给每个字段类型设置null太
* 麻烦,此时可以在字段列表中配置一个字段类型为`*`的字段类型,并设置其为null,即可覆盖所有继承的
* 字段类型。
*/
dataTypes?: {
/**
* 定义字段类型
*
* 这里key是字段类型名称,大小写敏感,由数据库决定。比如:ES的字段类型都小写,那么配置也是小
* 写的。
*
* key和{@link DbDataTypeDefine.type}区别:
*
* 1. key不带长度。比如:VARCHAR
* 2. {@link DbDataTypeDefine.type}是字段类型定义模板,可能带长度,比如:VARCHAR(?)
*/
[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;
/**
* 数据库扩展自定义属性配置。
*/
extConfs?: DbExtConf;
}
/**
* 配置一些关于db的个性化选项,用于在数据库连接设置页面中提供一些个性化的能力。比如提供一些个性化的
* 连接选项、构造个性化的连接URL等。
*/
declare interface JDBCConfigHelper {
/**
* 脚本文件在扩展目录下的地址
*
* 脚本接口定义参见{@link IDbConfScript}
*/
script?: ExtensionFilePath;
/**
* 新建数据库连接时默认的配置。
*
* 新建数据源时,会加载{@link defConf}中配置的默认值,并覆盖新建数据源表单中的相关输入项的默认
* 值,如果配置了自定义输入项(见{@link confItems}),由于自定义输入项中也可以给输入项配置默认
* 值,但它会被此属性配置的默认值覆盖,若需要设置自定义配置项默认值,请在此属性中进行设置。
*/
defConf?: JdbcConfigInfo,
/**
* 自定义的数据库连接配置项。
*
* 1. 如果配置的表单输入项的id与已有的输入项相同,那么将自动将这里配置的合并到原来的输入项上去。
* 2. 如果输入项配置了默认值(见{@link CommonExtensionFormItemInfo.value}),它会被{@link defConf}
* 配置的默认值覆盖,若需要设置自定义配置项默认值,请使用{@link defConf}配置。
* 3. 数据源设置的表单分数据库连接相关属性设置和连接池相关属性设置,此处自定义的个性化配置项只属
* 于前者,即用于个性化配置数据库连接相关的。
*/
confItems?: CommonExtensionFormItemInfo[];
/**
* 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;
}
/**
* 指定一个相对于当前扩展目录的脚本文件(前端脚本,.js结尾的文件),用于在数据库连接设置页面中提
* 供一些个性化的能力。
*/
declare interface IDbConfScript extends ICommonExtensionFormScript {
/**
* 获取一个运行时的{@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?: (form: ICommonExtensionForm, jdbcConf: JdbcConfigInfo) => 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;
/**纳秒数,必须在ss.后面。Excel日期格式本身不支持纳秒,SSSSSSSSS是java中支持的纳秒格式。 */
SSSSSSSSS: 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 {
/**
* 配置获取数据库版本信息的模板。
*
* 此模版的结果影响数据库连接器获取对应的版本的配置。如果连接器中提供了多个版本的配置,需要在第
* 一次建立链接时获取正确的版本号信息才能使用合适的配置。详
* 见:{@link DbCapabilities.matchDbVersion}。
*
* 通常不需要配置这个SQL模板,系统会自动调用jdbc驱动的api去获取,但有些数据库是基于常用数据库扩
* 展而来,使用的是通用驱动,返回的版本信息不是真实的数据库的版本。
*
* 1. Doris和StarRocks基于MySQL的,驱动返回的版本号是`5.1.0`,这是MySQL内核的版本号,不是Doris或
* StartRocks的版本号。
* 2. Greenplum/YMatrixDB基于PostgreSQL的,驱动返回的版本号是`9.4`,这是PostgreSQL的版本号,不是
* Greenplum/YMatrixDB的版本号。
*
* 这些数据库需要额外执行sql来获取真实的版本信息。
*
* 1. show variables like 'version_comment'
* - Doris version doris-1.2.6-rc03-Unknown -- Doris
* - 3.2.0-rc01-9d64ad2 -- StratRocks
* 2. select version()
* - PostgreSQL 12.12 (Greenplum Database 7.0.0 build dev) on x86_64-pc-linux-gnu,compiled by
* gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, 64-bit compiled on Jan 29 2024 14:44:44
* Bhuvnesh C.
* - PostgreSQL 12 (MatrixDB 4.4.9-community) (Greenplum Database 7.0.0+dev.17349.gcfe00e2616
* build commit:cfe00e26169c0bb648c6a2257d227844b4d9d8e3) on x86_64-pc-linux-gnu,compiled
* by gcc (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5), 64-bit compiled on Apr 18 2023 08:10:32
*
* 如果要获取真实的版本信息,需要配置此模板。由于版本变化的原因,相应的majorVersion等都会发生变
* 化,此模板的执行结果将返回如下字段列:
*
* 1. DATABASE_PRODUCT_VERSION 数据库产品完整版本
* - 对应驱动的`DatabaseMetaData.getDatabaseProductVersion()`
* - 如:`PostgreSQL 12.12 (Greenplum Database 7.0.0 build dev) on x86_64-pc-linux-gnu`等
* 2. DATABASE_VERSION 数据库版本号
* - 格式:以`x.y.z`开头,如`5.1.0`,`7.0.0 build dev`
* 3. DATABASE_MAJOR_VERSION 数据库产品主版本号
* - 对应驱动的`DatabaseMetaData.getDatabaseMajorVersion()`
* - 返回整形,如`5`
* - 可选,如果没有返回此字段,则会从DATABASE_VERSION中获取。
* 4. DATABASE_MINOR_VERSION 数据库产品次版本号
* - 对应驱动的`DatabaseMetaData.getDatabaseMinorVersion()`
* - 返回整形,如`1`
* - 可选,如果没有返回此字段,则会从DATABASE_VERSION中获取。
* 5. DATABASE_PRODUCT_NAME 数据库产品名称
* - 对应驱动的`DatabaseMetaData.getDatabaseProductName()`
* - 可选,如果驱动返回的是正确的产品名称,可以不返回此项。
*
* 此模板没有参数,如果配置了此模板,只在初始化连接器时执行一次。
*/
getDatabaseProductVersion?: SQLTemplateString;
/**
* 一个表(含视图)的“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`,此属性是`["catalog1","schema1","table1"]`,注意数组
* 中不会存在空值,已按需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;
/**
* 查询当前会话(链接)的ID。
*
* 如mysql是`SELECT CONNECTION_ID()`。
*/
getSessionID?: SQLTemplateString;
/**
* 强行杀死一个会话,断开链接。
*
* 模板中可用参数:
*
* 1. sessionId 会话的id。
* 2. user 当前用户id。
*
* 如mysql是`KILL CONNECTION ?`。
*/
killSession?: SQLTemplateString;
/**
* 获取当前会话的所有连接列表。
*
* TODO @dengw
*/
getSessions?: SQLTemplateString;
/**
* 返回数据库支持哪些分词器。
*
* 此模版用于db连接器向系统报告db支持的分词器,关于db连接器的分词器的作用和意义,见
* {@link JdbcConfigInfo.tokenizers},有些db无法自动获取支持的分词器,所以可以配置
* {@link JdbcConfigInfo.tokenizers}属性来人工设置,此时系统将不再使用此模版获取支持的分词器。
*
* 对于ES数据库的连接器,它除了报告es内部的真实分词器,还需要几个虚拟的分词器,系统会使用这些虚
* 拟的分词器来实现一些特殊的ES字段类型,见{@link DbTokenizerNames}。
*
* 返回的列:
*
* 1. TOKENIZER 分词器名称,见{@link DbTokenizerName}。
*
* @see JdbcConfigInfo.tokenizers
* @see DbTokenizerName
*/
getTokenizers?: SQLTemplateString;
/**
* 获取指定分词器对文本进行分词的结果。通常用于测试分词的效果。
*
* 模板中可用参数:
*
* 1. tokenizer 分词器名称,见{@link getTokenizers}。
* 2. text 要分词的文本。
*
* 分词结果是一个结果集,每一行代表一个分词,有如下列:
*
* 1. TOKEN 词的内容
* 2. TYPE 词的类型
* 3. POSITION 分词在文本中的位置
*/
tokenizeText?: SQLTemplateString;
/**
* 获取数据库配置信息的模板
*
* 有些数据库需要数据库配置动态调整{@link DbVersionCapabilities}中的配置,比如:数据库字符集,时
* 区,是否大小写敏感,是否支持启用了流式导入、数据库默认存储引擎等。
*
* 配置此模板后,可以通过{@link DbDialect.getDbConfigs()}访问到数据库配置信息。然后根据需要在脚
* 本{@link DbConnectorExt.initRuntimeCapabilitiesConf(conn, dialect)}中动态调整
* {@link DbVersionCapabilities}中的配置项。对于{@link createTable}模板也可以通过
* {@link DbDialect.getDbConfigs()}做一些个性话的配置。
*
* 此模板没有参数。
*
* 由于有的数据库可能是show语句,无法规定返回的列名,因此读取时通过序号获取值,默认第一列是配置
* 项名称,第二列是配置项值。
*
* 示例:
* 1. pg是`show all`
* 2. mysql是`show variables`
*/
getDbConfigs?: 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`,此属性是`["catalog1","schema1","table1"]`,注
* 意数组中不会存在空值,例如,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标准的`getTables`无法获取准确的物化视图类型,比如:oracle返回的是
* TABLE。因此需要通过另外的sql查询物化视图。如果驱动`getTables`返回了准确的类型,则不需要实现此
* 模板。
*
* 返回的字段列:
*
* 1. MVIEW_CAT String 必须,Catalog
* 2. MVIEW_SCHEM String 必须,SCHEMA
* 3. MVIEW_NAME String 必须,物化视图名
*
* 模板中可用参数与模版{@link qualifiedTableName}参数一致,其中参数`name`和`metaName`表示要查询
* 的表的名称,若为空,则表示查询schema下的所有表。
*
* 以Oracle为例如下,注意sql模板中的`[ WHERE OWNER = '?5']`部分,表示如果没有第二个参数时SQL就不
* 包括方括号的所有内容:
*
* ```sql
* select NULL MVIEW_CAT, OWNER MVIEW_SCHEM, MVIEW_NAME from ALL_MVIEWS [WHERE OWNER = '?5']
* ```
*/
getMaterializedViews?: 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模板或者脚本模板来实现。
* 14. IS_ENABLED Number 1表示启用,0表示禁用,此字段不一定总是存在,当启用
* {@link DbSupportsConf#supportsDisableTableIndex}为true后可通过此字段获取约束是否启
* 用。
*
* 模板中可用参数与模版{@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=?
* ```
*
* 模板接收参数table.metaSchema、table.metaName,没有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 MATERIALIZED VIEW ....`的一段语句。
* 说明参考{@link getTableDDL}。
*
* 模板参数与模版{@link getTableDDL}一致。
*/
getMaterializedViewDDL?: 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支持启用/禁用索引,对
* 于ES相当于设置索引的定时刷新间隔为-1表示禁用,大于0表示启用。对于不支持的db系统会自动删除索
* 引,并在结束时再恢复索引。
*
* 此模版需要启用{@link DbSupportsConf#supportsDisableTableIndex}后才生效。
*
* 接收参数:
*
* 1. table 目标表名,见{@link SQLTemplateParam_Identifier}。
* 2. indexData 索引的相关状态数据,由{@link disableTableIndex}在禁用索引时产生,然后恢复时传递
* 过来,可以是一个字符串,也可以是一个结果集,如果是结果集,那么会转换成一个json对象
*/
enableTableIndex?: SQLTemplateString;
/**
* 禁用表的指定的索引。类似{@link enableTableIndex}。
*
* 此模版需要启用{@link DbSupportsConf#supportsDisableTableIndex}后才生效。
*
* 接收参数:
*
* 1. table 目标表名,见{@link SQLTemplateParam_Identifier}。
*
* 此模版可以返回值,返回字符串或者结果集都行,返回值主要用来传递给{@link enableTableIndex}模
* 版,用于在禁用索引时记录下索引的相关信息,之后再根据这些信息进行恢复,比如ES要恢复索引的定时
* 刷新频率,需要返回紧用前的频率。
*/
disableTableIndex?: SQLTemplateString;
/**
* 刷新表的索引。
*
* 用于人工或系统调用的索引刷新,有些db,如ES支持手工刷新索引,虽说ES是支持自动刷新的,但是它的
* 刷新是有间隔的,而且也可以把间隔时间设置为-1表示不定时刷新了,此时就需要在数据同步完成后主动
* 调用一次刷新才行。
*
* 在批量写入数据时为了优化写入性能,此时可能会先禁用索引写入完成后回复索引,见
* {@link enableTableIndex},对于ES来说,连接器在恢复索引时也会自动刷新一次,所以此时不需要再次
* 调用此模版刷新索引了。
*
* 接收参数:
*
* 1. table 目标表名,见{@link SQLTemplateParam_Identifier}。
* 2. indexName 要操作的索引的名称,不传递时表示所有索引。
*/
refreshTableIndex?: 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. table 目标表,见{@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},类似参数table),此
* 参数存在,表示需要将此表的数据合并到目标表,要求表中的字段名与目标表保持一致。别名通过usingTable.alias获取。
* - usingFilter 当数据来源表是一个数据表时,可以指定一个此数据表的过滤条件。
* - usingSql 执行merge的数据来源sql,当usingTable为空,取这个值。详见:{@link SQLTemplateParam_SQLElement},别名通过usingSql.alias获取。
* - on 目的表和来源表或者sql的关联关系,大多数时候是主键的关联。
* - 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
* ...`语句,此参数类似table参数是一个完整的表名。
* - 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表示是主键
* - enableTextFullSearch 是否启用全文检索,详
* 见:{@link succ.dw.DwTableFieldInfo.enableTextFullSearch}
* - tokenizers 全文检索的分词器,多个,是一个数组,详
* 见:{@link succ.dw.DwTableFieldInfo.tokenizers}
* - primaryKey 主键字段设置,是一个索引对象,可访问的属性和下面的indexes的索引对象一致。
* - indexes 索引列表,是一个数组对象,每个元素都是一个索引,索引有如下属性:
* - name 推荐索引名,已按需quote,可能空,这是一个建议的名称,不强制使用,如果元数据信息是
* 从别的库读取出来的,那么这个name可能是索引在源库中的索引名,不一定能用到当前库中,
* 不同的数据库对索引名要求不同,大部分数据库要求索引名在schema内唯一,不能和其他对象
* 包括表名冲突(如pg),实现者创建表时可根据数据库的需要用其他的名称。
* - uname 强制索引名,已按需quote,可能空,当此属性存在时创建表应直接使用这里指定的索引名,
* 调用者自己保障索引名的合法性。
* - aname 自动索引名,已按需quote,不为空,由于索引名在不同的数据库上要求不同,但是其实索引
* 名并不十分重要,当上面指定的name不能使用时可以使用此处的aname,aname是系统自动产生
* 的,考虑了表名、字段等,不会和其他对象名称冲突。
* - unique 是否唯一
* - cluster 是否是聚集索引
* - enable 是否启用了
* - parts 索引的字段数组
* - column 字段名,已按需quote
* - sort 排序设置,空(默认)、DESC或ASC
* - comment 输出到SQL中的业务注释,方便用户理解SQL,可能为空,也可能为一个多行的文本,模版配置
* 时可以将其输出到合适的地方,在SQL开头或结尾都可以。
* - storageType 数据表的存储方式,详见:{@link DbTableStorageType}
* - storageEngine 存储引擎,如InnoDB,MyISAM等,如果为空,则使用默认的存储引擎。详
* 见:{@link DbSupportsConf.supportsStorageEngines}
* - distributionMode 分布式数据库模型的分布方式,{@link DbSupportsConf.supportsDistribute}为
* true有效,REPLICATION:复制表,HASH:散列分布式。详见:{@link DbTableDistributionMode}。
* - distributionColumns 分布式存储时的分布列字段,可能有多个,这时是一个数组对象,每个元素都是
* 一个字段名,见{@link SQLTemplateParam_Identifier}。
* - partition 分区信息,{@link DbSupportsConf.supportsPartition}为true有效,详
* 见:{@link DbTablePartitionInfo},分区有如下属性:
* - mode 分区类型,如RANGE、LIST、HASH等,详见:{@link DbTablePartitionMode}。
* - field 分区字段,不会为空。是一个数组,每个元素是一个字段对象,详见上面字段列表columns中
* 的定义。
* - partsCount Hash分区的分区个数。
* - parts 分区条目,是一个数组,每个元素是一个{@link DbTablePartitionItemInfo}
* - name 分区名,已按需quote,可能为空。
* - values 分区值集合,详见:{@link DbTablePartitionItemInfo.values}。值是可以直接输入
* 到SQL中的值,如果对应的分区字段是字符类型,则值已经用单引号扩起。如果分区字段是日期
* 类型,值的格式约定为:yyyy-mm-dd
* - includeMax RANGE区间是否包含最大值。
* - extAttrs 扩展属性,是一个List,每个元素有如下属性:
* - name 属性名,详见:{@link DbSupportsConf.supportsTableExtAttrs}
* - value 属性值
* - 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},模板中可用参数也与其类似,有如下不同之处:
*
* - createOrReplace ?2 多了这个参数,为`OR REPLACE`表示如果视图存在就重新创建它。
* - selectStatement ?3 参数总是存在。
* - tableType 视图类型,可能为 VIEW、MATERIALIZED_VIEW。
* - mvRefreshMode 可选,物化视图的刷新模式:详
* 见:{@link DbSupportsConf.supportsMaterializedViewRefreshModes}
* - mvRefreshType 可选,物化视图的刷新方式,比如:手动刷新、定时刷新、事务刷新:详
* 见:{@link DbSupportsConf.supportsMaterializedViewRefreshTypes}
* - mvRewrite 可选,物化视图是否支持查询重写,详
* 见:{@link DbSupportsConf.supportsMaterializedViewRewrite}
* - logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
* - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
* - dialect {@link DbDialect}。
*
* 当然也可以使用参数模板配置:`CREATE[ ?2] VIEW ?1 AS ?3`。
*/
createView?: SQLTemplateString;
/**
* 用于刷新视图的语句。
*
* 对于物化视图,大部分是手动刷新的,需要单独执行一个刷新数据的语句。
*
* 模板可使用的参数:
*
* - table 视图名,见{@link SQLTemplateParam_Identifier}。
* - logging 是否记录归档日志,可选,默认为false。有些数据库允许不记录日志,提高效率。
* - parallel 返回一个数值,表示并行度。oracle可以开启并行执行,提高效率。
* - dialect {@link DbDialect}。
*/
refreshMaterializedView?: 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;
/**
* 分析数据表的统计信息。
*
* 当数据表数据发生重大变化时,手动更新统计信息可以优化执行效率,提高查询效率。特别是有些数据是
* load进来的,比如:Hive直接导入文件,必需手动执行此命令,否则count(*)不准确。
*
* 模板参数与模版{@link getTableDDL}一致。
*/
analyzeTable?: SQLTemplateString;
}
/**
* 数据库扩展自定义属性配置
*
* 这里配置一些db的扩展属性,比如Doris和StarRocks{@link DbConnectorExt}中实现流式导入,只有csv格式的
* 配置不同,其他大部分实现都一样。通过配置此属性,使Doris和StarRocks可以使用相同的
* {@link DbConnectorExt}扩展实现。
*
* 注意:此属性属于自定义配置,只提供给{@link DbConnectorExt}使用。
*/
declare interface DbExtConf {
/**
* 自定义属性配置。
*/
[customProperty: string]: any;
}
/**
* 这里配置db的一些兼容性特性,这里每个选项都是描述的db支持什么、db能做到什么,而不是描述是否启用系
* 统的某个功能,系统会自动根据db能做到什么、能支持什么,自动选择应该怎么调用db的功能。
*/
declare interface DbSupportsConf {
/**
* 是否支持数据库本地的、高性能的数据批量读写方式。
*
* 当配置true时,系统在读写数据时会尝试使用{@link DbConnectorExt.createDbTableBulkSource}。
*
* 默认false
*/
supportsBulkLoad?: boolean;
/**
* 使用数据库本地的、高性能的数据批量读写方式时是否支持处理错误数据行,包括设置最大错误行数、反
* 馈错误行的详细信息。
*
* 当用户导入海量数据时,通常不希望因为少量数据导入失败,导致整个导入失败,此时可以设置最大错误
* 行数,见{@link BulkDataOptions.maxErrorRowCount},如果db的高性能导入方式不支持此特性,系统会
* 考虑分批将数据提供给导入逻辑,并对失败的批次改为JDBC的INSERT语句的批量提交,发现错误的行,并
* 尽量提交可以提交的数据行。
*
* 如果db的高性能导入方式支持此特性,系统会将maxErrorRowCount参数直接交给db底层自己处理,db连接
* 器扩展实现者在实现数据导入逻辑时需要在获取到错误信息后,调用
* {@link ExtBulkDataMonitor.onRejectRow()}函数来告诉系统错误的数据行信息,需要特别。
*
* 默认false
*/
supportsBulkLoadRejectErrorRows?: boolean;
/**
* 当用流式导入分批将数据提供给导入逻辑时,每个批次的行数。
*
* 关于分批,见{@link supportsBulkLoadRejectErrorRows}和{@link BulkDataOptions.batchCommit}。当
* 启用了{@link BulkDataOptions.batchCommit}和{@link BulkDataOptions.maxErrorRowCount}时,如果使
* 用db连接器提供的流式导入,且它不支持{@link supportsBulkLoadRejectErrorRows},此时系统会分批将
* 数据提供给流式导入接口,此选项规定了每个批次的大小。
*
* 考虑到有错误数据是少量情况,为了平衡性能,此值通常应该大于100000。
*
* 默认200000,通常应该大于100000。
*/
bulkLoadBatchSize?: number;
/**
* 是否通用的基于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;
/**
* 是否是分布式数据库,比如高斯、vertica。
*
* 分布式数据库才能进一步的设置更多分布式属性。
*
* 默认false
*/
supportsDistribute?: boolean;
/**
* 支持表的数据分布模式设置。
*
* 见{@link DbTableDistributionMode},启用这个属性后,在模型的属性设置中可以进行选用,比如把某些
* 小维表设置成复制表模式。
*
* 当{@link supportsDistribute}为true时,才会生效。
* 默认为空,表示支持所有的分布模式。
*/
supportsDistributionModes?: DbTableDistributionMode[];
/**
* 表是否支持分区。
*
* 支持分区,才能进一步设置分区属性。
*
* 默认为true。
*/
supportsPartition?: boolean;
/**
* 支持表的分区模式设置。
*
* 见{@link DbTablePartitionMode},启用这个属性后,在模型的属性设置中可以进行选用。
*
* 当{@link supportsPartition}为true时,才会生效。
* 默认为空,表示支持所有的分区模式。
*/
supportsPartitionModes?: DbTablePartitionMode[];
/**
* 是否支持full join。
*
* 无默认值,默认取jdbc驱动提供的值,若手动配置了,则就用配置的。通常不需要配置。
*/
supportsFullOuterJoins?: boolean;
/**
* 是否支持with语法。
*
* 使用with语法,某些情况下,会提高查询效率,比如oracle。
* 首先需要数据库本身支持。
*
* 默认true
*/
supportsWith?: boolean;
/**
* 是否支持values子句。
*
* 在SQL中,SELECT * FROM语句后接 VALUES子句是一种用于动态生成临时结果集的方式。
*
* 主流数据库的最新版本基本都支持此语法,产品里这些功能可以利用这个特性:
*
* 1. 工作流查询,应用数据和系统表可以存在不同的数据源,需要关联时先执行系统表的过滤查询,利用
* values子句将查询结果关联到应用数据库的查询。
* 2. 数据加工拆分行,需要使用unnest函数,目前仅pg支持,可以借助values子句构造一个自增长的临时表
* 并关联到主表,使用各数据库类似SUBSTRING_INDEX函数的功能,对每个序号计算拆分值。
* 3. 数据加工列传行,本质上就是和临时表的cross join。
* 4. 第三方数据源、枚举数据源等,通常数据量不会很大,使用values子句构造临时表后,可以很方便的和
* 其他数据表集成查询。
*
* ```sql
*
* SELECT e.name, v.day
* FROM employees e
* CROSS JOIN (VALUES
* ('周一'), ('周二'), ('周三'), ('周四'), ('周五')
* ) AS v(day)
* WHERE e.department = '研发部';
*
* ```
* 默认false
*/
supportsSelectFromValues?: boolean;
/**
* values子句的最大行数。
*
* 例如mysql限制SQL的最大长度为65565字节,mssql限制values的最大行数是1000行。
*
* 超过最大行数后会使用临时表进行优化。
*
* @see supportsSelectFromValues
*/
supportsSelectFromValuesLimit?: number;
/**
* 是否使用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;
/**
* 是否支持批量提交数据
*
* 大部分数据库都支持,有些分析型数据库可能不支持,可以通过驱动的方法
* {@Link DatabaseMetaData.supportsBatchUpdates()}判断。不支持的数据库(比如Hive),执行
* {@link PreparedStatement.addBatch()},实际将执行
* {@link Statement.executeUpdate()},{@link PreparedStatement.executeBatch()}将返回每次
* {@link Statement.executeUpdate()}的返回值数组。
*
* 默认取{@Link DatabaseMetaData.supportsBatchUpdates()},如果驱动没有实现,则为true。
*/
supportsBatchUpdates?: boolean;
/**
* 是否支持对blob,clob类型字段执行批量处理。
*
* 大部分数据库也支持对大字段批量写入,但是有些数据库不支持。比如:Gauss200数据,默认库启动,出
* 现RROR: invalid byte sequence for encoding "UTF8": 0x8b。查了很多资料,都是说字符集问题,但是
* 逐行提交,没有发现问题。
*
* 默认为{@link supportsBatchUpdates}
*/
supportsBatchUpdatesLob?: boolean;
/**
* 是否支持从批量提交的异常信息中获取正确的更新计数
*
* 数据库批量导入功能,当使用jdbc批量导入时,如果一个批次数据导入失败,失败原因有很多,比如:主
* 键冲突、超出字段范围等,会导致整个批次数据都无法写入,并抛出{@link BatchUpdateException}异
* 常。
*
* 如果此参数设置为false,系统会尝试每行单独提交写入,把能写入的写入,不能写入的记录到日志中,并
* 最终返回结果中会包含无法导入的行等提示。
*
* 如果此参数设置为true,系统会从{@link BatchUpdateException.getUpdateCounts()}获取此批次每行写
* 入的状态值,返回的数组长度和此批次的行数相同,数组元素是每行的写入状态,大于等于0表示成功的
* 行,-2表示{@link Statement.SUCCESS_NO_INFO},其他表示失败,并且从
* {@link BatchUpdateException.getNextException()}中获取每行失败的原因。从这些信息可以知道哪些已
* 经写入,哪些没法写入,不需要逐行重试了。
*
* 实际测试发现:
*
* 1. 一般数据库批量提交数据,都会抛出{@link BatchUpdateException}异
* 常。{@link BatchUpdateException.getCause()}会返回具体的异常。
* {@link BatchUpdateException.getNextException()}多数数据库返回的和{@link getCause()}相同。
* 只有MySQL{@link getNextException()}返回null。
* 2. {@link BatchUpdateException.getUpdateCounts()}并没有返回正确的值:
* 1. pg和mysql都返回-3,表示{@link Statement.EXECUTE_FAILED},无法分析出错的行号。
* 2. oracle返回正确写入的行数,不包括出错的行。比如第三行出错了,返回的是[1,1]表示前两行写入
* 成功,后面如果有能写入的,也没有尝试了。
* 3. 达梦都返回-2,表示{@link Statement.SUCCESS_NO_INFO},无法分析出错的行号。
*
* 所以传统数据库此参数一般都要设置为false,为此参数的默认值。
*
* 对于一些nosql的数据库,比如Es等,系统将实现自己的psql驱动,不支持事务,批量导入通过RestApi实
* 现,封装jdbc批量导入的逻辑,能把正确的写入,错误的不写入。如果有不能写入的,抛出
* {@link BatchUpdateException},实现正确的{@link BatchUpdateException.getUpdateCounts()}和
* {@link BatchUpdateException.getNextException()}。因此Es的连接器可以配置此参数为true。
*
* 默认false
*/
supportsBatchPartialSuccessMode?: boolean;
/**
* 推荐的批量插入或修改数据BatchSize大小。
*
* 批量修改数据时BatchSize非常影响性能,此参数将推荐应用端在使用JDBC的addBatch/executeBatch函数
* 批量插入或修改数据时,使用多大的BatchSize。
*
* 每个db可以有自己的最合适的推荐配置,以便达到最佳性能体验,默认1024。
*/
preferredBatchSize?: number;
/**
* 是否支持修改表注释。
* 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、upsert批处理操作时是否支持获得所有批次所有字段的值
*
* insert、upsert操作需要使用sql反查数据时,若此函数返回false,由于不支持批处理中返回多
* 行自增长列,只能逐行执行之后使用sql反查。
*
* @see SQLExecutor#getGeneratedColumnsData()
* @return 默认返回 {@link #supportsGetGeneratedKeys}
*/
supportsGetGeneratedKeysInBatch?: boolean;
/**
* insert时是否支持获得所有字段的值
*
* 默认false
*/
supportsGetGeneratedValues?: boolean;
/**
* insert、upsert批处理操作时是否支持获得所有批次所有字段的值
*
* insert、upsert操作需要使用sql反查数据时,若此函数返回false,由于不支持批处理中返回多
* 行反查字段的值,只能逐行执行之后使用sql反查。
*
* @see SQLExecutor#getGeneratedColumnsData()
*
* @return 默认返回 {@link #supportsGetGeneratedValues()}
*/
supportsGetGeneratedValuesInBatch?: boolean;
/**
* 是否支持主键
*
* 默认true
*/
supportsPrimaryKey?: boolean;
/**
* 是否支持多字段构成的主键。
*
* 对于ES这样的数据库,每个文档只有一个唯一id,此时需要返回false,这样如果模型使用了不支持多字段
* 主键的数据源,就可以限制只能设置一个字段了。
*
* 默认true
*/
supportsMultiColumnsPrimaryKey?: boolean;
/**
* 是否支持自动产生主键的值。
*
* 此设置不是指是否支持自增长主键,而是指对于不是自增长主键的主键字段,在写入新数据时,是否支持
* 不指定明确的值时,db会自动产生。
*
* 比如ES,它的每个文档自动有一个主键`_id`,写入新数据时可以指定,也可以不指定,不指定时ES会自动
* 产生一个。像订单、合同这类本来就有自己的唯一主键且主键稳定不变的数据,应该保持原有的主键直接
* 用到es,这样方便数据后续的同步增量更新,而对于日志、交易流水这种不变的数据、没有原主键的、只
* 会追加新数据的数据可以用es自己产生的。
*
* 对于支持此特性的db,在写入数据时,如果没有指定主键的值系统就不会在应用层面报告错误,而是交给
* db自己处理,有错误由db自己爆出。
*
* 默认false。
*/
supportsAutoGeneratedPrimaryKeyValue?: boolean;
/**
* 数据库约定的、固定名称的且唯一标识数据的主键字段名。
*
* nosql数据库,如ES、Mongodb,他们的表中存储的一条数据通常叫文档,表中会有一个约定的、固定名称
* 的且唯一标识数据的系统标识字段,Es和mangodb都是`_id`,用户不可删除_id、新建时也不需要创建
* _id,_id字段会自动创建,字段名也不能被更改,可以把它理解为传统db表的唯一主键字段,此时可以配
* 置此选项为`"_id"`,这样,即便逻辑层的模型表有自己的业务意义的主键名,系统也会在更新、删除、修
* 改和查询数据时自动将逻辑模型的主键名映射为底层db表上的`_id`字段。
*
* 默认空,表示没有统一主键字段名
*/
supportsFixPrimaryKeyName?: string;
/**
* 是否支持使用查询字段别名分组
*
* 默认true
*/
supportsGroupByAlias?: boolean;
/**
* 是否支持使用查询字段别名排序
*
* 默认true
*/
supportsOrderByAlias?: boolean;
/**
* 是否支持使用查询字段的索引分组
*
* 默认true
*/
supportsGroupByColumnIndex?: boolean;
/**
* 是否支持使用拆线呢字段的索引排序
*
* 默认true
*/
supportsOrderByColumnIndex?: boolean;
/**
* 是否优先字段别名,即字段别名是否优先于字段名
*
* sql中的表达式,大多数数据库都是数据库字段优先,有些数据库是字段别名优先,比如:ClickHouse。
*
* 在ClickHouse中,下面的sql会出异常:
* ```
* SELECT
* leftUTF8(XZQH, 2) AS XZQH,
* SUM(ZCZJ) AS ZCZJ,
* SUM(ZGRS) AS ZGRS,
* SUM(ZCZJ) + SUM(ZGRS) AS `ZCZJ+ZGRS` -- 正确语法:ZCZJ + ZGRS 或者 SUM(t0.ZCZJ) + SUM(t0.ZGRS)
* FROM
* testdbc.RES_QYML_FACT -- t0
* WHERE
* ZCZJ > 0 -- 正确语法:t0.ZCZJ > 0
* GROUP BY
* leftUTF8(XZQH, 2) -- 正确语法:XZQH (支持直接使用别名) 或者 leftUTF8(t0.XZQH, 2)
* HAVING
* SUM(ZCZJ) > 0 -- 正确语法:ZCZJ > 0 或者 SUM(t0.ZCZJ) > 0
* ORDER BY
* SUM(ZCZJ) -- 正确语法:ZCZJ 或者 SUM(t0.ZCZJ)
* ```
* 当此属性为true,翻译sql时,如果字段名不带前缀,且和字段别名有冲突时,需要给字段名加上前缀(所在数据表的别名)。
*
* 默认false
*/
supportsPreferFieldAlias?: boolean;
/**
* 是否驱动的getObject(int)可以获取到所有类型字段的值
*
* jdbc驱动直接访问{@link #getObject(int)}方法,可能会返回驱动内部的对象。
*
* 1. oracle对于timestamp类型字段,getObject返回的是oracle.sql.TIMESTAMP,导致不能通用处理。
* 2. Kingbase读取tinyint类型字段,getObject返回的是KBObject,不能通用处理。
* 3. Oracle数据库varchar类型,超过一定长度,getObject会返回Clob对象。
* 4. 对于clob和blob都有可能返回数据库自己的类型,这不利于上层统一处理。
*
* 设置为true,则会直接调用jdbc的getObject方法。设置为false,会根据字段类型调用相应的方法获取数
* 据,返回jdbc标准接口对象。特别的,对于clob会返回{@link String},对于blob会返回{@link Blob}。
*
* 默认为true。
*
*/
supportsResultSetGetObject?: 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时,需要同时配置{@link DbSQLTemplates.disableTableIndex}模版和
* {@link DbSQLTemplates.enableTableIndex}模版。
*
* 默认false
*/
supportsDisableTableIndex?: boolean;
/**
* 是否支持字段设置注释
*
* 默认true
*/
supportsColumnComments?: boolean;
/**
* 是否支持Clob及其类似的字段类型;
*
* 默认true
*/
supportsCLOB?: boolean;
/**
* 是否支持Blob及其类似的字段类型;
*
* 默认true
*/
supportsBLOB?: boolean;
/**
* 是否支持boolean类型的值作为查询返回值。
*
* Oracle和sqlserver不支持。Mysql/PostgreSQL/KingbaseES支持。
*
* 默认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时,系统会自动将年(月)值补充完整。
*
* 多数数据库都支持宽松的strToDate规则,比如oracle、postgresql、sqlserver等,目前只发现
* mysql有这个问题。因此默认应该为true。
*
* 默认true
*/
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;
/**
* 是否支持分页的Offset和Limit使用参数
*
* 一般数据库都支持分页使用参数,比如:`offset ? limit ?` 或者 `limit ?, ?` 。但是有的数据库不支
* 持,比如Presto,它支持`offset 10 limit 10`,不支持`offset ? limit ?`。
*
* 默认true,表示支持。
*/
supportsOffsetLimitParam?: boolean;
/**
* 是否支持视图
*
* 默认true。
*/
supportsView?: boolean;
/**
* 是否支持给视图表添加注释。
*
* mysql就不支持,配置false避免从jdbc驱动读取到不正确的信息。
*
* 默认true。
*/
supportsViewComment?: boolean;
/**
* 是否支持物化视图。
*
* 比如pg、oracle支持,但mysql不支持。
*
* 默认false。
*/
supportsMaterializedView?: boolean;
/**
* 是否支持物化视图的rewrite功能。
*
* 如果数据库支持此特性,那么数据库会自动优化sql的查询,当对物化视图的基表进行查询时,数据库会自
* 动判断能否通过查询物化视图来得到结果,如果可以,则避免了聚集或连接操作,而直接从已经计算好的
* 物化视图中读取数据。
*
* 1. Oracle的物化视图可以启用查询重写功能。
* 2. Doris和StarRocks的物化视图默认就是支持查询重写。
*
* 默认false。
*/
supportsMaterializedViewRewrite?: boolean;
/**
* 支持的物化视图的刷新模式
*
* 见{@link DbMaterializedViewRefreshMode},启用这个属性后,在模型的属性设置中可以进行选用。
*
* 默认为null,表示不支持刷新模式。
*/
supportsMaterializedViewRefreshModes?: DbMaterializedViewRefreshMode[];
/**
* 支持的物化视图刷新方式
*
* 见{@link DbMaterializedViewRefreshType},启用这个属性后,在模型的属性设置中可以进行选用。
*
* 默认为null,表示不支持刷新方式。
*/
supportsMaterializedViewRefreshTypes?: DbMaterializedViewRefreshType[];
/**
* 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;
/**
* 数据库支持的表的存储方式列表。
*
* 见{@link DbTableStorageType},启用这个属性后,在模型的属性设置中可以进行选用,设置模型对应数
* 据表的存储方式。
*
* 默认为null,表示只支持数据库的默认存储,此时建表的SQL语句不加相关设置。
*/
supportsStorageTypes?: Array<DbTableStorageType>;
/**
* 数据表的存储引擎
*
* 各个数据库的存储引擎可能不同,比如mysql支持的引擎有innodb、myisam等,此处配置的引擎在模型的属
* 性设置中可以进行选用。
*
* 如果没有配置,那么将使用数据库的默认存储引擎,此时建表的SQL语句不加相关设置。
*/
supportsStorageEngines?: string[];
/**
* 数据表的属性名称
*
* 创建数据表时,有些个性化的属性配置,各个数据库都不同,此处配置的属性,在模型的表存储属性设置
* 中可以进行选用。
*
* 比如:
*
* 1. GreenPlum 创建一个gzip压缩的,追加优化的表
* - WITH (appendoptimized=true, compresslevel=5)
* 2. Doris 指定ssd存储
* - PROPERTIES ("storage_type" = "column","storage_medium" = "SSD")
* 3. YMatrixDB 使用Mars3引擎,需要指定排序键
* - 语法:USING Mars3 ORDER BY (col1, col2)
* - 排序键的设置,通过自定义属性实现:
* - {
* "name": "storageOrderBy", //排序键的属性名
* "formItemType": "combobox", //下拉框字段列表
* "multiple": true, //选多个字段
* "visibleCondition": "storageEngine==='MARS3'", //只有选择了Mars3引擎才显示,storageEngine是存储引擎的属性名。
* "selectFields": true //自定义属性,根据此属性判断是否是字段列表,给ftl设置参数值时,将其转换为字段列表。
* }
*
* 这些模型的扩展属性会在创建表或修改表结构的SQL模版中以名为`extAttrs`的参数提供给模版,见
* {@link DbSQLTemplates.createTable}。
*/
supportsTableExtAttrs?: Array<CommonExtensionFormItemInfo>;
}
/**
* 配置一个数据库异常信息的“识别规则”,用于将各个数据库的各种错误信息的编码进行统一。
*
* 不同的数据库有不同的异常编码,比如主键冲突、表不存在等,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和索引名。
*
* 研发人员配置时可以自定义异常提示属性,但建议遵循以下标准:
* 1. 新增数据库配置时,尽量复用现有属性的命名。
* 2. 属性命名应清晰易懂,并直观反映异常内容。如:tableName(表名), fieldType(字段类型), rowNumber(行号)。
*
* 对于某些异常中不稳定的属性(比如`GBase`数据库的索引名称总是随机生成),可以选择不提取,因为业
* 务用户往往也看不懂这些信息;即使提取了也不会出现在异常对话框中,只会出现在详细信息中,供研发
* 人员查看并解决相关问题。
*
* 这里配置的正则表达式需要使用到“命名的分组匹配捕获”,即 Named capturing group: (?<name>...),
* 正则表达式中的每个组都是命名的,名称就是需要提取的属性名,每组匹配的值对应它的内容,相关正则
* 表达式的技术说明见下文链接:
*
* 1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group
* 2. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Backreferences
*
* 考虑到有些情况下一个异常识别规则可能对应多个数据库的异常信息,而每个异常信息的匹配模式可能不
* 同,所以此属性支持配置一个数组,当配置数组时,系统会依次使用数组中的所有正则表达式进行匹配,
* 找到所有可能的异常属性。
*
* 以pg配置错误“err.db.columnNotFound”为例,在pg中对应的是sqlState: 42703,但是42703还可能表示的
* 不是列不存在,还可能表示比如json的key不存在,所以需要限定`"errorMessage": "column",`,而42703
* 的错误信息在pg中也有多种,比如`ERROR: column "unknowncol" of relation "res_qyml_fr" does not
* exist`、`ERROR: column "unknowncol" does not exist`、`ERROR: column reference "alias" is
* ambiguous`等,所以需要配置多个匹配模式以便提取异常信息,整个完整的配置如下:
*
* ```
* "errorIdentifyConfs": [{
* //未找到列名
* {
* "sqlState": "42703", // ERROR: column "unknowncol" does not exist 位置:8
* //42703表示列或对象不存在,比如还可能有这样的错误: ERROR: key "emaill" does not exist in JSON object,所以限定只有包含cloumn的时候才是列
* "errorMessage": "column",
* "unifiedErrorCode": "err.db.columnNotFound",
* "extractPropertiesRegex": [
* //ERROR: column "unknowncol" of relation "res_qyml_fr" does not exist
* //ERROR: column "non_existent" does not exist in table/function
* //ERROR: column "invalid_col" does not exist in ORDER BY/GROUP BY
* "(column \"?)(?<fieldName>.+?)(\"? of relation)",
* //ERROR: column t0.unkonwncol does not exist
* //ERROR: column "unkonwncol" does not exist
* "(column \"?)(?<fieldName>.+?)(\"? does not exist)",
* //ERROR: column reference "alias" is ambiguous
* "(column reference \"?)(?<fieldName>.+?)(\"? is ambiguous)"
* ]
* },
* }]
* ```
*/
extractPropertiesRegex?: RegexString | RegexString[],
/**
* 此数据库异常是否是一个“严重”异常,为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;
/**
* 设置此字段类型实际允许使用的最大长度,仅对字符类型字段有效。
*
* {@link maxLen}定义的是数据库最大允许使用的长度,可能是极大的,但实际使用中用户在定义模型字段
* 长度时也许需要一个更合理的最大长度限制,此时可以设置此属性。
*
* 另外,有些db一个表内的所有字段的长度之和不能大于一个限制,如果某个字段很大,可能导致其他字段
* 就没法用了,所以此时也可以通过此选项给一个相对合理的每个字段的最大允许定义的长度限制,比如对
* mysql限制为8000。
*
* 不同db对长度的理解可能不同,如在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;
/**
* 此类型是否无需长度设置。
*
* 设置为true表示此字段类型不需要设置长度,即在定义表结构时不需要设置长度,在对比表结构差异时也
* 可以忽略字段长度的差异。
*
* 通常字符型字段类型(非CLOB)都是需要设置一个字段长度的,表示这个字段的数据最大可以输入多长的
* 数据,但有些db的字符型字段是不需要的,如ES、Hive、和ClickHouse等,但在逻辑层模型表中定义的文
* 本字段都有长度,进行差异比较时,如果此属性设置为true,就可以忽略长度的差异了。
*
* 默认false。
*/
laxLen?: boolean;
/**
* 此字段类型db底层支持的最大长度,数字(固定精度的数字,如NUMBERIC)、字符串字段有效。
*
* 此属性不同于{@link limitLen},此属性设置的是db底层实际上支持的字段最大长度,可能很大、是理论
* 上的、可能不具备实际使用意义,而{@link limitLen}设置的是一个业务使用时实际可用的最大字段长
* 度。
*
* 考虑到字段的长度有多个理解,比如`VARCHAR(20)`,长度定义为20,但在mysql上如果编码是utf8mb4,那
* 么一个汉字最多可能占4个字节,而mysql本身是按字节来限制整行长度的,考虑到在不同数据库上长度的
* 理解不同,此处的定义值需要定义者自己做一下转换处理,系统自会把它和字段的定义长度来比较,不会
* 考虑具体db的存储长度。
*
* @TJS-type integer
*/
maxLen?: number;
/**
* 此字段类型支持的最小长度,数字(固定精度的数字,如NUMBERIC)、字符串字段有效。
*
* 一般数据库的字符类型和数值类型长度都不能为0,比如varchar(1)、decimal(1,0)等,此参数的默认
* 值应该为1。有的数据库比如clickhouse,字符类型没有长度(可以设置任意值,读取为0),可设置为0,
* 用于长度验证,小于此值的长度将会被认为是错误的,给出提示。
*
* 默认为1
*/
minLen?: number;
/**
* 此字段类型支持的最大小数位数,数字(固定精度的数字,如NUMBERIC)字段有效,
* 当小数位数超过最大值时,若设置了此参数,则将小数位数自动调整为该值
*
* @TJS-type integer
*/
maxDecimal?: number;
/**
* 配置将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}。
* 3. `__SCRIPT__`,表示此模板使用脚本实现,具体见{@link DbConnectorExt.executeSQLTemplate}。
*
* `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,大小写和数据库规范一致)
* 4. fullName 对象的全名,如果有schema会带上schema,已按需quote。用于某些数据库自更新字段值,需要带
* 上表名前缀的情况。比如:pg的upsert、merge等语句的ftl配置。
*
* 以下属性只对表或试图对象有效(已按按需根据数据库规范统一大小写):
*
* 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`,此属性是`["catalog1","schema1","table1"]`,注意数组中
* 不会存在空值,已按需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,可以访问一些字段的属性。比如:Es
* 生成psql的DQL和DML语句时,需要将主键字段替换为系统字段_id。对应后台的Java对象
* {@link ExpModelFieldModel},可访问属性如下:
* - name 字段名(已按需quote),默认输出此属性。
* - metaName 原始字段名,未quote。
* - primaryKey 是否是主键字段。
* - dataType 字段类型,是{@link FieldDataType}中的类型。
* - sqlType 字段类型,是{@link JavaSQLTypeValue}中的类型。
* - nullable 是否可为空。
* 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)。也可以访问一些字段的属性,具体见
* {@link SQLTemplateParam_ColumnNames}中的字段名。
* 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`。
*
* 脚本支持继承和重载,规则如下:
*
* 1. 继承:当前脚本没有实现的方法,但是父连接器的脚本实现了,那么系统会调用父连接器的脚本实现。比
* 如:Oceanbase继承了MySQL的连接器,Oceanbase用脚本实现了getTables模板,流式导入继承MySQL的实
* 现,不需要额外实现。
* 2. 重载:当前脚本实现了某个方法,但是父连接器的脚本也实现了,那么系统会调用当前脚本的脚本实现。
* 3. 如果当前脚本没有实现的方法,父连接器也实现了,但是又不想调用父连接器的实现,那么可以在当前脚本
* 实现此方法,并返回`null`。
* 4. 对于sql模板的脚本,如果当前脚本没有实现,也不想调用父连接器的实现,那么可以直接在
* {@link DbVersionCapabilities.sqlTemplates}配置该sql模板为null。
*
* @see DbCapabilities.serverScript
* @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 dialect 数据库方言对象。可以通过{@link DbDialect.getConfig()}和
* {@link DbDialect.getDbConfigs()}获取连接配置和数据库配置信息。
* @returns 返回空或增量配置项。
*/
initRuntimeCapabilitiesConf?(conn: Connection, dialect: DbDialect): DbVersionCapabilities;
/**
* 创建一个数据库本地的、高性能的数据批量读写工具类。
*
* 更多业务信息说明见{@link ExtBulkDataSource}。
*
* 只有当配置了{@link DbSupportsConf.supportsBulkLoad}时,系统才会调用此函数。
*/
createDbTableBulkSource?(): ExtBulkDataSource;
/**
* 返回一个包装的Dialect对象。
*
* 主要用于扩展Dialect的功能,实现一些特定的数据库功能。
*
* 比如:Kingbase的Oracle模式,字段名如果用双引号扩起来,有如下规则:
* 1. 如果里面都是大写,会转小写存储,访问不区分大小写。
* 2. 如果是全部大写关键字,也转小写存储,但是访问需要扩起,扩起的全大写和全小写都可以。
* 3. 如果有大写有小写,按原样存储,且访问区分大小写,要扩起来访问。
*
* 这和双引号扩起来区分大小写规则冲突,需要扩展Dialect实现。
*
* @param dialect 原始的Dialect对象。默认返回null,如果需要扩展Dialect,需要返回一个新的Dialect
* 对象。
*/
wrapperDialect?(dialect: DbDialect): DbDialect;
/**
* 将一个表达式函数翻译成对应的SQL语句,用于在数据库中执行。
*
* 通常表达式的翻译是通过函数模板配置的,见{@link DbCapabilities.functionTemplates},但有些函数
* 的逻辑比较复杂,通过模板配置无法实现,此时可以选择使用脚本进行翻译,此时需要在函数模板配置中
* 配置函数的模板是`__SCRIPT__`。
*
* 此函数对操作符的翻译也有效。
*
* @param func 函数名或操作符名称,统一大写。
* @param args 参数列表,可能为null,表示没有。参数已经处理,是可以直接拼到sql中的字符串。比如:
* 参数中的字段名已经处理quote、函数已经翻译为当前数据库的语法、字符常量已经用单引号
* 包裹等。
* @param node 表达式节点对象,可能为空。通过这个对象可以知道参数的更多详细信息,比如数据类型
* `node.getNode(i).getDataType()`。有些情况会传空,比如:concat函数,字符串连接会调
* 用此函数实现,此时node不是concat函数节点,会传递null。
*/
expFunctionToSQL?(func: string, args: string[], node: any): string;
/**
* 这是一个SQL模板({@link DbSQLTemplates})的扩展实现。
*
* 通常用于用脚本或java实现的特定的数据库功能,替代那些用SQL模版不方便实现的功能。此时需要在
* {@link DbVersionCapabilities.sqlTemplates}中配置模板的主体是`__SCRIPT__`。详
* 见:{@link SQLTemplateString}
*
* 如果函数脚本遇到错误,比如对象不存在,那么可以直接抛出异常,系统会直接继续抛出提示给用户。
*
* 脚本的返回值根据模板定义决定,主要有三种类型:
*
* 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
*
* @param templateName 模板名,比如`getColumns`
* @param args 参数列表,详见: {@link SQLTemplateExtFunc}中的参数定义。
*/
executeSQLTemplate?(templateName: string, args: any): any;
}
/**
* 跨库迁移数据,或从文件导入数据的API函数的参数选项。
*/
interface MigrateDataArgs {
/**
* 项目名,用于权限判断
*/
projectName?: string;
/**
* 传递一个uuid当作任务id,前端可以通过这个id轮询任务的执行进度和日志信息。
*/
taskId?: string;
/**默认同步,是否异步,异步时函数调用直接返回,任务在线程池执行,否则是同步等待迁移完成才返回函数 */
async?: boolean;
/**
* 给此参数传递no,可以禁用线程池,所有数据迁移都是用串行模式。
*
* 默认yes。
*/
threadPool?: "no" | "yes";
/**
* 当源表是空表时,自动忽略,不进行数据拷贝。
*
* 启用此选项后将总是先查询源表的总行数,相当于{@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[];
/**
* 是否以宽松模式联合。
*
* 联合多个数据源时,若不设置此参数为true,那么要求联合的数据源必须表结构一致。若设置了此参数为
* true,那么将以宽松的联合方式来联合数据源,字段列表将取所有被联合数据源的并集,缺失字段使用
* null填充。
*
* 默认false
*/
laxUnionAll?: boolean;
/**
* 导出时设置的子表
*
* 数据文件中可能支持子表,如excel文件中支持多sheet存储不同的表数据,导出的时候如果需要将数据以
* 不同子表的形式存储到数据文件中,可以使用此参数来配置多个数据源。配置的子表数据源表结构不需要
* 相同。
*
* @see ExtBulkDataSource#getAllSubTables
*/
subTables?: 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;
/**是否行号字段,默认为false。如果设置那么该列会输出1开始的行号 */
rowNum?: boolean;
/**常量,此属性、{@link exp}和{@link fieldName}必须要有一个设置。 */
constValue?: any;
}>;
/**
* 当前源的元数据结构。
*
* 当读写某些特殊的文件时,数据源自己可能无法自己获取元数据信息,此时可以由调用者传递元数据信
* 息,便于特定数据源能读写元数据信息。也可能虽然文件有元数据,但是不够好,用户自己编辑了元数
* 据,比如数据加工中,用户可以设置文件的元数据结构。
*
* 默认空,数据源会自己读取元数据(不一定有)
*/
metaInfo?: TableMetaInfo;
//===============================文件源相关属性=======================================//
/**
* 文件
*
* 表示需要读写的文件。可以设置{@link File}、{@link string}类型。设置{@link string}可以是文件绝
* 对路径。如果同时设置了{@link BulkDataOptions.zipEntry},那表名文件是一个zip文件,此时要读取
* zip中的其中一个文件,另外,需要强调下,多个源可以设置同一个file,表示读写zip中的多个文件
*
* 如果没有设置{@link fileFormat},那么将自动取文件后缀作为格式。可以通过{@link FileHolder}来获
* 取磁盘文件或者输入输出流等信息。
*
* 在导出数据为文件时,如果设置了{@link BulkDataOptions.zipEntry},那么表示导出文件时将所有文件压
* 缩为一个文件,此时{@link FileHolder#getFileName} 将用作为压缩文件内部的相对路径,文件名和路径
* 需要有业务意义。导出数据时都设置通过此参数设置相同的文件路径,并且配置{@link BulkDataOptions.zipEntry}
* 那么将导入到一个zip文件中。
*
* 所有设置到参数中的文件对象都会被转换成{@link FileHolder},扩展开发者可以从此对象中获取文件或
* 者其他内容。
*
* 注意:外部通过{@link BulkDataOptions#file}获取的{@link FileHolder}对象需要自己通过
* {@link FileHolder#close}释放资源
*/
file?: FileHolder | string | File;
/**
* 指定压缩文件的编码格式。
*
* 当{@link BulkDataOptions#file}配置压缩文件时指定该文件的编码格式,默认为`utf-8`。
*/
zipFileEncoding?: string;
/**
* 指定读写压缩文件中的特定文件。
*
* 此属性只有在设置了{@link MigrateDataArgs.zipFile}之后才有效,此时,导出时表示将所有文件压缩为
* 一个文件,此时此属性表示要写入到zip中的文件名。而导入时表示要从zipFile中导入1个或多个表的数
* 据,此时此属性可以使用通配符表示导入zip中的一批文件,如`*` 表示导入所有文件(不会递归到子目录
* 下)、`*.csv` 表示导入csv文件。
*
* 相对路径表示,/分隔,不以/开头和结尾。
*
* 默认空,导出时自动取source的表名当做文件名,导入时表示导入所有文件。
*/
zipEntry?: string;
/**
* 文件格式,通常就是文件的后缀,如`csv`。
*
* 默认为{@link file}的后缀。
*/
fileFormat?: DataFileFormat;
/**
* 文件编码。
*
* {@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;
/**
* 是否在无法获取精确元数据信息的时候根据数据推断元数据结构。
*
* 例如当源是csv或excel文件时,文件中是没有元数据的,此时如果需要根据来源新建目标表的表结构,就
* 需要能自己推断结构了。推测元数据结构需要读取数据,会有一定代价。
*
* 默认true。
*/
inferMetadata?: boolean;
/**
* 在推测元数据结构时,最多读取多少行数据。
*
* 此选项只有在{@link inferMetadata}为true时有效。
*
* 默认10000。
*/
inferMetaMaxRowCount?: number;
/**
* 是否自动推测文件的默认参数。
*
* 设置true后在第一次读取文件内容时自动推测文件的默认参数,即自动调用
* {@link ExtBulkDataSource#inferOptions},生成的参数例如csv文件的编码、换行符,excel文件的版
* 本、列头范围等等。和{@link #inferMetaData}不同的是,{@link #inferMetaData}用于推测文件的表结构
* 如列头的列名,数据类型等。
*
* 用户如果指定了一部分参数,那么仍然会以用户指定的参数值为准,推测的信息只起到补充作用。
*
* 默认false。
*
* @see ExtBulkDataSource#inferOptions
*/
autoInferFileOptions?: boolean;
/**
* 首行是不是列头。
*
* {@link fileFormat}为`csv`时有效。
*
* 如果首行为列头,则在load data的时候,将会skip 1。比如导入带有列头的csv文件等.
* 有些类型的文件时先读程csv,用csv的处理逻辑进行导入,比如DBF,此时读取的数据不会包含列头,
* 需要在reader中将此属性改为false。
*
* 导出时,若指定首行不为列头,则仅导出数据,不导出列头。
*
* 对文件源默认true。
*/
firstRowIsColumnName?: boolean;
/**
* 是否导入行号。
*
* 启用后会自动增加行号列,按照数据顺序输出行号值,从1开始。数据顺序指格式化输出后的顺序,而不是文件中的
* 原始行号,例如excel存在两行列头,第三行才是数据,此时第三行的行号是1。
*
* 对所有文件类型都有效,默认为false,行号字段名为ROW_NUMBER。
*/
includeRowNum?: boolean;
/**
* 导出csv时的首行列名格式。
*
* {@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",表示第一行是列头,数据行从第二行开始
* 2. "1~3",表示第一到第三行是列头
* 3. "none",表示无列头,数据从第一行开始
* 4. "auto", 表示自动推测
*
* 为空时自动推测。
*/
excelDataHeader?: string;
/**
* 要读写的excel中的子表,也就是sheet。
*
* 支持sheet序号(1开始)或sheet名称
*
* 为空表示默认读取第一个。
*/
subTable?: string | number;
/**
* 要读写的excel中的第一个sheet的第一列的索引(1开始)。
*
* excel可能有隐藏列,或者存在离散的列,这种情况下,需要指定第一列的索引。
*/
excelSheetFirstDataColumn?: number;
/**
* 名匹配模式,是个正则表达式。
*
* 设置后将匹配到的sheet页数据依次写入到目标表,这些sheet应当是相同的表样。
*/
subTableMatch?: RegexString;
/**
* 表格是简历式表单,一个表单是一行数据。
*
* excel或pdf有效,默认为false。
*/
excelSheetIsForm?: boolean;
/**
* 是否要导出多个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}属性。
*
* 经测试,从本地pg导出千万级别的表到csv文件时,分片与否并不重要,pg读取数据就很快,生产端不是明
* 显瓶颈,所以当数据库就在本地且网络传输不是瓶颈时,分片不会带来明显的性能提升。当数据库是分布
* 式的,或从数据库读取数据传输到应用端有一定网络延迟,此时启用分片可以带来性能提升。故是否分片
* 读取通常需要用户自己控制,系统不自动启用。
*
* 默认空,不分片。
*/
sliceMode?: TableDataSliceMode;
/**
* 按此字段分片并发读写。
*
* 此属性是否生效依赖{@link sliceMode}的设置,需要注意:
*
* 1. 分片字段必须是主键或索引字段,只有这样才能提高查询效率。
* 2. 支持整形、字符、日期字段类型,不支持浮点类型。
*/
sliceField?: string;
/**
* 最多分片片数。
*
* 按{@link sliceField}进行分片时最大的分片片数。如果实际的数据比较少,那么分片可能会少一些,但
* 不会多于这个设置。
*
* 默认100.
*/
sliceMaxCount?: number;
/**
* 分片时每片的最小数据量。
*
* 期望分片的最小值,如果根据数据总行数和{@link sliceMaxCount}计算出来的每个分片数据行数小于这个设
* 置,则会尝试自动调整分片的数量。如果数据中行数太小,还不足以分2片,那就会放弃分片。
*
* 默认 30000
*/
sliceMinSize?: number;
/**
* 指定自定义的分片规则。
*
* 当{@link sliceMode}为{@link TableDataSliceMode.custom}时生效。
*
* 对于长整型、大数字,日期的条件请将条件中的取值都设置为字符,日期也同时支持使用时间戳长整型的
* 表示方式,格式要求以及示例:
*
* ```
* bigint_field < '10000000000000000' // 长整型
* decimal_field < '-100000.00000000000000' //大浮点数
* timestamp_field < '20220202 23:59:59' // yyyyMMdd HH:mm:ss
* timestamp_field < '20220202 23:59:59.999' // yyyyMMdd HH:mm:ss.SSS格式的字符
* timestamp_field < 1643817599999 // 长整型的时间戳形式
* ```
*/
slices?: Array<string>;
/**
* 进行分片操作的最大耗时,单位为秒
*
* 分片过程会采用二分法的方式:
*
* 1. 将最大值与最小值在内存中计算出中间值,分开为左右两部分,然后对两部分分别在数据库中求
* count(field)以查询到数据量
* 2. 对步骤一中得到的左右两部分的数据量,根据{@link sliceMinSize}进行区分:
* * 若是拆分结果大于{@link sliceMinSize}的3倍,则在这个分区中再次进行二分分片
* * 若拆分结果大于{@link sliceMinSize}并小于{@link sliceMinSize}的3倍,则将这个分区作为分片结
* 果中的一片
* * 若拆分结果小于{@link sliceMinSize}的,则将这个分片与另外一个分片的分片结果中的最靠近的一
* 个分片合并
* 3. 若是耗时超过限制,则直接在内存中根据最大值和最小值进行在内存中进行拆分
*
* 分片过程多次执行`count(field)`, `max(field)`,`min(field)`等聚集查找,可能因为没有索引或者数据量非
* 常大,导致查询耗时特别长,所以对分片时间需要有个限制,默认情况下,根据数据表大小作出限制:
*
* 1. 小于50w行,限制为0,完全根据内存来计算分片
* 2. 小于100w行,3秒
* 3. 小于1000w行,10秒
* 4. 大于3000w行,20秒
* 5. 最多30秒
*/
maxSliceTime?: number;
//========================== 数 据 迁 移 相 关 选 项 ==================================//
/**
* 设置一个批次传输给数据库的数据行数。
*
* 该值只作用于使用JDBC+INSERT方式导入数据时,使用连接器底层实现的流式导入数据方式时此选项无效,
* 批处理可以极大减少应用与数据库的网络交互次数,并提升整体吞吐量。通常在512~5000之间,不宜太
* 小、也不宜太大(可能OOM)。
*
* 默认取{@link JdbcConfigInfo.batchSize}。
*/
batchSize?: number;
/**
* 见{@link DbSupportsConf.bulkLoadBatchSize}。
*
* 通常不需要设置此选项。
*/
bulkLoadBatchSize?: number;
/**
* 是否分批提交数据。
*
* 为true时每个批次都会独立的提交数据,在迁移海量数据时不会因为巨大事务导致失败,也不会因为少量
* 数据失败而导致所有数据导入回滚。
*
* 迁移海量数据时由于极少的数据不合法或者是偶尔的网络故障而导致迁移失败是很让人崩溃的,此参数搭
* 配{@link maxErrorRowCount}参数,可以分批提交数据,让能成功导入的数据尽量成功导入。
*
* 使用JDBC+INSERT方式导入数据时,数据是分批传递给数据库的(见{@link batchSize}),但事务可能并
* 未提交,比如有100w行数据要导入到目标表,每个批次是1000行,如果启用了该选项,那么每个批次都会
* 执行提交事务(即数据库的commit),即便后面有错误没有完全导入,但是前面的批次都是入库了的。但
* 如果没有启用该选项,那么100w行数据将整体提交事务,如果有一行导入失败,那么所有行都会回滚,不
* 会导入成功。
*
* 使用连接器底层实现的流式导入数据方式时,考虑到现代数据库都对导入海量数据有优化处理,如果用户
* 没有设置{@link maxErrorRowCount},那么系统默认并不会将数据分批提供给流式导入,而是一次都给
* 它。如果用户设置了{@link maxErrorRowCount},且连接器底层实现的流式导入并不支持自己报告错误行
* 时,系统会分批将数据提供给底层导入接口。
*
* @see DbSupportsConf.supportsBulkLoadRejectErrorRows
* @see DbSupportsConf.bulkLoadBatchSize
*
* 默认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。
*
* 当使用扩展提供的导入方式时,扩展可以选择自己处理此选项,但如果底层db连接器扩展不支持,系统也
* 会分批将数据进行导入,并将遇到错误的批次改用JDBC+INSERT的方式来逐行导入以定位具体的错误行,具
* 体见{@link DbSupportsConf.supportsBulkLoadRejectErrorRows}。
*
* 默认0,表示导入过程中不接受一行失败,如果遇到错误,配置0会至少重试一次(只在JDBC+INSERT模式时
* 如此),这样可以知道具体哪行错误了,如果设置为-1表示不进行尝试,遇到错误就退出。大于0则进行尝
* 试直到遇到错误行数大于等于设置的行数。
*
* 默认0。
*/
maxErrorRowCount?: number;
/**
* 将错误行以csv格式输出到指定的文件。
*
* 此选项只在设置了{@link maxErrorRowCount}时才有效。
*/
errorRowsOutputFile?: string;
/**
* upsert语句的依据字段列表。
*
* 如果传递该值,则直接使用,否则会从数据库中查找主键、索引进行筛选。
*/
uniqueKey?: string;
/**
* 在并发迁移一个大表数据时,最开始添加到线程池中的最大数据读取的任务数量。
*
* 用于调节并合理利用线程资源,将一个大表进行分片操作分了100片,生产者就有100个,同时开100个线程
* 从数据库中读取数据,若是网络带宽仅支持30线程的并发,单位时间内生产的数据也没办法跟随生产者的
* 增加而加快,反倒因为线程池可能都被占满了,阻塞了其他任务的进行。
*
* 此选项是每个表独立作用的,配置在source源。
*
* 经测试,从本地pg导出千万级别的表到csv文件时,并发与否并不重要,pg读取数据就很快,生产端不是明
* 显瓶颈,所以当数据库就在本地且网络传输不是瓶颈时,分片不会带来明显的性能提升。当数据库是分布
* 式的,或从数据库读取数据传输到应用端有一定网络延迟,此时启用分片并发可以带来性能提升。故默认
* 值设置的并不大,是1,在数据迁移过程中系统会自动进行调节。
*
* 默认1,不能设置小于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;
/**
* 在导入一个大表数据时当来源文件最少有多少Mb才会启动并行写入。
*
* 此属性类似{@link minTableParallelWriteDataRowCount},但优先作用于文件。
*
* 此选项是每个表独立作用的,配置在target源。
*
* 单位Mb,默认是200。
*/
minTableParallelWriteDataLength?: 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;
/**
* 执行导入前,是否禁用数据表的索引
*
* 这里禁用的索引,包括主键。设置为true后,导入前会禁用主键和索引,导入完成后会恢复,提高导入的
* 效率。注意:此参数不能用于数据合并导入,如果是合并导入,此参数将不起作用。
*
* 有的数据库支持禁用和恢复索引,通过{@link DbSupportsConf.supportsDisableTableIndex}判断是否支
* 持,然后配合{@link DbSQLTemplates.disableTableIndex}模版和
* {@link DbSQLTemplates.enableTableIndex}模版来实现。如果数据库不支持禁用索引,且
* {@link DbSupportsConf.supportsAlterTablePrimaryKey}和{@link DbSupportsConf.supportsIndex}为
* true,则会导入前删除,导入后重建。
*
* 由于禁用索引代价比较大,只有在来源表数据量很大才做这个事情,比如如果文件大于
* {@link minDisableTableIndexWriteDataLength},或者数据行大于
* {@link minDisableTableIndexWriteDataRowCount}行,否则不做,即便设置了true。
*
* 对于ES,ES的索引对应的是数据库的数据表,本身没有数据表的索引概念。但是其索引可以设置禁用自动
* 刷新,来提高导入效率。这和禁用数据库索引的概念相同。
*
* 默认为false,表示不禁用索引。
*/
disableTableIndex?: boolean;
/**
* 在迁移一个大表数据时当来源数据最少有多少行时才会启动禁用索引。
*
* 由于禁用索引代价比较大,如果要写入的数据不多,那么直接写入,就不执行禁用索引了,即便
* {@link disableTableIndex}设置为true。对于导入文件或从其他数据库迁移表此参数都生效,来源是文件
* 时会自动估算行数。
*
* 此选项是每个表独立作用的,配置在target源。
*
* 默认是500000。
*/
minDisableTableIndexWriteDataRowCount?: number;
/**
* 在导入一个大表数据时当来源文件最少有多少Mb才会启动禁用索引。
*
* 此属性类似{@link minDisableTableIndexWriteDataRowCount},但优先作用于文件。
*
* 此选项是每个表独立作用的,配置在target源。
*
* 单位Mb,默认是10。
*/
minDisableTableIndexWriteDataLength?: number;
/** 目标表的描述,新建目标表时使用,不传递时将自动取源表的描述。 */
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.slices}作为切片结果
*/
custom = "custom",
/**
* 根据字段值的连续范围切片。
*
* 分析{@link BulkDataOptions.sliceField}的最大值和最小值,按{@link BulkDataOptions.sliceMaxCount}
* 设置的片数进行切片。
*/
fieldRange = "fieldRange",
/**
* 根据字段值的离散值分片。
*
* 分析{@link BulkDataOptions.sliceField}的所有值,一个值一个分片,通常用于分片例如地区、产品类
* 型等相对粗粒度的数据。
*
* 注意:这个会直接查询字段的去重值来作为分片,如果字段的去重值数量大于
* {@link BulkDataOptions.sliceMaxCount}则认为不能分片
*/
fieldDistinct = "fieldDistinct",
/**
* 根据日期的细粒度进行分片, TODO
*
* 比如:
*
* 1. 根据`年月`进行分片,将一年按照12个月份进行分片
* 2. 根据`年`进行分片
*/
// period = "period"
}
/**
* {@link ExtendPoint.dataFile} 拓展点。
*
* 拓展可以提供自定义的文件类型读取和写入的工具,用于支持产品原生不支持的文件类型,例如希望支持XML的
* 读写,或是需要支持一种特殊样式的Excel文件读写。
*
* 增加拓展后可用于需要文件读的产品功能:
*
* 1. 导入文件到数据库;
* 2. 数据加工的文件节点
*
* 约定在{@link ExtensionContributeInfo.main} 对应的脚本文件中定义脚本的写实现,实现接口参考
* {@link ExtBulkDataSourceContributor}
*
*/
declare interface DataFileExtensionContributorInfo extends ExtensionContributeInfo, CustomServerClassInfo {
/**
* 文件格式。
*
* 表示当前文件读取扩展适用的格式。当没有配置acceptFileTypes时,将默认使用fileFormat当作后缀名,
* 通常用于一些强特征性的后缀名上,如csv、pdf。这些格式数据读取方式几乎一致。对于一些弱特征性的
* 格式如xml,json之类的则不适合作为文件格式。如用户在xml中存储数据,可能读取数据的位置或者方式
* 不同,就需要配置不同的格式来区分。
*
* 基于业务来提供文件格式
*
* 提供文件格式扩展时,尽量基于使用场景或者业务来提供文件格式。如对于csv文件来说,可能需要支持很
* 多通用的选项,如文件分隔符、转义、列头等配置要通过{@link #optionItems}来配置实现,这些条件对
* 用户来说难以理解,不方便使用。应该基于业务考虑,提供类似如`pgdata`的文件格式,描述
* 为:PostgreSQL数据文件,应对pg数据库导出的数据文件读写需求。此文件格式对比通用的csv文件,不需
* 要设置任何条目,用户能很方便的根据描述来使用。
*
*
* +------------+----------------------+
* | fileFormat | 描述 |
* +------------+----------------------+
* | csv | CSV |
* +------------+----------------------+
* | pgdata | PostgreSQL数据文件 |
* +------------+----------------------+
* | mysqldata | Mysql数据文件 |
* +------------+----------------------+
* | customcsv | 自定义分隔列文本数据文件 |
* +------------+----------------------+
*
* 其中customcsv支持所有csv的可选条目,csv支持选择编码,其余的无需选择任何选项。
*
* {@link ExtBulkDataSourceContributor}.
*/
fileFormat: DataFileFormat;
/**
* 当前数据读取扩展适用的文件后缀,匹配文件时会忽略大小写。
*
* 当系统选择文件数据源或者导入文件到数据库时,后缀符合当前扩展设置的文件默认使用当前
* {@link fileFormat}来打开文件。
*/
acceptFileTypes?: succ.types.FileExtension[];
/**
* 文件格式是否支持子表
*
* 子表是数据文件中存储的子数据表格。如在excel中不同的sheet可以存储不同表结构的数据。sheet就是
* excel中的子表。文件格式支持子表时,系统文件数据源树上可以继续往下展开到子表,在数据加工中文件
* 节点设置文件的匹配规则时也能基于子表匹配。默认false。
*
* @see ExtBulkDataSource#getAllSubTables
*/
supportsSubTable?: boolean;
/**
* 数据文件支持的IO模式
*
* 支持读取的文件格式可以通过加工或者脚本读取数据文件中的数据,支持写入的文件格式支持导出时导出
* 成该格式。默认为rw,支持读写。
*
* 在{@link #optionItems}中可能有些条目只有在读取的时候才显示,可以在
* {@link CommonExtensionFormItemInfo#visible}中引用`iomode`来控制条目的显示隐藏。
*/
iomode?: ReadWriteMode;
/**
* 自定义属性。
*
* 配置后加工在拖入该文件类型时会自动显示这些自定义属性,用户可以在界面上修改设置来实现同一类型
* 文件的不同导入效果。
*
* 保存后的属性将以键值对的形式存储在元数据中。
*
* @see iomode
*/
optionItems?: CommonExtensionFormItemInfo[];
}
/**
* {@link ExtendPoint.dataFile} 拓展点中提供的第三方开发者编写的贡献器。
*
* 此接口可以是纯脚本实现,此时只需要在{@link CustomServerClassInfo.serverScript}指定的脚本文件中存在接口
* 约定的函数`createBulkDataSource`即可。
*
* 也可以是java实现,此时需要开发一个java类,并将类完整路径设置在
* {@link CustomServerClassInfo.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,
/**
* 读写过程中的运行状态与指标信息
*
* 1. 调度器会在这个对象中设置一些运行状态信息供`实现者`获取辅助代码判断,`实现者`也可以相同的修
* 改这些运行状态信息,:
* 1. {@link IORunningState.state}:运行状态
* 2. {@link IORunningState.canceled}:是否运行失败了
* 2. 记录一些日志信息方便调试与优化传入参数设置:
* 1. {@link IORunningState.log(msg: any)} 添加日志
* 2. {@link IORunningState.logSQL(sql: string)}:记录sql日志
* 3. 存储上下文变量信息,方便代码传递:{@link IORunningState.set?(name: string, v: any)}
* 4. 反馈一些`数据读写进度`以帮助调度器展示执行进度与流量控制;虽然不设置调度器也会根据内存流转
* 过数据进行预估,但是预估的毕竟不是事实数据,难免有些偏差,若是实现者有条件(比如导出到文
* 件,写出到文件的字节数是很容易获取的),还是建议正确设置这些数据:
* 1. {@link IORunningState.row_count_write} 已经写出的行数
* 2. {@link IORunningState.row_count_read} 已经读取的行数
* 3. {@link IORunningState.data_length_write} 已经写出的字节数
* 4. {@link IORunningState.data_length_read} 已经读取的字节数
*/
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,
/**
* {@link ExtBulkDataWriter.copy()}时要导入的字段中是否存在Clob字段。
*/
hasClobTargetFields?: boolean,
/**
* 有计算字段、常量字段或者当前时间戳字段要导入。
*/
hasExtraTargetFields?: boolean,
/**
* {@link ExtBulkDataWriter.copy()}时忽略的不导入的且也没有默认值的目标表字段。
*/
hasIgnoredTargetFields?: boolean,
/**
* 是否所有来源字段都被导入且与目标字段一一对应,没有计算字段、常量字段和当前时间戳字段。
*
* 为true时表示所有来源字段都导入了,没有忽略的,也没有多余的,但不保证目标表的所有字段都存在,
* 可能部分目标表的字段不需要导入数据。
*/
targetFieldsMatchAllSrcFields?: boolean,
/**
* 提供给扩展开发调用的向系统反馈的事件接口。
*
* 1. 遇到了导入不了的数据行时通知上下文{@link ExtBulkDataMonitor.onRejectRow}
* 2. 扩展实现中不太好统计执行进度{@link ExtBulkDataSourceCtx.runningState}的话,可以在向外写出
* 一行数据时委托`monitor`去计算和统计进度{@link ExtBulkDataMonitor.onWriteRow}
*
* 注意:不要同时修改{@link ExtBulkDataSourceCtx.runningState.row_count_write}和
* {@link ExtBulkDataMonitor.onWriteRow},会导致导出一条数据,但是数据记录写出两条
*/
monitor: ExtBulkDataMonitor,
/**
* 拓展文件类型的数据迁移自定义属性。
*
* 这个属性在生成reader和writer时使用,读写工具可以读取这个配置来调整读写逻辑,例如:
*
* 1. 是否要输出列头;
* 2. 设置输出日期的格式;
* 3. 将数值型输出为千分符、科学计数法、中国大写等;
* 4. 自定义读取文件的模式,例如读取简历格式的pdf和读取表格型的pdf肯定会使用不同的算法;
* 5. 读取excel时,前几行需要合并为列头;
* 6. 其他定制逻辑...
*
* @see DataFileReaderExtensionContributorInfo.propertyItems
*
*/
[propertyName: string]: any;
}
/**
* 提供给扩展开发调用的向系统反馈的事件接口。
*
* 比如遇到了导入不了的数据行需要通知系统。
*
* @see ExtBulkDataMonitor.java
*/
interface ExtBulkDataMonitor {
/**
* 方便扩展开发时通知系统错误的数据行。
*
* 当db支持数据库本地的、高性能的数据批量写入方式时(见
* {@link DbSupportsConf.supportsBulkLoad}),同时它也支持反馈错误行的详细信息(见
* {@link DbSupportsConf.supportsBulkLoadRejectErrorRows})那么db连接器的扩展开发者需要使用此接
* 口函数向系统报告导入时遇到错误的数据行,以便系统能做相应的记录并进行重试。
*
* @see DbSupportsConf.supportsBulkLoadRejectErrorRows
* @see BulkDataOptions.maxErrorRowCount
*
* @param args
*/
onRejectRow(args: {
/**错误描述信息 */
rejectError: string,
/**
* 行数据对象,需要特别注意的是,此数据行表示要写入目标表的数据,其字段顺序与
* {@link ExtBulkDataSourceCtx.targetFields}一致(要写入当前db时间戳的列为空列),不管是JDBC
* 模式导入还是流式模式导入,在报告错误行的时候都应该传递要写入目标表的数据。调用者需要保证
* 传入的行对象是稳定的,不会在后续被其它线程修改
*/
rejectRow: any,
/**错误的数据行号,0开始 */
rejectRowIndex: number,
/**当前累计的总错误行数 */
rejectRowCount: number,
}): void;
/**
* 通知系统成功写入一行数据,方便系统统计进度或进行流量控制。
*
* 当db支持数据库本地的、高性能的数据批量写入方式时(见
* {@link DbSupportsConf.supportsBulkLoad}),如果它是使用流式数据导入(如postgresql的copy命
* 令),那么它不需要调用此函数,其实此时也没法一行一行通知。
*
* 有些db的批量写入方式实现是程序代码逐行写入的,如MaxCompute,此时连接器的扩展开发者需要调用此
* 函数通知系统进度。
*
* @param row 数据行对象,是一个一维数组。
*/
onWriteRow(row: any[]): 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;
/**
* 推测打开此数据源需要的合适的参数。
*
* 在数据加工中,用户选择一个数据文件后,系统应该给出默认的适合于这个文件的选项配置,如对csv文件
* 来说,编码是utf8还是gbk、首行是列头或是数据、tab分隔还是逗号分隔等等;而在低代码中可能也会允
* 许用户上传自己的文件,有些上传的是gbk编码的,有些用户上传的是utf8编码的,系统也要能够自适应。
*
* 不同的文件格式推测的方法和要推测的选项参数不同,如csv可以推测编码、分隔符、列头等,而excel文
* 件可能需要推测数据行的起始位置,所以关于具体文件格式的选项的推测由此函数委托给扩展来实现。
*
* 扩展开发者在实现此函数时只负责进行必要的参数推测,对于用户已经在options中指定的参数可以不推
* 测,在执行此函数时直接将推测结果返回即可,不需要将推测结果自动应用于当前对象。扩展开发者也不
* 需要自己记录下上次推测的结果并在下次调用此函数时直接返回,系统会保证对一个文件只会最多调用一
* 次此函数。
*
* 系统在使用推测的选项时也会有选择的去使用,对于用户已经明确的指定了的选项,系统不会自动使用推
* 测的结果覆盖。
*
* @see BulkDataOptions.autoInferFileOptions
*
* @returns 如果无法推测,返回null。
*/
inferOptions?(): BulkDataOptions;
/**
* 获取所有子表格名称。
*
* 只对文件型数据源有效,用于获取文件里二级子表格的名称,例如excel文件里可以有多个sheet,在数据
* 加工的文件数据源列表中可以展开这些sheet,允许用户选择指定的sheet进行加工。类似的,pdf文件中可
* 能有多个页面多个表格,这种文件中存在多个表格数据的情况都可以抽象成子表格的概念。
*
* 本方法返回的结果不受到{@link BulkDataOptions#subTable}的影响。
*
* @returns 返回null表示没有子表格,当前文件就是一个表格,或文件类型不存在子表格,例如csv文件。
* 返回空数组表示是个空文件,例如空白excel。
*/
getAllSubTables?(): string[];
/**
* 做些读取数据前的准备工作。
*
* 通常不需要实现此函数。
*/
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
}
/**
* 数据文件格式,不包含点号。
*
* 对于一些强特征性文件格式,如csv、pdf,可以将文件的后缀作为数据文件格式。对于比较数据存储想对比较
* 灵活的文件,如xml,json的则不适合直接将文件后缀名作为文件格式。如用户在xml中存储数据,可能读取数据
* 的位置或者方式不同,需要使用不同的数据格式扩展来读取文件,此时针对xml就需要定义不同的文件格式来区
* 分。
*/
declare type DataFileFormat = string
/**
* 一个帮助持有文件和输入输出流的工具类。
*
* 在文件读取或者写入的时候,来源的数据文件可能是磁盘文件、也有可能是一个zip中的某个entry、甚至是一
* 个流。这些源头文件在使用时,多数以磁盘文件使用,为了让扩展开发更简单,提供一个文件的包装工具类。
* 扩展开发者总是基于此接口来操作文件或者流,底层会自动将用户设置的{@link BulkDataOptions#file}参数
* 包装成此接口。抚平来源文件的差异。增强易用性。
*
* @see BulkDataOptions#file
*/
declare interface FileHolder extends Closeable {
/**
* 获取内部持有的文件对象
*/
getFile(): File;
/**
* 获取文件名,包含文件后缀
*/
getFileName(): string;
/**
* 获取文件的数据格式
*
* @see DataFileFormat
*/
getFileFormat(): DataFileFormat;
/**
* 返回对应编码格式
*
* 对于设置了编码方式无法转换的,会抛出异常,见{@link Charset#forName(String)}
*
* @return 未设置编码格式会返回 UTF-8
*/
getEncoding(): string;
/**
* 打开reader.
*
* 返回的流可能是没有buffered的,是否需要包装buffer,由调用者自己控制。
* 返回的Reader需要使用者自己关闭
*/
openReader?(): Closeable;
/**
* 打开开头可能会有BOM标识的Reader。
*
* 微软在win2000后,对notepad存储的utf-8文档,会加上BOM(Byte Order Mark, U+FEFF),主要因为utf-8
* 和ascii是相容的;为了避免使用者自己忘记用什么存,造成utf-8文档用ascii模式打开看倒是乱码,所
* 以,在文档前加上BOM.
*
* 调用者需要负责关闭
*/
openBOMReader?(): Closeable;
/**
* 打开数据读取流。
*
* 返回的流可能是没有buffered的,比如对于文件就会直接返回{@link FileOutputStream},是否需要包装
* buffer,由调用者自己控制。
*
* @return 调用者需要自己关闭返回的流。
*/
openInputStream?(): Closeable;
/**
* 打开数据写入流。
*
* 返回的流可能是没有buffered的,是否需要包装buffer,由调用者自己控制。
*
* @return 调用者需要自己关闭返回的流。
*/
openWriter?(): Closeable;
/**
* 打开数据写入流。
*
* 返回的流可能是没有buffered的,比如对于文件就会直接返回{@link FileOutputStream},是否需要包装
* buffer,由调用者自己控制。
*
* @return 调用者需要自己关闭返回的流。
*/
openOutputStream?(): Closeable;
}
/**
* 一个结构化的、多行多列的、数据量可能会很大的数据表或文件对象。
*
* “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;
/**
* 返回持有的参数信息。
*
* 返回的结果是个对象,当启用了{@link BulkDataOptions#autoInferFileOptions}时,在执行
* {@link BulkDataSource#openReader()}时会自动调用{@link ExtBulkDataSource#inferOptions}推测参数
* 信息并补全,所以调用前后返回的内容会有所不同。
*
* @returns 当前数据源的参数配置,不为null。
*/
getOptions(): BulkDataOptions;
/**
* 返回数据总行数。
*
* 通常只对数据库表有效,文件如csv文件无法知道行数。
*
* @return -1表示未知
* @throws Exception
*/
getDataRowCount?(): number;
/**
* 返回元数据信息。
*
* 这里返回的是读取这个源时的数据结构,这里返回的元数据信息可能会被用于数据迁移时创建目标表的表
* 结构、或者建立来源和目标字段之间的映射关系。返回的元数据信息需要和{@link #openReader()}读取的
* 数据结构严格一致,包括字段个数和字段顺序。
*
* 当{@link BulkDataOptions.inferMetadata}为true时(默认true),此函数会在无法查询元数据信息的时
* 候根据数据推断元数据结构。例如当源是csv或excel文件时,文件中是没有元数据的,此时如果需要根据
* 来源新建目标表的表结构,就需要能自己推断结构了。推测元数据结构需要读取数据,会有一定代价。
*
* @param throwIfMetaNotExist 是否在实在无法获取字段列表时抛出异常,默认true。
* @return 返回来源的元数据结构,或推测的结构,可能返回null。
* @throws Exception
*/
getMetaInfo(throwIfMetaNotExist?: boolean): TableMetaInfo;
/**
* 获取所有子表格名称。
*
* 只对文件型数据源有效,用于获取文件里二级子表格的名称,例如excel文件里可以有多个sheet,在数据
* 加工的文件数据源列表中可以展开这些sheet,允许用户选择指定的sheet进行加工。类似的,pdf文件中可
* 能有多个页面多个表格,这种文件中存在多个表格数据的情况都可以抽象成子表格的概念。
*
* 本方法返回的结果不受到{@link BulkDataOptions#subTable}的影响。
*
* @return 返回null表示没有子表格,当前文件就是一个表格,或文件类型不存在子表格,例如csv文件。返
* 回空数组表示是个空文件,例如空白excel。
*/
getAllSubTables(): string[];
/**
* 打开数据读取器。
*
* 通常调用此函数不会有大代价,调用此函数并不会立即执行数据查询,也不会打开网络或大文件,因为有
* 时候获取reader只是为了获取元数据信息,reader的实现通常会确保在第一次
* {@link BulkDataReader#next()}或第一次调用{@link BulkDataReader#getCSVStream()}时才会真正的执
* 行具体资源的查询和读取。
*
* 在{@link #setOptions()}函数设置中或者当前对象调用{@link #prepareCtx()}时,都可能在内部记录了
* 用于读取器共享的一些上下文信息,如果存在,此函数需要使用它。
*
* 通常一个源,可以多次调用{@link #openReader()},就像同时并发查询一个表的数据或同时读取一个文件
* 的数据一样。需要注意,一个openReader就是一个open,要对应一个{@link BulkDataReader#close()}
* 的,调用者需要确保自己关闭返回的对象。
*
* 如果源是并发分片读取的({@link #isSlicedRead()}返回true),那么需要调用
* {@link #openSlicedReaders()}函数,而不是{@link #openReader()}函数,后者只会返回第一片的读取
* 器。
*
* @return 不会返回null
*/
openReader?(): BulkDataReader;
/**
* 是否是并行分片读取。
*
* 比如一个超大表,可以分片并发进行数据迁移,如果是分片的,此时需要调用
* {@link #openSlicedReaders()}函数,而不是{@link #openReader()}函数,后者只返回一个分片的
* reader。
*
* @return
*/
isSlicedRead?(): boolean;
/**
* 返回所有可用的分片数据读取器。
*
* 如果源是并发分片读取的({@link #isSlicedRead()}返回true),那么需要调用此函数,如果调用
* {@link #openReader()}函数只会返回第一片的读取器。如果不是并发切片读取的,只返回一个reader构成
* 的数组。
*
* 需要注意,返回的数组中的每个reader都需要在不使用时调用其关闭方法
* {@link BulkDataReader#close()}。
*
* 在{@link #setOptions()}函数设置中或者当前对象调用{@link #prepareCtx()}时,都可能在内部记录了
* 用于读取器共享的一些上下文信息,如果存在,此函数需要使用它。
*
* @return 不会返回null,如果不支持分片读取,相当于调用{@link openReader()}
*/
openSlicedReaders?(): 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(xxx)`函数可以设置切片的每片数据行数,对于需要切片的库,推荐10w~50w一片。当当前
* 切片流读取完毕后,流对象已经标记为“EOF”了,此时可以调用`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;
/**
* 批量读取多行数据。
*
* 此函数用于高效的进行行遍历。
*
* @param rows 存放读取的数据,从第0行开始填充数据,最多读取参数count指定的行数,rows中可能存在
* 也可能不存在行数组,如果存在可以直接填充数据以便复用内存,如果不存在,那么读取数据时会
* 自动创建新的行对象。
* @param count 最多读取多少行,必须传递大于0的整数,默认等于传入的rows的长度。
* @return 返回读取的行数,-1表示没有数据了。
*/
nextRows?(rows: Array<Array<any>>, count?: number): number;
/**
* 获取当前行对象。
*
* 此函数用于高效的进行行遍历,不用做多余的内存复制。需要特别注意的是,返回的行对象是内部复用
* 的,调用者在读取完毕后不要修改它,遍历下一行数据时,此对象可能会发生改变。
*
* @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, Cancelable {
/**
* 写入一行数据。
*
* 此函数通常用于在写入文件时使用。在写入大量数据时,{@link #copy(BulkDataReader)}函数通常性能更
* 好,推荐使用它。
*
* @param row
*/
writeRow(row: any[]): void;
/**
* 将数据导入到目标库或文件。
*
* 此函数使用最高效的方式将数据批量写入到目标源。
*
* 传入的reader提供了基于CSV结构的流式数据读取接口,也可以使用API一行一行遍历数据,CSV是标准的
* CSV文件格式:
*
* 1. 使用双引号扩起来转义,如果内部有双引号,那么用两个双引号转义
* 2. 不支持斜线转义,有些数据库(比如mysql)也许支持导入文件时用斜线转义,但其实标准csv都不支持
*
* @param reader 数据来源reader
*/
copy(reader: BulkDataReader): void;
}
/**
* 用于给扩展开发者实现的一个结构化的、多行多列的、数据量可能会很大的数据表或文件对象的数据写入器。
*
* 更多关于此接口使用场景的描述见{@link ExtBulkDataSource},此接口与{@link BulkDataWriter}接口相似但
* 不同,此接口主要定位给扩展开发实现使用,注意是扩展实现,也就是说当要开发一个自定义的数据写入器扩
* 展“贡献”给系统时使用,系统会将扩展提供的接口封装为{@link BulkDataWriter}接口,提供给外部使用。
*
* 此类只负责数据写入,不负责创建和调整表结构。
*
* 对应后端接口`ExtBulkDataWriter.java`,需与其保持同步修改!!!
*/
declare interface ExtBulkDataWriter extends Closeable, Cancelable {
/**
* 执行初始化,只会执行一次。
*
* @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",
/**
* 分布列和主键不兼容
*/
ERR_DISTRIBUTE_PRIMARYKEY = "err.db.distributePrimaryKey"
}
是否有帮助?
0条评论
评论