241 lines
6.3 KiB
Go
241 lines
6.3 KiB
Go
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
|
|
|
|
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)
|
|
conn := db.GetDB(args.Str(0), args.Logger)
|
|
args.This.ToObject(vm).Set("conn", conn)
|
|
return nil
|
|
},
|
|
}
|
|
|
|
gojs.Register("apigo.cc/gojs/db", gojs.Module{
|
|
ObjectMaker: func(vm *goja.Runtime) gojs.Map {
|
|
conn := db.GetDB("default", gojs.GetLogger(vm))
|
|
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,
|
|
})
|
|
}
|
|
|
|
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))
|
|
}
|
|
},
|
|
}
|
|
|
|
if conn != nil {
|
|
obj["make"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
|
|
args, conn, _, logger := initDBArgs(argsIn, vm, 1)
|
|
arg0 := args.Str(0)
|
|
tryFile := gojs.FindPath(vm, arg0)
|
|
if u.FileExists(tryFile) {
|
|
arg0 = u.ReadFileN(tryFile)
|
|
}
|
|
if err := dao.MakeDBFromDesc(conn, args.Str(0), logger); err == nil {
|
|
return nil
|
|
} else {
|
|
panic(vm.NewGoError(err))
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|