Skip to content

Commit b126964

Browse files
committed
Merge branch 'devel'
2 parents 6304965 + 81d3026 commit b126964

File tree

4 files changed

+102
-174
lines changed

4 files changed

+102
-174
lines changed

generator/templates/model.tgo

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,6 @@ func (s *{{.StoreName}}) DisableCacher() *{{.StoreName}} {
123123
return &{{.StoreName}}{s.Store.DisableCacher()}
124124
}
125125

126-
// DisableCacher turns on prepared statements. This is the default.
127-
func (s *{{.StoreName}}) EnableCacher() *{{.StoreName}} {
128-
return &{{.StoreName}}{s.Store.EnableCacher()}
129-
}
130-
131126
{{if .HasNonInverses}}
132127
func (s *{{.StoreName}}) relationshipRecords(record *{{.Name}}) []modelSaveFunc {
133128
var result []modelSaveFunc

store.go

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -64,62 +64,69 @@ func defaultLogger(message string, args ...interface{}) {
6464
log.Printf("%s, args: %v", message, args)
6565
}
6666

67-
// basicLogger is a database runner that logs all SQL statements executed.
68-
type basicLogger struct {
69-
logger LoggerFunc
70-
runner squirrel.BaseRunner
71-
}
72-
73-
// basicLogger is a database runner that logs all SQL statements executed.
67+
// runnerLogger is a database runner that logs all SQL statements executed.
7468
type proxyLogger struct {
75-
basicLogger
69+
squirrel.DBProxyContext
70+
logger LoggerFunc
7671
}
7772

78-
func (p *basicLogger) Exec(query string, args ...interface{}) (sql.Result, error) {
73+
func (p *proxyLogger) Exec(query string, args ...interface{}) (sql.Result, error) {
7974
p.logger(fmt.Sprintf("kallax: Exec: %s", query), args...)
80-
return p.runner.Exec(query, args...)
75+
return p.DBProxyContext.Exec(query, args...)
8176
}
8277

83-
func (p *basicLogger) Query(query string, args ...interface{}) (*sql.Rows, error) {
78+
func (p *proxyLogger) Query(query string, args ...interface{}) (*sql.Rows, error) {
8479
p.logger(fmt.Sprintf("kallax: Query: %s", query), args...)
85-
return p.runner.Query(query, args...)
80+
return p.DBProxyContext.Query(query, args...)
8681
}
8782

8883
func (p *proxyLogger) QueryRow(query string, args ...interface{}) squirrel.RowScanner {
89-
p.basicLogger.logger(fmt.Sprintf("kallax: QueryRow: %s", query), args...)
90-
if queryRower, ok := p.basicLogger.runner.(squirrel.QueryRower); ok {
91-
return queryRower.QueryRow(query, args...)
92-
} else {
93-
panic("Called proxyLogger with a runner which doesn't implement QueryRower")
94-
}
84+
p.logger(fmt.Sprintf("kallax: QueryRow: %s", query), args...)
85+
return p.DBProxyContext.QueryRow(query, args...)
9586
}
9687

9788
func (p *proxyLogger) Prepare(query string) (*sql.Stmt, error) {
98-
// If chained runner is a proxy, run Prepare(). Otherwise, noop.
99-
if preparer, ok := p.basicLogger.runner.(squirrel.Preparer); ok {
100-
p.basicLogger.logger(fmt.Sprintf("kallax: Prepare: %s", query))
101-
return preparer.Prepare(query)
102-
} else {
103-
panic("Called proxyLogger with a runner which doesn't implement QueryRower")
104-
}
89+
//If chained runner is a proxy, run Prepare(). Otherwise, noop.
90+
p.logger(fmt.Sprintf("kallax: Prepare: %s", query))
91+
return p.DBProxyContext.Prepare(query)
92+
}
93+
94+
// PrepareContext will not be logged
95+
96+
// dbRunner is a copypaste from squirrel.dbRunner, used to make sql.DB implement squirrel.QueryRower.
97+
// squirrel will silently fail and return nil if BaseRunner(s) supplied to RunWith don't implement QueryRower, so
98+
// it has been copied there to avoid that.
99+
// TODO: Delete this when squirrel dependency is dropped.
100+
type dbRunner struct {
101+
*sql.DB
102+
}
103+
104+
func (r *dbRunner) QueryRow(query string, args ...interface{}) squirrel.RowScanner {
105+
return r.DB.QueryRow(query, args...)
106+
}
107+
108+
// txRunner does the analogous for sql.Tx
109+
type txRunner struct {
110+
*sql.Tx
111+
}
112+
113+
func (r *txRunner) QueryRow(query string, args ...interface{}) squirrel.RowScanner {
114+
return r.Tx.QueryRow(query, args...)
105115
}
106116

107117
// Store is a structure capable of retrieving records from a concrete table in
108118
// the database.
109119
type Store struct {
110-
db interface {
111-
squirrel.BaseRunner
112-
squirrel.PreparerContext
113-
}
114-
runner squirrel.BaseRunner
120+
db squirrel.DBProxyContext
121+
runner squirrel.DBProxyContext
115122
useCacher bool
116123
logger LoggerFunc
117124
}
118125

119126
// NewStore returns a new Store instance.
120127
func NewStore(db *sql.DB) *Store {
121128
return (&Store{
122-
db: db,
129+
db: &dbRunner{db},
123130
useCacher: true,
124131
}).init()
125132
}
@@ -132,12 +139,8 @@ func (s *Store) init() *Store {
132139
s.runner = squirrel.NewStmtCacher(s.db)
133140
}
134141

135-
if s.logger != nil && !s.useCacher {
136-
// Use BasicLogger as wrapper
137-
s.runner = &basicLogger{s.logger, s.runner}
138-
} else if s.logger != nil && s.useCacher {
139-
// We're using a proxy (cacher), so use proxyLogger instead
140-
s.runner = &proxyLogger{basicLogger{s.logger, s.runner}}
142+
if s.logger != nil {
143+
s.runner = &proxyLogger{logger: s.logger, DBProxyContext: s.runner}
141144
}
142145

143146
return s
@@ -159,7 +162,7 @@ func (s *Store) DebugWith(logger LoggerFunc) *Store {
159162
}).init()
160163
}
161164

162-
// DisableCacher turns off prepared statements, which can be useful in some scenarios.
165+
// DisableCacher returns a new store with prepared statements turned off, which can be useful in some scenarios.
163166
func (s *Store) DisableCacher() *Store {
164167
return (&Store{
165168
db: s.db,
@@ -168,15 +171,6 @@ func (s *Store) DisableCacher() *Store {
168171
}).init()
169172
}
170173

171-
// EnableCacher turns on prepared statements. This is the default.
172-
func (s *Store) EnableCacher() *Store {
173-
return (&Store{
174-
db: s.db,
175-
logger: s.logger,
176-
useCacher: true,
177-
}).init()
178-
}
179-
180174
// Insert insert the given record in the table, returns error if no-new
181175
// record is given. The record id is set if it's empty.
182176
func (s *Store) Insert(schema Schema, record Record) error {
@@ -478,7 +472,7 @@ func (s *Store) MustCount(q Query) int64 {
478472
func (s *Store) Transaction(callback func(*Store) error) error {
479473
var tx *sql.Tx
480474
var err error
481-
if db, ok := s.db.(*sql.DB); ok {
475+
if db, ok := s.db.(*dbRunner); ok {
482476
// db is *sql.DB, not *sql.Tx
483477
tx, err = db.Begin()
484478
if err != nil {
@@ -490,7 +484,7 @@ func (s *Store) Transaction(callback func(*Store) error) error {
490484
}
491485

492486
txStore := (&Store{
493-
db: tx,
487+
db: &txRunner{tx},
494488
logger: s.logger,
495489
useCacher: s.useCacher,
496490
}).init()

0 commit comments

Comments
 (0)