-
Notifications
You must be signed in to change notification settings - Fork 1
/
util.go
142 lines (123 loc) · 3.06 KB
/
util.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
// Copyright 2015 Luke Shumaker
// Copyright 2015 Davis Webb
package backend
import (
"crypto/rand"
"locale"
"math/big"
"periwinkle"
"strings"
"github.com/go-sql-driver/mysql"
sqlite3 "github.com/mattn/go-sqlite3"
)
type errorList []locale.Error
var _ locale.Error = errorList{}
func (e errorList) Locales() []locale.Spec {
m := map[locale.Spec]int{}
for _, err := range e {
for _, l := range err.Locales() {
m[l] = m[l] + 1
}
}
var ret []locale.Spec
for l, c := range m {
if c == len(e) {
ret = append(ret, l)
}
}
return ret
}
func (errs errorList) L10NString(l locale.Spec) string {
strs := make([]string, len(errs))
for i, err := range errs {
strs[i] = " - " + strings.Replace(err.L10NString(l), "\n", "\n ", -1)
}
return strings.Join(strs, "\n")
}
func (errs errorList) Error() string {
return errs.L10NString("C")
}
func errHelper(errs *errorList, err locale.Error) {
if err != nil {
*errs = append(*errs, err)
}
}
type table interface {
dbSchema(*periwinkle.Tx) locale.Error
}
type tableSeed interface {
table
dbSeed(*periwinkle.Tx) locale.Error
}
func DbSchema(db *periwinkle.Tx) locale.Error {
errs := errorList{}
for _, table := range tables {
errHelper(&errs, table.dbSchema(db))
}
if len(errs) > 0 {
return errs
}
return nil
}
func DbDrop(db *periwinkle.Tx) locale.Error {
errs := errorList{}
for i := range tables {
table := tables[len(tables)-1-i]
errHelper(&errs, locale.UntranslatedError(db.DropTable(table).Error))
}
if len(errs) > 0 {
return errs
}
return nil
}
func DbSeed(db *periwinkle.Tx) locale.Error {
errs := errorList{}
for _, table := range tables {
if seeder, ok := table.(tableSeed); ok {
errHelper(&errs, seeder.dbSeed(db))
}
}
if len(errs) > 0 {
return errs
}
return nil
}
// Panic, but a little nicer
func dbError(err error) {
// TODO: return better messages for Conflict errors.
switch e := err.(type) {
case sqlite3.Error:
if e.Code == sqlite3.ErrConstraint {
panic(periwinkle.Conflict{locale.UntranslatedError(e)})
}
panic(locale.UntranslatedError(e))
case *mysql.MySQLError:
// TODO: this list of error numbers might not be
// complete, or totally correct. See
// https://mariadb.com/kb/en/mariadb/mariadb-error-codes/
switch e.Number {
case 1022, 1062, 1169, 1216, 1217, 1451, 1452, 1557, 1761, 1762, 1834:
panic(periwinkle.Conflict{locale.UntranslatedError(e)})
}
panic(locale.UntranslatedError(e))
default:
panic(locale.Errorf("Programmer Error: the programmer said this is a database error, but it's not: %s", e))
}
}
// Panic, but a little nicer
func programmerError(str string) {
panic(locale.Errorf("Programmer Error: %s", locale.Sprintf(str)))
}
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
var alphabetLen = big.NewInt(int64(len(alphabet)))
func RandomString(size int) string {
bytes := make([]byte, size)
for i := 0; i < size; i++ {
bigint, err := rand.Int(rand.Reader, alphabetLen)
if err != nil {
panic(err) // Luke says this is OK
}
bytes[i] = alphabet[bigint.Int64()]
}
return string(bytes[:])
}