代码拉取完成,页面将自动刷新
package dborm
import (
"database/sql"
"fmt"
"reflect"
"strings"
"sync"
"gitee.com/leminewx/dborm/dialect"
"gitee.com/leminewx/dborm/schema"
"gitee.com/leminewx/dborm/session"
"gitee.com/leminewx/loggo"
)
const (
DriverMySQL = "mysql"
DriverSqlite3 = "sqlite3"
DriverPostgreSQL = "postgresql"
)
// Engine 定义 ORM 引擎的数据结构
type Engine struct {
name string
dialect dialect.Dialect
db *sql.DB
schemas *sync.Map
}
// NewEngine 创建一个 ORM 引擎
func NewEngine(driverName, dbSource string) (eng *Engine, err error) {
// 打开数据库连接
db, err := sql.Open(driverName, dbSource)
if err != nil {
return nil, err
}
// 检查数据库连接是否活跃
if err = db.Ping(); err != nil {
return nil, err
}
// make sure the specific dialect exists.
dial := dialect.Get(driverName)
if dial == nil {
return nil, fmt.Errorf("dborm: not supported database driver: %s", driverName)
}
var dbName string
switch driverName {
case dialect.Mysql:
dbName = strings.Split(strings.Split(dbSource, "/")[1], "?")[0]
case dialect.Sqlite3:
case dialect.Postgresql:
}
eng = &Engine{name: dbName, dialect: dial, db: db, schemas: new(sync.Map)}
loggo.Info("connect database successfully.")
return
}
func (own *Engine) SetMaxIdleConns(num int) {
own.db.SetMaxIdleConns(num)
}
func (own *Engine) SetMaxOpenConns(num int) {
own.db.SetMaxOpenConns(num)
}
// NewSession 新建一个会话
func (own *Engine) NewSession(model ...any) *session.Session {
if len(model) == 0 {
return session.New(own.name, own.db, own.dialect, nil)
}
// 解析数据模型
modelType := reflect.TypeOf(model[0]).String()
tab, ok := own.schemas.Load(modelType)
if !ok {
tab = schema.Parse(own.dialect, model[0])
own.schemas.Store(modelType, tab)
}
// 复用数据模型,提高性能
return session.New(own.name, own.db, own.dialect, tab.(*schema.Schema))
}
// TxFunc will be called between tx.Begin() and tx.Commit()
type TxFunc func(*session.Session) (any, error)
// Transaction executes sql wrapped in a transaction, then automatically commit if no error occurs
func (own *Engine) Transaction(fn TxFunc) (res any, err error) {
// 新建会话,并开始事务
session := own.NewSession()
if err = session.Begin(); err != nil {
return nil, err
}
// 回滚或提交事务
defer func() {
if p := recover(); p != nil { // 调用异常,回滚事务
session.Rollback()
err = fmt.Errorf("%v", p)
} else if err != nil { // 执行失败,回滚事务
session.Rollback()
} else { // 提交事务
err = session.Commit()
}
}()
// 执行事务
return fn(session)
}
// ALTER TABLE <表名> ADD <新字段名> <数据类型> [约束条件] [first | after 已存在字段名]
// ALTER TABLE <表名> ADD COLUMN <新字段名>, <数据类型>;
// Migrate 迁移数据表
// func (own *Engine) Migrate(value any) error {
// _, err := own.Transaction(func(s *session.Session) (result any, err error) {
// // sets the data model.
// if !s.SetModel(value).IsExistTable() {
// loggo.Error("not exists table:", s.GetSchema().Name)
// return nil, s.CreateTable()
// }
// table := s.RefTable()
// rows, _ := s.Raw(fmt.Sprintf("SELECT * FROM %s LIMIT 1", table.Name)).QueryRows()
// columns, _ := rows.Columns()
// addCols := difference(table.FieldNames, columns)
// delCols := difference(columns, table.FieldNames)
// loggo.Infof("added cols %v, deleted cols %v", addCols, delCols)
// for _, col := range addCols {
// f := table.GetField(col)
// sqlStr := fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s %s;", table.Name, f.Name, f.Type)
// if _, err = s.Raw(sqlStr).Exec(); err != nil {
// return
// }
// }
// if len(delCols) == 0 {
// return
// }
// tmp := "tmp_" + table.Name
// fieldStr := strings.Join(table.FieldNames, ", ")
// s.Raw(fmt.Sprintf("CREATE TABLE %s AS SELECT %s from %s;", tmp, fieldStr, table.Name))
// s.Raw(fmt.Sprintf("DROP TABLE %s;", table.Name))
// s.Raw(fmt.Sprintf("ALTER TABLE %s RENAME TO %s;", tmp, table.Name))
// _, err = s.Exec()
// return
// })
// return err
// }
// // difference returns a - b
// func difference(a []string, b []string) (diff []string) {
// mapB := make(map[string]bool)
// for _, v := range b {
// mapB[v] = true
// }
// for _, v := range a {
// if _, ok := mapB[v]; !ok {
// diff = append(diff, v)
// }
// }
// return
// }
// Close 关闭引擎
func (own *Engine) Close() error {
return own.db.Close()
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。