From 5889d9c391788fea4d8a10c6b7b3a2e42012e86d Mon Sep 17 00:00:00 2001 From: Richard Date: Fri, 15 Dec 2023 15:55:24 +0800 Subject: [PATCH] feat: support PostgreSQL (#118) * feat: support postgres by add driver config --- CHANGELOG.md | 10 ++++++ config/docker/database.yaml | 1 + config/local/database.yaml | 3 +- go.mod | 12 ++++--- go.sum | 19 ++++++++-- main.go | 2 +- pkg/storage/orm/orm.go | 72 +++++++++++++++++++++++++++---------- 7 files changed, 93 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0263a130e9..1964bec258 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ ## Changelog +## v1.8.2 +- feat: support PostgreSQL + +## v1.8.1 +- fix: GitHub workflow badge URL +- chore: improve cmd[run/new] +- chore: improve print log for crontab +- chore: update config in logger.yaml +- chore: upgrade go to v1.19 + ## v1.8.0 - feat(es): add elasticsearch client(v7) - feat: support custom filename when init log diff --git a/config/docker/database.yaml b/config/docker/database.yaml index f13b5688d1..a8ed86f127 100644 --- a/config/docker/database.yaml +++ b/config/docker/database.yaml @@ -1,3 +1,4 @@ +Driver: mysql # 驱动名称,目前支持 mysql,postgres,默认: mysql Name: eagle # 数据库名称 Addr: db:3306 # 如果是 docker,可以替换为 对应的服务名称,eg: db:3306 UserName: root diff --git a/config/local/database.yaml b/config/local/database.yaml index 418733b374..50be4d5d2b 100644 --- a/config/local/database.yaml +++ b/config/local/database.yaml @@ -1,5 +1,6 @@ +Driver: mysql # 驱动名称,目前支持: mysql,postgres,默认: mysql Name: eagle # 数据库名称 -Addr: localhost:3306 # 如果是 docker,可以替换为 对应的服务名称,eg: db:3306 +Addr: localhost:3306 # 如果是 docker,可以替换为 对应的服务名称,eg: db:3306, pg:5432 UserName: root Password: 123456 ShowLog: true # 是否打印所有SQL日志 diff --git a/go.mod b/go.mod index 68deec4ac4..a50742fedb 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/go-playground/locales v0.14.1 github.com/go-playground/universal-translator v0.18.1 github.com/go-playground/validator/v10 v10.11.2 - github.com/go-sql-driver/mysql v1.5.0 + github.com/go-sql-driver/mysql v1.7.0 github.com/golang-jwt/jwt/v4 v4.4.2 github.com/golang/protobuf v1.5.2 github.com/golang/snappy v0.0.3 @@ -70,8 +70,9 @@ require ( golang.org/x/sync v0.1.0 google.golang.org/grpc v1.43.0 google.golang.org/protobuf v1.28.1 - gorm.io/driver/mysql v1.0.4 - gorm.io/gorm v1.20.12 + gorm.io/driver/mysql v1.5.2 + gorm.io/driver/postgres v1.5.4 + gorm.io/gorm v1.25.5 ) require ( @@ -122,8 +123,11 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/serf v0.9.6 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.4.3 // indirect github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.1 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jonboulle/clockwork v0.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect diff --git a/go.sum b/go.sum index d5980c1393..83bda9f482 100644 --- a/go.sum +++ b/go.sum @@ -247,6 +247,8 @@ github.com/go-redis/redis/v8 v8.11.2 h1:WqlSpAwz8mxDSMCvbyz1Mkiqe0LE5OY4j3lgkvu1 github.com/go-redis/redis/v8 v8.11.2/go.mod h1:DLomh7y2e3ggQXQLd1YgmvIfecPJoFl7WU5SOQ/r06M= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= @@ -411,10 +413,17 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= +github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= 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.1 h1:g39TucaRWyV3dwDO++eEc6qf8TVIQ/Da48WmqjZ3i7E= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -1203,11 +1212,17 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.0.4 h1:TATTzt+kR+IV0+h3iUB3dHUe8omCvQ0rOkmfCsUBohk= gorm.io/driver/mysql v1.0.4/go.mod h1:MEgp8tk2n60cSBCq5iTcPDw3ns8Gs+zOva9EUhkknTs= +gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs= +gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8= +gorm.io/driver/postgres v1.5.4 h1:Iyrp9Meh3GmbSuyIAGyjkN+n9K+GHX9b9MqsTL4EJCo= +gorm.io/driver/postgres v1.5.4/go.mod h1:Bgo89+h0CRcdA33Y6frlaHHVuTdOf87pmyzwW9C/BH0= gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM= gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw= gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.12 h1:ebZ5KrSHzet+sqOCVdH9mTjW91L298nX3v5lVxAzSUY= gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= +gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/main.go b/main.go index 6445511769..5882a3ac85 100644 --- a/main.go +++ b/main.go @@ -70,7 +70,7 @@ func main() { // -------------- init resource ------------- logger.Init() // init db - // model.Init() + model.Init() // init redis // nolint: errcheck // redis.Init() diff --git a/pkg/storage/orm/orm.go b/pkg/storage/orm/orm.go index e1aed75b32..5ab72bcf34 100644 --- a/pkg/storage/orm/orm.go +++ b/pkg/storage/orm/orm.go @@ -8,16 +8,24 @@ import ( "time" otelgorm "github.com/1024casts/gorm-opentelemetry" - - // MySQL driver. "gorm.io/driver/mysql" + "gorm.io/driver/postgres" + // GORM MySQL "gorm.io/gorm" "gorm.io/gorm/logger" ) -// Config mysql config +const ( + // DriverMySQL mysql driver + DriverMySQL = "mysql" + // DriverPostgres postgresSQL driver + DriverPostgres = "postgres" +) + +// Config database config type Config struct { + Driver string Name string Addr string UserName string @@ -29,20 +37,28 @@ type Config struct { SlowThreshold time.Duration // 慢查询时长,默认500ms } -// NewMySQL 链接数据库,生成数据库实例 +// NewMySQL connect to database and create a db instance func NewMySQL(c *Config) (db *gorm.DB) { - dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=%t&loc=%s", - c.UserName, - c.Password, - c.Addr, - c.Name, - true, - //"Asia/Shanghai"), - "Local") + var ( + err error + sqlDB *sql.DB + ) + dsn := getDSN(c) + switch c.Driver { + case DriverMySQL: + db, err = gorm.Open(mysql.Open(dsn), gormConfig(c)) + case DriverPostgres: + db, err = gorm.Open(postgres.Open(dsn), gormConfig(c)) + default: + db, err = gorm.Open(mysql.Open(dsn), gormConfig(c)) + } + if err != nil { + log.Panicf("open mysql failed. driver: %s, database name: %s, err: %+v", c.Driver, c.Name, err) + } - sqlDB, err := sql.Open("mysql", dsn) + sqlDB, err = db.DB() if err != nil { - log.Panicf("open mysql failed. database name: %s, err: %+v", c.Name, err) + log.Panicf("database connection failed. database name: %s, err: %+v", c.Name, err) } // set for db connection // 用于设置最大打开的连接数,默认值为0表示不限制.设置最大的连接数,可以避免并发太高导致连接mysql出现too many connections的错误。 @@ -51,10 +67,6 @@ func NewMySQL(c *Config) (db *gorm.DB) { sqlDB.SetMaxIdleConns(c.MaxIdleConn) sqlDB.SetConnMaxLifetime(c.ConnMaxLifeTime) - db, err = gorm.Open(mysql.New(mysql.Config{Conn: sqlDB}), gormConfig(c)) - if err != nil { - log.Panicf("database connection failed. database name: %s, err: %+v", c.Name, err) - } db.Set("gorm:table_options", "CHARSET=utf8mb4") // Initialize otel plugin with options @@ -71,6 +83,30 @@ func NewMySQL(c *Config) (db *gorm.DB) { return db } +// getDSN return dsn string +func getDSN(c *Config) string { + // default mysql + dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=%t&loc=%s", + c.UserName, + c.Password, + c.Addr, + c.Name, + true, + //"Asia/Shanghai"), + "Local") + + if c.Driver == DriverPostgres { + dsn = fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=disable", + c.UserName, + c.Password, + c.Addr, + c.Name, + ) + } + + return dsn +} + // gormConfig 根据配置决定是否开启日志 func gormConfig(c *Config) *gorm.Config { config := &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true} // 禁止外键约束, 生产环境不建议使用外键约束