From cf8080d487de4f94d25e932f9b0642ea062c9f9f Mon Sep 17 00:00:00 2001 From: LyricTian Date: Fri, 1 Sep 2023 11:51:45 +0800 Subject: [PATCH] fix: Fix table name prefix --- cmd/start.go | 15 ++--- internal/bootstrap/bootstrap.go | 5 +- internal/bootstrap/http.go | 6 +- internal/mods/rbac/dal/menu.dal.go | 7 +++ internal/mods/rbac/dal/menu_resource.dal.go | 7 +++ internal/mods/rbac/dal/role.dal.go | 7 +++ internal/mods/rbac/dal/role_menu.dal.go | 7 +++ internal/mods/rbac/dal/user.dal.go | 7 +++ internal/mods/rbac/dal/user_role.dal.go | 11 +++- internal/mods/rbac/main.go | 1 + internal/mods/rbac/schema/menu.go | 4 -- internal/mods/rbac/schema/menu_resource.go | 4 -- internal/mods/rbac/schema/role.go | 4 -- internal/mods/rbac/schema/role_menu.go | 4 -- internal/mods/rbac/schema/user.go | 4 -- internal/mods/rbac/schema/user_role.go | 4 -- main.go | 2 +- pkg/gormx/gorm.go | 61 ++++++++++----------- 18 files changed, 86 insertions(+), 74 deletions(-) diff --git a/cmd/start.go b/cmd/start.go index cf0b6a37..841a1a2a 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -15,7 +15,7 @@ import ( // The function defines a CLI command to start a server with various flags and options, including the // ability to run as a daemon. -func StartCmd(ver string) *cli.Command { +func StartCmd() *cli.Command { return &cli.Command{ Name: "start", Usage: "Start server", @@ -53,11 +53,7 @@ func StartCmd(ver string) *cli.Command { if c.Bool("daemon") { bin, err := filepath.Abs(os.Args[0]) if err != nil { - fmt.Printf("Failed to get absolute path for command: %s \n", err.Error()) - return err - } - - if err := c.Set("daemon", "false"); err != nil { + fmt.Printf("failed to get absolute path for command: %s \n", err.Error()) return err } @@ -65,17 +61,17 @@ func StartCmd(ver string) *cli.Command { args = append(args, "-d", workDir) args = append(args, "-c", configs) args = append(args, "-s", staticDir) - fmt.Printf("execute command: %s %s\n", bin, strings.Join(args, " ")) + fmt.Printf("execute command: %s %s \n", bin, strings.Join(args, " ")) command := exec.Command(bin, args...) err = command.Start() if err != nil { - fmt.Printf("Failed to start daemon thread: %s \n", err.Error()) + fmt.Printf("failed to start daemon thread: %s \n", err.Error()) return err } pid := command.Process.Pid _ = os.WriteFile(fmt.Sprintf("%s.lock", c.App.Name), []byte(fmt.Sprintf("%d", pid)), 0666) - fmt.Printf("Service %s daemon thread started with pid %d \n", config.C.General.AppName, pid) + fmt.Printf("service %s daemon thread started with pid %d \n", config.C.General.AppName, pid) os.Exit(0) } @@ -83,7 +79,6 @@ func StartCmd(ver string) *cli.Command { WorkDir: workDir, Configs: configs, StaticDir: staticDir, - Version: ver, }) if err != nil { panic(err) diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index 0901b4fb..b01cc676 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -20,7 +20,6 @@ type RunConfig struct { WorkDir string // Working directory Configs string // Directory or files (multiple separated by commas) StaticDir string // Static files directory - Version string } // The Run function initializes and starts a service with configuration and logging, and handles @@ -37,7 +36,6 @@ func Run(ctx context.Context, runCfg RunConfig) error { config.MustLoad(workDir, strings.Split(runCfg.Configs, ",")...) config.C.General.WorkDir = workDir config.C.Middleware.Static.Dir = staticDir - config.C.General.Version = runCfg.Version config.C.Print() cleanLoggerFn, err := logging.InitWithConfig(ctx, &config.C.Logger, initLoggerHook) @@ -47,7 +45,7 @@ func Run(ctx context.Context, runCfg RunConfig) error { ctx = logging.NewTag(ctx, logging.TagKeyMain) logging.Context(ctx).Info("starting service ...", - zap.String("version", runCfg.Version), + zap.String("version", config.C.General.Version), zap.Int("pid", os.Getpid()), zap.String("work_dir", workDir), zap.String("config", runCfg.Configs), @@ -74,7 +72,6 @@ func Run(ctx context.Context, runCfg RunConfig) error { } return util.Run(ctx, func(ctx context.Context) (func(), error) { - // Start HTTP server cleanHTTPServerFn, err := startHTTPServer(ctx, injector) if err != nil { return cleanInjectorFn, err diff --git a/internal/bootstrap/http.go b/internal/bootstrap/http.go index c15df940..f8a657a9 100644 --- a/internal/bootstrap/http.go +++ b/internal/bootstrap/http.go @@ -36,13 +36,14 @@ func startHTTPServer(ctx context.Context, injector *wirex.Injector) (func(), err Skip: config.C.Middleware.Recovery.Skip, })) e.NoMethod(func(c *gin.Context) { - util.ResError(c, errors.MethodNotAllowed("", "Method not allowed")) + util.ResError(c, errors.MethodNotAllowed("", "Method Not Allowed")) }) e.NoRoute(func(c *gin.Context) { - util.ResError(c, errors.NotFound("", "Not found")) + util.ResError(c, errors.NotFound("", "Not Found")) }) allowedPrefixes := injector.M.RouterPrefixes() + // Register middlewares if err := useHTTPMiddlewares(ctx, e, injector, allowedPrefixes); err != nil { return nil, err @@ -53,6 +54,7 @@ func startHTTPServer(ctx context.Context, injector *wirex.Injector) (func(), err return nil, err } + // Register swagger if !config.C.General.DisableSwagger { e.StaticFile("/openapi.json", filepath.Join(config.C.General.WorkDir, "openapi.json")) e.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) diff --git a/internal/mods/rbac/dal/menu.dal.go b/internal/mods/rbac/dal/menu.dal.go index 413417a1..b56b4599 100644 --- a/internal/mods/rbac/dal/menu.dal.go +++ b/internal/mods/rbac/dal/menu.dal.go @@ -14,6 +14,13 @@ func GetMenuDB(ctx context.Context, defDB *gorm.DB) *gorm.DB { return util.GetDB(ctx, defDB).Model(new(schema.Menu)) } +// Get menu table name +func GetMenuTableName(defDB *gorm.DB) string { + stat := gorm.Statement{DB: defDB} + stat.Parse(&schema.Menu{}) + return stat.Table +} + // Menu management for RBAC type Menu struct { DB *gorm.DB diff --git a/internal/mods/rbac/dal/menu_resource.dal.go b/internal/mods/rbac/dal/menu_resource.dal.go index 88ced6c3..7eccac0e 100644 --- a/internal/mods/rbac/dal/menu_resource.dal.go +++ b/internal/mods/rbac/dal/menu_resource.dal.go @@ -14,6 +14,13 @@ func GetMenuResourceDB(ctx context.Context, defDB *gorm.DB) *gorm.DB { return util.GetDB(ctx, defDB).Model(new(schema.MenuResource)) } +// Get menu resource table name +func GetMenuResourceTableName(defDB *gorm.DB) string { + stat := gorm.Statement{DB: defDB} + stat.Parse(&schema.MenuResource{}) + return stat.Table +} + // Menu resource management for RBAC type MenuResource struct { DB *gorm.DB diff --git a/internal/mods/rbac/dal/role.dal.go b/internal/mods/rbac/dal/role.dal.go index fcc5470a..1bbcc7fe 100644 --- a/internal/mods/rbac/dal/role.dal.go +++ b/internal/mods/rbac/dal/role.dal.go @@ -14,6 +14,13 @@ func GetRoleDB(ctx context.Context, defDB *gorm.DB) *gorm.DB { return util.GetDB(ctx, defDB).Model(new(schema.Role)) } +// Get role table name +func GetRoleTableName(defDB *gorm.DB) string { + stat := gorm.Statement{DB: defDB} + stat.Parse(&schema.Role{}) + return stat.Table +} + // Role management for RBAC type Role struct { DB *gorm.DB diff --git a/internal/mods/rbac/dal/role_menu.dal.go b/internal/mods/rbac/dal/role_menu.dal.go index 4c338067..bbaa68b3 100644 --- a/internal/mods/rbac/dal/role_menu.dal.go +++ b/internal/mods/rbac/dal/role_menu.dal.go @@ -14,6 +14,13 @@ func GetRoleMenuDB(ctx context.Context, defDB *gorm.DB) *gorm.DB { return util.GetDB(ctx, defDB).Model(new(schema.RoleMenu)) } +// Get role menu table name +func GetRoleMenuTableName(defDB *gorm.DB) string { + stat := gorm.Statement{DB: defDB} + stat.Parse(&schema.RoleMenu{}) + return stat.Table +} + // Role permissions for RBAC type RoleMenu struct { DB *gorm.DB diff --git a/internal/mods/rbac/dal/user.dal.go b/internal/mods/rbac/dal/user.dal.go index eedfcb40..a8175938 100644 --- a/internal/mods/rbac/dal/user.dal.go +++ b/internal/mods/rbac/dal/user.dal.go @@ -14,6 +14,13 @@ func GetUserDB(ctx context.Context, defDB *gorm.DB) *gorm.DB { return util.GetDB(ctx, defDB).Model(new(schema.User)) } +// Get user table name +func GetUserTableName(defDB *gorm.DB) string { + stat := gorm.Statement{DB: defDB} + stat.Parse(&schema.User{}) + return stat.Table +} + // User management for RBAC type User struct { DB *gorm.DB diff --git a/internal/mods/rbac/dal/user_role.dal.go b/internal/mods/rbac/dal/user_role.dal.go index 2149e654..f1f98205 100644 --- a/internal/mods/rbac/dal/user_role.dal.go +++ b/internal/mods/rbac/dal/user_role.dal.go @@ -15,6 +15,13 @@ func GetUserRoleDB(ctx context.Context, defDB *gorm.DB) *gorm.DB { return util.GetDB(ctx, defDB).Model(new(schema.UserRole)) } +// Get user role table name +func GetUserRoleTableName(defDB *gorm.DB) string { + stat := gorm.Statement{DB: defDB} + stat.Parse(&schema.UserRole{}) + return stat.Table +} + // User roles for RBAC type UserRole struct { DB *gorm.DB @@ -27,9 +34,9 @@ func (a *UserRole) Query(ctx context.Context, params schema.UserRoleQueryParam, opt = opts[0] } - db := a.DB.Table(fmt.Sprintf("%s AS a", schema.UserRole{}.TableName())) + db := a.DB.Table(fmt.Sprintf("%s AS a", GetUserRoleTableName(a.DB))) if opt.JoinRole { - db = db.Joins(fmt.Sprintf("left join %s b on a.role_id=b.id", schema.Role{}.TableName())) + db = db.Joins(fmt.Sprintf("left join %s b on a.role_id=b.id", GetRoleTableName(a.DB))) db = db.Select("a.*,b.name as role_name") } diff --git a/internal/mods/rbac/main.go b/internal/mods/rbac/main.go index 69bba6cc..83a3163e 100644 --- a/internal/mods/rbac/main.go +++ b/internal/mods/rbac/main.go @@ -39,6 +39,7 @@ func (a *RBAC) Init(ctx context.Context) error { if err := a.AutoMigrate(ctx); err != nil { return err } + if err := a.Casbinx.Load(ctx); err != nil { return err } diff --git a/internal/mods/rbac/schema/menu.go b/internal/mods/rbac/schema/menu.go index 8e4a2dcf..881541f2 100644 --- a/internal/mods/rbac/schema/menu.go +++ b/internal/mods/rbac/schema/menu.go @@ -38,10 +38,6 @@ type Menu struct { Resources MenuResources `json:"resources" gorm:"-"` // Resources of menu } -func (a Menu) TableName() string { - return "menu" -} - // Defining the query parameters for the `Menu` struct. type MenuQueryParam struct { util.PaginationParam diff --git a/internal/mods/rbac/schema/menu_resource.go b/internal/mods/rbac/schema/menu_resource.go index af45e20a..6708bd39 100644 --- a/internal/mods/rbac/schema/menu_resource.go +++ b/internal/mods/rbac/schema/menu_resource.go @@ -16,10 +16,6 @@ type MenuResource struct { UpdatedAt time.Time `json:"updated_at" gorm:"index;"` // Update time } -func (a MenuResource) TableName() string { - return "menu_resource" -} - // Defining the query parameters for the `MenuResource` struct. type MenuResourceQueryParam struct { util.PaginationParam diff --git a/internal/mods/rbac/schema/role.go b/internal/mods/rbac/schema/role.go index 902f0a9c..e6854976 100644 --- a/internal/mods/rbac/schema/role.go +++ b/internal/mods/rbac/schema/role.go @@ -24,10 +24,6 @@ type Role struct { Menus RoleMenus `json:"menus" gorm:"-"` // Role menu list } -func (a Role) TableName() string { - return "role" -} - // Defining the query parameters for the `Role` struct. type RoleQueryParam struct { util.PaginationParam diff --git a/internal/mods/rbac/schema/role_menu.go b/internal/mods/rbac/schema/role_menu.go index a27cde68..1635c5a7 100644 --- a/internal/mods/rbac/schema/role_menu.go +++ b/internal/mods/rbac/schema/role_menu.go @@ -15,10 +15,6 @@ type RoleMenu struct { UpdatedAt time.Time `json:"updated_at" gorm:"index;"` // Update time } -func (a RoleMenu) TableName() string { - return "role_menu" -} - // Defining the query parameters for the `RoleMenu` struct. type RoleMenuQueryParam struct { util.PaginationParam diff --git a/internal/mods/rbac/schema/user.go b/internal/mods/rbac/schema/user.go index 6ddb4473..2a288cd6 100644 --- a/internal/mods/rbac/schema/user.go +++ b/internal/mods/rbac/schema/user.go @@ -28,10 +28,6 @@ type User struct { Roles UserRoles `json:"roles" gorm:"-"` // Roles of user } -func (a User) TableName() string { - return "user" -} - // Defining the query parameters for the `User` struct. type UserQueryParam struct { util.PaginationParam diff --git a/internal/mods/rbac/schema/user_role.go b/internal/mods/rbac/schema/user_role.go index e5d8fd3e..315e807b 100644 --- a/internal/mods/rbac/schema/user_role.go +++ b/internal/mods/rbac/schema/user_role.go @@ -16,10 +16,6 @@ type UserRole struct { RoleName string `json:"role_name" gorm:"<-:false"` // From Role.Name } -func (a UserRole) TableName() string { - return "user_role" -} - // Defining the query parameters for the `UserRole` struct. type UserRoleQueryParam struct { util.PaginationParam diff --git a/main.go b/main.go index 23c8fc68..2eef9d08 100644 --- a/main.go +++ b/main.go @@ -24,7 +24,7 @@ func main() { app.Version = VERSION app.Usage = "A lightweight, flexible, elegant and full-featured RBAC scaffolding based on GIN + GORM 2.0 + Casbin 2.0 + Wire DI." app.Commands = []*cli.Command{ - cmd.StartCmd(VERSION), + cmd.StartCmd(), cmd.StopCmd(), cmd.VersionCmd(VERSION), } diff --git a/pkg/gormx/gorm.go b/pkg/gormx/gorm.go index c3d01c47..fc7d0ce6 100644 --- a/pkg/gormx/gorm.go +++ b/pkg/gormx/gorm.go @@ -38,46 +38,45 @@ type Config struct { Resolver []ResolverConfig } -func New(c Config) (*gorm.DB, error) { +func New(cfg Config) (*gorm.DB, error) { var dialector gorm.Dialector - switch strings.ToLower(c.DBType) { + switch strings.ToLower(cfg.DBType) { case "mysql": - if err := createDatabaseWithMySQL(c.DSN); err != nil { + if err := createDatabaseWithMySQL(cfg.DSN); err != nil { return nil, err } - dialector = mysql.Open(c.DSN) + dialector = mysql.Open(cfg.DSN) case "postgres": - dialector = postgres.Open(c.DSN) + dialector = postgres.Open(cfg.DSN) case "sqlite3": - _ = os.MkdirAll(filepath.Dir(c.DSN), os.ModePerm) - dialector = sqlite.Open(c.DSN) + _ = os.MkdirAll(filepath.Dir(cfg.DSN), os.ModePerm) + dialector = sqlite.Open(cfg.DSN) default: - return nil, fmt.Errorf("unsupported database type: %s", c.DBType) + return nil, fmt.Errorf("unsupported database type: %s", cfg.DBType) } - gconfig := &gorm.Config{ + ormCfg := &gorm.Config{ NamingStrategy: schema.NamingStrategy{ - TablePrefix: c.TablePrefix, + TablePrefix: cfg.TablePrefix, SingularTable: true, }, Logger: logger.Discard, } - if c.Debug { - gconfig.Logger = logger.Default + if cfg.Debug { + ormCfg.Logger = logger.Default } - db, err := gorm.Open(dialector, gconfig) + db, err := gorm.Open(dialector, ormCfg) if err != nil { return nil, err } - if len(c.Resolver) > 0 { + if len(cfg.Resolver) > 0 { resolver := &dbresolver.DBResolver{} - for _, r := range c.Resolver { - rcfg := dbresolver.Config{} - + for _, r := range cfg.Resolver { + resolverCfg := dbresolver.Config{} var open func(dsn string) gorm.Dialector dbType := strings.ToLower(r.DBType) switch dbType { @@ -93,32 +92,32 @@ func New(c Config) (*gorm.DB, error) { for _, replica := range r.Replicas { if dbType == "sqlite3" { - _ = os.MkdirAll(filepath.Dir(c.DSN), os.ModePerm) + _ = os.MkdirAll(filepath.Dir(cfg.DSN), os.ModePerm) } - rcfg.Replicas = append(rcfg.Replicas, open(replica)) + resolverCfg.Replicas = append(resolverCfg.Replicas, open(replica)) } for _, source := range r.Sources { if dbType == "sqlite3" { - _ = os.MkdirAll(filepath.Dir(c.DSN), os.ModePerm) + _ = os.MkdirAll(filepath.Dir(cfg.DSN), os.ModePerm) } - rcfg.Sources = append(rcfg.Sources, open(source)) + resolverCfg.Sources = append(resolverCfg.Sources, open(source)) } tables := stringSliceToInterfaceSlice(r.Tables) - resolver.Register(rcfg, tables...) + resolver.Register(resolverCfg, tables...) zap.L().Info(fmt.Sprintf("Use resolver, #tables: %v, #replicas: %v, #sources: %v \n", tables, r.Replicas, r.Sources)) } - resolver.SetMaxIdleConns(c.MaxIdleConns). - SetMaxOpenConns(c.MaxOpenConns). - SetConnMaxLifetime(time.Duration(c.MaxLifetime) * time.Second). - SetConnMaxIdleTime(time.Duration(c.MaxIdleTime) * time.Second) + resolver.SetMaxIdleConns(cfg.MaxIdleConns). + SetMaxOpenConns(cfg.MaxOpenConns). + SetConnMaxLifetime(time.Duration(cfg.MaxLifetime) * time.Second). + SetConnMaxIdleTime(time.Duration(cfg.MaxIdleTime) * time.Second) if err := db.Use(resolver); err != nil { return nil, err } } - if c.Debug { + if cfg.Debug { db = db.Debug() } @@ -127,10 +126,10 @@ func New(c Config) (*gorm.DB, error) { return nil, err } - sqlDB.SetMaxIdleConns(c.MaxIdleConns) - sqlDB.SetMaxOpenConns(c.MaxOpenConns) - sqlDB.SetConnMaxLifetime(time.Duration(c.MaxLifetime) * time.Second) - sqlDB.SetConnMaxIdleTime(time.Duration(c.MaxIdleTime) * time.Second) + sqlDB.SetMaxIdleConns(cfg.MaxIdleConns) + sqlDB.SetMaxOpenConns(cfg.MaxOpenConns) + sqlDB.SetConnMaxLifetime(time.Duration(cfg.MaxLifetime) * time.Second) + sqlDB.SetConnMaxIdleTime(time.Duration(cfg.MaxIdleTime) * time.Second) return db, nil }