From 1c96e85e0db62600dc746dd4e3a01e3b70a0582b Mon Sep 17 00:00:00 2001 From: Luis Davim Date: Sun, 31 Dec 2023 12:47:25 +0000 Subject: [PATCH 1/2] feat: sql module Signed-off-by: Luis Davim --- cmd/risor-lsp/go.mod | 4 +- cmd/risor-lsp/go.sum | 8 +- cmd/risor/go.mod | 8 ++ cmd/risor/go.sum | 32 ++++++ cmd/risor/root.go | 2 + examples/go/struct/go.mod | 4 +- examples/go/struct/go.sum | 8 +- examples/scripts/sql.risor | 22 ++++ go.work | 1 + go.work.sum | 10 +- modules/sql/db.go | 200 +++++++++++++++++++++++++++++++++++++ modules/sql/go.mod | 21 ++++ modules/sql/go.sum | 48 +++++++++ modules/sql/sql.go | 33 ++++++ tag.sh | 1 + 15 files changed, 388 insertions(+), 14 deletions(-) create mode 100755 examples/scripts/sql.risor create mode 100644 modules/sql/db.go create mode 100644 modules/sql/go.mod create mode 100644 modules/sql/go.sum create mode 100644 modules/sql/sql.go diff --git a/cmd/risor-lsp/go.mod b/cmd/risor-lsp/go.mod index 9a86ac0d..8ce813c4 100644 --- a/cmd/risor-lsp/go.mod +++ b/cmd/risor-lsp/go.mod @@ -12,7 +12,7 @@ require ( require ( github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - golang.org/x/sys v0.14.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/sys v0.15.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect ) diff --git a/cmd/risor-lsp/go.sum b/cmd/risor-lsp/go.sum index 74fbfd7b..5822732d 100644 --- a/cmd/risor-lsp/go.sum +++ b/cmd/risor-lsp/go.sum @@ -9,8 +9,8 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -23,8 +23,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/cmd/risor/go.mod b/cmd/risor/go.mod index 602dc35e..0e5df534 100644 --- a/cmd/risor/go.mod +++ b/cmd/risor/go.mod @@ -8,6 +8,7 @@ replace ( github.com/risor-io/risor/modules/image => ../../modules/image github.com/risor-io/risor/modules/kubernetes => ../../modules/kubernetes github.com/risor-io/risor/modules/pgx => ../../modules/pgx + github.com/risor-io/risor/modules/sql => ../../modules/sql github.com/risor-io/risor/modules/uuid => ../../modules/uuid github.com/risor-io/risor/os/s3fs => ../../os/s3fs ) @@ -25,6 +26,7 @@ require ( github.com/risor-io/risor/modules/image v1.1.1 github.com/risor-io/risor/modules/kubernetes v0.0.0-00010101000000-000000000000 github.com/risor-io/risor/modules/pgx v1.1.1 + github.com/risor-io/risor/modules/sql v0.0.0-00010101000000-000000000000 github.com/risor-io/risor/modules/uuid v1.1.1 github.com/risor-io/risor/os/s3fs v1.1.1 github.com/spf13/cobra v1.7.0 @@ -93,8 +95,11 @@ require ( github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.19.14 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect + github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect @@ -109,9 +114,11 @@ require ( github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.6 // indirect github.com/mattn/go-colorable v0.1.13 // indirect + github.com/microsoft/go-mssqldb v1.6.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -123,6 +130,7 @@ require ( github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/xo/dburl v0.20.0 // indirect golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20230314191032-db074128a8ec // indirect golang.org/x/image v0.14.0 // indirect diff --git a/cmd/risor/go.sum b/cmd/risor/go.sum index 3f4e58fc..6bffc6f9 100644 --- a/cmd/risor/go.sum +++ b/cmd/risor/go.sum @@ -38,6 +38,18 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/MarvinJWendt/testza v0.1.0/go.mod h1:7AxNvlfeHP7Z/hDQ5JtE3OKYT3XFUeLCDE2DQninSqs= @@ -216,10 +228,18 @@ github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXym github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -284,6 +304,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -339,6 +361,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= @@ -355,6 +381,8 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4 github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= +github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -375,6 +403,8 @@ github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmv github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -442,6 +472,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xo/dburl v0.20.0 h1:v601OhM9J4Zh56R270ncM9HRgoxp39tf9+nt5ft9UD0= +github.com/xo/dburl v0.20.0/go.mod h1:B7/G9FGungw6ighV8xJNwWYQPMfn3gsi2sn5SE8Bzco= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= diff --git a/cmd/risor/root.go b/cmd/risor/root.go index d5bb58c8..aa116b88 100644 --- a/cmd/risor/root.go +++ b/cmd/risor/root.go @@ -24,6 +24,7 @@ import ( "github.com/risor-io/risor/modules/image" k8s "github.com/risor-io/risor/modules/kubernetes" "github.com/risor-io/risor/modules/pgx" + "github.com/risor-io/risor/modules/sql" "github.com/risor-io/risor/modules/uuid" "github.com/risor-io/risor/object" ros "github.com/risor-io/risor/os" @@ -230,6 +231,7 @@ var rootCmd = &cobra.Command{ opts = append(opts, risor.WithGlobals(map[string]any{ "image": image.Module(), "pgx": pgx.Module(), + "sql": sql.Module(), "uuid": uuid.Module(), })) // AWS support may or may not be compiled in based on build tags diff --git a/examples/go/struct/go.mod b/examples/go/struct/go.mod index 904fa57d..825b0825 100644 --- a/examples/go/struct/go.mod +++ b/examples/go/struct/go.mod @@ -12,7 +12,7 @@ require ( require ( github.com/jmespath-community/go-jmespath v1.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect golang.org/x/exp v0.0.0-20230314191032-db074128a8ec // indirect - golang.org/x/sys v0.14.0 // indirect + golang.org/x/sys v0.15.0 // indirect ) diff --git a/examples/go/struct/go.sum b/examples/go/struct/go.sum index 0b578a13..0dd50553 100644 --- a/examples/go/struct/go.sum +++ b/examples/go/struct/go.sum @@ -7,8 +7,8 @@ github.com/jmespath-community/go-jmespath v1.1.1/go.mod h1:4gOyFJsR/Gk+05RgTKYri github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= @@ -17,7 +17,7 @@ golang.org/x/exp v0.0.0-20230314191032-db074128a8ec h1:pAv+d8BM2JNnNctsLJ6nnZ6Nq golang.org/x/exp v0.0.0-20230314191032-db074128a8ec/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/examples/scripts/sql.risor b/examples/scripts/sql.risor new file mode 100755 index 00000000..b208c019 --- /dev/null +++ b/examples/scripts/sql.risor @@ -0,0 +1,22 @@ +#!/usr/bin/env risor -- + +func connect(user="root", pass="root", host="localhost", port=3306, db="mysql") { + return sql.connect('mysql+tcp://{user}:{pass}@{host}:{port}/{db}') +} + +db := connect("root", "root") + +data := fetch('https://raw.githubusercontent.com/bbrumm/databasestar/main/sample_databases/sample_db_superheroes/mysql/01_reference_data.sql') + +data.text().split(';'). + each(func(row) { + row = row.trim_space() + if row != "" && !row.has_prefix('#') { + db.exec(row) + } + }) + +db.query("select full_name from superhero.superhero where superhero_name like 'Batman%'"). + each(func(row) { + print(row["full_name"]) + }) diff --git a/go.work b/go.work index aea1a4fb..c36e327e 100644 --- a/go.work +++ b/go.work @@ -9,6 +9,7 @@ use ( ./modules/aws ./modules/image ./modules/pgx + ./modules/sql ./modules/uuid ./os/s3fs ) diff --git a/go.work.sum b/go.work.sum index abbfc2f0..61509dd2 100644 --- a/go.work.sum +++ b/go.work.sum @@ -172,8 +172,6 @@ github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6 github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= @@ -185,11 +183,16 @@ github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/S github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= @@ -234,6 +237,7 @@ golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -251,8 +255,10 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= diff --git a/modules/sql/db.go b/modules/sql/db.go new file mode 100644 index 00000000..8bb02518 --- /dev/null +++ b/modules/sql/db.go @@ -0,0 +1,200 @@ +package sql + +import ( + "context" + "database/sql" + "fmt" + "sync" + + // TODO: we can add more drivers from this list: + // https://github.com/xo/dburl?tab=readme-ov-file#database-schemes-aliases-and-drivers + _ "github.com/go-sql-driver/mysql" + _ "github.com/lib/pq" + _ "github.com/microsoft/go-mssqldb" + "github.com/xo/dburl" + + "github.com/risor-io/risor/internal/arg" + "github.com/risor-io/risor/object" + "github.com/risor-io/risor/op" +) + +const DB_CONN object.Type = "db.conn" + +type DB struct { + conn *sql.DB + once sync.Once + closed chan bool +} + +func (db *DB) Type() object.Type { + return DB_CONN +} + +func (db *DB) Inspect() string { + return "sql.conn" +} + +func (db *DB) Interface() interface{} { + return db.conn +} + +func (db *DB) IsTruthy() bool { + return db.conn != nil +} + +func (db *DB) Cost() int { + return 8 +} + +func (db *DB) MarshalJSON() ([]byte, error) { + return nil, fmt.Errorf("type error: unable to marshal db.conn") +} + +func (db *DB) RunOperation(opType op.BinaryOpType, right object.Object) object.Object { + return object.Errorf("eval error: unsupported operation for %s: %v", DB_CONN, opType) +} + +func (db *DB) Equals(other object.Object) object.Object { + if other.Type() != DB_CONN { + return object.False + } + return object.NewBool(db.conn == other.(*DB).conn) +} + +func (db *DB) SetAttr(name string, value object.Object) error { + return fmt.Errorf("attribute error: %s object has no attribute %q", DB_CONN, name) +} + +func (db *DB) GetAttr(name string) (object.Object, bool) { + switch name { + case "query": + return object.NewBuiltin("sql.query", db.Query), true + case "exec": + return object.NewBuiltin("sql.exec", db.Exec), true + case "close": + return object.NewBuiltin("sql.close", func(ctx context.Context, args ...object.Object) object.Object { + if err := arg.Require("sql.close", 0, args); err != nil { + return err + } + if err := db.Close(); err != nil { + return object.NewError(err) + } + return object.Nil + }), true + } + return nil, false +} + +func (db *DB) Exec(ctx context.Context, args ...object.Object) object.Object { + numArgs := len(args) + if numArgs < 1 { + return object.Errorf("type error: sql.exec() requires at least one argument") + } + + query, errObj := object.AsString(args[0]) + if errObj != nil { + return errObj + } + + // Build list of query args as their Go types + var queryArgs []interface{} + for _, queryArg := range args[1:] { + queryArgs = append(queryArgs, queryArg.Interface()) + } + _, err := db.conn.Exec(query, queryArgs...) + if err != nil { + return object.NewError(err) + } + + return nil +} + +func (db *DB) Query(ctx context.Context, args ...object.Object) object.Object { + numArgs := len(args) + if numArgs < 1 { + return object.Errorf("type error: sql.query() requires at least one argument") + } + + query, errObj := object.AsString(args[0]) + if errObj != nil { + return errObj + } + + // Build list of query args as their Go types + var queryArgs []interface{} + for _, queryArg := range args[1:] { + queryArgs = append(queryArgs, queryArg.Interface()) + } + + // Start the query + rows, err := db.conn.Query(query, queryArgs...) + if err != nil || rows.Err() != nil { + return object.Errorf("failed to query db: %w", err) + } + defer rows.Close() + + columns, err := rows.Columns() + if err != nil { + return object.Errorf("failed to get columns: %w", err) + } + + rowList := object.NewList(make([]object.Object, 0)) + for rows.Next() { + rowValues := make([]interface{}, len(columns)) + for i := range rowValues { + var s interface{} + rowValues[i] = &s + } + if err := rows.Scan(rowValues...); err != nil { + return object.NewError(err) + } + + row := object.NewMap(make(map[string]object.Object)) + for i := range rowValues { + val := *(rowValues[i].(*interface{})) + switch val := val.(type) { + case []byte: + row.Set(columns[i], object.NewString(string(val))) + default: + row.Set(columns[i], object.FromGoType(val)) + } + } + + rowList.Append(row) + } + + return rowList +} + +func (db *DB) Close() error { + var err error + db.once.Do(func() { + err = db.conn.Close() + close(db.closed) + }) + return err +} + +func (db *DB) waitToClose(ctx context.Context) { + go func() { + select { + case <-db.closed: + case <-ctx.Done(): + _ = db.conn.Close() + } + }() +} + +func New(ctx context.Context, connection string) (*DB, error) { + db, err := dburl.Open(connection) + if err != nil { + return nil, fmt.Errorf("failed to connect to db: %w", err) + } + + obj := &DB{ + conn: db, + closed: make(chan bool), + } + obj.waitToClose(ctx) + return obj, nil +} diff --git a/modules/sql/go.mod b/modules/sql/go.mod new file mode 100644 index 00000000..bbcdb3a4 --- /dev/null +++ b/modules/sql/go.mod @@ -0,0 +1,21 @@ +module github.com/risor-io/risor/modules/sql + +go 1.21 + +replace github.com/risor-io/risor => ../.. + +require ( + github.com/go-sql-driver/mysql v1.7.0 + github.com/lib/pq v1.10.7 + github.com/microsoft/go-mssqldb v1.6.0 + github.com/risor-io/risor v1.1.0 + github.com/xo/dburl v0.20.0 +) + +require ( + github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect + github.com/golang-sql/sqlexp v0.1.0 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect +) diff --git a/modules/sql/go.sum b/modules/sql/go.sum new file mode 100644 index 00000000..302245e8 --- /dev/null +++ b/modules/sql/go.sum @@ -0,0 +1,48 @@ +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= +github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/xo/dburl v0.20.0 h1:v601OhM9J4Zh56R270ncM9HRgoxp39tf9+nt5ft9UD0= +github.com/xo/dburl v0.20.0/go.mod h1:B7/G9FGungw6ighV8xJNwWYQPMfn3gsi2sn5SE8Bzco= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/modules/sql/sql.go b/modules/sql/sql.go new file mode 100644 index 00000000..ccc4fe87 --- /dev/null +++ b/modules/sql/sql.go @@ -0,0 +1,33 @@ +package sql + +import ( + "context" + + "github.com/risor-io/risor/object" +) + +func Connect(ctx context.Context, args ...object.Object) object.Object { + numArgs := len(args) + + if numArgs < 1 { + return object.NewArgsError("sql.connect", 1, numArgs) + } + + connStr, err := object.AsString(args[0]) + if err != nil { + return err + } + + db, connErr := New(ctx, connStr) + if connErr != nil { + return object.NewError(connErr) + } + + return db +} + +func Module() *object.Module { + return object.NewBuiltinsModule("sql", map[string]object.Object{ + "connect": object.NewBuiltin("sql.connect", Connect), + }) +} diff --git a/tag.sh b/tag.sh index 5b458f1b..b53455af 100755 --- a/tag.sh +++ b/tag.sh @@ -22,6 +22,7 @@ git push origin $VERSION git push origin os/s3fs/$VERSION git push origin modules/uuid/$VERSION git push origin modules/pgx/$VERSION +git push origin modules/sql/$VERSION git push origin modules/image/$VERSION git push origin modules/aws/$VERSION git push origin modules/kubernetes/$VERSION From 68d055a52ca4eaa9130ab8b351176459ecf08d37 Mon Sep 17 00:00:00 2001 From: Luis Davim Date: Sun, 31 Dec 2023 12:55:30 +0000 Subject: [PATCH 2/2] refactor: use object.Errorf --- modules/aws/client.go | 2 +- modules/aws/config.go | 2 +- modules/exec/command.go | 2 +- modules/exec/exec.go | 6 +++--- modules/exec/result.go | 4 ++-- modules/http/request.go | 4 ++-- modules/http/response.go | 2 +- modules/jmespath/jmespath.go | 3 +-- modules/os/os.go | 3 +-- modules/pgx/pgx_conn.go | 2 +- 10 files changed, 14 insertions(+), 16 deletions(-) diff --git a/modules/aws/client.go b/modules/aws/client.go index 2b800cb8..6c953d0a 100644 --- a/modules/aws/client.go +++ b/modules/aws/client.go @@ -120,7 +120,7 @@ func (c *Client) IsTruthy() bool { } func (c *Client) RunOperation(opType op.BinaryOpType, right object.Object) object.Object { - return object.NewError(fmt.Errorf("eval error: unsupported operation for aws.client: %v ", opType)) + return object.Errorf("eval error: unsupported operation for aws.client: %v ", opType) } func (c *Client) Cost() int { diff --git a/modules/aws/config.go b/modules/aws/config.go index 11c434f9..8e1c0e0c 100644 --- a/modules/aws/config.go +++ b/modules/aws/config.go @@ -103,7 +103,7 @@ func (c *Config) IsTruthy() bool { } func (c *Config) RunOperation(opType op.BinaryOpType, right object.Object) object.Object { - return object.NewError(fmt.Errorf("eval error: unsupported operation for aws.config: %v ", opType)) + return object.Errorf("eval error: unsupported operation for aws.config: %v ", opType) } func (c *Config) Cost() int { diff --git a/modules/exec/command.go b/modules/exec/command.go index 697665c6..249388c3 100644 --- a/modules/exec/command.go +++ b/modules/exec/command.go @@ -207,7 +207,7 @@ func (c *Command) IsTruthy() bool { } func (c *Command) RunOperation(opType op.BinaryOpType, right object.Object) object.Object { - return object.NewError(fmt.Errorf("eval error: unsupported operation for exec.command: %v ", opType)) + return object.Errorf("eval error: unsupported operation for exec.command: %v ", opType) } func (c *Command) Cost() int { diff --git a/modules/exec/exec.go b/modules/exec/exec.go index adb94ec8..b58c20dc 100644 --- a/modules/exec/exec.go +++ b/modules/exec/exec.go @@ -72,14 +72,14 @@ func Exec(ctx context.Context, args ...object.Object) object.Object { if stdoutObj := params.GetWithDefault("stdout", nil); stdoutObj != nil { stdoutBuf, ok := stdoutObj.(io.Writer) if !ok { - return object.NewError(fmt.Errorf("eval error: exec expected io.Writer for stdout (%T given)", stdoutObj)) + return object.Errorf("eval error: exec expected io.Writer for stdout (%T given)", stdoutObj) } cmd.Stdout = stdoutBuf } if stderrObj := params.GetWithDefault("stderr", nil); stderrObj != nil { stderrBuf, ok := stderrObj.(io.Writer) if !ok { - return object.NewError(fmt.Errorf("eval error: exec expected io.Writer for stderr (%T given)", stderrObj)) + return object.Errorf("eval error: exec expected io.Writer for stderr (%T given)", stderrObj) } cmd.Stderr = stderrBuf } @@ -92,7 +92,7 @@ func Exec(ctx context.Context, args ...object.Object) object.Object { case io.Reader: cmd.Stdin = stdinObj default: - return object.NewError(fmt.Errorf("eval error: exec expected io.Reader for stdin (%T given)", stdinObj)) + return object.Errorf("eval error: exec expected io.Reader for stdin (%T given)", stdinObj) } } if dirObj := params.GetWithDefault("dir", nil); dirObj != nil { diff --git a/modules/exec/result.go b/modules/exec/result.go index c0cbd52b..1220861a 100644 --- a/modules/exec/result.go +++ b/modules/exec/result.go @@ -70,7 +70,7 @@ func (r *Result) JSON() object.Object { case *object.Buffer: data = stdout.Value().Bytes() default: - return object.NewError(fmt.Errorf("eval error: exec.result.json does not support stdout type %T", stdout)) + return object.Errorf("eval error: exec.result.json does not support stdout type %T", stdout) } var obj interface{} if err := json.Unmarshal(data, &obj); err != nil { @@ -107,7 +107,7 @@ func (r *Result) IsTruthy() bool { } func (r *Result) RunOperation(opType op.BinaryOpType, right object.Object) object.Object { - return object.NewError(fmt.Errorf("eval error: unsupported operation for exec.result: %v", opType)) + return object.Errorf("eval error: unsupported operation for exec.result: %v", opType) } func (r *Result) Cost() int { diff --git a/modules/http/request.go b/modules/http/request.go index 55921d24..e6332e81 100644 --- a/modules/http/request.go +++ b/modules/http/request.go @@ -166,7 +166,7 @@ func (r *HttpRequest) Cost() int { } func (r *HttpRequest) RunOperation(opType op.BinaryOpType, right object.Object) object.Object { - return object.NewError(fmt.Errorf("eval error: unsupported operation for http.request: %v", opType)) + return object.Errorf("eval error: unsupported operation for http.request: %v", opType) } func (r *HttpRequest) AddHeaders(headers *object.Map) { @@ -333,7 +333,7 @@ func (r *HttpRequest) Send(ctx context.Context) object.Object { return object.NewError(limits.LimitsNotFound) } if r.req == nil { - return object.NewError(fmt.Errorf("bad request")) + return object.Errorf("bad request") } if r.client == nil { r.client = &http.Client{} diff --git a/modules/http/response.go b/modules/http/response.go index b30293d6..b75ffe8e 100644 --- a/modules/http/response.go +++ b/modules/http/response.go @@ -183,7 +183,7 @@ func (r *HttpResponse) Equals(other object.Object) object.Object { } func (r *HttpResponse) RunOperation(opType op.BinaryOpType, right object.Object) object.Object { - return object.NewError(fmt.Errorf("eval error: unsupported operation for http.response: %v", opType)) + return object.Errorf("eval error: unsupported operation for http.response: %v", opType) } func (r *HttpResponse) Cost() int { diff --git a/modules/jmespath/jmespath.go b/modules/jmespath/jmespath.go index fc2e6075..ac34efbd 100644 --- a/modules/jmespath/jmespath.go +++ b/modules/jmespath/jmespath.go @@ -2,7 +2,6 @@ package jmespath import ( "context" - "fmt" "github.com/jmespath-community/go-jmespath/pkg/api" "github.com/jmespath-community/go-jmespath/pkg/parsing" @@ -28,7 +27,7 @@ func Jmespath(ctx context.Context, args ...object.Object) object.Object { if _, err := parsing.NewParser().Parse(expression); err != nil { if syntaxError, ok := err.(parsing.SyntaxError); ok { - return object.NewError(fmt.Errorf("%s\n%s", syntaxError, syntaxError.HighlightLocation())) + return object.Errorf("%s\n%s", syntaxError, syntaxError.HighlightLocation()) } return object.NewError(err) } diff --git a/modules/os/os.go b/modules/os/os.go index fd98e562..d29b5604 100644 --- a/modules/os/os.go +++ b/modules/os/os.go @@ -3,7 +3,6 @@ package os import ( "bytes" "context" - "fmt" "github.com/risor-io/risor/internal/arg" "github.com/risor-io/risor/object" @@ -298,7 +297,7 @@ func WriteFile(ctx context.Context, args ...object.Object) object.Object { case *object.String: data = []byte(arg.Value()) default: - return object.NewError(fmt.Errorf("type error: expected byte_slice or string (got %s)", args[1].Type())) + return object.Errorf("type error: expected byte_slice or string (got %s)", args[1].Type()) } var perm int64 = 0644 if len(args) == 3 { diff --git a/modules/pgx/pgx_conn.go b/modules/pgx/pgx_conn.go index 733156f6..afaa967f 100644 --- a/modules/pgx/pgx_conn.go +++ b/modules/pgx/pgx_conn.go @@ -70,7 +70,7 @@ func (c *PgxConn) SetAttr(name string, value object.Object) error { } func (c *PgxConn) RunOperation(opType op.BinaryOpType, right object.Object) object.Object { - return object.NewError(fmt.Errorf("eval error: unsupported operation for pgx.conn: %v", opType)) + return object.Errorf("eval error: unsupported operation for pgx.conn: %v", opType) } func (c *PgxConn) Close() error {