forked from gobuffalo/pop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sqlite.go
110 lines (91 loc) · 2.73 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
package pop
import (
"fmt"
"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"
"github.com/pkg/errors"
)
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 errors.Wrap(genericCreate(s, model, cols), "sqlite create")
})
}
func (m *sqlite) Update(s store, model *Model, cols Columns) error {
return m.locker(m.smGil, func() error {
return errors.Wrap(genericUpdate(s, model, cols), "sqlite update")
})
}
func (m *sqlite) Destroy(s store, model *Model) error {
return m.locker(m.smGil, func() error {
return errors.Wrap(genericDestroy(s, model), "sqlite destroy")
})
}
func (m *sqlite) SelectOne(s store, model *Model, query Query) error {
return m.locker(m.smGil, func() error {
return errors.Wrap(genericSelectOne(s, model, query), "sqlite select one")
})
}
func (m *sqlite) SelectMany(s store, models *Model, query Query) error {
return m.locker(m.smGil, func() error {
return errors.Wrap(genericSelectMany(s, models, query), "sqlite select many")
})
}
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)
return errors.Wrapf(os.MkdirAll(d, 0766), "could not create SQLite database %s", m.ConnectionDetails.Database)
}
func (m *sqlite) DropDB() error {
return errors.Wrapf(os.Remove(m.ConnectionDetails.Database), "could not drop SQLite database %s", 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
}