forked from gobuffalo/pop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sqlite.go
114 lines (95 loc) · 2.45 KB
/
sqlite.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
package pop
import (
"fmt"
"log"
"os"
"path/filepath"
"sync"
"time"
"github.com/markbates/going/defaults"
. "github.com/markbates/pop/columns"
"github.com/markbates/pop/fizz"
"github.com/markbates/pop/fizz/translators"
)
type sqlite struct {
gil *sync.Mutex
smGil *sync.Mutex
ConnectionDetails *ConnectionDetails
}
func (m *sqlite) Details() *ConnectionDetails {
return m.ConnectionDetails
}
func (m *sqlite) URL() string {
return m.ConnectionDetails.Database + "?_busy_timeout=5000"
}
func (m *sqlite) MigrationURL() string {
return m.ConnectionDetails.URL
}
func (m *sqlite) Create(s store, model *Model, cols Columns) error {
return m.locker(m.smGil, func() error {
return genericCreate(s, model, cols)
})
}
func (m *sqlite) Update(s store, model *Model, cols Columns) error {
return m.locker(m.smGil, func() error {
return genericUpdate(s, model, cols)
})
}
func (m *sqlite) Destroy(s store, model *Model) error {
return m.locker(m.smGil, func() error {
return genericDestroy(s, model)
})
}
func (m *sqlite) SelectOne(s store, model *Model, query Query) error {
return m.locker(m.smGil, func() error {
return genericSelectOne(s, model, query)
})
}
func (m *sqlite) SelectMany(s store, models *Model, query Query) error {
return m.locker(m.smGil, func() error {
return genericSelectMany(s, models, query)
})
}
func (m *sqlite) Lock(fn func() error) error {
return m.locker(m.gil, fn)
}
func (m *sqlite) locker(l *sync.Mutex, fn func() error) error {
if defaults.String(m.Details().Options["lock"], "true") == "true" {
defer l.Unlock()
l.Lock()
}
err := fn()
attempts := 0
for err != nil && err.Error() == "database is locked" && attempts <= m.Details().RetryLimit() {
time.Sleep(m.Details().RetrySleep())
err = fn()
attempts++
}
return err
}
func (m *sqlite) CreateDB() error {
d := filepath.Dir(m.ConnectionDetails.Database)
err := os.MkdirAll(d, 0766)
if err != nil {
log.Println(err)
}
return err
}
func (m *sqlite) DropDB() error {
return os.Remove(m.ConnectionDetails.Database)
}
func (m *sqlite) TranslateSQL(sql string) string {
return sql
}
func (m *sqlite) FizzTranslator() fizz.Translator {
return translators.NewSQLite(m.Details().Database)
}
func newSQLite(deets *ConnectionDetails) dialect {
deets.URL = fmt.Sprintf("sqlite3://%s", deets.Database)
cd := &sqlite{
gil: &sync.Mutex{},
smGil: &sync.Mutex{},
ConnectionDetails: deets,
}
return cd
}