Browse Source

增加sqlite数据库的初始化

Arthur Liu 3 years ago
parent
commit
a1f2dd702f

+ 7 - 1
server/config.yaml

@@ -42,7 +42,7 @@ casbin:
 system:
   env: 'public'  # Change to "develop" to skip authentication for development mode
   addr: 8888
-  db-type: 'mysql'
+  db-type: 'mysql'     # mysql, sqlite
   oss-type: 'local'    # 控制oss选择走本地还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
   use-multipoint: false
 
@@ -64,6 +64,12 @@ mysql:
   log-mode: false
   log-zap: ""
 
+# sqlite connect configuration
+sqlite:
+  path:''
+  config:''
+  db-name:''
+
 # local configuration
 local:
   path: 'uploads/file'

+ 2 - 1
server/config/config.go

@@ -11,7 +11,8 @@ type Server struct {
 	// auto
 	AutoCode Autocode `mapstructure:"autoCode" json:"autoCode" yaml:"autoCode"`
 	// gorm
-	Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
+	Mysql  Mysql  `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
+	Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"`
 	// oss
 	Local      Local      `mapstructure:"local" json:"local" yaml:"local"`
 	Qiniu      Qiniu      `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"`

+ 6 - 0
server/config/gorm.go

@@ -1,5 +1,11 @@
 package config
 
+type Sqlite struct {
+	Path   string `mapstructure:"path" json:"path" yaml:"path"`         // 数据库路径
+	Config string `mapstructure:"config" json:"config" yaml:"config"`   // 高级配置
+	Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` // 数据库名
+}
+
 type Mysql struct {
 	Path         string `mapstructure:"path" json:"path" yaml:"path"`                             // 服务器地址:端口
 	Config       string `mapstructure:"config" json:"config" yaml:"config"`                       // 高级配置

+ 26 - 0
server/initialize/gorm.go

@@ -1,6 +1,7 @@
 package initialize
 
 import (
+	"fmt"
 	"gin-vue-admin/global"
 	"gin-vue-admin/initialize/internal"
 	"gin-vue-admin/model"
@@ -8,6 +9,7 @@ import (
 
 	"go.uber.org/zap"
 	"gorm.io/driver/mysql"
+	"gorm.io/driver/sqlite"
 	"gorm.io/gorm"
 	"gorm.io/gorm/logger"
 )
@@ -21,6 +23,8 @@ func Gorm() *gorm.DB {
 	switch global.GVA_CONFIG.System.DbType {
 	case "mysql":
 		return GormMysql()
+	case "sqlite":
+		return GormSqlite()
 	default:
 		return GormMysql()
 	}
@@ -91,6 +95,28 @@ func GormMysql() *gorm.DB {
 	}
 }
 
+//@author: arthur-jx
+//@function: GormSqlite
+//@description: 初始化Sqlite数据库
+//@return: *gorm.DB
+
+func GormSqlite() *gorm.DB {
+	m := global.GVA_CONFIG.Sqlite
+	if m.Dbname == "" {
+		return nil
+	}
+	dbpath := m.Dbname
+	if len(m.Path) > 0 {
+		dbpath = fmt.Sprintf("%s/%s", m.Path, m.Dbname)
+	}
+
+	if db, err := gorm.Open(sqlite.Open(dbpath), &gorm.Config{}); err != nil {
+		return nil
+	} else {
+		return db
+	}
+}
+
 //@author: SliverHorn
 //@function: gormConfig
 //@description: 根据配置决定是否开启日志

+ 2 - 0
server/model/request/sys_init.go

@@ -1,6 +1,8 @@
 package request
 
 type InitDB struct {
+	SqlType  string `json:"sqlType"`                     //数据库类型
+	Path     string `json:"path"`                        //sqlite数据库路径
 	Host     string `json:"host"`                        // 服务器地址
 	Port     string `json:"port"`                        // 数据库连接端口
 	UserName string `json:"userName" binding:"required"` // 数据库用户名

+ 101 - 47
server/service/sys_initdb.go

@@ -9,10 +9,12 @@ import (
 	"gin-vue-admin/model/request"
 	"gin-vue-admin/source"
 	"gin-vue-admin/utils"
+	"path/filepath"
+
 	"github.com/spf13/viper"
 	"gorm.io/driver/mysql"
+	"gorm.io/driver/sqlite"
 	"gorm.io/gorm"
-	"path/filepath"
 )
 
 //@author: [songzhibin97](https://github.com/songzhibin97)
@@ -30,6 +32,15 @@ func writeConfig(viper *viper.Viper, mysql config.Mysql) error {
 	return viper.WriteConfig()
 }
 
+func writeSqliteConfig(viper *viper.Viper, sqlite config.Sqlite) error {
+	global.GVA_CONFIG.Sqlite = sqlite
+	cs := utils.StructToMap(global.GVA_CONFIG)
+	for k, v := range cs {
+		viper.Set(k, v)
+	}
+	return viper.WriteConfig()
+}
+
 //@author: [songzhibin97](https://github.com/songzhibin97)
 //@function: createTable
 //@description: 创建数据库(mysql)
@@ -79,55 +90,90 @@ func InitDB(conf request.InitDB) error {
 		Config:   "charset=utf8mb4&parseTime=True&loc=Local",
 	}
 
-	if conf.Host == "" {
-		conf.Host = "127.0.0.1"
+	BaseSqlite := config.Sqlite{
+		Path:   "",
+		Dbname: "",
+		Config: "",
 	}
 
-	if conf.Port == "" {
-		conf.Port = "3306"
-	}
-	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/", conf.UserName, conf.Password, conf.Host, conf.Port)
-	createSql := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;", conf.DBName)
-	if err := createTable(dsn, "mysql", createSql); err != nil {
-		return err
-	}
+	if conf.SqlType == "mysql" {
 
-	MysqlConfig := config.Mysql{
-		Path:     fmt.Sprintf("%s:%s", conf.Host, conf.Port),
-		Dbname:   conf.DBName,
-		Username: conf.UserName,
-		Password: conf.Password,
-		Config:   "charset=utf8mb4&parseTime=True&loc=Local",
-	}
+		if conf.Host == "" {
+			conf.Host = "127.0.0.1"
+		}
 
-	if err := writeConfig(global.GVA_VP, MysqlConfig); err != nil {
-		return err
-	}
-	m := global.GVA_CONFIG.Mysql
-	if m.Dbname == "" {
-		return nil
-	}
+		if conf.Port == "" {
+			conf.Port = "3306"
+		}
+		dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/", conf.UserName, conf.Password, conf.Host, conf.Port)
+		createSql := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;", conf.DBName)
+		if err := createTable(dsn, "mysql", createSql); err != nil {
+			return err
+		}
 
-	linkDns := m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config
-	mysqlConfig := mysql.Config{
-		DSN:                       linkDns, // DSN data source name
-		DefaultStringSize:         191,     // string 类型字段的默认长度
-		DisableDatetimePrecision:  true,    // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
-		DontSupportRenameIndex:    true,    // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
-		DontSupportRenameColumn:   true,    // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
-		SkipInitializeWithVersion: false,   // 根据版本自动配置
-	}
-	if db, err := gorm.Open(mysql.New(mysqlConfig), &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}); err != nil {
-		//global.GVA_LOG.Error("MySQL启动异常!", zap.Any("err", err))
-		//os.Exit(0)
-		//return nil
-		_ = writeConfig(global.GVA_VP, BaseMysql)
-		return nil
-	} else {
-		sqlDB, _ := db.DB()
-		sqlDB.SetMaxIdleConns(m.MaxIdleConns)
-		sqlDB.SetMaxOpenConns(m.MaxOpenConns)
-		global.GVA_DB = db
+		MysqlConfig := config.Mysql{
+			Path:     fmt.Sprintf("%s:%s", conf.Host, conf.Port),
+			Dbname:   conf.DBName,
+			Username: conf.UserName,
+			Password: conf.Password,
+			Config:   "charset=utf8mb4&parseTime=True&loc=Local",
+		}
+
+		if err := writeConfig(global.GVA_VP, MysqlConfig); err != nil {
+			return err
+		}
+		m := global.GVA_CONFIG.Mysql
+		if m.Dbname == "" {
+			return nil
+		}
+
+		linkDns := m.Username + ":" + m.Password + "@tcp(" + m.Path + ")/" + m.Dbname + "?" + m.Config
+		mysqlConfig := mysql.Config{
+			DSN:                       linkDns, // DSN data source name
+			DefaultStringSize:         191,     // string 类型字段的默认长度
+			DisableDatetimePrecision:  true,    // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
+			DontSupportRenameIndex:    true,    // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
+			DontSupportRenameColumn:   true,    // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
+			SkipInitializeWithVersion: false,   // 根据版本自动配置
+		}
+		if db, err := gorm.Open(mysql.New(mysqlConfig), &gorm.Config{DisableForeignKeyConstraintWhenMigrating: true}); err != nil {
+			//global.GVA_LOG.Error("MySQL启动异常!", zap.Any("err", err))
+			//os.Exit(0)
+			//return nil
+			_ = writeConfig(global.GVA_VP, BaseMysql)
+			return nil
+		} else {
+			sqlDB, _ := db.DB()
+			sqlDB.SetMaxIdleConns(m.MaxIdleConns)
+			sqlDB.SetMaxOpenConns(m.MaxOpenConns)
+			global.GVA_DB = db
+		}
+	} else if conf.SqlType == "sqlite" {
+		sqliteConfig := config.Sqlite{
+			Path:   conf.Path,
+			Dbname: conf.DBName,
+			Config: "",
+		}
+
+		if err := writeSqliteConfig(global.GVA_VP, sqliteConfig); err != nil {
+			return err
+		}
+		m := global.GVA_CONFIG.Sqlite
+		if m.Dbname == "" {
+			return nil
+		}
+
+		dbpath := conf.DBName
+		if len(conf.Path) > 0 {
+			dbpath = fmt.Sprintf("%s/%s", conf.Path, conf.DBName)
+		}
+
+		if db, err := gorm.Open(sqlite.Open(dbpath), &gorm.Config{}); err != nil {
+			_ = writeSqliteConfig(global.GVA_VP, BaseSqlite)
+			return nil
+		} else {
+			global.GVA_DB = db
+		}
 	}
 
 	err := global.GVA_DB.AutoMigrate(
@@ -147,7 +193,11 @@ func InitDB(conf request.InitDB) error {
 		model.SysOperationRecord{},
 	)
 	if err != nil {
-		_ = writeConfig(global.GVA_VP, BaseMysql)
+		if conf.SqlType == "sqlite" {
+			_ = writeSqliteConfig(global.GVA_VP, BaseSqlite)
+		} else {
+			_ = writeConfig(global.GVA_VP, BaseMysql)
+		}
 		return err
 	}
 	err = initDB(
@@ -163,7 +213,11 @@ func InitDB(conf request.InitDB) error {
 		source.File,
 		source.BaseMenu)
 	if err != nil {
-		_ = writeConfig(global.GVA_VP, BaseMysql)
+		if conf.SqlType == "sqlite" {
+			_ = writeSqliteConfig(global.GVA_VP, BaseSqlite)
+		} else {
+			_ = writeConfig(global.GVA_VP, BaseMysql)
+		}
 		return err
 	}
 	global.GVA_CONFIG.AutoCode.Root, _ = filepath.Abs("..")

+ 9 - 2
server/source/authority_menu.go

@@ -3,6 +3,7 @@ package source
 import (
 	"gin-vue-admin/global"
 	"gin-vue-admin/model"
+
 	"github.com/gookit/color"
 )
 
@@ -17,8 +18,14 @@ func (a *authorityMenu) Init() error {
 		color.Danger.Println("\n[Mysql] --> authority_menu 视图已存在!")
 		return nil
 	}
-	if err := global.GVA_DB.Exec("CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `authority_menu` AS select `sys_base_menus`.`id` AS `id`,`sys_base_menus`.`created_at` AS `created_at`, `sys_base_menus`.`updated_at` AS `updated_at`, `sys_base_menus`.`deleted_at` AS `deleted_at`, `sys_base_menus`.`menu_level` AS `menu_level`,`sys_base_menus`.`parent_id` AS `parent_id`,`sys_base_menus`.`path` AS `path`,`sys_base_menus`.`name` AS `name`,`sys_base_menus`.`hidden` AS `hidden`,`sys_base_menus`.`component` AS `component`, `sys_base_menus`.`title`  AS `title`,`sys_base_menus`.`icon` AS `icon`,`sys_base_menus`.`sort` AS `sort`,`sys_authority_menus`.`sys_authority_authority_id` AS `authority_id`,`sys_authority_menus`.`sys_base_menu_id` AS `menu_id`,`sys_base_menus`.`keep_alive` AS `keep_alive`,`sys_base_menus`.`default_menu` AS `default_menu` from (`sys_authority_menus` join `sys_base_menus` on ((`sys_authority_menus`.`sys_base_menu_id` = `sys_base_menus`.`id`)))").Error; err != nil {
-		return err
+	if global.GVA_CONFIG.System.DbType == "sqlite" {
+		if err := global.GVA_DB.Exec("CREATE VIEW `authority_menu` AS select `sys_base_menus`.`id` AS `id`,`sys_base_menus`.`created_at` AS `created_at`, `sys_base_menus`.`updated_at` AS `updated_at`, `sys_base_menus`.`deleted_at` AS `deleted_at`, `sys_base_menus`.`menu_level` AS `menu_level`,`sys_base_menus`.`parent_id` AS `parent_id`,`sys_base_menus`.`path` AS `path`,`sys_base_menus`.`name` AS `name`,`sys_base_menus`.`hidden` AS `hidden`,`sys_base_menus`.`component` AS `component`, `sys_base_menus`.`title`  AS `title`,`sys_base_menus`.`icon` AS `icon`,`sys_base_menus`.`sort` AS `sort`,`sys_authority_menus`.`sys_authority_authority_id` AS `authority_id`,`sys_authority_menus`.`sys_base_menu_id` AS `menu_id`,`sys_base_menus`.`keep_alive` AS `keep_alive`,`sys_base_menus`.`default_menu` AS `default_menu` from (`sys_authority_menus` join `sys_base_menus` on ((`sys_authority_menus`.`sys_base_menu_id` = `sys_base_menus`.`id`)))").Error; err != nil {
+			return err
+		}
+	} else {
+		if err := global.GVA_DB.Exec("CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `authority_menu` AS select `sys_base_menus`.`id` AS `id`,`sys_base_menus`.`created_at` AS `created_at`, `sys_base_menus`.`updated_at` AS `updated_at`, `sys_base_menus`.`deleted_at` AS `deleted_at`, `sys_base_menus`.`menu_level` AS `menu_level`,`sys_base_menus`.`parent_id` AS `parent_id`,`sys_base_menus`.`path` AS `path`,`sys_base_menus`.`name` AS `name`,`sys_base_menus`.`hidden` AS `hidden`,`sys_base_menus`.`component` AS `component`, `sys_base_menus`.`title`  AS `title`,`sys_base_menus`.`icon` AS `icon`,`sys_base_menus`.`sort` AS `sort`,`sys_authority_menus`.`sys_authority_authority_id` AS `authority_id`,`sys_authority_menus`.`sys_base_menu_id` AS `menu_id`,`sys_base_menus`.`keep_alive` AS `keep_alive`,`sys_base_menus`.`default_menu` AS `default_menu` from (`sys_authority_menus` join `sys_base_menus` on ((`sys_authority_menus`.`sys_base_menu_id` = `sys_base_menus`.`id`)))").Error; err != nil {
+			return err
+		}
 	}
 	color.Info.Println("\n[Mysql] --> authority_menu 视图创建成功!")
 	return nil

+ 11 - 6
web/src/view/init/init.vue

@@ -5,25 +5,29 @@
     <div class="form-card in-three a-fadeinB">
       <el-form ref="form" :model="form" label-width="100px">
         <el-form-item label="数据库类型">
-          <el-select v-model="form.sqlType" disabled placeholder="请选择">
-            <el-option key="mysql" label="mysql(目前只支持mysql)" value="mysql" />
+          <el-select v-model="form.sqlType" placeholder="请选择">
+            <el-option key="mysql" label="mysql" value="mysql" />
+            <el-option key="sqlite" label="Sqlite" value="sqlite" />
           </el-select>
         </el-form-item>
-        <el-form-item label="host">
+        <el-form-item label="host" v-if="form.sqlType=='mysql'">
           <el-input v-model="form.host" placeholder="请输入数据库链接" />
         </el-form-item>
-        <el-form-item label="port">
+        <el-form-item label="port" v-if="form.sqlType=='mysql'">
           <el-input v-model="form.port" placeholder="请输入数据库端口" />
         </el-form-item>
-        <el-form-item label="userName">
+        <el-form-item label="userName" v-if="form.sqlType=='mysql'">
           <el-input v-model="form.userName" placeholder="请输入数据库用户名" />
         </el-form-item>
-        <el-form-item label="password">
+        <el-form-item label="password" v-if="form.sqlType=='mysql'">
           <el-input
             v-model="form.password"
             placeholder="请输入数据库密码(没有则为空)"
           />
         </el-form-item>
+        <el-form-item label="dbPath" v-if="form.sqlType=='sqlite'">
+          <el-input v-model="form.path" placeholder="请输入数据库路径" />
+        </el-form-item>
         <el-form-item label="dbName">
           <el-input v-model="form.dbName" placeholder="请输入数据库名称" />
         </el-form-item>
@@ -44,6 +48,7 @@ export default {
   data() {
     return {
       form: {
+        path:'',
         sqlType: 'mysql',
         host: '127.0.0.1',
         port: '3306',