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 var defaultDB = "default" 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) defaultDB = args.Str(0) conn := db.GetDB(defaultDB, 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(defaultDB, 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, SetSSKey: func(key, iv []byte) { db.SetEncryptKeys(key, iv) }, }) } 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)) } }, "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))) }, } if tx == nil { obj["make"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { args, conn, _, logger := initDBArgs(argsIn, vm, 1) erDesc := args.Str(0) tryFile := gojs.FindPath(vm, erDesc) if u.FileExists(tryFile) { erDesc = u.ReadFileN(tryFile) } if err := dao.MakeDBFromDesc(conn, erDesc, logger); err == nil { return nil } else { panic(vm.NewGoError(err)) } } 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 } 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 }