diff --git a/readme.md b/readme.md index b7a4b4f..aa66dbc 100644 --- a/readme.md +++ b/readme.md @@ -111,11 +111,15 @@ var rose = gorose.Open( ``` ## 驱动支持 -- MySQL -- MsSQL -- Postgresql -- Oracle -- Sqlite3 +- mysql : https://github.com/go-sql-driver/mysql +- sqlite3 : https://github.com/mattn/go-sqlite3 +- postgres : https://github.com/lib/pq +- oracle : https://github.com/mattn/go-oci8 +- mssql : https://github.com/denisenkom/go-mssqldb + +目前实现了以上5中数据库的支持, 通用数据库,只需要添加更多的 `gorose/driver/dialect.IDialect` 接口即可 +非通用数据库,只要实现了 gorose/driver.IDriver 接口,理论上可以支持任意数据库,包括 redis,mongo 等都可以通过这个接口来实现 +所有的 orm 链式操作都在 `gorose/builder.Context` 中, 直接可以拿到最原始的数据 ## 事务 ```go @@ -125,7 +129,7 @@ db().Transaction(func(tx gorose.TxHandler) error { tx().Insert(&user) tx().Update(&user) tx().To(&user) -} +}) // 手动事务 tx = db().Begin() @@ -269,6 +273,7 @@ db().Table(User{}).Where("id",">", 1).Where(func(wh builder.IWhere) { wh.Where("sex", 1).OrWhere("sex", 2) }) ``` +这里的 Where 等同于 WhereNested ```go // where id>1 and (sex=1 or sex=2) db().Table(User{}).Where("id",">", 1).WhereNested(func(wh builder.IWhere) { @@ -386,9 +391,6 @@ db().Table("users").MinTo("age", &min) ## 日志 默认采用 官方库的 slog debug level, 如果不想显示sql日志, 只需要设置slog的level到debug以上即可, 如: Info, Warn, Error -## 驱动 -只要实现了 gorose/driver.IDriver 接口即可,理论上可以支持任意数据库, 目前实现了mysql的支持, 可以开发更多接口的支持 - ## 数据库字段为null的处理 ```go type User struct { @@ -475,7 +477,8 @@ if age.Valid { - [x] Pluck - [x] List -- [x] Value +- [x] Value +- [x] Paginate - [x] Increment - [x] Decrement @@ -508,3 +511,4 @@ if age.Valid { - [x] MaxTo - [x] UnionTo - [x] UnionAllTo + diff --git a/sugar.go b/sugar.go index e7c2d9b..eccb20e 100644 --- a/sugar.go +++ b/sugar.go @@ -53,7 +53,6 @@ func (db *Database) Paginate(obj ...any) (result Pagination, err error) { return } - func (db *Database) WhereSub(column string, operation string, sub builder.WhereSubHandler) *Database { db.Context.WhereClause.WhereSub(column, operation, sub) return db @@ -113,6 +112,7 @@ func (db *Database) OrWhereLike(column, value string) *Database { db.Context.WhereClause.OrWhereLike(column, value) return db } + //func (db *Database) WhereNotIn(column string, value any) *Database { // db.Context.WhereClause.WhereNotIn(column, value) // return db @@ -148,6 +148,7 @@ func (db *Database) OrWhereLike(column, value string) *Database { // db.Context.WhereClause.whereLike("OR", column, value, true) // return db //} + func (db *Database) WhereNot(column any, args ...any) *Database { db.Context.WhereClause.WhereNot(column, args...) return db diff --git a/toSql_test.go b/toSql_test.go index b833f00..c5d0fef 100644 --- a/toSql_test.go +++ b/toSql_test.go @@ -11,10 +11,10 @@ type User struct { } // var dbg = Open("mysql") // just test toSql -// var dbg = Open("postgresql") // just test toSql +var dbg = Open("postgresql") // just test toSql // var dbg = Open("mssql") // just test toSql // var dbg = Open("oracle") // just test toSql -var dbg = Open("sqlite3") // just test toSql +//var dbg = Open("sqlite3") // just test toSql func db() *Database { return dbg.NewDatabase() @@ -63,12 +63,15 @@ func TestDatabase_ToSqlInsert(t *testing.T) { driver.AssertsEqual(t, expectValues, values) } func TestDatabase_ToSqlInserts(t *testing.T) { - var user = []User{{Name: "John"}, {Name: "Alice"}} + var user = []User{{Id: 1, Name: "John"}, {Id: 2, Name: "Alice"}} prepare, values, err := db().ToSqlInsert(&user) driver.AssertsError(t, err) - var expect = "INSERT INTO `User` (`name`) VALUES (?),(?)" - driver.AssertsEqual(t, expect, prepare) - var expectValues = []string{"John", "Alice"} + var expect = map[string]string{ + "mysql": "INSERT INTO `User` (`id`,`name`) VALUES (?,?),(?,?)", + "postgresql": `INSERT INTO "User" ("id","name") VALUES ($1,$2),($3,$4)`, + } + driver.AssertsEqual(t, expect[dbg.driver], prepare) + var expectValues = []interface{}{1, "John", 2, "Alice"} driver.AssertsEqual(t, expectValues, values) } func TestDatabase_ToSqlUpdate(t *testing.T) { diff --git a/util.go b/util.go index c77225c..e36b4c1 100644 --- a/util.go +++ b/util.go @@ -2,11 +2,8 @@ package gorose import ( "database/sql" - "fmt" "github.com/gohouse/gorose/v3/builder" "math/rand" - "regexp" - "strings" "time" ) @@ -23,32 +20,33 @@ func As(table any, alias string) builder.TableClause { func GetRandomInt(num int) int { return rand.Intn(num) } -func GetRandomWeightedIndex(weights []int) int { - if len(weights) == 0 { - return 0 - } - if len(weights) == 1 { - return 0 - } - totalWeight := 0 - for _, w := range weights { - totalWeight += w - } - if totalWeight == 0 { - return rand.Intn(len(weights)) - } - rnd := rand.Intn(totalWeight) - - currentWeight := 0 - for i, w := range weights { - currentWeight += w - if rnd < currentWeight { - return i - } - } - return -1 // 如果权重都为 0,或者总权重为 0,则返回 -1 -} +//func GetRandomWeightedIndex(weights []int) int { +// if len(weights) == 0 { +// return 0 +// } +// if len(weights) == 1 { +// return 0 +// } +// totalWeight := 0 +// for _, w := range weights { +// totalWeight += w +// } +// if totalWeight == 0 { +// return rand.Intn(len(weights)) +// } +// +// rnd := rand.Intn(totalWeight) +// +// currentWeight := 0 +// for i, w := range weights { +// currentWeight += w +// if rnd < currentWeight { +// return i +// } +// } +// return -1 // 如果权重都为 0,或者总权重为 0,则返回 -1 +//} //////////// struct field ptr 4 orm helpers //////////// @@ -61,7 +59,3 @@ func Ptr[T any](arg T) *T { func Null[T any](arg T) sql.Null[T] { return sql.Null[T]{V: arg, Valid: true} } - -func NamedSprintf(format string, a ...any) string { - return strings.TrimSpace(regexp.MustCompile(`\s{2,}`).ReplaceAllString(fmt.Sprintf(regexp.MustCompile(`:\w+`).ReplaceAllString(format, "%s"), a...), " ")) -}