45aa0712 by slene

orm add queries debug logger

1 parent 85630002
...@@ -527,7 +527,7 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, skipAuto bool, ...@@ -527,7 +527,7 @@ func (d *dbBase) collectValues(mi *modelInfo, ind reflect.Value, skipAuto bool,
527 return 527 return
528 } 528 }
529 529
530 func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (*sql.Stmt, error) { 530 func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (stmtQuerier, string, error) {
531 dbcols := make([]string, 0, len(mi.fields.dbcols)) 531 dbcols := make([]string, 0, len(mi.fields.dbcols))
532 marks := make([]string, 0, len(mi.fields.dbcols)) 532 marks := make([]string, 0, len(mi.fields.dbcols))
533 for _, fi := range mi.fields.fieldsDB { 533 for _, fi := range mi.fields.fieldsDB {
...@@ -540,10 +540,11 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (*sql.Stmt, error) { ...@@ -540,10 +540,11 @@ func (d *dbBase) PrepareInsert(q dbQuerier, mi *modelInfo) (*sql.Stmt, error) {
540 columns := strings.Join(dbcols, "`,`") 540 columns := strings.Join(dbcols, "`,`")
541 541
542 query := fmt.Sprintf("INSERT INTO `%s` (`%s`) VALUES (%s)", mi.table, columns, qmarks) 542 query := fmt.Sprintf("INSERT INTO `%s` (`%s`) VALUES (%s)", mi.table, columns, qmarks)
543 return q.Prepare(query) 543 stmt, err := q.Prepare(query)
544 return stmt, query, err
544 } 545 }
545 546
546 func (d *dbBase) InsertStmt(stmt *sql.Stmt, mi *modelInfo, ind reflect.Value) (int64, error) { 547 func (d *dbBase) InsertStmt(stmt stmtQuerier, mi *modelInfo, ind reflect.Value) (int64, error) {
547 _, values, err := d.collectValues(mi, ind, true, true) 548 _, values, err := d.collectValues(mi, ind, true, true)
548 if err != nil { 549 if err != nil {
549 return 0, err 550 return 0, err
......
1 package orm 1 package orm
2 2
3 import ( 3 import (
4 "log"
5 "os"
6 "sync" 4 "sync"
7 ) 5 )
8 6
...@@ -15,7 +13,6 @@ const ( ...@@ -15,7 +13,6 @@ const (
15 ) 13 )
16 14
17 var ( 15 var (
18 errLog *log.Logger
19 modelCache = &_modelCache{ 16 modelCache = &_modelCache{
20 cache: make(map[string]*modelInfo), 17 cache: make(map[string]*modelInfo),
21 cacheByFN: make(map[string]*modelInfo), 18 cacheByFN: make(map[string]*modelInfo),
...@@ -44,10 +41,6 @@ var ( ...@@ -44,10 +41,6 @@ var (
44 } 41 }
45 ) 42 )
46 43
47 func init() {
48 errLog = log.New(os.Stderr, "[ORM] ", log.Ldate|log.Ltime|log.Lshortfile)
49 }
50
51 type _modelCache struct { 44 type _modelCache struct {
52 sync.RWMutex 45 sync.RWMutex
53 orders []string 46 orders []string
......
...@@ -97,9 +97,11 @@ func NewComment() *Comment { ...@@ -97,9 +97,11 @@ func NewComment() *Comment {
97 var DBARGS = struct { 97 var DBARGS = struct {
98 Driver string 98 Driver string
99 Source string 99 Source string
100 Debug string
100 }{ 101 }{
101 os.Getenv("ORM_DRIVER"), 102 os.Getenv("ORM_DRIVER"),
102 os.Getenv("ORM_SOURCE"), 103 os.Getenv("ORM_SOURCE"),
104 os.Getenv("ORM_DEBUG"),
103 } 105 }
104 106
105 var dORM Ormer 107 var dORM Ormer
...@@ -111,6 +113,8 @@ func init() { ...@@ -111,6 +113,8 @@ func init() {
111 RegisterModel(new(Tag)) 113 RegisterModel(new(Tag))
112 RegisterModel(new(Comment)) 114 RegisterModel(new(Comment))
113 115
116 Debug, _ = StrTo(DBARGS.Debug).Bool()
117
114 if DBARGS.Driver == "" || DBARGS.Source == "" { 118 if DBARGS.Driver == "" || DBARGS.Source == "" {
115 fmt.Println(`need driver and source! 119 fmt.Println(`need driver and source!
116 120
......
...@@ -4,18 +4,26 @@ import ( ...@@ -4,18 +4,26 @@ import (
4 "database/sql" 4 "database/sql"
5 "errors" 5 "errors"
6 "fmt" 6 "fmt"
7 "os"
7 "reflect" 8 "reflect"
8 "time" 9 "time"
9 ) 10 )
10 11
12 const (
13 Debug_Queries = iota
14 )
15
11 var ( 16 var (
17 // DebugLevel = Debug_Queries
18 Debug = true
19 DebugLog = NewLog(os.Stderr)
12 DefaultRowsLimit = 1000 20 DefaultRowsLimit = 1000
13 DefaultRelsDepth = 5 21 DefaultRelsDepth = 5
14 DefaultTimeLoc = time.Local 22 DefaultTimeLoc = time.Local
15 ErrTxHasBegan = errors.New("<Ormer.Begin> transaction already begin") 23 ErrTxHasBegan = errors.New("<Ormer.Begin> transaction already begin")
16 ErrTxDone = errors.New("<Ormer.Commit/Rollback> transaction not begin") 24 ErrTxDone = errors.New("<Ormer.Commit/Rollback> transaction not begin")
17 ErrMultiRows = errors.New("<QuerySeter> return multi rows") 25 ErrMultiRows = errors.New("<QuerySeter> return multi rows")
18 ErrNoRows = errors.New("<QuerySeter> not row found") 26 ErrNoRows = errors.New("<QuerySeter> no row found")
19 ErrStmtClosed = errors.New("<QuerySeter> stmt already closed") 27 ErrStmtClosed = errors.New("<QuerySeter> stmt already closed")
20 ErrNotImplement = errors.New("have not implement") 28 ErrNotImplement = errors.New("have not implement")
21 ) 29 )
...@@ -124,7 +132,11 @@ func (o *orm) Using(name string) error { ...@@ -124,7 +132,11 @@ func (o *orm) Using(name string) error {
124 } 132 }
125 if al, ok := dataBaseCache.get(name); ok { 133 if al, ok := dataBaseCache.get(name); ok {
126 o.alias = al 134 o.alias = al
127 o.db = al.DB 135 if Debug {
136 o.db = newDbQueryLog(al, al.DB)
137 } else {
138 o.db = al.DB
139 }
128 } else { 140 } else {
129 return errors.New(fmt.Sprintf("<orm.Using> unknown db alias name `%s`", name)) 141 return errors.New(fmt.Sprintf("<orm.Using> unknown db alias name `%s`", name))
130 } 142 }
...@@ -135,12 +147,17 @@ func (o *orm) Begin() error { ...@@ -135,12 +147,17 @@ func (o *orm) Begin() error {
135 if o.isTx { 147 if o.isTx {
136 return ErrTxHasBegan 148 return ErrTxHasBegan
137 } 149 }
138 tx, err := o.alias.DB.Begin() 150 var tx *sql.Tx
151 tx, err := o.db.(txer).Begin()
139 if err != nil { 152 if err != nil {
140 return err 153 return err
141 } 154 }
142 o.isTx = true 155 o.isTx = true
143 o.db = tx 156 if Debug {
157 o.db.(*dbQueryLog).SetDB(tx)
158 } else {
159 o.db = tx
160 }
144 return nil 161 return nil
145 } 162 }
146 163
...@@ -148,10 +165,10 @@ func (o *orm) Commit() error { ...@@ -148,10 +165,10 @@ func (o *orm) Commit() error {
148 if o.isTx == false { 165 if o.isTx == false {
149 return ErrTxDone 166 return ErrTxDone
150 } 167 }
151 err := o.db.(*sql.Tx).Commit() 168 err := o.db.(txEnder).Commit()
152 if err == nil { 169 if err == nil {
153 o.isTx = false 170 o.isTx = false
154 o.db = o.alias.DB 171 o.Using(o.alias.Name)
155 } else if err == sql.ErrTxDone { 172 } else if err == sql.ErrTxDone {
156 return ErrTxDone 173 return ErrTxDone
157 } 174 }
...@@ -162,10 +179,10 @@ func (o *orm) Rollback() error { ...@@ -162,10 +179,10 @@ func (o *orm) Rollback() error {
162 if o.isTx == false { 179 if o.isTx == false {
163 return ErrTxDone 180 return ErrTxDone
164 } 181 }
165 err := o.db.(*sql.Tx).Rollback() 182 err := o.db.(txEnder).Rollback()
166 if err == nil { 183 if err == nil {
167 o.isTx = false 184 o.isTx = false
168 o.db = o.alias.DB 185 o.Using(o.alias.Name)
169 } else if err == sql.ErrTxDone { 186 } else if err == sql.ErrTxDone {
170 return ErrTxDone 187 return ErrTxDone
171 } 188 }
......
1 package orm
2
3 import (
4 "database/sql"
5 "fmt"
6 "io"
7 "log"
8 "strings"
9 "time"
10 )
11
12 type Log struct {
13 *log.Logger
14 }
15
16 func NewLog(out io.Writer) *Log {
17 d := new(Log)
18 d.Logger = log.New(out, "[ORM]", 1e9)
19 return d
20 }
21
22 func debugLogQueies(alias *alias, operaton, query string, t time.Time, err error, args ...interface{}) {
23 sub := time.Now().Sub(t) / 1e5
24 elsp := float64(int(sub)) / 10.0
25 con := fmt.Sprintf(" - %s - [Queries/%s] - [%11s / %7.1fms] - [%s]", t.Format(format_DateTime), alias.Name, operaton, elsp, query)
26 cons := make([]string, 0, len(args))
27 for _, arg := range args {
28 cons = append(cons, fmt.Sprintf("%v", arg))
29 }
30 if len(cons) > 0 {
31 con += fmt.Sprintf(" - `%s`", strings.Join(cons, "`, `"))
32 }
33 if err != nil {
34 con += " - " + err.Error()
35 }
36 DebugLog.Println(con)
37 }
38
39 type stmtQueryLog struct {
40 alias *alias
41 query string
42 stmt stmtQuerier
43 }
44
45 var _ stmtQuerier = new(stmtQueryLog)
46
47 func (d *stmtQueryLog) Close() error {
48 a := time.Now()
49 err := d.stmt.Close()
50 debugLogQueies(d.alias, "st.Close", d.query, a, err)
51 return err
52 }
53
54 func (d *stmtQueryLog) Exec(args ...interface{}) (sql.Result, error) {
55 a := time.Now()
56 res, err := d.stmt.Exec(args...)
57 debugLogQueies(d.alias, "st.Exec", d.query, a, err, args...)
58 return res, err
59 }
60
61 func (d *stmtQueryLog) Query(args ...interface{}) (*sql.Rows, error) {
62 a := time.Now()
63 res, err := d.stmt.Query(args...)
64 debugLogQueies(d.alias, "st.Query", d.query, a, err, args...)
65 return res, err
66 }
67
68 func (d *stmtQueryLog) QueryRow(args ...interface{}) *sql.Row {
69 a := time.Now()
70 res := d.stmt.QueryRow(args...)
71 debugLogQueies(d.alias, "st.QueryRow", d.query, a, nil, args...)
72 return res
73 }
74
75 func newStmtQueryLog(alias *alias, stmt stmtQuerier, query string) stmtQuerier {
76 d := new(stmtQueryLog)
77 d.stmt = stmt
78 d.alias = alias
79 d.query = query
80 return d
81 }
82
83 type dbQueryLog struct {
84 alias *alias
85 db dbQuerier
86 tx txer
87 txe txEnder
88 }
89
90 var _ dbQuerier = new(dbQueryLog)
91 var _ txer = new(dbQueryLog)
92 var _ txEnder = new(dbQueryLog)
93
94 func (d *dbQueryLog) Prepare(query string) (*sql.Stmt, error) {
95 a := time.Now()
96 stmt, err := d.db.Prepare(query)
97 debugLogQueies(d.alias, "db.Prepare", query, a, err)
98 return stmt, err
99 }
100
101 func (d *dbQueryLog) Exec(query string, args ...interface{}) (sql.Result, error) {
102 a := time.Now()
103 res, err := d.db.Exec(query, args...)
104 debugLogQueies(d.alias, "db.Exec", query, a, err, args...)
105 return res, err
106 }
107
108 func (d *dbQueryLog) Query(query string, args ...interface{}) (*sql.Rows, error) {
109 a := time.Now()
110 res, err := d.db.Query(query, args...)
111 debugLogQueies(d.alias, "db.Query", query, a, err, args...)
112 return res, err
113 }
114
115 func (d *dbQueryLog) QueryRow(query string, args ...interface{}) *sql.Row {
116 a := time.Now()
117 res := d.db.QueryRow(query, args...)
118 debugLogQueies(d.alias, "db.QueryRow", query, a, nil, args...)
119 return res
120 }
121
122 func (d *dbQueryLog) Begin() (*sql.Tx, error) {
123 a := time.Now()
124 tx, err := d.db.(txer).Begin()
125 debugLogQueies(d.alias, "db.Begin", "START TRANSACTION", a, err)
126 return tx, err
127 }
128
129 func (d *dbQueryLog) Commit() error {
130 a := time.Now()
131 err := d.db.(txEnder).Commit()
132 debugLogQueies(d.alias, "tx.Commit", "COMMIT", a, err)
133 return err
134 }
135
136 func (d *dbQueryLog) Rollback() error {
137 a := time.Now()
138 err := d.db.(txEnder).Commit()
139 debugLogQueies(d.alias, "tx.Rollback", "ROLLBACK", a, err)
140 return err
141 }
142
143 func (d *dbQueryLog) SetDB(db dbQuerier) {
144 d.db = db
145 }
146
147 func newDbQueryLog(alias *alias, db dbQuerier) dbQuerier {
148 d := new(dbQueryLog)
149 d.alias = alias
150 d.db = db
151 return d
152 }
1 package orm 1 package orm
2 2
3 import ( 3 import (
4 "database/sql"
5 "fmt" 4 "fmt"
6 "reflect" 5 "reflect"
7 ) 6 )
...@@ -9,7 +8,7 @@ import ( ...@@ -9,7 +8,7 @@ import (
9 type insertSet struct { 8 type insertSet struct {
10 mi *modelInfo 9 mi *modelInfo
11 orm *orm 10 orm *orm
12 stmt *sql.Stmt 11 stmt stmtQuerier
13 closed bool 12 closed bool
14 } 13 }
15 14
...@@ -49,10 +48,14 @@ func newInsertSet(orm *orm, mi *modelInfo) (Inserter, error) { ...@@ -49,10 +48,14 @@ func newInsertSet(orm *orm, mi *modelInfo) (Inserter, error) {
49 bi := new(insertSet) 48 bi := new(insertSet)
50 bi.orm = orm 49 bi.orm = orm
51 bi.mi = mi 50 bi.mi = mi
52 st, err := orm.alias.DbBaser.PrepareInsert(orm.db, mi) 51 st, query, err := orm.alias.DbBaser.PrepareInsert(orm.db, mi)
53 if err != nil { 52 if err != nil {
54 return nil, err 53 return nil, err
55 } 54 }
56 bi.stmt = st 55 if Debug {
56 bi.stmt = newStmtQueryLog(orm.alias, st, query)
57 } else {
58 bi.stmt = st
59 }
57 return bi, nil 60 return bi, nil
58 } 61 }
......
...@@ -26,7 +26,7 @@ func getResult(res sql.Result) (int64, error) { ...@@ -26,7 +26,7 @@ func getResult(res sql.Result) (int64, error) {
26 26
27 type rawPrepare struct { 27 type rawPrepare struct {
28 rs *rawSet 28 rs *rawSet
29 stmt *sql.Stmt 29 stmt stmtQuerier
30 closed bool 30 closed bool
31 } 31 }
32 32
...@@ -53,7 +53,11 @@ func newRawPreparer(rs *rawSet) (RawPreparer, error) { ...@@ -53,7 +53,11 @@ func newRawPreparer(rs *rawSet) (RawPreparer, error) {
53 if err != nil { 53 if err != nil {
54 return nil, err 54 return nil, err
55 } 55 }
56 o.stmt = st 56 if Debug {
57 o.stmt = newStmtQueryLog(rs.orm.alias, st, rs.query)
58 } else {
59 o.stmt = st
60 }
57 return o, nil 61 return o, nil
58 } 62 }
59 63
......
...@@ -94,6 +94,13 @@ type IFieldErrors interface { ...@@ -94,6 +94,13 @@ type IFieldErrors interface {
94 List() []IFieldError 94 List() []IFieldError
95 } 95 }
96 96
97 type stmtQuerier interface {
98 Close() error
99 Exec(args ...interface{}) (sql.Result, error)
100 Query(args ...interface{}) (*sql.Rows, error)
101 QueryRow(args ...interface{}) *sql.Row
102 }
103
97 type dbQuerier interface { 104 type dbQuerier interface {
98 Prepare(query string) (*sql.Stmt, error) 105 Prepare(query string) (*sql.Stmt, error)
99 Exec(query string, args ...interface{}) (sql.Result, error) 106 Exec(query string, args ...interface{}) (sql.Result, error)
...@@ -101,10 +108,19 @@ type dbQuerier interface { ...@@ -101,10 +108,19 @@ type dbQuerier interface {
101 QueryRow(query string, args ...interface{}) *sql.Row 108 QueryRow(query string, args ...interface{}) *sql.Row
102 } 109 }
103 110
111 type txer interface {
112 Begin() (*sql.Tx, error)
113 }
114
115 type txEnder interface {
116 Commit() error
117 Rollback() error
118 }
119
104 type dbBaser interface { 120 type dbBaser interface {
105 Read(dbQuerier, *modelInfo, reflect.Value) error 121 Read(dbQuerier, *modelInfo, reflect.Value) error
106 Insert(dbQuerier, *modelInfo, reflect.Value) (int64, error) 122 Insert(dbQuerier, *modelInfo, reflect.Value) (int64, error)
107 InsertStmt(*sql.Stmt, *modelInfo, reflect.Value) (int64, error) 123 InsertStmt(stmtQuerier, *modelInfo, reflect.Value) (int64, error)
108 Update(dbQuerier, *modelInfo, reflect.Value) (int64, error) 124 Update(dbQuerier, *modelInfo, reflect.Value) (int64, error)
109 Delete(dbQuerier, *modelInfo, reflect.Value) (int64, error) 125 Delete(dbQuerier, *modelInfo, reflect.Value) (int64, error)
110 ReadBatch(dbQuerier, *querySet, *modelInfo, *Condition, interface{}) (int64, error) 126 ReadBatch(dbQuerier, *querySet, *modelInfo, *Condition, interface{}) (int64, error)
...@@ -112,6 +128,6 @@ type dbBaser interface { ...@@ -112,6 +128,6 @@ type dbBaser interface {
112 DeleteBatch(dbQuerier, *querySet, *modelInfo, *Condition) (int64, error) 128 DeleteBatch(dbQuerier, *querySet, *modelInfo, *Condition) (int64, error)
113 Count(dbQuerier, *querySet, *modelInfo, *Condition) (int64, error) 129 Count(dbQuerier, *querySet, *modelInfo, *Condition) (int64, error)
114 GetOperatorSql(*modelInfo, string, []interface{}) (string, []interface{}) 130 GetOperatorSql(*modelInfo, string, []interface{}) (string, []interface{})
115 PrepareInsert(dbQuerier, *modelInfo) (*sql.Stmt, error) 131 PrepareInsert(dbQuerier, *modelInfo) (stmtQuerier, string, error)
116 ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}) (int64, error) 132 ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}) (int64, error)
117 } 133 }
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!