db/db.go

262 lines
6.9 KiB
Go
Raw Normal View History

2024-10-11 11:32:50 +08:00
package db
import (
_ "embed"
"apigo.cc/gojs"
"apigo.cc/gojs/goja"
"github.com/ssgo/dao/dao"
"github.com/ssgo/db"
"github.com/ssgo/log"
"github.com/ssgo/u"
)
//go:embed db.ts
var dbTS string
//go:embed README.md
var dbMD string
2024-10-26 23:32:08 +08:00
var defaultDB = "default"
2024-10-11 11:32:50 +08:00
func init() {
obj := map[string]any{
"get": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
conn := db.GetDB(args.Str(0), args.Logger)
return vm.ToValue(makeDBObject(conn, nil))
},
"setDefault": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
2024-10-26 23:32:08 +08:00
defaultDB = args.Str(0)
conn := db.GetDB(defaultDB, args.Logger)
2024-10-11 11:32:50 +08:00
args.This.ToObject(vm).Set("conn", conn)
return nil
},
}
gojs.Register("apigo.cc/gojs/db", gojs.Module{
ObjectMaker: func(vm *goja.Runtime) gojs.Map {
2024-10-26 23:32:08 +08:00
conn := db.GetDB(defaultDB, gojs.GetLogger(vm))
2024-10-11 11:32:50 +08:00
dbObj := makeDBObject(conn, nil)
for k, v := range obj {
dbObj[k] = v
}
return dbObj
},
Desc: "db api by github.com/ssgo/db",
TsCode: dbTS,
Example: dbMD,
2024-10-27 00:36:18 +08:00
SetSSKey: func(key, iv []byte) {
db.SetEncryptKeys(key, iv)
},
2024-10-11 11:32:50 +08:00
})
}
func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
obj := map[string]any{
"conn": conn,
"tx": tx,
"query": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
var r *db.QueryResult
if tx != nil {
r = tx.Query(args.Str(0), args.Array(1)...)
} else {
r = conn.Query(args.Str(0), args.Array(1)...)
}
if r.Error == nil {
return vm.ToValue(makeQueryResult(r, r.MapResults()))
} else {
panic(vm.NewGoError(r.Error))
}
},
"query1": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
var r *db.QueryResult
if tx != nil {
r = tx.Query(args.Str(0), args.Array(1)...)
} else {
r = conn.Query(args.Str(0), args.Array(1)...)
}
if r.Error == nil {
return vm.ToValue(makeQueryResult(r, r.MapOnR1()))
} else {
panic(vm.NewGoError(r.Error))
}
},
"query11": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
var r *db.QueryResult
if tx != nil {
r = tx.Query(args.Str(0), args.Array(1)...)
} else {
r = conn.Query(args.Str(0), args.Array(1)...)
}
if r.Error == nil {
a := r.SliceResults()
if len(a) > 0 && len(a[0]) > 0 {
return vm.ToValue(makeQueryResult(r, a[0][0]))
}
return vm.ToValue(nil)
} else {
panic(vm.NewGoError(r.Error))
}
},
"exec": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
var r *db.ExecResult
if tx != nil {
r = tx.Exec(args.Str(0), args.Array(1)...)
} else {
r = conn.Exec(args.Str(0), args.Array(1)...)
}
if r.Error == nil {
return vm.ToValue(makeExecResult(r))
} else {
panic(vm.NewGoError(r.Error))
}
},
"insert": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 2)
var r *db.ExecResult
if tx != nil {
r = tx.Insert(args.Str(0), args.Any(1))
} else {
r = conn.Insert(args.Str(0), args.Any(1))
}
if r.Error == nil {
return vm.ToValue(makeExecResult(r))
} else {
panic(vm.NewGoError(r.Error))
}
},
"replace": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 2)
var r *db.ExecResult
if tx != nil {
r = tx.Replace(args.Str(0), args.Any(1))
} else {
r = conn.Replace(args.Str(0), args.Any(1))
}
if r.Error == nil {
return vm.ToValue(makeExecResult(r))
} else {
panic(vm.NewGoError(r.Error))
}
},
"update": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 3)
var r *db.ExecResult
if tx != nil {
r = tx.Update(args.Str(0), args.Any(1), args.Str(2), args.Array(3)...)
} else {
r = conn.Update(args.Str(0), args.Any(1), args.Str(2), args.Array(3)...)
}
if r.Error == nil {
return vm.ToValue(makeExecResult(r))
} else {
panic(vm.NewGoError(r.Error))
}
},
"delete": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 2)
var r *db.ExecResult
if tx != nil {
r = tx.Delete(args.Str(0), args.Str(1), args.Array(2)...)
} else {
r = conn.Delete(args.Str(0), args.Str(1), args.Array(2)...)
}
if r.Error == nil {
return vm.ToValue(makeExecResult(r))
} else {
panic(vm.NewGoError(r.Error))
}
},
2024-10-27 00:36:18 +08:00
"makeInKeys": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
return vm.ToValue(db.InKeys(args.Int(0)))
},
2024-10-11 11:32:50 +08:00
}
2024-10-26 23:32:08 +08:00
if tx == nil {
2024-10-11 11:32:50 +08:00
obj["make"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, _, logger := initDBArgs(argsIn, vm, 1)
2024-11-22 16:36:11 +08:00
erDesc := args.Str(0)
tryFile := gojs.FindPath(vm, erDesc)
2024-10-11 11:32:50 +08:00
if u.FileExists(tryFile) {
2024-11-22 16:36:11 +08:00
erDesc = u.ReadFileN(tryFile)
2024-10-11 11:32:50 +08:00
}
2024-11-22 16:36:11 +08:00
if err := dao.MakeDBFromDesc(conn, erDesc, logger); err == nil {
2024-10-11 11:32:50 +08:00
return nil
} else {
panic(vm.NewGoError(err))
}
}
2024-11-22 16:36:11 +08:00
obj["makeER"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, _, _, logger := initDBArgs(argsIn, vm, 1)
outputFile := args.Str(0)
erDesc := args.Str(1)
tryFile := gojs.FindPath(vm, erDesc)
if u.FileExists(tryFile) {
erDesc = u.ReadFileN(tryFile)
}
dao.MakeERFile(erDesc, "", outputFile, logger)
return nil
}
2024-10-11 11:32:50 +08:00
obj["destroy"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
_, conn, _, _ := initDBArgs(argsIn, vm, 0)
if err := conn.Destroy(); err == nil {
return nil
} else {
panic(vm.NewGoError(err))
}
}
obj["begin"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
_, conn, _, _ := initDBArgs(argsIn, vm, 0)
return vm.ToValue(makeDBObject(nil, conn.Begin()))
}
}
if tx != nil {
obj["end"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, _, tx, _ := initDBArgs(argsIn, vm, 1)
if err := tx.Finish(args.Bool(0)); err != nil {
panic(vm.NewGoError(err))
}
return nil
}
}
return obj
}
func makeQueryResult(r *db.QueryResult, result any) map[string]any {
return map[string]any{
"sql": *r.Sql,
"args": r.Args,
"result": result,
}
}
func makeExecResult(r *db.ExecResult) map[string]any {
return map[string]any{
"sql": *r.Sql,
"args": r.Args,
"id": r.Id(),
"changes": r.Changes(),
}
}
func initDBArgs(argsIn goja.FunctionCall, vm *goja.Runtime, checkArgsNum int) (*gojs.Arr, *db.DB, *db.Tx, *log.Logger) {
args := gojs.MakeArgs(&argsIn, vm).Check(checkArgsNum)
logger := args.Logger
conn, _ := args.This.ToObject(vm).Get("conn").Export().(*db.DB)
var tx *db.Tx
if conn == nil {
tx, _ = args.This.ToObject(vm).Get("tx").Export().(*db.Tx)
}
return args, conn, tx, logger
}