From 475ba3db3e23d3675dba047328e9e8df1d7308d5 Mon Sep 17 00:00:00 2001 From: Ian Tan Date: Sat, 18 Nov 2017 19:06:00 +0800 Subject: [PATCH] Proof of concept using DB.logger --- expecter.go | 113 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 87 insertions(+), 26 deletions(-) diff --git a/expecter.go b/expecter.go index d95b203e..a6bb3578 100644 --- a/expecter.go +++ b/expecter.go @@ -1,22 +1,84 @@ package gorm import ( + "database/sql" + "errors" "fmt" ) +type Recorder struct { + stmt string +} + +func (r *Recorder) Print(args ...interface{}) { + msgs := LogFormatter(args...) + if len(msgs) >= 4 { + if v, ok := msgs[3].(string); ok { + r.stmt = v + } + // for i, msg := range msgs { + // switch v := msg.(type) { + // case string: + // case []byte: + // r.buf.Read([]byte(v)) + // default: + // return + // } + // } + } +} + // AdapterFactory is a generic interface for arbitrary adapters that satisfy // the interface. variadic args are passed to gorm.Open. type AdapterFactory func(dialect string, args ...interface{}) (*DB, Adapter, error) // Expecter is the exported struct used for setting expectations type Expecter struct { - Value interface{} - adapter Adapter - search *search - values map[string]interface{} - // globally scoped expecter - root *Expecter + adapter Adapter + noop NoopDB + gorm *DB + recorder *Recorder +} + +type NoopDB interface { + GetStmts() []string +} + +type DefaultNoopDB struct{} + +type NoopResult struct{} + +func (r NoopResult) LastInsertId() (int64, error) { + return 1, nil +} + +func (r NoopResult) RowsAffected() (int64, error) { + return 1, nil +} + +func NewNoopDB() NoopDB { + return &DefaultNoopDB{} +} + +func (r *DefaultNoopDB) Exec(query string, args ...interface{}) (sql.Result, error) { + return NoopResult{}, nil +} + +func (r *DefaultNoopDB) Prepare(query string) (*sql.Stmt, error) { + return &sql.Stmt{}, nil +} + +func (r *DefaultNoopDB) Query(query string, args ...interface{}) (*sql.Rows, error) { + return nil, errors.New("noop") +} + +func (r *DefaultNoopDB) QueryRow(query string, args ...interface{}) *sql.Row { + return &sql.Row{} +} + +func (r *DefaultNoopDB) GetStmts() []string { + return []string{"not", "implemented"} } // NewDefaultExpecter returns a Expecter powered by go-sqlmock @@ -27,7 +89,21 @@ func NewDefaultExpecter() (*DB, *Expecter, error) { return nil, nil, err } - return gormDb, &Expecter{adapter: adapter}, nil + recorder := &Recorder{} + noop := &DefaultNoopDB{} + + gorm := &DB{ + db: noop, + logger: recorder, + logMode: 2, + values: map[string]interface{}{}, + callbacks: DefaultCallback, + dialect: newDialect("sqlmock", noop), + } + + gorm.parent = gorm + + return gormDb, &Expecter{adapter: adapter, noop: noop, gorm: gorm, recorder: recorder}, nil } // NewExpecter returns an Expecter for arbitrary adapters @@ -44,28 +120,13 @@ func NewExpecter(fn AdapterFactory, dialect string, args ...interface{}) (*DB, * /* PUBLIC METHODS */ // First triggers a Query -func (h *Expecter) First(model interface{}) ExpectedQuery { - fmt.Printf("Expecting query: %s", "some query\n") - return h.adapter.ExpectQuery("some sql") +func (h *Expecter) First(out interface{}, where ...interface{}) ExpectedQuery { + h.gorm.First(out, where) + return h.adapter.ExpectQuery(h.recorder.stmt) } // Find triggers a Query -func (h *Expecter) Find(model interface{}) ExpectedQuery { +func (h *Expecter) Find(out interface{}, where ...interface{}) ExpectedQuery { fmt.Printf("Expecting query: %s\n", "some query involving Find") return h.adapter.ExpectQuery("some find condition") } - -/* PRIVATE METHODS */ - -// clone is similar to DB.clone, and ensures that the root Expecter is not -// polluted with subsequent search constraints -func (h *Expecter) clone() *Expecter { - expecterCopy := &Expecter{ - adapter: h.adapter, - root: h.root, - values: map[string]interface{}{}, - Value: h.Value, - } - - return expecterCopy -}