89 lines
1.7 KiB
Go
89 lines
1.7 KiB
Go
package db
|
||
|
||
import (
|
||
"allapp-go/pkg/uniqueid"
|
||
"fmt"
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
var identRe = regexp.MustCompile(`^[a-zA-Z0-9_]+$`)
|
||
|
||
// 安全标识符校验
|
||
func safeIdent(name string) bool {
|
||
return identRe.MatchString(name)
|
||
}
|
||
|
||
// 表名引用(支持 schema)
|
||
func quoteTable(table string) string {
|
||
parts := strings.Split(table, ".")
|
||
for i, p := range parts {
|
||
if !safeIdent(p) {
|
||
panic(fmt.Sprintf("invalid table: %s", p))
|
||
}
|
||
parts[i] = `"` + p + `"`
|
||
}
|
||
return strings.Join(parts, ".")
|
||
}
|
||
|
||
// 字段引用
|
||
func quoteCol(col string) string {
|
||
if !safeIdent(col) {
|
||
panic(fmt.Sprintf("invalid column: %s", col))
|
||
}
|
||
return `"` + col + `"`
|
||
}
|
||
|
||
// 校验数据
|
||
func validateData(table string, keyField string, data map[string]any) (any, error) {
|
||
if table == "" {
|
||
return nil, fmt.Errorf("表名不能为空")
|
||
}
|
||
|
||
if len(data) == 0 {
|
||
return nil, fmt.Errorf("数据不能为空")
|
||
}
|
||
|
||
if keyField == "" {
|
||
return nil, fmt.Errorf("主键字段不能为空")
|
||
}
|
||
|
||
val, ok := data[keyField]
|
||
if !ok {
|
||
return nil, fmt.Errorf("缺少主键字段: %s", keyField)
|
||
}
|
||
|
||
if val == nil {
|
||
return nil, fmt.Errorf("主键字段值不能为空")
|
||
}
|
||
|
||
return val, nil
|
||
}
|
||
|
||
// 校验数据
|
||
func validateInsertData(table string, keyField string, data map[string]any) (any, error) {
|
||
if table == "" {
|
||
return nil, fmt.Errorf("表名不能为空")
|
||
}
|
||
|
||
if len(data) == 0 {
|
||
return nil, fmt.Errorf("数据不能为空")
|
||
}
|
||
|
||
if keyField == "" {
|
||
return nil, fmt.Errorf("主键字段不能为空")
|
||
}
|
||
|
||
val, _ := data[keyField]
|
||
|
||
return val, nil
|
||
}
|
||
|
||
func ensureID(data map[string]any, keyField string) {
|
||
v, ok := data[keyField]
|
||
|
||
if !ok || v == nil || v == "" {
|
||
data[keyField] = uniqueid.NextId()
|
||
}
|
||
}
|