From 61604b22cc75ebd723b7cb2ee4a9023fed5b4c8d Mon Sep 17 00:00:00 2001 From: sxwebdev Date: Thu, 11 Apr 2024 10:10:22 -0700 Subject: [PATCH] keystone and include table columns --- Makefile | 8 +- README.md | 9 +- cmd/pgxgen/main.go | 2 +- go.mod | 80 +++-- go.sum | 213 ++++++------ internal/assets/templates/constants.templ | 106 ++++++ internal/assets/templates/constants_templ.go | 142 ++++++++ .../assets/templates/crud-constants.go.tmpl | 19 -- .../assets/templates/keystone-model.go.tmpl | 6 +- internal/config/go_constants.go | 3 +- internal/crud/crud.go | 4 +- internal/goconstatnts/goconstatnts.go | 47 +-- internal/goconstatnts/params.go | 35 +- internal/gomodels/gomodels.go | 88 +++-- internal/keystone/keystone.go | 88 +---- internal/sqlc/movemodels.go | 8 +- internal/sqlc/replace.go | 2 +- internal/structs/field.go | 8 + internal/structs/parameters.go | 9 +- internal/structs/parser.go | 103 ++++++ internal/structs/pgxgen_test.go | 32 ++ internal/structs/slice.go | 4 + internal/structs/structs.go | 307 +++++++++++++++++- internal/typescript/typescript.go | 7 +- pkg/logger/types.go | 16 +- pkg/sqlc/analyzer/analyzer.go | 2 +- pkg/sqlc/cmd/cmd.go | 1 - pkg/sqlc/cmd/generate.go | 14 + pkg/sqlc/codegen/golang/driver.go | 46 +-- pkg/sqlc/codegen/golang/gen.go | 9 +- pkg/sqlc/codegen/golang/imports.go | 21 +- pkg/sqlc/codegen/golang/mysql_type.go | 16 +- pkg/sqlc/codegen/golang/opts/enum.go | 64 ++++ pkg/sqlc/codegen/golang/opts/options.go | 25 ++ pkg/sqlc/codegen/golang/postgresql_type.go | 118 +++---- pkg/sqlc/codegen/golang/query.go | 3 +- pkg/sqlc/codegen/golang/struct.go | 4 +- .../go-sql-driver-mysql/copyfromCopy.tmpl | 2 +- .../golang/templates/pgx/batchCode.tmpl | 2 +- .../codegen/golang/templates/template.tmpl | 13 + pkg/sqlc/config/v_two.go | 2 +- pkg/sqlc/engine/dolphin/stdlib.go | 9 + pkg/sqlc/engine/postgresql/convert.go | 15 +- pkg/sqlc/engine/postgresql/parse.go | 6 +- pkg/sqlc/engine/postgresql/parse_default.go | 2 +- .../postgresql/parser/parser_default.go | 2 +- pkg/sqlc/engine/postgresql/utils.go | 2 +- pkg/sqlc/engine/sqlite/parse.go | 1 + pkg/sqlc/info/facts.go | 2 +- pkg/sqlc/pgx/poolcache/poolcache.go | 32 ++ pkg/sqlc/sql/ast/aggref.go | 1 - pkg/sqlc/sql/ast/grant_role_stmt.go | 1 - pkg/sqlc/sql/ast/index_stmt.go | 1 - pkg/sqlc/sql/ast/op_expr.go | 1 - pkg/sqlc/sql/ast/scalar_array_op_expr.go | 1 - pkg/sqlc/sqltest/local/postgres.go | 100 +++--- testdata/teststructs/teststructs.go | 17 + testdata/teststructs/unexported.go | 6 + utils/files.go | 2 +- utils/go_files.go | 2 +- 60 files changed, 1335 insertions(+), 556 deletions(-) create mode 100644 internal/assets/templates/constants.templ create mode 100644 internal/assets/templates/constants_templ.go delete mode 100644 internal/assets/templates/crud-constants.go.tmpl create mode 100644 internal/structs/parser.go create mode 100644 pkg/sqlc/codegen/golang/opts/enum.go create mode 100644 pkg/sqlc/pgx/poolcache/poolcache.go create mode 100644 testdata/teststructs/teststructs.go create mode 100644 testdata/teststructs/unexported.go diff --git a/Makefile b/Makefile index 7078cb3..3ce47cf 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -install: +install: gen go install ./cmd/pgxgen upgrade: @@ -13,3 +13,9 @@ test: copysqlc: go run cmd/copysqlc/main.go + +fmt: + gofumpt -l -w . + +gen: + @templ generate diff --git a/README.md b/README.md index a5a2fc4..ebc0eec 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ pgxgen use [`sqlc`](https://github.com/sqlc-dev/sqlc) tool with additional impro ### Requirements -- `Go 1.21+` +- `Go 1.22.2+` ```bash go install github.com/tkcrm/pgxgen/cmd/pgxgen@latest @@ -51,7 +51,7 @@ At root of your project create a `pgxgen.yaml`. Example of configuration below. > Example: `pgxgen --pgxgen-config pgxgen-new.yaml` ```yaml -version: 1 +version: "1" sqlc: - # directory with migrations. required schema_dir: sql/migrations @@ -125,6 +125,7 @@ sqlc: tables: users: output_dir: internal/store/users/repo_users + include_column_names: true # modification of existing models. not required gen_models: @@ -293,14 +294,14 @@ At root of your project create a `sqlc.yaml` file with the configuration describ > Example: `pgxgen --sqlc-config sqlc-new.yaml` ```yaml -version: 2 +version: "2" sql: - schema: "sql/migrations" queries: "sql/queries" engine: "postgresql" gen: go: - sql_package: "pgx/v4" + sql_package: "pgx/v5" out: "internal/store" emit_prepared_queries: false emit_json_tags: true diff --git a/cmd/pgxgen/main.go b/cmd/pgxgen/main.go index 003ab3c..4a77894 100644 --- a/cmd/pgxgen/main.go +++ b/cmd/pgxgen/main.go @@ -15,7 +15,7 @@ import ( "github.com/tkcrm/pgxgen/pkg/logger" ) -var version = "v0.2.9" +var version = "v0.3.0" func main() { logger := logger.New() diff --git a/go.mod b/go.mod index 0f8232f..815bedf 100644 --- a/go.mod +++ b/go.mod @@ -1,23 +1,22 @@ module github.com/tkcrm/pgxgen -go 1.21 +go 1.22.2 require ( github.com/cubicdaiya/gonp v1.0.4 github.com/davecgh/go-spew v1.1.1 - github.com/go-sql-driver/mysql v1.7.1 + github.com/go-sql-driver/mysql v1.8.1 github.com/gobeam/stringy v0.0.6 github.com/google/go-cmp v0.6.0 - github.com/jackc/pgx/v4 v4.18.1 + github.com/jackc/pgx/v4 v4.18.3 github.com/jinzhu/inflection v1.0.0 github.com/lib/pq v1.10.9 - github.com/mattn/go-sqlite3 v1.14.18 // indirect github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 - github.com/tkcrm/modules v0.0.0-20240108190415-64d66743be2e - golang.org/x/sync v0.6.0 - golang.org/x/tools v0.16.1 - google.golang.org/protobuf v1.32.0 + github.com/tkcrm/modules v0.0.0-20240309201610-ce17a6cd6af6 + golang.org/x/sync v0.7.0 + golang.org/x/tools v0.20.0 + google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -27,40 +26,39 @@ require ( ) require ( + github.com/a-h/templ v0.2.663 github.com/antlr4-go/antlr/v4 v4.13.0 github.com/cristalhq/flagx v0.5.0 github.com/fatih/structtag v1.2.0 - github.com/google/cel-go v0.18.2 - github.com/jackc/pgx/v5 v5.5.1 - github.com/pingcap/tidb/pkg/parser v0.0.0-20240111081109-0236944eab41 - github.com/stretchr/testify v1.8.4 - github.com/tetratelabs/wazero v1.6.0 - github.com/wasilibs/go-pgquery v0.0.0-20240111074841-2809d93c5e23 - modernc.org/sqlite v1.28.0 + github.com/google/cel-go v0.20.1 + github.com/jackc/pgx/v5 v5.5.5 + github.com/pganalyze/pg_query_go/v5 v5.1.0 + github.com/pingcap/tidb/pkg/parser v0.0.0-20240411124952-572e5c48d98a + github.com/stretchr/testify v1.9.0 + github.com/tetratelabs/wazero v1.7.0 + github.com/wasilibs/go-pgquery v0.0.0-20240319230125-b9b2e95c69a7 + modernc.org/sqlite v1.29.6 ) require ( + filippo.io/edwards25519 v1.1.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/google/uuid v1.5.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect - github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/pganalyze/pg_query_go/v5 v5.1.0 // indirect - github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/pingcap/failpoint v0.0.0-20240411090902-411cc9a77e11 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect - github.com/wasilibs/wazerox v0.0.0-20240105014115-75455786b41e // indirect - golang.org/x/net v0.20.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect - lukechampine.com/uint128 v1.3.0 // indirect - modernc.org/cc/v3 v3.41.0 // indirect - modernc.org/ccgo/v3 v3.16.15 // indirect - modernc.org/libc v1.40.1 // indirect + golang.org/x/net v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect + modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect + modernc.org/libc v1.49.3 // indirect modernc.org/mathutil v1.6.0 // indirect - modernc.org/memory v1.7.2 // indirect - modernc.org/opt v0.1.3 // indirect + modernc.org/memory v1.8.0 // indirect modernc.org/strutil v1.2.0 // indirect modernc.org/token v1.1.0 // indirect ) @@ -69,28 +67,26 @@ require ( github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/goccy/go-json v0.10.2 // indirect - github.com/golang/protobuf v1.5.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.14.1 // indirect + github.com/jackc/pgconn v1.14.3 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.2 // indirect + github.com/jackc/pgproto3/v2 v2.3.3 // indirect github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect - github.com/jackc/pgtype v1.14.0 // indirect - github.com/pganalyze/pg_query_go/v4 v4.2.3 - github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // indirect + github.com/jackc/pgtype v1.14.3 // indirect + github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb // indirect github.com/pingcap/log v1.1.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/riza-io/grpc-go v0.2.0 go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/sys v0.16.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.22.0 // indirect + golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/sys v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/grpc v1.60.1 + google.golang.org/grpc v1.63.2 gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect ) diff --git a/go.sum b/go.sum index 8804a0a..557ef42 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/a-h/templ v0.2.663 h1:aa0WMm27InkYHGjimcM7us6hJ6BLhg98ZbfaiDPyjHE= +github.com/a-h/templ v0.2.663/go.mod h1:SA7mtYwVEajbIXFRh3vKdYm/4FYyLQAtPH1+KxzGPA8= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= @@ -31,8 +35,8 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobeam/stringy v0.0.6 h1:IboItevQArUAYUbjb7xmtGoJfN5Aqpk3/bVCd7JgWe0= github.com/gobeam/stringy v0.0.6/go.mod h1:W3620X9dJHf2FSZF5fRnWekHcHQjwmCz8ZQ2d1qloqE= @@ -40,29 +44,19 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/cel-go v0.18.2 h1:L0B6sNBSVmt0OyECi8v6VOS74KOc9W/tLiWKfZABvf4= -github.com/google/cel-go v0.18.2/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= +github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= @@ -75,9 +69,8 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= -github.com/jackc/pgconn v1.14.1 h1:smbxIaZA08n6YuxEX1sDyjV/qkbtUtkH20qLkR9MUR4= -github.com/jackc/pgconn v1.14.1/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= +github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= +github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -93,8 +86,8 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= -github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= +github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= @@ -103,16 +96,18 @@ github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01C github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.14.3 h1:h6W9cPuHsRWQFTWUZMAKMgG5jSwQI0Zurzdvlx3Plus= +github.com/jackc/pgtype v1.14.3/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= -github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= -github.com/jackc/pgx/v5 v5.5.1 h1:5I9etrGkLrN+2XPCsi6XLlV5DITbSL/xBZdmAxFcXPI= -github.com/jackc/pgx/v5 v5.5.1/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= +github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= +github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA= +github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= @@ -121,8 +116,6 @@ github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= -github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -147,22 +140,22 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 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/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI= -github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/pganalyze/pg_query_go/v4 v4.2.3 h1:cNLqyiVMasV7YGWyYV+fkXyHp32gDfXVNCqoHztEGNk= -github.com/pganalyze/pg_query_go/v4 v4.2.3/go.mod h1:aEkDNOXNM5j0YGzaAapwJ7LB3dLNj+bvbWcLv1hOVqA= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/pganalyze/pg_query_go/v5 v5.1.0 h1:MlxQqHZnvA3cbRQYyIrjxEjzo560P6MyTgtlaf3pmXg= github.com/pganalyze/pg_query_go/v5 v5.1.0/go.mod h1:FsglvxidZsVN+Ltw3Ai6nTgPVcK2BPukH3jCDEqc1Ug= github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 h1:+FZIDR/D97YOPik4N4lPDaUcLDF/EQPogxtlHB2ZZRM= -github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= -github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c h1:CgbKAHto5CQgWM9fSBIvaxsJHuGP0uM74HXtv3MyyGQ= -github.com/pingcap/failpoint v0.0.0-20220801062533-2eaa32854a6c/go.mod h1:4qGtCB0QK0wBzKtFEGDhxXnSnbQApw1gc9siScUl8ew= +github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb h1:3pSi4EDG6hg0orE1ndHkXvX6Qdq2cZn8gAPir8ymKZk= +github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= +github.com/pingcap/failpoint v0.0.0-20240411090902-411cc9a77e11 h1:t/VpmQsbI7w2YaNhqUep+WHW/usbm77ab60Vtv/1fOI= +github.com/pingcap/failpoint v0.0.0-20240411090902-411cc9a77e11/go.mod h1:cv98q58yGEqg4gkB3e8n2+8MEW4fo3kPTz6EoQBMG4o= github.com/pingcap/log v1.1.0 h1:ELiPxACz7vdo1qAvvaWJg1NrYFoY6gqAh/+Uo6aXdD8= github.com/pingcap/log v1.1.0/go.mod h1:DWQW5jICDR7UJh4HtxXSM20Churx4CQL0fwL/SoOSA4= -github.com/pingcap/tidb/pkg/parser v0.0.0-20240111081109-0236944eab41 h1:BT4vDbMDuZwuMq54636AWgyXO5tA0KJbjC67+eC502c= -github.com/pingcap/tidb/pkg/parser v0.0.0-20240111081109-0236944eab41/go.mod h1:yRkiqLFwIqibYg2P7h4bclHjHcJiIFRLKhGRyBcKYus= +github.com/pingcap/tidb/pkg/parser v0.0.0-20240411124952-572e5c48d98a h1:QZ487KK4EQy8QI9WTLgE6qSGks7O82SS8bVVjFBXlwo= +github.com/pingcap/tidb/pkg/parser v0.0.0-20240411124952-572e5c48d98a/go.mod h1:c/4la2yfv1vBYvtIG8WCDyDinLMDIUC5+zLRHiafY+Y= 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= @@ -173,8 +166,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq github.com/riza-io/grpc-go v0.2.0 h1:2HxQKFVE7VuYstcJ8zqpN84VnAoJ4dCL6YFhJewNcHQ= github.com/riza-io/grpc-go v0.2.0/go.mod h1:2bDvR9KkKC3KhtlSHfR3dAXjUMT86kg4UfWFyVGWqi8= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -205,16 +198,14 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -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/tetratelabs/wazero v1.6.0 h1:z0H1iikCdP8t+q341xqepY4EWvHEw8Es7tlqiVzlP3g= -github.com/tetratelabs/wazero v1.6.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A= -github.com/tkcrm/modules v0.0.0-20240108190415-64d66743be2e h1:w7D6BYIGX5zzdL42+H4B3MfHCcO2vhk+2YayE6whh/E= -github.com/tkcrm/modules v0.0.0-20240108190415-64d66743be2e/go.mod h1:wddYzszCh+PUUwgYkf+8FginiPzs/52RwWg6jCHo+9c= -github.com/wasilibs/go-pgquery v0.0.0-20240111074841-2809d93c5e23 h1:1B9kkf0PExgz4wCLPT2N+4G1TkIwtZxG853iHdUseog= -github.com/wasilibs/go-pgquery v0.0.0-20240111074841-2809d93c5e23/go.mod h1:FLoYE5udIomDGSYRnsylrqjB1zDlfm97oAsJxEoLzEU= -github.com/wasilibs/wazerox v0.0.0-20240105014115-75455786b41e h1:9h7OzkTRM/FD0Stn2JJEx09+Cx1sD3niOqdqPDm2e0o= -github.com/wasilibs/wazerox v0.0.0-20240105014115-75455786b41e/go.mod h1:IQNVyA4d1hWIe23mlMMuqXjyWMdndgSlNx6FqBkwPsM= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tetratelabs/wazero v1.7.0 h1:jg5qPydno59wqjpGrHph81lbtHzTrWzwwtD4cD88+hQ= +github.com/tetratelabs/wazero v1.7.0/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= +github.com/tkcrm/modules v0.0.0-20240309201610-ce17a6cd6af6 h1:tPm4A8CcFMF1eDC5gB0A3yxENlmC1R2T0WdPI6ePWss= +github.com/tkcrm/modules v0.0.0-20240309201610-ce17a6cd6af6/go.mod h1:nOp+brGbkfHZTKaPMPk07S5YdqN44UOmoHt1UQeFCP4= +github.com/wasilibs/go-pgquery v0.0.0-20240319230125-b9b2e95c69a7 h1:sqqLVb63En4uTKFKBWSJ7c1aIFonhM1yn35/+KchOf4= +github.com/wasilibs/go-pgquery v0.0.0-20240319230125-b9b2e95c69a7/go.mod h1:ZAUjWnxivykc22k0TKFZylOV0WlVQ9nWMExfGFIBuF4= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -226,8 +217,8 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -240,8 +231,8 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -252,17 +243,21 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e h1:723BNChdd0c2Wk6WOE320qGBiPtYx0F0Bbm1kriShfE= -golang.org/x/exp v0.0.0-20240110193028-0dcbfd608b1e/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= +golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -270,12 +265,17 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -292,12 +292,18 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -305,6 +311,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -318,31 +326,26 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1 h1:OPXtXn7fNMaXwO3JvOmF1QyTc00jsSFFz1vXXBOdCDo= -google.golang.org/genproto/googleapis/api v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda h1:b6F6WIV4xHHD0FA4oIyzU6mHWg2WI2X1RBehwa5QN38= +google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda/go.mod h1:AHcE/gZH76Bk/ROZhQphlRoWo5xKDEtz3eVEO1LfA8c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -363,31 +366,29 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= -lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= -modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= -modernc.org/ccgo/v3 v3.16.15 h1:KbDR3ZAVU+wiLyMESPtbtE/Add4elztFyfsWoNTgxS0= -modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI= -modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk= -modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= -modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v1.40.1 h1:ZhRylEBcj3GyQbPVC8JxIg7SdrT4JOxIDJoUon0NfF8= -modernc.org/libc v1.40.1/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= +modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk= +modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA= +modernc.org/ccgo/v4 v4.16.0/go.mod h1:dkNyWIjFrVIZ68DTo36vHK+6/ShBn4ysU61So6PIqCI= +modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= +modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= +modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= +modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= +modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b h1:BnN1t+pb1cy61zbvSUV7SeI0PwosMhlAEi/vBY4qxp8= +modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/libc v1.49.3 h1:j2MRCRdwJI2ls/sGbeSk0t2bypOG/uvPZUsGQFDulqg= +modernc.org/libc v1.49.3/go.mod h1:yMZuGkn7pXbKfoT/M35gFJOAEdSKdxL0q64sF7KqCDo= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= -modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= +modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= +modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= +modernc.org/sqlite v1.29.6 h1:0lOXGrycJPptfHDuohfYgNqoe4hu+gYuN/pKgY5XjS4= +modernc.org/sqlite v1.29.6/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= -modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= -modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY= -modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE= diff --git a/internal/assets/templates/constants.templ b/internal/assets/templates/constants.templ new file mode 100644 index 0000000..9c0640d --- /dev/null +++ b/internal/assets/templates/constants.templ @@ -0,0 +1,106 @@ +package templates + +import ( + "fmt" + "strings" + "github.com/gobeam/stringy" +) + +type ConstantsTableNamesParamsItem struct { + NamePreffix string + Name string +} + +type ConstantsColumnNamesParamsItem struct { + TableName string + NamePreffix string + Name string +} + +type ConstantsParams struct { + Package string + Version string + Tables []ConstantsTableNamesParamsItem + ColumnNames []ConstantsColumnNamesParamsItem +} + +func (p ConstantsParams) GetColumnsForTable(tableName string) []ConstantsColumnNamesParamsItem { + res := []ConstantsColumnNamesParamsItem{} + for _, item := range p.ColumnNames { + if item.TableName == tableName { + res = append(res, item) + } + } + return res +} + +func (p ConstantsParams) GetHeaderComment() string { + content := strings.Builder{} + content.WriteString(fmt.Sprintf(`// Code generated by pgxgen. DO NOT EDIT. +// versions: +// pgxgen %s +package %s + +import ( + "strings" + "github.com/gobeam/stringy" +)`, p.Version, p.Package)) + content.WriteString("\n") + return content.String() +} + +func (p ConstantsParams) GetTablesContent() string { + content := strings.Builder{} + content.WriteString(`type TableName string + +func (s TableName) String() string { return string(s) }`) + content.WriteString("\n") + + for _, item := range p.Tables { + content.WriteString("\nconst (\n") + content.WriteString(fmt.Sprintf(`TableName%s TableName = "%s"`, item.NamePreffix, item.Name)) + content.WriteString(")\n") + } + return content.String() +} + +func (p ConstantsParams) GetColumnNamesContent() string { + content := strings.Builder{} + content.WriteString(`type ColumnName string + +func (s ColumnName) String() string { return string(s) } + +func (s ColumnName) StructName() string { + v := stringy.New(string(s)).CamelCase() + v = stringy.New(v).UcFirst() + return strings.ReplaceAll(v, "Id", "ID") +}`) + content.WriteString("\nconst (\n") + + for _, item := range p.ColumnNames { + content.WriteString(fmt.Sprintf(`ColumnName%s ColumnName = "%s"`, item.NamePreffix, item.Name)) + content.WriteString("\n") + } + content.WriteString(")\n\n") + + for _, tableName := range p.Tables { + content.WriteString(fmt.Sprintf("func %sColumnNames() []ColumnName {\n", stringy.New(stringy.New(tableName.Name).CamelCase()).UcFirst())) + content.WriteString("return []ColumnName{\n") + for _, item := range p.GetColumnsForTable(tableName.Name) { + content.WriteString(fmt.Sprintf("ColumnName%s,\n", item.NamePreffix)) + } + content.WriteString("}\n") + content.WriteString("}\n") + } + return content.String() +} + +templ Constatnts(p ConstantsParams) { + @templ.Raw(p.GetHeaderComment()) + if len(p.Tables) > 0 { + @templ.Raw(p.GetTablesContent()) + } + if len(p.ColumnNames) > 0 { + @templ.Raw(p.GetColumnNamesContent()) + } +} diff --git a/internal/assets/templates/constants_templ.go b/internal/assets/templates/constants_templ.go new file mode 100644 index 0000000..1d2118f --- /dev/null +++ b/internal/assets/templates/constants_templ.go @@ -0,0 +1,142 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.663 +package templates + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import "context" +import "io" +import "bytes" + +import ( + "fmt" + "github.com/gobeam/stringy" + "strings" +) + +type ConstantsTableNamesParamsItem struct { + NamePreffix string + Name string +} + +type ConstantsColumnNamesParamsItem struct { + TableName string + NamePreffix string + Name string +} + +type ConstantsParams struct { + Package string + Version string + Tables []ConstantsTableNamesParamsItem + ColumnNames []ConstantsColumnNamesParamsItem +} + +func (p ConstantsParams) GetColumnsForTable(tableName string) []ConstantsColumnNamesParamsItem { + res := []ConstantsColumnNamesParamsItem{} + for _, item := range p.ColumnNames { + if item.TableName == tableName { + res = append(res, item) + } + } + return res +} + +func (p ConstantsParams) GetHeaderComment() string { + content := strings.Builder{} + content.WriteString(fmt.Sprintf(`// Code generated by pgxgen. DO NOT EDIT. +// versions: +// pgxgen %s +package %s + +import ( + "strings" + "github.com/gobeam/stringy" +)`, p.Version, p.Package)) + content.WriteString("\n") + return content.String() +} + +func (p ConstantsParams) GetTablesContent() string { + content := strings.Builder{} + content.WriteString(`type TableName string + +func (s TableName) String() string { return string(s) }`) + content.WriteString("\n") + + for _, item := range p.Tables { + content.WriteString("\nconst (\n") + content.WriteString(fmt.Sprintf(`TableName%s TableName = "%s"`, item.NamePreffix, item.Name)) + content.WriteString(")\n") + } + return content.String() +} + +func (p ConstantsParams) GetColumnNamesContent() string { + content := strings.Builder{} + content.WriteString(`type ColumnName string + +func (s ColumnName) String() string { return string(s) } + +func (s ColumnName) StructName() string { + v := stringy.New(string(s)).CamelCase() + v = stringy.New(v).UcFirst() + return strings.ReplaceAll(v, "Id", "ID") +}`) + content.WriteString("\nconst (\n") + + for _, item := range p.ColumnNames { + content.WriteString(fmt.Sprintf(`ColumnName%s ColumnName = "%s"`, item.NamePreffix, item.Name)) + content.WriteString("\n") + } + content.WriteString(")\n\n") + + for _, tableName := range p.Tables { + content.WriteString(fmt.Sprintf("func %sColumnNames() []ColumnName {\n", stringy.New(stringy.New(tableName.Name).CamelCase()).UcFirst())) + content.WriteString("return []ColumnName{\n") + for _, item := range p.GetColumnsForTable(tableName.Name) { + content.WriteString(fmt.Sprintf("ColumnName%s,\n", item.NamePreffix)) + } + content.WriteString("}\n") + content.WriteString("}\n") + } + return content.String() +} + +func Constatnts(p ConstantsParams) templ.Component { + return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templ.Raw(p.GetHeaderComment()).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if len(p.Tables) > 0 { + templ_7745c5c3_Err = templ.Raw(p.GetTablesContent()).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + if len(p.ColumnNames) > 0 { + templ_7745c5c3_Err = templ.Raw(p.GetColumnNamesContent()).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/internal/assets/templates/crud-constants.go.tmpl b/internal/assets/templates/crud-constants.go.tmpl deleted file mode 100644 index e7fcc5f..0000000 --- a/internal/assets/templates/crud-constants.go.tmpl +++ /dev/null @@ -1,19 +0,0 @@ -{{ define "crudConstants" }}// Code generated by pgxgen. DO NOT EDIT. -// versions: -// pgxgen {{ .Version }} - -package {{ .Package }} - -{{ if isNotEmptyArray .Tables }} -type TableName string - -func (s TableName) String() string { - return string(s) -} - -const ( - {{ range .Tables }} - TableName{{ .TableNamePreffix }} TableName = "{{ .TableName }}"{{ end }} -) -{{ end }} -{{ end }} diff --git a/internal/assets/templates/keystone-model.go.tmpl b/internal/assets/templates/keystone-model.go.tmpl index c8b4624..a59c672 100644 --- a/internal/assets/templates/keystone-model.go.tmpl +++ b/internal/assets/templates/keystone-model.go.tmpl @@ -49,6 +49,8 @@ export class {{.Name}}s{{ $.ExportModelSuffix}} extends Model({ if(v) { this.draft = draft(v); this.formInstance?.updateFormValues(this.draft?.data.getInitialValues) + } else { + this.draft = undefined; } } @@ -65,9 +67,9 @@ export class {{.Name}}s{{ $.ExportModelSuffix}} extends Model({ @modelAction clearTempData(): void { - this.setGetResponse(undefined); - this.setDraft(undefined); this.setFormInstance(undefined); + this.setDraft(undefined); + this.setGetResponse(undefined); } @modelAction diff --git a/internal/config/go_constants.go b/internal/config/go_constants.go index 372e402..1438399 100644 --- a/internal/config/go_constants.go +++ b/internal/config/go_constants.go @@ -7,5 +7,6 @@ type GoConstants struct { type GoConstantsTables map[string]GoConstantsTablesItem type GoConstantsTablesItem struct { - OutputDir string `yaml:"output_dir"` + OutputDir string `yaml:"output_dir"` + IncludeColumnNames bool `yaml:"include_column_names"` } diff --git a/internal/crud/crud.go b/internal/crud/crud.go index 451020e..c6f4e00 100644 --- a/internal/crud/crud.go +++ b/internal/crud/crud.go @@ -141,8 +141,8 @@ func (s *crud) generateSQLForEachTable(crudParams config.CrudParams, outputPaths return nil, err } - //headText := fmt.Sprintf("-- Code generated by pgxgen. DO NOT EDIT.\n-- versions:\n-- pgxgen %s\n\n", s.config.Pgxgen.Version) - //builder.WriteString(headText) + // headText := fmt.Sprintf("-- Code generated by pgxgen. DO NOT EDIT.\n-- versions:\n-- pgxgen %s\n\n", s.config.Pgxgen.Version) + // builder.WriteString(headText) // Sort tables tableKeys := make([]string, 0, len(crudParams.Tables)) diff --git a/internal/goconstatnts/goconstatnts.go b/internal/goconstatnts/goconstatnts.go index 205bd0f..dd62278 100644 --- a/internal/goconstatnts/goconstatnts.go +++ b/internal/goconstatnts/goconstatnts.go @@ -1,12 +1,13 @@ package goconstatnts import ( + "bytes" + "context" "fmt" "path/filepath" "time" - "github.com/tkcrm/modules/pkg/templates" - "github.com/tkcrm/pgxgen/internal/assets" + "github.com/tkcrm/pgxgen/internal/assets/templates" "github.com/tkcrm/pgxgen/internal/config" "github.com/tkcrm/pgxgen/internal/schema" "github.com/tkcrm/pgxgen/pkg/logger" @@ -33,17 +34,6 @@ func New(logger logger.Logger, config config.Config) IGoConstants { const defaultConstatsFileName = "constants_gen.go" -type GenTableNamesParamsItem struct { - TableNamePreffix string - TableName string -} - -type ConstantParamsItem struct { - Package string - Version string - Tables []GenTableNamesParamsItem -} - func (s *goConstants) GenerateConstants() error { for _, cfg := range s.config.Pgxgen.Sqlc { if len(cfg.GoConstants.Tables) == 0 { @@ -90,7 +80,15 @@ func (s *goConstants) GenerateConstants() error { if t.Rel.Name != tableName { continue } - if err := params.addConstantItem(s.config.Pgxgen.Version, table.OutputDir, tableName); err != nil { + + columnNames := make([]string, 0, len(t.Columns)) + if table.IncludeColumnNames { + for _, column := range t.Columns { + columnNames = append(columnNames, column.Name) + } + } + + if err := params.addConstantItem(s.config.Pgxgen.Version, table.OutputDir, tableName, columnNames); err != nil { return err } } @@ -98,25 +96,12 @@ func (s *goConstants) GenerateConstants() error { } for outputDir, item := range params.ConstantsParams { - tpl := templates.New() - tpl.AddFunc("isNotEmptyArray", func(arr []GenTableNamesParamsItem) bool { - return len(arr) > 0 - }) - - compiledRes, err := tpl.Compile(templates.CompileParams{ - TemplateName: "crudConstants", - TemplateType: templates.TextTemplateType, - FS: assets.TemplatesFS, - FSPaths: []string{ - "templates/crud-constants.go.tmpl", - }, - Data: item, - }) - if err != nil { - return fmt.Errorf("tpl.Compile error: %w", err) + buf := new(bytes.Buffer) + if err := templates.Constatnts(item).Render(context.Background(), buf); err != nil { + return err } - compiledRes, err = utils.UpdateGoImports(compiledRes) + compiledRes, err := utils.UpdateGoImports(buf.Bytes()) if err != nil { return fmt.Errorf("UpdateGoImports error: %w", err) } diff --git a/internal/goconstatnts/params.go b/internal/goconstatnts/params.go index 84498a9..449242a 100644 --- a/internal/goconstatnts/params.go +++ b/internal/goconstatnts/params.go @@ -7,16 +7,17 @@ import ( "github.com/gobeam/stringy" cmnutils "github.com/tkcrm/modules/pkg/utils" + "github.com/tkcrm/pgxgen/internal/assets/templates" "github.com/tkcrm/pgxgen/utils" ) type generateConstantsParams struct { - ConstantsParams map[string]ConstantParamsItem + ConstantsParams map[string]templates.ConstantsParams } -func (s *generateConstantsParams) addConstantItem(version, outputDir, tableName string) error { +func (s *generateConstantsParams) addConstantItem(version, outputDir, tableName string, columnNames []string) error { if s.ConstantsParams == nil { - s.ConstantsParams = make(map[string]ConstantParamsItem) + s.ConstantsParams = make(map[string]templates.ConstantsParams) } packageName, err := utils.GetGoPackageNameForDir(outputDir) @@ -26,28 +27,42 @@ func (s *generateConstantsParams) addConstantItem(version, outputDir, tableName params, ok := s.ConstantsParams[outputDir] if !ok { - params = ConstantParamsItem{ + params = templates.ConstantsParams{ Package: packageName, Version: version, } } - if _, ok := cmnutils.FindInArray(params.Tables, func(v GenTableNamesParamsItem) bool { - return v.TableName == tableName + if _, ok := cmnutils.FindInArray(params.Tables, func(v templates.ConstantsTableNamesParamsItem) bool { + return v.Name == tableName }); !ok { re := regexp.MustCompile(`[\_\-0-9]`) tableNamePrffix := re.ReplaceAllString(tableName, " ") tableNamePrffix = stringy.New(tableNamePrffix).CamelCase() tableNamePrffix = stringy.New(tableNamePrffix).UcFirst() - params.Tables = append(params.Tables, GenTableNamesParamsItem{ - TableNamePreffix: tableNamePrffix, - TableName: tableName, + params.Tables = append(params.Tables, templates.ConstantsTableNamesParamsItem{ + NamePreffix: tableNamePrffix, + Name: tableName, }) + + if len(columnNames) > 0 { + for _, columnName := range columnNames { + columnNamePrffix := re.ReplaceAllString(tableName+"_"+columnName, " ") + columnNamePrffix = stringy.New(columnNamePrffix).CamelCase() + columnNamePrffix = stringy.New(columnNamePrffix).UcFirst() + + params.ColumnNames = append(params.ColumnNames, templates.ConstantsColumnNamesParamsItem{ + TableName: tableName, + NamePreffix: columnNamePrffix, + Name: columnName, + }) + } + } } sort.Slice(params.Tables, func(i, j int) bool { - return params.Tables[i].TableNamePreffix < params.Tables[j].TableNamePreffix + return params.Tables[i].NamePreffix < params.Tables[j].NamePreffix }) s.ConstantsParams[outputDir] = params diff --git a/internal/gomodels/gomodels.go b/internal/gomodels/gomodels.go index 620c6c7..f94317e 100644 --- a/internal/gomodels/gomodels.go +++ b/internal/gomodels/gomodels.go @@ -1,10 +1,8 @@ package gomodels import ( - "bufio" "context" "fmt" - "io" "os" "path/filepath" "regexp" @@ -114,14 +112,8 @@ func (s *gomodels) generateModels(cfg config.GenModels) error { } for index, filePath := range filePaths { - // get models.go file content - fileContent, err := utils.ReadFile(filePath) - if err != nil { - return fmt.Errorf("read file error: %w", err) - } - // get structs from go file - _structs := structs.GetStructs(string(fileContent)) + _structs := structs.GetStructsByFilePath(filePath) // filter structs by exclude_structs params if len(cfg.ExcludeStructs) > 0 { @@ -159,7 +151,7 @@ func (s *gomodels) generateModels(cfg config.GenModels) error { } // get all types from ModelsOutputDir - scalarTypes := make(structs.Types) + // scalarTypes := make(structs.Types) dirItems, err := os.ReadDir(config.GetModelsOutputDir()) if err != nil { return fmt.Errorf("read dir error: %w", err) @@ -171,17 +163,17 @@ func (s *gomodels) generateModels(cfg config.GenModels) error { } path := filepath.Join(config.GetModelsOutputDir(), item.Name()) - file, err := utils.ReadFile(path) - if err != nil { - return fmt.Errorf("read file error: %w", err) - } + // file, err := utils.ReadFile(path) + // if err != nil { + // return fmt.Errorf("read file error: %w", err) + // } - for key, value := range structs.GetStructs(string(file)) { + for key, value := range structs.GetStructsByFilePath(path) { _structs[key] = value } - for key, value := range s.getScalarTypes(string(file)) { - scalarTypes[key] = value - } + // for key, value := range s.getScalarTypes(string(file)) { + // scalarTypes[key] = value + // } } if config.DeleteOriginalFiles { @@ -194,36 +186,36 @@ func (s *gomodels) generateModels(cfg config.GenModels) error { return nil } -func (s *gomodels) getScalarTypes(fileContent string) structs.Types { - types := make(structs.Types) - r := bufio.NewReader(strings.NewReader(fileContent)) - - for { - line, err := r.ReadString('\n') - if err != nil { - if err == io.EOF { - break - } - s.logger.Fatal(err) - } - - if strings.Contains(line, "struct {") { - continue - } - - r := regexp.MustCompile(`^type (\w+) ([^\s]+)`) - match := r.FindStringSubmatch(line) - - if len(match) == 3 { - types[match[1]] = structs.TypesParameters{ - Name: match[1], - Type: match[2], - } - } - } - - return types -} +// func (s *gomodels) getScalarTypes(fileContent string) structs.Types { +// types := make(structs.Types) +// r := bufio.NewReader(strings.NewReader(fileContent)) + +// for { +// line, err := r.ReadString('\n') +// if err != nil { +// if err == io.EOF { +// break +// } +// s.logger.Fatal(err) +// } + +// if strings.Contains(line, "struct {") { +// continue +// } + +// r := regexp.MustCompile(`^type (\w+) ([^\s]+)`) +// match := r.FindStringSubmatch(line) + +// if len(match) == 3 { +// types[match[1]] = structs.TypesParameters{ +// Name: match[1], +// Type: match[2], +// } +// } +// } + +// return types +// } func (s *gomodels) processStructs(c config.GenModels, st *structs.Structs) error { // rename structs diff --git a/internal/keystone/keystone.go b/internal/keystone/keystone.go index 864cf21..347f6c3 100644 --- a/internal/keystone/keystone.go +++ b/internal/keystone/keystone.go @@ -1,14 +1,10 @@ package keystone import ( - "bufio" "context" "fmt" - "io" - "os" "os/exec" "path/filepath" - "regexp" "strings" "time" @@ -53,45 +49,12 @@ func (s *keystone) generateKeystone() error { return err } - // get models file content - fileContent, err := utils.ReadFile(params.InputFilePath) - if err != nil { - return err - } - // get structs from go file - modelStructs := structs.GetStructs(string(fileContent)) + modelStructs := structs.GetStructsByFilePath(params.InputFilePath) + modelStructs.RemoveUnexportedFields() // get all types from ModelsOutputDir scalarTypes := make(structs.Types) - dirItems, err := os.ReadDir(filepath.Dir(params.InputFilePath)) - if err != nil { - return err - } - - allStructs := make(structs.Structs) - - for _, item := range dirItems { - if item.IsDir() { - continue - } - path := filepath.Join(filepath.Dir(params.InputFilePath), item.Name()) - - file, err := utils.ReadFile(path) - if err != nil { - return err - } - - for key, value := range structs.GetStructs(string(file)) { - allStructs[key] = value - } - - for key, value := range s.getScalarTypes(string(file)) { - scalarTypes[key] = value - } - } - - structs.FillMissedTypes(allStructs, modelStructs, scalarTypes) for _, modelName := range params.SkipModels { delete(modelStructs, modelName) @@ -105,36 +68,6 @@ func (s *keystone) generateKeystone() error { return nil } -func (s *keystone) getScalarTypes(file_models_str string) structs.Types { - types := make(structs.Types) - r := bufio.NewReader(strings.NewReader(file_models_str)) - - for { - line, err := r.ReadString('\n') - if err != nil { - if err == io.EOF { - break - } - s.logger.Fatal(err) - } - - if strings.Contains(line, "struct {") { - continue - } - r := regexp.MustCompile(`^type (\w+) ([^\s]+)`) - match := r.FindStringSubmatch(line) - - if len(match) == 3 { - types[match[1]] = structs.TypesParameters{ - Name: match[1], - Type: match[2], - } - } - } - - return types -} - func compileMobxKeystoneModels(ver string, cfg config.GenKeystoneFromStruct, st structs.Structs, sct structs.Types) error { if cfg.OutputDir == "" { return fmt.Errorf("compile mobx keystone error: undefined output dir") @@ -150,8 +83,10 @@ func compileMobxKeystoneModels(ver string, cfg config.GenKeystoneFromStruct, st } structs := structs.ConvertStructsToSlice(st) - if err := structs.Sort(strings.Split(cfg.Sort, ",")...); err != nil { - return err + if cfg.Sort != "" { + if err := structs.Sort(strings.Split(cfg.Sort, ",")...); err != nil { + return err + } } tctx := tmplKeystoneCtx{ @@ -244,7 +179,7 @@ func getKeystoneType(cfg config.GenKeystoneFromStruct, st structs.Structs, sct s tp = "" switch t { case "int", "int8", "int16", "int32", - "uint", "uint8", "uint16", "uint32": + "uint", "uint8", "uint16", "uint32", "pgtype.Int2": tp = "types.integer" if !isNullable { tp += ",0" @@ -266,7 +201,7 @@ func getKeystoneType(cfg config.GenKeystoneFromStruct, st structs.Structs, sct s if !isNullable { tp += ",0" } - case "string": + case "string", "pgtype.Text": tp = "types.string" if !isNullable { tp += ",\"\"" @@ -276,7 +211,7 @@ func getKeystoneType(cfg config.GenKeystoneFromStruct, st structs.Structs, sct s if !isNullable { tp += ",false" } - case "bun.NullTime", "time.Time", "pgtype.Time": + case "bun.NullTime", "time.Time", "pgtype.Time", "pgtype.Timestamp", "timestamppb.Timestamp": tp = "types.dateString" if !isNullable { tp += ",\"\"" @@ -286,9 +221,12 @@ func getKeystoneType(cfg config.GenKeystoneFromStruct, st structs.Structs, sct s if !isNullable { tp += ",\"\"" } - case "map[string]interface{}", "pgtype.JSONB": + case "map[string]interface{}", "map[string]any", "pgtype.JSONB": tp = "Record" typeWrap = typeWrapUnchecked + "({})" + case "[]byte": + tp = "Record" + typeWrap = typeWrapUnchecked + "()" default: _, okst := st[t] existScalarItem, oksct := sct[t] diff --git a/internal/sqlc/movemodels.go b/internal/sqlc/movemodels.go index b673ce7..eb2fb17 100644 --- a/internal/sqlc/movemodels.go +++ b/internal/sqlc/movemodels.go @@ -22,14 +22,8 @@ func (s *sqlc) moveModels( modelFileStructs, alreadyMoved := (*modelsMoved)[cfg.SchemaDir] if !alreadyMoved { - // get sqlc model file content - modelFileContent, err := utils.ReadFile(modelPath) - if err != nil { - return err - } - // get structs from model file - modelFileStructs = structs.GetStructs(string(modelFileContent)) + modelFileStructs = structs.GetStructsByFilePath(modelPath) // replace package name in model file if err := s.replace( diff --git a/internal/sqlc/replace.go b/internal/sqlc/replace.go index 5589579..f730821 100644 --- a/internal/sqlc/replace.go +++ b/internal/sqlc/replace.go @@ -132,7 +132,7 @@ func replaceImports(str string, sqlcModelParam config.SqlcModels, modelFileStruc matches := r2.FindStringSubmatch(str) if len(matches) == 3 { packageImports := matches[2] - var re2 = regexp.MustCompile(`(\s+(.*)\n?)`) + re2 := regexp.MustCompile(`(\s+(.*)\n?)`) rs2 := re2.FindAllStringSubmatch(packageImports, -1) imports := make([]string, 0, len(rs2)) for _, item := range rs2 { diff --git a/internal/structs/field.go b/internal/structs/field.go index 77d0d51..9988d6a 100644 --- a/internal/structs/field.go +++ b/internal/structs/field.go @@ -3,12 +3,16 @@ package structs import ( "fmt" "sort" + + "github.com/gobeam/stringy" ) type StructField struct { Name string Type string Tags map[string]string + + exprData *fieldExprData } func (s *StructField) GetGoTag() string { @@ -29,3 +33,7 @@ func (s *StructField) GetGoTag() string { return tag } + +func (s StructField) IsExported() bool { + return s.Name == stringy.New(s.Name).UcFirst() +} diff --git a/internal/structs/parameters.go b/internal/structs/parameters.go index 221bef7..d57c6cc 100644 --- a/internal/structs/parameters.go +++ b/internal/structs/parameters.go @@ -1,9 +1,12 @@ package structs type StructParameters struct { - Name string - Imports []string - Fields []*StructField + ExternalPackage string + Name string + Imports []string + Fields []*StructField + + originalName string } func (s *StructParameters) ExistFieldIndex(name string) int { diff --git a/internal/structs/parser.go b/internal/structs/parser.go new file mode 100644 index 0000000..3e19c11 --- /dev/null +++ b/internal/structs/parser.go @@ -0,0 +1,103 @@ +package structs + +import ( + "fmt" + "go/ast" + "strings" +) + +type fieldExprData struct { + isExported bool + ixExternal bool + typeName string + pkgName string + pkgType string +} + +func parseTypeExpr(file *ast.File, typeExpr ast.Expr, ref bool) (*fieldExprData, error) { + switch expr := typeExpr.(type) { + // type Foo interface{} + case *ast.InterfaceType: + return nil, nil + + // type Foo struct {...} + case *ast.StructType: + return nil, fmt.Errorf("currently unavailable parse nested struct") + + // type Foo Baz + case *ast.Ident: + return &fieldExprData{ + isExported: expr.IsExported(), + typeName: expr.Name, + }, nil + + // type Foo *Baz + case *ast.StarExpr: + t, err := parseTypeExpr(file, expr.X, ref) + if err != nil { + return nil, err + } + return &fieldExprData{ + isExported: t.isExported, + typeName: "*" + t.typeName, + }, nil + + // type Foo pkg.Bar + case *ast.SelectorExpr: + if xIdent, ok := expr.X.(*ast.Ident); ok { + fd := &fieldExprData{ + isExported: xIdent.IsExported(), + ixExternal: true, + typeName: strings.Join([]string{xIdent.Name, expr.Sel.Name}, "."), + pkgName: xIdent.Name, + pkgType: expr.Sel.Name, + } + return fd, nil + } + + return nil, fmt.Errorf("undefined selector expr") + + // type Foo []Baz + case *ast.ArrayType: + t, err := parseTypeExpr(file, expr.Elt, true) + if err != nil { + return nil, err + } + + return &fieldExprData{ + isExported: t.isExported, + typeName: "[]" + t.typeName, + }, nil + + // type Foo map[string]Bar + case *ast.MapType: + key, err := parseTypeExpr(file, expr.Value, true) + if err != nil { + return nil, err + } + + if _, ok := expr.Value.(*ast.InterfaceType); ok { + fd := &fieldExprData{ + typeName: fmt.Sprintf("map[%s]any", key.typeName), + } + return fd, nil + } + + value, err := parseTypeExpr(file, expr.Value, true) + if err != nil { + return nil, err + } + + fd := &fieldExprData{ + isExported: value.isExported, + typeName: fmt.Sprintf("map[%s]%s", key.typeName, value.typeName), + } + + return fd, nil + + case *ast.FuncType: + return nil, nil + default: + return nil, fmt.Errorf("unavailable type: %v", expr) + } +} diff --git a/internal/structs/pgxgen_test.go b/internal/structs/pgxgen_test.go index 3dcad81..eeb6172 100644 --- a/internal/structs/pgxgen_test.go +++ b/internal/structs/pgxgen_test.go @@ -7,6 +7,11 @@ import ( "regexp" "strings" "testing" + "time" + + "github.com/davecgh/go-spew/spew" + "github.com/tkcrm/pgxgen/internal/structs" + "github.com/tkcrm/pgxgen/utils" ) type structParameters struct { @@ -126,3 +131,30 @@ func Test_UpdateStruct(t *testing.T) { w.WriteString("bun.BaseModel `bun:\"table:users,alias:u\"`\n\n") } } + +func TestGetStructsOld(t *testing.T) { + data, err := utils.ReadFile("./teststruct.go") + if err != nil { + t.Fatal(err) + } + + now := time.Now() + res := structs.GetStructsOld(string(data)) + spew.Dump(res) + fmt.Println(time.Since(now)) +} + +func TestGetStructs(t *testing.T) { + now := time.Now() + res := structs.GetStructsByFilePath("../../testdata/teststructs/teststructs.go") + spew.Dump(res) + fmt.Println(time.Since(now)) +} + +func TestGetStructsRemoveUnexported(t *testing.T) { + now := time.Now() + res := structs.GetStructsByFilePath("../../testdata/teststructs/unexported.go") + res.RemoveUnexportedFields() + spew.Dump(res) + fmt.Println(time.Since(now)) +} diff --git a/internal/structs/slice.go b/internal/structs/slice.go index cfd5aab..309717b 100644 --- a/internal/structs/slice.go +++ b/internal/structs/slice.go @@ -18,6 +18,10 @@ func (st *StructSlice) ExistStructIndex(name string) (int, *StructParameters) { } func (st *StructSlice) Sort(priorityNames ...string) error { + if len(priorityNames) == 0 { + return nil + } + names := make([]string, 0, len(*st)) for _, name := range priorityNames { existStructIndex, _ := st.ExistStructIndex(name) diff --git a/internal/structs/structs.go b/internal/structs/structs.go index ba10dad..2197358 100644 --- a/internal/structs/structs.go +++ b/internal/structs/structs.go @@ -2,24 +2,321 @@ package structs import ( "bufio" + "fmt" + "go/ast" + "go/parser" + "go/token" "io" "log" + "path/filepath" "regexp" "slices" "strings" "github.com/gobeam/stringy" "github.com/tkcrm/pgxgen/utils" + "golang.org/x/tools/go/packages" ) -type Types map[string]TypesParameters -type Structs map[string]*StructParameters +type ( + Types map[string]TypesParameters + Structs map[string]*StructParameters +) func (s Structs) AddStruct(name string, params *StructParameters) { s[name] = params } -func GetStructs(file_models_str string) Structs { +func (st *Structs) RemoveUnexportedFields() { + for _, s := range *st { + newFields := []*StructField{} + for _, field := range s.Fields { + if field.IsExported() { + newFields = append(newFields, field) + } + } + s.Fields = newFields + } +} + +func loadPackages(dirPath string) ([]*packages.Package, error) { + conf := &packages.Config{ + Dir: dirPath, + Mode: packages.NeedFiles | + packages.NeedDeps | + packages.NeedSyntax | + packages.NeedImports | + packages.NeedTypes | + packages.NeedTypesInfo | + packages.NeedModule, + } + + pkgs, err := packages.Load(conf) + if err != nil { + return nil, fmt.Errorf("load packages error: %v", err) + } + + // if packages.PrintErrors(pkgs) > 0 { + // return nil, fmt.Errorf("failed to load packages") + // } + + return pkgs, nil +} + +func GetStructsByFilePath(filePath string) Structs { + structs := make(Structs) + + fset := token.NewFileSet() + node, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments) + if err != nil { + log.Fatal(err) + } + + // get file imports + fileImports := make([]string, 0, len(node.Imports)) + for _, i := range node.Imports { + var name, path string + if i.Name != nil { + name = i.Name.Name + } + if i.Path != nil { + path = i.Path.Value + } + fileImports = append(fileImports, strings.TrimSpace(fmt.Sprintf("%s %s", name, path))) + } + + _externalTypes := make(map[string]*ast.TypeSpec) + + // get struct types + ast.Inspect(node, func(n ast.Node) bool { + sp := &StructParameters{ + Imports: fileImports, + } + + switch n := n.(type) { + case *ast.TypeSpec: + if _, ok := n.Type.(*ast.StructType); ok { + if err := parseTypeSpec(node, sp, n); err != nil { + log.Fatal(err) + } + if sp.Name != "" { + structs.AddStruct(sp.Name, sp) + } + } else { + _externalTypes[n.Name.Name] = n + } + + // default: + // spew.Dump(n) + } + + return true + }) + + pkgs, err := loadPackages(filepath.Dir(filePath)) + if err != nil { + log.Fatal(err) + } + + for typeName, item := range _externalTypes { + se, ok := item.Type.(*ast.SelectorExpr) + if !ok { + continue + } + + x, ok := se.X.(*ast.Ident) + if !ok { + continue + } + + packages.Visit(pkgs, nil, func(p *packages.Package) { + for _, syntax := range p.Syntax { + if syntax.Name.Name != x.Name { + continue + } + + for _, decl := range syntax.Decls { + genDecl, ok := decl.(*ast.GenDecl) + if !ok { + continue + } + + for _, spec := range genDecl.Specs { + ts, ok := spec.(*ast.TypeSpec) + if !ok { + continue + } + + if ts.Name.Name == se.Sel.Name { + sp := &StructParameters{ + ExternalPackage: se.Sel.Name, + Imports: fileImports, + } + if err := parseTypeSpec(syntax, sp, ts); err != nil { + log.Fatal(err) + } + sp.Name = typeName + if sp.Name != "" { + structs.AddStruct(sp.Name, sp) + } + } + } + } + // spew.Dump(syntax) + } + }) + } + + // map[fieldTypeName]*StructField + exportedTypes := make(map[string]*StructField) + // map[pkgName]map[pkgFieldTypeName]*StructField + externalTypes := make(map[string]map[string]*StructField) + for _, s := range structs { + for _, field := range s.Fields { + // exported fields + if field.exprData.isExported { + exportedTypes[field.Type] = field + } + + // external fields + if field.exprData.ixExternal { + if _, ok := externalTypes[s.originalName]; !ok { + externalTypes[field.exprData.pkgName] = make(map[string]*StructField) + } + externalTypes[field.exprData.pkgName][field.exprData.pkgType] = field + } + } + } + + // find exported types in package + if len(exportedTypes) > 0 { + for _, pkg := range pkgs { + for _, syntax := range pkg.Syntax { + for _, decl := range syntax.Decls { + genDecl, ok := decl.(*ast.GenDecl) + if !ok { + continue + } + + for _, spec := range genDecl.Specs { + ts, ok := spec.(*ast.TypeSpec) + if !ok { + continue + } + + if _, ok := exportedTypes[ts.Name.Name]; !ok { + continue + } + + sp := &StructParameters{ + Imports: fileImports, + } + if err := parseTypeSpec(syntax, sp, ts); err != nil { + log.Fatal(err) + } + sp.Name = ts.Name.Name + if sp.Name != "" { + structs.AddStruct(sp.Name, sp) + } + } + } + } + } + } + + // find extrnal + if len(externalTypes) > 0 { + packages.Visit(pkgs, nil, func(p *packages.Package) { + for _, syntax := range p.Syntax { + extPkg, ok := externalTypes[syntax.Name.Name] + if !ok { + continue + } + + for _, decl := range syntax.Decls { + genDecl, ok := decl.(*ast.GenDecl) + if !ok { + continue + } + + for _, spec := range genDecl.Specs { + ts, ok := spec.(*ast.TypeSpec) + if !ok { + continue + } + + extType, ok := extPkg[ts.Name.Name] + if !ok { + continue + } + + sp := &StructParameters{ + ExternalPackage: syntax.Name.Name, + Imports: fileImports, + } + if err := parseTypeSpec(syntax, sp, ts); err != nil { + log.Fatal(err) + } + sp.Name = extType.Name + if sp.Name != "" { + structs.AddStruct(sp.Name, sp) + } + } + } + } + }) + } + + return structs +} + +func parseTypeSpec(node *ast.File, sp *StructParameters, spec *ast.TypeSpec) error { + structType, ok := spec.Type.(*ast.StructType) + if !ok { + return nil + } + + if spec.Name != nil { + sp.Name = spec.Name.Name + sp.originalName = spec.Name.Name + } + + if structType.Fields != nil { + for _, field := range structType.Fields.List { + f := &StructField{} + + if field.Tag != nil { + reTags := regexp.MustCompile(`(\w+):\"(\w+)\"`) + match := reTags.FindAllStringSubmatch(field.Tag.Value, -1) + f.Tags = make(map[string]string, len(match)) + for _, m := range match { + f.Tags[m[1]] = m[2] + } + } + + fTypeData, err := parseTypeExpr(node, field.Type, true) + if err != nil { + log.Fatal(err) + } + + if fTypeData.typeName == "" { + continue + } + + f.Type = fTypeData.typeName + f.exprData = fTypeData + + for _, fName := range field.Names { + f.Name = fName.Name + sp.Fields = append(sp.Fields, f) + } + } + } + + return nil +} + +func GetStructsOld(file_models_str string) Structs { r := bufio.NewReader(strings.NewReader(file_models_str)) structs := make(Structs) @@ -126,6 +423,10 @@ func (s StructParameters) GetNestedStructs(scalarTypes Types) []string { continue } + if slices.Contains([]string{"[]byte"}, field.Type) { + continue + } + _, existScalarType := scalarTypes[field.Type] if !slices.Contains(res, field.Type) && !existScalarType { res = append(res, field.Type) diff --git a/internal/typescript/typescript.go b/internal/typescript/typescript.go index cc0ee34..0afaea5 100644 --- a/internal/typescript/typescript.go +++ b/internal/typescript/typescript.go @@ -74,12 +74,7 @@ func (s *typescript) generateTypescript(args []string) error { continue } - file, err := os.ReadFile(filepath.Join(config.Path, item.Name())) - if err != nil { - return err - } - - for key, value := range structs.GetStructs(string(file)) { + for key, value := range structs.GetStructsByFilePath(filepath.Join(config.Path, item.Name())) { _structs[key] = value } diff --git a/pkg/logger/types.go b/pkg/logger/types.go index d16bf9b..26021a5 100644 --- a/pkg/logger/types.go +++ b/pkg/logger/types.go @@ -6,23 +6,23 @@ import ( ) type Logger interface { - //Debug(...any) - //Debugf(template string, args ...any) + // Debug(...any) + // Debugf(template string, args ...any) Info(...any) Infof(template string, args ...any) - //Warn(...any) - //Warnf(template string, args ...any) + // Warn(...any) + // Warnf(template string, args ...any) - //Error(...any) - //Errorf(template string, args ...any) + // Error(...any) + // Errorf(template string, args ...any) Fatal(...any) Fatalf(template string, args ...any) - //Panic(...any) - //Panicf(template string, args ...any) + // Panic(...any) + // Panicf(template string, args ...any) } type logger struct { diff --git a/pkg/sqlc/analyzer/analyzer.go b/pkg/sqlc/analyzer/analyzer.go index c59a1d4..9f52a65 100644 --- a/pkg/sqlc/analyzer/analyzer.go +++ b/pkg/sqlc/analyzer/analyzer.go @@ -48,7 +48,7 @@ func (c *CachedAnalyzer) Analyze(ctx context.Context, n ast.Node, q string, sche } func (c *CachedAnalyzer) analyze(ctx context.Context, n ast.Node, q string, schema []string, np *named.ParamSet) (*analysis.Analysis, bool, error) { - // Only cache queries for managed databases. We can't be certain the the + // Only cache queries for managed databases. We can't be certain the // database is in an unchanged state otherwise if !c.db.Managed { return nil, true, nil diff --git a/pkg/sqlc/cmd/cmd.go b/pkg/sqlc/cmd/cmd.go index 235d114..7319c32 100644 --- a/pkg/sqlc/cmd/cmd.go +++ b/pkg/sqlc/cmd/cmd.go @@ -36,7 +36,6 @@ func init() { func Do(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) int { rootCmd := &cobra.Command{Use: "sqlc", SilenceUsage: true} rootCmd.PersistentFlags().StringP("file", "f", "", "specify an alternate config file (default: sqlc.yaml)") - rootCmd.PersistentFlags().BoolP("experimental", "x", false, "DEPRECATED: enable experimental features (default: false)") rootCmd.PersistentFlags().Bool("no-remote", false, "disable remote execution (default: false)") rootCmd.PersistentFlags().Bool("remote", false, "enable remote execution (default: false)") diff --git a/pkg/sqlc/cmd/generate.go b/pkg/sqlc/cmd/generate.go index ba92392..002b791 100644 --- a/pkg/sqlc/cmd/generate.go +++ b/pkg/sqlc/cmd/generate.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "runtime/trace" + "strings" "sync" "google.golang.org/grpc" @@ -208,8 +209,21 @@ func (g *generator) ProcessResult(ctx context.Context, combo config.CombinedSett files[file.Name] = string(file.Contents) } g.m.Lock() + + // out is specified by the user, not a plugin + absout := filepath.Join(g.dir, out) + for n, source := range files { filename := filepath.Join(g.dir, out, n) + // filepath.Join calls filepath.Clean which should remove all "..", but + // double check to make sure + if strings.Contains(filename, "..") { + return fmt.Errorf("invalid file output path: %s", filename) + } + // The output file must be contained inside the output directory + if !strings.HasPrefix(filename, absout) { + return fmt.Errorf("invalid file output path: %s", filename) + } g.output[filename] = source } g.m.Unlock() diff --git a/pkg/sqlc/codegen/golang/driver.go b/pkg/sqlc/codegen/golang/driver.go index 7ef723b..4b106f3 100644 --- a/pkg/sqlc/codegen/golang/driver.go +++ b/pkg/sqlc/codegen/golang/driver.go @@ -1,46 +1,14 @@ package golang -type SQLDriver string +import "github.com/tkcrm/pgxgen/pkg/sqlc/codegen/golang/opts" -const ( - SQLPackagePGXV4 string = "pgx/v4" - SQLPackagePGXV5 string = "pgx/v5" - SQLPackageStandard string = "database/sql" -) - -const ( - SQLDriverPGXV4 SQLDriver = "github.com/jackc/pgx/v4" - SQLDriverPGXV5 = "github.com/jackc/pgx/v5" - SQLDriverLibPQ = "github.com/lib/pq" - SQLDriverGoSQLDriverMySQL = "github.com/go-sql-driver/mysql" -) - -func parseDriver(sqlPackage string) SQLDriver { +func parseDriver(sqlPackage string) opts.SQLDriver { switch sqlPackage { - case SQLPackagePGXV4: - return SQLDriverPGXV4 - case SQLPackagePGXV5: - return SQLDriverPGXV5 - default: - return SQLDriverLibPQ - } -} - -func (d SQLDriver) IsPGX() bool { - return d == SQLDriverPGXV4 || d == SQLDriverPGXV5 -} - -func (d SQLDriver) IsGoSQLDriverMySQL() bool { - return d == SQLDriverGoSQLDriverMySQL -} - -func (d SQLDriver) Package() string { - switch d { - case SQLDriverPGXV4: - return SQLPackagePGXV4 - case SQLDriverPGXV5: - return SQLPackagePGXV5 + case opts.SQLPackagePGXV4: + return opts.SQLDriverPGXV4 + case opts.SQLPackagePGXV5: + return opts.SQLDriverPGXV5 default: - return SQLPackageStandard + return opts.SQLDriverLibPQ } } diff --git a/pkg/sqlc/codegen/golang/gen.go b/pkg/sqlc/codegen/golang/gen.go index 2331420..c8a6e95 100644 --- a/pkg/sqlc/codegen/golang/gen.go +++ b/pkg/sqlc/codegen/golang/gen.go @@ -19,7 +19,7 @@ import ( type tmplCtx struct { Q string Package string - SQLDriver SQLDriver + SQLDriver opts.SQLDriver Enums []Enum Structs []Struct GoQueries []Query @@ -189,15 +189,15 @@ func generate(req *plugin.GenerateRequest, options *opts.Options, enums []Enum, OmitSqlcVersion: options.OmitSqlcVersion, } - if tctx.UsesCopyFrom && !tctx.SQLDriver.IsPGX() && options.SqlDriver != SQLDriverGoSQLDriverMySQL { + if tctx.UsesCopyFrom && !tctx.SQLDriver.IsPGX() && options.SqlDriver != opts.SQLDriverGoSQLDriverMySQL { return nil, errors.New(":copyfrom is only supported by pgx and github.com/go-sql-driver/mysql") } - if tctx.UsesCopyFrom && options.SqlDriver == SQLDriverGoSQLDriverMySQL { + if tctx.UsesCopyFrom && options.SqlDriver == opts.SQLDriverGoSQLDriverMySQL { if err := checkNoTimesForMySQLCopyFrom(queries); err != nil { return nil, err } - tctx.SQLDriver = SQLDriverGoSQLDriverMySQL + tctx.SQLDriver = opts.SQLDriverGoSQLDriverMySQL } if tctx.UsesBatch && !tctx.SQLDriver.IsPGX() { @@ -209,6 +209,7 @@ func generate(req *plugin.GenerateRequest, options *opts.Options, enums []Enum, "comment": sdk.DoubleSlashComment, "escape": sdk.EscapeBacktick, "imports": i.Imports, + "hasImports": i.HasImports, "hasPrefix": strings.HasPrefix, // These methods are Go specific, they do not belong in the codegen package diff --git a/pkg/sqlc/codegen/golang/imports.go b/pkg/sqlc/codegen/golang/imports.go index 8bffb6e..8494366 100644 --- a/pkg/sqlc/codegen/golang/imports.go +++ b/pkg/sqlc/codegen/golang/imports.go @@ -75,6 +75,11 @@ func (i *importer) usesType(typ string) bool { return false } +func (i *importer) HasImports(filename string) bool { + imports := i.Imports(filename) + return len(imports[0]) != 0 || len(imports[1]) != 0 +} + func (i *importer) Imports(filename string) [][]ImportSpec { dbFileName := "db.go" if i.Options.OutputDbFileName != "" { @@ -121,10 +126,10 @@ func (i *importer) dbImports() fileImports { sqlpkg := parseDriver(i.Options.SqlPackage) switch sqlpkg { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgconn"}) pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgx/v4"}) - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgx/v5/pgconn"}) pkg = append(pkg, ImportSpec{Path: "github.com/jackc/pgx/v5"}) default: @@ -167,9 +172,9 @@ func buildImports(options *opts.Options, queries []Query, uses func(string) bool for _, q := range queries { if q.Cmd == metadata.CmdExecResult { switch sqlpkg { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: pkg[ImportSpec{Path: "github.com/jackc/pgconn"}] = struct{}{} - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: pkg[ImportSpec{Path: "github.com/jackc/pgx/v5/pgconn"}] = struct{}{} default: std["database/sql"] = struct{}{} @@ -184,7 +189,7 @@ func buildImports(options *opts.Options, queries []Query, uses func(string) bool } if uses("pgtype.") { - if sqlpkg == SQLDriverPGXV5 { + if sqlpkg == opts.SQLDriverPGXV5 { pkg[ImportSpec{Path: "github.com/jackc/pgx/v5/pgtype"}] = struct{}{} } else { pkg[ImportSpec{Path: "github.com/jackc/pgtype"}] = struct{}{} @@ -424,7 +429,7 @@ func (i *importer) copyfromImports() fileImports { }) std["context"] = struct{}{} - if i.Options.SqlDriver == SQLDriverGoSQLDriverMySQL { + if i.Options.SqlDriver == opts.SQLDriverGoSQLDriverMySQL { std["io"] = struct{}{} std["fmt"] = struct{}{} std["sync/atomic"] = struct{}{} @@ -476,9 +481,9 @@ func (i *importer) batchImports() fileImports { std["errors"] = struct{}{} sqlpkg := parseDriver(i.Options.SqlPackage) switch sqlpkg { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: pkg[ImportSpec{Path: "github.com/jackc/pgx/v4"}] = struct{}{} - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: pkg[ImportSpec{Path: "github.com/jackc/pgx/v5"}] = struct{}{} } diff --git a/pkg/sqlc/codegen/golang/mysql_type.go b/pkg/sqlc/codegen/golang/mysql_type.go index ec16125..4638130 100644 --- a/pkg/sqlc/codegen/golang/mysql_type.go +++ b/pkg/sqlc/codegen/golang/mysql_type.go @@ -31,14 +31,22 @@ func mysqlType(req *plugin.GenerateRequest, options *opts.Options, col *plugin.C } else { if notNull { if unsigned { - return "uint32" + return "uint8" } - return "int32" + return "int8" } - return "sql.NullInt32" + // The database/sql package does not have a sql.NullInt8 type, so we + // use the smallest type they have which is NullInt16 + return "sql.NullInt16" } - case "smallint", "year": + case "year": + if notNull { + return "int16" + } + return "sql.NullInt16" + + case "smallint": if notNull { if unsigned { return "uint16" diff --git a/pkg/sqlc/codegen/golang/opts/enum.go b/pkg/sqlc/codegen/golang/opts/enum.go new file mode 100644 index 0000000..40457d0 --- /dev/null +++ b/pkg/sqlc/codegen/golang/opts/enum.go @@ -0,0 +1,64 @@ +package opts + +import "fmt" + +type SQLDriver string + +const ( + SQLPackagePGXV4 string = "pgx/v4" + SQLPackagePGXV5 string = "pgx/v5" + SQLPackageStandard string = "database/sql" +) + +var validPackages = map[string]struct{}{ + string(SQLPackagePGXV4): {}, + string(SQLPackagePGXV5): {}, + string(SQLPackageStandard): {}, +} + +func validatePackage(sqlPackage string) error { + if _, found := validPackages[sqlPackage]; !found { + return fmt.Errorf("unknown SQL package: %s", sqlPackage) + } + return nil +} + +const ( + SQLDriverPGXV4 SQLDriver = "github.com/jackc/pgx/v4" + SQLDriverPGXV5 = "github.com/jackc/pgx/v5" + SQLDriverLibPQ = "github.com/lib/pq" + SQLDriverGoSQLDriverMySQL = "github.com/go-sql-driver/mysql" +) + +var validDrivers = map[string]struct{}{ + string(SQLDriverPGXV4): {}, + string(SQLDriverPGXV5): {}, + string(SQLDriverLibPQ): {}, + string(SQLDriverGoSQLDriverMySQL): {}, +} + +func validateDriver(sqlDriver string) error { + if _, found := validDrivers[sqlDriver]; !found { + return fmt.Errorf("unknown SQL driver: %s", sqlDriver) + } + return nil +} + +func (d SQLDriver) IsPGX() bool { + return d == SQLDriverPGXV4 || d == SQLDriverPGXV5 +} + +func (d SQLDriver) IsGoSQLDriverMySQL() bool { + return d == SQLDriverGoSQLDriverMySQL +} + +func (d SQLDriver) Package() string { + switch d { + case SQLDriverPGXV4: + return SQLPackagePGXV4 + case SQLDriverPGXV5: + return SQLPackagePGXV5 + default: + return SQLPackageStandard + } +} diff --git a/pkg/sqlc/codegen/golang/opts/options.go b/pkg/sqlc/codegen/golang/opts/options.go index 5e483b6..3f67d1c 100644 --- a/pkg/sqlc/codegen/golang/opts/options.go +++ b/pkg/sqlc/codegen/golang/opts/options.go @@ -43,6 +43,9 @@ type Options struct { OmitSqlcVersion bool `json:"omit_sqlc_version,omitempty" yaml:"omit_sqlc_version"` OmitUnusedStructs bool `json:"omit_unused_structs,omitempty" yaml:"omit_unused_structs"` BuildTags string `json:"build_tags,omitempty" yaml:"build_tags"` + Initialisms *[]string `json:"initialisms,omitempty" yaml:"initialisms"` + + InitialismsMap map[string]struct{} `json:"-" yaml:"-"` } type GlobalOptions struct { @@ -94,11 +97,33 @@ func parseOpts(req *plugin.GenerateRequest) (*Options, error) { } } + if options.SqlPackage != "" { + if err := validatePackage(options.SqlPackage); err != nil { + return nil, fmt.Errorf("invalid options: %s", err) + } + } + + if options.SqlDriver != "" { + if err := validateDriver(options.SqlDriver); err != nil { + return nil, fmt.Errorf("invalid options: %s", err) + } + } + if options.QueryParameterLimit == nil { options.QueryParameterLimit = new(int32) *options.QueryParameterLimit = 1 } + if options.Initialisms == nil { + options.Initialisms = new([]string) + *options.Initialisms = []string{"id"} + } + + options.InitialismsMap = map[string]struct{}{} + for _, initial := range *options.Initialisms { + options.InitialismsMap[initial] = struct{}{} + } + return &options, nil } diff --git a/pkg/sqlc/codegen/golang/postgresql_type.go b/pkg/sqlc/codegen/golang/postgresql_type.go index 54446ef..97070ac 100644 --- a/pkg/sqlc/codegen/golang/postgresql_type.go +++ b/pkg/sqlc/codegen/golang/postgresql_type.go @@ -48,7 +48,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int32" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Int4" } return "sql.NullInt32" @@ -60,7 +60,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int64" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Int8" } return "sql.NullInt64" @@ -72,7 +72,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int16" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Int2" } return "sql.NullInt16" @@ -84,7 +84,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int32" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Int4" } return "sql.NullInt32" @@ -96,7 +96,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int64" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Int8" } return "sql.NullInt64" @@ -108,7 +108,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*int16" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Int2" } return "sql.NullInt16" @@ -120,7 +120,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*float64" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Float8" } return "sql.NullFloat64" @@ -132,7 +132,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*float32" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Float4" } return "sql.NullFloat64" // TODO: Change to sql.NullFloat32 after updating the go.mod file @@ -160,18 +160,18 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*bool" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Bool" } return "sql.NullBool" case "json": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "[]byte" - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.JSON" - case SQLDriverLibPQ: + case opts.SQLDriverLibPQ: if notNull { return "json.RawMessage" } else { @@ -183,11 +183,11 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "jsonb": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "[]byte" - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.JSONB" - case SQLDriverLibPQ: + case opts.SQLDriverLibPQ: if notNull { return "json.RawMessage" } else { @@ -201,7 +201,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi return "[]byte" case "date": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Date" } if notNull { @@ -213,7 +213,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi return "sql.NullTime" case "pg_catalog.time": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Time" } if notNull { @@ -234,7 +234,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi return "sql.NullTime" case "pg_catalog.timestamp": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Timestamp" } if notNull { @@ -246,7 +246,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi return "sql.NullTime" case "pg_catalog.timestamptz", "timestamptz": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Timestamptz" } if notNull { @@ -264,13 +264,13 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*string" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Text" } return "sql.NullString" case "uuid": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.UUID" } if notNull { @@ -283,14 +283,14 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "inet": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: if notNull { return "netip.Addr" } return "*netip.Addr" - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.Inet" - case SQLDriverLibPQ: + case opts.SQLDriverLibPQ: return "pqtype.Inet" default: return "interface{}" @@ -298,14 +298,14 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "cidr": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: if notNull { return "netip.Prefix" } return "*netip.Prefix" - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.CIDR" - case SQLDriverLibPQ: + case opts.SQLDriverLibPQ: return "pqtype.CIDR" default: return "interface{}" @@ -313,11 +313,11 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "macaddr", "macaddr8": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "net.HardwareAddr" - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.Macaddr" - case SQLDriverLibPQ: + case opts.SQLDriverLibPQ: return "pqtype.Macaddr" default: return "interface{}" @@ -335,13 +335,13 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi if emitPointersForNull { return "*string" } - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Text" } return "sql.NullString" case "interval", "pg_catalog.interval": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Interval" } if notNull { @@ -354,9 +354,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "daterange": switch driver { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.Daterange" - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Range[pgtype.Date]" default: return "interface{}" @@ -364,7 +364,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "datemultirange": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Multirange[pgtype.Range[pgtype.Date]]" default: return "interface{}" @@ -372,9 +372,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "tsrange": switch driver { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.Tsrange" - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Range[pgtype.Timestamp]" default: return "interface{}" @@ -382,7 +382,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "tsmultirange": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Multirange[pgtype.Range[pgtype.Timestamp]]" default: return "interface{}" @@ -390,9 +390,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "tstzrange": switch driver { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.Tstzrange" - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Range[pgtype.Timestamptz]" default: return "interface{}" @@ -400,7 +400,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "tstzmultirange": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Multirange[pgtype.Range[pgtype.Timestamptz]]" default: return "interface{}" @@ -408,9 +408,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "numrange": switch driver { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.Numrange" - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Range[pgtype.Numeric]" default: return "interface{}" @@ -418,7 +418,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "nummultirange": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Multirange[pgtype.Range[pgtype.Numeric]]" default: return "interface{}" @@ -426,9 +426,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "int4range": switch driver { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.Int4range" - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Range[pgtype.Int4]" default: return "interface{}" @@ -436,7 +436,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "int4multirange": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Multirange[pgtype.Range[pgtype.Int4]]" default: return "interface{}" @@ -444,9 +444,9 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "int8range": switch driver { - case SQLDriverPGXV4: + case opts.SQLDriverPGXV4: return "pgtype.Int8range" - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Range[pgtype.Int8]" default: return "interface{}" @@ -454,7 +454,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi case "int8multirange": switch driver { - case SQLDriverPGXV5: + case opts.SQLDriverPGXV5: return "pgtype.Multirange[pgtype.Range[pgtype.Int8]]" default: return "interface{}" @@ -467,26 +467,26 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi return "interface{}" case "bit", "varbit", "pg_catalog.bit", "pg_catalog.varbit": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Bits" } - if driver == SQLDriverPGXV4 { + if driver == opts.SQLDriverPGXV4 { return "pgtype.Varbit" } case "cid": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Uint32" } - if driver == SQLDriverPGXV4 { + if driver == opts.SQLDriverPGXV4 { return "pgtype.CID" } case "oid": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Uint32" } - if driver == SQLDriverPGXV4 { + if driver == opts.SQLDriverPGXV4 { return "pgtype.OID" } @@ -496,10 +496,10 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi } case "xid": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { return "pgtype.Uint32" } - if driver == SQLDriverPGXV4 { + if driver == opts.SQLDriverPGXV4 { return "pgtype.XID" } @@ -539,7 +539,7 @@ func postgresType(req *plugin.GenerateRequest, options *opts.Options, col *plugi } case "vector": - if driver == SQLDriverPGXV5 { + if driver == opts.SQLDriverPGXV5 { if emitPointersForNull { return "*pgvector.Vector" } else { diff --git a/pkg/sqlc/codegen/golang/query.go b/pkg/sqlc/codegen/golang/query.go index 3883ef0..7c3cc2f 100644 --- a/pkg/sqlc/codegen/golang/query.go +++ b/pkg/sqlc/codegen/golang/query.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/tkcrm/pgxgen/pkg/sqlc/codegen/golang/opts" "github.com/tkcrm/pgxgen/pkg/sqlc/metadata" "github.com/tkcrm/pgxgen/pkg/sqlc/plugin" ) @@ -15,7 +16,7 @@ type QueryValue struct { DBName string // The name of the field in the database. Only set if Struct==nil. Struct *Struct Typ string - SQLDriver SQLDriver + SQLDriver opts.SQLDriver // Column is kept so late in the generation process around to differentiate // between mysql slices and pg arrays diff --git a/pkg/sqlc/codegen/golang/struct.go b/pkg/sqlc/codegen/golang/struct.go index f466107..55982d3 100644 --- a/pkg/sqlc/codegen/golang/struct.go +++ b/pkg/sqlc/codegen/golang/struct.go @@ -32,8 +32,8 @@ func StructName(name string, options *opts.Options) string { }, name) for _, p := range strings.Split(name, "_") { - if p == "id" { - out += "ID" + if _, found := options.InitialismsMap[p]; found { + out += strings.ToUpper(p) } else { out += strings.Title(p) } diff --git a/pkg/sqlc/codegen/golang/templates/go-sql-driver-mysql/copyfromCopy.tmpl b/pkg/sqlc/codegen/golang/templates/go-sql-driver-mysql/copyfromCopy.tmpl index 3bdc5d5..e6b9061 100644 --- a/pkg/sqlc/codegen/golang/templates/go-sql-driver-mysql/copyfromCopy.tmpl +++ b/pkg/sqlc/codegen/golang/templates/go-sql-driver-mysql/copyfromCopy.tmpl @@ -10,7 +10,7 @@ func convertRowsFor{{.MethodName}}(w *io.PipeWriter, {{.Arg.SlicePair}}) { {{- range $arg.CopyFromMySQLFields}} {{- if eq .Type "string"}} e.AppendString({{if eq (len $arg.CopyFromMySQLFields) 1}}row{{else}}row.{{.Name}}{{end}}) -{{- else if eq .Type "[]byte"}} +{{- else if or (eq .Type "[]byte") (eq .Type "json.RawMessage")}} e.AppendBytes({{if eq (len $arg.CopyFromMySQLFields) 1}}row{{else}}row.{{.Name}}{{end}}) {{- else}} e.AppendValue({{if eq (len $arg.CopyFromMySQLFields) 1}}row{{else}}row.{{.Name}}{{end}}) diff --git a/pkg/sqlc/codegen/golang/templates/pgx/batchCode.tmpl b/pkg/sqlc/codegen/golang/templates/pgx/batchCode.tmpl index 93cdad4..35bd701 100644 --- a/pkg/sqlc/codegen/golang/templates/pgx/batchCode.tmpl +++ b/pkg/sqlc/codegen/golang/templates/pgx/batchCode.tmpl @@ -16,7 +16,7 @@ type {{.MethodName}}BatchResults struct { closed bool } -{{if .Arg.EmitStruct}} +{{if .Arg.Struct}} type {{.Arg.Type}} struct { {{- range .Arg.Struct.Fields}} {{.Name}} {{.Type}} {{if .Tag}}{{$.Q}}{{.Tag}}{{$.Q}}{{end}} {{- end}} diff --git a/pkg/sqlc/codegen/golang/templates/template.tmpl b/pkg/sqlc/codegen/golang/templates/template.tmpl index 9540004..afd50c0 100644 --- a/pkg/sqlc/codegen/golang/templates/template.tmpl +++ b/pkg/sqlc/codegen/golang/templates/template.tmpl @@ -9,12 +9,14 @@ package {{.Package}} +{{ if hasImports .SourceName }} import ( {{range imports .SourceName}} {{range .}}{{.}} {{end}} {{end}} ) +{{end}} {{template "dbCode" . }} {{end}} @@ -40,12 +42,14 @@ import ( package {{.Package}} +{{ if hasImports .SourceName }} import ( {{range imports .SourceName}} {{range .}}{{.}} {{end}} {{end}} ) +{{end}} {{template "interfaceCode" . }} {{end}} @@ -69,12 +73,14 @@ import ( package {{.Package}} +{{ if hasImports .SourceName }} import ( {{range imports .SourceName}} {{range .}}{{.}} {{end}} {{end}} ) +{{end}} {{template "modelsCode" . }} {{end}} @@ -167,12 +173,14 @@ type {{.Name}} struct { {{- range .Fields}} package {{.Package}} +{{ if hasImports .SourceName }} import ( {{range imports .SourceName}} {{range .}}{{.}} {{end}} {{end}} ) +{{end}} {{template "queryCode" . }} {{end}} @@ -196,12 +204,14 @@ import ( package {{.Package}} +{{ if hasImports .SourceName }} import ( {{range imports .SourceName}} {{range .}}{{.}} {{end}} {{end}} ) +{{end}} {{template "copyfromCode" . }} {{end}} @@ -225,12 +235,15 @@ import ( package {{.Package}} +{{ if hasImports .SourceName }} import ( {{range imports .SourceName}} {{range .}}{{.}} {{end}} {{end}} ) +{{end}} + {{template "batchCode" . }} {{end}} diff --git a/pkg/sqlc/config/v_two.go b/pkg/sqlc/config/v_two.go index 1d3b224..0fe22ff 100644 --- a/pkg/sqlc/config/v_two.go +++ b/pkg/sqlc/config/v_two.go @@ -76,7 +76,7 @@ func v2ParseConfig(rd io.Reader) (Config, error) { if cg.Out == "" { return conf, ErrNoOutPath } - // TOOD: Allow the use of built-in codegen from here + // TODO: Allow the use of built-in codegen from here if _, ok := plugins[cg.Plugin]; !ok { return conf, ErrPluginNotFound } diff --git a/pkg/sqlc/engine/dolphin/stdlib.go b/pkg/sqlc/engine/dolphin/stdlib.go index db0e2d5..1e98614 100644 --- a/pkg/sqlc/engine/dolphin/stdlib.go +++ b/pkg/sqlc/engine/dolphin/stdlib.go @@ -2388,6 +2388,15 @@ func defaultSchema(name string) *catalog.Schema { Args: []*catalog.Argument{}, ReturnType: &ast.TypeName{Name: "datetime"}, }, + { + Name: "NEXTVAL", + Args: []*catalog.Argument{ + { + Type: &ast.TypeName{Name: "any"}, + }, + }, + ReturnType: &ast.TypeName{Name: "int"}, + }, { Name: "NOW", Args: []*catalog.Argument{ diff --git a/pkg/sqlc/engine/postgresql/convert.go b/pkg/sqlc/engine/postgresql/convert.go index 6bfc2ba..301f73c 100644 --- a/pkg/sqlc/engine/postgresql/convert.go +++ b/pkg/sqlc/engine/postgresql/convert.go @@ -3,7 +3,7 @@ package postgresql import ( "fmt" - pg "github.com/pganalyze/pg_query_go/v4" + pg "github.com/pganalyze/pg_query_go/v5" "github.com/tkcrm/pgxgen/pkg/sqlc/sql/ast" ) @@ -183,7 +183,6 @@ func convertAggref(n *pg.Aggref) *ast.Aggref { Aggtype: ast.Oid(n.Aggtype), Aggcollid: ast.Oid(n.Aggcollid), Inputcollid: ast.Oid(n.Inputcollid), - Aggtranstype: ast.Oid(n.Aggtranstype), Aggargtypes: convertSlice(n.Aggargtypes), Aggdirectargs: convertSlice(n.Aggdirectargs), Args: convertSlice(n.Args), @@ -1663,7 +1662,6 @@ func convertGrantRoleStmt(n *pg.GrantRoleStmt) *ast.GrantRoleStmt { GrantedRoles: convertSlice(n.GrantedRoles), GranteeRoles: convertSlice(n.GranteeRoles), IsGrant: n.IsGrant, - AdminOpt: n.AdminOpt, Grantor: convertRoleSpec(n.Grantor), Behavior: ast.DropBehavior(n.Behavior), } @@ -1693,7 +1691,6 @@ func convertGroupingFunc(n *pg.GroupingFunc) *ast.GroupingFunc { Xpr: convertNode(n.Xpr), Args: convertSlice(n.Args), Refs: convertSlice(n.Refs), - Cols: convertSlice(n.Cols), Agglevelsup: ast.Index(n.Agglevelsup), Location: int(n.Location), } @@ -1754,7 +1751,6 @@ func convertIndexStmt(n *pg.IndexStmt) *ast.IndexStmt { ExcludeOpNames: convertSlice(n.ExcludeOpNames), Idxcomment: makeString(n.Idxcomment), IndexOid: ast.Oid(n.IndexOid), - OldNode: ast.Oid(n.OldNode), Unique: n.Unique, Primary: n.Primary, Isconstraint: n.Isconstraint, @@ -2016,7 +2012,6 @@ func convertOpExpr(n *pg.OpExpr) *ast.OpExpr { return &ast.OpExpr{ Xpr: convertNode(n.Xpr), Opno: ast.Oid(n.Opno), - Opfuncid: ast.Oid(n.Opfuncid), Opresulttype: ast.Oid(n.Opresulttype), Opretset: n.Opretset, Opcollid: ast.Oid(n.Opcollid), @@ -2108,7 +2103,7 @@ func convertPartitionSpec(n *pg.PartitionSpec) *ast.PartitionSpec { return nil } return &ast.PartitionSpec{ - Strategy: makeString(n.Strategy), + Strategy: makeString(n.Strategy.String()), PartParams: convertSlice(n.PartParams), Location: int(n.Location), } @@ -2266,11 +2261,6 @@ func convertRangeTblEntry(n *pg.RangeTblEntry) *ast.RangeTblEntry { Lateral: n.Lateral, Inh: n.Inh, InFromCl: n.InFromCl, - RequiredPerms: ast.AclMode(n.RequiredPerms), - CheckAsUser: ast.Oid(n.CheckAsUser), - SelectedCols: makeUint32Slice(n.SelectedCols), - InsertedCols: makeUint32Slice(n.InsertedCols), - UpdatedCols: makeUint32Slice(n.UpdatedCols), SecurityQuals: convertSlice(n.SecurityQuals), } } @@ -2498,7 +2488,6 @@ func convertScalarArrayOpExpr(n *pg.ScalarArrayOpExpr) *ast.ScalarArrayOpExpr { return &ast.ScalarArrayOpExpr{ Xpr: convertNode(n.Xpr), Opno: ast.Oid(n.Opno), - Opfuncid: ast.Oid(n.Opfuncid), UseOr: n.UseOr, Inputcollid: ast.Oid(n.Inputcollid), Args: convertSlice(n.Args), diff --git a/pkg/sqlc/engine/postgresql/parse.go b/pkg/sqlc/engine/postgresql/parse.go index ab4dd02..d39820c 100644 --- a/pkg/sqlc/engine/postgresql/parse.go +++ b/pkg/sqlc/engine/postgresql/parse.go @@ -6,7 +6,7 @@ import ( "io" "strings" - nodes "github.com/pganalyze/pg_query_go/v4" + nodes "github.com/pganalyze/pg_query_go/v5" "github.com/tkcrm/pgxgen/pkg/sqlc/engine/postgresql/parser" "github.com/tkcrm/pgxgen/pkg/sqlc/source" @@ -271,7 +271,7 @@ func translate(node *nodes.Node) (ast.Node, error) { case nodes.AlterTableType_AT_AddColumn: d, ok := altercmd.Def.Node.(*nodes.Node_ColumnDef) if !ok { - return nil, fmt.Errorf("expected alter table defintion to be a ColumnDef") + return nil, fmt.Errorf("expected alter table definition to be a ColumnDef") } rel, err := parseRelationFromNodes(d.ColumnDef.TypeName.Names) @@ -290,7 +290,7 @@ func translate(node *nodes.Node) (ast.Node, error) { case nodes.AlterTableType_AT_AlterColumnType: d, ok := altercmd.Def.Node.(*nodes.Node_ColumnDef) if !ok { - return nil, fmt.Errorf("expected alter table defintion to be a ColumnDef") + return nil, fmt.Errorf("expected alter table definition to be a ColumnDef") } col := "" if altercmd.Name != "" { diff --git a/pkg/sqlc/engine/postgresql/parse_default.go b/pkg/sqlc/engine/postgresql/parse_default.go index 993ac60..3f802cc 100644 --- a/pkg/sqlc/engine/postgresql/parse_default.go +++ b/pkg/sqlc/engine/postgresql/parse_default.go @@ -4,7 +4,7 @@ package postgresql import ( - nodes "github.com/pganalyze/pg_query_go/v4" + nodes "github.com/pganalyze/pg_query_go/v5" ) var Parse = nodes.Parse diff --git a/pkg/sqlc/engine/postgresql/parser/parser_default.go b/pkg/sqlc/engine/postgresql/parser/parser_default.go index 55555d1..06fea36 100644 --- a/pkg/sqlc/engine/postgresql/parser/parser_default.go +++ b/pkg/sqlc/engine/postgresql/parser/parser_default.go @@ -3,6 +3,6 @@ package parser -import "github.com/pganalyze/pg_query_go/v4/parser" +import "github.com/pganalyze/pg_query_go/v5/parser" type Error = parser.Error diff --git a/pkg/sqlc/engine/postgresql/utils.go b/pkg/sqlc/engine/postgresql/utils.go index 15b1c49..05d4ecc 100644 --- a/pkg/sqlc/engine/postgresql/utils.go +++ b/pkg/sqlc/engine/postgresql/utils.go @@ -1,7 +1,7 @@ package postgresql import ( - nodes "github.com/pganalyze/pg_query_go/v4" + nodes "github.com/pganalyze/pg_query_go/v5" ) func isArray(n *nodes.TypeName) bool { diff --git a/pkg/sqlc/engine/sqlite/parse.go b/pkg/sqlc/engine/sqlite/parse.go index 274fd23..dc36784 100644 --- a/pkg/sqlc/engine/sqlite/parse.go +++ b/pkg/sqlc/engine/sqlite/parse.go @@ -69,6 +69,7 @@ func (p *Parser) Parse(r io.Reader) ([]ast.Statement, error) { converter := &cc{} out := converter.convert(stmt) if _, ok := out.(*ast.TODO); ok { + loc = stmt.GetStop().GetStop() + 2 continue } len := (stmt.GetStop().GetStop() + 1) - loc diff --git a/pkg/sqlc/info/facts.go b/pkg/sqlc/info/facts.go index f3748c6..29df254 100644 --- a/pkg/sqlc/info/facts.go +++ b/pkg/sqlc/info/facts.go @@ -2,4 +2,4 @@ package info // When no version is set, return the next bug fix version // after the most recent tag -const Version = "v1.25.0" +const Version = "v1.26.0" diff --git a/pkg/sqlc/pgx/poolcache/poolcache.go b/pkg/sqlc/pgx/poolcache/poolcache.go new file mode 100644 index 0000000..93401ec --- /dev/null +++ b/pkg/sqlc/pgx/poolcache/poolcache.go @@ -0,0 +1,32 @@ +package poolcache + +import ( + "context" + "sync" + + "github.com/jackc/pgx/v5/pgxpool" +) + +var lock sync.RWMutex +var pools = map[string]*pgxpool.Pool{} + +func New(ctx context.Context, uri string) (*pgxpool.Pool, error) { + lock.RLock() + existing, found := pools[uri] + lock.RUnlock() + + if found { + return existing, nil + } + + pool, err := pgxpool.New(ctx, uri) + if err != nil { + return nil, err + } + + lock.Lock() + pools[uri] = pool + lock.Unlock() + + return pool, nil +} diff --git a/pkg/sqlc/sql/ast/aggref.go b/pkg/sqlc/sql/ast/aggref.go index c4fa9af..6642f4d 100644 --- a/pkg/sqlc/sql/ast/aggref.go +++ b/pkg/sqlc/sql/ast/aggref.go @@ -6,7 +6,6 @@ type Aggref struct { Aggtype Oid Aggcollid Oid Inputcollid Oid - Aggtranstype Oid Aggargtypes *List Aggdirectargs *List Args *List diff --git a/pkg/sqlc/sql/ast/grant_role_stmt.go b/pkg/sqlc/sql/ast/grant_role_stmt.go index 5d785ef..5e0b2a8 100644 --- a/pkg/sqlc/sql/ast/grant_role_stmt.go +++ b/pkg/sqlc/sql/ast/grant_role_stmt.go @@ -4,7 +4,6 @@ type GrantRoleStmt struct { GrantedRoles *List GranteeRoles *List IsGrant bool - AdminOpt bool Grantor *RoleSpec Behavior DropBehavior } diff --git a/pkg/sqlc/sql/ast/index_stmt.go b/pkg/sqlc/sql/ast/index_stmt.go index c0f12bd..fe0f035 100644 --- a/pkg/sqlc/sql/ast/index_stmt.go +++ b/pkg/sqlc/sql/ast/index_stmt.go @@ -11,7 +11,6 @@ type IndexStmt struct { ExcludeOpNames *List Idxcomment *string IndexOid Oid - OldNode Oid Unique bool Primary bool Isconstraint bool diff --git a/pkg/sqlc/sql/ast/op_expr.go b/pkg/sqlc/sql/ast/op_expr.go index 5b37154..0c7c217 100644 --- a/pkg/sqlc/sql/ast/op_expr.go +++ b/pkg/sqlc/sql/ast/op_expr.go @@ -3,7 +3,6 @@ package ast type OpExpr struct { Xpr Node Opno Oid - Opfuncid Oid Opresulttype Oid Opretset bool Opcollid Oid diff --git a/pkg/sqlc/sql/ast/scalar_array_op_expr.go b/pkg/sqlc/sql/ast/scalar_array_op_expr.go index 6b9ad6a..fc438c1 100644 --- a/pkg/sqlc/sql/ast/scalar_array_op_expr.go +++ b/pkg/sqlc/sql/ast/scalar_array_op_expr.go @@ -3,7 +3,6 @@ package ast type ScalarArrayOpExpr struct { Xpr Node Opno Oid - Opfuncid Oid UseOr bool Inputcollid Oid Args *List diff --git a/pkg/sqlc/sqltest/local/postgres.go b/pkg/sqlc/sqltest/local/postgres.go index 161c96e..8869b06 100644 --- a/pkg/sqlc/sqltest/local/postgres.go +++ b/pkg/sqlc/sqltest/local/postgres.go @@ -3,23 +3,31 @@ package local import ( "context" "fmt" + "hash/fnv" "net/url" "os" "strings" - "sync" "testing" "github.com/jackc/pgx/v5" - "github.com/jackc/pgx/v5/pgxpool" + "golang.org/x/sync/singleflight" migrate "github.com/tkcrm/pgxgen/pkg/sqlc/migrations" + "github.com/tkcrm/pgxgen/pkg/sqlc/pgx/poolcache" "github.com/tkcrm/pgxgen/pkg/sqlc/sql/sqlpath" ) -var postgresPool *pgxpool.Pool -var postgresSync sync.Once +var flight singleflight.Group func PostgreSQL(t *testing.T, migrations []string) string { + return postgreSQL(t, migrations, true) +} + +func ReadOnlyPostgreSQL(t *testing.T, migrations []string) string { + return postgreSQL(t, migrations, false) +} + +func postgreSQL(t *testing.T, migrations []string, rw bool) string { ctx := context.Background() t.Helper() @@ -28,16 +36,9 @@ func PostgreSQL(t *testing.T, migrations []string) string { t.Skip("POSTGRESQL_SERVER_URI is empty") } - postgresSync.Do(func() { - pool, err := pgxpool.New(ctx, dburi) - if err != nil { - t.Fatal(err) - } - postgresPool = pool - }) - - if postgresPool == nil { - t.Fatalf("PostgreSQL pool creation failed") + postgresPool, err := poolcache.New(ctx, dburi) + if err != nil { + t.Fatalf("PostgreSQL pool creation failed: %s", err) } var seed []string @@ -45,48 +46,73 @@ func PostgreSQL(t *testing.T, migrations []string) string { if err != nil { t.Fatal(err) } + + h := fnv.New64() for _, f := range files { blob, err := os.ReadFile(f) if err != nil { t.Fatal(err) } + h.Write(blob) seed = append(seed, migrate.RemoveRollbackStatements(string(blob))) } - uri, err := url.Parse(dburi) - if err != nil { - t.Fatal(err) + var name string + if rw { + name = fmt.Sprintf("sqlc_test_%s", id()) + } else { + name = fmt.Sprintf("sqlc_test_%x", h.Sum(nil)) } - name := fmt.Sprintf("sqlc_test_%s", id()) - - if _, err := postgresPool.Exec(ctx, fmt.Sprintf(`CREATE DATABASE "%s"`, name)); err != nil { + uri, err := url.Parse(dburi) + if err != nil { t.Fatal(err) } - uri.Path = name dropQuery := fmt.Sprintf(`DROP DATABASE IF EXISTS "%s" WITH (FORCE)`, name) - t.Cleanup(func() { - if _, err := postgresPool.Exec(ctx, dropQuery); err != nil { - t.Fatal(err) + key := uri.String() + + _, err, _ = flight.Do(key, func() (interface{}, error) { + row := postgresPool.QueryRow(ctx, + fmt.Sprintf(`SELECT datname FROM pg_database WHERE datname = '%s'`, name)) + + var datname string + if err := row.Scan(&datname); err == nil { + t.Logf("database exists: %s", name) + return nil, nil } - }) - conn, err := pgx.Connect(ctx, uri.String()) - if err != nil { - t.Fatalf("connect %s: %s", name, err) - } - defer conn.Close(ctx) + t.Logf("creating database: %s", name) + if _, err := postgresPool.Exec(ctx, fmt.Sprintf(`CREATE DATABASE "%s"`, name)); err != nil { + return nil, err + } - for _, q := range seed { - if len(strings.TrimSpace(q)) == 0 { - continue + conn, err := pgx.Connect(ctx, uri.String()) + if err != nil { + return nil, fmt.Errorf("connect %s: %s", name, err) } - if _, err := conn.Exec(ctx, q); err != nil { - t.Fatalf("%s: %s", q, err) + defer conn.Close(ctx) + + for _, q := range seed { + if len(strings.TrimSpace(q)) == 0 { + continue + } + if _, err := conn.Exec(ctx, q); err != nil { + return nil, fmt.Errorf("%s: %s", q, err) + } } + return nil, nil + }) + if rw || err != nil { + t.Cleanup(func() { + if _, err := postgresPool.Exec(ctx, dropQuery); err != nil { + t.Fatalf("failed cleaning up: %s", err) + } + }) } - - return uri.String() + if err != nil { + t.Fatalf("create db: %s", err) + } + return key } diff --git a/testdata/teststructs/teststructs.go b/testdata/teststructs/teststructs.go new file mode 100644 index 0000000..e629398 --- /dev/null +++ b/testdata/teststructs/teststructs.go @@ -0,0 +1,17 @@ +package teststructs + +import ( + "github.com/tkcrm/pgxgen/internal/structs" + "github.com/tkcrm/pgxgen/internal/ver" +) + +type SomeType int + +type TestStruct struct { + ID string + Data []byte + SomeType SomeType + SF structs.StructField + AnotherField structs.Types + SomeExternalType ver.CheckLastestReleaseVersionResponse +} diff --git a/testdata/teststructs/unexported.go b/testdata/teststructs/unexported.go new file mode 100644 index 0000000..78843b6 --- /dev/null +++ b/testdata/teststructs/unexported.go @@ -0,0 +1,6 @@ +package teststructs + +type Unexported struct { + ID string + skip byte +} diff --git a/utils/files.go b/utils/files.go index f807e2a..e828c42 100644 --- a/utils/files.go +++ b/utils/files.go @@ -18,7 +18,7 @@ func ExistsPath(path string) bool { func CreatePath(path string) error { if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { - if err := os.MkdirAll(path, 0755); err != nil { + if err := os.MkdirAll(path, 0o755); err != nil { return err } } diff --git a/utils/go_files.go b/utils/go_files.go index 35fdac1..58c4e03 100644 --- a/utils/go_files.go +++ b/utils/go_files.go @@ -96,7 +96,7 @@ func GetGoImportsFromFile(data string) []string { matches := r2.FindStringSubmatch(data) if len(matches) == 3 { packageImports := matches[2] - var re2 = regexp.MustCompile(`(\s+(.*)\n?)`) + re2 := regexp.MustCompile(`(\s+(.*)\n?)`) rs2 := re2.FindAllStringSubmatch(packageImports, -1) imports := make([]string, 0, len(rs2)) for _, item := range rs2 {