diff --git a/README.md b/README.md index 2443e4ef..909dd06b 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ Xorm is a simple and powerful ORM for Go. * Postgres schema support +* Context Get Cache + ## Drivers Support Drivers for Go's sql package which currently support database/sql includes: @@ -358,6 +360,33 @@ if _, err := session.Exec("delete from userinfo where username = ?", user2.Usern return session.Commit() ``` +* Context Cache, if enabled, current query result will be cached on session and be used by next same statement on the same session. + +```Go + sess := engine.NewSession() + defer sess.Close() + + var c2 ContextGetStruct + has, err := sess.ID(1).ContextCache().Get(&c2) + assert.NoError(t, err) + assert.True(t, has) + assert.EqualValues(t, 1, c2.Id) + assert.EqualValues(t, "1", c2.Name) + sql, args := sess.LastSQL() + assert.True(t, len(sql) > 0) + assert.True(t, len(args) > 0) + + var c3 ContextGetStruct + has, err = sess.ID(1).Get(&c3) + assert.NoError(t, err) + assert.True(t, has) + assert.EqualValues(t, 1, c3.Id) + assert.EqualValues(t, "1", c3.Name) + sql, args = sess.LastSQL() + assert.True(t, len(sql) == 0) + assert.True(t, len(args) == 0) +``` + ## Contributing If you want to pull request, please see [CONTRIBUTING](https://github.com/go-xorm/xorm/blob/master/CONTRIBUTING.md). And we also provide [Xorm on Google Groups](https://groups.google.com/forum/#!forum/xorm) to discuss. diff --git a/context.go b/context.go index 1ca3664f..074ba35a 100644 --- a/context.go +++ b/context.go @@ -24,14 +24,3 @@ func (session *Session) PingContext(ctx context.Context) error { session.engine.logger.Infof("PING DATABASE %v", session.engine.DriverName()) return session.DB().PingContext(ctx) } - -// WithContext cooperate with ctx -func (session *Session) WithContext(ctx context.Context) *Session { - session.context = ctx - return session -} - -// WithContext cooperate session with ctx -func WithContext(sess *Session, ctx context.Context) *Session { - return sess.WithContext(ctx) -} diff --git a/session.go b/session.go index fcfcbbdf..0c6813d3 100644 --- a/session.go +++ b/session.go @@ -84,11 +84,7 @@ func (session *Session) Init() { session.lastSQL = "" session.lastSQLArgs = []interface{}{} - if session.engine.enableContextCache { - session.context = context.Background() - } else { - session.context = nil - } + session.context = nil } // Close release the connection from pool @@ -109,6 +105,16 @@ func (session *Session) Close() { } } +// ContextCache enable context cache or not +func (session *Session) ContextCache(enabled ...bool) *Session { + if len(enabled) > 0 { + session.statement.enableContextCache = enabled[0] + } else { + session.statement.enableContextCache = true + } + return session +} + // IsClosed returns if session is closed func (session *Session) IsClosed() bool { return session.db == nil diff --git a/session_get.go b/session_get.go index 1107f097..b8a959e1 100644 --- a/session_get.go +++ b/session_get.go @@ -83,7 +83,10 @@ func (session *Session) get(bean interface{}) (bool, error) { if err != nil || !has { return has, err } - if session.context != nil { + if session.statement.enableContextCache { + if session.context == nil { + session.context = context.Background() + } session.context = context.WithValue(session.context, fmt.Sprintf("%v-%v", sqlStr, args), bean) } diff --git a/session_get_test.go b/session_get_test.go index dacb3d06..3e7b47b5 100644 --- a/session_get_test.go +++ b/session_get_test.go @@ -5,7 +5,6 @@ package xorm import ( - "context" "database/sql" "fmt" "testing" @@ -333,11 +332,11 @@ func TestContextGet(t *testing.T) { _, err := testEngine.Insert(&ContextGetStruct{Name: "1"}) assert.NoError(t, err) - sess := WithContext(testEngine.NewSession(), context.Background()) + sess := testEngine.NewSession() defer sess.Close() var c2 ContextGetStruct - has, err := sess.ID(1).Get(&c2) + has, err := sess.ID(1).ContextCache().Get(&c2) assert.NoError(t, err) assert.True(t, has) assert.EqualValues(t, 1, c2.Id) diff --git a/statement.go b/statement.go index 56644036..47714de1 100644 --- a/statement.go +++ b/statement.go @@ -19,46 +19,47 @@ import ( // Statement save all the sql info for executing SQL type Statement struct { - RefTable *core.Table - Engine *Engine - Start int - LimitN int - idParam *core.PK - OrderStr string - JoinStr string - joinArgs []interface{} - GroupByStr string - HavingStr string - ColumnStr string - selectStr string - useAllCols bool - OmitStr string - AltTableName string - tableName string - RawSQL string - RawParams []interface{} - UseCascade bool - UseAutoJoin bool - StoreEngine string - Charset string - UseCache bool - UseAutoTime bool - noAutoCondition bool - IsDistinct bool - IsForUpdate bool - TableAlias string - allUseBool bool - checkVersion bool - unscoped bool - columnMap columnMap - omitColumnMap columnMap - mustColumnMap map[string]bool - nullableMap map[string]bool - incrColumns map[string]incrParam - decrColumns map[string]decrParam - exprColumns map[string]exprParam - cond builder.Cond - bufferSize int + RefTable *core.Table + Engine *Engine + Start int + LimitN int + idParam *core.PK + OrderStr string + JoinStr string + joinArgs []interface{} + GroupByStr string + HavingStr string + ColumnStr string + selectStr string + useAllCols bool + OmitStr string + AltTableName string + tableName string + RawSQL string + RawParams []interface{} + UseCascade bool + UseAutoJoin bool + StoreEngine string + Charset string + UseCache bool + UseAutoTime bool + noAutoCondition bool + IsDistinct bool + IsForUpdate bool + TableAlias string + allUseBool bool + checkVersion bool + unscoped bool + columnMap columnMap + omitColumnMap columnMap + mustColumnMap map[string]bool + nullableMap map[string]bool + incrColumns map[string]incrParam + decrColumns map[string]decrParam + exprColumns map[string]exprParam + cond builder.Cond + bufferSize int + enableContextCache bool } // Init reset all the statement's fields