This repository has been archived by the owner on Aug 12, 2021. It is now read-only.
/
database.go
113 lines (82 loc) · 1.86 KB
/
database.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
package database
import (
"database/sql"
"fmt"
_ "github.com/mattn/go-sqlite3"
_ "github.com/whosonfirst/go-spatialite"
_ "log"
"strings"
"sync"
)
type SQLiteDatabase struct {
conn *sql.DB
dsn string
mu *sync.Mutex
}
func NewDB(dsn string) (*SQLiteDatabase, error) {
return NewDBWithDriver("sqlite3", dsn)
}
func NewDBWithDriver(driver string, dsn string) (*SQLiteDatabase, error) {
if !strings.HasPrefix(dsn, "file:") {
// because this and this:
if dsn == ":memory:" {
// https://github.com/mattn/go-sqlite3#faq
// https://github.com/mattn/go-sqlite3/issues/204
dsn = "file::memory:?mode=memory&cache=shared"
} else {
// https://github.com/mattn/go-sqlite3/issues/39
dsn = fmt.Sprintf("file:%s?cache=shared&mode=rwc", dsn)
}
}
conn, err := sql.Open(driver, dsn)
if err != nil {
return nil, err
}
mu := new(sync.Mutex)
db := SQLiteDatabase{
conn: conn,
dsn: dsn,
mu: mu,
}
return &db, err
}
// https://blog.devart.com/increasing-sqlite-performance.html
// https://www.sqlite.org/pragma.html#pragma_journal_mode
func (db *SQLiteDatabase) LiveHardDieFast() error {
conn, err := db.Conn()
if err != nil {
return err
}
pragma := []string{
"PRAGMA JOURNAL_MODE=OFF",
"PRAGMA SYNCHRONOUS=OFF",
"PRAGMA LOCKING_MODE=EXCLUSIVE",
// https://www.gaia-gis.it/gaia-sins/spatialite-cookbook/html/system.html
"PRAGMA PAGE_SIZE=4096",
"PRAGMA CACHE_SIZE=1000000",
}
for _, p := range pragma {
_, err = conn.Exec(p)
if err != nil {
return err
}
}
return nil
}
func (db *SQLiteDatabase) Lock() error {
db.mu.Lock()
return nil
}
func (db *SQLiteDatabase) Unlock() error {
db.mu.Unlock()
return nil
}
func (db *SQLiteDatabase) Conn() (*sql.DB, error) {
return db.conn, nil
}
func (db *SQLiteDatabase) DSN() string {
return db.dsn
}
func (db *SQLiteDatabase) Close() error {
return db.conn.Close()
}