diff --git a/server/internal/db/application/db_transfer.go b/server/internal/db/application/db_transfer.go index c41dc365..1be4b5c1 100644 --- a/server/internal/db/application/db_transfer.go +++ b/server/internal/db/application/db_transfer.go @@ -162,12 +162,19 @@ func (app *dbTransferAppImpl) transferTables(task *entity.DbTransferTask, srcCon ctx := context.Background() for tbName, cols := range columnMap { - // 在目标库建表 - // 把源列信息转化成公共列信息 - commonColumns := srcDialect.TransColumns(cols) + targetCols := make([]dbi.Column, 0) + for _, col := range cols { + colPtr := &col + // 源库列转为公共列 + srcDialect.ToCommonColumn(colPtr) + // 公共列转为目标库列 + targetDialect.ToColumn(colPtr) + targetCols = append(targetCols, *colPtr) + } + // 通过公共列信息生成目标库的建表语句,并执行目标库建表 logx.Infof("开始创建目标表: 表名:%s", tbName) - _, err := targetDialect.CreateTable(commonColumns, tableMap[tbName], true) + _, err := targetDialect.CreateTable(targetCols, tableMap[tbName], true) if err != nil { end(fmt.Sprintf("创建目标表失败: 表名:%s, error: %s", tbName, err.Error()), err) return @@ -184,7 +191,7 @@ func (app *dbTransferAppImpl) transferTables(task *entity.DbTransferTask, srcCon logx.Infof("迁移数据成功: 表名:%s, 数据:%d 条", tbName, total) // 有些数据库迁移完数据之后,需要更新表自增序列为当前表最大值 - targetDialect.UpdateSequence(tbName, commonColumns) + targetDialect.UpdateSequence(tbName, targetCols) // 迁移索引信息 logx.Infof("开始迁移索引: 表名:%s", tbName) diff --git a/server/internal/db/dbm/dbi/dialect.go b/server/internal/db/dbm/dbi/dialect.go index b428b470..03382666 100644 --- a/server/internal/db/dbm/dbi/dialect.go +++ b/server/internal/db/dbm/dbi/dialect.go @@ -2,33 +2,7 @@ package dbi import ( "database/sql" -) - -const ( - CommonTypeVarchar string = "varchar" - CommonTypeChar string = "char" - CommonTypeText string = "text" - CommonTypeBlob string = "blob" - CommonTypeLongblob string = "longblob" - CommonTypeLongtext string = "longtext" - CommonTypeBinary string = "binary" - CommonTypeMediumblob string = "mediumblob" - CommonTypeMediumtext string = "mediumtext" - CommonTypeVarbinary string = "varbinary" - - CommonTypeInt string = "int" - CommonTypeSmallint string = "smallint" - CommonTypeTinyint string = "tinyint" - CommonTypeNumber string = "number" - CommonTypeBigint string = "bigint" - - CommonTypeDatetime string = "datetime" - CommonTypeDate string = "date" - CommonTypeTime string = "time" - CommonTypeTimestamp string = "timestamp" - - CommonTypeEnum string = "enum" - CommonTypeJSON string = "json" + "errors" ) const ( @@ -60,13 +34,36 @@ type Dialect interface { // 拷贝表 CopyTable(copy *DbCopyTable) error - CreateTable(commonColumns []Column, tableInfo Table, dropOldTable bool) (int, error) + CreateTable(columns []Column, tableInfo Table, dropOldTable bool) (int, error) CreateIndex(tableInfo Table, indexs []Index) error - // 把方言类型转换为通用类型 - TransColumns(columns []Column) []Column - // 有些数据库迁移完数据之后,需要更新表自增序列为当前表最大值 UpdateSequence(tableName string, columns []Column) + + // 数据库方言自带的列转换为公共列 + ToCommonColumn(dialectColumn *Column) + + // 公共列转为各个数据库方言自带的列 + ToColumn(commonColumn *Column) +} + +type DefaultDialect struct { +} + +// GetDbProgram 获取数据库程序模块,用于数据库备份与恢复 +func (dd *DefaultDialect) GetDbProgram() (DbProgram, error) { + return nil, errors.New("not support db program") +} + +func (dd *DefaultDialect) ToCommonColumn(dialectColumn *Column) { + +} + +func (dd *DefaultDialect) ToColumn(commonColumn *Column) { + +} + +func (dd *DefaultDialect) UpdateSequence(tableName string, columns []Column) { + } diff --git a/server/internal/db/dbm/dbi/metadata.go b/server/internal/db/dbm/dbi/metadata.go index 5722c718..1af4e218 100644 --- a/server/internal/db/dbm/dbi/metadata.go +++ b/server/internal/db/dbm/dbi/metadata.go @@ -2,6 +2,7 @@ package dbi import ( "embed" + "fmt" "mayfly-go/pkg/biz" "mayfly-go/pkg/utils/collx" "mayfly-go/pkg/utils/stringx" @@ -57,16 +58,30 @@ type Table struct { // 表的列信息 type Column struct { - TableName string `json:"tableName"` // 表名 - ColumnName string `json:"columnName"` // 列名 - ColumnType string `json:"columnType"` // 列类型 - ColumnComment string `json:"columnComment"` // 列备注 - IsPrimaryKey bool `json:"isPrimaryKey"` // 是否为主键 - IsIdentity bool `json:"isIdentity"` // 是否自增 - ColumnDefault string `json:"columnDefault"` // 默认值 - Nullable string `json:"nullable"` // 是否可为null - NumScale string `json:"numScale"` // 小数点 - Extra collx.M `json:"extra"` // 其他额外信息 + TableName string `json:"tableName"` // 表名 + ColumnName string `json:"columnName"` // 列名 + ColumnType string `json:"columnType"` // 列类型,包含类型等描述(后续移除) + DataType ColumnDataType `json:"dataType"` // 数据类型 + ColumnComment string `json:"columnComment"` // 列备注 + IsPrimaryKey bool `json:"isPrimaryKey"` // 是否为主键 + IsIdentity bool `json:"isIdentity"` // 是否自增 + ColumnDefault string `json:"columnDefault"` // 默认值 + Nullable string `json:"nullable"` // 是否可为null + CharMaxLength int `json:"charMaxLength"` // 字符最大长度 + NumPrecision int `json:"numPrecision"` // 精度(总数字位数) + NumScale int `json:"numScale"` // 小数点位数 + Extra collx.M `json:"extra"` // 其他额外信息 +} + +// 获取列类型,拼接数据类型与长度等。如varchar(2000),decimal(20,2) +func (c *Column) GetColumnType() string { + if c.CharMaxLength > 0 { + return fmt.Sprintf("%s(%d)", c.DataType, c.CharMaxLength) + } + if c.NumPrecision > 0 { + return fmt.Sprintf("%s(%d,%d)", c.DataType, c.NumPrecision, c.NumScale) + } + return string(c.DataType) } // 表索引信息 @@ -79,6 +94,35 @@ type Index struct { IsUnique bool `json:"isUnique"` } +type ColumnDataType string + +const ( + CommonTypeVarchar ColumnDataType = "varchar" + CommonTypeChar ColumnDataType = "char" + CommonTypeText ColumnDataType = "text" + CommonTypeBlob ColumnDataType = "blob" + CommonTypeLongblob ColumnDataType = "longblob" + CommonTypeLongtext ColumnDataType = "longtext" + CommonTypeBinary ColumnDataType = "binary" + CommonTypeMediumblob ColumnDataType = "mediumblob" + CommonTypeMediumtext ColumnDataType = "mediumtext" + CommonTypeVarbinary ColumnDataType = "varbinary" + + CommonTypeInt ColumnDataType = "int" + CommonTypeSmallint ColumnDataType = "smallint" + CommonTypeTinyint ColumnDataType = "tinyint" + CommonTypeNumber ColumnDataType = "number" + CommonTypeBigint ColumnDataType = "bigint" + + CommonTypeDatetime ColumnDataType = "datetime" + CommonTypeDate ColumnDataType = "date" + CommonTypeTime ColumnDataType = "time" + CommonTypeTimestamp ColumnDataType = "timestamp" + + CommonTypeEnum ColumnDataType = "enum" + CommonTypeJSON ColumnDataType = "json" +) + type DataType string const ( diff --git a/server/internal/db/dbm/dbi/metasql/dm_meta.sql b/server/internal/db/dbm/dbi/metasql/dm_meta.sql index 8ce62553..0f6d54a7 100644 --- a/server/internal/db/dbm/dbi/metasql/dm_meta.sql +++ b/server/internal/db/dbm/dbi/metasql/dm_meta.sql @@ -28,33 +28,9 @@ FROM all_objects a WHERE a.owner = (SELECT SF_GET_SCHEMA_NAME_BY_ID(CURRENT_SCHID)) AND a.object_type = 'TABLE' AND a.status = 'VALID' -ORDER BY a.object_name ---------------------------------------- ---DM_TABLE_INFO_BY_NAMES 表详细信息 -SELECT a.object_name as TABLE_NAME, - b.comments as TABLE_COMMENT, - a.created as CREATE_TIME, - TABLE_USED_SPACE( - (SELECT SF_GET_SCHEMA_NAME_BY_ID(CURRENT_SCHID)), - a.object_name - ) * page() as DATA_LENGTH, - (SELECT sum(INDEX_USED_PAGES(id))* page() - FROM SYSOBJECTS - WHERE NAME IN (SELECT INDEX_NAME - FROM ALL_INDEXES - WHERE OWNER = 'wxb' - AND TABLE_NAME = a.object_name)) as INDEX_LENGTH, - c.num_rows as TABLE_ROWS -FROM all_objects a - LEFT JOIN ALL_TAB_COMMENTS b ON b.TABLE_TYPE = 'TABLE' - AND a.object_name = b.TABLE_NAME - AND b.owner = a.owner - LEFT JOIN (SELECT a.owner, a.table_name, a.num_rows FROM all_tables a) c - ON c.owner = a.owner AND c.table_name = a.object_name -WHERE a.owner = (SELECT SF_GET_SCHEMA_NAME_BY_ID(CURRENT_SCHID)) - AND a.object_type = 'TABLE' - AND a.status = 'VALID' - AND a.object_name in (%s) + {{if .tableNames}} + and a.object_name in ({{.tableNames}}) + {{end}} ORDER BY a.object_name --------------------------------------- --DM_INDEX_INFO 表索引信息 diff --git a/server/internal/db/dbm/dbi/metasql/mssql_meta.sql b/server/internal/db/dbm/dbi/metasql/mssql_meta.sql index 2d05eaa4..d9445865 100644 --- a/server/internal/db/dbm/dbi/metasql/mssql_meta.sql +++ b/server/internal/db/dbm/dbi/metasql/mssql_meta.sql @@ -32,21 +32,9 @@ FROM sys.tables t left OUTER JOIN sys.partitions p ON t.object_id = p.object_id AND p.index_id = 1 left OUTER JOIN sys.extended_properties c ON t.object_id = c.major_id AND c.minor_id = 0 AND c.class = 1 where ss.name = ? -ORDER BY t.name DESC; ---------------------------------------- ---MSSQL_TABLE_INFO_BY_NAMES 表详细信息 -SELECT t.name AS tableName, - ss.name AS tableSchema, - c.value AS tableComment, - p.rows AS tableRows, - 0 AS dataLength, - 0 AS indexLength, - t.create_date AS createTime -FROM sys.tables t - left OUTER JOIN sys.schemas ss on t.schema_id = ss.schema_id - left OUTER JOIN sys.partitions p ON t.object_id = p.object_id AND p.index_id = 1 - left OUTER JOIN sys.extended_properties c ON t.object_id = c.major_id AND c.minor_id = 0 AND c.class = 1 -where ss.name = ? and t.name in (%s) +{{if .tableNames}} + and t.name in ({{.tableNames}}) +{{end}} ORDER BY t.name DESC; --------------------------------------- --MSSQL_INDEX_INFO 索引信息 diff --git a/server/internal/db/dbm/dbi/metasql/mysql_meta.sql b/server/internal/db/dbm/dbi/metasql/mysql_meta.sql index 2d67a90b..8265e734 100644 --- a/server/internal/db/dbm/dbi/metasql/mysql_meta.sql +++ b/server/internal/db/dbm/dbi/metasql/mysql_meta.sql @@ -19,25 +19,9 @@ FROM information_schema.tables WHERE table_type = 'BASE TABLE' - AND table_schema = ( - SELECT - database () - ) -ORDER BY table_name ---------------------------------------- ---MYSQL_TABLE_INFO_BY_NAMES 表详细信息 -SELECT - table_name tableName, - table_comment tableComment, - table_rows tableRows, - data_length dataLength, - index_length indexLength, - create_time createTime -FROM - information_schema.tables -WHERE - table_type = 'BASE TABLE' - AND table_name IN (%s) + {{if .tableNames}} + AND table_name IN ({{.tableNames}}) + {{end}} AND table_schema = ( SELECT database () @@ -68,6 +52,7 @@ ORDER BY SELECT table_name tableName, column_name columnName, column_type columnType, + data_type dataType, column_default columnDefault, column_comment columnComment, CASE @@ -81,7 +66,9 @@ SELECT table_name tableName, ELSE 0 END AS isIdentity, is_nullable nullable, - NUMERIC_SCALE numScale + CHARACTER_MAXIMUM_LENGTH charMaxLength, + NUMERIC_SCALE numScale, + NUMERIC_PRECISION numPrecision FROM information_schema.COLUMNS WHERE table_schema = (SELECT DATABASE()) AND table_name IN (%s) diff --git a/server/internal/db/dbm/dbi/metasql/oracle_meta.sql b/server/internal/db/dbm/dbi/metasql/oracle_meta.sql index bbe03221..eafb7ff4 100644 --- a/server/internal/db/dbm/dbi/metasql/oracle_meta.sql +++ b/server/internal/db/dbm/dbi/metasql/oracle_meta.sql @@ -15,6 +15,9 @@ from ALL_TABLES a left join ALL_OBJECTS c on c.OBJECT_TYPE = 'TABLE' AND c.OWNER = a.OWNER AND c.OBJECT_NAME = a.TABLE_NAME left join dba_segments d on d.SEGMENT_TYPE = 'TABLE' AND d.OWNER = a.OWNER AND d.SEGMENT_NAME = a.TABLE_NAME where a.owner = (SELECT sys_context('USERENV', 'CURRENT_SCHEMA') FROM dual) +{{if .tableNames}} + and a.TABLE_NAME in ({{.tableNames}}) +{{end}} ORDER BY a.TABLE_NAME --------------------------------------- --ORACLE_INDEX_INFO 表索引信息 diff --git a/server/internal/db/dbm/dbi/metasql/pgsql_meta.sql b/server/internal/db/dbm/dbi/metasql/pgsql_meta.sql index 6c7a9da4..1228eb2e 100644 --- a/server/internal/db/dbm/dbi/metasql/pgsql_meta.sql +++ b/server/internal/db/dbm/dbi/metasql/pgsql_meta.sql @@ -29,26 +29,9 @@ where has_table_privilege(CAST(c.oid AS regclass), 'SELECT') and n.nspname = current_schema() and c.reltype > 0 -order by c.relname ---------------------------------------- ---PGSQL_TABLE_INFO_BY_NAMES 表详细信息 -select - c.relname as "tableName", - obj_description (c.oid) as "tableComment", - pg_table_size ('"' || n.nspname || '"."' || c.relname || '"') as "dataLength", - pg_indexes_size ('"' || n.nspname || '"."' || c.relname || '"') as "indexLength", - psut.n_live_tup as "tableRows" -from - pg_class c -join pg_namespace n on - c.relnamespace = n.oid -join pg_stat_user_tables psut on - psut.relid = c.oid -where - has_table_privilege(CAST(c.oid AS regclass), 'SELECT') - and n.nspname = current_schema() - and c.reltype > 0 - and c.relname in (%s) + {{if .tableNames}} + and c.relname in ({{.tableNames}}) + {{end}} order by c.relname --------------------------------------- --PGSQL_INDEX_INFO 表索引信息 diff --git a/server/internal/db/dbm/dbi/metasql/sqlite_meta.sql b/server/internal/db/dbm/dbi/metasql/sqlite_meta.sql index 637a610f..a2b303c8 100644 --- a/server/internal/db/dbm/dbi/metasql/sqlite_meta.sql +++ b/server/internal/db/dbm/dbi/metasql/sqlite_meta.sql @@ -8,19 +8,9 @@ select tbl_name as tableName, FROM sqlite_master WHERE type = 'table' and name not like 'sqlite_%' -ORDER BY tbl_name ---------------------------------------- ---SQLITE_TABLE_INFO_BY_NAMES 表详细信息 -select tbl_name as tableName, - '' as tableComment, - '' as createTime, - 0 as dataLength, - 0 as indexLength, - 0 as tableRows -FROM sqlite_master -WHERE type = 'table' - and name not like 'sqlite_%' - and tbl_name in (%s) + {{if .tableNames}} + and tbl_name in ({{.tableNames}}) + {{end}} ORDER BY tbl_name --------------------------------------- --SQLITE_INDEX_INFO 表索引信息 diff --git a/server/internal/db/dbm/dm/dialect.go b/server/internal/db/dbm/dm/dialect.go index 17b0bab9..184c13c3 100644 --- a/server/internal/db/dbm/dm/dialect.go +++ b/server/internal/db/dbm/dm/dialect.go @@ -16,12 +16,9 @@ import ( ) type DMDialect struct { - dc *dbi.DbConn -} + dbi.DefaultDialect -// GetDbProgram 获取数据库程序模块,用于数据库备份与恢复 -func (dd *DMDialect) GetDbProgram() (dbi.DbProgram, error) { - return nil, fmt.Errorf("该数据库类型不支持数据库备份与恢复: %v", dd.dc.Info.Type) + dc *dbi.DbConn } func (dd *DMDialect) BatchInsert(tx *sql.Tx, tableName string, columns []string, values [][]any, duplicateStrategy int) (int64, error) { @@ -168,28 +165,28 @@ func (dd *DMDialect) CopyTable(copy *dbi.DbCopyTable) error { return err } -func (dd *DMDialect) TransColumns(columns []dbi.Column) []dbi.Column { - var commonColumns []dbi.Column - for _, column := range columns { - // 取出当前数据库类型 - arr := strings.Split(column.ColumnType, "(") - ctype := arr[0] +// func (dd *DMDialect) TransColumns(columns []dbi.Column) []dbi.Column { +// var commonColumns []dbi.Column +// for _, column := range columns { +// // 取出当前数据库类型 +// arr := strings.Split(column.ColumnType, "(") +// ctype := arr[0] - // 翻译为通用数据库类型 - t1 := commonColumnMap[ctype] - if t1 == "" { - ctype = "VARCHAR(2000)" - } else { - // 回写到列信息 - if len(arr) > 1 { - ctype = t1 + "(" + arr[1] - } - } - column.ColumnType = ctype - commonColumns = append(commonColumns, column) - } - return commonColumns -} +// // 翻译为通用数据库类型 +// t1 := commonColumnMap[ctype] +// if t1 == "" { +// ctype = "VARCHAR(2000)" +// } else { +// // 回写到列信息 +// if len(arr) > 1 { +// ctype = t1 + "(" + arr[1] +// } +// } +// column.ColumnType = ctype +// commonColumns = append(commonColumns, column) +// } +// return commonColumns +// } func (dd *DMDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Table, dropOldTable bool) (int, error) { meta := dd.dc.GetMetaData() @@ -210,7 +207,7 @@ func (dd *DMDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Table arr := strings.Split(column.ColumnType, "(") ctype := arr[0] // 翻译为通用数据库类型 - t1 := dmColumnMap[ctype] + t1 := dmColumnMap[dbi.ColumnDataType(ctype)] if t1 == "" { ctype = "VARCHAR(2000)" } else { diff --git a/server/internal/db/dbm/dm/metadata.go b/server/internal/db/dbm/dm/metadata.go index e642ff04..ed325041 100644 --- a/server/internal/db/dbm/dm/metadata.go +++ b/server/internal/db/dbm/dm/metadata.go @@ -6,18 +6,18 @@ import ( "mayfly-go/pkg/errorx" "mayfly-go/pkg/utils/anyx" "mayfly-go/pkg/utils/collx" + "mayfly-go/pkg/utils/stringx" "regexp" "strings" "time" ) const ( - DM_META_FILE = "metasql/dm_meta.sql" - DM_DB_SCHEMAS = "DM_DB_SCHEMAS" - DM_TABLE_INFO_KEY = "DM_TABLE_INFO" - DM_INDEX_INFO_KEY = "DM_INDEX_INFO" - DM_COLUMN_MA_KEY = "DM_COLUMN_MA" - DM_TABLE_INFO_BY_NAMES_KEY = "DM_TABLE_INFO_BY_NAMES" + DM_META_FILE = "metasql/dm_meta.sql" + DM_DB_SCHEMAS = "DM_DB_SCHEMAS" + DM_TABLE_INFO_KEY = "DM_TABLE_INFO" + DM_INDEX_INFO_KEY = "DM_INDEX_INFO" + DM_COLUMN_MA_KEY = "DM_COLUMN_MA" ) type DMMetaData struct { @@ -59,11 +59,12 @@ func (dd *DMMetaData) GetTables(tableNames ...string) ([]dbi.Table, error) { var res []map[string]any var err error - if tableNames != nil && len(tableNames) > 0 { - _, res, err = dd.dc.Query(fmt.Sprintf(dbi.GetLocalSql(DM_META_FILE, DM_TABLE_INFO_BY_NAMES_KEY), names)) - } else { - _, res, err = dd.dc.Query(dbi.GetLocalSql(DM_META_FILE, DM_TABLE_INFO_KEY)) + sql, err := stringx.TemplateParse(dbi.GetLocalSql(DM_META_FILE, DM_TABLE_INFO_KEY), collx.M{"tableNames": names}) + if err != nil { + return nil, err } + + _, res, err = dd.dc.Query(sql) if err != nil { return nil, err } @@ -104,7 +105,7 @@ func (dd *DMMetaData) GetColumns(tableNames ...string) ([]dbi.Column, error) { IsPrimaryKey: anyx.ConvInt(re["IS_PRIMARY_KEY"]) == 1, IsIdentity: anyx.ConvInt(re["IS_IDENTITY"]) == 1, ColumnDefault: anyx.ConvString(re["COLUMN_DEFAULT"]), - NumScale: anyx.ConvString(re["NUM_SCALE"]), + NumScale: anyx.ConvInt(re["NUM_SCALE"]), }) } return columns, nil @@ -266,7 +267,7 @@ var ( converter = new(DataConverter) // 达梦数据类型 对应 公共数据类型 - commonColumnMap = map[string]string{ + commonColumnMap = map[string]dbi.ColumnDataType{ "CHAR": dbi.CommonTypeChar, // 字符数据类型 "VARCHAR": dbi.CommonTypeVarchar, @@ -295,7 +296,7 @@ var ( } // 公共数据类型 对应 达梦数据类型 - dmColumnMap = map[string]string{ + dmColumnMap = map[dbi.ColumnDataType]string{ dbi.CommonTypeVarchar: "VARCHAR", dbi.CommonTypeChar: "CHAR", dbi.CommonTypeText: "TEXT", diff --git a/server/internal/db/dbm/mssql/dialect.go b/server/internal/db/dbm/mssql/dialect.go index b001d4b7..7a97ee25 100644 --- a/server/internal/db/dbm/mssql/dialect.go +++ b/server/internal/db/dbm/mssql/dialect.go @@ -12,6 +12,8 @@ import ( ) type MssqlDialect struct { + dbi.DefaultDialect + dc *dbi.DbConn } @@ -251,29 +253,29 @@ func (md *MssqlDialect) CopyTable(copy *dbi.DbCopyTable) error { return err } -func (md *MssqlDialect) TransColumns(columns []dbi.Column) []dbi.Column { - var commonColumns []dbi.Column - for _, column := range columns { - // 取出当前数据库类型 - arr := strings.Split(column.ColumnType, "(") - ctype := arr[0] - // 翻译为通用数据库类型 - t1 := commonColumnTypeMap[ctype] - if t1 == "" { - ctype = "nvarchar(2000)" - } else { - // 回写到列信息 - if len(arr) > 1 { - ctype = t1 + "(" + arr[1] - } else { - ctype = t1 - } - } - column.ColumnType = ctype - commonColumns = append(commonColumns, column) - } - return commonColumns -} +// func (md *MssqlDialect) TransColumns(columns []dbi.Column) []dbi.Column { +// var commonColumns []dbi.Column +// for _, column := range columns { +// // 取出当前数据库类型 +// arr := strings.Split(column.ColumnType, "(") +// ctype := arr[0] +// // 翻译为通用数据库类型 +// t1 := commonColumnTypeMap[ctype] +// if t1 == "" { +// ctype = "nvarchar(2000)" +// } else { +// // 回写到列信息 +// if len(arr) > 1 { +// ctype = t1 + "(" + arr[1] +// } else { +// ctype = t1 +// } +// } +// column.ColumnType = ctype +// commonColumns = append(commonColumns, column) +// } +// return commonColumns +// } func (md *MssqlDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Table, dropOldTable bool) (int, error) { meta := md.dc.GetMetaData() @@ -292,7 +294,7 @@ func (md *MssqlDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Ta arr := strings.Split(column.ColumnType, "(") ctype := arr[0] // 翻译为通用数据库类型 - t1 := mssqlColumnTypeMap[ctype] + t1 := mssqlColumnTypeMap[dbi.ColumnDataType(ctype)] if t1 == "" { ctype = "nvarchar(2000)" } else { diff --git a/server/internal/db/dbm/mssql/metadata.go b/server/internal/db/dbm/mssql/metadata.go index 816e7885..3f33f59a 100644 --- a/server/internal/db/dbm/mssql/metadata.go +++ b/server/internal/db/dbm/mssql/metadata.go @@ -6,21 +6,21 @@ import ( "mayfly-go/pkg/errorx" "mayfly-go/pkg/utils/anyx" "mayfly-go/pkg/utils/collx" + "mayfly-go/pkg/utils/stringx" "regexp" "strings" "time" ) const ( - MSSQL_META_FILE = "metasql/mssql_meta.sql" - MSSQL_DBS_KEY = "MSSQL_DBS" - MSSQL_DB_SCHEMAS_KEY = "MSSQL_DB_SCHEMAS" - MSSQL_TABLE_INFO_KEY = "MSSQL_TABLE_INFO" - MSSQL_TABLE_INFO_BY_NAMES_KEY = "MSSQL_TABLE_INFO_BY_NAMES" - MSSQL_INDEX_INFO_KEY = "MSSQL_INDEX_INFO" - MSSQL_COLUMN_MA_KEY = "MSSQL_COLUMN_MA" - MSSQL_TABLE_DETAIL_KEY = "MSSQL_TABLE_DETAIL" - MSSQL_TABLE_INDEX_DDL_KEY = "MSSQL_TABLE_INDEX_DDL" + MSSQL_META_FILE = "metasql/mssql_meta.sql" + MSSQL_DBS_KEY = "MSSQL_DBS" + MSSQL_DB_SCHEMAS_KEY = "MSSQL_DB_SCHEMAS" + MSSQL_TABLE_INFO_KEY = "MSSQL_TABLE_INFO" + MSSQL_INDEX_INFO_KEY = "MSSQL_INDEX_INFO" + MSSQL_COLUMN_MA_KEY = "MSSQL_COLUMN_MA" + MSSQL_TABLE_DETAIL_KEY = "MSSQL_TABLE_DETAIL" + MSSQL_TABLE_INDEX_DDL_KEY = "MSSQL_TABLE_INDEX_DDL" ) type MssqlMetaData struct { @@ -64,13 +64,16 @@ func (md *MssqlMetaData) GetTables(tableNames ...string) ([]dbi.Table, error) { var res []map[string]any var err error - - if tableNames != nil || len(tableNames) > 0 { - _, res, err = md.dc.Query(fmt.Sprintf(dbi.GetLocalSql(MSSQL_META_FILE, MSSQL_TABLE_INFO_BY_NAMES_KEY), names), schema) - } else { - _, res, err = md.dc.Query(dbi.GetLocalSql(MSSQL_META_FILE, MSSQL_TABLE_INFO_KEY), schema) + if err != nil { + return nil, err } + sql, err := stringx.TemplateParse(dbi.GetLocalSql(MSSQL_META_FILE, MSSQL_TABLE_INFO_KEY), collx.M{"tableNames": names}) + if err != nil { + return nil, err + } + + _, res, err = md.dc.Query(sql, schema) if err != nil { return nil, err } @@ -112,7 +115,7 @@ func (md *MssqlMetaData) GetColumns(tableNames ...string) ([]dbi.Column, error) IsPrimaryKey: anyx.ConvInt(re["IS_PRIMARY_KEY"]) == 1, IsIdentity: anyx.ConvInt(re["IS_IDENTITY"]) == 1, ColumnDefault: anyx.ToString(re["COLUMN_DEFAULT"]), - NumScale: anyx.ToString(re["NUM_SCALE"]), + NumScale: anyx.ConvInt(re["NUM_SCALE"]), }) } return columns, nil @@ -314,7 +317,7 @@ var ( // 定义正则表达式,匹配括号内的数字 bracketsRegexp = regexp.MustCompile(`\((\d+)\)`) // mssql数据类型 对应 公共数据类型 - commonColumnTypeMap = map[string]string{ + commonColumnTypeMap = map[string]dbi.ColumnDataType{ "bigint": dbi.CommonTypeBigint, "numeric": dbi.CommonTypeNumber, "bit": dbi.CommonTypeInt, @@ -353,7 +356,7 @@ var ( // 公共数据类型 对应 mssql数据类型 - mssqlColumnTypeMap = map[string]string{ + mssqlColumnTypeMap = map[dbi.ColumnDataType]string{ dbi.CommonTypeVarchar: "nvarchar", dbi.CommonTypeChar: "nchar", dbi.CommonTypeText: "ntext", diff --git a/server/internal/db/dbm/mysql/dialect.go b/server/internal/db/dbm/mysql/dialect.go index e65c74dc..53b19c6b 100644 --- a/server/internal/db/dbm/mysql/dialect.go +++ b/server/internal/db/dbm/mysql/dialect.go @@ -10,6 +10,8 @@ import ( ) type MysqlDialect struct { + dbi.DefaultDialect + dc *dbi.DbConn } @@ -76,31 +78,30 @@ func (md *MysqlDialect) CopyTable(copy *dbi.DbCopyTable) error { return err } -func (md *MysqlDialect) TransColumns(columns []dbi.Column) []dbi.Column { - var commonColumns []dbi.Column - for _, column := range columns { - // 取出当前数据库类型 - arr := strings.Split(column.ColumnType, "(") - ctype := arr[0] - // 翻译为通用数据库类型 - t1 := commonColumnTypeMap[ctype] - if t1 == "" { - ctype = "varchar(2000)" - } else { - // 回写到列信息 - if len(arr) > 1 { - ctype = t1 + "(" + arr[1] - } else { - ctype = t1 - } - } - column.ColumnType = ctype - commonColumns = append(commonColumns, column) +func (md *MysqlDialect) ToCommonColumn(column *dbi.Column) { + dataType := column.DataType + + t1 := commonColumnTypeMap[string(dataType)] + commonColumnType := dbi.CommonTypeVarchar + + if t1 != "" { + commonColumnType = t1 } - return commonColumns + + column.DataType = commonColumnType } -func (md *MysqlDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Table, dropOldTable bool) (int, error) { +func (md *MysqlDialect) ToColumn(column *dbi.Column) { + ctype := mysqlColumnTypeMap[column.DataType] + if ctype == "" { + column.DataType = "varchar" + column.CharMaxLength = 1000 + } else { + column.DataType = dbi.ColumnDataType(ctype) + } +} + +func (md *MysqlDialect) CreateTable(columns []dbi.Column, tableInfo dbi.Table, dropOldTable bool) (int, error) { if dropOldTable { _, _ = md.dc.Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s", tableInfo.TableName)) } @@ -109,22 +110,7 @@ func (md *MysqlDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Ta fields := make([]string, 0) pks := make([]string, 0) // 把通用类型转换为达梦类型 - for _, column := range commonColumns { - // 取出当前数据库类型 - arr := strings.Split(column.ColumnType, "(") - ctype := arr[0] - // 翻译为通用数据库类型 - t1 := mysqlColumnTypeMap[ctype] - if t1 == "" { - ctype = "varchar(2000)" - } else { - // 回写到列信息 - if len(arr) > 1 { - ctype = t1 + "(" + arr[1] - } - } - column.ColumnType = ctype - + for _, column := range columns { if column.IsPrimaryKey { pks = append(pks, column.ColumnName) } @@ -134,7 +120,7 @@ func (md *MysqlDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Ta if len(pks) > 0 { createSql += fmt.Sprintf(", PRIMARY KEY (%s)", strings.Join(pks, ",")) } - createSql += fmt.Sprintf(") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ") + createSql += ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 " if tableInfo.TableComment != "" { replacer := strings.NewReplacer(";", "", "'", "") createSql += fmt.Sprintf(" COMMENT '%s'", replacer.Replace(tableInfo.TableComment)) @@ -183,7 +169,7 @@ func (md *MysqlDialect) genColumnBasicSql(column dbi.Column) string { comment = fmt.Sprintf(" COMMENT '%s'", commentStr) } - columnSql := fmt.Sprintf(" %s %s %s %s %s %s", md.dc.GetMetaData().QuoteIdentifier(column.ColumnName), column.ColumnType, nullAble, incr, defVal, comment) + columnSql := fmt.Sprintf(" %s %s %s %s %s %s", md.dc.GetMetaData().QuoteIdentifier(column.ColumnName), column.GetColumnType(), nullAble, incr, defVal, comment) return columnSql } @@ -211,7 +197,3 @@ func (md *MysqlDialect) CreateIndex(tableInfo dbi.Table, indexs []dbi.Index) err } return nil } - -func (md *MysqlDialect) UpdateSequence(tableName string, columns []dbi.Column) { - -} diff --git a/server/internal/db/dbm/mysql/metadata.go b/server/internal/db/dbm/mysql/metadata.go index f4ece291..39363a93 100644 --- a/server/internal/db/dbm/mysql/metadata.go +++ b/server/internal/db/dbm/mysql/metadata.go @@ -7,6 +7,7 @@ import ( "mayfly-go/pkg/errorx" "mayfly-go/pkg/utils/anyx" "mayfly-go/pkg/utils/collx" + "mayfly-go/pkg/utils/stringx" "regexp" "strings" "time" @@ -15,12 +16,11 @@ import ( ) const ( - MYSQL_META_FILE = "metasql/mysql_meta.sql" - MYSQL_DBS = "MYSQL_DBS" - MYSQL_TABLE_INFO_KEY = "MYSQL_TABLE_INFO" - MYSQL_TABLE_INFO_BY_NAMES_KEY = "MYSQL_TABLE_INFO_BY_NAMES" - MYSQL_INDEX_INFO_KEY = "MYSQL_INDEX_INFO" - MYSQL_COLUMN_MA_KEY = "MYSQL_COLUMN_MA" + MYSQL_META_FILE = "metasql/mysql_meta.sql" + MYSQL_DBS = "MYSQL_DBS" + MYSQL_TABLE_INFO_KEY = "MYSQL_TABLE_INFO" + MYSQL_INDEX_INFO_KEY = "MYSQL_INDEX_INFO" + MYSQL_COLUMN_MA_KEY = "MYSQL_COLUMN_MA" ) type MysqlMetaData struct { @@ -62,12 +62,12 @@ func (md *MysqlMetaData) GetTables(tableNames ...string) ([]dbi.Table, error) { var res []map[string]any var err error - if tableNames != nil || len(tableNames) > 0 { - _, res, err = md.dc.Query(fmt.Sprintf(dbi.GetLocalSql(MYSQL_META_FILE, MYSQL_TABLE_INFO_BY_NAMES_KEY), names)) - } else { - _, res, err = md.dc.Query(dbi.GetLocalSql(MYSQL_META_FILE, MYSQL_TABLE_INFO_KEY)) + sql, err := stringx.TemplateParse(dbi.GetLocalSql(MYSQL_META_FILE, MYSQL_TABLE_INFO_KEY), collx.M{"tableNames": names}) + if err != nil { + return nil, err } + _, res, err = md.dc.Query(sql) if err != nil { return nil, err } @@ -104,12 +104,15 @@ func (md *MysqlMetaData) GetColumns(tableNames ...string) ([]dbi.Column, error) TableName: anyx.ConvString(re["tableName"]), ColumnName: anyx.ConvString(re["columnName"]), ColumnType: strings.Replace(anyx.ConvString(re["columnType"]), " unsigned", "", 1), + DataType: dbi.ColumnDataType(anyx.ConvString(re["dataType"])), ColumnComment: anyx.ConvString(re["columnComment"]), Nullable: anyx.ConvString(re["nullable"]), IsPrimaryKey: anyx.ConvInt(re["isPrimaryKey"]) == 1, IsIdentity: anyx.ConvInt(re["isIdentity"]) == 1, ColumnDefault: anyx.ConvString(re["columnDefault"]), - NumScale: anyx.ConvString(re["numScale"]), + CharMaxLength: anyx.ConvInt(re["charMaxLength"]), + NumPrecision: anyx.ConvInt(re["numPrecision"]), + NumScale: anyx.ConvInt(re["numScale"]), }) } return columns, nil @@ -215,7 +218,7 @@ var ( converter = new(DataConverter) // mysql数据类型 映射 公共数据类型 - commonColumnTypeMap = map[string]string{ + commonColumnTypeMap = map[string]dbi.ColumnDataType{ "bigint": dbi.CommonTypeBigint, "binary": dbi.CommonTypeBinary, "blob": dbi.CommonTypeBlob, @@ -243,7 +246,7 @@ var ( } // 公共数据类型 映射 mysql数据类型 - mysqlColumnTypeMap = map[string]string{ + mysqlColumnTypeMap = map[dbi.ColumnDataType]string{ dbi.CommonTypeVarchar: "varchar", dbi.CommonTypeChar: "char", dbi.CommonTypeText: "text", diff --git a/server/internal/db/dbm/oracle/dialect.go b/server/internal/db/dbm/oracle/dialect.go index 6e2ccdfc..528bd464 100644 --- a/server/internal/db/dbm/oracle/dialect.go +++ b/server/internal/db/dbm/oracle/dialect.go @@ -14,12 +14,9 @@ import ( ) type OracleDialect struct { - dc *dbi.DbConn -} + dbi.DefaultDialect -// GetDbProgram 获取数据库程序模块,用于数据库备份与恢复 -func (od *OracleDialect) GetDbProgram() (dbi.DbProgram, error) { - return nil, fmt.Errorf("该数据库类型不支持数据库备份与恢复: %v", od.dc.Info.Type) + dc *dbi.DbConn } func (od *OracleDialect) BatchInsert(tx *sql.Tx, tableName string, columns []string, values [][]any, duplicateStrategy int) (int64, error) { @@ -159,37 +156,37 @@ func (od *OracleDialect) CopyTable(copy *dbi.DbCopyTable) error { return err } -func (od *OracleDialect) TransColumns(columns []dbi.Column) []dbi.Column { - var commonColumns []dbi.Column - for _, column := range columns { - // 取出当前数据库类型 - arr := strings.Split(column.ColumnType, "(") - ctype := arr[0] +// func (od *OracleDialect) TransColumns(columns []dbi.Column) []dbi.Column { +// var commonColumns []dbi.Column +// for _, column := range columns { +// // 取出当前数据库类型 +// arr := strings.Split(column.ColumnType, "(") +// ctype := arr[0] - // 翻译为通用数据库类型 - t1 := commonColumnTypeMap[ctype] - if t1 == "" { - ctype = "NVARCHAR2(2000)" - } else { - // 回写到列信息 - if t1 == "NUMBER" { - // 如果是转number类型,需要根据公共类型加上长度, 如 bigint 需要转换为number(19,0) - if column.ColumnType == dbi.CommonTypeBigint { - ctype = t1 + "(19, 0)" - } else { - ctype = t1 - } - } else if t1 != "NUMBER" && len(arr) > 1 { - ctype = t1 + "(" + arr[1] - } else { - ctype = t1 - } - } - column.ColumnType = ctype - commonColumns = append(commonColumns, column) - } - return commonColumns -} +// // 翻译为通用数据库类型 +// t1 := commonColumnTypeMap[ctype] +// if t1 == "" { +// ctype = "NVARCHAR2(2000)" +// } else { +// // 回写到列信息 +// if t1 == "NUMBER" { +// // 如果是转number类型,需要根据公共类型加上长度, 如 bigint 需要转换为number(19,0) +// if column.ColumnType == dbi.CommonTypeBigint { +// ctype = t1 + "(19, 0)" +// } else { +// ctype = t1 +// } +// } else if t1 != "NUMBER" && len(arr) > 1 { +// ctype = t1 + "(" + arr[1] +// } else { +// ctype = t1 +// } +// } +// column.ColumnType = ctype +// commonColumns = append(commonColumns, column) +// } +// return commonColumns +// } func (od *OracleDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Table, dropOldTable bool) (int, error) { meta := od.dc.GetMetaData() @@ -220,7 +217,7 @@ end; arr := strings.Split(column.ColumnType, "(") ctype := arr[0] // 翻译为通用数据库类型 - t1 := oracleColumnTypeMap[ctype] + t1 := oracleColumnTypeMap[dbi.ColumnDataType(ctype)] if t1 == "" { ctype = "NVARCHAR2(2000)" } else { diff --git a/server/internal/db/dbm/oracle/metadata.go b/server/internal/db/dbm/oracle/metadata.go index a47376e1..731ba5f8 100644 --- a/server/internal/db/dbm/oracle/metadata.go +++ b/server/internal/db/dbm/oracle/metadata.go @@ -6,6 +6,7 @@ import ( "mayfly-go/pkg/errorx" "mayfly-go/pkg/utils/anyx" "mayfly-go/pkg/utils/collx" + "mayfly-go/pkg/utils/stringx" "regexp" "strings" "time" @@ -13,12 +14,11 @@ import ( // ---------------------------------- DM元数据 ----------------------------------- const ( - ORACLE_META_FILE = "metasql/oracle_meta.sql" - ORACLE_DB_SCHEMAS = "ORACLE_DB_SCHEMAS" - ORACLE_TABLE_INFO_KEY = "ORACLE_TABLE_INFO" - ORACLE_TABLE_INFO_BY_NAMES_KEY = "ORACLE_TABLE_INFO_BY_NAMES" - ORACLE_INDEX_INFO_KEY = "ORACLE_INDEX_INFO" - ORACLE_COLUMN_MA_KEY = "ORACLE_COLUMN_MA" + ORACLE_META_FILE = "metasql/oracle_meta.sql" + ORACLE_DB_SCHEMAS = "ORACLE_DB_SCHEMAS" + ORACLE_TABLE_INFO_KEY = "ORACLE_TABLE_INFO" + ORACLE_INDEX_INFO_KEY = "ORACLE_INDEX_INFO" + ORACLE_COLUMN_MA_KEY = "ORACLE_COLUMN_MA" ) type OracleMetaData struct { @@ -61,11 +61,12 @@ func (od *OracleMetaData) GetTables(tableNames ...string) ([]dbi.Table, error) { var res []map[string]any var err error - if tableNames != nil || len(tableNames) > 0 { - _, res, err = od.dc.Query(fmt.Sprintf(dbi.GetLocalSql(ORACLE_META_FILE, ORACLE_TABLE_INFO_BY_NAMES_KEY), names)) - } else { - _, res, err = od.dc.Query(dbi.GetLocalSql(ORACLE_META_FILE, ORACLE_TABLE_INFO_KEY)) + sql, err := stringx.TemplateParse(dbi.GetLocalSql(ORACLE_META_FILE, ORACLE_TABLE_INFO_KEY), collx.M{"tableNames": names}) + if err != nil { + return nil, err } + + _, res, err = od.dc.Query(sql) if err != nil { return nil, err } @@ -130,7 +131,7 @@ func (od *OracleMetaData) GetColumns(tableNames ...string) ([]dbi.Column, error) IsPrimaryKey: anyx.ConvInt(re["IS_PRIMARY_KEY"]) == 1, IsIdentity: anyx.ConvInt(re["IS_IDENTITY"]) == 1, ColumnDefault: defaultVal, - NumScale: anyx.ConvString(re["NUM_SCALE"]), + NumScale: anyx.ConvInt(re["NUM_SCALE"]), }) } return columns, nil @@ -286,7 +287,7 @@ var ( converter = new(DataConverter) // oracle数据类型 映射 公共数据类型 - commonColumnTypeMap = map[string]string{ + commonColumnTypeMap = map[string]dbi.ColumnDataType{ "CHAR": dbi.CommonTypeChar, "NCHAR": dbi.CommonTypeChar, "VARCHAR2": dbi.CommonTypeVarchar, @@ -309,7 +310,7 @@ var ( } // 公共数据类型 映射 oracle数据类型 - oracleColumnTypeMap = map[string]string{ + oracleColumnTypeMap = map[dbi.ColumnDataType]string{ dbi.CommonTypeVarchar: "NVARCHAR2", dbi.CommonTypeChar: "NCHAR", dbi.CommonTypeText: "CLOB", diff --git a/server/internal/db/dbm/postgres/dialect.go b/server/internal/db/dbm/postgres/dialect.go index ba4ed550..224df409 100644 --- a/server/internal/db/dbm/postgres/dialect.go +++ b/server/internal/db/dbm/postgres/dialect.go @@ -11,12 +11,9 @@ import ( ) type PgsqlDialect struct { - dc *dbi.DbConn -} + dbi.DefaultDialect -// GetDbProgram 获取数据库程序模块,用于数据库备份与恢复 -func (pd *PgsqlDialect) GetDbProgram() (dbi.DbProgram, error) { - return nil, fmt.Errorf("该数据库类型不支持数据库备份与恢复: %v", pd.dc.Info.Type) + dc *dbi.DbConn } func (pd *PgsqlDialect) BatchInsert(tx *sql.Tx, tableName string, columns []string, values [][]any, duplicateStrategy int) (int64, error) { @@ -183,30 +180,6 @@ func (pd *PgsqlDialect) CopyTable(copy *dbi.DbCopyTable) error { return err } -func (pd *PgsqlDialect) TransColumns(columns []dbi.Column) []dbi.Column { - var commonColumns []dbi.Column - for _, column := range columns { - // 取出当前数据库类型 - arr := strings.Split(column.ColumnType, "(") - ctype := arr[0] - // 翻译为通用数据库类型 - t1 := commonColumnTypeMap[ctype] - if t1 == "" { - ctype = "varchar(2000)" - } else { - // 回写到列信息 - if len(arr) > 1 { - ctype = t1 + "(" + arr[1] - } else { - ctype = t1 - } - } - column.ColumnType = ctype - commonColumns = append(commonColumns, column) - } - return commonColumns -} - func (pd *PgsqlDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Table, dropOldTable bool) (int, error) { meta := pd.dc.GetMetaData() replacer := strings.NewReplacer(";", "", "'", "") @@ -224,7 +197,7 @@ func (pd *PgsqlDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Ta arr := strings.Split(column.ColumnType, "(") ctype := arr[0] // 翻译为通用数据库类型 - t1 := pgsqlColumnTypeMap[ctype] + t1 := pgsqlColumnTypeMap[dbi.ColumnDataType(ctype)] if t1 == "" { ctype = "varchar(2000)" } else { diff --git a/server/internal/db/dbm/postgres/metadata.go b/server/internal/db/dbm/postgres/metadata.go index 4bd82de2..79794377 100644 --- a/server/internal/db/dbm/postgres/metadata.go +++ b/server/internal/db/dbm/postgres/metadata.go @@ -6,19 +6,19 @@ import ( "mayfly-go/pkg/errorx" "mayfly-go/pkg/utils/anyx" "mayfly-go/pkg/utils/collx" + "mayfly-go/pkg/utils/stringx" "regexp" "strings" "time" ) const ( - PGSQL_META_FILE = "metasql/pgsql_meta.sql" - PGSQL_DB_SCHEMAS = "PGSQL_DB_SCHEMAS" - PGSQL_TABLE_INFO_KEY = "PGSQL_TABLE_INFO" - PGSQL_INDEX_INFO_KEY = "PGSQL_INDEX_INFO" - PGSQL_COLUMN_MA_KEY = "PGSQL_COLUMN_MA" - PGSQL_TABLE_DDL_KEY = "PGSQL_TABLE_DDL_FUNC" - PGSQL_TABLE_INFO_BY_NAMES_KEY = "PGSQL_TABLE_INFO_BY_NAMES" + PGSQL_META_FILE = "metasql/pgsql_meta.sql" + PGSQL_DB_SCHEMAS = "PGSQL_DB_SCHEMAS" + PGSQL_TABLE_INFO_KEY = "PGSQL_TABLE_INFO" + PGSQL_INDEX_INFO_KEY = "PGSQL_INDEX_INFO" + PGSQL_COLUMN_MA_KEY = "PGSQL_COLUMN_MA" + PGSQL_TABLE_DDL_KEY = "PGSQL_TABLE_DDL_FUNC" ) type PgsqlMetaData struct { @@ -61,14 +61,16 @@ func (pd *PgsqlMetaData) GetTables(tableNames ...string) ([]dbi.Table, error) { var res []map[string]any var err error - if tableNames != nil || len(tableNames) > 0 { - _, res, err = pd.dc.Query(fmt.Sprintf(dbi.GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_INFO_BY_NAMES_KEY), names)) - } else { - _, res, err = pd.dc.Query(dbi.GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_INFO_KEY)) - } + sql, err := stringx.TemplateParse(dbi.GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_INFO_KEY), collx.M{"tableNames": names}) if err != nil { return nil, err } + + _, res, err = pd.dc.Query(sql) + if err != nil { + return nil, err + } + tables := make([]dbi.Table, 0) for _, re := range res { tables = append(tables, dbi.Table{ @@ -106,7 +108,7 @@ func (pd *PgsqlMetaData) GetColumns(tableNames ...string) ([]dbi.Column, error) IsPrimaryKey: anyx.ConvInt(re["isPrimaryKey"]) == 1, IsIdentity: anyx.ConvInt(re["isIdentity"]) == 1, ColumnDefault: anyx.ConvString(re["columnDefault"]), - NumScale: anyx.ConvString(re["numScale"]), + NumScale: anyx.ConvInt(re["numScale"]), }) } return columns, nil @@ -228,7 +230,7 @@ var ( converter = new(DataConverter) // pgsql数据类型 映射 公共数据类型 - commonColumnTypeMap = map[string]string{ + commonColumnTypeMap = map[string]dbi.ColumnDataType{ "int2": dbi.CommonTypeSmallint, "int4": dbi.CommonTypeInt, "int8": dbi.CommonTypeBigint, @@ -251,7 +253,7 @@ var ( "timestamp": dbi.CommonTypeTimestamp, } // 公共数据类型 映射 pgsql数据类型 - pgsqlColumnTypeMap = map[string]string{ + pgsqlColumnTypeMap = map[dbi.ColumnDataType]string{ dbi.CommonTypeVarchar: "varchar", dbi.CommonTypeChar: "char", dbi.CommonTypeText: "text", diff --git a/server/internal/db/dbm/sqlite/dialect.go b/server/internal/db/dbm/sqlite/dialect.go index 6868fc70..3cb66f5f 100644 --- a/server/internal/db/dbm/sqlite/dialect.go +++ b/server/internal/db/dbm/sqlite/dialect.go @@ -11,12 +11,9 @@ import ( ) type SqliteDialect struct { - dc *dbi.DbConn -} + dbi.DefaultDialect -// GetDbProgram 获取数据库程序模块,用于数据库备份与恢复 -func (sd *SqliteDialect) GetDbProgram() (dbi.DbProgram, error) { - return nil, fmt.Errorf("该数据库类型不支持数据库备份与恢复: %v", sd.dc.Info.Type) + dc *dbi.DbConn } func (sd *SqliteDialect) BatchInsert(tx *sql.Tx, tableName string, columns []string, values [][]any, duplicateStrategy int) (int64, error) { @@ -91,29 +88,29 @@ func (sd *SqliteDialect) CopyTable(copy *dbi.DbCopyTable) error { return err } -func (sd *SqliteDialect) TransColumns(columns []dbi.Column) []dbi.Column { - var commonColumns []dbi.Column - for _, column := range columns { - // 取出当前数据库类型 - arr := strings.Split(column.ColumnType, "(") - ctype := arr[0] - // 翻译为通用数据库类型 - t1 := commonColumnTypeMap[ctype] - if t1 == "" { - ctype = "varchar(2000)" - } else { - // 回写到列信息 - if len(arr) > 1 { - ctype = t1 + "(" + arr[1] - } else { - ctype = t1 - } - } - column.ColumnType = ctype - commonColumns = append(commonColumns, column) - } - return commonColumns -} +// func (sd *SqliteDialect) TransColumns(columns []dbi.Column) []dbi.Column { +// var commonColumns []dbi.Column +// for _, column := range columns { +// // 取出当前数据库类型 +// arr := strings.Split(column.ColumnType, "(") +// ctype := arr[0] +// // 翻译为通用数据库类型 +// t1 := commonColumnTypeMap[ctype] +// if t1 == "" { +// ctype = "varchar(2000)" +// } else { +// // 回写到列信息 +// if len(arr) > 1 { +// ctype = t1 + "(" + arr[1] +// } else { +// ctype = t1 +// } +// } +// column.ColumnType = ctype +// commonColumns = append(commonColumns, column) +// } +// return commonColumns +// } func (sd *SqliteDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.Table, dropOldTable bool) (int, error) { tbName := sd.dc.GetMetaData().QuoteIdentifier(tableInfo.TableName) @@ -133,7 +130,7 @@ func (sd *SqliteDialect) CreateTable(commonColumns []dbi.Column, tableInfo dbi.T arr := strings.Split(column.ColumnType, "(") ctype := arr[0] // 翻译为通用数据库类型 - t1 := sqliteColumnTypeMap[ctype] + t1 := sqliteColumnTypeMap[dbi.ColumnDataType(ctype)] if t1 == "" { ctype = "nvarchar(2000)" } else { diff --git a/server/internal/db/dbm/sqlite/metadata.go b/server/internal/db/dbm/sqlite/metadata.go index aac7bf31..3e515902 100644 --- a/server/internal/db/dbm/sqlite/metadata.go +++ b/server/internal/db/dbm/sqlite/metadata.go @@ -7,16 +7,16 @@ import ( "mayfly-go/pkg/logx" "mayfly-go/pkg/utils/anyx" "mayfly-go/pkg/utils/collx" + "mayfly-go/pkg/utils/stringx" "regexp" "strings" "time" ) const ( - SQLITE_META_FILE = "metasql/sqlite_meta.sql" - SQLITE_TABLE_INFO_KEY = "SQLITE_TABLE_INFO" - SQLITE_INDEX_INFO_KEY = "SQLITE_INDEX_INFO" - SQLITE_TABLE_INFO_BY_NAMES_KEY = "SQLITE_TABLE_INFO_BY_NAMES" + SQLITE_META_FILE = "metasql/sqlite_meta.sql" + SQLITE_TABLE_INFO_KEY = "SQLITE_TABLE_INFO" + SQLITE_INDEX_INFO_KEY = "SQLITE_INDEX_INFO" ) type SqliteMetaData struct { @@ -58,14 +58,16 @@ func (sd *SqliteMetaData) GetTables(tableNames ...string) ([]dbi.Table, error) { var res []map[string]any var err error - if tableNames != nil || len(tableNames) > 0 { - _, res, err = sd.dc.Query(fmt.Sprintf(dbi.GetLocalSql(SQLITE_META_FILE, SQLITE_TABLE_INFO_BY_NAMES_KEY), names)) - } else { - _, res, err = sd.dc.Query(dbi.GetLocalSql(SQLITE_META_FILE, SQLITE_TABLE_INFO_KEY)) - } + sql, err := stringx.TemplateParse(dbi.GetLocalSql(SQLITE_META_FILE, SQLITE_TABLE_INFO_KEY), collx.M{"tableNames": names}) if err != nil { return nil, err } + + _, res, err = sd.dc.Query(sql) + if err != nil { + return nil, err + } + tables := make([]dbi.Table, 0) for _, re := range res { tables = append(tables, dbi.Table{ @@ -111,7 +113,7 @@ func (sd *SqliteMetaData) GetColumns(tableNames ...string) ([]dbi.Column, error) IsPrimaryKey: anyx.ConvInt(re["pk"]) == 1, IsIdentity: anyx.ConvInt(re["pk"]) == 1, ColumnDefault: defaultValue, - NumScale: "0", + NumScale: 0, }) } } @@ -204,7 +206,7 @@ var ( converter = new(DataConverter) // sqlite数据类型 映射 公共数据类型 - commonColumnTypeMap = map[string]string{ + commonColumnTypeMap = map[string]dbi.ColumnDataType{ "int": dbi.CommonTypeInt, "integer": dbi.CommonTypeInt, "tinyint": dbi.CommonTypeTinyint, @@ -234,7 +236,7 @@ var ( } // 公共数据类型 映射 sqlite数据类型 - sqliteColumnTypeMap = map[string]string{ + sqliteColumnTypeMap = map[dbi.ColumnDataType]string{ dbi.CommonTypeVarchar: "nvarchar", dbi.CommonTypeChar: "nchar", dbi.CommonTypeText: "text",