diff --git a/.gitignore b/.gitignore index b698bc6f..22486d5f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ temp_test.go .vscode xorm.test *.sqlite3 + +.idea/ diff --git a/README.md b/README.md index ffb6fc85..9f6c20cb 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,7 @@ has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist() ```Go var users []User err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users) -// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10 +// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0 type Detail struct { Id int64 @@ -234,7 +234,7 @@ err := engine.Table("user").Select("user.*, detail.*"). Join("INNER", "detail", "detail.user_id = user.id"). Where("user.name = ?", name).Limit(10, 0). Find(&users) -// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10 +// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0 ``` * `Iterate` and `Rows` query multiple records and record by record handle, there are two methods Iterate and Rows diff --git a/README_CN.md b/README_CN.md index 71b30c8e..b4258d54 100644 --- a/README_CN.md +++ b/README_CN.md @@ -224,7 +224,7 @@ has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist() ```Go var users []User err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users) -// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10 +// SELECT * FROM user WHERE name = ? AND age > 10 limit 10 offset 0 type Detail struct { Id int64 @@ -241,7 +241,7 @@ err := engine.Table("user").Select("user.*, detail.*") Join("INNER", "detail", "detail.user_id = user.id"). Where("user.name = ?", name).Limit(10, 0). Find(&users) -// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10 +// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0 ``` * `Iterate` 和 `Rows` 根据条件遍历数据库,可以有两种方式: Iterate and Rows diff --git a/session_exist.go b/session_exist.go index 049c1ddf..378a6483 100644 --- a/session_exist.go +++ b/session_exist.go @@ -10,6 +10,7 @@ import ( "reflect" "github.com/go-xorm/builder" + "github.com/go-xorm/core" ) // Exist returns true if the record exist otherwise return false @@ -35,10 +36,18 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) { return false, err } - sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL) + if session.engine.dialect.DBType() == core.MSSQL { + sqlStr = fmt.Sprintf("SELECT top 1 * FROM %s WHERE %s", tableName, condSQL) + } else { + sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL) + } args = condArgs } else { - sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName) + if session.engine.dialect.DBType() == core.MSSQL { + sqlStr = fmt.Sprintf("SELECT top 1 * FROM %s", tableName) + } else { + sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName) + } args = []interface{}{} } } else { diff --git a/session_query.go b/session_query.go index 5b4e0dc4..f8098f84 100644 --- a/session_query.go +++ b/session_query.go @@ -17,7 +17,17 @@ import ( func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) { if len(sqlorArgs) > 0 { - return sqlorArgs[0].(string), sqlorArgs[1:], nil + switch sqlorArgs[0].(type) { + case string: + return sqlorArgs[0].(string), sqlorArgs[1:], nil + case *builder.Builder: + return sqlorArgs[0].(*builder.Builder).ToSQL() + case builder.Builder: + bd := sqlorArgs[0].(builder.Builder) + return bd.ToSQL() + default: + return "", nil, ErrUnSupportedType + } } if session.statement.RawSQL != "" { diff --git a/session_query_test.go b/session_query_test.go index e84a7142..1e556453 100644 --- a/session_query_test.go +++ b/session_query_test.go @@ -10,6 +10,8 @@ import ( "testing" "time" + "github.com/go-xorm/builder" + "github.com/stretchr/testify/assert" ) @@ -183,3 +185,48 @@ func TestQueryNoParams(t *testing.T) { assert.NoError(t, err) assertResult(t, results) } + +func TestQueryWithBuilder(t *testing.T) { + assert.NoError(t, prepareEngine()) + + type QueryWithBuilder struct { + Id int64 `xorm:"autoincr pk"` + Msg string `xorm:"varchar(255)"` + Age int + Money float32 + Created time.Time `xorm:"created"` + } + + testEngine.ShowSQL(true) + + assert.NoError(t, testEngine.Sync2(new(QueryWithBuilder))) + + var q = QueryWithBuilder{ + Msg: "message", + Age: 20, + Money: 3000, + } + cnt, err := testEngine.Insert(&q) + assert.NoError(t, err) + assert.EqualValues(t, 1, cnt) + + assertResult := func(t *testing.T, results []map[string][]byte) { + assert.EqualValues(t, 1, len(results)) + id, err := strconv.ParseInt(string(results[0]["id"]), 10, 64) + assert.NoError(t, err) + assert.EqualValues(t, 1, id) + assert.Equal(t, "message", string(results[0]["msg"])) + + age, err := strconv.Atoi(string(results[0]["age"])) + assert.NoError(t, err) + assert.EqualValues(t, 20, age) + + money, err := strconv.ParseFloat(string(results[0]["money"]), 32) + assert.NoError(t, err) + assert.EqualValues(t, 3000, money) + } + + results, err := testEngine.Query(builder.Select("*").From("query_with_builder")) + assert.NoError(t, err) + assertResult(t, results) +} \ No newline at end of file