Initial commit
This commit is contained in:
commit
01cd6d8e01
8
.idea/database.iml
generated
Normal file
8
.idea/database.iml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/database.iml" filepath="$PROJECT_DIR$/.idea/database.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
9
.idea/workspace.xml
generated
Normal file
9
.idea/workspace.xml
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectViewState">
|
||||||
|
<option name="autoscrollFromSource" value="true" />
|
||||||
|
<option name="autoscrollToSource" value="true" />
|
||||||
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
|
<option name="showLibraryContents" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
21
config.go
Normal file
21
config.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
DSN string `yaml:"dsn" envconfig:"DSN"`
|
||||||
|
MaxIdleConns int `yaml:"maxIdleConns" envconfig:"MAX_IDLE_CONNS"`
|
||||||
|
MaxOpenConns int `yaml:"maxOpenConns" envconfig:"MAX_OPEN_CONNS"`
|
||||||
|
ConnMaxLifetime int `yaml:"connMaxLifetime" envconfig:"CONNS_MAX_LIFE_TIME"`
|
||||||
|
AutoMigrate bool `yaml:"autoMigrate" envconfig:"AUTO_MIGRATE"`
|
||||||
|
ShowSql bool `yaml:"showSql" envconfig:"SHOW_SQL"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
DSN: "host=localhost user=gate password=gate dbname=gate port=5432 sslmode=disable",
|
||||||
|
MaxIdleConns: 10,
|
||||||
|
MaxOpenConns: 20,
|
||||||
|
ConnMaxLifetime: 3600,
|
||||||
|
AutoMigrate: false,
|
||||||
|
ShowSql: false,
|
||||||
|
}
|
||||||
|
}
|
27
entities.go
Normal file
27
entities.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/satori/go.uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EntityBase contains common columns for all tables.
|
||||||
|
type EntityBase struct {
|
||||||
|
ID uuid.UUID `gorm:"type:uuid;primary_key;"`
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt *time.Time
|
||||||
|
//DeletedAt *time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeforeCreate will set a UUID rather than numeric ID.
|
||||||
|
func (base *EntityBase) BeforeCreate(tx *gorm.DB) error {
|
||||||
|
base.ID = uuid.NewV4()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (base *EntityBase) BeforeUpdate(tx *gorm.DB) error {
|
||||||
|
now := time.Now()
|
||||||
|
base.UpdatedAt = &now
|
||||||
|
return nil
|
||||||
|
}
|
29
go.mod
Normal file
29
go.mod
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
module netgarden.dev/maf/database
|
||||||
|
|
||||||
|
go 1.24.1
|
||||||
|
|
||||||
|
replace netgarden.dev/maf/maf => ../maf
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/satori/go.uuid v1.2.0
|
||||||
|
gorm.io/driver/postgres v1.5.11
|
||||||
|
gorm.io/gorm v1.25.12
|
||||||
|
netgarden.dev/maf/maf v0.0.0-20250327102624-f25d54ddf786
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/elliotchance/orderedmap v1.6.0 // 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.5.5 // indirect
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||||
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
|
github.com/kelseyhightower/envconfig v1.4.0 // indirect
|
||||||
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||||
|
golang.org/x/crypto v0.17.0 // indirect
|
||||||
|
golang.org/x/sync v0.1.0 // indirect
|
||||||
|
golang.org/x/text v0.14.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
51
go.sum
Normal file
51
go.sum
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
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/elliotchance/orderedmap v1.6.0 h1:xjn+kbbKXeDq6v9RVE+WYwRbYfAZKvlWfcJNxM8pvEw=
|
||||||
|
github.com/elliotchance/orderedmap v1.6.0/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys=
|
||||||
|
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.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||||
|
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||||
|
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/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||||
|
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||||
|
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
|
||||||
|
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||||
|
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||||
|
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
|
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||||
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||||
|
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
|
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||||
|
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||||
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
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=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
|
||||||
|
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||||
|
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||||
|
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
16
interfaces.go
Normal file
16
interfaces.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"netgarden.dev/maf/maf"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Consumer interface {
|
||||||
|
maf.Module
|
||||||
|
SetDB(db *gorm.DB)
|
||||||
|
}
|
||||||
|
|
||||||
|
type EntitiesProvider interface {
|
||||||
|
maf.Module
|
||||||
|
GetDBEntities() []interface{}
|
||||||
|
}
|
162
module.go
Normal file
162
module.go
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/driver/postgres"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
|
"log/slog"
|
||||||
|
"netgarden.dev/maf/maf"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewModule() *Module {
|
||||||
|
return &Module{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Module struct {
|
||||||
|
manager *maf.Manager
|
||||||
|
config *Config
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) GetID() string {
|
||||||
|
return "database"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) GetName() string {
|
||||||
|
return "database"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) SetManager(manager *maf.Manager) {
|
||||||
|
m.manager = manager
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) CreateConfig() interface{} {
|
||||||
|
return NewConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) SetConfig(cfg interface{}) {
|
||||||
|
m.config = cfg.(*Config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) PreInitialize() error {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
m.db, err = m.connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.autoMigrate()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
m.notifyConsumers()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) connect() (*gorm.DB, error) {
|
||||||
|
|
||||||
|
gormPgConfig := postgres.Config{
|
||||||
|
DSN: m.config.DSN,
|
||||||
|
}
|
||||||
|
|
||||||
|
gormConfig := &gorm.Config{}
|
||||||
|
if m.config.ShowSql {
|
||||||
|
gormConfig.Logger = logger.Default.LogMode(logger.Info)
|
||||||
|
}
|
||||||
|
|
||||||
|
var db *gorm.DB
|
||||||
|
var err error
|
||||||
|
|
||||||
|
db, err = gorm.Open(postgres.New(gormPgConfig), gormConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlDB, err := db.DB()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sqlDB.SetMaxIdleConns(m.config.MaxIdleConns)
|
||||||
|
sqlDB.SetMaxOpenConns(m.config.MaxOpenConns)
|
||||||
|
sqlDB.SetConnMaxLifetime(time.Second * time.Duration(m.config.ConnMaxLifetime))
|
||||||
|
|
||||||
|
err = sqlDB.Ping()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return db, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) autoMigrate() error {
|
||||||
|
|
||||||
|
if !m.config.AutoMigrate {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
err = m.autoMigrateTables()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) autoMigrateTables() error {
|
||||||
|
|
||||||
|
slog.Info("Storage tables auto migration starting ...")
|
||||||
|
|
||||||
|
entities := make([]interface{}, 0)
|
||||||
|
for _, module := range m.manager.GetModulesList() {
|
||||||
|
if consumer, ok := module.(EntitiesProvider); ok {
|
||||||
|
consumerEntities := consumer.GetDBEntities()
|
||||||
|
if consumerEntities != nil && len(consumerEntities) > 0 {
|
||||||
|
entities = append(entities, consumerEntities...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
err = m.db.AutoMigrate(entities...)
|
||||||
|
|
||||||
|
slog.Info("Storage tables auto migration finished ...")
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) notifyConsumers() {
|
||||||
|
for _, module := range m.manager.GetModulesList() {
|
||||||
|
if consumer, ok := module.(Consumer); ok {
|
||||||
|
consumer.SetDB(m.db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) Stop() error {
|
||||||
|
|
||||||
|
if m.db == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlDB, err := m.db.DB()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = sqlDB.Close()
|
||||||
|
m.db = nil
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) GetDB() *gorm.DB {
|
||||||
|
return m.db
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user