/
database_mysql.go
executable file
·131 lines (106 loc) · 2.8 KB
/
database_mysql.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
package adapters
import (
"database/sql"
"fmt"
// Mysql driver
_ "github.com/go-sql-driver/mysql"
)
// MysqlAdapter conforms to the query.Database interface
type MysqlAdapter struct {
*Adapter
options map[string]string
sqlDB *sql.DB
debug bool
}
// Open this database
func (db *MysqlAdapter) Open(opts map[string]string) error {
db.debug = false
db.options = map[string]string{
"adapter": "mysql",
"user": "root", // sub your user
"password": "",
"db": "query_test",
"protocol": "tcp",
"host": "localhost",
"port": "3306",
"params": "charset=utf8&parseTime=true",
}
if opts["debug"] == "true" {
db.debug = true
}
// Merge options
for k, v := range opts {
db.options[k] = v
}
// A typical connection string is of the form:
//"user:password@tcp(localhost:3306)/dbname?charset=utf8&parseTime=true")
options := fmt.Sprintf("%s:%s@%s(%s:%s)/%s?%s",
db.options["user"],
db.options["password"],
db.options["protocol"],
db.options["host"],
db.options["port"],
db.options["db"],
db.options["params"])
var err error
db.sqlDB, err = sql.Open(db.options["adapter"], options)
if err != nil {
return err
}
if db.sqlDB == nil {
fmt.Printf("Mysql options:%s", options)
return fmt.Errorf("\nError creating database with options: %v", db.options)
}
// Call ping on the db to check it does actually exist!
err = db.sqlDB.Ping()
if err != nil {
return err
}
return err
}
// Close the database
func (db *MysqlAdapter) Close() error {
if db.sqlDB != nil {
return db.sqlDB.Close()
}
return nil
}
// SQLDB returns the internal db.sqlDB pointer
func (db *MysqlAdapter) SQLDB() *sql.DB {
return db.sqlDB
}
// Query SQL execute - NB caller must call use defer rows.Close() with rows returned
func (db *MysqlAdapter) Query(query string, args ...interface{}) (*sql.Rows, error) {
return db.performQuery(db.sqlDB, db.debug, query, args...)
}
// Exec - use this for non-select statements
func (db *MysqlAdapter) Exec(query string, args ...interface{}) (sql.Result, error) {
return db.performExec(db.sqlDB, db.debug, query, args...)
}
// QuoteField quotes a table name or column name
func (db *MysqlAdapter) QuoteField(name string) string {
return fmt.Sprintf("`%s`", name)
}
// Insert a record with params and return the id - psql behaves differently
func (db *MysqlAdapter) Insert(query string, args ...interface{}) (id int64, err error) {
tx, err := db.sqlDB.Begin()
if err != nil {
return 0, err
}
// Execute the sql using db
result, err := db.Exec(query, args...)
if err != nil {
return 0, err
}
// TODO - check this works on mysql under load with concurrent connections
// fine if connection not shared
id, err = result.LastInsertId()
if err != nil {
return 0, err
}
err = tx.Commit()
if err != nil {
return 0, err
}
return id, nil
}