-
Notifications
You must be signed in to change notification settings - Fork 0
/
sql.go
158 lines (132 loc) · 3.7 KB
/
sql.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
package main
import (
"database/sql"
"fmt"
"reflect"
"strings"
)
// parses the mysql type string and returns
// the basic type and its sign (if any)
func parseMysqlType(s string) (typ string, sign string) {
fields := strings.Split(s, " ")
if len(fields) > 1 {
sign = fields[1]
}
fields2 := strings.Split(fields[0], "(")
typ = fields2[0]
return
}
// connect to mysql and return all
// of the tables and their fields
func mysql(md *Metadata, db *sql.DB) error {
rows, err := db.Query("show tables")
if err != nil {
return err
}
var tables []string
var table string
for rows.Next() {
rows.Scan(&table)
tables = append(tables, table)
}
for _, table := range tables {
rows, err := db.Query(fmt.Sprintf("show columns from %s", table))
if err != nil {
return err
}
strct := Struct{
Name: table,
CleanName: formatStructName(table),
}
var field, mtyp, null string
for rows.Next() {
rows.Scan(&field, &mtyp, &null, &null, &null, &null)
// default type
vtype := reflect.TypeOf("")
typ, _ := parseMysqlType(mtyp)
switch typ {
case "tinyint", "smallint", "mediumint", "int", "bigint":
// if sign == "unsigned" {
// vtype = reflect.TypeOf(uint64(0))
// } else {
vtype = reflect.TypeOf(int64(0))
// }
case "decimal", "float", "double":
vtype = reflect.TypeOf(float64(0))
case "blob", "tinyblog", "mediumblob", "longblob":
vtype = reflect.TypeOf([]byte{})
}
strct.Fields = append(strct.Fields, Field{
Name: field,
CleanName: formatFieldName(field),
Type: vtype,
})
}
md.Structs = append(md.Structs, strct)
}
return nil
}
// connect to postgresql and return all
// of the tables and their fields
func postgresql(md *Metadata, db *sql.DB) error {
//"SELECT column_name, data_type FROM information_schema.columns WHERE table_name = ?"
return nil
}
// parses the sqlite3 type string and returns
// the basic type
func parseSqlite3Type(s string) (typ string, sign string) {
fields := strings.Split(s, "(")
typ = fields[0]
if strings.Contains(s, "unsigned") {
sign = "unsigned"
}
return
}
func sqlite3(md *Metadata, db *sql.DB) error {
rows, err := db.Query("SELECT tbl_name FROM sqlite_master WHERE type = ?", "table")
if err != nil {
return err
}
var tables []string
var table string
for rows.Next() {
rows.Scan(&table)
tables = append(tables, table)
}
for _, table := range tables {
rows, err := db.Query(fmt.Sprintf("PRAGMA TABLE_INFO('%s')", table))
if err != nil {
return err
}
strct := Struct{
Name: table,
CleanName: formatStructName(table),
}
var field, styp, null string
for rows.Next() {
rows.Scan(&null, &field, &styp, &null, &null, &null)
// default type
vtype := reflect.TypeOf("")
typ, _ := parseSqlite3Type(strings.ToLower(styp))
switch typ {
case "int", "integer", "tinyint", "smallint", "mediumint", "bigint", "unsigned big int", "big int", "int2", "int8":
// if sign == "unsigned" {
// vtype = reflect.TypeOf(uint64(0))
// } else {
vtype = reflect.TypeOf(int64(0))
// }
case "real", "double", "double precision", "float", "numeric", "decimal", "date", "datetime":
vtype = reflect.TypeOf(float64(0))
case "bit", "boolean", "bool":
vtype = reflect.TypeOf(true)
}
strct.Fields = append(strct.Fields, Field{
Name: field,
CleanName: formatFieldName(field),
Type: vtype,
})
}
md.Structs = append(md.Structs, strct)
}
return nil
}