forked from brianvoe/gofakeit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sql.go
156 lines (132 loc) · 4.1 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
package gofakeit
import (
"encoding/json"
"errors"
"fmt"
"strings"
)
type SQLOptions struct {
Table string `json:"table" xml:"table"` // Table name we are inserting into
Count int `json:"count" xml:"count"` // How many entries (tuples) we're generating
Fields []Field `json:"fields" xml:"fields"` // The fields to be generated
}
func SQL(so *SQLOptions) (string, error) { return sqlFunc(GlobalFaker, so) }
func (f *Faker) SQL(so *SQLOptions) (string, error) { return sqlFunc(f, so) }
func sqlFunc(f *Faker, so *SQLOptions) (string, error) {
if so.Table == "" {
return "", errors.New("must provide table name to generate SQL")
}
if so.Fields == nil || len(so.Fields) <= 0 {
return "", errors.New(("must pass fields in order to generate SQL queries"))
}
if so.Count <= 0 {
return "", errors.New("must have entry count")
}
var sb strings.Builder
sb.WriteString("INSERT INTO " + so.Table + " ")
// Loop through each field and put together column names
var cols []string
for _, f := range so.Fields {
cols = append(cols, f.Name)
}
sb.WriteString("(" + strings.Join(cols, ", ") + ")")
sb.WriteString(" VALUES ")
for i := 0; i < so.Count; i++ {
// Start opening value
sb.WriteString("(")
// Now, we need to add all of our fields
var endStr string
for ii, field := range so.Fields {
// Set end of value string
endStr = ", "
if ii == len(so.Fields)-1 {
endStr = ""
}
// If autoincrement, add based upon loop
if field.Function == "autoincrement" {
sb.WriteString(fmt.Sprintf("%d%s", i+1, endStr))
continue
}
// Get the function info for the field
funcInfo := GetFuncLookup(field.Function)
if funcInfo == nil {
return "", errors.New("invalid function, " + field.Function + " does not exist")
}
// Generate the value
val, err := funcInfo.Generate(f, &field.Params, funcInfo)
if err != nil {
return "", err
}
// Convert the output value to the proper SQL type
convertType := sqlConvertType(funcInfo.Output, val)
// If its the last field, we need to close the value
sb.WriteString(convertType + endStr)
}
// If its the last value, we need to close the value
if i == so.Count-1 {
sb.WriteString(");")
} else {
sb.WriteString("),")
}
}
return sb.String(), nil
}
// sqlConvertType will take in a type and value and convert it to the proper SQL type
func sqlConvertType(t string, val any) string {
switch t {
case "string":
return `'` + fmt.Sprintf("%v", val) + `'`
case "[]byte":
return `'` + fmt.Sprintf("%s", val) + `'`
default:
return fmt.Sprintf("%v", val)
}
}
func addDatabaseSQLLookup() {
AddFuncLookup("sql", Info{
Display: "SQL",
Category: "database",
Description: "Command in SQL used to add new data records into a database table",
Example: `INSERT INTO people
(id, first_name, price, age, created_at)
VALUES
(1, 'Markus', 804.92, 21, '1937-01-30 07:58:01'),
(2, 'Santino', 235.13, 40, '1964-07-07 22:25:40');`,
Output: "string",
ContentType: "application/sql",
Params: []Param{
{Field: "table", Display: "Table", Type: "string", Description: "Name of the table to insert into"},
{Field: "count", Display: "Count", Type: "int", Default: "100", Description: "Number of inserts to generate"},
{Field: "fields", Display: "Fields", Type: "[]Field", Description: "Fields containing key name and function to run in json format"},
},
Generate: func(f *Faker, m *MapParams, info *Info) (any, error) {
so := SQLOptions{}
table, err := info.GetString(m, "table")
if err != nil {
return nil, err
}
so.Table = table
count, err := info.GetInt(m, "count")
if err != nil {
return nil, err
}
so.Count = count
fieldsStr, err := info.GetStringArray(m, "fields")
if err != nil {
return nil, err
}
// Check to make sure fields has length
if len(fieldsStr) > 0 {
so.Fields = make([]Field, len(fieldsStr))
for i, f := range fieldsStr {
// Unmarshal fields string into fields array
err = json.Unmarshal([]byte(f), &so.Fields[i])
if err != nil {
return nil, err
}
}
}
return sqlFunc(f, &so)
},
})
}