1 Star 0 Fork 102

seven / zorm

forked from springrain / zorm 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
dialect.go 23.79 KB
一键复制 编辑 原始数据 按行查看 历史
springrain 提交于 2021-03-02 09:53 . 修改注释
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
package zorm
import (
"database/sql"
"errors"
"reflect"
"regexp"
"strconv"
"strings"
"time"
"gitee.com/chunanyong/zorm/gouuid"
)
//wrapPageSQL 包装分页的SQL语句
//wrapPageSQL SQL statement for wrapping paging
func wrapPageSQL(dbType string, sqlstr string, page *Page) (string, error) {
//新的分页方法都已经不需要order by了,不再强制检查
//The new paging method does not require 'order by' anymore, no longer mandatory check.
//
/*
locOrderBy := findOrderByIndex(sqlstr)
if len(locOrderBy) <= 0 { //如果没有 order by
return "", errors.New("分页语句必须有 order by")
}
*/
var sqlbuilder strings.Builder
sqlbuilder.WriteString(sqlstr)
if dbType == "mysql" || dbType == "sqlite" || dbType == "dm" || dbType == "gbase" { //MySQL,sqlite3,dm数据库,南大通用
sqlbuilder.WriteString(" LIMIT ")
sqlbuilder.WriteString(strconv.Itoa(page.PageSize * (page.PageNo - 1)))
sqlbuilder.WriteString(",")
sqlbuilder.WriteString(strconv.Itoa(page.PageSize))
} else if dbType == "postgresql" || dbType == "kingbase" || dbType == "shentong" { //postgresql,kingbase,神通数据库
sqlbuilder.WriteString(" LIMIT ")
sqlbuilder.WriteString(strconv.Itoa(page.PageSize))
sqlbuilder.WriteString(" OFFSET ")
sqlbuilder.WriteString(strconv.Itoa(page.PageSize * (page.PageNo - 1)))
} else if dbType == "mssql" || dbType == "oracle" { //sqlserver 2012+,oracle 12c+
sqlbuilder.WriteString(" OFFSET ")
sqlbuilder.WriteString(strconv.Itoa(page.PageSize * (page.PageNo - 1)))
sqlbuilder.WriteString(" ROWS FETCH NEXT ")
sqlbuilder.WriteString(strconv.Itoa(page.PageSize))
sqlbuilder.WriteString(" ROWS ONLY ")
} else if dbType == "db2" { //db2
//先不写啦
//bug(springrain) 还需要其他的数据库分页语句
}
sqlstr = sqlbuilder.String()
return reBindSQL(dbType, sqlstr)
}
//wrapInsertSQL 包装保存Struct语句.返回语句,是否自增,错误信息
//数组传递,如果外部方法有调用append的逻辑,append会破坏指针引用,所以传递指针
//wrapInsertSQL Pack and save 'Struct' statement. Return SQL statement, whether it is incremented, error message
//Array transfer, if the external method has logic to call append, append will destroy the pointer reference, so the pointer is passed
func wrapInsertSQL(dbType string, typeOf reflect.Type, entity IEntityStruct, columns *[]reflect.StructField, values *[]interface{}) (string, int, string, error) {
sqlstr, autoIncrement, pktype, err := wrapInsertSQLNOreBuild(dbType, typeOf, entity, columns, values)
savesql, err := reBindSQL(dbType, sqlstr)
return savesql, autoIncrement, pktype, err
}
//wrapInsertSQLNOreBuild 包装保存Struct语句.返回语句,没有rebuild,返回原始的SQL,是否自增,错误信息
//数组传递,如果外部方法有调用append的逻辑,传递指针,因为append会破坏指针引用
//Pack and save Struct statement. Return SQL statement, no rebuild, return original SQL, whether it is self-increment, error message
//Array transfer, if the external method has logic to call append, append will destroy the pointer reference, so the pointer is passed
func wrapInsertSQLNOreBuild(dbType string, typeOf reflect.Type, entity IEntityStruct, columns *[]reflect.StructField, values *[]interface{}) (string, int, string, error) {
//自增类型 0(不自增),1(普通自增),2(序列自增),3(触发器自增)
//Self-increment type: 0(Not increase),1(Ordinary increment),2(Sequence increment),3(Trigger increment)
autoIncrement := 0
//主键类型
//Primary key type
pktype := ""
//SQL语句的构造器
//SQL statement constructor
var sqlBuilder strings.Builder
sqlBuilder.WriteString("INSERT INTO ")
sqlBuilder.WriteString(entity.GetTableName())
sqlBuilder.WriteString("(")
//SQL语句中,VALUES(?,?,...)语句的构造器
//In the SQL statement, the constructor of the VALUES(?,?,...) statement
var valueSQLBuilder strings.Builder
valueSQLBuilder.WriteString(" VALUES (")
//主键的名称
//The name of the primary key.
pkFieldName, e := entityPKFieldName(entity, typeOf)
if e != nil {
return "", autoIncrement, pktype, e
}
var sequence string
var sequenceOK bool
if entity.GetPkSequence() != nil {
sequence, sequenceOK = entity.GetPkSequence()[dbType]
if sequenceOK { //存在序列 Existence sequence
if sequence == "" { //触发器自增,也兼容自增关键字 Auto-increment by trigger, also compatible with auto-increment keywords.
autoIncrement = 3
} else { //序列自增 Sequence increment
autoIncrement = 2
}
}
}
for i := 0; i < len(*columns); i++ {
field := (*columns)[i]
if field.Name == pkFieldName { //如果是主键 | If it is the primary key
//获取主键类型 | Get the primary key type.
pkKind := field.Type.Kind()
if pkKind == reflect.String {
pktype = "string"
} else if pkKind == reflect.Int || pkKind == reflect.Int32 || pkKind == reflect.Int16 || pkKind == reflect.Int8 {
pktype = "int"
} else if pkKind == reflect.Int64 {
pktype = "int64"
} else {
return "", autoIncrement, pktype, errors.New("wrapInsertSQLNOreBuild不支持的主键类型")
}
if autoIncrement == 3 {
//如果是后台触发器生成的主键值,sql语句中不再体现
//去掉这一列,后续不再处理
// If it is the primary key value generated by the background trigger, it is no longer reflected in the sql statement
//Remove this column and will not process it later.
*columns = append((*columns)[:i], (*columns)[i+1:]...)
*values = append((*values)[:i], (*values)[i+1:]...)
i = i - 1
continue
}
//主键的值
//The value of the primary key
pkValue := (*values)[i]
if autoIncrement == 2 { //如果是序列自增 | If it is a sequence increment
//拼接字符串 | Concatenated string
//sqlBuilder.WriteString(getStructFieldTagColumnValue(typeOf, field.Name))
sqlBuilder.WriteString(field.Tag.Get(tagColumnName))
sqlBuilder.WriteString(",")
valueSQLBuilder.WriteString(sequence)
valueSQLBuilder.WriteString(",")
//去掉这一列,后续不再处理
//Remove this column and will not process it later.
*columns = append((*columns)[:i], (*columns)[i+1:]...)
*values = append((*values)[:i], (*values)[i+1:]...)
i = i - 1
continue
} else if (pktype == "string") && (pkValue.(string) == "") { //主键是字符串类型,并且值为"",赋值id
//生成主键字符串
//Generate primary key string
id := FuncGenerateStringID()
(*values)[i] = id
//给对象主键赋值
//Assign a value to the primary key of the object
v := reflect.ValueOf(entity).Elem()
v.FieldByName(field.Name).Set(reflect.ValueOf(id))
//如果是数字类型,并且值为0,认为是数据库自增,从数组中删除掉主键的信息,让数据库自己生成
//If it is a number type and the value is 0,
//it is considered to be a database self-increment,
//delete the primary key information from the array, and let the database generate itself.
} else if (pktype == "int" && pkValue.(int) == 0) || (pktype == "int64" && pkValue.(int64) == 0) {
//标记是自增主键
//Mark is auto-incrementing primary key
autoIncrement = 1
//去掉这一列,后续不再处理
//Remove this column and will not process it later.
*columns = append((*columns)[:i], (*columns)[i+1:]...)
*values = append((*values)[:i], (*values)[i+1:]...)
i = i - 1
continue
}
}
//拼接字符串
//Concatenated string.
//sqlBuilder.WriteString(getStructFieldTagColumnValue(typeOf, field.Name))
sqlBuilder.WriteString(field.Tag.Get(tagColumnName))
sqlBuilder.WriteString(",")
valueSQLBuilder.WriteString("?,")
}
//去掉字符串最后的 ','
//Remove the',' at the end of the string
sqlstr := sqlBuilder.String()
if len(sqlstr) > 0 {
sqlstr = sqlstr[:len(sqlstr)-1]
}
valuestr := valueSQLBuilder.String()
if len(valuestr) > 0 {
valuestr = valuestr[:len(valuestr)-1]
}
sqlstr = sqlstr + ")" + valuestr + ")"
//savesql, err := wrapSQL(dbType, sqlstr)
return sqlstr, autoIncrement, pktype, nil
}
//wrapInsertSliceSQL 包装批量保存StructSlice语句.返回语句,是否自增,错误信息
//数组传递,如果外部方法有调用append的逻辑,append会破坏指针引用,所以传递指针
//wrapInsertSliceSQL Package and save Struct Slice statements in batches. Return SQL statement, whether it is incremented, error message
//Array transfer, if the external method has logic to call append, append will destroy the pointer reference, so the pointer is passed
func wrapInsertSliceSQL(dbType string, typeOf reflect.Type, entityStructSlice []IEntityStruct, columns *[]reflect.StructField, values *[]interface{}) (string, int, error) {
sliceLen := len(entityStructSlice)
if entityStructSlice == nil || sliceLen < 1 {
return "", 0, errors.New("wrapInsertSliceSQL对象数组不能为空")
}
//第一个对象,获取第一个Struct对象,用于获取数据库字段,也获取了值
//The first object, get the first Struct object, used to get the database field, and also get the value
entity := entityStructSlice[0]
//先生成一条语句
//Generate a statement first
sqlstr, autoIncrement, _, firstErr := wrapInsertSQLNOreBuild(dbType, typeOf, entity, columns, values)
if firstErr != nil {
return "", autoIncrement, firstErr
}
//如果只有一个Struct对象
//If there is only one Struct object
if sliceLen == 1 {
sqlstr, _ = reBindSQL(dbType, sqlstr)
return sqlstr, autoIncrement, firstErr
}
//主键的名称
//The name of the primary key
pkFieldName, e := entityPKFieldName(entity, typeOf)
if e != nil {
return "", autoIncrement, e
}
//截取生成的SQL语句中 VALUES 后面的字符串值
//Intercept the string value after VALUES in the generated SQL statement
valueIndex := strings.Index(sqlstr, " VALUES (")
if valueIndex < 1 { //生成的语句异常
return "", autoIncrement, errors.New("wrapInsertSliceSQL生成的语句异常")
}
//value后面的字符串 例如 (?,?,?),用于循环拼接
//The string after the value, such as (?,?,?), is used for circular splicing
valuestr := sqlstr[valueIndex+8:]
//SQL语句的构造器
//SQL statement constructor
var insertSliceSQLBuilder strings.Builder
insertSliceSQLBuilder.WriteString(sqlstr)
for i := 1; i < sliceLen; i++ {
//拼接字符串
//Splicing string
insertSliceSQLBuilder.WriteString(",")
insertSliceSQLBuilder.WriteString(valuestr)
entityStruct := entityStructSlice[i]
for j := 0; j < len(*columns); j++ {
// 获取实体类的反射,指针下的struct
// Get the reflection of the entity class, the struct under the pointer
valueOf := reflect.ValueOf(entityStruct).Elem()
field := (*columns)[j]
if field.Name == pkFieldName { //如果是主键 | If it is the primary key
pkKind := field.Type.Kind()
//主键的值
//The value of the primary key
pkValue := valueOf.FieldByName(field.Name).Interface()
//只处理字符串类型的主键,其他类型,columns中并不包含
//Only handle primary keys of string type, other types, not included in columns
if (pkKind == reflect.String) && (pkValue.(string) == "") {
//主键是字符串类型,并且值为"",赋值'id'
//生成主键字符串
//The primary key is a string type, and the value is "", assigned the value'id'
//Generate primary key string
id := FuncGenerateStringID()
*values = append(*values, id)
//给对象主键赋值
//Assign a value to the primary key of the object
valueOf.FieldByName(field.Name).Set(reflect.ValueOf(id))
continue
}
}
//给字段赋值
//Assign a value to the field.
*values = append(*values, valueOf.FieldByName(field.Name).Interface())
}
}
//包装sql
//Wrap sql
savesql, err := reBindSQL(dbType, insertSliceSQLBuilder.String())
return savesql, autoIncrement, err
}
//wrapUpdateSQL 包装更新Struct语句
//数组传递,如果外部方法有调用append的逻辑,append会破坏指针引用,所以传递指针
//wrapUpdateSQL Package update Struct statement
//Array transfer, if the external method has logic to call append, append will destroy the pointer reference, so the pointer is passed
func wrapUpdateSQL(dbType string, typeOf reflect.Type, entity IEntityStruct, columns *[]reflect.StructField, values *[]interface{}, onlyUpdateNotZero bool) (string, error) {
//SQL语句的构造器
//SQL statement constructor
var sqlBuilder strings.Builder
sqlBuilder.WriteString("UPDATE ")
sqlBuilder.WriteString(entity.GetTableName())
sqlBuilder.WriteString(" SET ")
//主键的值
//The value of the primary key
var pkValue interface{}
//主键的名称
//The name of the primary key
pkFieldName, e := entityPKFieldName(entity, typeOf)
if e != nil {
return "", e
}
for i := 0; i < len(*columns); i++ {
field := (*columns)[i]
if field.Name == pkFieldName {
//如果是主键
//If it is the primary key.
pkValue = (*values)[i]
//去掉这一列,最后处理主键
//Remove this column, and finally process the primary key
*columns = append((*columns)[:i], (*columns)[i+1:]...)
*values = append((*values)[:i], (*values)[i+1:]...)
i = i - 1
continue
}
//如果是默认值字段,删除掉,不更新
//If it is the default value field, delete it and do not update
if onlyUpdateNotZero && (reflect.ValueOf((*values)[i]).IsZero()) {
//去掉这一列,不再处理
//Remove this column and no longer process
*columns = append((*columns)[:i], (*columns)[i+1:]...)
*values = append((*values)[:i], (*values)[i+1:]...)
i = i - 1
continue
}
//sqlBuilder.WriteString(getStructFieldTagColumnValue(typeOf, field.Name))
sqlBuilder.WriteString(field.Tag.Get(tagColumnName))
sqlBuilder.WriteString("=?,")
}
//主键的值是最后一个
//The value of the primary key is the last
*values = append(*values, pkValue)
//去掉字符串最后的 ','
//Remove the',' at the end of the string
sqlstr := sqlBuilder.String()
sqlstr = sqlstr[:len(sqlstr)-1]
sqlstr = sqlstr + " WHERE " + entity.GetPKColumnName() + "=?"
return reBindSQL(dbType, sqlstr)
}
//wrapDeleteSQL 包装删除Struct语句
//wrapDeleteSQL Package delete Struct statement
func wrapDeleteSQL(dbType string, entity IEntityStruct) (string, error) {
//SQL语句的构造器
//SQL statement constructor
var sqlBuilder strings.Builder
sqlBuilder.WriteString("DELETE FROM ")
sqlBuilder.WriteString(entity.GetTableName())
sqlBuilder.WriteString(" WHERE ")
sqlBuilder.WriteString(entity.GetPKColumnName())
sqlBuilder.WriteString("=?")
sqlstr := sqlBuilder.String()
return reBindSQL(dbType, sqlstr)
}
//wrapInsertEntityMapSQL 包装保存Map语句,Map因为没有字段属性,无法完成Id的类型判断和赋值,需要确保Map的值是完整的
//wrapInsertEntityMapSQL Pack and save the Map statement. Because Map does not have field attributes,
//it cannot complete the type judgment and assignment of Id. It is necessary to ensure that the value of Map is complete
func wrapInsertEntityMapSQL(dbType string, entity IEntityMap) (string, []interface{}, bool, error) {
//是否自增,默认false
autoIncrement := false
dbFieldMap := entity.GetDBFieldMap()
if len(dbFieldMap) < 1 {
return "", nil, autoIncrement, errors.New("wrapInsertEntityMapSQL-->GetDBFieldMap返回值不能为空")
}
//SQL对应的参数
//SQL corresponding parameters
values := []interface{}{}
//SQL语句的构造器
//SQL statement constructor
var sqlBuilder strings.Builder
sqlBuilder.WriteString("INSERT INTO ")
sqlBuilder.WriteString(entity.GetTableName())
sqlBuilder.WriteString("(")
//SQL语句中,VALUES(?,?,...)语句的构造器
//In the SQL statement, the constructor of the VALUES(?,?,...) statement.
var valueSQLBuilder strings.Builder
valueSQLBuilder.WriteString(" VALUES (")
//是否Set了主键
//Whether the primary key is set.
_, hasPK := dbFieldMap[entity.GetPKColumnName()]
if !hasPK { //如果没有设置主键,认为是自增或者序列 | If the primary key is not set, it is considered to be auto-increment or sequence
autoIncrement = true
if sequence, ok := entity.GetPkSequence()[dbType]; ok { //如果是序列 | If it is a sequence.
sqlBuilder.WriteString(entity.GetPKColumnName())
sqlBuilder.WriteString(",")
valueSQLBuilder.WriteString(sequence)
valueSQLBuilder.WriteString(",")
}
}
for k, v := range dbFieldMap {
//拼接字符串
//Concatenated string
sqlBuilder.WriteString(k)
sqlBuilder.WriteString(",")
valueSQLBuilder.WriteString("?,")
values = append(values, v)
}
//去掉字符串最后的 ','
//Remove the',' at the end of the string
sqlstr := sqlBuilder.String()
if len(sqlstr) > 0 {
sqlstr = sqlstr[:len(sqlstr)-1]
}
valuestr := valueSQLBuilder.String()
if len(valuestr) > 0 {
valuestr = valuestr[:len(valuestr)-1]
}
sqlstr = sqlstr + ")" + valuestr + ")"
var e error
sqlstr, e = reBindSQL(dbType, sqlstr)
if e != nil {
return "", nil, autoIncrement, e
}
return sqlstr, values, autoIncrement, nil
}
//wrapUpdateEntityMapSQL 包装Map更新语句,Map因为没有字段属性,无法完成Id的类型判断和赋值,需要确保Map的值是完整的
//wrapUpdateEntityMapSQL Wrap the Map update statement. Because Map does not have field attributes,
//it cannot complete the type judgment and assignment of Id. It is necessary to ensure that the value of Map is complete
func wrapUpdateEntityMapSQL(dbType string, entity IEntityMap) (string, []interface{}, error) {
dbFieldMap := entity.GetDBFieldMap()
if len(dbFieldMap) < 1 {
return "", nil, errors.New("wrapUpdateEntityMapSQL-->GetDBFieldMap返回值不能为空")
}
//SQL语句的构造器
//SQL statement constructor
var sqlBuilder strings.Builder
sqlBuilder.WriteString("UPDATE ")
sqlBuilder.WriteString(entity.GetTableName())
sqlBuilder.WriteString(" SET ")
//SQL对应的参数
//SQL corresponding parameters
values := []interface{}{}
//主键名称
//Primary key name
var pkValue interface{}
for k, v := range dbFieldMap {
if k == entity.GetPKColumnName() { //如果是主键 | If it is the primary key
pkValue = v
continue
}
//拼接字符串 | Splicing string.
sqlBuilder.WriteString(k)
sqlBuilder.WriteString("=?,")
values = append(values, v)
}
//主键的值是最后一个
//The value of the primary key is the last
values = append(values, pkValue)
//去掉字符串最后的 ','
//Remove the',' at the end of the string
sqlstr := sqlBuilder.String()
sqlstr = sqlstr[:len(sqlstr)-1]
sqlstr = sqlstr + " WHERE " + entity.GetPKColumnName() + "=?"
var e error
sqlstr, e = reBindSQL(dbType, sqlstr)
if e != nil {
return "", nil, e
}
return sqlstr, values, nil
}
//wrapQuerySQL 封装查询语句
//wrapQuerySQL Encapsulated query statement
func wrapQuerySQL(dbType string, finder *Finder, page *Page) (string, error) {
//获取到没有page的sql的语句
//Get the SQL statement without page.
sqlstr, err := finder.GetSQL()
if err != nil {
return "", err
}
if page == nil {
sqlstr, err = reBindSQL(dbType, sqlstr)
} else {
sqlstr, err = wrapPageSQL(dbType, sqlstr, page)
}
if err != nil {
return "", err
}
return sqlstr, err
}
//reBindSQL 包装基础的SQL语句,根据数据库类型,调整SQL变量符号,例如?,? $1,$2这样的
//reBindSQL Pack basic SQL statements, adjust the SQL variable symbols according to the database type, such as?,? $1,$2
func reBindSQL(dbType string, sqlstr string) (string, error) {
if dbType == "mysql" || dbType == "sqlite" || dbType == "dm" || dbType == "gbase" {
return sqlstr, nil
}
strs := strings.Split(sqlstr, "?")
if len(strs) < 1 {
return sqlstr, nil
}
var sqlBuilder strings.Builder
sqlBuilder.WriteString(strs[0])
for i := 1; i < len(strs); i++ {
if dbType == "postgresql" || dbType == "kingbase" { //postgresql,kingbase
sqlBuilder.WriteString("$")
sqlBuilder.WriteString(strconv.Itoa(i))
} else if dbType == "mssql" { //mssql
sqlBuilder.WriteString("@p")
sqlBuilder.WriteString(strconv.Itoa(i))
} else if dbType == "oracle" || dbType == "shentong" { //oracle,神州通用
sqlBuilder.WriteString(":")
sqlBuilder.WriteString(strconv.Itoa(i))
} else { //其他情况,还是使用 '?' | In other cases, or use'?'
sqlBuilder.WriteString("?")
}
sqlBuilder.WriteString(strs[i])
}
return sqlBuilder.String(), nil
}
//查询'order by'在sql中出现的开始位置和结束位置
//Query the start position and end position of'order by' in SQL
var orderByExpr = "\\s+(order)\\s+(by)+\\s"
var orderByRegexp, _ = regexp.Compile(orderByExpr)
//findOrderByIndex 查询order by在sql中出现的开始位置和结束位置
// findOrderByIndex Query the start position and end position of'order by' in SQL
func findOrderByIndex(strsql string) []int {
loc := orderByRegexp.FindStringIndex(strings.ToLower(strsql))
return loc
}
//查询'group by'在sql中出现的开始位置和结束位置
//Query the start position and end position of'group by' in sql。
var groupByExpr = "\\s+(group)\\s+(by)+\\s"
var groupByRegexp, _ = regexp.Compile(groupByExpr)
//findGroupByIndex 查询group by在sql中出现的开始位置和结束位置
//findGroupByIndex Query the start position and end position of'group by' in sql
func findGroupByIndex(strsql string) []int {
loc := groupByRegexp.FindStringIndex(strings.ToLower(strsql))
return loc
}
//查询 from 在sql中出现的开始位置和结束位置
//Query the start position and end position of 'from' in sql
var fromExpr = "\\s+(from)+\\s"
var fromRegexp, _ = regexp.Compile(fromExpr)
//findFromIndexa 查询from在sql中出现的开始位置和结束位置
//findFromIndex Query the start position and end position of 'from' in sql
func findFromIndex(strsql string) []int {
loc := fromRegexp.FindStringIndex(strings.ToLower(strsql))
return loc
}
//converValueColumnType 根据数据库的字段类型,转化成golang的类型,不处理sql.Nullxxx类型
//converValueColumnType According to the field type of the database, it is converted to the type of golang, and the sql.Nullxxx type is not processed
func converValueColumnType(v interface{}, columnType *sql.ColumnType) interface{} {
if v == nil {
return nil
}
//如果是字节数组
//If it is a byte array
value, ok := v.([]byte)
if !ok { //转化失败,不是字节数组,例如:string,直接返回值
return v
}
if len(value) < 1 { //值为空,为nil
return value
}
//获取数据库类型,自己对应golang的基础类型值,不处理sql.Nullxxx类型
//Get the database type, corresponding to the basic type value of golang, and do not process the sql.Nullxxx type.
databaseTypeName := strings.ToUpper(columnType.DatabaseTypeName())
switch databaseTypeName {
case "CHAR", "NCHAR", "VARCHAR", "NVARCHAR", "VARCHAR2", "NVARCHAR2", "TINYTEXT", "MEDIUMTEXT", "TEXT", "NTEXT", "LONGTEXT", "LONG":
return typeConvertString(v)
case "INT", "INT4", "INTEGER", "SERIAL", "TINYINT", "BIT", "SMALLINT", "SMALLSERIAL", "INT2":
return typeConvertInt(v)
case "BIGINT", "BIGSERIAL", "INT8":
return typeConvertInt64(v)
case "FLOAT", "REAL":
return typeConvertFloat32(v)
case "DOUBLE":
return typeConvertFloat64(v)
case "DECIMAL", "NUMBER", "NUMERIC", "DEC":
return typeConvertDecimal(v)
case "DATE":
return typeConvertTime(v, "2006-01-02", time.Local)
case "TIME":
return typeConvertTime(v, "15:04:05", time.Local)
case "DATETIME":
return typeConvertTime(v, "2006-01-02 15:04:05", time.Local)
case "TIMESTAMP":
return typeConvertTime(v, "2006-01-02 15:04:05.000", time.Local)
case "BOOLEAN", "BOOL":
return typeConvertBool(v)
}
//其他类型以后再写.....
//Other types will be written later...
return v
}
//FuncGenerateStringID 默认生成字符串ID的函数.方便自定义扩展
//FuncGenerateStringID Function to generate string ID by default. Convenient for custom extension
var FuncGenerateStringID func() string = generateStringID
//generateStringID 生成主键字符串
//generateStringID Generate primary key string
func generateStringID() string {
//pk := strconv.FormatInt(time.Now().UnixNano(), 10)
pk, errUUID := gouuid.NewV4()
if errUUID != nil {
return ""
}
return pk.String()
}
Go
1
https://gitee.com/sevenday/zorm.git
git@gitee.com:sevenday/zorm.git
sevenday
zorm
zorm
master

搜索帮助