forked from kuroneko/gosqlite3
-
Notifications
You must be signed in to change notification settings - Fork 5
/
database_test.go
111 lines (99 loc) · 3.71 KB
/
database_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
package sqlite3
import "testing"
import "time"
func (db *Database) createTestTables(t *testing.T, tables ...*Table) {
for _, table := range tables {
table.Drop(db)
table.Create(db)
if c, _ := table.Rows(db); c != 0 {
t.Fatalf("%v already contains data", table.Name)
}
}
}
func (db *Database) createTestData(t *testing.T, repeats int) {
db.runQuery(t, "PRAGMA synchronous=OFF")
for i := 0; i < repeats; i++ {
if i%2 == 0 {
db.runQuery(t, "INSERT INTO foo values (?, 'holy moly')", i)
db.runQuery(t, "INSERT INTO bar values (?, ?)", i, TwoItems{"holy moly", "guacomole"})
} else {
db.runQuery(t, "INSERT INTO foo values (?, 'guacomole')", i)
db.runQuery(t, "INSERT INTO bar values (?, ?)", i, TwoItems{"guacomole", "holy moly"})
}
}
db.runQuery(t, "PRAGMA synchronous=NORMAL")
}
func TestTransfers(t *testing.T) {
TransientSession(func(source *Database) {
source.createTestTables(t, FOO, BAR)
source.createTestData(t, 1000)
Session("target.db", func(target *Database) {
t.Logf("Database opened: %v [flags: %v]", target.Filename, int(target.Flags))
target.createTestTables(t, FOO, BAR)
fatalOnError(t, target.Load(source, "main"), "loading from %v[%]", source.Filename, "main")
for _, table := range []*Table{FOO, BAR} {
i, _ := table.Rows(target)
j, _ := table.Rows(source)
if i != j {
t.Fatalf("failed to load data for table %v", table.Name)
}
}
Session("backup.db", func(backup *Database) {
t.Logf("Database opened: %v [flags: %v]", backup.Filename, int(backup.Flags))
backup.createTestTables(t, FOO, BAR)
fatalOnError(t, target.Save(backup, "main"), "saving to %v[%v]", backup.Filename, "main")
for _, table := range []*Table{FOO, BAR} {
i, _ := table.Rows(target)
j, _ := table.Rows(backup)
if i != j {
t.Fatalf("failed to load data for table %v", table.Name)
}
}
})
})
})
}
func (r *Reporter) finished(t *testing.T) bool {
report, ok := <-(*r)
if report != nil {
switch e := report.Error.(type) {
case Errno:
if e != DONE {
t.Fatalf("Backup error %v", e)
}
// case nil: t.Logf("Backup still has %v pages of %v to copy to %v", report.Remaining, report.PageCount, report.Target)
}
}
return !ok
}
func TestBackup(t *testing.T) {
var messages int
Session("test.db", func(db *Database) {
db.createTestTables(t, FOO, BAR)
db.createTestData(t, 1000)
if sync_reporter, e := db.Backup(BackupParameters{Target: "sync.db", PagesPerStep: 3, QueueLength: 1}); e == nil {
d := time.Now()
for messages = 0; !sync_reporter.finished(t); messages++ {
}
t.Logf("backup of %v generated %v synchronous messages and took %vns", db.Filename, messages, time.Now().Sub(d))
}
if sync_reporter, e := db.Backup(BackupParameters{Target: "sync.db", PagesPerStep: 3, QueueLength: 1, Interval: 100000}); e == nil {
d := time.Now()
for messages = 0; !sync_reporter.finished(t); messages++ {
}
t.Logf("backup of %v generated %v synchronous messages and took %vns with interval %v", db.Filename, messages, time.Now().Sub(d), 100000)
}
if async_reporter, e := db.Backup(BackupParameters{Target: "async.db", PagesPerStep: 3, QueueLength: 8}); e == nil {
d := time.Now()
for messages = 0; !async_reporter.finished(t); messages++ {
}
t.Logf("backup of %v generated %v asynchronous messages and took %vns", db.Filename, messages, time.Now().Sub(d))
}
if async_reporter, e := db.Backup(BackupParameters{Target: "async.db", PagesPerStep: 3, QueueLength: 8}); e == nil {
d := time.Now()
for messages = 0; !async_reporter.finished(t); messages++ {
}
t.Logf("backup of %v generated %v asynchronous messages and took %vns with interval %v", db.Filename, messages, time.Now().Sub(d), 100000)
}
})
}