diff --git a/core/db.go b/core/db.go index 97103039..6dedbb86 100644 --- a/core/db.go +++ b/core/db.go @@ -155,6 +155,19 @@ func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) { return s.Stmt.Exec(args...) } +func (s *Stmt) Query(args ...interface{}) (*Rows, error) { + rows, err := s.Stmt.Query(args...) + if err != nil { + return nil, err + } + return &Rows{rows, s.Mapper}, nil +} + +func (s *Stmt) QueryRow(args ...interface{}) *Row { + row := s.Stmt.QueryRow(args...) + return &Row{row, nil, s.Mapper} +} + var ( re = regexp.MustCompile(`[?](\w+)`) ) diff --git a/engine.go b/engine.go index af910562..2ac88f33 100644 --- a/engine.go +++ b/engine.go @@ -124,8 +124,8 @@ func (engine *Engine) MapCacher(bean interface{}, cacher core.Cacher) { } // OpenDB provides a interface to operate database directly. -func (engine *Engine) OpenDB() (*sql.DB, error) { - return sql.Open(engine.DriverName, engine.DataSourceName) +func (engine *Engine) OpenDB() (*core.DB, error) { + return core.Open(engine.DriverName, engine.DataSourceName) } // New a session diff --git a/helpers.go b/helpers.go index 8b327fa8..12ed4a03 100644 --- a/helpers.go +++ b/helpers.go @@ -1,7 +1,6 @@ package xorm import ( - "database/sql" "fmt" "reflect" "strconv" @@ -121,7 +120,7 @@ func value2Bytes(rawValue *reflect.Value) (data []byte, err error) { return } -func rows2maps(rows *sql.Rows) (resultsSlice []map[string][]byte, err error) { +func rows2maps(rows *core.Rows) (resultsSlice []map[string][]byte, err error) { fields, err := rows.Columns() if err != nil { return nil, err diff --git a/pool.go b/pool.go index 7a7b173e..bdef3268 100644 --- a/pool.go +++ b/pool.go @@ -1,7 +1,7 @@ package xorm import ( - "database/sql" + "github.com/lunny/xorm/core" //"fmt" "sync" //"sync/atomic" @@ -18,8 +18,8 @@ import ( // Close for invoking when engine.Close type IConnectPool interface { Init(engine *Engine) error - RetrieveDB(engine *Engine) (*sql.DB, error) - ReleaseDB(engine *Engine, db *sql.DB) + RetrieveDB(engine *Engine) (*core.DB, error) + ReleaseDB(engine *Engine, db *core.DB) Close(engine *Engine) error SetMaxIdleConns(conns int) MaxIdleConns() int @@ -43,13 +43,13 @@ func (p *NoneConnectPool) Init(engine *Engine) error { } // RetrieveDB directly open a connection -func (p *NoneConnectPool) RetrieveDB(engine *Engine) (db *sql.DB, err error) { +func (p *NoneConnectPool) RetrieveDB(engine *Engine) (db *core.DB, err error) { db, err = engine.OpenDB() return } // ReleaseDB directly close a connection -func (p *NoneConnectPool) ReleaseDB(engine *Engine, db *sql.DB) { +func (p *NoneConnectPool) ReleaseDB(engine *Engine, db *core.DB) { db.Close() } @@ -78,7 +78,7 @@ func (p *NoneConnectPool) MaxConns() int { // About the system connection pool, you can review the code database/sql/sql.go // It's currently default Pool implments. type SysConnectPool struct { - db *sql.DB + db *core.DB maxIdleConns int maxConns int curConns int @@ -118,7 +118,7 @@ func newCondNode() *node { } // RetrieveDB just return the only db -func (s *SysConnectPool) RetrieveDB(engine *Engine) (db *sql.DB, err error) { +func (s *SysConnectPool) RetrieveDB(engine *Engine) (db *core.DB, err error) { /*if s.maxConns > 0 { fmt.Println("before retrieve") s.mutex.Lock() @@ -141,7 +141,7 @@ func (s *SysConnectPool) RetrieveDB(engine *Engine) (db *sql.DB, err error) { } // ReleaseDB do nothing -func (s *SysConnectPool) ReleaseDB(engine *Engine, db *sql.DB) { +func (s *SysConnectPool) ReleaseDB(engine *Engine, db *core.DB) { /*if s.maxConns > 0 { s.mutex.Lock() fmt.Println("before release", s.queue.Len()) @@ -191,8 +191,8 @@ func (p *SysConnectPool) MaxConns() int { // NewSimpleConnectPool new a SimpleConnectPool func NewSimpleConnectPool() IConnectPool { - return &SimpleConnectPool{releasedConnects: make([]*sql.DB, 10), - usingConnects: map[*sql.DB]time.Time{}, + return &SimpleConnectPool{releasedConnects: make([]*core.DB, 10), + usingConnects: map[*core.DB]time.Time{}, cur: -1, maxWaitTimeOut: 14400, maxIdleConns: 10, @@ -205,9 +205,9 @@ func NewSimpleConnectPool() IConnectPool { // Opening or Closing a database connection must be enter a lock. // This implements will be improved in furture. type SimpleConnectPool struct { - releasedConnects []*sql.DB + releasedConnects []*core.DB cur int - usingConnects map[*sql.DB]time.Time + usingConnects map[*core.DB]time.Time maxWaitTimeOut int mutex *sync.Mutex maxIdleConns int @@ -218,10 +218,10 @@ func (s *SimpleConnectPool) Init(engine *Engine) error { } // RetrieveDB get a connection from connection pool -func (p *SimpleConnectPool) RetrieveDB(engine *Engine) (*sql.DB, error) { +func (p *SimpleConnectPool) RetrieveDB(engine *Engine) (*core.DB, error) { p.mutex.Lock() defer p.mutex.Unlock() - var db *sql.DB = nil + var db *core.DB = nil var err error = nil //fmt.Printf("%x, rbegin - released:%v, using:%v\n", &p, p.cur+1, len(p.usingConnects)) if p.cur < 0 { @@ -242,7 +242,7 @@ func (p *SimpleConnectPool) RetrieveDB(engine *Engine) (*sql.DB, error) { } // ReleaseDB release a db from connection pool -func (p *SimpleConnectPool) ReleaseDB(engine *Engine, db *sql.DB) { +func (p *SimpleConnectPool) ReleaseDB(engine *Engine, db *core.DB) { p.mutex.Lock() defer p.mutex.Unlock() //fmt.Printf("%x, lbegin - released:%v, using:%v\n", &p, p.cur+1, len(p.usingConnects)) diff --git a/rows.go b/rows.go index ef04af75..ecbbce46 100644 --- a/rows.go +++ b/rows.go @@ -4,14 +4,16 @@ import ( "database/sql" "fmt" "reflect" + + "github.com/lunny/xorm/core" ) type Rows struct { NoTypeCheck bool session *Session - stmt *sql.Stmt - rows *sql.Rows + stmt *core.Stmt + rows *core.Rows fields []string fieldsCount int beanType reflect.Type diff --git a/session.go b/session.go index 9dc60c14..271175fc 100644 --- a/session.go +++ b/session.go @@ -17,9 +17,9 @@ import ( // Struct Session keep a pointer to sql.DB and provides all execution of all // kind of database operations. type Session struct { - Db *sql.DB + Db *core.DB Engine *Engine - Tx *sql.Tx + Tx *core.Tx Statement Statement IsAutoCommit bool IsCommitedOrRollbacked bool @@ -35,7 +35,7 @@ type Session struct { beforeClosures []func(interface{}) afterClosures []func(interface{}) - stmtCache map[uint32]*sql.Stmt //key: hash.Hash32 of (queryStr, len(queryStr)) + stmtCache map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr)) } // Method Init reset the session as the init status. @@ -262,7 +262,7 @@ func (session *Session) newDb() error { return err } session.Db = db - session.stmtCache = make(map[uint32]*sql.Stmt, 0) + session.stmtCache = make(map[uint32]*core.Stmt, 0) } return nil } @@ -897,7 +897,7 @@ func (session *Session) Iterate(bean interface{}, fun IterFunc) error { return nil } -func (session *Session) doPrepare(sqlStr string) (stmt *sql.Stmt, err error) { +func (session *Session) doPrepare(sqlStr string) (stmt *core.Stmt, err error) { crc := crc32.ChecksumIEEE([]byte(sqlStr)) // TODO try hash(sqlStr+len(sqlStr)) var has bool @@ -944,7 +944,7 @@ func (session *Session) Get(bean interface{}) (bool, error) { } } - var rawRows *sql.Rows + var rawRows *core.Rows session.queryPreprocess(&sqlStr, args...) if session.IsAutoCommit { stmt, err := session.doPrepare(sqlStr) @@ -1102,8 +1102,8 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{}) } if sliceValue.Kind() != reflect.Map { - var rawRows *sql.Rows - var stmt *sql.Stmt + var rawRows *core.Rows + var stmt *core.Stmt session.queryPreprocess(&sqlStr, args...) // err = session.queryRows(&stmt, &rawRows, sqlStr, args...) @@ -1377,7 +1377,7 @@ func (session *Session) dropAll() error { return nil } -func row2map(rows *sql.Rows, fields []string) (resultsMap map[string][]byte, err error) { +func row2map(rows *core.Rows, fields []string) (resultsMap map[string][]byte, err error) { result := make(map[string][]byte) scanResultContainers := make([]interface{}, len(fields)) for i := 0; i < len(fields); i++ { @@ -1426,7 +1426,7 @@ func (session *Session) getField(dataStruct *reflect.Value, key string, table *c return fieldValue } -func (session *Session) row2Bean(rows *sql.Rows, fields []string, fieldsCount int, bean interface{}) error { +func (session *Session) row2Bean(rows *core.Rows, fields []string, fieldsCount int, bean interface{}) error { dataStruct := reflect.Indirect(reflect.ValueOf(bean)) if dataStruct.Kind() != reflect.Struct { @@ -1713,7 +1713,7 @@ func (session *Session) query(sqlStr string, paramStr ...interface{}) (resultsSl return txQuery(session.Tx, sqlStr, paramStr...) } -func txQuery(tx *sql.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) { +func txQuery(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) { rows, err := tx.Query(sqlStr, params...) if err != nil { return nil, err @@ -1723,7 +1723,7 @@ func txQuery(tx *sql.Tx, sqlStr string, params ...interface{}) (resultsSlice []m return rows2maps(rows) } -func query(db *sql.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) { +func query(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) { s, err := db.Prepare(sqlStr) if err != nil { return nil, err