-
Notifications
You must be signed in to change notification settings - Fork 27
/
mssql_test.go
183 lines (155 loc) · 4.64 KB
/
mssql_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package godb_test
import (
"bytes"
"os"
"testing"
"time"
"github.com/samonzeweb/godb"
"github.com/samonzeweb/godb/adapters/mssql"
"github.com/samonzeweb/godb/dbtests/common"
. "github.com/smartystreets/goconvey/convey"
)
func fixturesSetupMSSQL(t *testing.T) (*godb.DB, func()) {
if os.Getenv("GODB_MSSQL") == "" {
t.Skip("Don't run SQL Server test, GODB_MSSQL not set")
}
db, err := godb.Open(mssql.Adapter, os.Getenv("GODB_MSSQL"))
if err != nil {
t.Fatal(err)
}
// Enable logger if needed
//db.SetLogger(log.New(os.Stderr, "", 0))
createTable :=
`create table books (
id int identity,
title nvarchar(128) not null,
author nvarchar(128) not null,
published datetime2 not null,
version int not null default 0);
create table inventories (
id int identity,
book_id int not null,
last_inventory datetime2 not null,
counting int not null default 0);
create table bookswithrowversion (
id int identity,
title nvarchar(128) not null,
author nvarchar(128) not null,
published datetime2 not null,
version rowversion);
`
_, err = db.CurrentDB().Exec(createTable)
if err != nil {
t.Fatal(err)
}
fixturesTeardown := func() {
dropTable := "drop table books; drop table inventories; drop table bookswithrowversion;"
_, err := db.CurrentDB().Exec(dropTable)
if err != nil {
t.Fatal(err)
}
err = db.Close()
if err != nil {
t.Fatal(err)
}
}
return db, fixturesTeardown
}
func TestStatementsMSSQL(t *testing.T) {
Convey("A DB for a SQL Server database", t, func() {
db, teardown := fixturesSetupMSSQL(t)
defer teardown()
Convey("The common statements tests must pass", func() {
common.StatementsTests(db, t)
})
})
}
func TestStructsMSSQL(t *testing.T) {
Convey("A DB for a SQL Server database", t, func() {
db, teardown := fixturesSetupMSSQL(t)
defer teardown()
Convey("The common structs tests must pass", func() {
common.StructsTests(db, t)
})
})
}
func TestRawMSSQL(t *testing.T) {
Convey("A DB for a SQLite database", t, func() {
db, teardown := fixturesSetupMSSQL(t)
defer teardown()
Convey("The common raw tests must pass", func() {
common.RawSQLTests(db, t)
})
})
}
type bookWithRowversion struct {
Id int `db:"id,key,auto"`
Title string `db:"title"`
Author string `db:"author"`
Published time.Time `db:"published"`
Version mssql.Rowversion `db:"version,auto,oplock"`
}
func (bookWithRowversion) TableName() string {
return "bookswithrowversion"
}
func TestReturningClauseMSSQL(t *testing.T) {
Convey("A DB for a SQL Server database", t, func() {
db, teardown := fixturesSetupMSSQL(t)
defer teardown()
Convey("The auto columns are set after a struct insert", func() {
book := bookWithRowversion{
Title: "The Hobbit",
Author: "Tolkien",
Published: time.Date(1937, 9, 21, 0, 0, 0, 0, time.UTC),
}
db.Insert(&book).Do()
So(book.Id, ShouldBeGreaterThan, 0)
// Expect non zeroes (or empty) slice for Version
allZeroOrEmpty := true
for _, v := range book.Version.Version {
allZeroOrEmpty = allZeroOrEmpty && (v == 0)
}
So(allZeroOrEmpty, ShouldBeFalse)
})
Convey("The auto columns are updates after a struct update", func() {
book := bookWithRowversion{
Title: "The Hobbit",
Author: "Tolkien",
Published: time.Date(1937, 9, 21, 0, 0, 0, 0, time.UTC),
}
db.Insert(&book).Do()
previousVersion := book.Version.Copy()
db.Update(&book).Do()
// Expect differents values in versions
So(bytes.Compare(book.Version.Version, previousVersion.Version), ShouldNotEqual, 0)
})
})
}
func TestAutomaticOptimisticLockingMSSQL(t *testing.T) {
Convey("A DB for a SQL Server database", t, func() {
db, teardown := fixturesSetupMSSQL(t)
defer teardown()
Convey("A row inserted in database", func() {
book := bookWithRowversion{
Title: "The Hobbit",
Author: "Tolkien",
Published: time.Date(1937, 9, 21, 0, 0, 0, 0, time.UTC),
}
db.Insert(&book).Do()
Convey("Another player read the row", func() {
var sameBook bookWithRowversion
db.Select(&sameBook).Where("id = ? ", book.Id).Do()
Convey("Both instances has same value for the oplock field", func() {
// Expact same values in versions
So(bytes.Compare(book.Version.Version, sameBook.Version.Version), ShouldEqual, 0)
Convey("Both players update the row, but the second fails because oplock", func() {
err := db.Update(&book).Do()
So(err, ShouldBeNil)
err = db.Update(&sameBook).Do()
So(err, ShouldEqual, godb.ErrOpLock)
})
})
})
})
})
}