-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdb-context.go
109 lines (92 loc) · 2.47 KB
/
db-context.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
package main
import (
"fmt"
"github.com/thoas/go-funk"
"go-ef/utils"
"log"
"reflect"
"strings"
)
type DbContext struct {
tables []DbTable
}
func CreateDbContext() DbContext {
return DbContext{
tables: make([]DbTable, 0),
}
}
func (ctx *DbContext) RegisterTable(entity any) {
tableType := reflect.TypeOf(entity)
tableName := tableType.Name()
columns := make([]DbColumn, 0)
for i := 0; i < tableType.NumField(); i++ {
column := tableType.Field(i)
columnType := getDbColumnType(column.Type)
columns = append(columns, DbColumn{name: column.Name, columnType: columnType})
}
ctx.tables = append(ctx.tables, DbTable{
tableName: tableName,
columns: columns,
})
}
func (ctx *DbContext) Add(entity any) {
tableName := reflect.TypeOf(entity).Name()
tableIndex := funk.IndexOf(ctx.tables, func(table DbTable) bool {
return table.tableName == tableName
})
if tableIndex == -1 {
panic("Table not found")
}
ctx.tables[tableIndex].records = append(ctx.tables[tableIndex].records, entity)
}
func (ctx *DbContext) BuildQuery() string {
var sb strings.Builder
for _, table := range ctx.tables {
if len(table.records) == 0 {
continue
}
query := generateQuery(table)
sb.WriteString(query)
}
return sb.String()
}
func (ctx *DbContext) Save() {
query := ctx.BuildQuery()
log.Println(query)
}
func generateQuery(table DbTable) string {
if len(table.records) == 0 {
panic("No records")
}
columnNames := utils.Select(table.columns, func(column DbColumn) string { return column.name })
commaSeparatedColumnNames := strings.Join(columnNames[:], ", ")
var sb strings.Builder
for _, record := range table.records {
structVal := reflect.ValueOf(record)
values := utils.Select(table.columns, func(column DbColumn) string {
fieldVal := structVal.FieldByName(column.name)
return addQuotesIfNecessary(fmt.Sprint(fieldVal.Interface()), column.columnType)
})
sb.WriteString(fmt.Sprintf("(%s)", strings.Join(values, ", ")))
}
return fmt.Sprintf("INSERT INTO %s (%s) VALUES %s;", table.tableName, commaSeparatedColumnNames, sb.String())
}
func addQuotesIfNecessary(value string, columnType DbColumnType) string {
if columnType == String {
return addQuotes(value)
}
return value
}
func addQuotes(value string) string {
return fmt.Sprintf("'%s'", value)
}
func getDbColumnType(columnType reflect.Type) DbColumnType {
switch columnType.Kind() {
default:
panic("Unrecognized column type")
case reflect.Int:
return Integer
case reflect.String:
return String
}
}