v0.1.2 Insert function now supports both struct and slice pointer parameters, batch inserting and auto transaction
This commit is contained in:
parent
8c81e70188
commit
a2ebf21969
47
README.md
47
README.md
|
@ -16,6 +16,7 @@ Drivers for Go's sql package which currently support database/sql includes:
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
* **v0.1.2** : Insert function now supports both struct and slice pointer parameters, batch inserting and auto transaction
|
||||||
* **v0.1.1** : Add Id, In functions and improved README
|
* **v0.1.1** : Add Id, In functions and improved README
|
||||||
* **v0.1.0** : Inital release.
|
* **v0.1.0** : Inital release.
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ Drivers for Go's sql package which currently support database/sql includes:
|
||||||
|
|
||||||
1.Create a database engine just like sql.Open, commonly you just need create once.
|
1.Create a database engine just like sql.Open, commonly you just need create once.
|
||||||
|
|
||||||
```
|
```Go
|
||||||
import (
|
import (
|
||||||
_ "github.com/Go-SQL-Driver/MySQL"
|
_ "github.com/Go-SQL-Driver/MySQL"
|
||||||
"github.com/lunny/xorm"
|
"github.com/lunny/xorm"
|
||||||
|
@ -49,7 +50,7 @@ engine := xorm.Create("mysql", "root:123@/test?charset=utf8")
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
```
|
```Go
|
||||||
import (
|
import (
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
"github.com/lunny/xorm"
|
"github.com/lunny/xorm"
|
||||||
|
@ -59,13 +60,13 @@ engine = xorm.Create("sqlite3", "./test.db")
|
||||||
|
|
||||||
1.1.If you want to show all generated SQL
|
1.1.If you want to show all generated SQL
|
||||||
|
|
||||||
```
|
```Go
|
||||||
engine.ShowSQL = true
|
engine.ShowSQL = true
|
||||||
```
|
```
|
||||||
|
|
||||||
2.Define a struct
|
2.Define a struct
|
||||||
|
|
||||||
```
|
```Go
|
||||||
type User struct {
|
type User struct {
|
||||||
Id int
|
Id int
|
||||||
Name string
|
Name string
|
||||||
|
@ -77,7 +78,7 @@ type User struct {
|
||||||
|
|
||||||
3.When you set up your program, you can use CreateTables to create database tables.
|
3.When you set up your program, you can use CreateTables to create database tables.
|
||||||
|
|
||||||
```
|
```Go
|
||||||
err := engine.CreateTables(&User{})
|
err := engine.CreateTables(&User{})
|
||||||
// or err := engine.Map(&User{}, &Article{})
|
// or err := engine.Map(&User{}, &Article{})
|
||||||
// err = engine.CreateAll()
|
// err = engine.CreateAll()
|
||||||
|
@ -85,13 +86,13 @@ err := engine.CreateTables(&User{})
|
||||||
|
|
||||||
4.then, insert an struct to table
|
4.then, insert an struct to table
|
||||||
|
|
||||||
```
|
```Go
|
||||||
id, err := engine.Insert(&User{Name:"lunny"})
|
id, err := engine.Insert(&User{Name:"lunny"})
|
||||||
```
|
```
|
||||||
|
|
||||||
or if you want to update records
|
or if you want to update records
|
||||||
|
|
||||||
```
|
```Go
|
||||||
user := User{Name:"xlw"}
|
user := User{Name:"xlw"}
|
||||||
rows, err := engine.Update(&user, &User{Id:1})
|
rows, err := engine.Update(&user, &User{Id:1})
|
||||||
// or rows, err := engine.Where("id = ?", 1).Update(&user)
|
// or rows, err := engine.Where("id = ?", 1).Update(&user)
|
||||||
|
@ -100,7 +101,7 @@ rows, err := engine.Update(&user, &User{Id:1})
|
||||||
|
|
||||||
5.Fetch a single object by user
|
5.Fetch a single object by user
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var user = User{Id:27}
|
var user = User{Id:27}
|
||||||
err := engine.Get(&user)
|
err := engine.Get(&user)
|
||||||
// or err := engine.Id(27).Get(&user)
|
// or err := engine.Id(27).Get(&user)
|
||||||
|
@ -111,42 +112,42 @@ err := engine.Get(&user)
|
||||||
|
|
||||||
6.Fetch multipe objects, use Find:
|
6.Fetch multipe objects, use Find:
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var everyone []Userinfo
|
var everyone []Userinfo
|
||||||
err := engine.Find(&everyone)
|
err := engine.Find(&everyone)
|
||||||
```
|
```
|
||||||
|
|
||||||
6.1 also you can use Where, Limit
|
6.1 also you can use Where, Limit
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var allusers []Userinfo
|
var allusers []Userinfo
|
||||||
err := engine.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
|
err := engine.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
|
||||||
```
|
```
|
||||||
|
|
||||||
6.2 or you can use a struct query
|
6.2 or you can use a struct query
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var tenusers []Userinfo
|
var tenusers []Userinfo
|
||||||
err := engine.Limit(10).Find(&tenusers, &Userinfo{Name:"xlw"}) //Get All Name="xlw" limit 10 offset 0
|
err := engine.Limit(10).Find(&tenusers, &Userinfo{Name:"xlw"}) //Get All Name="xlw" limit 10 offset 0
|
||||||
```
|
```
|
||||||
|
|
||||||
6.3 or In function
|
6.3 or In function
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var tenusers []Userinfo
|
var tenusers []Userinfo
|
||||||
err := engine.In("id", 1, 3, 5).Find(&tenusers) //Get All id in (1, 3, 5)
|
err := engine.In("id", 1, 3, 5).Find(&tenusers) //Get All id in (1, 3, 5)
|
||||||
```
|
```
|
||||||
|
|
||||||
7.Delete
|
7.Delete
|
||||||
|
|
||||||
```
|
```Go
|
||||||
err := engine.Delete(&User{Id:1})
|
err := engine.Delete(&User{Id:1})
|
||||||
// or err := engine.Id(1).Delete(&User{})
|
// or err := engine.Id(1).Delete(&User{})
|
||||||
```
|
```
|
||||||
|
|
||||||
8.Count
|
8.Count
|
||||||
|
|
||||||
```
|
```Go
|
||||||
total, err := engine.Count(&User{Name:"xlw"})
|
total, err := engine.Count(&User{Name:"xlw"})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -155,14 +156,14 @@ Of course, SQL execution is also provided.
|
||||||
|
|
||||||
1.if select then use Query
|
1.if select then use Query
|
||||||
|
|
||||||
```
|
```Go
|
||||||
sql := "select * from userinfo"
|
sql := "select * from userinfo"
|
||||||
results, err := engine.Query(sql)
|
results, err := engine.Query(sql)
|
||||||
```
|
```
|
||||||
|
|
||||||
2.if insert, update or delete then use Exec
|
2.if insert, update or delete then use Exec
|
||||||
|
|
||||||
```
|
```Go
|
||||||
sql = "update userinfo set username=? where id=?"
|
sql = "update userinfo set username=? where id=?"
|
||||||
res, err := engine.Exec(sql, "xiaolun", 1)
|
res, err := engine.Exec(sql, "xiaolun", 1)
|
||||||
```
|
```
|
||||||
|
@ -170,7 +171,7 @@ res, err := engine.Exec(sql, "xiaolun", 1)
|
||||||
##Advanced Usage
|
##Advanced Usage
|
||||||
for deep usage, you should create a session, this func will create a database connection immediatelly
|
for deep usage, you should create a session, this func will create a database connection immediatelly
|
||||||
|
|
||||||
```
|
```Go
|
||||||
session, err := engine.MakeSession()
|
session, err := engine.MakeSession()
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -180,7 +181,7 @@ if err != nil {
|
||||||
|
|
||||||
1.Fetch a single object by where
|
1.Fetch a single object by where
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var user Userinfo
|
var user Userinfo
|
||||||
session.Where("id=?", 27).Get(&user)
|
session.Where("id=?", 27).Get(&user)
|
||||||
|
|
||||||
|
@ -193,7 +194,7 @@ session.Where("name = ? and age < ?", "john", 88).Get(&user4) // even more compl
|
||||||
|
|
||||||
2.Fetch multiple objects
|
2.Fetch multiple objects
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var allusers []Userinfo
|
var allusers []Userinfo
|
||||||
err := session.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
|
err := session.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
|
||||||
|
|
||||||
|
@ -206,7 +207,7 @@ err := session.Find(&everyone)
|
||||||
|
|
||||||
3.Transaction
|
3.Transaction
|
||||||
|
|
||||||
```
|
```Go
|
||||||
// add Begin() before any action
|
// add Begin() before any action
|
||||||
session.Begin()
|
session.Begin()
|
||||||
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
||||||
|
@ -237,7 +238,7 @@ if err != nil {
|
||||||
|
|
||||||
4.Mixed Transaction
|
4.Mixed Transaction
|
||||||
|
|
||||||
```
|
```Go
|
||||||
// add Begin() before any action
|
// add Begin() before any action
|
||||||
session.Begin()
|
session.Begin()
|
||||||
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
||||||
|
@ -304,7 +305,7 @@ Another is use field tag, field tag support the below keywords which split with
|
||||||
|
|
||||||
For Example
|
For Example
|
||||||
|
|
||||||
```
|
```Go
|
||||||
type Userinfo struct {
|
type Userinfo struct {
|
||||||
Uid int `xorm:"id pk not null autoincr"`
|
Uid int `xorm:"id pk not null autoincr"`
|
||||||
Username string
|
Username string
|
||||||
|
@ -321,7 +322,7 @@ Please visit [GoWalker](http://gowalker.org/github.com/lunny/xorm)
|
||||||
|
|
||||||
Use space.
|
Use space.
|
||||||
|
|
||||||
```
|
```Go
|
||||||
type User struct {
|
type User struct {
|
||||||
Name string `json:"name" xorm:"name"`
|
Name string `json:"name" xorm:"name"`
|
||||||
}
|
}
|
||||||
|
|
47
README_CN.md
47
README_CN.md
|
@ -14,6 +14,7 @@ xorm是一个Go语言的ORM库. 通过它可以使数据库操作非常简便。
|
||||||
|
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
* **v0.1.2** : Insert函数支持混合struct和slice指针传入,并根据数据库类型自动批量插入,同时自动添加事务
|
||||||
* **v0.1.1** : 添加 Id, In 函数,改善 README 文档
|
* **v0.1.1** : 添加 Id, In 函数,改善 README 文档
|
||||||
* **v0.1.0** : 初始化工程
|
* **v0.1.0** : 初始化工程
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ xorm是一个Go语言的ORM库. 通过它可以使数据库操作非常简便。
|
||||||
|
|
||||||
1.创建数据库引擎,这个函数的参数和sql.Open相同,但不会立即创建连接 (例如: mysql)
|
1.创建数据库引擎,这个函数的参数和sql.Open相同,但不会立即创建连接 (例如: mysql)
|
||||||
|
|
||||||
```
|
```Go
|
||||||
import (
|
import (
|
||||||
_ "github.com/Go-SQL-Driver/MySQL"
|
_ "github.com/Go-SQL-Driver/MySQL"
|
||||||
"github.com/lunny/xorm"
|
"github.com/lunny/xorm"
|
||||||
|
@ -46,7 +47,7 @@ engine := xorm.Create("mysql", "root:123@/test?charset=utf8")
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
```
|
```Go
|
||||||
import (
|
import (
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
"github.com/lunny/xorm"
|
"github.com/lunny/xorm"
|
||||||
|
@ -56,13 +57,13 @@ engine = xorm.Create("sqlite3", "./test.db")
|
||||||
|
|
||||||
1.1.默认将不会显示自动生成的SQL语句,如果要显示,则需要设置
|
1.1.默认将不会显示自动生成的SQL语句,如果要显示,则需要设置
|
||||||
|
|
||||||
```
|
```Go
|
||||||
engine.ShowSQL = true
|
engine.ShowSQL = true
|
||||||
```
|
```
|
||||||
|
|
||||||
2.所有的ORM操作都针对一个或多个结构体,一个结构体对应一张表,定义一个结构体如下:
|
2.所有的ORM操作都针对一个或多个结构体,一个结构体对应一张表,定义一个结构体如下:
|
||||||
|
|
||||||
```
|
```Go
|
||||||
type User struct {
|
type User struct {
|
||||||
Id int
|
Id int
|
||||||
Name string
|
Name string
|
||||||
|
@ -74,19 +75,19 @@ type User struct {
|
||||||
|
|
||||||
3.在程序初始化时,可能会需要创建表
|
3.在程序初始化时,可能会需要创建表
|
||||||
|
|
||||||
```
|
```Go
|
||||||
err := engine.CreateTables(&User{})
|
err := engine.CreateTables(&User{})
|
||||||
```
|
```
|
||||||
|
|
||||||
4.然后,可以将一个结构体作为一条记录插入到表中。
|
4.然后,可以将一个结构体作为一条记录插入到表中。
|
||||||
|
|
||||||
```
|
```Go
|
||||||
id, err := engine.Insert(&User{Name:"lunny"})
|
id, err := engine.Insert(&User{Name:"lunny"})
|
||||||
```
|
```
|
||||||
|
|
||||||
或者执行更新操作:
|
或者执行更新操作:
|
||||||
|
|
||||||
```
|
```Go
|
||||||
user := User{Name:"xlw"}
|
user := User{Name:"xlw"}
|
||||||
rows, err := engine.Update(&user, &User{Id:1})
|
rows, err := engine.Update(&user, &User{Id:1})
|
||||||
// rows, err := engine.Where("id = ?", 1).Update(&user)
|
// rows, err := engine.Where("id = ?", 1).Update(&user)
|
||||||
|
@ -95,7 +96,7 @@ rows, err := engine.Update(&user, &User{Id:1})
|
||||||
|
|
||||||
5.获取单个对象,可以用Get方法:
|
5.获取单个对象,可以用Get方法:
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var user = User{Id:27}
|
var user = User{Id:27}
|
||||||
err := engine.Get(&user)
|
err := engine.Get(&user)
|
||||||
// or err := engine.Id(27).Get(&user)
|
// or err := engine.Id(27).Get(&user)
|
||||||
|
@ -105,42 +106,42 @@ err := engine.Get(&user)
|
||||||
|
|
||||||
6.获取多个对象,可以用Find方法:
|
6.获取多个对象,可以用Find方法:
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var everyone []Userinfo
|
var everyone []Userinfo
|
||||||
err := engine.Find(&everyone)
|
err := engine.Find(&everyone)
|
||||||
```
|
```
|
||||||
|
|
||||||
6.1 你也可以使用Where和Limit方法设定条件和查询数量
|
6.1 你也可以使用Where和Limit方法设定条件和查询数量
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var allusers []Userinfo
|
var allusers []Userinfo
|
||||||
err := engine.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
|
err := engine.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
|
||||||
```
|
```
|
||||||
|
|
||||||
6.2 用一个结构体作为查询条件也是允许的
|
6.2 用一个结构体作为查询条件也是允许的
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var tenusers []Userinfo
|
var tenusers []Userinfo
|
||||||
err := engine.Limit(10).Find(&tenusers, &Userinfo{Name:"xlw"}) //Get All Name="xlw" limit 10 offset 0
|
err := engine.Limit(10).Find(&tenusers, &Userinfo{Name:"xlw"}) //Get All Name="xlw" limit 10 offset 0
|
||||||
```
|
```
|
||||||
|
|
||||||
6.3 也可以调用In函数
|
6.3 也可以调用In函数
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var tenusers []Userinfo
|
var tenusers []Userinfo
|
||||||
err := engine.In("id", 1, 3, 5).Find(&tenusers) //Get All id in (1, 3, 5)
|
err := engine.In("id", 1, 3, 5).Find(&tenusers) //Get All id in (1, 3, 5)
|
||||||
```
|
```
|
||||||
|
|
||||||
7.Delete方法
|
7.Delete方法
|
||||||
|
|
||||||
```
|
```Go
|
||||||
err := engine.Delete(&User{Id:1})
|
err := engine.Delete(&User{Id:1})
|
||||||
// or err := engine.Id(1).Delete(&User{})
|
// or err := engine.Id(1).Delete(&User{})
|
||||||
```
|
```
|
||||||
|
|
||||||
8.Count方法
|
8.Count方法
|
||||||
|
|
||||||
```
|
```Go
|
||||||
total, err := engine.Count(&User{Name:"xlw"})
|
total, err := engine.Count(&User{Name:"xlw"})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -149,14 +150,14 @@ total, err := engine.Count(&User{Name:"xlw"})
|
||||||
|
|
||||||
如果执行Select,请用Query()
|
如果执行Select,请用Query()
|
||||||
|
|
||||||
```
|
```Go
|
||||||
sql := "select * from userinfo"
|
sql := "select * from userinfo"
|
||||||
results, err := engine.Query(sql)
|
results, err := engine.Query(sql)
|
||||||
```
|
```
|
||||||
|
|
||||||
如果执行Insert, Update, Delete 等操作,请用Exec()
|
如果执行Insert, Update, Delete 等操作,请用Exec()
|
||||||
|
|
||||||
```
|
```Go
|
||||||
sql = "update userinfo set username=? where id=?"
|
sql = "update userinfo set username=? where id=?"
|
||||||
res, err := engine.Exec(sql, "xiaolun", 1)
|
res, err := engine.Exec(sql, "xiaolun", 1)
|
||||||
```
|
```
|
||||||
|
@ -165,7 +166,7 @@ res, err := engine.Exec(sql, "xiaolun", 1)
|
||||||
<a name="mapping" id="mapping"></a>
|
<a name="mapping" id="mapping"></a>
|
||||||
更高级的用法,我们必须要使用session对象,session对象在创建时会立刻创建一个数据库连接。
|
更高级的用法,我们必须要使用session对象,session对象在创建时会立刻创建一个数据库连接。
|
||||||
|
|
||||||
```
|
```Go
|
||||||
session, err := engine.MakeSession()
|
session, err := engine.MakeSession()
|
||||||
defer session.Close()
|
defer session.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -175,7 +176,7 @@ if err != nil {
|
||||||
|
|
||||||
1.session对象同样也可以查询
|
1.session对象同样也可以查询
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var user Userinfo
|
var user Userinfo
|
||||||
session.Where("id=?", 27).Get(&user)
|
session.Where("id=?", 27).Get(&user)
|
||||||
|
|
||||||
|
@ -188,7 +189,7 @@ session.Where("name = ? and age < ?", "john", 88).Get(&user4) // even more compl
|
||||||
|
|
||||||
2.获取多个对象
|
2.获取多个对象
|
||||||
|
|
||||||
```
|
```Go
|
||||||
var allusers []Userinfo
|
var allusers []Userinfo
|
||||||
err := session.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
|
err := session.Where("id > ?", "3").Limit(10,20).Find(&allusers) //Get id>3 limit 10 offset 20
|
||||||
|
|
||||||
|
@ -201,7 +202,7 @@ err := session.Find(&everyone)
|
||||||
|
|
||||||
3.事务处理
|
3.事务处理
|
||||||
|
|
||||||
```
|
```Go
|
||||||
// add Begin() before any action
|
// add Begin() before any action
|
||||||
session.Begin()
|
session.Begin()
|
||||||
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
||||||
|
@ -232,7 +233,7 @@ if err != nil {
|
||||||
|
|
||||||
4.混合型事务,这个事务中,既有直接的SQL语句,又有ORM方法:
|
4.混合型事务,这个事务中,既有直接的SQL语句,又有ORM方法:
|
||||||
|
|
||||||
```
|
```Go
|
||||||
// add Begin() before any action
|
// add Begin() before any action
|
||||||
session.Begin()
|
session.Begin()
|
||||||
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
||||||
|
@ -298,7 +299,7 @@ UserInfo中的成员UserName将会自动对应名为user_name的字段。
|
||||||
</table>
|
</table>
|
||||||
例如:
|
例如:
|
||||||
|
|
||||||
```
|
```Go
|
||||||
type Userinfo struct {
|
type Userinfo struct {
|
||||||
Uid int `xorm:"id pk not null autoincr"`
|
Uid int `xorm:"id pk not null autoincr"`
|
||||||
Username string
|
Username string
|
||||||
|
@ -316,7 +317,7 @@ type Userinfo struct {
|
||||||
|
|
||||||
答案:使用空格分开
|
答案:使用空格分开
|
||||||
|
|
||||||
```
|
```Go
|
||||||
type User struct {
|
type User struct {
|
||||||
Name string `json:"name" xorm:"name"`
|
Name string `json:"name" xorm:"name"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ type Engine struct {
|
||||||
Tables map[reflect.Type]Table
|
Tables map[reflect.Type]Table
|
||||||
AutoIncrement string
|
AutoIncrement string
|
||||||
ShowSQL bool
|
ShowSQL bool
|
||||||
|
InsertMany bool
|
||||||
QuoteIdentifier string
|
QuoteIdentifier string
|
||||||
Statement Statement
|
Statement Statement
|
||||||
}
|
}
|
||||||
|
|
113
session.go
113
session.go
|
@ -16,11 +16,13 @@ type Session struct {
|
||||||
Tx *sql.Tx
|
Tx *sql.Tx
|
||||||
Statement Statement
|
Statement Statement
|
||||||
IsAutoCommit bool
|
IsAutoCommit bool
|
||||||
|
IsCommitedOrRollbacked bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) Init() {
|
func (session *Session) Init() {
|
||||||
session.Statement = Statement{}
|
session.Statement = Statement{}
|
||||||
session.IsAutoCommit = true
|
session.IsAutoCommit = true
|
||||||
|
session.IsCommitedOrRollbacked = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) Close() {
|
func (session *Session) Close() {
|
||||||
|
@ -69,7 +71,9 @@ func (session *Session) Having(conditions string) *Session {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) Begin() error {
|
func (session *Session) Begin() error {
|
||||||
|
if session.IsAutoCommit {
|
||||||
session.IsAutoCommit = false
|
session.IsAutoCommit = false
|
||||||
|
session.IsCommitedOrRollbacked = false
|
||||||
tx, err := session.Db.Begin()
|
tx, err := session.Db.Begin()
|
||||||
session.Tx = tx
|
session.Tx = tx
|
||||||
if session.Engine.ShowSQL {
|
if session.Engine.ShowSQL {
|
||||||
|
@ -77,20 +81,30 @@ func (session *Session) Begin() error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (session *Session) Rollback() error {
|
func (session *Session) Rollback() error {
|
||||||
|
if !session.IsAutoCommit && !session.IsCommitedOrRollbacked {
|
||||||
if session.Engine.ShowSQL {
|
if session.Engine.ShowSQL {
|
||||||
fmt.Println("ROLL BACK")
|
fmt.Println("ROLL BACK")
|
||||||
}
|
}
|
||||||
|
session.IsCommitedOrRollbacked = true
|
||||||
return session.Tx.Rollback()
|
return session.Tx.Rollback()
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (session *Session) Commit() error {
|
func (session *Session) Commit() error {
|
||||||
|
if !session.IsAutoCommit && !session.IsCommitedOrRollbacked {
|
||||||
if session.Engine.ShowSQL {
|
if session.Engine.ShowSQL {
|
||||||
fmt.Println("COMMIT")
|
fmt.Println("COMMIT")
|
||||||
}
|
}
|
||||||
|
session.IsCommitedOrRollbacked = true
|
||||||
return session.Tx.Commit()
|
return session.Tx.Commit()
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]byte) error {
|
func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]byte) error {
|
||||||
dataStruct := reflect.Indirect(reflect.ValueOf(obj))
|
dataStruct := reflect.Indirect(reflect.ValueOf(obj))
|
||||||
|
@ -359,13 +373,108 @@ func (session *Session) Query(sql string, paramStr ...interface{}) (resultsSlice
|
||||||
|
|
||||||
func (session *Session) Insert(beans ...interface{}) (int64, error) {
|
func (session *Session) Insert(beans ...interface{}) (int64, error) {
|
||||||
var lastId int64 = -1
|
var lastId int64 = -1
|
||||||
|
var err error = nil
|
||||||
|
isInTransaction := !session.IsAutoCommit
|
||||||
|
|
||||||
|
if !isInTransaction {
|
||||||
|
session.Begin()
|
||||||
|
}
|
||||||
|
|
||||||
for _, bean := range beans {
|
for _, bean := range beans {
|
||||||
lastId, err := session.InsertOne(bean)
|
sliceValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||||
|
if sliceValue.Kind() == reflect.Slice {
|
||||||
|
if session.Engine.InsertMany {
|
||||||
|
lastId, err = session.InsertMulti(bean)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if !isInTransaction {
|
||||||
|
session.Rollback()
|
||||||
|
}
|
||||||
|
return lastId, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size := sliceValue.Len()
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
lastId, err = session.InsertOne(sliceValue.Index(i).Interface())
|
||||||
|
if err != nil {
|
||||||
|
if !isInTransaction {
|
||||||
|
session.Rollback()
|
||||||
|
}
|
||||||
return lastId, err
|
return lastId, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return lastId, nil
|
}
|
||||||
|
} else {
|
||||||
|
lastId, err = session.InsertOne(bean)
|
||||||
|
if err != nil {
|
||||||
|
if !isInTransaction {
|
||||||
|
session.Rollback()
|
||||||
|
}
|
||||||
|
return lastId, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !isInTransaction {
|
||||||
|
err = session.Commit()
|
||||||
|
}
|
||||||
|
return lastId, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *Session) InsertMulti(rowsSlicePtr interface{}) (int64, error) {
|
||||||
|
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
||||||
|
if sliceValue.Kind() != reflect.Slice {
|
||||||
|
return -1, errors.New("needs a pointer to a slice")
|
||||||
|
}
|
||||||
|
|
||||||
|
bean := sliceValue.Index(0).Interface()
|
||||||
|
sliceElementType := Type(bean)
|
||||||
|
|
||||||
|
table := session.Engine.Tables[sliceElementType]
|
||||||
|
session.Statement.Table = &table
|
||||||
|
|
||||||
|
size := sliceValue.Len()
|
||||||
|
|
||||||
|
colNames := make([]string, 0)
|
||||||
|
colMultiPlaces := make([]string, 0)
|
||||||
|
var args = make([]interface{}, 0)
|
||||||
|
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
elemValue := sliceValue.Index(i).Interface()
|
||||||
|
colPlaces := make([]string, 0)
|
||||||
|
|
||||||
|
for _, col := range table.Columns {
|
||||||
|
fieldValue := reflect.Indirect(reflect.ValueOf(elemValue)).FieldByName(col.FieldName)
|
||||||
|
val := fieldValue.Interface()
|
||||||
|
if col.IsAutoIncrement && fieldValue.Int() == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
args = append(args, val)
|
||||||
|
if i == 0 {
|
||||||
|
colNames = append(colNames, col.Name)
|
||||||
|
}
|
||||||
|
colPlaces = append(colPlaces, "?")
|
||||||
|
}
|
||||||
|
colMultiPlaces = append(colMultiPlaces, strings.Join(colPlaces, ", "))
|
||||||
|
}
|
||||||
|
|
||||||
|
statement := fmt.Sprintf("INSERT INTO %v%v%v (%v) VALUES (%v)",
|
||||||
|
session.Engine.QuoteIdentifier,
|
||||||
|
table.Name,
|
||||||
|
session.Engine.QuoteIdentifier,
|
||||||
|
strings.Join(colNames, ", "),
|
||||||
|
strings.Join(colMultiPlaces, "),("))
|
||||||
|
|
||||||
|
res, err := session.Exec(statement, args...)
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := res.LastInsertId()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) InsertOne(bean interface{}) (int64, error) {
|
func (session *Session) InsertOne(bean interface{}) (int64, error) {
|
||||||
|
|
1
xorm.go
1
xorm.go
|
@ -10,6 +10,7 @@ func Create(driverName string, dataSourceName string) Engine {
|
||||||
|
|
||||||
engine.Tables = make(map[reflect.Type]Table)
|
engine.Tables = make(map[reflect.Type]Table)
|
||||||
engine.Statement.Engine = &engine
|
engine.Statement.Engine = &engine
|
||||||
|
engine.InsertMany = true
|
||||||
if driverName == SQLITE {
|
if driverName == SQLITE {
|
||||||
engine.AutoIncrement = "AUTOINCREMENT"
|
engine.AutoIncrement = "AUTOINCREMENT"
|
||||||
} else {
|
} else {
|
||||||
|
|
36
xorm_test.go
36
xorm_test.go
|
@ -106,24 +106,33 @@ func insertAutoIncr(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func insertMulti(t *testing.T) {
|
func insertMulti(t *testing.T) {
|
||||||
user1 := Userinfo{Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()}
|
users := []*Userinfo{
|
||||||
user2 := Userinfo{Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()}
|
{Username: "xlw", Departname: "dev", Alias: "lunny2", Created: time.Now()},
|
||||||
_, err := engine.Insert(&user1, &user2)
|
{Username: "xlw2", Departname: "dev", Alias: "lunny3", Created: time.Now()},
|
||||||
|
}
|
||||||
|
_, err := engine.Insert(&users)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
engine.InsertMany = false
|
||||||
|
|
||||||
|
users = []*Userinfo{
|
||||||
|
{Username: "xlw9", Departname: "dev", Alias: "lunny9", Created: time.Now()},
|
||||||
|
{Username: "xlw10", Departname: "dev", Alias: "lunny10", Created: time.Now()},
|
||||||
|
}
|
||||||
|
_, err = engine.Insert(&users)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.InsertMany = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func insertTwoTable(t *testing.T) {
|
func insertTwoTable(t *testing.T) {
|
||||||
userinfo := Userinfo{Username: "xlw3", Departname: "dev", Alias: "lunny4", Created: time.Now()}
|
userinfo := Userinfo{Username: "xlw3", Departname: "dev", Alias: "lunny4", Created: time.Now()}
|
||||||
uid, err := engine.Insert(&userinfo)
|
userdetail := Userdetail{Uid: 1, Intro: "I'm a very beautiful women.", Profile: "sfsaf"}
|
||||||
if err != nil {
|
_, err := engine.Insert(&userinfo, &userdetail)
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userdetail := Userdetail{Uid: int(uid), Intro: "I'm a very beautiful women.", Profile: "sfsaf"}
|
|
||||||
_, err = engine.Insert(&userdetail)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -199,7 +208,8 @@ func in(t *testing.T) {
|
||||||
}
|
}
|
||||||
fmt.Println(users)
|
fmt.Println(users)
|
||||||
|
|
||||||
err = engine.Where("id > ?", 2).In("id", 1, 2, 3).Find(&users)
|
ids := []interface{}{1, 2, 3}
|
||||||
|
err = engine.Where("id > ?", 2).In("id", ids...).Find(&users)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
return
|
return
|
||||||
|
@ -352,6 +362,7 @@ func TestMysql(t *testing.T) {
|
||||||
exec(t)
|
exec(t)
|
||||||
insertAutoIncr(t)
|
insertAutoIncr(t)
|
||||||
insertMulti(t)
|
insertMulti(t)
|
||||||
|
insertTwoTable(t)
|
||||||
update(t)
|
update(t)
|
||||||
delete(t)
|
delete(t)
|
||||||
get(t)
|
get(t)
|
||||||
|
@ -378,6 +389,7 @@ func TestSqlite(t *testing.T) {
|
||||||
exec(t)
|
exec(t)
|
||||||
insertAutoIncr(t)
|
insertAutoIncr(t)
|
||||||
insertMulti(t)
|
insertMulti(t)
|
||||||
|
insertTwoTable(t)
|
||||||
update(t)
|
update(t)
|
||||||
delete(t)
|
delete(t)
|
||||||
get(t)
|
get(t)
|
||||||
|
|
Loading…
Reference in New Issue