-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdatabase.go
136 lines (123 loc) · 2.83 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package gw
import (
"database/sql"
"fmt"
"github.com/juju/errors"
_ "github.com/lib/pq"
"github.com/mattes/migrate"
"github.com/mattes/migrate/database/postgres"
_ "github.com/mattes/migrate/source/file"
"net/url"
"regexp"
"strconv"
)
func Migrate(connection, path string) error {
db, err := sql.Open("postgres", connection)
if err != nil {
return err
}
driver, err := postgres.WithInstance(db, &postgres.Config{})
if err != nil {
return err
}
m, err := migrate.NewWithDatabaseInstance(path, "postgres", driver)
if err != nil {
return err
}
err = m.Up()
if err != nil {
if err == migrate.ErrNoChange {
return nil
} else {
return err
}
}
return nil
}
const (
ASC = "ascend"
DESC = "descend"
)
type QuerySettings struct {
Start int
Count int
Field string
Order string
Compiled string
}
// Supports ordering and subsetting of queries by building the relevant
// portions of a SELECT query out of URL query args. Returns a string with
// the relevant clauses, generally suitable for appending to the end of a
// query (without said clauses).
// * start: integer, starting index of query. Defaults to 0.
// * count: integer, max size of query. Defaults to 0, which is unlimited.
// This will probably change!
// * field: string, name of column to sort by. Default supplied as col arg to
// function. Leave arg empty to ignore sorting.
// * order: ("ascend"|"descend") Default supplied as ord arg to function.
func QuerySetHelper(args url.Values, col, ord string) (*QuerySettings, error) {
var start int
var count int
var column string
var order string
var options string
var err error
qs := &QuerySettings{}
startArg := args.Get("start")
if startArg == "" {
start = 0
} else {
start, err = strconv.Atoi(startArg)
if err != nil {
return nil, errors.Trace(err)
}
}
countArg := args.Get("count")
if countArg == "" {
count = 0
} else {
count, err = strconv.Atoi(countArg)
if err != nil {
return nil, errors.Trace(err)
}
}
fieldArg := args.Get("field")
if fieldArg == "" {
column = col
} else {
match, err := regexp.MatchString("(?i)^[a-z_][a-z0-9_]*$", fieldArg)
if err != nil {
return nil, errors.Trace(err)
}
if match {
column = fieldArg
} else {
return nil, errors.Errorf("Invalid field name")
}
}
orderArg := args.Get("order")
if orderArg == "" {
orderArg = ord
}
if orderArg == ASC {
order = "ASC"
} else if orderArg == DESC {
order = "DESC"
} else {
return nil, errors.Errorf("Invalid order argument %s", orderArg)
}
if column != "" {
options = fmt.Sprintf("ORDER BY %s %s", column, order)
} else {
options = ""
}
if count > 0 {
options = fmt.Sprintf(" %s LIMIT %d OFFSET %d", options, count, start)
}
qs.Start = start
qs.Count = count
qs.Field = column
qs.Order = order
qs.Compiled = options
return qs, nil
}