diff --git a/aorm.go b/aorm.go index f5caf4a..10fde4c 100644 --- a/aorm.go +++ b/aorm.go @@ -2,77 +2,64 @@ package aorm import ( "database/sql" //只需导入你需要的驱动即可 + "github.com/tangpanqing/aorm/executor" ) -// LinkCommon database/sql提供的库连接与事务,二者有很多方法是一致的,为了通用,抽象为该interface -type LinkCommon interface { - Exec(query string, args ...interface{}) (sql.Result, error) - Prepare(query string) (*sql.Stmt, error) - Query(query string, args ...interface{}) (*sql.Rows, error) - QueryRow(query string, args ...interface{}) *sql.Row +// DbContent 数据库连接与数据库类型 +type DbContent struct { + DriverName string + DbLink *sql.DB } -// Executor 查询记录所需要的条件 -type Executor struct { - //数据库操作连接 - linkCommon LinkCommon +func Open(driverName string, dataSourceName string) (DbContent, error) { + db, err := sql.Open(driverName, dataSourceName) + if err != nil { + return DbContent{}, err + } - //查询参数 - tableName string - selectList []string - selectExpList []*ExpItem - groupList []string - whereList []WhereItem - joinList []string - havingList []WhereItem - orderList []string - offset int - pageSize int - isDebug bool - isLockForUpdate bool - - //sql与参数 - sql string - paramList []interface{} - - //表属性 - opinionList []OpinionItem -} - -type ExpItem struct { - Executor **Executor - FieldName string + return DbContent{ + DriverName: driverName, + DbLink: db, + }, nil } // Use 使用数据库连接,或者事务 -func Use(linkCommon LinkCommon) *Executor { - executor := &Executor{ - linkCommon: linkCommon, +func Use(linkCommon executor.LinkCommon) *executor.Executor { + executor := &executor.Executor{ + LinkCommon: linkCommon, + } + + return executor +} + +func UseNew(dbContent DbContent) *executor.Executor { + executor := &executor.Executor{ + LinkCommon: dbContent.DbLink, } return executor } // Sub 子查询 -func Sub() *Executor { - executor := &Executor{} +func Sub() *executor.Executor { + executor := &executor.Executor{} return executor } //清空查询条件,复用对象 -func (db *Executor) clear() { - db.tableName = "" - db.selectList = make([]string, 0) - db.groupList = make([]string, 0) - db.whereList = make([]WhereItem, 0) - db.joinList = make([]string, 0) - db.havingList = make([]WhereItem, 0) - db.orderList = make([]string, 0) - db.offset = 0 - db.pageSize = 0 - db.isDebug = false - db.isLockForUpdate = false - db.sql = "" - db.paramList = make([]interface{}, 0) - db.opinionList = make([]OpinionItem, 0) -} +//func (ex *executor.Executor) clear() { +// ex.tableName = "" +// ex.selectList = make([]string, 0) +// ex.groupList = make([]string, 0) +// ex.whereList = make([]executor.WhereItem, 0) +// ex.joinList = make([]string, 0) +// ex.havingList = make([]executor.WhereItem, 0) +// ex.orderList = make([]string, 0) +// ex.offset = 0 +// ex.pageSize = 0 +// ex.isDebug = false +// ex.isLockForUpdate = false +// ex.sql = "" +// ex.paramList = make([]interface{}, 0) +// ex.opinionList = make([]OpinionItem, 0) +//} diff --git a/crud.go b/executor/crud.go similarity index 61% rename from crud.go rename to executor/crud.go index d2b7487..2bee28b 100644 --- a/crud.go +++ b/executor/crud.go @@ -1,9 +1,11 @@ -package aorm +package executor import ( "database/sql" "errors" "fmt" + "github.com/tangpanqing/aorm" + "github.com/tangpanqing/aorm/null" "reflect" "strings" "unsafe" @@ -35,21 +37,21 @@ type WhereItem struct { } type IntStruct struct { - C Int + C null.Int } type FloatStruct struct { - C Float + C null.Float } // Insert 增加记录 -func (db *Executor) Insert(dest interface{}) (int64, error) { +func (ex *Executor) Insert(dest interface{}) (int64, error) { typeOf := reflect.TypeOf(dest) valueOf := reflect.ValueOf(dest) //如果没有设置表名 - if db.tableName == "" { - db.tableName = reflectTableName(typeOf, valueOf) + if ex.tableName == "" { + ex.tableName = reflectTableName(typeOf, valueOf) } var keys []string @@ -58,7 +60,7 @@ func (db *Executor) Insert(dest interface{}) (int64, error) { for i := 0; i < typeOf.Elem().NumField(); i++ { isNotNull := valueOf.Elem().Field(i).Field(0).Field(1).Bool() if isNotNull { - key := UnderLine(typeOf.Elem().Field(i).Name) + key := aorm.UnderLine(typeOf.Elem().Field(i).Name) val := valueOf.Elem().Field(i).Field(0).Field(0).Interface() keys = append(keys, key) paramList = append(paramList, val) @@ -66,9 +68,9 @@ func (db *Executor) Insert(dest interface{}) (int64, error) { } } - sqlStr := "INSERT INTO " + db.tableName + " (" + strings.Join(keys, ",") + ") VALUES (" + strings.Join(place, ",") + ")" + sqlStr := "INSERT INTO " + ex.tableName + " (" + strings.Join(keys, ",") + ") VALUES (" + strings.Join(place, ",") + ")" - res, err := db.Exec(sqlStr, paramList...) + res, err := ex.Exec(sqlStr, paramList...) if err != nil { return 0, err } @@ -82,7 +84,7 @@ func (db *Executor) Insert(dest interface{}) (int64, error) { } // InsertBatch 批量增加记录 -func (db *Executor) InsertBatch(values interface{}) (int64, error) { +func (ex *Executor) InsertBatch(values interface{}) (int64, error) { var keys []string var paramList []any @@ -95,8 +97,8 @@ func (db *Executor) InsertBatch(values interface{}) (int64, error) { typeOf := reflect.TypeOf(values).Elem().Elem() //如果没有设置表名 - if db.tableName == "" { - db.tableName = reflectTableName(typeOf, valueOf.Index(0)) + if ex.tableName == "" { + ex.tableName = reflectTableName(typeOf, valueOf.Index(0)) } for j := 0; j < valueOf.Len(); j++ { @@ -106,7 +108,7 @@ func (db *Executor) InsertBatch(values interface{}) (int64, error) { isNotNull := valueOf.Index(j).Field(i).Field(0).Field(1).Bool() if isNotNull { if j == 0 { - key := UnderLine(typeOf.Field(i).Name) + key := aorm.UnderLine(typeOf.Field(i).Name) keys = append(keys, key) } @@ -119,9 +121,9 @@ func (db *Executor) InsertBatch(values interface{}) (int64, error) { place = append(place, "("+strings.Join(placeItem, ",")+")") } - sqlStr := "INSERT INTO " + db.tableName + " (" + strings.Join(keys, ",") + ") VALUES " + strings.Join(place, ",") + sqlStr := "INSERT INTO " + ex.tableName + " (" + strings.Join(keys, ",") + ") VALUES " + strings.Join(place, ",") - res, err := db.Exec(sqlStr, paramList...) + res, err := ex.Exec(sqlStr, paramList...) if err != nil { return 0, err } @@ -135,10 +137,10 @@ func (db *Executor) InsertBatch(values interface{}) (int64, error) { } // GetRows 获取行操作 -func (db *Executor) GetRows() (*sql.Rows, error) { - sqlStr, paramList := db.GetSqlAndParams() +func (ex *Executor) GetRows() (*sql.Rows, error) { + sqlStr, paramList := ex.GetSqlAndParams() - smt, errSmt := db.linkCommon.Prepare(sqlStr) + smt, errSmt := ex.LinkCommon.Prepare(sqlStr) if errSmt != nil { return nil, errSmt } @@ -153,8 +155,8 @@ func (db *Executor) GetRows() (*sql.Rows, error) { } // GetMany 查询记录(新) -func (db *Executor) GetMany(values interface{}) error { - rows, errRows := db.GetRows() +func (ex *Executor) GetMany(values interface{}) error { + rows, errRows := ex.GetRows() defer rows.Close() if errRows != nil { return errRows @@ -188,10 +190,10 @@ func (db *Executor) GetMany(values interface{}) error { } // GetOne 查询某一条记录 -func (db *Executor) GetOne(obj interface{}) error { - db.Limit(0, 1) +func (ex *Executor) GetOne(obj interface{}) error { + ex.Limit(0, 1) - rows, errRows := db.GetRows() + rows, errRows := ex.GetRows() defer rows.Close() if errRows != nil { return errRows @@ -221,31 +223,31 @@ func (db *Executor) GetOne(obj interface{}) error { } // RawSql 执行原始的sql语句 -func (db *Executor) RawSql(sql string, paramList ...interface{}) *Executor { - db.sql = sql - db.paramList = paramList - return db +func (ex *Executor) RawSql(sql string, paramList ...interface{}) *Executor { + ex.sql = sql + ex.paramList = paramList + return ex } -func (db *Executor) GetSqlAndParams() (string, []interface{}) { - if db.sql != "" { - return db.sql, db.paramList +func (ex *Executor) GetSqlAndParams() (string, []interface{}) { + if ex.sql != "" { + return ex.sql, ex.paramList } var paramList []interface{} - fieldStr, paramList := handleField(db.selectList, db.selectExpList, paramList) - whereStr, paramList := handleWhere(db.whereList, paramList) - joinStr := handleJoin(db.joinList) - groupStr := handleGroup(db.groupList) - havingStr, paramList := handleHaving(db.havingList, paramList) - orderStr := handleOrder(db.orderList) - limitStr, paramList := handleLimit(db.offset, db.pageSize, paramList) - lockStr := handleLockForUpdate(db.isLockForUpdate) + fieldStr, paramList := handleField(ex.selectList, ex.selectExpList, paramList) + whereStr, paramList := handleWhere(ex.whereList, paramList) + joinStr := handleJoin(ex.joinList) + groupStr := handleGroup(ex.groupList) + havingStr, paramList := handleHaving(ex.havingList, paramList) + orderStr := handleOrder(ex.orderList) + limitStr, paramList := handleLimit(ex.offset, ex.pageSize, paramList) + lockStr := handleLockForUpdate(ex.isLockForUpdate) - sqlStr := "SELECT " + fieldStr + " FROM " + db.tableName + joinStr + whereStr + groupStr + havingStr + orderStr + limitStr + lockStr + sqlStr := "SELECT " + fieldStr + " FROM " + ex.tableName + joinStr + whereStr + groupStr + havingStr + orderStr + limitStr + lockStr - if db.isDebug { + if ex.isDebug { fmt.Println(sqlStr) fmt.Println(paramList...) } @@ -254,35 +256,35 @@ func (db *Executor) GetSqlAndParams() (string, []interface{}) { } // Update 更新记录 -func (db *Executor) Update(dest interface{}) (int64, error) { +func (ex *Executor) Update(dest interface{}) (int64, error) { var paramList []any - setStr, paramList := db.handleSet(dest, paramList) - whereStr, paramList := handleWhere(db.whereList, paramList) - sqlStr := "UPDATE " + db.tableName + setStr + whereStr + setStr, paramList := ex.handleSet(dest, paramList) + whereStr, paramList := handleWhere(ex.whereList, paramList) + sqlStr := "UPDATE " + ex.tableName + setStr + whereStr - return db.ExecAffected(sqlStr, paramList...) + return ex.ExecAffected(sqlStr, paramList...) } // Delete 删除记录 -func (db *Executor) Delete() (int64, error) { +func (ex *Executor) Delete() (int64, error) { var paramList []any - whereStr, paramList := handleWhere(db.whereList, paramList) - sqlStr := "DELETE FROM " + db.tableName + whereStr + whereStr, paramList := handleWhere(ex.whereList, paramList) + sqlStr := "DELETE FROM " + ex.tableName + whereStr - return db.ExecAffected(sqlStr, paramList...) + return ex.ExecAffected(sqlStr, paramList...) } // Truncate 清空记录 -func (db *Executor) Truncate() (int64, error) { - sqlStr := "TRUNCATE TABLE " + db.tableName +func (ex *Executor) Truncate() (int64, error) { + sqlStr := "TRUNCATE TABLE " + ex.tableName - return db.ExecAffected(sqlStr) + return ex.ExecAffected(sqlStr) } // Count 聚合函数-数量 -func (db *Executor) Count(fieldName string) (int64, error) { +func (ex *Executor) Count(fieldName string) (int64, error) { var obj []IntStruct - err := db.Select("count(" + fieldName + ") as c").GetMany(&obj) + err := ex.Select("count(" + fieldName + ") as c").GetMany(&obj) if err != nil { return 0, err } @@ -291,9 +293,9 @@ func (db *Executor) Count(fieldName string) (int64, error) { } // Sum 聚合函数-合计 -func (db *Executor) Sum(fieldName string) (float64, error) { +func (ex *Executor) Sum(fieldName string) (float64, error) { var obj []FloatStruct - err := db.Select("sum(" + fieldName + ") as c").GetMany(&obj) + err := ex.Select("sum(" + fieldName + ") as c").GetMany(&obj) if err != nil { return 0, err } @@ -302,9 +304,9 @@ func (db *Executor) Sum(fieldName string) (float64, error) { } // Avg 聚合函数-平均值 -func (db *Executor) Avg(fieldName string) (float64, error) { +func (ex *Executor) Avg(fieldName string) (float64, error) { var obj []FloatStruct - err := db.Select("avg(" + fieldName + ") as c").GetMany(&obj) + err := ex.Select("avg(" + fieldName + ") as c").GetMany(&obj) if err != nil { return 0, err } @@ -313,9 +315,9 @@ func (db *Executor) Avg(fieldName string) (float64, error) { } // Max 聚合函数-最大值 -func (db *Executor) Max(fieldName string) (float64, error) { +func (ex *Executor) Max(fieldName string) (float64, error) { var obj []FloatStruct - err := db.Select("max(" + fieldName + ") as c").GetMany(&obj) + err := ex.Select("max(" + fieldName + ") as c").GetMany(&obj) if err != nil { return 0, err } @@ -324,9 +326,9 @@ func (db *Executor) Max(fieldName string) (float64, error) { } // Min 聚合函数-最小值 -func (db *Executor) Min(fieldName string) (float64, error) { +func (ex *Executor) Min(fieldName string) (float64, error) { var obj []FloatStruct - err := db.Select("min(" + fieldName + ") as c").GetMany(&obj) + err := ex.Select("min(" + fieldName + ") as c").GetMany(&obj) if err != nil { return 0, err } @@ -335,10 +337,10 @@ func (db *Executor) Min(fieldName string) (float64, error) { } // Value 字段值 -func (db *Executor) Value(fieldName string, dest interface{}) error { - db.Select(fieldName).Limit(0, 1) +func (ex *Executor) Value(fieldName string, dest interface{}) error { + ex.Select(fieldName).Limit(0, 1) - rows, errRows := db.GetRows() + rows, errRows := ex.GetRows() defer rows.Close() if errRows != nil { return errRows @@ -373,10 +375,10 @@ func (db *Executor) Value(fieldName string, dest interface{}) error { } // Pluck 获取某一列的值 -func (db *Executor) Pluck(fieldName string, values interface{}) error { - db.Select(fieldName) +func (ex *Executor) Pluck(fieldName string, values interface{}) error { + ex.Select(fieldName) - rows, errRows := db.GetRows() + rows, errRows := ex.GetRows() defer rows.Close() if errRows != nil { return errRows @@ -415,33 +417,33 @@ func (db *Executor) Pluck(fieldName string, values interface{}) error { } // Increment 某字段自增 -func (db *Executor) Increment(fieldName string, step int) (int64, error) { +func (ex *Executor) Increment(fieldName string, step int) (int64, error) { var paramList []any paramList = append(paramList, step) - whereStr, paramList := handleWhere(db.whereList, paramList) - sqlStr := "UPDATE " + db.tableName + " SET " + fieldName + "=" + fieldName + "+?" + whereStr + whereStr, paramList := handleWhere(ex.whereList, paramList) + sqlStr := "UPDATE " + ex.tableName + " SET " + fieldName + "=" + fieldName + "+?" + whereStr - return db.ExecAffected(sqlStr, paramList...) + return ex.ExecAffected(sqlStr, paramList...) } // Decrement 某字段自减 -func (db *Executor) Decrement(fieldName string, step int) (int64, error) { +func (ex *Executor) Decrement(fieldName string, step int) (int64, error) { var paramList []any paramList = append(paramList, step) - whereStr, paramList := handleWhere(db.whereList, paramList) - sqlStr := "UPDATE " + db.tableName + " SET " + fieldName + "=" + fieldName + "-?" + whereStr + whereStr, paramList := handleWhere(ex.whereList, paramList) + sqlStr := "UPDATE " + ex.tableName + " SET " + fieldName + "=" + fieldName + "-?" + whereStr - return db.ExecAffected(sqlStr, paramList...) + return ex.ExecAffected(sqlStr, paramList...) } // Exec 通用执行-新增,更新,删除 -func (db *Executor) Exec(sqlStr string, args ...interface{}) (sql.Result, error) { - if db.isDebug { +func (ex *Executor) Exec(sqlStr string, args ...interface{}) (sql.Result, error) { + if ex.isDebug { fmt.Println(sqlStr) fmt.Println(args...) } - smt, err1 := db.linkCommon.Prepare(sqlStr) + smt, err1 := ex.LinkCommon.Prepare(sqlStr) if err1 != nil { return nil, err1 } @@ -452,13 +454,13 @@ func (db *Executor) Exec(sqlStr string, args ...interface{}) (sql.Result, error) return nil, err2 } - db.clear() + //ex.clear() return res, nil } // ExecAffected 通用执行-更新,删除 -func (db *Executor) ExecAffected(sqlStr string, args ...interface{}) (int64, error) { - res, err := db.Exec(sqlStr, args...) +func (ex *Executor) ExecAffected(sqlStr string, args ...interface{}) (int64, error) { + res, err := ex.Exec(sqlStr, args...) if err != nil { return 0, err } @@ -472,400 +474,400 @@ func (db *Executor) ExecAffected(sqlStr string, args ...interface{}) (int64, err } // Debug 链式操作-是否开启调试,打印sql -func (db *Executor) Debug(isDebug bool) *Executor { - db.isDebug = isDebug - return db +func (ex *Executor) Debug(isDebug bool) *Executor { + ex.isDebug = isDebug + return ex } // Select 链式操作-查询哪些字段,默认 * -func (db *Executor) Select(fields ...string) *Executor { - db.selectList = append(db.selectList, fields...) - return db +func (ex *Executor) Select(fields ...string) *Executor { + ex.selectList = append(ex.selectList, fields...) + return ex } // SelectCount 链式操作-count(field) as field_new -func (db *Executor) SelectCount(field string, fieldNew string) *Executor { - db.selectList = append(db.selectList, "count("+field+") AS "+fieldNew) - return db +func (ex *Executor) SelectCount(field string, fieldNew string) *Executor { + ex.selectList = append(ex.selectList, "count("+field+") AS "+fieldNew) + return ex } // SelectSum 链式操作-sum(field) as field_new -func (db *Executor) SelectSum(field string, fieldNew string) *Executor { - db.selectList = append(db.selectList, "sum("+field+") AS "+fieldNew) - return db +func (ex *Executor) SelectSum(field string, fieldNew string) *Executor { + ex.selectList = append(ex.selectList, "sum("+field+") AS "+fieldNew) + return ex } // SelectMin 链式操作-min(field) as field_new -func (db *Executor) SelectMin(field string, fieldNew string) *Executor { - db.selectList = append(db.selectList, "min("+field+") AS "+fieldNew) - return db +func (ex *Executor) SelectMin(field string, fieldNew string) *Executor { + ex.selectList = append(ex.selectList, "min("+field+") AS "+fieldNew) + return ex } // SelectMax 链式操作-max(field) as field_new -func (db *Executor) SelectMax(field string, fieldNew string) *Executor { - db.selectList = append(db.selectList, "max("+field+") AS "+fieldNew) - return db +func (ex *Executor) SelectMax(field string, fieldNew string) *Executor { + ex.selectList = append(ex.selectList, "max("+field+") AS "+fieldNew) + return ex } // SelectAvg 链式操作-avg(field) as field_new -func (db *Executor) SelectAvg(field string, fieldNew string) *Executor { - db.selectList = append(db.selectList, "avg("+field+") AS "+fieldNew) - return db +func (ex *Executor) SelectAvg(field string, fieldNew string) *Executor { + ex.selectList = append(ex.selectList, "avg("+field+") AS "+fieldNew) + return ex } // SelectExp 链式操作-表达式 -func (db *Executor) SelectExp(dbSub **Executor, fieldName string) *Executor { - db.selectExpList = append(db.selectExpList, &ExpItem{ +func (ex *Executor) SelectExp(dbSub **Executor, fieldName string) *Executor { + ex.selectExpList = append(ex.selectExpList, &ExpItem{ Executor: dbSub, FieldName: fieldName, }) - return db + return ex } // Table 链式操作-从哪个表查询,允许直接写别名,例如 person p -func (db *Executor) Table(tableName string) *Executor { - db.tableName = tableName - return db +func (ex *Executor) Table(tableName string) *Executor { + ex.tableName = tableName + return ex } // LeftJoin 链式操作,左联查询,例如 LeftJoin("project p", "p.project_id=o.project_id") -func (db *Executor) LeftJoin(tableName string, condition string) *Executor { - db.joinList = append(db.joinList, "LEFT JOIN "+tableName+" ON "+condition) - return db +func (ex *Executor) LeftJoin(tableName string, condition string) *Executor { + ex.joinList = append(ex.joinList, "LEFT JOIN "+tableName+" ON "+condition) + return ex } // RightJoin 链式操作,右联查询,例如 RightJoin("project p", "p.project_id=o.project_id") -func (db *Executor) RightJoin(tableName string, condition string) *Executor { - db.joinList = append(db.joinList, "RIGHT JOIN "+tableName+" ON "+condition) - return db +func (ex *Executor) RightJoin(tableName string, condition string) *Executor { + ex.joinList = append(ex.joinList, "RIGHT JOIN "+tableName+" ON "+condition) + return ex } // Join 链式操作,内联查询,例如 Join("project p", "p.project_id=o.project_id") -func (db *Executor) Join(tableName string, condition string) *Executor { - db.joinList = append(db.joinList, "INNER JOIN "+tableName+" ON "+condition) - return db +func (ex *Executor) Join(tableName string, condition string) *Executor { + ex.joinList = append(ex.joinList, "INNER JOIN "+tableName+" ON "+condition) + return ex } // Where 链式操作,以对象作为查询条件 -func (db *Executor) Where(dest interface{}) *Executor { +func (ex *Executor) Where(dest interface{}) *Executor { typeOf := reflect.TypeOf(dest) valueOf := reflect.ValueOf(dest) //如果没有设置表名 - if db.tableName == "" { - db.tableName = reflectTableName(typeOf, valueOf) + if ex.tableName == "" { + ex.tableName = reflectTableName(typeOf, valueOf) } for i := 0; i < typeOf.Elem().NumField(); i++ { isNotNull := valueOf.Elem().Field(i).Field(0).Field(1).Bool() if isNotNull { - key := UnderLine(typeOf.Elem().Field(i).Name) + key := aorm.UnderLine(typeOf.Elem().Field(i).Name) val := valueOf.Elem().Field(i).Field(0).Field(0).Interface() - db.whereList = append(db.whereList, WhereItem{Field: key, Opt: Eq, Val: val}) + ex.whereList = append(ex.whereList, WhereItem{Field: key, Opt: Eq, Val: val}) } } - return db + return ex } // WhereArr 链式操作,以数组作为查询条件 -func (db *Executor) WhereArr(whereList []WhereItem) *Executor { - db.whereList = append(db.whereList, whereList...) - return db +func (ex *Executor) WhereArr(whereList []WhereItem) *Executor { + ex.whereList = append(ex.whereList, whereList...) + return ex } -func (db *Executor) WhereEq(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereEq(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Eq, Val: val, }) - return db + return ex } -func (db *Executor) WhereNe(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereNe(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Ne, Val: val, }) - return db + return ex } -func (db *Executor) WhereGt(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereGt(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Gt, Val: val, }) - return db + return ex } -func (db *Executor) WhereGe(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereGe(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Ge, Val: val, }) - return db + return ex } -func (db *Executor) WhereLt(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereLt(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Lt, Val: val, }) - return db + return ex } -func (db *Executor) WhereLe(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereLe(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Le, Val: val, }) - return db + return ex } -func (db *Executor) WhereIn(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereIn(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: In, Val: val, }) - return db + return ex } -func (db *Executor) WhereNotIn(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereNotIn(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: NotIn, Val: val, }) - return db + return ex } -func (db *Executor) WhereBetween(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereBetween(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Between, Val: val, }) - return db + return ex } -func (db *Executor) WhereNotBetween(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereNotBetween(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: NotBetween, Val: val, }) - return db + return ex } -func (db *Executor) WhereLike(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereLike(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Like, Val: val, }) - return db + return ex } -func (db *Executor) WhereNotLike(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereNotLike(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: NotLike, Val: val, }) - return db + return ex } -func (db *Executor) WhereRaw(field string, val interface{}) *Executor { - db.whereList = append(db.whereList, WhereItem{ +func (ex *Executor) WhereRaw(field string, val interface{}) *Executor { + ex.whereList = append(ex.whereList, WhereItem{ Field: field, Opt: Raw, Val: val, }) - return db + return ex } // GroupBy 链式操作,以某字段进行分组 -func (db *Executor) GroupBy(fieldName string) *Executor { - db.groupList = append(db.groupList, fieldName) - return db +func (ex *Executor) GroupBy(fieldName string) *Executor { + ex.groupList = append(ex.groupList, fieldName) + return ex } // Having 链式操作,以对象作为筛选条件 -func (db *Executor) Having(dest interface{}) *Executor { +func (ex *Executor) Having(dest interface{}) *Executor { typeOf := reflect.TypeOf(dest) valueOf := reflect.ValueOf(dest) //如果没有设置表名 - if db.tableName == "" { - db.tableName = reflectTableName(typeOf, valueOf) + if ex.tableName == "" { + ex.tableName = reflectTableName(typeOf, valueOf) } for i := 0; i < typeOf.Elem().NumField(); i++ { isNotNull := valueOf.Elem().Field(i).Field(0).Field(1).Bool() if isNotNull { - key := UnderLine(typeOf.Elem().Field(i).Name) + key := aorm.UnderLine(typeOf.Elem().Field(i).Name) val := valueOf.Elem().Field(i).Field(0).Field(0).Interface() - db.havingList = append(db.havingList, WhereItem{Field: key, Opt: Eq, Val: val}) + ex.havingList = append(ex.havingList, WhereItem{Field: key, Opt: Eq, Val: val}) } } - return db + return ex } // HavingArr 链式操作,以数组作为筛选条件 -func (db *Executor) HavingArr(havingList []WhereItem) *Executor { - db.havingList = append(db.havingList, havingList...) - return db +func (ex *Executor) HavingArr(havingList []WhereItem) *Executor { + ex.havingList = append(ex.havingList, havingList...) + return ex } -func (db *Executor) HavingEq(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingEq(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Eq, Val: val, }) - return db + return ex } -func (db *Executor) HavingNe(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingNe(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Ne, Val: val, }) - return db + return ex } -func (db *Executor) HavingGt(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingGt(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Gt, Val: val, }) - return db + return ex } -func (db *Executor) HavingGe(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingGe(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Ge, Val: val, }) - return db + return ex } -func (db *Executor) HavingLt(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingLt(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Lt, Val: val, }) - return db + return ex } -func (db *Executor) HavingLe(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingLe(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Le, Val: val, }) - return db + return ex } -func (db *Executor) HavingIn(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingIn(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: In, Val: val, }) - return db + return ex } -func (db *Executor) HavingNotIn(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingNotIn(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: NotIn, Val: val, }) - return db + return ex } -func (db *Executor) HavingBetween(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingBetween(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Between, Val: val, }) - return db + return ex } -func (db *Executor) HavingNotBetween(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingNotBetween(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: NotBetween, Val: val, }) - return db + return ex } -func (db *Executor) HavingLike(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingLike(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Like, Val: val, }) - return db + return ex } -func (db *Executor) HavingNotLike(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingNotLike(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: NotLike, Val: val, }) - return db + return ex } -func (db *Executor) HavingRaw(field string, val interface{}) *Executor { - db.havingList = append(db.havingList, WhereItem{ +func (ex *Executor) HavingRaw(field string, val interface{}) *Executor { + ex.havingList = append(ex.havingList, WhereItem{ Field: field, Opt: Raw, Val: val, }) - return db + return ex } // OrderBy 链式操作,以某字段进行排序 -func (db *Executor) OrderBy(field string, orderType string) *Executor { - db.orderList = append(db.orderList, field+" "+orderType) - return db +func (ex *Executor) OrderBy(field string, orderType string) *Executor { + ex.orderList = append(ex.orderList, field+" "+orderType) + return ex } // Limit 链式操作,分页 -func (db *Executor) Limit(offset int, pageSize int) *Executor { - db.offset = offset - db.pageSize = pageSize - return db +func (ex *Executor) Limit(offset int, pageSize int) *Executor { + ex.offset = offset + ex.pageSize = pageSize + return ex } // Page 链式操作,分页 -func (db *Executor) Page(pageNum int, pageSize int) *Executor { - db.offset = (pageNum - 1) * pageSize - db.pageSize = pageSize - return db +func (ex *Executor) Page(pageNum int, pageSize int) *Executor { + ex.offset = (pageNum - 1) * pageSize + ex.pageSize = pageSize + return ex } // LockForUpdate 加锁 -func (db *Executor) LockForUpdate(isLockForUpdate bool) *Executor { - db.isLockForUpdate = isLockForUpdate - return db +func (ex *Executor) LockForUpdate(isLockForUpdate bool) *Executor { + ex.isLockForUpdate = isLockForUpdate + return ex } //拼接SQL,字段相关 @@ -897,20 +899,20 @@ func handleWhere(where []WhereItem, paramList []any) (string, []any) { } //拼接SQL,更新信息 -func (db *Executor) handleSet(dest interface{}, paramList []any) (string, []any) { +func (ex *Executor) handleSet(dest interface{}, paramList []any) (string, []any) { typeOf := reflect.TypeOf(dest) valueOf := reflect.ValueOf(dest) //如果没有设置表名 - if db.tableName == "" { - db.tableName = reflectTableName(typeOf, valueOf) + if ex.tableName == "" { + ex.tableName = reflectTableName(typeOf, valueOf) } var keys []string for i := 0; i < typeOf.Elem().NumField(); i++ { isNotNull := valueOf.Elem().Field(i).Field(0).Field(1).Bool() if isNotNull { - key := UnderLine(typeOf.Elem().Field(i).Name) + key := aorm.UnderLine(typeOf.Elem().Field(i).Name) val := valueOf.Elem().Field(i).Field(0).Field(0).Interface() keys = append(keys, key+"=?") @@ -984,7 +986,7 @@ func handleLockForUpdate(isLock bool) string { func whereAndHaving(where []WhereItem, paramList []any) ([]string, []any) { var whereList []string for i := 0; i < len(where); i++ { - if "**aorm.Executor" == reflect.TypeOf(where[i].Val).String() { + if "**Executor" == reflect.TypeOf(where[i].Val).String() { executor := *(**Executor)(unsafe.Pointer(reflect.ValueOf(where[i].Val).Pointer())) subSql, subParams := executor.GetSqlAndParams() @@ -1092,7 +1094,7 @@ func reflectTableName(typeOf reflect.Type, valueOf reflect.Value) string { return res[0].String() } else { arr := strings.Split(typeOf.String(), ".") - return UnderLine(arr[len(arr)-1]) + return aorm.UnderLine(arr[len(arr)-1]) } } @@ -1108,7 +1110,7 @@ func getFieldNameMap(destValue reflect.Value, destType reflect.Type) map[string] func getScans(columnNameList []string, fieldNameMap map[string]int, destValue reflect.Value) []interface{} { var scans []interface{} for _, columnName := range columnNameList { - fieldName := CamelString(strings.ToLower(columnName)) + fieldName := aorm.CamelString(strings.ToLower(columnName)) index, ok := fieldNameMap[fieldName] if ok { scans = append(scans, destValue.Field(index).Addr().Interface()) diff --git a/executor/model.go b/executor/model.go new file mode 100644 index 0000000..dca3735 --- /dev/null +++ b/executor/model.go @@ -0,0 +1,52 @@ +package executor + +import "database/sql" + +// LinkCommon database/sql提供的库连接与事务,二者有很多方法是一致的,为了通用,抽象为该interface +type LinkCommon interface { + Exec(query string, args ...interface{}) (sql.Result, error) + Prepare(query string) (*sql.Stmt, error) + Query(query string, args ...interface{}) (*sql.Rows, error) + QueryRow(query string, args ...interface{}) *sql.Row +} + +// ExpItem 将某子语句重命名为某字段 +type ExpItem struct { + Executor **Executor + FieldName string +} + +// Executor 查询记录所需要的条件 +type Executor struct { + //数据库操作连接 + LinkCommon LinkCommon + + //查询参数 + tableName string + selectList []string + selectExpList []*ExpItem + groupList []string + whereList []WhereItem + joinList []string + havingList []WhereItem + orderList []string + offset int + pageSize int + isDebug bool + isLockForUpdate bool + + //sql与参数 + sql string + paramList []interface{} + + //表属性 + opinionList []OpinionItem + + //驱动名字 + driverName string +} + +type OpinionItem struct { + Key string + Val string +} diff --git a/migrate.go b/migrate.go index 1a3be1e..4cae9e2 100644 --- a/migrate.go +++ b/migrate.go @@ -1,490 +1,456 @@ package aorm import ( - "fmt" + "github.com/tangpanqing/aorm/executor" + "github.com/tangpanqing/aorm/migrate_mysql" "reflect" - "strconv" "strings" ) -type Table struct { - TableName String - Engine String - TableComment String +func (ex *executor.Executor) Driver(driverName string) *executor.Executor { + ex.driverName = driverName + return ex } -type Column struct { - ColumnName String - ColumnDefault String - IsNullable String - DataType String //数据类型 varchar,bigint,int - MaxLength Int //数据最大长度 20 - ColumnComment String - Extra String //扩展信息 auto_increment -} - -type Index struct { - NonUnique int - ColumnName string - KeyName string -} - -type OpinionItem struct { - Key string - Val string -} - -func (db *Executor) Opinion(key string, val string) *Executor { +func (ex *executor.Executor) Opinion(key string, val string) *executor.Executor { if key == "COMMENT" { val = "'" + val + "'" } - db.opinionList = append(db.opinionList, OpinionItem{Key: key, Val: val}) + ex.opinionList = append(ex.opinionList, OpinionItem{Key: key, Val: val}) - return db + return ex } -func (db *Executor) ShowCreateTable(tableName string) string { - var str string - db.RawSql("show create table "+tableName).Value("Create Table", &str) - return str +//ShowCreateTable 获取创建表的ddl +func (ex *executor.Executor) ShowCreateTable(tableName string) string { + if ex.driverName == "mysql" { + cr := migrate_mysql.MigrateExecutor{} + return cr.SetEx(ex).ShowCreateTable(tableName) + } + return "" } // AutoMigrate 迁移数据库结构,需要输入数据库名,表名自动获取 -func (db *Executor) AutoMigrate(dest interface{}) { +func (ex *Executor) AutoMigrate(dest interface{}) { typeOf := reflect.TypeOf(dest) arr := strings.Split(typeOf.String(), ".") tableName := UnderLine(arr[len(arr)-1]) - db.migrateCommon(tableName, typeOf) + ex.migrateCommon(tableName, typeOf) } // Migrate 自动迁移数据库结构,需要输入数据库名,表名 -func (db *Executor) Migrate(tableName string, dest interface{}) { +func (ex *Executor) Migrate(tableName string, dest interface{}) { typeOf := reflect.TypeOf(dest) - db.migrateCommon(tableName, typeOf) + ex.migrateCommon(tableName, typeOf) } -func (db *Executor) migrateCommon(tableName string, typeOf reflect.Type) error { - tableFromCode := db.getTableFromCode(tableName) - columnsFromCode := db.getColumnsFromCode(typeOf) - indexsFromCode := db.getIndexsFromCode(typeOf, tableFromCode) - - //获取数据库名称 - var dbName string - err := db.RawSql("SELECT DATABASE()").Value("DATABASE()", &dbName) - if err != nil { - fmt.Println(err.Error()) - return err +func (ex *Executor) migrateCommon(tableName string, typeOf reflect.Type) { + if ex.driverName == "mysql" { + cr := migrate_mysql.MigrateExecutor{} + cr.SetEx(ex).MigrateCommon(tableName, typeOf) } - //查询表信息,如果找不到就新建 - sql := "SELECT TABLE_NAME,ENGINE,TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA =" + "'" + dbName + "' AND TABLE_NAME =" + "'" + tableName + "'" - var dataList []Table - db.RawSql(sql).GetMany(&dataList) - for i := 0; i < len(dataList); i++ { - dataList[i].TableComment = StringFrom("'" + dataList[i].TableComment.String + "'") - } - - if len(dataList) != 0 { - tableFromDb := dataList[0] - columnsFromDb := db.getColumnsFromDb(dbName, tableName) - indexsFromDb := db.getIndexsFromDb(tableName) - - db.modifyTable(tableFromCode, columnsFromCode, indexsFromCode, tableFromDb, columnsFromDb, indexsFromDb) - } else { - db.createTable(tableFromCode, columnsFromCode, indexsFromCode) - } - - return nil -} - -func (db *Executor) getTableFromCode(tableName string) Table { - var tableFromCode Table - tableFromCode.TableName = StringFrom(tableName) - tableFromCode.Engine = StringFrom(db.getValFromOpinion("ENGINE", "MyISAM")) - tableFromCode.TableComment = StringFrom(db.getValFromOpinion("COMMENT", "")) - - return tableFromCode -} - -func (db *Executor) getColumnsFromCode(typeOf reflect.Type) []Column { - var columnsFromCode []Column - for i := 0; i < typeOf.Elem().NumField(); i++ { - fieldName := UnderLine(typeOf.Elem().Field(i).Name) - fieldType := typeOf.Elem().Field(i).Type.Name() - fieldMap := getTagMap(typeOf.Elem().Field(i).Tag.Get("aorm")) - columnsFromCode = append(columnsFromCode, getColumnFromCode(fieldName, fieldType, fieldMap)) - } - - return columnsFromCode -} - -func (db *Executor) getIndexsFromCode(typeOf reflect.Type, tableFromCode Table) []Index { - var indexsFromCode []Index - for i := 0; i < typeOf.Elem().NumField(); i++ { - fieldName := UnderLine(typeOf.Elem().Field(i).Name) - fieldMap := getTagMap(typeOf.Elem().Field(i).Tag.Get("aorm")) - - _, primaryIs := fieldMap["primary"] - if primaryIs { - indexsFromCode = append(indexsFromCode, Index{ - NonUnique: 0, - ColumnName: fieldName, - KeyName: "PRIMARY", - }) - } - - _, uniqueIndexIs := fieldMap["unique"] - if uniqueIndexIs { - indexsFromCode = append(indexsFromCode, Index{ - NonUnique: 0, - ColumnName: fieldName, - KeyName: "idx_" + tableFromCode.TableName.String + "_" + fieldName, - }) - } - - _, indexIs := fieldMap["index"] - if indexIs { - indexsFromCode = append(indexsFromCode, Index{ - NonUnique: 1, - ColumnName: fieldName, - KeyName: "idx_" + tableFromCode.TableName.String + "_" + fieldName, - }) - } - } - - return indexsFromCode -} - -func (db *Executor) getColumnsFromDb(dbName string, tableName string) []Column { - var columnsFromDb []Column - - sqlColumn := "SELECT COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH as Max_Length,COLUMN_DEFAULT,COLUMN_COMMENT,EXTRA,IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA =" + "'" + dbName + "' AND TABLE_NAME =" + "'" + tableName + "'" - db.RawSql(sqlColumn).GetMany(&columnsFromDb) - - for j := 0; j < len(columnsFromDb); j++ { - if columnsFromDb[j].DataType.String == "text" && columnsFromDb[j].MaxLength.Int64 == 65535 { - columnsFromDb[j].MaxLength = IntFrom(0) - } - } - - return columnsFromDb -} - -func (db *Executor) getIndexsFromDb(tableName string) []Index { - sqlIndex := "SHOW INDEXES FROM " + tableName - - var indexsFromDb []Index - db.RawSql(sqlIndex).GetMany(&indexsFromDb) - - return indexsFromDb -} - -// 修改表 -func (db *Executor) modifyTable(tableFromCode Table, columnsFromCode []Column, indexsFromCode []Index, tableFromDb Table, columnsFromDb []Column, indexsFromDb []Index) { - if tableFromCode.Engine != tableFromDb.Engine { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " Engine " + tableFromCode.Engine.String - _, err := db.Exec(sql) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("修改表:" + sql) - } - } - - if tableFromCode.TableComment != tableFromDb.TableComment { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " Comment " + tableFromCode.TableComment.String - _, err := db.Exec(sql) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("修改表:" + sql) - } - } - - for i := 0; i < len(columnsFromCode); i++ { - isFind := 0 - columnCode := columnsFromCode[i] - - for j := 0; j < len(columnsFromDb); j++ { - columnDb := columnsFromDb[j] - if columnCode.ColumnName == columnDb.ColumnName { - isFind = 1 - if columnCode.DataType.String != columnDb.DataType.String || - columnCode.MaxLength.Int64 != columnDb.MaxLength.Int64 || - columnCode.ColumnComment.String != columnDb.ColumnComment.String || - columnCode.Extra.String != columnDb.Extra.String || - columnCode.ColumnDefault.String != columnDb.ColumnDefault.String { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " MODIFY " + getColumnStr(columnCode) - _, err := db.Exec(sql) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("修改属性:" + sql) - } - } - } - } - - if isFind == 0 { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getColumnStr(columnCode) - _, err := db.Exec(sql) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("增加属性:" + sql) - } - } - } - - for i := 0; i < len(indexsFromCode); i++ { - isFind := 0 - indexCode := indexsFromCode[i] - - for j := 0; j < len(indexsFromDb); j++ { - indexDb := indexsFromDb[j] - if indexCode.ColumnName == indexDb.ColumnName { - isFind = 1 - if indexCode.KeyName != indexDb.KeyName || indexCode.NonUnique != indexDb.NonUnique { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " MODIFY " + getIndexStr(indexCode) - _, err := db.Exec(sql) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("修改索引:" + sql) - } - } - } - } - - if isFind == 0 { - sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getIndexStr(indexCode) - _, err := db.Exec(sql) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("增加索引:" + sql) - } - } + if ex.driverName == "sqlite3" { + //cr := migrate_sqlite3.MigrateExecutor{ + // Ex: ex, + //} + //cr.MigrateCommon(tableName, typeOf) } } -// 创建表 -func (db *Executor) createTable(tableFromCode Table, columnsFromCode []Column, indexsFromCode []Index) { - var fieldArr []string - - for i := 0; i < len(columnsFromCode); i++ { - column := columnsFromCode[i] - fieldArr = append(fieldArr, getColumnStr(column)) - } - - for i := 0; i < len(indexsFromCode); i++ { - index := indexsFromCode[i] - fieldArr = append(fieldArr, getIndexStr(index)) - } - - sqlStr := "CREATE TABLE `" + tableFromCode.TableName.String + "` (\n" + strings.Join(fieldArr, ",\n") + "\n) " + getTableInfoFromCode(tableFromCode) + ";" - _, err := db.Exec(sqlStr) - if err != nil { - fmt.Println(err) - } else { - fmt.Println("创建表:" + tableFromCode.TableName.String) - } +func (ex *Executor) GetOpinionList() []OpinionItem { + return ex.opinionList } // -func (db *Executor) getValFromOpinion(key string, def string) string { - for i := 0; i < len(db.opinionList); i++ { - opinionItem := db.opinionList[i] - if opinionItem.Key == key { - def = opinionItem.Val - } - } - return def -} - -func getTableInfoFromCode(tableFromCode Table) string { - return " ENGINE " + tableFromCode.Engine.String + " COMMENT " + tableFromCode.TableComment.String -} - -// 获得某列的结构 -func getColumnFromCode(fieldName string, fieldType string, fieldMap map[string]string) Column { - var column Column - //字段名 - column.ColumnName = StringFrom(fieldName) - //字段数据类型 - column.DataType = StringFrom(getDataType(fieldType, fieldMap)) - //字段数据长度 - column.MaxLength = IntFrom(int64(getMaxLength(column.DataType.String, fieldMap))) - //字段是否可以为空 - column.IsNullable = StringFrom(getNullAble(fieldMap)) - //字段注释 - column.ColumnComment = StringFrom(getComment(fieldMap)) - //扩展信息 - column.Extra = StringFrom(getExtra(fieldMap)) - //默认信息 - column.ColumnDefault = StringFrom(getDefaultVal(fieldMap)) - - return column -} - -// 转换tag成map -func getTagMap(fieldTag string) map[string]string { - var fieldMap = make(map[string]string) - if "" != fieldTag { - tagArr := strings.Split(fieldTag, ";") - for j := 0; j < len(tagArr); j++ { - tagArrArr := strings.Split(tagArr[j], ":") - fieldMap[tagArrArr[0]] = "" - if len(tagArrArr) > 1 { - fieldMap[tagArrArr[0]] = tagArrArr[1] - } - } - } - return fieldMap -} - -func getColumnStr(column Column) string { - var strArr []string - strArr = append(strArr, column.ColumnName.String) - if column.MaxLength.Int64 == 0 { - if column.DataType.String == "varchar" { - strArr = append(strArr, column.DataType.String+"(255)") - } else { - strArr = append(strArr, column.DataType.String) - } - } else { - strArr = append(strArr, column.DataType.String+"("+strconv.Itoa(int(column.MaxLength.Int64))+")") - } - - if column.ColumnDefault.String != "" { - strArr = append(strArr, "DEFAULT '"+column.ColumnDefault.String+"'") - } - - if column.IsNullable.String == "NO" { - strArr = append(strArr, "NOT NULL") - } - - if column.ColumnComment.String != "" { - strArr = append(strArr, "COMMENT '"+column.ColumnComment.String+"'") - } - - if column.Extra.String != "" { - strArr = append(strArr, column.Extra.String) - } - - return strings.Join(strArr, " ") -} - -func getIndexStr(index Index) string { - var strArr []string - - if "PRIMARY" == index.KeyName { - strArr = append(strArr, index.KeyName) - strArr = append(strArr, "KEY") - strArr = append(strArr, "(`"+index.ColumnName+"`)") - } else { - if 0 == index.NonUnique { - strArr = append(strArr, "Unique") - strArr = append(strArr, index.KeyName) - strArr = append(strArr, "(`"+index.ColumnName+"`)") - } else { - strArr = append(strArr, "Index") - strArr = append(strArr, index.KeyName) - strArr = append(strArr, "(`"+index.ColumnName+"`)") - } - } - - return strings.Join(strArr, " ") -} - -//将对象属性类型转换数据库字段数据类型 -func getDataType(fieldType string, fieldMap map[string]string) string { - var DataType string - - dataTypeVal, dataTypeOk := fieldMap["type"] - if dataTypeOk { - DataType = dataTypeVal - } else { - if "Int" == fieldType { - DataType = "int" - } - if "String" == fieldType { - DataType = "varchar" - } - if "Bool" == fieldType { - DataType = "tinyint" - } - if "Time" == fieldType { - DataType = "datetime" - } - if "Float" == fieldType { - DataType = "float" - } - } - - return DataType -} - -func getMaxLength(DataType string, fieldMap map[string]string) int { - var MaxLength int - - maxLengthVal, maxLengthOk := fieldMap["size"] - if maxLengthOk { - num, _ := strconv.Atoi(maxLengthVal) - MaxLength = num - } else { - MaxLength = 0 - if "varchar" == DataType { - MaxLength = 255 - } - } - - return MaxLength -} - -func getNullAble(fieldMap map[string]string) string { - var IsNullable string - - _, primaryOk := fieldMap["primary"] - if primaryOk { - IsNullable = "NO" - } else { - _, ok := fieldMap["not null"] - if ok { - IsNullable = "NO" - } else { - IsNullable = "YES" - } - } - - return IsNullable -} - -func getComment(fieldMap map[string]string) string { - commentVal, commentIs := fieldMap["comment"] - if commentIs { - return commentVal - } - - return "" -} - -func getExtra(fieldMap map[string]string) string { - _, commentIs := fieldMap["auto_increment"] - if commentIs { - return "auto_increment" - } - - return "" -} - -func getDefaultVal(fieldMap map[string]string) string { - defaultVal, defaultIs := fieldMap["default"] - if defaultIs { - return defaultVal - } - - return "" -} +//func (ex *Executor) getTableFromCode(tableName string) Table { +// var tableFromCode Table +// tableFromCode.TableName = StringFrom(tableName) +// tableFromCode.Engine = StringFrom(ex.getValFromOpinion("ENGINE", "MyISAM")) +// tableFromCode.TableComment = StringFrom(ex.getValFromOpinion("COMMENT", "")) +// +// return tableFromCode +//} +// +//func (ex *Executor) getColumnsFromCode(typeOf reflect.Type) []Column { +// var columnsFromCode []Column +// for i := 0; i < typeOf.Elem().NumField(); i++ { +// fieldName := UnderLine(typeOf.Elem().Field(i).Name) +// fieldType := typeOf.Elem().Field(i).Type.Name() +// fieldMap := getTagMap(typeOf.Elem().Field(i).Tag.Get("aorm")) +// columnsFromCode = append(columnsFromCode, getColumnFromCode(fieldName, fieldType, fieldMap)) +// } +// +// return columnsFromCode +//} +// +//func (ex *Executor) getIndexsFromCode(typeOf reflect.Type, tableFromCode Table) []Index { +// var indexsFromCode []Index +// for i := 0; i < typeOf.Elem().NumField(); i++ { +// fieldName := UnderLine(typeOf.Elem().Field(i).Name) +// fieldMap := getTagMap(typeOf.Elem().Field(i).Tag.Get("aorm")) +// +// _, primaryIs := fieldMap["primary"] +// if primaryIs { +// indexsFromCode = append(indexsFromCode, Index{ +// NonUnique: 0, +// ColumnName: fieldName, +// KeyName: "PRIMARY", +// }) +// } +// +// _, uniqueIndexIs := fieldMap["unique"] +// if uniqueIndexIs { +// indexsFromCode = append(indexsFromCode, Index{ +// NonUnique: 0, +// ColumnName: fieldName, +// KeyName: "idx_" + tableFromCode.TableName.String + "_" + fieldName, +// }) +// } +// +// _, indexIs := fieldMap["index"] +// if indexIs { +// indexsFromCode = append(indexsFromCode, Index{ +// NonUnique: 1, +// ColumnName: fieldName, +// KeyName: "idx_" + tableFromCode.TableName.String + "_" + fieldName, +// }) +// } +// } +// +// return indexsFromCode +//} +// +//func (ex *Executor) getColumnsFromDb(dbName string, tableName string) []Column { +// var columnsFromDb []Column +// +// sqlColumn := "SELECT COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH as Max_Length,COLUMN_DEFAULT,COLUMN_COMMENT,EXTRA,IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA =" + "'" + dbName + "' AND TABLE_NAME =" + "'" + tableName + "'" +// ex.RawSql(sqlColumn).GetMany(&columnsFromDb) +// +// for j := 0; j < len(columnsFromDb); j++ { +// if columnsFromDb[j].DataType.String == "text" && columnsFromDb[j].MaxLength.Int64 == 65535 { +// columnsFromDb[j].MaxLength = IntFrom(0) +// } +// } +// +// return columnsFromDb +//} +// +//func (ex *Executor) getIndexsFromDb(tableName string) []Index { +// sqlIndex := "SHOW INDEXES FROM " + tableName +// +// var indexsFromDb []Index +// ex.RawSql(sqlIndex).GetMany(&indexsFromDb) +// +// return indexsFromDb +//} +// +//// 修改表 +//func (ex *Executor) modifyTable(tableFromCode Table, columnsFromCode []Column, indexsFromCode []Index, tableFromDb Table, columnsFromDb []Column, indexsFromDb []Index) { +// if tableFromCode.Engine != tableFromDb.Engine { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " Engine " + tableFromCode.Engine.String +// _, err := ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("修改表:" + sql) +// } +// } +// +// if tableFromCode.TableComment != tableFromDb.TableComment { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " Comment " + tableFromCode.TableComment.String +// _, err := ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("修改表:" + sql) +// } +// } +// +// for i := 0; i < len(columnsFromCode); i++ { +// isFind := 0 +// columnCode := columnsFromCode[i] +// +// for j := 0; j < len(columnsFromDb); j++ { +// columnDb := columnsFromDb[j] +// if columnCode.ColumnName == columnDb.ColumnName { +// isFind = 1 +// if columnCode.DataType.String != columnDb.DataType.String || +// columnCode.MaxLength.Int64 != columnDb.MaxLength.Int64 || +// columnCode.ColumnComment.String != columnDb.ColumnComment.String || +// columnCode.Extra.String != columnDb.Extra.String || +// columnCode.ColumnDefault.String != columnDb.ColumnDefault.String { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " MODIFY " + getColumnStr(columnCode) +// _, err := ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("修改属性:" + sql) +// } +// } +// } +// } +// +// if isFind == 0 { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getColumnStr(columnCode) +// _, err := ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("增加属性:" + sql) +// } +// } +// } +// +// for i := 0; i < len(indexsFromCode); i++ { +// isFind := 0 +// indexCode := indexsFromCode[i] +// +// for j := 0; j < len(indexsFromDb); j++ { +// indexDb := indexsFromDb[j] +// if indexCode.ColumnName == indexDb.ColumnName { +// isFind = 1 +// if indexCode.KeyName != indexDb.KeyName || indexCode.NonUnique != indexDb.NonUnique { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " MODIFY " + getIndexStr(indexCode) +// _, err := ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("修改索引:" + sql) +// } +// } +// } +// } +// +// if isFind == 0 { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getIndexStr(indexCode) +// _, err := ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("增加索引:" + sql) +// } +// } +// } +//} +// +//// 创建表 +//func (ex *Executor) createTable(tableFromCode Table, columnsFromCode []Column, indexsFromCode []Index) { +// var fieldArr []string +// +// for i := 0; i < len(columnsFromCode); i++ { +// column := columnsFromCode[i] +// fieldArr = append(fieldArr, getColumnStr(column)) +// } +// +// for i := 0; i < len(indexsFromCode); i++ { +// index := indexsFromCode[i] +// fieldArr = append(fieldArr, getIndexStr(index)) +// } +// +// sqlStr := "CREATE TABLE `" + tableFromCode.TableName.String + "` (\n" + strings.Join(fieldArr, ",\n") + "\n) " + getTableInfoFromCode(tableFromCode) + ";" +// _, err := ex.Exec(sqlStr) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("创建表:" + tableFromCode.TableName.String) +// } +//} +// +//// +//func (ex *Executor) getValFromOpinion(key string, def string) string { +// for i := 0; i < len(ex.opinionList); i++ { +// opinionItem := ex.opinionList[i] +// if opinionItem.Key == key { +// def = opinionItem.Val +// } +// } +// return def +//} +// +//func getTableInfoFromCode(tableFromCode Table) string { +// return " ENGINE " + tableFromCode.Engine.String + " COMMENT " + tableFromCode.TableComment.String +//} +// +//// 获得某列的结构 +//func getColumnFromCode(fieldName string, fieldType string, fieldMap map[string]string) Column { +// var column Column +// //字段名 +// column.ColumnName = StringFrom(fieldName) +// //字段数据类型 +// column.DataType = StringFrom(getDataType(fieldType, fieldMap)) +// //字段数据长度 +// column.MaxLength = IntFrom(int64(getMaxLength(column.DataType.String, fieldMap))) +// //字段是否可以为空 +// column.IsNullable = StringFrom(getNullAble(fieldMap)) +// //字段注释 +// column.ColumnComment = StringFrom(getComment(fieldMap)) +// //扩展信息 +// column.Extra = StringFrom(getExtra(fieldMap)) +// //默认信息 +// column.ColumnDefault = StringFrom(getDefaultVal(fieldMap)) +// +// return column +//} +// +//// 转换tag成map +//func getTagMap(fieldTag string) map[string]string { +// var fieldMap = make(map[string]string) +// if "" != fieldTag { +// tagArr := strings.Split(fieldTag, ";") +// for j := 0; j < len(tagArr); j++ { +// tagArrArr := strings.Split(tagArr[j], ":") +// fieldMap[tagArrArr[0]] = "" +// if len(tagArrArr) > 1 { +// fieldMap[tagArrArr[0]] = tagArrArr[1] +// } +// } +// } +// return fieldMap +//} +// +//func getColumnStr(column Column) string { +// var strArr []string +// strArr = append(strArr, column.ColumnName.String) +// if column.MaxLength.Int64 == 0 { +// if column.DataType.String == "varchar" { +// strArr = append(strArr, column.DataType.String+"(255)") +// } else { +// strArr = append(strArr, column.DataType.String) +// } +// } else { +// strArr = append(strArr, column.DataType.String+"("+strconv.Itoa(int(column.MaxLength.Int64))+")") +// } +// +// if column.ColumnDefault.String != "" { +// strArr = append(strArr, "DEFAULT '"+column.ColumnDefault.String+"'") +// } +// +// if column.IsNullable.String == "NO" { +// strArr = append(strArr, "NOT NULL") +// } +// +// if column.ColumnComment.String != "" { +// strArr = append(strArr, "COMMENT '"+column.ColumnComment.String+"'") +// } +// +// if column.Extra.String != "" { +// strArr = append(strArr, column.Extra.String) +// } +// +// return strings.Join(strArr, " ") +//} +// +//func getIndexStr(index Index) string { +// var strArr []string +// +// if "PRIMARY" == index.KeyName { +// strArr = append(strArr, index.KeyName) +// strArr = append(strArr, "KEY") +// strArr = append(strArr, "(`"+index.ColumnName+"`)") +// } else { +// if 0 == index.NonUnique { +// strArr = append(strArr, "Unique") +// strArr = append(strArr, index.KeyName) +// strArr = append(strArr, "(`"+index.ColumnName+"`)") +// } else { +// strArr = append(strArr, "Index") +// strArr = append(strArr, index.KeyName) +// strArr = append(strArr, "(`"+index.ColumnName+"`)") +// } +// } +// +// return strings.Join(strArr, " ") +//} +// +////将对象属性类型转换数据库字段数据类型 +//func getDataType(fieldType string, fieldMap map[string]string) string { +// var DataType string +// +// dataTypeVal, dataTypeOk := fieldMap["type"] +// if dataTypeOk { +// DataType = dataTypeVal +// } else { +// if "Int" == fieldType { +// DataType = "int" +// } +// if "String" == fieldType { +// DataType = "varchar" +// } +// if "Bool" == fieldType { +// DataType = "tinyint" +// } +// if "Time" == fieldType { +// DataType = "datetime" +// } +// if "Float" == fieldType { +// DataType = "float" +// } +// } +// +// return DataType +//} +// +//func getMaxLength(DataType string, fieldMap map[string]string) int { +// var MaxLength int +// +// maxLengthVal, maxLengthOk := fieldMap["size"] +// if maxLengthOk { +// num, _ := strconv.Atoi(maxLengthVal) +// MaxLength = num +// } else { +// MaxLength = 0 +// if "varchar" == DataType { +// MaxLength = 255 +// } +// } +// +// return MaxLength +//} +// +//func getNullAble(fieldMap map[string]string) string { +// var IsNullable string +// +// _, primaryOk := fieldMap["primary"] +// if primaryOk { +// IsNullable = "NO" +// } else { +// _, ok := fieldMap["not null"] +// if ok { +// IsNullable = "NO" +// } else { +// IsNullable = "YES" +// } +// } +// +// return IsNullable +//} +// +//func getComment(fieldMap map[string]string) string { +// commentVal, commentIs := fieldMap["comment"] +// if commentIs { +// return commentVal +// } +// +// return "" +//} +// +//func getExtra(fieldMap map[string]string) string { +// _, commentIs := fieldMap["auto_increment"] +// if commentIs { +// return "auto_increment" +// } +// +// return "" +//} +// +//func getDefaultVal(fieldMap map[string]string) string { +// defaultVal, defaultIs := fieldMap["default"] +// if defaultIs { +// return defaultVal +// } +// +// return "" +//} diff --git a/migrate_mysql/migrate.go b/migrate_mysql/migrate.go new file mode 100644 index 0000000..3d505f9 --- /dev/null +++ b/migrate_mysql/migrate.go @@ -0,0 +1,472 @@ +package migrate_mysql + +import ( + "github.com/tangpanqing/aorm/executor" + "github.com/tangpanqing/aorm/null" + "reflect" +) + +type Table struct { + TableName null.String + Engine null.String + TableComment null.String +} + +type Column struct { + ColumnName null.String + ColumnDefault null.String + IsNullable null.String + DataType null.String //数据类型 varchar,bigint,int + MaxLength null.Int //数据最大长度 20 + ColumnComment null.String + Extra null.String //扩展信息 auto_increment +} + +type Index struct { + NonUnique null.Int + ColumnName null.String + KeyName null.String +} + +//MigrateExecutor 定义结构 +type MigrateExecutor struct { + ex *executor.Executor +} + +//SetEx 设置ex执行者 +func (mm *MigrateExecutor) SetEx(ex *executor.Executor) *MigrateExecutor { + mm.ex = ex + return mm +} + +//ShowCreateTable 查看创建表的ddl +//func (mm *MigrateExecutor) ShowCreateTable(tableName string) string { +// var str string +// mm.ex.RawSql("show create table "+tableName).Value("Create Table", &str) +// return str +//} + +//MigrateCommon 迁移的主要过程 +func (mm *MigrateExecutor) MigrateCommon(tableName string, typeOf reflect.Type) error { + //tableFromCode := mm.getTableFromCode(tableName) + //columnsFromCode := mm.getColumnsFromCode(typeOf) + //indexesFromCode := mm.getIndexesFromCode(typeOf, tableFromCode) + // + //dbName, dbErr := mm.getDbName() + //if dbErr != nil { + // return dbErr + //} + // + //tablesFromDb := mm.getTableFromDb(dbName, tableName) + //if len(tablesFromDb) != 0 { + // tableFromDb := tablesFromDb[0] + // columnsFromDb := mm.getColumnsFromDb(dbName, tableName) + // indexsFromDb := mm.getIndexesFromDb(tableName) + // + // mm.modifyTable(tableFromCode, columnsFromCode, indexesFromCode, tableFromDb, columnsFromDb, indexsFromDb) + //} else { + // mm.createTable(tableFromCode, columnsFromCode, indexesFromCode) + //} + + return nil +} + +// +//func (mm *MigrateExecutor) getTableFromCode(tableName string) Table { +// var tableFromCode Table +// tableFromCode.TableName = aorm.StringFrom(tableName) +// tableFromCode.Engine = aorm.StringFrom(mm.getOpinionVal("ENGINE", "MyISAM")) +// tableFromCode.TableComment = aorm.StringFrom(mm.getOpinionVal("COMMENT", "")) +// +// return tableFromCode +//} +// +//func (mm *MigrateExecutor) getColumnsFromCode(typeOf reflect.Type) []Column { +// var columnsFromCode []Column +// for i := 0; i < typeOf.Elem().NumField(); i++ { +// fieldName := aorm.UnderLine(typeOf.Elem().Field(i).Name) +// fieldType := typeOf.Elem().Field(i).Type.Name() +// fieldMap := getTagMap(typeOf.Elem().Field(i).Tag.Get("aorm")) +// columnsFromCode = append(columnsFromCode, Column{ +// ColumnName: aorm.StringFrom(fieldName), +// DataType: aorm.StringFrom(getDataType(fieldType, fieldMap)), +// MaxLength: aorm.IntFrom(int64(getMaxLength(getDataType(fieldType, fieldMap), fieldMap))), +// IsNullable: aorm.StringFrom(getNullAble(fieldMap)), +// ColumnComment: aorm.StringFrom(getComment(fieldMap)), +// Extra: aorm.StringFrom(getExtra(fieldMap)), +// ColumnDefault: aorm.StringFrom(getDefaultVal(fieldMap)), +// }) +// } +// +// return columnsFromCode +//} +// +//func (mm *MigrateExecutor) getIndexesFromCode(typeOf reflect.Type, tableFromCode Table) []Index { +// var indexesFromCode []Index +// for i := 0; i < typeOf.Elem().NumField(); i++ { +// fieldName := aorm.UnderLine(typeOf.Elem().Field(i).Name) +// fieldMap := getTagMap(typeOf.Elem().Field(i).Tag.Get("aorm")) +// +// _, primaryIs := fieldMap["primary"] +// if primaryIs { +// indexesFromCode = append(indexesFromCode, Index{ +// NonUnique: aorm.IntFrom(0), +// ColumnName: aorm.StringFrom(fieldName), +// KeyName: aorm.StringFrom("PRIMARY"), +// }) +// } +// +// _, uniqueIndexIs := fieldMap["unique"] +// if uniqueIndexIs { +// indexesFromCode = append(indexesFromCode, Index{ +// NonUnique: aorm.IntFrom(0), +// ColumnName: aorm.StringFrom(fieldName), +// KeyName: aorm.StringFrom("idx_" + tableFromCode.TableName.String + "_" + fieldName), +// }) +// } +// +// _, indexIs := fieldMap["index"] +// if indexIs { +// indexesFromCode = append(indexesFromCode, Index{ +// NonUnique: aorm.IntFrom(1), +// ColumnName: aorm.StringFrom(fieldName), +// KeyName: aorm.StringFrom("idx_" + tableFromCode.TableName.String + "_" + fieldName), +// }) +// } +// } +// +// return indexesFromCode +//} +// +//func (mm *MigrateExecutor) getDbName() (string, error) { +// //获取数据库名称 +// var dbName string +// err := mm.ex.RawSql("SELECT DATABASE()").Value("DATABASE()", &dbName) +// if err != nil { +// return "", err +// } +// +// return dbName, nil +//} +// +//func (mm *MigrateExecutor) getTableFromDb(dbName string, tableName string) []Table { +// sql := "SELECT TABLE_NAME,ENGINE,TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA =" + "'" + dbName + "' AND TABLE_NAME =" + "'" + tableName + "'" +// var dataList []Table +// mm.ex.RawSql(sql).GetMany(&dataList) +// for i := 0; i < len(dataList); i++ { +// dataList[i].TableComment = aorm.StringFrom("'" + dataList[i].TableComment.String + "'") +// } +// +// return dataList +//} +// +//func (mm *MigrateExecutor) getColumnsFromDb(dbName string, tableName string) []Column { +// var columnsFromDb []Column +// +// sqlColumn := "SELECT COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH as Max_Length,COLUMN_DEFAULT,COLUMN_COMMENT,EXTRA,IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA =" + "'" + dbName + "' AND TABLE_NAME =" + "'" + tableName + "'" +// mm.ex.RawSql(sqlColumn).GetMany(&columnsFromDb) +// +// for j := 0; j < len(columnsFromDb); j++ { +// if columnsFromDb[j].DataType.String == "text" && columnsFromDb[j].MaxLength.Int64 == 65535 { +// columnsFromDb[j].MaxLength = aorm.IntFrom(0) +// } +// } +// +// return columnsFromDb +//} +// +//func (mm *MigrateExecutor) getIndexesFromDb(tableName string) []Index { +// sqlIndex := "SHOW INDEXES FROM " + tableName +// +// var indexsFromDb []Index +// mm.ex.RawSql(sqlIndex).GetMany(&indexsFromDb) +// +// return indexsFromDb +//} +// +//func (mm *MigrateExecutor) modifyTable(tableFromCode Table, columnsFromCode []Column, indexesFromCode []Index, tableFromDb Table, columnsFromDb []Column, indexsFromDb []Index) { +// if tableFromCode.Engine != tableFromDb.Engine { +// mm.modifyTableEngine(tableFromCode) +// } +// +// if tableFromCode.TableComment != tableFromDb.TableComment { +// mm.modifyTableComment(tableFromCode) +// } +// +// for i := 0; i < len(columnsFromCode); i++ { +// isFind := 0 +// columnCode := columnsFromCode[i] +// +// for j := 0; j < len(columnsFromDb); j++ { +// columnDb := columnsFromDb[j] +// if columnCode.ColumnName == columnDb.ColumnName { +// isFind = 1 +// if columnCode.DataType.String != columnDb.DataType.String || +// columnCode.MaxLength.Int64 != columnDb.MaxLength.Int64 || +// columnCode.ColumnComment.String != columnDb.ColumnComment.String || +// columnCode.Extra.String != columnDb.Extra.String || +// columnCode.ColumnDefault.String != columnDb.ColumnDefault.String { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " MODIFY " + getColumnStr(columnCode) +// _, err := mm.ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("修改属性:" + sql) +// } +// } +// } +// } +// +// if isFind == 0 { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getColumnStr(columnCode) +// _, err := mm.ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("增加属性:" + sql) +// } +// } +// } +// +// for i := 0; i < len(indexesFromCode); i++ { +// isFind := 0 +// indexCode := indexesFromCode[i] +// +// for j := 0; j < len(indexsFromDb); j++ { +// indexDb := indexsFromDb[j] +// if indexCode.ColumnName == indexDb.ColumnName { +// isFind = 1 +// if indexCode.KeyName != indexDb.KeyName || indexCode.NonUnique != indexDb.NonUnique { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " MODIFY " + getIndexStr(indexCode) +// _, err := mm.ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("修改索引:" + sql) +// } +// } +// } +// } +// +// if isFind == 0 { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " ADD " + getIndexStr(indexCode) +// _, err := mm.ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("增加索引:" + sql) +// } +// } +// } +//} +// +//func (mm *MigrateExecutor) modifyTableEngine(tableFromCode Table) { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " Engine " + tableFromCode.Engine.String +// _, err := mm.ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("修改表:" + sql) +// } +//} +// +//func (mm *MigrateExecutor) modifyTableComment(tableFromCode Table) { +// sql := "ALTER TABLE " + tableFromCode.TableName.String + " Comment " + tableFromCode.TableComment.String +// _, err := mm.ex.Exec(sql) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("修改表:" + sql) +// } +//} +// +//func (mm *MigrateExecutor) createTable(tableFromCode Table, columnsFromCode []Column, indexesFromCode []Index) { +// var fieldArr []string +// +// for i := 0; i < len(columnsFromCode); i++ { +// column := columnsFromCode[i] +// fieldArr = append(fieldArr, getColumnStr(column)) +// } +// +// for i := 0; i < len(indexesFromCode); i++ { +// index := indexesFromCode[i] +// fieldArr = append(fieldArr, getIndexStr(index)) +// } +// +// sqlStr := "CREATE TABLE `" + tableFromCode.TableName.String + "` (\n" + strings.Join(fieldArr, ",\n") + "\n) " + " ENGINE " + tableFromCode.Engine.String + " COMMENT " + tableFromCode.TableComment.String + ";" +// _, err := mm.ex.Exec(sqlStr) +// if err != nil { +// fmt.Println(err) +// } else { +// fmt.Println("创建表:" + tableFromCode.TableName.String) +// } +//} +// +//func (mm *MigrateExecutor) getOpinionVal(key string, def string) string { +// opinions := mm.ex.GetOpinionList() +// for i := 0; i < len(opinions); i++ { +// opinionItem := opinions[i] +// if opinionItem.Key == key { +// def = opinionItem.Val +// } +// } +// return def +//} +// +//func getTagMap(fieldTag string) map[string]string { +// var fieldMap = make(map[string]string) +// if "" != fieldTag { +// tagArr := strings.Split(fieldTag, ";") +// for j := 0; j < len(tagArr); j++ { +// tagArrArr := strings.Split(tagArr[j], ":") +// fieldMap[tagArrArr[0]] = "" +// if len(tagArrArr) > 1 { +// fieldMap[tagArrArr[0]] = tagArrArr[1] +// } +// } +// } +// return fieldMap +//} +// +//func getColumnStr(column Column) string { +// var strArr []string +// strArr = append(strArr, column.ColumnName.String) +// if column.MaxLength.Int64 == 0 { +// if column.DataType.String == "varchar" { +// strArr = append(strArr, column.DataType.String+"(255)") +// } else { +// strArr = append(strArr, column.DataType.String) +// } +// } else { +// strArr = append(strArr, column.DataType.String+"("+strconv.Itoa(int(column.MaxLength.Int64))+")") +// } +// +// if column.ColumnDefault.String != "" { +// strArr = append(strArr, "DEFAULT '"+column.ColumnDefault.String+"'") +// } +// +// if column.IsNullable.String == "NO" { +// strArr = append(strArr, "NOT NULL") +// } +// +// if column.ColumnComment.String != "" { +// strArr = append(strArr, "COMMENT '"+column.ColumnComment.String+"'") +// } +// +// if column.Extra.String != "" { +// strArr = append(strArr, column.Extra.String) +// } +// +// return strings.Join(strArr, " ") +//} +// +//func getIndexStr(index Index) string { +// var strArr []string +// +// if "PRIMARY" == index.KeyName.String { +// strArr = append(strArr, index.KeyName.String) +// strArr = append(strArr, "KEY") +// strArr = append(strArr, "(`"+index.ColumnName.String+"`)") +// } else { +// if 0 == index.NonUnique.Int64 { +// strArr = append(strArr, "Unique") +// strArr = append(strArr, index.KeyName.String) +// strArr = append(strArr, "(`"+index.ColumnName.String+"`)") +// } else { +// strArr = append(strArr, "Index") +// strArr = append(strArr, index.KeyName.String) +// strArr = append(strArr, "(`"+index.ColumnName.String+"`)") +// } +// } +// +// return strings.Join(strArr, " ") +//} +// +//func getDataType(fieldType string, fieldMap map[string]string) string { +// var DataType string +// +// dataTypeVal, dataTypeOk := fieldMap["type"] +// if dataTypeOk { +// DataType = dataTypeVal +// } else { +// if "Int" == fieldType { +// DataType = "int" +// } +// if "String" == fieldType { +// DataType = "varchar" +// } +// if "Bool" == fieldType { +// DataType = "tinyint" +// } +// if "Time" == fieldType { +// DataType = "datetime" +// } +// if "Float" == fieldType { +// DataType = "float" +// } +// } +// +// return DataType +//} +// +//func getMaxLength(DataType string, fieldMap map[string]string) int { +// var MaxLength int +// +// maxLengthVal, maxLengthOk := fieldMap["size"] +// if maxLengthOk { +// num, _ := strconv.Atoi(maxLengthVal) +// MaxLength = num +// } else { +// MaxLength = 0 +// if "varchar" == DataType { +// MaxLength = 255 +// } +// } +// +// return MaxLength +//} +// +//func getNullAble(fieldMap map[string]string) string { +// var IsNullable string +// +// _, primaryOk := fieldMap["primary"] +// if primaryOk { +// IsNullable = "NO" +// } else { +// _, ok := fieldMap["not null"] +// if ok { +// IsNullable = "NO" +// } else { +// IsNullable = "YES" +// } +// } +// +// return IsNullable +//} +// +//func getComment(fieldMap map[string]string) string { +// commentVal, commentIs := fieldMap["comment"] +// if commentIs { +// return commentVal +// } +// +// return "" +//} +// +//func getExtra(fieldMap map[string]string) string { +// _, commentIs := fieldMap["auto_increment"] +// if commentIs { +// return "auto_increment" +// } +// +// return "" +//} +// +//func getDefaultVal(fieldMap map[string]string) string { +// defaultVal, defaultIs := fieldMap["default"] +// if defaultIs { +// return defaultVal +// } +// +// return "" +//} diff --git a/null.go b/null/null.go similarity index 99% rename from null.go rename to null/null.go index 6c4f749..4ab94e2 100644 --- a/null.go +++ b/null/null.go @@ -1,4 +1,4 @@ -package aorm +package null import ( "bytes" diff --git a/test/aorm_test.go b/test/aorm_test.go index 3f2f53d..c4c4482 100644 --- a/test/aorm_test.go +++ b/test/aorm_test.go @@ -5,100 +5,125 @@ import ( _ "github.com/go-sql-driver/mysql" _ "github.com/mattn/go-sqlite3" "github.com/tangpanqing/aorm" + "github.com/tangpanqing/aorm/executor" + "github.com/tangpanqing/aorm/null" "testing" "time" ) type Article struct { - Id aorm.Int `aorm:"primary;auto_increment;type:bigint" json:"id"` - Type aorm.Int `aorm:"index;comment:类型" json:"type"` - PersonId aorm.Int `aorm:"comment:人员Id" json:"personId"` - ArticleBody aorm.String `aorm:"type:text;comment:文章内容" json:"articleBody"` + Id null.Int `aorm:"primary;auto_increment;type:bigint" json:"id"` + Type null.Int `aorm:"index;comment:类型" json:"type"` + PersonId null.Int `aorm:"comment:人员Id" json:"personId"` + ArticleBody null.String `aorm:"type:text;comment:文章内容" json:"articleBody"` } type ArticleVO struct { - Id aorm.Int `aorm:"primary;auto_increment;type:bigint" json:"id"` - Type aorm.Int `aorm:"index;comment:类型" json:"type"` - PersonId aorm.Int `aorm:"comment:人员Id" json:"personId"` - PersonName aorm.String `aorm:"comment:人员名称" json:"personName"` - ArticleBody aorm.String `aorm:"type:text;comment:文章内容" json:"articleBody"` + Id null.Int `aorm:"primary;auto_increment;type:bigint" json:"id"` + Type null.Int `aorm:"index;comment:类型" json:"type"` + PersonId null.Int `aorm:"comment:人员Id" json:"personId"` + PersonName null.String `aorm:"comment:人员名称" json:"personName"` + ArticleBody null.String `aorm:"type:text;comment:文章内容" json:"articleBody"` } type Person struct { - Id aorm.Int `aorm:"primary;auto_increment" json:"id"` - Name aorm.String `aorm:"size:100;not null;comment:名字" json:"name"` - Sex aorm.Bool `aorm:"index;comment:性别" json:"sex"` - Age aorm.Int `aorm:"index;comment:年龄" json:"age"` - Type aorm.Int `aorm:"index;comment:类型" json:"type"` - CreateTime aorm.Time `aorm:"comment:创建时间" json:"createTime"` - Money aorm.Float `aorm:"comment:金额" json:"money"` - Test aorm.Float `aorm:"type:double;comment:测试" json:"test"` + Id null.Int `aorm:"primary;auto_increment" json:"id"` + Name null.String `aorm:"size:100;not null;comment:名字" json:"name"` + Sex null.Bool `aorm:"index;comment:性别" json:"sex"` + Age null.Int `aorm:"index;comment:年龄" json:"age"` + Type null.Int `aorm:"index;comment:类型" json:"type"` + CreateTime null.Time `aorm:"comment:创建时间" json:"createTime"` + Money null.Float `aorm:"comment:金额" json:"money"` + Test null.Float `aorm:"type:double;comment:测试" json:"test"` } type PersonAge struct { - Age aorm.Int - AgeCount aorm.Int + Age null.Int + AgeCount null.Int } type PersonWithArticleCount struct { - Id aorm.Int `aorm:"primary;auto_increment" json:"id"` - Name aorm.String `aorm:"size:100;not null;comment:名字" json:"name"` - Sex aorm.Bool `aorm:"index;comment:性别" json:"sex"` - Age aorm.Int `aorm:"index;comment:年龄" json:"age"` - Type aorm.Int `aorm:"index;comment:类型" json:"type"` - CreateTime aorm.Time `aorm:"comment:创建时间" json:"createTime"` - Money aorm.Float `aorm:"comment:金额" json:"money"` - Test aorm.Float `aorm:"type:double;comment:测试" json:"test"` - ArticleCount aorm.Int `aorm:"comment:文章数量" json:"articleCount"` + Id null.Int `aorm:"primary;auto_increment" json:"id"` + Name null.String `aorm:"size:100;not null;comment:名字" json:"name"` + Sex null.Bool `aorm:"index;comment:性别" json:"sex"` + Age null.Int `aorm:"index;comment:年龄" json:"age"` + Type null.Int `aorm:"index;comment:类型" json:"type"` + CreateTime null.Time `aorm:"comment:创建时间" json:"createTime"` + Money null.Float `aorm:"comment:金额" json:"money"` + Test null.Float `aorm:"type:double;comment:测试" json:"test"` + ArticleCount null.Int `aorm:"comment:文章数量" json:"articleCount"` } func TestAll(t *testing.T) { - name := "mysql" - db := testMysqlConnect() + sqlite3Content, sqlite3Err := aorm.Open("sqlite3", "test.db") + if sqlite3Err != nil { + panic(sqlite3Err) + } - testMigrate(name, db) + //username := "root" + //password := "root" + //hostname := "localhost" + //port := "3306" + //dbname := "database_name" + // + //mysqlContent, mysqlErr := aorm.Open("mysql", username+":"+password+"@tcp("+hostname+":"+port+")/"+dbname+"?charset=utf8mb4&parseTime=True&loc=Local") + //if mysqlErr != nil { + // panic(mysqlErr) + //} - testShowCreateTable(name, db) + dbList := make([]aorm.DbContent, 0) + dbList = append(dbList, sqlite3Content) + //dbList = append(dbList, mysqlContent) - id := testInsert(name, db) - testInsertBatch(name, db) + for i := 0; i < len(dbList); i++ { + dbItem := dbList[i] - testGetOne(name, db, id) - testGetMany(name, db) - testUpdate(name, db, id) - testDelete(name, db, id) + testMigrate(dbItem.DriverName, dbItem.DbLink) + break - id2 := testInsert(name, db) - testTable(name, db) - testSelect(name, db) - testSelectWithSub(name, db) - testWhereWithSub(name, db) - testWhere(name, db) - testJoin(name, db) - testGroupBy(name, db) - testHaving(name, db) - testOrderBy(name, db) - testLimit(name, db) - testLock(name, db, id2) + testShowCreateTable(dbItem.DriverName, dbItem.DbLink) - testIncrement(name, db, id2) - testDecrement(name, db, id2) + id := testInsert(dbItem.DriverName, dbItem.DbLink) + testInsertBatch(dbItem.DriverName, dbItem.DbLink) - testValue(name, db, id2) + testGetOne(dbItem.DriverName, dbItem.DbLink, id) + testGetMany(dbItem.DriverName, dbItem.DbLink) + testUpdate(dbItem.DriverName, dbItem.DbLink, id) + testDelete(dbItem.DriverName, dbItem.DbLink, id) - testPluck(name, db) + id2 := testInsert(dbItem.DriverName, dbItem.DbLink) + testTable(dbItem.DriverName, dbItem.DbLink) + testSelect(dbItem.DriverName, dbItem.DbLink) + testSelectWithSub(dbItem.DriverName, dbItem.DbLink) + testWhereWithSub(dbItem.DriverName, dbItem.DbLink) + testWhere(dbItem.DriverName, dbItem.DbLink) + testJoin(dbItem.DriverName, dbItem.DbLink) + testGroupBy(dbItem.DriverName, dbItem.DbLink) + testHaving(dbItem.DriverName, dbItem.DbLink) + testOrderBy(dbItem.DriverName, dbItem.DbLink) + testLimit(dbItem.DriverName, dbItem.DbLink) + testLock(dbItem.DriverName, dbItem.DbLink, id2) - testCount(name, db) - testSum(name, db) - testAvg(name, db) - testMin(name, db) - testMax(name, db) + testIncrement(dbItem.DriverName, dbItem.DbLink, id2) + testDecrement(dbItem.DriverName, dbItem.DbLink, id2) - testExec(name, db) + testValue(dbItem.DriverName, dbItem.DbLink, id2) + + testPluck(dbItem.DriverName, dbItem.DbLink) + + testCount(dbItem.DriverName, dbItem.DbLink) + testSum(dbItem.DriverName, dbItem.DbLink) + testAvg(dbItem.DriverName, dbItem.DbLink) + testMin(dbItem.DriverName, dbItem.DbLink) + testMax(dbItem.DriverName, dbItem.DbLink) + + testExec(dbItem.DriverName, dbItem.DbLink) + + testTransaction(dbItem.DriverName, dbItem.DbLink) + testTruncate(dbItem.DriverName, dbItem.DbLink) + testHelper(dbItem.DriverName, dbItem.DbLink) + } - testTransaction(name, db) - testTruncate(name, db) - testHelper(name, db) // //for _, db := range dbMap { // db.Close() @@ -131,36 +156,36 @@ func testMysqlConnect() *sql.DB { func testMigrate(name string, db *sql.DB) { //AutoMigrate - aorm.Use(db).Opinion("ENGINE", "InnoDB").Opinion("COMMENT", "人员表").AutoMigrate(&Person{}) - aorm.Use(db).Opinion("ENGINE", "InnoDB").Opinion("COMMENT", "文章").AutoMigrate(&Article{}) + aorm.Use(db).Driver(name).Opinion("ENGINE", "InnoDB").Opinion("COMMENT", "人员表").AutoMigrate(&Person{}) + aorm.Use(db).Driver(name).Opinion("ENGINE", "InnoDB").Opinion("COMMENT", "文章").AutoMigrate(&Article{}) //Migrate - aorm.Use(db).Opinion("ENGINE", "InnoDB").Opinion("COMMENT", "人员表").Migrate("person_1", &Person{}) + aorm.Use(db).Driver(name).Opinion("ENGINE", "InnoDB").Opinion("COMMENT", "人员表").Migrate("person_1", &Person{}) } func testShowCreateTable(name string, db *sql.DB) { - aorm.Use(db).ShowCreateTable("person") + aorm.Use(db).Driver(name).ShowCreateTable("person") } func testInsert(name string, db *sql.DB) int64 { id, errInsert := aorm.Use(db).Debug(false).Insert(&Person{ - Name: aorm.StringFrom("Alice"), - Sex: aorm.BoolFrom(false), - Age: aorm.IntFrom(18), - Type: aorm.IntFrom(0), - CreateTime: aorm.TimeFrom(time.Now()), - Money: aorm.FloatFrom(100.15987654321), - Test: aorm.FloatFrom(200.15987654321987654321), + Name: null.StringFrom("Alice"), + Sex: null.BoolFrom(false), + Age: null.IntFrom(18), + Type: null.IntFrom(0), + CreateTime: null.TimeFrom(time.Now()), + Money: null.FloatFrom(100.15987654321), + Test: null.FloatFrom(200.15987654321987654321), }) if errInsert != nil { panic(name + "testInsert" + "found err") } aorm.Use(db).Debug(false).Insert(&Article{ - Type: aorm.IntFrom(0), - PersonId: aorm.IntFrom(id), - ArticleBody: aorm.StringFrom("文章内容"), + Type: null.IntFrom(0), + PersonId: null.IntFrom(id), + ArticleBody: null.StringFrom("文章内容"), }) return id @@ -169,23 +194,23 @@ func testInsert(name string, db *sql.DB) int64 { func testInsertBatch(name string, db *sql.DB) int64 { var batch []Person batch = append(batch, Person{ - Name: aorm.StringFrom("Alice"), - Sex: aorm.BoolFrom(false), - Age: aorm.IntFrom(18), - Type: aorm.IntFrom(0), - CreateTime: aorm.TimeFrom(time.Now()), - Money: aorm.FloatFrom(100.15987654321), - Test: aorm.FloatFrom(200.15987654321987654321), + Name: null.StringFrom("Alice"), + Sex: null.BoolFrom(false), + Age: null.IntFrom(18), + Type: null.IntFrom(0), + CreateTime: null.TimeFrom(time.Now()), + Money: null.FloatFrom(100.15987654321), + Test: null.FloatFrom(200.15987654321987654321), }) batch = append(batch, Person{ - Name: aorm.StringFrom("Bob"), - Sex: aorm.BoolFrom(true), - Age: aorm.IntFrom(18), - Type: aorm.IntFrom(0), - CreateTime: aorm.TimeFrom(time.Now()), - Money: aorm.FloatFrom(100.15987654321), - Test: aorm.FloatFrom(200.15987654321987654321), + Name: null.StringFrom("Bob"), + Sex: null.BoolFrom(true), + Age: null.IntFrom(18), + Type: null.IntFrom(0), + CreateTime: null.TimeFrom(time.Now()), + Money: null.FloatFrom(100.15987654321), + Test: null.FloatFrom(200.15987654321987654321), }) count, err := aorm.Use(db).Debug(false).InsertBatch(&batch) @@ -198,7 +223,7 @@ func testInsertBatch(name string, db *sql.DB) int64 { func testGetOne(name string, db *sql.DB, id int64) { var person Person - errFind := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).GetOne(&person) + errFind := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).GetOne(&person) if errFind != nil { panic(name + "testGetOne" + "found err") } @@ -206,28 +231,28 @@ func testGetOne(name string, db *sql.DB, id int64) { func testGetMany(name string, db *sql.DB) { var list []Person - errSelect := aorm.Use(db).Debug(false).Where(&Person{Type: aorm.IntFrom(0)}).GetMany(&list) + errSelect := aorm.Use(db).Debug(false).Where(&Person{Type: null.IntFrom(0)}).GetMany(&list) if errSelect != nil { panic(name + " testGetMany " + "found err:" + errSelect.Error()) } } func testUpdate(name string, db *sql.DB, id int64) { - _, errUpdate := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).Update(&Person{Name: aorm.StringFrom("Bob")}) + _, errUpdate := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).Update(&Person{Name: null.StringFrom("Bob")}) if errUpdate != nil { panic(name + "testGetMany" + "found err") } } func testDelete(name string, db *sql.DB, id int64) { - _, errDelete := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).Delete() + _, errDelete := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).Delete() if errDelete != nil { panic(name + "testDelete" + "found err") } } func testTable(name string, db *sql.DB) { - _, err := aorm.Use(db).Debug(false).Table("person_1").Insert(&Person{Name: aorm.StringFrom("Cherry")}) + _, err := aorm.Use(db).Debug(false).Table("person_1").Insert(&Person{Name: null.StringFrom("Cherry")}) if err != nil { panic(name + "testTable" + "found err") } @@ -235,7 +260,7 @@ func testTable(name string, db *sql.DB) { func testSelect(name string, db *sql.DB) { var listByFiled []Person - err := aorm.Use(db).Debug(false).Select("name,age").Where(&Person{Age: aorm.IntFrom(18)}).GetMany(&listByFiled) + err := aorm.Use(db).Debug(false).Select("name,age").Where(&Person{Age: null.IntFrom(18)}).GetMany(&listByFiled) if err != nil { panic(name + " testSelect " + "found err:" + err.Error()) } @@ -248,7 +273,7 @@ func testSelectWithSub(name string, db *sql.DB) { err := aorm.Use(db).Debug(false). SelectExp(&sub, "article_count"). Select("*"). - Where(&Person{Age: aorm.IntFrom(18)}). + Where(&Person{Age: null.IntFrom(18)}). GetMany(&listByFiled) if err != nil { @@ -274,12 +299,12 @@ func testWhereWithSub(name string, db *sql.DB) { func testWhere(name string, db *sql.DB) { var listByWhere []Person - var where1 []aorm.WhereItem - where1 = append(where1, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0}) - where1 = append(where1, aorm.WhereItem{Field: "age", Opt: aorm.In, Val: []int{18, 20}}) - where1 = append(where1, aorm.WhereItem{Field: "money", Opt: aorm.Between, Val: []float64{100.1, 200.9}}) - where1 = append(where1, aorm.WhereItem{Field: "money", Opt: aorm.Eq, Val: 100.15}) - where1 = append(where1, aorm.WhereItem{Field: "name", Opt: aorm.Like, Val: []string{"%", "li", "%"}}) + var where1 []executor.WhereItem + where1 = append(where1, executor.WhereItem{Field: "type", Opt: executor.Eq, Val: 0}) + where1 = append(where1, executor.WhereItem{Field: "age", Opt: executor.In, Val: []int{18, 20}}) + where1 = append(where1, executor.WhereItem{Field: "money", Opt: executor.Between, Val: []float64{100.1, 200.9}}) + where1 = append(where1, executor.WhereItem{Field: "money", Opt: executor.Eq, Val: 100.15}) + where1 = append(where1, executor.WhereItem{Field: "name", Opt: executor.Like, Val: []string{"%", "li", "%"}}) err := aorm.Use(db).Debug(false).Table("person").WhereArr(where1).GetMany(&listByWhere) if err != nil { @@ -289,9 +314,9 @@ func testWhere(name string, db *sql.DB) { func testJoin(name string, db *sql.DB) { var list2 []ArticleVO - var where2 []aorm.WhereItem - where2 = append(where2, aorm.WhereItem{Field: "o.type", Opt: aorm.Eq, Val: 0}) - where2 = append(where2, aorm.WhereItem{Field: "p.age", Opt: aorm.In, Val: []int{18, 20}}) + var where2 []executor.WhereItem + where2 = append(where2, executor.WhereItem{Field: "o.type", Opt: executor.Eq, Val: 0}) + where2 = append(where2, executor.WhereItem{Field: "p.age", Opt: executor.In, Val: []int{18, 20}}) err := aorm.Use(db).Debug(false). Table("article o"). LeftJoin("person p", "p.id=o.person_id"). @@ -306,8 +331,8 @@ func testJoin(name string, db *sql.DB) { func testGroupBy(name string, db *sql.DB) { var personAge PersonAge - var where []aorm.WhereItem - where = append(where, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0}) + var where []executor.WhereItem + where = append(where, executor.WhereItem{Field: "type", Opt: executor.Eq, Val: 0}) err := aorm.Use(db).Debug(false). Table("person"). Select("age"). @@ -323,11 +348,11 @@ func testGroupBy(name string, db *sql.DB) { func testHaving(name string, db *sql.DB) { var listByHaving []PersonAge - var where3 []aorm.WhereItem - where3 = append(where3, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0}) + var where3 []executor.WhereItem + where3 = append(where3, executor.WhereItem{Field: "type", Opt: executor.Eq, Val: 0}) - var having []aorm.WhereItem - having = append(having, aorm.WhereItem{Field: "age_count", Opt: aorm.Gt, Val: 4}) + var having []executor.WhereItem + having = append(having, executor.WhereItem{Field: "age_count", Opt: executor.Gt, Val: 4}) err := aorm.Use(db).Debug(false). Table("person"). @@ -344,12 +369,12 @@ func testHaving(name string, db *sql.DB) { func testOrderBy(name string, db *sql.DB) { var listByOrder []Person - var where []aorm.WhereItem - where = append(where, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0}) + var where []executor.WhereItem + where = append(where, executor.WhereItem{Field: "type", Opt: executor.Eq, Val: 0}) err := aorm.Use(db).Debug(false). Table("person"). WhereArr(where). - OrderBy("age", aorm.Desc). + OrderBy("age", executor.Desc). GetMany(&listByOrder) if err != nil { panic(name + "testOrderBy" + "found err") @@ -358,8 +383,8 @@ func testOrderBy(name string, db *sql.DB) { func testLimit(name string, db *sql.DB) { var list3 []Person - var where1 []aorm.WhereItem - where1 = append(where1, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0}) + var where1 []executor.WhereItem + where1 = append(where1, executor.WhereItem{Field: "type", Opt: executor.Eq, Val: 0}) err1 := aorm.Use(db).Debug(false). Table("person"). WhereArr(where1). @@ -370,8 +395,8 @@ func testLimit(name string, db *sql.DB) { } var list4 []Person - var where2 []aorm.WhereItem - where2 = append(where2, aorm.WhereItem{Field: "type", Opt: aorm.Eq, Val: 0}) + var where2 []executor.WhereItem + where2 = append(where2, executor.WhereItem{Field: "type", Opt: executor.Eq, Val: 0}) err := aorm.Use(db).Debug(false). Table("person"). WhereArr(where2). @@ -385,21 +410,21 @@ func testLimit(name string, db *sql.DB) { func testLock(name string, db *sql.DB, id int64) { var itemByLock Person - err := aorm.Use(db).Debug(false).LockForUpdate(true).Where(&Person{Id: aorm.IntFrom(id)}).GetOne(&itemByLock) + err := aorm.Use(db).Debug(false).LockForUpdate(true).Where(&Person{Id: null.IntFrom(id)}).GetOne(&itemByLock) if err != nil { panic(name + "testLock" + "found err") } } func testIncrement(name string, db *sql.DB, id int64) { - _, err := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).Increment("age", 1) + _, err := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).Increment("age", 1) if err != nil { panic(name + "testIncrement" + "found err") } } func testDecrement(name string, db *sql.DB, id int64) { - _, err := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).Decrement("age", 2) + _, err := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).Decrement("age", 2) if err != nil { panic(name + "testDecrement" + "found err") } @@ -408,25 +433,25 @@ func testDecrement(name string, db *sql.DB, id int64) { func testValue(dbName string, db *sql.DB, id int64) { var name string - errName := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).Value("name", &name) + errName := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).Value("name", &name) if errName != nil { panic(dbName + "testValue" + "found err") } var age int64 - errAge := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).Value("age", &age) + errAge := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).Value("age", &age) if errAge != nil { panic(dbName + "testValue" + "found err") } var money float32 - errMoney := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).Value("money", &money) + errMoney := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).Value("money", &money) if errMoney != nil { panic(dbName + "testValue" + "found err") } var test float64 - errTest := aorm.Use(db).Debug(false).Where(&Person{Id: aorm.IntFrom(id)}).Value("test", &test) + errTest := aorm.Use(db).Debug(false).Where(&Person{Id: null.IntFrom(id)}).Value("test", &test) if errTest != nil { panic(dbName + "testValue" + "found err") } @@ -435,60 +460,60 @@ func testValue(dbName string, db *sql.DB, id int64) { func testPluck(name string, db *sql.DB) { var nameList []string - errNameList := aorm.Use(db).Debug(false).Where(&Person{Type: aorm.IntFrom(0)}).Limit(0, 3).Pluck("name", &nameList) + errNameList := aorm.Use(db).Debug(false).Where(&Person{Type: null.IntFrom(0)}).Limit(0, 3).Pluck("name", &nameList) if errNameList != nil { panic(name + "testPluck" + "found err") } var ageList []int64 - errAgeList := aorm.Use(db).Debug(false).Where(&Person{Type: aorm.IntFrom(0)}).Limit(0, 3).Pluck("age", &ageList) + errAgeList := aorm.Use(db).Debug(false).Where(&Person{Type: null.IntFrom(0)}).Limit(0, 3).Pluck("age", &ageList) if errAgeList != nil { panic(name + "testPluck" + "found err:" + errAgeList.Error()) } var moneyList []float32 - errMoneyList := aorm.Use(db).Debug(false).Where(&Person{Type: aorm.IntFrom(0)}).Limit(0, 3).Pluck("money", &moneyList) + errMoneyList := aorm.Use(db).Debug(false).Where(&Person{Type: null.IntFrom(0)}).Limit(0, 3).Pluck("money", &moneyList) if errMoneyList != nil { panic(name + "testPluck" + "found err") } var testList []float64 - errTestList := aorm.Use(db).Debug(false).Where(&Person{Type: aorm.IntFrom(0)}).Limit(0, 3).Pluck("test", &testList) + errTestList := aorm.Use(db).Debug(false).Where(&Person{Type: null.IntFrom(0)}).Limit(0, 3).Pluck("test", &testList) if errTestList != nil { panic(name + "testPluck" + "found err") } } func testCount(name string, db *sql.DB) { - _, err := aorm.Use(db).Debug(false).Where(&Person{Age: aorm.IntFrom(18)}).Count("*") + _, err := aorm.Use(db).Debug(false).Where(&Person{Age: null.IntFrom(18)}).Count("*") if err != nil { panic(name + "testCount" + "found err") } } func testSum(name string, db *sql.DB) { - _, err := aorm.Use(db).Debug(false).Where(&Person{Age: aorm.IntFrom(18)}).Sum("age") + _, err := aorm.Use(db).Debug(false).Where(&Person{Age: null.IntFrom(18)}).Sum("age") if err != nil { panic(name + "testSum" + "found err") } } func testAvg(name string, db *sql.DB) { - _, err := aorm.Use(db).Debug(false).Where(&Person{Age: aorm.IntFrom(18)}).Avg("age") + _, err := aorm.Use(db).Debug(false).Where(&Person{Age: null.IntFrom(18)}).Avg("age") if err != nil { panic(name + "testAvg" + "found err") } } func testMin(name string, db *sql.DB) { - _, err := aorm.Use(db).Debug(false).Where(&Person{Age: aorm.IntFrom(18)}).Min("age") + _, err := aorm.Use(db).Debug(false).Where(&Person{Age: null.IntFrom(18)}).Min("age") if err != nil { panic(name + "testMin" + "found err") } } func testMax(name string, db *sql.DB) { - _, err := aorm.Use(db).Debug(false).Where(&Person{Age: aorm.IntFrom(18)}).Max("age") + _, err := aorm.Use(db).Debug(false).Where(&Person{Age: null.IntFrom(18)}).Max("age") if err != nil { panic(name + "testMax" + "found err") } @@ -506,7 +531,7 @@ func testTransaction(name string, db *sql.DB) { tx, _ := db.Begin() id, errInsert := aorm.Use(tx).Debug(false).Insert(&Person{ - Name: aorm.StringFrom("Alice"), + Name: null.StringFrom("Alice"), }) if errInsert != nil { @@ -516,7 +541,7 @@ func testTransaction(name string, db *sql.DB) { } _, errCount := aorm.Use(tx).Debug(false).Where(&Person{ - Id: aorm.IntFrom(id), + Id: null.IntFrom(id), }).Count("*") if errCount != nil { tx.Rollback() @@ -526,7 +551,7 @@ func testTransaction(name string, db *sql.DB) { var person Person errPerson := aorm.Use(tx).Debug(false).Where(&Person{ - Id: aorm.IntFrom(id), + Id: null.IntFrom(id), }).GetOne(&person) if errPerson != nil { tx.Rollback() @@ -535,9 +560,9 @@ func testTransaction(name string, db *sql.DB) { } _, errUpdate := aorm.Use(tx).Debug(false).Where(&Person{ - Id: aorm.IntFrom(id), + Id: null.IntFrom(id), }).Update(&Person{ - Name: aorm.StringFrom("Bob"), + Name: null.StringFrom("Bob"), }) if errUpdate != nil { @@ -559,9 +584,9 @@ func testTruncate(name string, db *sql.DB) { func testHelper(name string, db *sql.DB) { var list2 []ArticleVO - var where2 []aorm.WhereItem - where2 = append(where2, aorm.WhereItem{Field: "o.type", Opt: aorm.Eq, Val: 0}) - where2 = append(where2, aorm.WhereItem{Field: "p.age", Opt: aorm.In, Val: []int{18, 20}}) + var where2 []executor.WhereItem + where2 = append(where2, executor.WhereItem{Field: "o.type", Opt: executor.Eq, Val: 0}) + where2 = append(where2, executor.WhereItem{Field: "p.age", Opt: executor.In, Val: []int{18, 20}}) err := aorm.Use(db).Debug(false). Table("article o"). LeftJoin("person p", aorm.Ul("p.id=o.personId")).