-
Notifications
You must be signed in to change notification settings - Fork 0
/
connect.go
168 lines (141 loc) · 4.19 KB
/
connect.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
package gorpx
import (
"database/sql"
"fmt"
"log"
"os"
"path"
"runtime"
"strings"
"github.com/zew/util"
_ "github.com/go-sql-driver/mysql" // must be imported for side effects
_ "github.com/mattn/go-sqlite3"
)
// SQLHost represents DB resource
type SQLHost struct {
Type string `json:"type"` // sqlite3
User string `json:"user"`
Host string `json:"host"`
Port string `json:"port"`
DbName string `json:"db_name"` // also sqlite3 filename
ConnectionParams map[string]string `json:"connection_params"`
}
// SQLHosts organizes multiple DB resources
type SQLHosts map[string]SQLHost
// Connects to a db and pings it as a check
func initDB(hosts SQLHosts, key string) (SQLHost, *sql.DB) {
var (
db4 *sql.DB
sh SQLHost
err error
)
if len(hosts) == 0 {
log.Fatalf("initDb() requires a map of hosts as argument. Subsequently calls sql.Open()")
}
sh = hosts[key]
if sh.Type != "mysql" && sh.Type != "sqlite3" {
log.Fatalf("sql host type %q unknown", sh.Type)
}
// param docu at https://github.com/go-sql-driver/mysql
paramsJoined := "?"
for k, v := range sh.ConnectionParams {
paramsJoined = fmt.Sprintf("%s%s=%s&", paramsJoined, k, v)
}
if sh.Type == "sqlite3" {
workDir, err := os.Getwd()
util.CheckErr(err)
_, srcFile, _, ok := runtime.Caller(1)
if !ok {
log.Fatalf("runtime caller not found")
}
fName := fmt.Sprintf("%v.sqlite", sh.DbName)
if strings.HasSuffix(fName, ".sqlite.sqlite") {
fName = strings.TrimSuffix(fName, ".sqlite") // chop off doubly extensions
}
paths := []string{
path.Join(".", fName),
path.Join(workDir, fName),
path.Join(path.Dir(srcFile), fName), // src file location as last option
}
found := false
for _, v := range paths {
// file, err = os.Open(v)
db4, err = sql.Open("sqlite3", v)
if err != nil {
log.Printf("cn %q: could not open %v: %v", key, v, err)
continue
}
// Following pragmas speed up backup or clone immensely
{
res, err := db4.Exec("PRAGMA automatic_index = false;")
if err != nil {
log.Printf("pragma automatic_index failed: %v", err)
}
log.Printf("pragma automatic_index succeeded; %v", res)
}
{
res, err := db4.Exec("PRAGMA journal_mode = OFF;")
if err != nil {
log.Printf("pragma journal_mode failed: %v", err)
}
log.Printf("pragma journal_mode succeeded; %v", res)
}
{
res, err := db4.Exec("PRAGMA main.journal_mode = OFF;")
if err != nil {
log.Printf("pragma main.journal_mode failed: %v", err)
}
log.Printf("pragma main.journal_mode succeeded; %v", res)
}
{
res, err := db4.Exec("PRAGMA synchronous = 0;")
if err != nil {
log.Printf("pragma synchronous failed: %v", err)
}
log.Printf("pragma synchronous succeeded; %v", res)
}
{
res, err := db4.Exec("PRAGMA main.synchronous = 0;")
if err != nil {
log.Printf("pragma main.synchronous failed: %v", err)
}
log.Printf("pragma main.synchronous succeeded; %v", res)
}
found = true
break
}
if !found {
log.Fatalf("cn %q: check the directory of main.sqlite", key)
}
} else {
connStr2 := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s%s", sh.User, util.EnvVarRequired("SQL_PW"), sh.Host, sh.Port, sh.DbName, paramsJoined)
connStrWithoutPass := connStr2
sqlPw, err := util.EnvVar("SQL_PW")
if err == nil && sqlPw != "" {
connStrWithoutPass = strings.Replace(connStrWithoutPass, sqlPw, "secret", -1)
log.Printf("cn %q - gorp conn: %v", key, connStrWithoutPass)
}
db4, err = sql.Open("mysql", connStr2)
util.CheckErr(err)
}
err = db4.Ping()
util.CheckErr(err)
log.Printf("cn %q: gorp database connection up", key)
return sh, db4
}
// CheckRes is checking the error *and* the sql result
// of a sql query.
func CheckRes(sqlRes sql.Result, err error) {
util.CheckErr(err)
liID, err := sqlRes.LastInsertId()
util.CheckErr(err)
affected, err := sqlRes.RowsAffected()
util.CheckErr(err)
if affected > 0 && liID > 0 {
log.Printf("%d row(s) affected; Id %d ", affected, liID)
} else if affected > 0 {
log.Printf("%d row(s) affected", affected)
} else if liID > 0 {
log.Printf("Id %d", liID)
}
}