From 7b1ba09fa930c775d6a20a06b75fce426eab67d7 Mon Sep 17 00:00:00 2001 From: qqxhb <30866940+qqxhb@users.noreply.github.com> Date: Thu, 25 May 2023 15:24:27 +0800 Subject: [PATCH] feat: gen from sql (#815) --- go.mod | 9 +- go.sum | 17 +++- rawsql_driver/go.mod | 24 +++++ rawsql_driver/go.sum | 66 +++++++++++++ rawsql_driver/migrator.go | 58 ++++++++++++ rawsql_driver/sql.go | 140 ++++++++++++++++++++++++++++ rawsql_driver/table.go | 144 +++++++++++++++++++++++++++++ rawsql_driver/tests/gen_test.go | 36 ++++++++ rawsql_driver/tests/sql/tables.sql | 56 +++++++++++ rawsql_driver/tests/sql/user.sql | 12 +++ 10 files changed, 553 insertions(+), 9 deletions(-) create mode 100644 rawsql_driver/go.mod create mode 100644 rawsql_driver/go.sum create mode 100644 rawsql_driver/migrator.go create mode 100644 rawsql_driver/sql.go create mode 100644 rawsql_driver/table.go create mode 100644 rawsql_driver/tests/gen_test.go create mode 100644 rawsql_driver/tests/sql/tables.sql create mode 100644 rawsql_driver/tests/sql/user.sql diff --git a/go.mod b/go.mod index f2047e09..f8a84a67 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module gorm.io/gen go 1.18 require ( - golang.org/x/tools v0.1.12 + golang.org/x/tools v0.6.0 gopkg.in/yaml.v3 v3.0.1 gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c gorm.io/driver/clickhouse v0.5.0 @@ -45,10 +45,11 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect + github.com/stretchr/testify v1.8.2 // indirect go.opentelemetry.io/otel v1.10.0 // indirect go.opentelemetry.io/otel/trace v1.10.0 // indirect golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 // indirect - golang.org/x/text v0.3.7 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/text v0.8.0 // indirect ) diff --git a/go.sum b/go.sum index 76e6b387..564fb02f 100644 --- a/go.sum +++ b/go.sum @@ -195,14 +195,16 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -262,8 +264,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -282,6 +285,7 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= 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= @@ -311,8 +315,9 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 h1:AzgQNqF+FKwyQ5LbVrVqOcuuFB67N47F9+htZYH0wFM= golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= @@ -321,8 +326,9 @@ 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= 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 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -337,8 +343,9 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 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= diff --git a/rawsql_driver/go.mod b/rawsql_driver/go.mod new file mode 100644 index 00000000..5299c945 --- /dev/null +++ b/rawsql_driver/go.mod @@ -0,0 +1,24 @@ +module gorm.io/gen/rawsql_driver + +go 1.18 + +require ( + github.com/pingcap/tidb/parser v0.0.0-20230327100244-b67c0321c05a + gorm.io/gorm v1.24.6 +) + +require ( + github.com/benbjohnson/clock v1.1.0 // indirect + github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // indirect + github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/exp v0.0.0-20220428152302-39d4317da171 // indirect + golang.org/x/text v0.8.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect +) diff --git a/rawsql_driver/go.sum b/rawsql_driver/go.sum new file mode 100644 index 00000000..82f7d3bb --- /dev/null +++ b/rawsql_driver/go.sum @@ -0,0 +1,66 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso= +github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/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/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/pingcap/errors v0.11.0/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/log v0.0.0-20210625125904-98ed8e2eb1c7 h1:k2BbABz9+TNpYRwsCCFS8pEEnFVOdbgEjL/kTlLuzZQ= +github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM= +github.com/pingcap/tidb/parser v0.0.0-20230327100244-b67c0321c05a h1:GsiwtTVFsN+1bfeUaStwOoBzTC4tKpETiWmhxT55jAc= +github.com/pingcap/tidb/parser v0.0.0-20230327100244-b67c0321c05a/go.mod h1:IxXRBZ14Of1KkR3NXEwsoKrM8JbkOIHJHpwS/Ad8vPY= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20220428152302-39d4317da171 h1:TfdoLivD44QwvssI9Sv1xwa5DcL5XQr4au4sZ2F2NV4= +golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gorm.io/gorm v1.24.6 h1:wy98aq9oFEetsc4CAbKD2SoBCdMzsbSIvSUUFJuHi5s= +gorm.io/gorm v1.24.6/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= diff --git a/rawsql_driver/migrator.go b/rawsql_driver/migrator.go new file mode 100644 index 00000000..1077b420 --- /dev/null +++ b/rawsql_driver/migrator.go @@ -0,0 +1,58 @@ +package rawsql_driver + +import ( + "strings" + + "gorm.io/gorm" + "gorm.io/gorm/migrator" +) + +type Migrator struct { + migrator.Migrator + Dialector +} + +func (m Migrator) ColumnTypes(value interface{}) ([]gorm.ColumnType, error) { + columnTypes := make([]gorm.ColumnType, 0) + err := m.RunWithValue(value, func(stmt *gorm.Statement) error { + var ( + _, tableName = m.CurrentSchema(stmt, stmt.Table) + ) + table, ok := m.tables[tableName] + if ok && table != nil { + columnTypes = table.ColumnTypes + } + return nil + }) + return columnTypes, err +} + +func (m Migrator) GetIndexes(value interface{}) ([]gorm.Index, error) { + indexes := make([]gorm.Index, 0) + err := m.RunWithValue(value, func(stmt *gorm.Statement) error { + var ( + _, tableName = m.CurrentSchema(stmt, stmt.Table) + ) + table, ok := m.tables[tableName] + if ok && table != nil { + indexes = table.Indexes + } + return nil + }) + return indexes, err +} + +func (m Migrator) GetTables() (tableList []string, err error) { + tableList = make([]string, 0, len(m.tables)) + for tb, _ := range m.tables { + tableList = append(tableList, tb) + } + return tableList, nil +} +func (m Migrator) CurrentSchema(stmt *gorm.Statement, table string) (string, string) { + if tables := strings.Split(table, `.`); len(tables) == 2 { + return tables[0], tables[1] + } + m.DB = m.DB.Table(table) + return "", table +} diff --git a/rawsql_driver/sql.go b/rawsql_driver/sql.go new file mode 100644 index 00000000..d0dddae7 --- /dev/null +++ b/rawsql_driver/sql.go @@ -0,0 +1,140 @@ +package rawsql_driver + +import ( + "io/ioutil" + "os" + "path/filepath" + + _ "github.com/pingcap/tidb/parser/test_driver" + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/migrator" + "gorm.io/gorm/schema" +) + +type Config struct { + DriverName string //mysql + FilePath []string //create table sql file or file path + SQL []string //create table sql content + Parser +} + +type Dialector struct { + *Config + tables map[string]*Table +} + +func New(config Config) gorm.Dialector { + return &Dialector{Config: &config, tables: map[string]*Table{}} +} + +func (dialector Dialector) Name() string { + return dialector.DriverName +} + +func (dialector Dialector) Initialize(db *gorm.DB) error { + if dialector.DriverName == "" { + dialector.DriverName = "mysql" + } + if dialector.SQL == nil { + dialector.SQL = make([]string, 0) + } + if dialector.tables == nil { + dialector.tables = make(map[string]*Table) + } + if dialector.Parser == nil { + dialector.Parser = &defaultParser{} + } + if err := dialector.fileTOSQL(); err != nil { + return err + } + + if err := dialector.sqlTOTable(); err != nil { + return err + } + + return nil +} + +func (dialector Dialector) sqlTOTable() error { + for _, sql := range dialector.SQL { + tables, err := dialector.Parser.Tables(sql) + if err != nil { + return err + } + for _, table := range tables { + dialector.tables[table.Name] = table + } + } + return nil +} + +func (dialector Dialector) fileTOSQL() error { + for _, f := range dialector.FilePath { + if f == "" { + continue + } + v, err := os.Stat(f) + if err != nil { + return err + } + if v.IsDir() { + err = dialector.readFiles(f) + } else { + err = dialector.readFile(f) + } + if err != nil { + return err + } + } + return nil +} + +func (dialector Dialector) readFiles(folder string) (err error) { + files, _ := ioutil.ReadDir(folder) + for _, file := range files { + fn := filepath.Join(folder, file.Name()) + if file.IsDir() { + err = dialector.readFiles(fn) + } else { + err = dialector.readFile(fn) + } + if err != nil { + return err + } + } + return nil +} + +func (dialector Dialector) readFile(fileName string) error { + content, err := ioutil.ReadFile(fileName) + if err != nil { + return err + } + dialector.SQL = append(dialector.SQL, string(content)) + return nil +} + +func (dialector Dialector) Migrator(db *gorm.DB) gorm.Migrator { + return Migrator{ + Migrator: migrator.Migrator{ + Config: migrator.Config{ + DB: db, + Dialector: dialector, + }, + }, + Dialector: dialector, + } +} + +func (dialector Dialector) DataTypeOf(field *schema.Field) string { + return "" +} +func (dialector Dialector) DefaultValueOf(field *schema.Field) clause.Expression { + return clause.Expr{SQL: "DEFAULT"} +} +func (dialector Dialector) BindVarTo(writer clause.Writer, stmt *gorm.Statement, v interface{}) {} +func (dialector Dialector) QuoteTo(writer clause.Writer, str string) {} +func (dialector Dialector) Explain(sql string, vars ...interface{}) string { + return "" +} diff --git a/rawsql_driver/table.go b/rawsql_driver/table.go new file mode 100644 index 00000000..e1a4420e --- /dev/null +++ b/rawsql_driver/table.go @@ -0,0 +1,144 @@ +package rawsql_driver + +import ( + "database/sql" + "reflect" + "time" + + "github.com/pingcap/tidb/parser" + "github.com/pingcap/tidb/parser/ast" + "github.com/pingcap/tidb/parser/mysql" + "github.com/pingcap/tidb/parser/test_driver" + "github.com/pingcap/tidb/parser/types" + "gorm.io/gorm" + "gorm.io/gorm/migrator" +) + +type Table struct { + ColumnTypes []gorm.ColumnType + Indexes []gorm.Index + Name string +} + +type Parser interface { + Tables(createSql string) (tables []*Table, err error) +} + +type defaultParser struct{} + +func (d *defaultParser) Tables(createSql string) (tables []*Table, err error) { + p := parser.New() + stmtNodes, _, err := p.Parse(createSql, "", "") + if err != nil { + return nil, err + } + tables = make([]*Table, 0, len(stmtNodes)) + for _, node := range stmtNodes { + //convert fail will panic + create := node.(*ast.CreateTableStmt) + tables = append(tables, &Table{ + Name: create.Table.Name.String(), + ColumnTypes: d.getColumnTypes(create), + Indexes: d.getIndexes(create), + }) + + } + return tables, nil +} + +func (*defaultParser) getColumnTypes(create *ast.CreateTableStmt) (cols []gorm.ColumnType) { + if create == nil || len(create.Cols) == 0 { + return nil + } + cols = make([]gorm.ColumnType, 0, len(create.Cols)) + for _, col := range create.Cols { + ct := &migrator.ColumnType{ + NameValue: sql.NullString{Valid: true, String: col.Name.String()}, + DataTypeValue: sql.NullString{Valid: true, String: types.TypeToStr(col.Tp.GetType(), col.Tp.GetCharset())}, + ColumnTypeValue: sql.NullString{Valid: true, String: col.Tp.String()}, + PrimaryKeyValue: sql.NullBool{Bool: mysql.HasPriKeyFlag(col.Tp.GetFlag()), Valid: mysql.HasPriKeyFlag(col.Tp.GetFlag())}, + UniqueValue: sql.NullBool{Bool: mysql.HasUniKeyFlag(col.Tp.GetFlag()), Valid: mysql.HasUniKeyFlag(col.Tp.GetFlag())}, + LengthValue: sql.NullInt64{Int64: int64(col.Tp.GetFlen()), Valid: col.Tp.IsVarLengthType()}, + DecimalSizeValue: sql.NullInt64{Int64: int64(col.Tp.GetFlen()), Valid: col.Tp.IsDecimalValid()}, + ScaleValue: sql.NullInt64{Int64: int64(col.Tp.GetDecimal()), Valid: col.Tp.IsDecimalValid()}, + NullableValue: sql.NullBool{Bool: true, Valid: true}, + SQLColumnType: &sql.ColumnType{}, + ScanTypeValue: getType(col.Tp), + } + for _, opt := range col.Options { + if opt.Tp == ast.ColumnOptionNotNull { + ct.NullableValue.Bool = false + continue + } + if opt.Tp == ast.ColumnOptionComment { + ct.CommentValue = sql.NullString{String: opt.Expr.(*test_driver.ValueExpr).Datum.GetString(), Valid: true} + continue + } + if opt.Tp == ast.ColumnOptionAutoIncrement { + ct.AutoIncrementValue = sql.NullBool{Bool: true, Valid: true} + continue + } + if opt.Tp == ast.ColumnOptionDefaultValue { + if v, ok := opt.Expr.(*test_driver.ValueExpr); ok { + ct.CommentValue = sql.NullString{Valid: true, String: v.Datum.GetString()} + continue + } + + if v2, ok := opt.Expr.(*ast.FuncCallExpr); ok { + ct.CommentValue = sql.NullString{Valid: true, String: v2.FnName.String()} + } + } + } + cols = append(cols, ct) + } + return cols +} + +func (d *defaultParser) getIndexes(create *ast.CreateTableStmt) []gorm.Index { + if create == nil || len(create.Constraints) == 0 { + return nil + } + indexs := make([]gorm.Index, 0, len(create.Constraints)) + table := create.Table.Name.String() + for _, cons := range create.Constraints { + idx := &migrator.Index{TableName: table, NameValue: cons.Name, ColumnList: []string{}, + PrimaryKeyValue: sql.NullBool{Bool: ast.ConstraintPrimaryKey == cons.Tp, Valid: ast.ConstraintPrimaryKey == cons.Tp}, + UniqueValue: sql.NullBool{Bool: ast.ConstraintUniq == cons.Tp, Valid: ast.ConstraintUniq == cons.Tp}, + } + for _, col := range cons.Keys { + idx.ColumnList = append(idx.ColumnList, col.Column.Name.String()) + } + indexs = append(indexs, idx) + } + return indexs +} + +var ( + intT = reflect.TypeOf(int32(0)) + longT = reflect.TypeOf(int64(0)) + boolT = reflect.TypeOf(false) + stringT = reflect.TypeOf("") + floatT = reflect.TypeOf(float32(0)) + doubleT = reflect.TypeOf(float64(0)) + timeT = reflect.TypeOf(time.Time{}) +) + +func getType(tp *types.FieldType) reflect.Type { + if tp == nil { + return nil + } + switch tp.GetType() { + case mysql.TypeTiny, mysql.TypeShort, mysql.TypeLong: + return intT + case mysql.TypeFloat: + return floatT + case mysql.TypeDouble: + return doubleT + case mysql.TypeTimestamp, mysql.TypeLonglong, mysql.TypeInt24: + return longT + case mysql.TypeDate, mysql.TypeDatetime, mysql.TypeNewDate: + return timeT + default: + return stringT + } +} diff --git a/rawsql_driver/tests/gen_test.go b/rawsql_driver/tests/gen_test.go new file mode 100644 index 00000000..2ea1ba02 --- /dev/null +++ b/rawsql_driver/tests/gen_test.go @@ -0,0 +1,36 @@ +package tests + +import ( + "fmt" + "testing" + + "gorm.io/gen/rawsql_driver" + "gorm.io/gorm" +) + +func TestSqlGen(t *testing.T) { + //rawsql := []string{ + // "CREATE TABLE `users` (\n `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,\n `created_at` datetime(3) DEFAULT NULL,\n `name` varchar(255) DEFAULT NULL COMMENT 'oneline',\n `address` varchar(255) DEFAULT '',\n `register_time` datetime(3) DEFAULT NULL,\n `alive` tinyint(1) DEFAULT NULL COMMENT 'multiline\\nline1\\nline2',\n `company_id` bigint(20) unsigned DEFAULT '666',\n `private_url` varchar(255) DEFAULT 'https://a.b.c ',\n PRIMARY KEY (`id`),\n KEY `idx_name` (`name`) USING BTREE\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + //} + db, err := gorm.Open(rawsql_driver.New(rawsql_driver.Config{ + //SQL: rawsql, //create table sql + FilePath: []string{ + //"./sql/user.sql", // create table sql file + "./sql", // create table sql file directory + }, + })) + if err != nil { + fmt.Println(err.Error()) + return + } + fmt.Println(db.Migrator().GetTables()) + fmt.Println(db.Migrator().ColumnTypes("users")) + //cfg := gen.Config{OutPath: "query/dal"} + //cfg.FieldWithTypeTag = true + //cfg.FieldWithIndexTag = true + //g := gen.NewGenerator(cfg) + //g.UseDB(db) + //g.ApplyBasic(g.GenerateModel("users"), g.GenerateModelAs("customers", "Customer")) + //g.ApplyBasic(g.GenerateAllTable()...) + //g.Execute() +} diff --git a/rawsql_driver/tests/sql/tables.sql b/rawsql_driver/tests/sql/tables.sql new file mode 100644 index 00000000..47aacd15 --- /dev/null +++ b/rawsql_driver/tests/sql/tables.sql @@ -0,0 +1,56 @@ +CREATE TABLE `banks` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` longtext, + `address` longtext, + `scale` bigint(20) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +CREATE TABLE `credit_cards` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `created_at` datetime(3) DEFAULT NULL, + `updated_at` datetime(3) DEFAULT NULL, + `deleted_at` datetime(3) DEFAULT NULL, + `number` longtext, + `customer_refer` bigint(20) unsigned DEFAULT NULL, + `bank_id` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_credit_cards_deleted_at` (`deleted_at`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + + +CREATE TABLE `customers` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `created_at` datetime(3) DEFAULT NULL, + `updated_at` datetime(3) DEFAULT NULL, + `deleted_at` datetime(3) DEFAULT NULL, + `bank_id` bigint(20) unsigned DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_customers_deleted_at` (`deleted_at`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + + +CREATE TABLE `people` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) DEFAULT NULL, + `alias` varchar(255) DEFAULT NULL, + `age` int(11) unsigned DEFAULT NULL, + `flag` tinyint(1) DEFAULT NULL, + `another_flag` tinyint(4) DEFAULT NULL, + `commit` varchar(255) DEFAULT NULL, + `First` tinyint(1) DEFAULT NULL, + `bit` bit(1) DEFAULT NULL, + `small` smallint(5) unsigned DEFAULT NULL, + `deleted_at` datetime(3) DEFAULT NULL, + `score` decimal(19,0) DEFAULT NULL, + `number` int(11) DEFAULT NULL, + `birth` datetime DEFAULT CURRENT_TIMESTAMP, + `xmlHTTPRequest` varchar(255) DEFAULT ' ', + `jStr` json DEFAULT NULL, + `geo` json DEFAULT NULL, + `mint` mediumint(9) DEFAULT NULL, + `blank` varchar(64) DEFAULT ' ', + `remark` text, + `long_remark` longtext, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/rawsql_driver/tests/sql/user.sql b/rawsql_driver/tests/sql/user.sql new file mode 100644 index 00000000..f1a803eb --- /dev/null +++ b/rawsql_driver/tests/sql/user.sql @@ -0,0 +1,12 @@ +CREATE TABLE `users` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `created_at` datetime(3) DEFAULT NULL, + `name` varchar(255) DEFAULT NULL COMMENT 'oneline', + `address` varchar(255) DEFAULT '', + `register_time` datetime(3) DEFAULT NULL, + `alive` tinyint(1) DEFAULT NULL COMMENT 'multiline\nline1\nline2', + `company_id` bigint(20) unsigned DEFAULT '666', + `private_url` varchar(255) DEFAULT 'https://a.b.c ', + PRIMARY KEY (`id`), + KEY `idx_name` (`name`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;