feat(db): 具名化 JS 导出并动态包裹错误(by AI)

This commit is contained in:
AI Engineer 2026-06-21 10:36:31 +08:00
parent c8ab5ec3d1
commit 6ca41963e1
5 changed files with 247 additions and 123 deletions

View File

@ -1,5 +1,24 @@
# 变更记录 - @go/db # 变更记录 - @go/db
## [1.5.7] - 2026-06-21
- **错误堆栈重构**:
- 重构 `js_export.go`,将匿名函数改写为包级具名函数。
- 在返回错误或向结果结构注入错误时,使用 `jsmod.MakeError` 动态包裹,以携带完整的调用堆栈。
- **依赖对齐**:
- 升级依赖 `jsmod``v1.5.3`, `cast``v1.5.3`, `rand``v1.5.3`, `encoding``v1.5.4`, `shell``v1.5.3`, `safe``v1.5.2`, `id``v1.5.4`, `crypto``v1.5.3`, `file``v1.5.5`, `config``v1.5.3`, `log``v1.5.8`, `redis``v1.5.6`
## [1.5.6] - 2026-06-11
- **依赖对齐**:
- 对齐基础设施依赖到 v1.5.x。
## [1.5.5] - 2026-06-10
- **优化**:
- 导出 PascalCase 格式的 JS 接口并平铺默认实例。
## [1.5.4] - 2026-06-10
- **重构**:
- 使用 `jsmod.Get` 进行上下文配置提取。
## [1.5.3] - 2026-06-08 ## [1.5.3] - 2026-06-08
- **新增**: `SetConfig(name, setting string)` 方法,支持动态配置数据库连接(不依赖配置文件),方便通过别名获取连接。 - **新增**: `SetConfig(name, setting string)` 方法,支持动态配置数据库连接(不依赖配置文件),方便通过别名获取连接。
- **优化**: 重构配置加载逻辑,支持动态配置与 `config/db.yaml` 配置文件配置共存。 - **优化**: 重构配置加载逻辑,支持动态配置与 `config/db.yaml` 配置文件配置共存。

View File

@ -6,7 +6,7 @@
- **通过**: 13 - **通过**: 13
- **失败**: 0 - **失败**: 0
- **编译状态**: 成功 (Success) - **编译状态**: 成功 (Success)
- **测试日期**: 2026-05-13 - **测试日期**: 2026-06-21
## ✅ 详细详情 ## ✅ 详细详情
| 测试用例 | 状态 | 耗时 | 备注 | | 测试用例 | 状态 | 耗时 | 备注 |

24
go.mod
View File

@ -3,16 +3,16 @@ module apigo.cc/go/db
go 1.25.0 go 1.25.0
require ( require (
apigo.cc/go/cast v1.5.2 apigo.cc/go/cast v1.5.3
apigo.cc/go/config v1.5.2 apigo.cc/go/config v1.5.3
apigo.cc/go/crypto v1.5.2 apigo.cc/go/crypto v1.5.3
apigo.cc/go/file v1.5.4 apigo.cc/go/file v1.5.5
apigo.cc/go/id v1.5.3 apigo.cc/go/id v1.5.4
apigo.cc/go/jsmod v1.5.2 apigo.cc/go/jsmod v1.5.3
apigo.cc/go/log v1.5.6 apigo.cc/go/log v1.5.8
apigo.cc/go/redis v1.5.4 apigo.cc/go/redis v1.5.6
apigo.cc/go/safe v1.5.1 apigo.cc/go/safe v1.5.2
apigo.cc/go/shell v1.5.2 apigo.cc/go/shell v1.5.3
github.com/go-sql-driver/mysql v1.10.0 github.com/go-sql-driver/mysql v1.10.0
github.com/jackc/pgx/v5 v5.9.2 github.com/jackc/pgx/v5 v5.9.2
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0
@ -20,8 +20,8 @@ require (
) )
require ( require (
apigo.cc/go/encoding v1.5.3 // indirect apigo.cc/go/encoding v1.5.4 // indirect
apigo.cc/go/rand v1.5.2 // indirect apigo.cc/go/rand v1.5.3 // indirect
filippo.io/edwards25519 v1.2.0 // indirect filippo.io/edwards25519 v1.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gomodule/redigo v2.0.0+incompatible // indirect github.com/gomodule/redigo v2.0.0+incompatible // indirect

55
go.sum
View File

@ -1,27 +1,27 @@
apigo.cc/go/cast v1.5.0 h1:UBGJtFQ8eJPMQXs37cUgqd7YQo1zI9opuSDBDmn2/pE= apigo.cc/go/cast v1.5.3 h1:jk6VX0rGFhjKtfPhsaV6IKYpiGmORRk9qPTtuNS53tw=
apigo.cc/go/cast v1.5.0/go.mod h1:z2GW5p5WCZGEqVVIJUdhl232vRbLf2Qu4EDlEakX/D8= apigo.cc/go/cast v1.5.3/go.mod h1:GMjjrYn93tWat1U409G7h1jR3ejfLLI7r0efBo9Sbd4=
apigo.cc/go/config v1.5.1 h1:rpj7oCzlsDV3f2/YK3Pb+CHbfr2DL5Vyyv6VNkobJP4= apigo.cc/go/config v1.5.3 h1:peq1FM2xO+vzPHJf8Dwg3DXm8PtFQMfTFKQj6fpoG7A=
apigo.cc/go/config v1.5.1/go.mod h1:jdMiDLPa9gzB8/FFZvm9jOopUqdxb7XSX+0OeWcZZUM= apigo.cc/go/config v1.5.3/go.mod h1:ZiOAjWa1mQIzszaJZN+kO6YU4GXreng+NxkcK/TAkqQ=
apigo.cc/go/crypto v1.5.0 h1:Nxz7a6VKCdvaF258IU0NkjQyureOLxfR308Sy2iftUI= apigo.cc/go/crypto v1.5.3 h1:2JUHC2cgR2zrnn36EzwkUAdxmmTXAA/8yTNo+2X1mPE=
apigo.cc/go/crypto v1.5.0/go.mod h1:F9M6nXv+5328r1ZwbTvI6fcr8VdgqHVzALOcsdv6ntE= apigo.cc/go/crypto v1.5.3/go.mod h1:PheYKHEXmoEFI1AK5PpY1borQWcRlkkSaWncT3cWbhE=
apigo.cc/go/encoding v1.5.0 h1:EJNdRVDOMoI2DAvZwQNQTbYuqB/6zsEzvg7lS5pQI+I= apigo.cc/go/encoding v1.5.4 h1:Fk8TrveZATyy8SHukC4ZiqdTSp+QIfsRHtt55xmMK7w=
apigo.cc/go/encoding v1.5.0/go.mod h1:8++NfZj3hWig0qh2g7GQRw/4LpSvCYMWUZ+8J+x58cA= apigo.cc/go/encoding v1.5.4/go.mod h1:dShEsZ3gKqBINz7TSOYf4e7/fBCqCY9VzlenoGUQUFM=
apigo.cc/go/file v1.5.0 h1:Fh1NSDBqaxjuXYJ71yPHPXVJ8BFEv/AGS3l+jkLi5uw= apigo.cc/go/file v1.5.5 h1:/+HmDumLu6Qk2KuQL63M9lpgzHTDL+QJ8dStOl7e9gs=
apigo.cc/go/file v1.5.0/go.mod h1:4YhOGgBINTpmmmgws3H8LAyXQQBGzBp44hYUoCS+kr0= apigo.cc/go/file v1.5.5/go.mod h1:xRVNhctvqOKeBemmcRW/BQfgkc3B+vT/UZVdSc7duUo=
apigo.cc/go/id v1.5.0 h1:MjNWPhBhDsoXaLeJDv/0wfJmVMU9EvOs8pWYfsTQ6e8= apigo.cc/go/id v1.5.4 h1:D1Zx9gEZhOgdTgZ4SdmPImhpc9xGiOA33Y+j2MkstzQ=
apigo.cc/go/id v1.5.0/go.mod h1:qhu4a1/KLc/XcBpcsRu+mXZt7U7Wvd9zMcPs4VspuPA= apigo.cc/go/id v1.5.4/go.mod h1:hCTQq+KC1ALWe1FpPERf+W4B6FSulg9FAgOUJDDySiY=
apigo.cc/go/jsmod v1.5.0 h1:JgQtJNiJWy1NOP9AzE8NX5VXJkpO/x3GqLsCCSny5Ec= apigo.cc/go/jsmod v1.5.3 h1:S3W317bH0QV2NMeRO1E0v6ySIBOfMWYv/NuQJbvqKWU=
apigo.cc/go/jsmod v1.5.0/go.mod h1:bmyeZtOAP/j5am+YRnaiM89smysK24K7ebk0koFtsSw= apigo.cc/go/jsmod v1.5.3/go.mod h1:bmyeZtOAP/j5am+YRnaiM89smysK24K7ebk0koFtsSw=
apigo.cc/go/log v1.5.4 h1:LNyU4v09gfcnZOY53ctnXoKzo45FHoEcPR33lk6PBaY= apigo.cc/go/log v1.5.8 h1:/IYtGPWhRjT3OayylDIphkWZIQbpLjqVeSnFEiD3Dy0=
apigo.cc/go/log v1.5.4/go.mod h1:Djy+I5aLhGB/EjwRz4KHqkVEz584IAD55FAFiIfInuo= apigo.cc/go/log v1.5.8/go.mod h1:HfFPANMYxJx197SSTXB21Pgxcz/gGqPP8nlSErgd5WE=
apigo.cc/go/rand v1.5.0 h1:1o8hh8fhdBuk1/h02IvugvamuT3dkWbVJrqEJVQKB2E= apigo.cc/go/rand v1.5.3 h1:O4bPIwyaOWEBCr0nL9A4G4qG48AqiGTCzfPeckm3Ius=
apigo.cc/go/rand v1.5.0/go.mod h1:Lh98S2dm9UY0X+M+kNQQEKyXHG5pcCKSFPyXN0QCGdk= apigo.cc/go/rand v1.5.3/go.mod h1:q1BTFkY/cXE229dDD5Q22lF7T0DoKPV6xAu+6bCrDH4=
apigo.cc/go/redis v1.5.0 h1:VXNDqzKj87BchF7ubDEH+T6lp8NrjeK0izU4ooo7u1A= apigo.cc/go/redis v1.5.6 h1:Lzo8M2binfqdQdVVp31Z/Max4qT8D82QdZjLlLQsrIY=
apigo.cc/go/redis v1.5.0/go.mod h1:/olsrHndkUNezUX1KbBBt8b4Got7SX7E8EJzcb1PknM= apigo.cc/go/redis v1.5.6/go.mod h1:HmqSh2Ll7/b2zFXDi2Ap13YOuMCVniuZNbwtxkbIYII=
apigo.cc/go/safe v1.5.0 h1:W1NblmcU8cex1f9Y5z8mNLUJOzZTE1s6fszb3FbhGnk= apigo.cc/go/safe v1.5.2 h1:EnuEOW/SGwf/5A0nw9LnqfKJE071+TIc6ez8HI9R9Lg=
apigo.cc/go/safe v1.5.0/go.mod h1:OfQ5d6COePSGEuPvMeOk6KagX2sezw7nvKh7exj9SeM= apigo.cc/go/safe v1.5.2/go.mod h1:2GqCCLLGex4OAhdET3iBWm1R+LIYtmTrvHP8W0iESSw=
apigo.cc/go/shell v1.5.0 h1:WLDMMqUU0INeaBDmQsTPr0h/NfB2RknAtiJ5NL467+Q= apigo.cc/go/shell v1.5.3 h1:pI+u12sy6upoygq+1XXqUlvUboBfH4Q52jRpoJFv56A=
apigo.cc/go/shell v1.5.0/go.mod h1:rYHA77d5hEsQHcJrbAWf1pHy0sxayeJ0gU55LA/JWQk= apigo.cc/go/shell v1.5.3/go.mod h1:FdZWUrcXHGJXo725oSyHqAeFoX0E9yY3PDhrz9hujgY=
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -52,6 +52,7 @@ github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NB
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
@ -86,23 +87,29 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.28.2 h1:3tQ0lf2ADtoby2EtSP+J7IE2SHwEJdP8ioR59wx7XpY= modernc.org/cc/v4 v4.28.2 h1:3tQ0lf2ADtoby2EtSP+J7IE2SHwEJdP8ioR59wx7XpY=
modernc.org/cc/v4 v4.28.2/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
modernc.org/ccgo/v4 v4.34.2 h1:mxsy2FdrB6+qG3NfXefz1AmWv0ehOSDO4jxgxd7h9yo= modernc.org/ccgo/v4 v4.34.2 h1:mxsy2FdrB6+qG3NfXefz1AmWv0ehOSDO4jxgxd7h9yo=
modernc.org/ccgo/v4 v4.34.2/go.mod h1:1L7us56+kAKu04p25EATpmBBvhbcqqZ85ibqWVwVgog=
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM= modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU= modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.3 h1:6QAplYyVO+KdPW3pGnqmJDUxtkec8ooEWvks/hhU3lc= modernc.org/gc/v3 v3.1.3 h1:6QAplYyVO+KdPW3pGnqmJDUxtkec8ooEWvks/hhU3lc=
modernc.org/gc/v3 v3.1.3/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.72.5 h1:m2OGx9Ser1VvTS4Z9ZJlWs+CBMxutLaTiAWkNz+NB9U= modernc.org/libc v1.72.5 h1:m2OGx9Ser1VvTS4Z9ZJlWs+CBMxutLaTiAWkNz+NB9U=
modernc.org/libc v1.72.5/go.mod h1:np0N7KDJ7eUtMZmOqVZNldrZyG+DHLl2B5pg8Hbar3U=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg= modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg=
modernc.org/opt v0.2.0/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.51.0 h1:aH/MMSoayAIhozZ7uJbVTT9QO/VhzBf0J9tymmmuC/U= modernc.org/sqlite v1.51.0 h1:aH/MMSoayAIhozZ7uJbVTT9QO/VhzBf0J9tymmmuC/U=
modernc.org/sqlite v1.51.0/go.mod h1:tcNzv5p84E0skkmJn038y+hWJbLQXQqEnQfeh5r2JLM=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=

View File

@ -13,65 +13,107 @@ import (
func init() { func init() {
jsmod.Register("db", map[string]any{ jsmod.Register("db", map[string]any{
// 入口:支持别名获取,不传则默认 "default" // 入口:支持别名获取,不传则默认 "default"
"Get": func(ctx context.Context, name *string) (*jsDB, error) { "Get": jsGet,
"Query": jsQuery,
"Exec": jsExec,
"Insert": jsInsert,
"Update": jsUpdate,
"Delete": jsDelete,
"Replace": jsReplace,
"Begin": jsBegin,
})
}
func jsGet(ctx context.Context, name *string) (*jsDB, error) {
target := "default" target := "default"
if name != nil { if name != nil {
target = *name target = *name
} }
return getJSDB(ctx, target) db, err := getJSDB(ctx, target)
}, if err != nil {
return nil, jsmod.MakeError(err)
}
return db, nil
}
// 默认快捷调用 (面向 "default" 实例) func jsQuery(ctx context.Context, query string, args ...any) (*QueryResult, error) {
"Query": func(ctx context.Context, query string, args ...any) (*QueryResult, error) {
jd, err := getJSDB(ctx, "default") jd, err := getJSDB(ctx, "default")
if err != nil { if err != nil {
return nil, err return nil, jsmod.MakeError(err)
} }
return jd.Query(query, args...), nil res := jd.Query(query, args...)
}, if res != nil && res.Error != nil {
"Exec": func(ctx context.Context, query string, args ...any) (*ExecResult, error) { res.Error = jsmod.MakeError(res.Error)
jd, err := getJSDB(ctx, "default")
if err != nil {
return nil, err
} }
return jd.Exec(query, args...), nil return res, nil
}, }
"Insert": func(ctx context.Context, table string, data any) (*ExecResult, error) {
func jsExec(ctx context.Context, query string, args ...any) (*ExecResult, error) {
jd, err := getJSDB(ctx, "default") jd, err := getJSDB(ctx, "default")
if err != nil { if err != nil {
return nil, err return nil, jsmod.MakeError(err)
} }
return jd.Insert(table, data), nil res := jd.Exec(query, args...)
}, if res != nil && res.Error != nil {
"Update": func(ctx context.Context, table string, data any, conditions string, args ...any) (*ExecResult, error) { res.Error = jsmod.MakeError(res.Error)
jd, err := getJSDB(ctx, "default")
if err != nil {
return nil, err
} }
return jd.Update(table, data, conditions, args...), nil return res, nil
}, }
"Delete": func(ctx context.Context, table string, conditions string, args ...any) (*ExecResult, error) {
func jsInsert(ctx context.Context, table string, data any) (*ExecResult, error) {
jd, err := getJSDB(ctx, "default") jd, err := getJSDB(ctx, "default")
if err != nil { if err != nil {
return nil, err return nil, jsmod.MakeError(err)
} }
return jd.Delete(table, conditions, args...), nil res := jd.Insert(table, data)
}, if res != nil && res.Error != nil {
"Replace": func(ctx context.Context, table string, data any) (*ExecResult, error) { res.Error = jsmod.MakeError(res.Error)
jd, err := getJSDB(ctx, "default")
if err != nil {
return nil, err
} }
return jd.Replace(table, data), nil return res, nil
}, }
"Begin": func(ctx context.Context) (*jsTx, error) {
func jsUpdate(ctx context.Context, table string, data any, conditions string, args ...any) (*ExecResult, error) {
jd, err := getJSDB(ctx, "default") jd, err := getJSDB(ctx, "default")
if err != nil { if err != nil {
return nil, err return nil, jsmod.MakeError(err)
}
res := jd.Update(table, data, conditions, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res, nil
}
func jsDelete(ctx context.Context, table string, conditions string, args ...any) (*ExecResult, error) {
jd, err := getJSDB(ctx, "default")
if err != nil {
return nil, jsmod.MakeError(err)
}
res := jd.Delete(table, conditions, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res, nil
}
func jsReplace(ctx context.Context, table string, data any) (*ExecResult, error) {
jd, err := getJSDB(ctx, "default")
if err != nil {
return nil, jsmod.MakeError(err)
}
res := jd.Replace(table, data)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res, nil
}
func jsBegin(ctx context.Context) (*jsTx, error) {
jd, err := getJSDB(ctx, "default")
if err != nil {
return nil, jsmod.MakeError(err)
} }
return jd.Begin() return jd.Begin()
},
})
} }
func getJSDB(ctx context.Context, name string) (*jsDB, error) { func getJSDB(ctx context.Context, name string) (*jsDB, error) {
@ -87,7 +129,7 @@ func getJSDB(ctx context.Context, name string) (*jsDB, error) {
} }
_, err := file.VerifyPathForSafeMode(ctx, path) _, err := file.VerifyPathForSafeMode(ctx, path)
if err != nil { if err != nil {
return nil, err return nil, jsmod.MakeError(err)
} }
isReadOnly = false isReadOnly = false
} else { } else {
@ -109,7 +151,7 @@ func getJSDB(ctx context.Context, name string) (*jsDB, error) {
d := GetDB(name, nil) d := GetDB(name, nil)
if d.Error != nil { if d.Error != nil {
return nil, d.Error return nil, jsmod.MakeError(d.Error)
} }
return &jsDB{db: d, ctx: ctx, isReadOnly: isReadOnly}, nil return &jsDB{db: d, ctx: ctx, isReadOnly: isReadOnly}, nil
} }
@ -131,50 +173,74 @@ func (jd *jsDB) checkWrite() error {
// Read Operations // Read Operations
func (jd *jsDB) Query(query string, args ...any) *QueryResult { func (jd *jsDB) Query(query string, args ...any) *QueryResult {
return jd.db.Query(query, args...) res := jd.db.Query(query, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
// Write Operations // Write Operations
func (jd *jsDB) Exec(query string, args ...any) *ExecResult { func (jd *jsDB) Exec(query string, args ...any) *ExecResult {
if err := jd.checkWrite(); err != nil { if err := jd.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jd.db.Exec(query, args...) res := jd.db.Exec(query, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jd *jsDB) Insert(table string, data any) *ExecResult { func (jd *jsDB) Insert(table string, data any) *ExecResult {
if err := jd.checkWrite(); err != nil { if err := jd.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jd.db.Insert(table, data) res := jd.db.Insert(table, data)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jd *jsDB) Update(table string, data any, conditions string, args ...any) *ExecResult { func (jd *jsDB) Update(table string, data any, conditions string, args ...any) *ExecResult {
if err := jd.checkWrite(); err != nil { if err := jd.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jd.db.Update(table, data, conditions, args...) res := jd.db.Update(table, data, conditions, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jd *jsDB) Delete(table string, conditions string, args ...any) *ExecResult { func (jd *jsDB) Delete(table string, conditions string, args ...any) *ExecResult {
if err := jd.checkWrite(); err != nil { if err := jd.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jd.db.Delete(table, conditions, args...) res := jd.db.Delete(table, conditions, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jd *jsDB) Replace(table string, data any) *ExecResult { func (jd *jsDB) Replace(table string, data any) *ExecResult {
if err := jd.checkWrite(); err != nil { if err := jd.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jd.db.Replace(table, data) res := jd.db.Replace(table, data)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
// Transaction Support // Transaction Support
func (jd *jsDB) Begin() (*jsTx, error) { func (jd *jsDB) Begin() (*jsTx, error) {
tx := jd.db.Begin() tx := jd.db.Begin()
if tx.Error != nil { if tx.Error != nil {
return nil, tx.Error return nil, jsmod.MakeError(tx.Error)
} }
return &jsTx{tx: tx, ctx: jd.ctx, isReadOnly: jd.isReadOnly}, nil return &jsTx{tx: tx, ctx: jd.ctx, isReadOnly: jd.isReadOnly}, nil
} }
@ -198,49 +264,81 @@ func (jt *jsTx) checkWrite() error {
} }
func (jt *jsTx) Query(query string, args ...any) *QueryResult { func (jt *jsTx) Query(query string, args ...any) *QueryResult {
return jt.tx.Query(query, args...) res := jt.tx.Query(query, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jt *jsTx) Exec(query string, args ...any) *ExecResult { func (jt *jsTx) Exec(query string, args ...any) *ExecResult {
if err := jt.checkWrite(); err != nil { if err := jt.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jt.tx.Exec(query, args...) res := jt.tx.Exec(query, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jt *jsTx) Insert(table string, data any) *ExecResult { func (jt *jsTx) Insert(table string, data any) *ExecResult {
if err := jt.checkWrite(); err != nil { if err := jt.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jt.tx.Insert(table, data) res := jt.tx.Insert(table, data)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jt *jsTx) Update(table string, data any, conditions string, args ...any) *ExecResult { func (jt *jsTx) Update(table string, data any, conditions string, args ...any) *ExecResult {
if err := jt.checkWrite(); err != nil { if err := jt.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jt.tx.Update(table, data, conditions, args...) res := jt.tx.Update(table, data, conditions, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jt *jsTx) Delete(table string, conditions string, args ...any) *ExecResult { func (jt *jsTx) Delete(table string, conditions string, args ...any) *ExecResult {
if err := jt.checkWrite(); err != nil { if err := jt.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jt.tx.Delete(table, conditions, args...) res := jt.tx.Delete(table, conditions, args...)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jt *jsTx) Replace(table string, data any) *ExecResult { func (jt *jsTx) Replace(table string, data any) *ExecResult {
if err := jt.checkWrite(); err != nil { if err := jt.checkWrite(); err != nil {
return &ExecResult{Error: err} return &ExecResult{Error: jsmod.MakeError(err)}
} }
return jt.tx.Replace(table, data) res := jt.tx.Replace(table, data)
if res != nil && res.Error != nil {
res.Error = jsmod.MakeError(res.Error)
}
return res
} }
func (jt *jsTx) Commit() error { func (jt *jsTx) Commit() error {
if err := jt.checkWrite(); err != nil { if err := jt.checkWrite(); err != nil {
return err return jsmod.MakeError(err)
} }
return jt.tx.Commit() if err := jt.tx.Commit(); err != nil {
return jsmod.MakeError(err)
}
return nil
} }
func (jt *jsTx) Rollback() error { return jt.tx.Rollback() } func (jt *jsTx) Rollback() error {
if err := jt.tx.Rollback(); err != nil {
return jsmod.MakeError(err)
}
return nil
}