Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
B
beego
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
beego
Commits
d55f54a8
Unverified
Commit
d55f54a8
authored
Jul 23, 2018
by
astaxie
Committed by
GitHub
Jul 23, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3149 from liaoishere/feature/support-begintx
Support DB.BeginTx in go 1.8
parents
03de7456
feb0e67f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
107 additions
and
8 deletions
+107
-8
.travis.yml
.travis.yml
+4
-4
db.go
orm/db.go
+2
-0
orm.go
orm/orm.go
+8
-1
orm_log.go
orm/orm_log.go
+8
-0
orm_test.go
orm/orm_test.go
+72
-3
types.go
orm/types.go
+13
-0
No files found.
.travis.yml
View file @
d55f54a8
language
:
go
go
:
-
"
1.9.
2
"
-
"
1.9.
7
"
-
"
1.10.3"
services
:
-
redis-server
...
...
@@ -44,8 +44,8 @@ before_script:
-
sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi"
-
sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi"
-
sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi"
-
sh -c "
if [ $(go version) == *1.[5-9]* ]; then go get github.com/golang/lint/golint; golint ./...; fi
"
-
sh -c "
if [ $(go version) == *1.[5-9]* ]; then go tool vet .; fi
"
-
sh -c "
go get github.com/golang/lint/golint; golint ./...;
"
-
sh -c "
go tool vet .
"
-
mkdir -p res/var
-
./ssdb/ssdb-server ./ssdb/ssdb.conf -d
after_script
:
...
...
@@ -59,4 +59,4 @@ script:
-
find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s
-
golint ./...
addons
:
postgresql
:
"
9.
4
"
postgresql
:
"
9.
6
"
orm/db.go
View file @
d55f54a8
...
...
@@ -536,6 +536,8 @@ func (d *dbBase) InsertOrUpdate(q dbQuerier, mi *modelInfo, ind reflect.Value, a
updates
:=
make
([]
string
,
len
(
names
))
var
conflitValue
interface
{}
for
i
,
v
:=
range
names
{
// identifier in database may not be case-sensitive, so quote it
v
=
fmt
.
Sprintf
(
"%s%s%s"
,
Q
,
v
,
Q
)
marks
[
i
]
=
"?"
valueStr
:=
argsMap
[
strings
.
ToLower
(
v
)]
if
v
==
args0
{
...
...
orm/orm.go
View file @
d55f54a8
...
...
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// +build go1.8
// Package orm provide ORM for MySQL/PostgreSQL/sqlite
// Simple Usage
//
...
...
@@ -52,6 +54,7 @@
package
orm
import
(
"context"
"database/sql"
"errors"
"fmt"
...
...
@@ -458,11 +461,15 @@ func (o *orm) Using(name string) error {
// begin transaction
func
(
o
*
orm
)
Begin
()
error
{
return
o
.
BeginTx
(
context
.
Background
(),
nil
)
}
func
(
o
*
orm
)
BeginTx
(
ctx
context
.
Context
,
opts
*
sql
.
TxOptions
)
error
{
if
o
.
isTx
{
return
ErrTxHasBegan
}
var
tx
*
sql
.
Tx
tx
,
err
:=
o
.
db
.
(
txer
)
.
Begin
(
)
tx
,
err
:=
o
.
db
.
(
txer
)
.
Begin
Tx
(
ctx
,
opts
)
if
err
!=
nil
{
return
err
}
...
...
orm/orm_log.go
View file @
d55f54a8
...
...
@@ -15,6 +15,7 @@
package
orm
import
(
"context"
"database/sql"
"fmt"
"io"
...
...
@@ -150,6 +151,13 @@ func (d *dbQueryLog) Begin() (*sql.Tx, error) {
return
tx
,
err
}
func
(
d
*
dbQueryLog
)
BeginTx
(
ctx
context
.
Context
,
opts
*
sql
.
TxOptions
)
(
*
sql
.
Tx
,
error
)
{
a
:=
time
.
Now
()
tx
,
err
:=
d
.
db
.
(
txer
)
.
BeginTx
(
ctx
,
opts
)
debugLogQueies
(
d
.
alias
,
"db.BeginTx"
,
"START TRANSACTION"
,
a
,
err
)
return
tx
,
err
}
func
(
d
*
dbQueryLog
)
Commit
()
error
{
a
:=
time
.
Now
()
err
:=
d
.
db
.
(
txEnder
)
.
Commit
()
...
...
orm/orm_test.go
View file @
d55f54a8
...
...
@@ -12,10 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// +build go1.8
package
orm
import
(
"bytes"
"context"
"database/sql"
"fmt"
"io/ioutil"
...
...
@@ -452,9 +455,9 @@ func TestNullDataTypes(t *testing.T) {
throwFail
(
t
,
AssertIs
(
*
d
.
Float32Ptr
,
float32Ptr
))
throwFail
(
t
,
AssertIs
(
*
d
.
Float64Ptr
,
float64Ptr
))
throwFail
(
t
,
AssertIs
(
*
d
.
DecimalPtr
,
decimalPtr
))
throwFail
(
t
,
AssertIs
((
*
d
.
TimePtr
)
.
Format
(
testTime
),
timePtr
.
Format
(
testTime
)))
throwFail
(
t
,
AssertIs
((
*
d
.
DatePtr
)
.
Format
(
testDate
),
datePtr
.
Format
(
testDate
)))
throwFail
(
t
,
AssertIs
((
*
d
.
DateTimePtr
)
.
Format
(
testDateTime
),
dateTimePtr
.
Format
(
testDateTime
)))
throwFail
(
t
,
AssertIs
((
*
d
.
TimePtr
)
.
UTC
()
.
Format
(
testTime
),
timePtr
.
UTC
()
.
Format
(
testTime
)))
throwFail
(
t
,
AssertIs
((
*
d
.
DatePtr
)
.
UTC
()
.
Format
(
testDate
),
datePtr
.
UTC
()
.
Format
(
testDate
)))
throwFail
(
t
,
AssertIs
((
*
d
.
DateTimePtr
)
.
UTC
()
.
Format
(
testDateTime
),
dateTimePtr
.
UTC
()
.
Format
(
testDateTime
)))
}
func
TestDataCustomTypes
(
t
*
testing
.
T
)
{
...
...
@@ -1990,6 +1993,66 @@ func TestTransaction(t *testing.T) {
}
func
TestTransactionIsolationLevel
(
t
*
testing
.
T
)
{
// this test worked when database support transaction isolation level
if
IsSqlite
{
return
}
o1
:=
NewOrm
()
o2
:=
NewOrm
()
// start two transaction with isolation level repeatable read
err
:=
o1
.
BeginTx
(
context
.
Background
(),
&
sql
.
TxOptions
{
Isolation
:
sql
.
LevelRepeatableRead
})
throwFail
(
t
,
err
)
err
=
o2
.
BeginTx
(
context
.
Background
(),
&
sql
.
TxOptions
{
Isolation
:
sql
.
LevelRepeatableRead
})
throwFail
(
t
,
err
)
// o1 insert tag
var
tag
Tag
tag
.
Name
=
"test-transaction"
id
,
err
:=
o1
.
Insert
(
&
tag
)
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
id
>
0
,
true
))
// o2 query tag table, no result
num
,
err
:=
o2
.
QueryTable
(
"tag"
)
.
Filter
(
"name"
,
"test-transaction"
)
.
Count
()
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
0
))
// o1 commit
o1
.
Commit
()
// o2 query tag table, still no result
num
,
err
=
o2
.
QueryTable
(
"tag"
)
.
Filter
(
"name"
,
"test-transaction"
)
.
Count
()
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
0
))
// o2 commit and query tag table, get the result
o2
.
Commit
()
num
,
err
=
o2
.
QueryTable
(
"tag"
)
.
Filter
(
"name"
,
"test-transaction"
)
.
Count
()
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
1
))
num
,
err
=
o1
.
QueryTable
(
"tag"
)
.
Filter
(
"name"
,
"test-transaction"
)
.
Delete
()
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
num
,
1
))
}
func
TestBeginTxWithContextCanceled
(
t
*
testing
.
T
)
{
o
:=
NewOrm
()
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
o
.
BeginTx
(
ctx
,
nil
)
id
,
err
:=
o
.
Insert
(
&
Tag
{
Name
:
"test-context"
})
throwFail
(
t
,
err
)
throwFail
(
t
,
AssertIs
(
id
>
0
,
true
))
// cancel the context before commit to make it error
cancel
()
err
=
o
.
Commit
()
throwFail
(
t
,
AssertIs
(
err
,
context
.
Canceled
))
}
func
TestReadOrCreate
(
t
*
testing
.
T
)
{
u
:=
&
User
{
UserName
:
"Kyle"
,
...
...
@@ -2260,6 +2323,7 @@ func TestIgnoreCaseTag(t *testing.T) {
throwFail
(
t
,
AssertIs
(
info
.
fields
.
GetByName
(
"Name02"
)
.
column
,
"Name"
))
throwFail
(
t
,
AssertIs
(
info
.
fields
.
GetByName
(
"Name03"
)
.
column
,
"name"
))
}
func
TestInsertOrUpdate
(
t
*
testing
.
T
)
{
RegisterModel
(
new
(
User
))
user
:=
User
{
UserName
:
"unique_username133"
,
Status
:
1
,
Password
:
"o"
}
...
...
@@ -2297,6 +2361,11 @@ func TestInsertOrUpdate(t *testing.T) {
throwFailNow
(
t
,
AssertIs
(
user2
.
Status
,
test
.
Status
))
throwFailNow
(
t
,
AssertIs
(
user2
.
Password
,
strings
.
TrimSpace
(
test
.
Password
)))
}
//postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
if
IsPostgres
{
return
}
//test3 +
_
,
err
=
dORM
.
InsertOrUpdate
(
&
user2
,
"user_name"
,
"status=status+1"
)
if
err
!=
nil
{
...
...
orm/types.go
View file @
d55f54a8
...
...
@@ -15,6 +15,7 @@
package
orm
import
(
"context"
"database/sql"
"reflect"
"time"
...
...
@@ -106,6 +107,17 @@ type Ormer interface {
// ...
// err = o.Rollback()
Begin
()
error
// begin transaction with provided context and option
// the provided context is used until the transaction is committed or rolled back.
// if the context is canceled, the transaction will be rolled back.
// the provided TxOptions is optional and may be nil if defaults should be used.
// if a non-default isolation level is used that the driver doesn't support, an error will be returned.
// for example:
// o := NewOrm()
// err := o.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
// ...
// err = o.Rollback()
BeginTx
(
ctx
context
.
Context
,
opts
*
sql
.
TxOptions
)
error
// commit transaction
Commit
()
error
// rollback transaction
...
...
@@ -401,6 +413,7 @@ type dbQuerier interface {
// transaction beginner
type
txer
interface
{
Begin
()
(
*
sql
.
Tx
,
error
)
BeginTx
(
ctx
context
.
Context
,
opts
*
sql
.
TxOptions
)
(
*
sql
.
Tx
,
error
)
}
// transaction ending
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment