package system import ( "context" "errors" "os" "path/filepath" "github.com/glebarez/sqlite" "github.com/go-kratos/kratos/v2/log" "gorm.io/gorm" ) // SqliteConfig SQLite配置 type SqliteConfig struct { Path string Dbname string MaxIdleConns int MaxOpenConns int LogMode string } // Dsn 生成SQLite DSN func (c *SqliteConfig) Dsn() string { return filepath.Join(c.Path, c.Dbname+".db") } // SqliteInitHandler SQLite初始化处理器 type SqliteInitHandler struct { log *log.Helper configWriter func(ctx context.Context, dbType string, config interface{}) error } // NewSqliteInitHandler 创建SQLite初始化处理器 func NewSqliteInitHandler(logger *log.Helper, configWriter func(ctx context.Context, dbType string, config interface{}) error) *SqliteInitHandler { return &SqliteInitHandler{ log: logger, configWriter: configWriter, } } // WriteConfig sqlite回写配置 func (h *SqliteInitHandler) WriteConfig(ctx context.Context) error { c, ok := ctx.Value("config").(SqliteConfig) if !ok { return errors.New("sqlite config invalid") } if h.configWriter != nil { return h.configWriter(ctx, "sqlite", c) } return nil } // EnsureDB 创建数据库并初始化 sqlite func (h *SqliteInitHandler) EnsureDB(ctx context.Context, conf *InitDBRequest) (next context.Context, err error) { if s, ok := ctx.Value("dbtype").(string); !ok || s != "sqlite" { return ctx, ErrDBTypeMismatch } c := h.toSqliteConfig(conf) next = context.WithValue(ctx, "config", c) if c.Dbname == "" { return ctx, nil } // 如果没有数据库名, 则跳出初始化数据 dsn := h.sqliteEmptyDsn(conf) var db *gorm.DB if db, err = gorm.Open(sqlite.Open(dsn), &gorm.Config{ DisableForeignKeyConstraintWhenMigrating: true, }); err != nil { return ctx, err } // 设置AutoCode根目录 autoCodeRoot, _ := filepath.Abs("..") next = context.WithValue(next, "autoCodeRoot", autoCodeRoot) next = context.WithValue(next, "db", db) return next, err } // InitTables 初始化表 func (h *SqliteInitHandler) InitTables(ctx context.Context, inits InitSlice) error { return createTables(ctx, inits) } // InitData 初始化数据 func (h *SqliteInitHandler) InitData(ctx context.Context, inits InitSlice) error { next, cancel := context.WithCancel(ctx) defer cancel() for _, init := range inits { if init.DataInserted(next) { h.log.Infof(InitDataExist, Sqlite, init.InitializerName()) continue } if n, err := init.InitializeData(next); err != nil { h.log.Errorf(InitDataFailed, Sqlite, init.InitializerName(), err) return err } else { next = n h.log.Infof(InitDataSuccess, Sqlite, init.InitializerName()) } } h.log.Infof(InitSuccess, Sqlite) return nil } // sqliteEmptyDsn sqlite 空数据库 建库链接 func (h *SqliteInitHandler) sqliteEmptyDsn(i *InitDBRequest) string { separator := string(os.PathSeparator) return i.DBPath + separator + i.DBName + ".db" } // toSqliteConfig 转换为SQLite配置 func (h *SqliteInitHandler) toSqliteConfig(i *InitDBRequest) SqliteConfig { return SqliteConfig{ Path: i.DBPath, Dbname: i.DBName, MaxIdleConns: 10, MaxOpenConns: 100, LogMode: "error", } }