forked from loopfz/gadgeto
/
database.go
108 lines (98 loc) · 2.42 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
package rekordo
import (
"database/sql"
"errors"
"time"
"github.com/go-gorp/gorp"
"github.com/loopfz/gadgeto/zesty"
)
// Default database settings.
const (
maxOpenConns = 5
maxIdleConns = 3
)
// DatabaseConfig represents the configuration used to
// register a new database.
type DatabaseConfig struct {
Name string
DSN string
System DBMS
MaxOpenConns int
MaxIdleConns int
ConnMaxLifetime time.Duration
AutoCreateTables bool
}
// RegisterDatabase creates a gorp map with tables and tc and
// registers it with zesty.
func RegisterDatabase(dbcfg *DatabaseConfig, tc gorp.TypeConverter) (zesty.DB, error) {
dbConn, err := sql.Open(dbcfg.System.DriverName(), dbcfg.DSN)
if err != nil {
return nil, err
}
// Make sure we have proper values for the database
// settings, and replace them with default if necessary
// before applying to the new connection.
if dbcfg.MaxOpenConns == 0 {
dbcfg.MaxOpenConns = maxOpenConns
}
dbConn.SetMaxOpenConns(dbcfg.MaxOpenConns)
if dbcfg.MaxIdleConns == 0 {
dbcfg.MaxIdleConns = maxIdleConns
}
dbConn.SetMaxIdleConns(dbcfg.MaxIdleConns)
dbConn.SetConnMaxLifetime(dbcfg.ConnMaxLifetime)
// Select the proper dialect used by gorp.
var dialect gorp.Dialect
switch dbcfg.System {
case DatabaseMySQL:
dialect = gorp.MySQLDialect{}
case DatabasePostgreSQL:
dialect = gorp.PostgresDialect{}
case DatabaseSqlite3:
dialect = gorp.SqliteDialect{}
default:
return nil, errors.New("unknown database system")
}
dbmap := &gorp.DbMap{
Db: dbConn,
Dialect: dialect,
TypeConverter: tc,
}
modelsMu.Lock()
tableModels := models[dbcfg.Name]
for _, t := range tableModels {
dbmap.AddTableWithName(t.Model, t.Name).SetKeys(t.AutoIncrement, t.Keys...)
}
modelsMu.Unlock()
if dbcfg.AutoCreateTables {
err = dbmap.CreateTablesIfNotExists()
if err != nil {
return nil, err
}
}
db := zesty.NewDB(dbmap)
if err := zesty.RegisterDB(db, dbcfg.Name); err != nil {
return nil, err
}
return db, nil
}
// DBMS represents a database management system.
type DBMS uint8
// Database management systems.
const (
DatabasePostgreSQL DBMS = iota ^ 42
DatabaseMySQL
DatabaseSqlite3
)
// DriverName returns the name of the driver for ds.
func (d DBMS) DriverName() string {
switch d {
case DatabasePostgreSQL:
return "postgres"
case DatabaseMySQL:
return "mysql"
case DatabaseSqlite3:
return "sqlite3"
}
return ""
}