support database sqlite

This commit is contained in:
zhuyasen 2024-02-13 12:58:45 +08:00
parent a56a20263a
commit 1d398d0659
46 changed files with 589 additions and 258 deletions

3
.github/RELEASE.md vendored
View File

@ -1,8 +1,9 @@
## Change log
- Added generate database initialization code command.
- Added support for postgresql, tidb generation code.
- Added support for postgresql, tidb, sqlite generation code.
- Modify the Sponge UI interface.
- Adjust database configuration in configuration.
- Added generate k8s configmap script command.
- The generated code version matches the local sponge version.
- Fixed redundant createdAt and updatedAt fields in service and handler.

View File

@ -169,7 +169,7 @@ image-build-rpc-test:
.PHONY: patch
# patch some dependent code, such as types.proto, mysql initialization code. e.g. make patch TYPE=types-pb , make patch TYPE=init-mysql, make patch TYPE=init-postgresql
# patch some dependent code, such as types.proto, mysql initialization code. e.g. make patch TYPE=types-pb , make patch TYPE=init-your_db_driver, replace "your_db_driver" with mysql, postgresql, tidb, sqlite
patch:
@bash scripts/patch.sh $(TYPE)

View File

@ -15,7 +15,7 @@
</div>
**Sponge** is a basic development framework that integrates `code auto generation`, `gin and grpc`, sponge has a wealth of generating code commands, generating different functional code can be combined into a complete service (similar to the way that artificially broken sponge cells can automatically recombine into a new sponge). The code is decoupled and modularly designed, it is easy to build a complete project from development to deployment, so that you develop web or microservices project easily, Go can also be "low-code development".
**Sponge** is a basic development framework that integrates `code auto generation`, `Gin and GRPC`, sponge has a rich set of code generation commands, generating different functional code can be combined into a complete service (similar to the way that artificially broken sponge cells can automatically recombine into a new sponge). The code is decoupled and modularly designed, it is easy to build a complete project from development to deployment, just fill in the business logic code on the generated template code, greatly improved development efficiency and reduced development difficulty, the use of Go can also be "low-code development".
<br>

View File

@ -1,7 +1,7 @@
[sponge](https://github.com/zhufuyi/sponge) 是一个集成了 `自动生成代码`、`gin和grpc` 的基础开发框架。sponge拥有丰富的生成代码命令生成不同的功能代码可以组合成完整的服务(类似人为打散的海绵细胞可以自动重组成一个新的海绵)。代码解耦模块化设计,很容易构建出从开发到部署的完整工程项目,让你开发web或微服务项目轻而易举、事半功倍使用go也可以"低代码开发"。
[sponge](https://github.com/zhufuyi/sponge) 是一个集成了 `自动生成代码`、`Gin和GRPC` 的基础开发框架。sponge拥有丰富的生成代码命令生成不同的功能代码可以组合成完整的服务(类似人为打散的海绵细胞可以自动重组成一个新的海绵)。代码解耦模块化设计,很容易构建出从开发到部署的完整工程项目,只需在生成的模板代码上填充具体业务逻辑代码,极大的提高了开发效率和降低了开发难度使用go也可以"低代码开发"。
<br>

View File

@ -27,6 +27,8 @@ const (
DBDriverPostgresql = "postgresql"
// DBDriverTidb tidb driver
DBDriverTidb = "tidb"
// DBDriverSqlite sqlite driver
DBDriverSqlite = "sqlite"
)
var (
@ -88,8 +90,8 @@ var (
appConfigFileMark = "# todo generate http or rpc server configuration here"
appConfigFileMark2 = "# todo generate the database configuration here"
deploymentConfigFile = "kubernetes/serverNameExample-configmap.yml"
deploymentConfigFileMark = "# todo generate the database configuration for deployment here"
//deploymentConfigFile = "kubernetes/serverNameExample-configmap.yml"
//deploymentConfigFileMark = "# todo generate the database configuration for deployment here"
spongeTemplateVersionMark = "// todo generate the local sponge template code version here"
@ -372,27 +374,42 @@ func replacePackage(data []byte, moduleName string, serverName string) []byte {
return data
}
func getDBConfigCode(dbDriver string, forDeployment ...bool) string {
isDeployment := false
if len(forDeployment) > 0 {
isDeployment = forDeployment[0]
}
//func getDBConfigCode(dbDriver string, forDeployment ...bool) string {
// isDeployment := false
// if len(forDeployment) > 0 {
// isDeployment = forDeployment[0]
// }
//
// dbConfigCode := ""
// switch strings.ToLower(dbDriver) {
// case DBDriverMysql, DBDriverTidb:
// if isDeployment {
// dbConfigCode = mysqlConfigForDeploymentCode
// } else {
// dbConfigCode = mysqlConfigCode
// }
//
// case DBDriverPostgresql:
// if isDeployment {
// dbConfigCode = postgresqlConfigForDeploymentCode
// } else {
// dbConfigCode = postgresqlConfigCode
// }
// default:
// panic("getDBConfigCode error, unsupported database driver: " + dbDriver)
// }
// return dbConfigCode
//}
func getDBConfigCode(dbDriver string) string {
dbConfigCode := ""
switch strings.ToLower(dbDriver) {
case DBDriverMysql, DBDriverTidb:
if isDeployment {
dbConfigCode = mysqlConfigForDeploymentCode
} else {
dbConfigCode = mysqlConfigCode
}
dbConfigCode = mysqlConfigCode
case DBDriverPostgresql:
if isDeployment {
dbConfigCode = postgresqlConfigForDeploymentCode
} else {
dbConfigCode = postgresqlConfigCode
}
dbConfigCode = postgresqlConfigCode
case DBDriverSqlite:
dbConfigCode = sqliteConfigCode
default:
panic("getDBConfigCode error, unsupported database driver: " + dbDriver)
}
@ -406,6 +423,8 @@ func getInitDBCode(dbDriver string) string {
initDBCode = modelInitDBFileMysqlCode
case DBDriverPostgresql:
initDBCode = modelInitDBFilePostgresqlCode
case DBDriverSqlite:
initDBCode = modelInitDBFileSqliteCode
default:
panic("getInitDBCode error, unsupported database driver: " + dbDriver)
}
@ -482,3 +501,11 @@ func generateConfigmap(serverName string, outPath string) error {
data := strings.ReplaceAll(string(configmapFileData), configmapFileMark, configFileData)
return os.WriteFile(configmapFile, []byte(data), 0666)
}
func sqliteDSNAdaptation(dbDriver string, dsn string) string {
if dbDriver == DBDriverSqlite && gofile.IsWindows() {
dsn = strings.Replace(dsn, "\\", "\\\\", -1)
dsn = strings.Replace(dsn, "/", "\\\\", -1)
}
return dsn
}

View File

@ -34,16 +34,16 @@ func DaoCommand(parentName string) *cobra.Command {
Examples:
# generate dao code and embed gorm.model struct.
sponge %s dao --module-name=yourModuleName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge %s dao --module-name=yourModuleName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
# generate dao code with multiple table names.
sponge %s dao --module-name=yourModuleName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
sponge %s dao --module-name=yourModuleName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
# generate dao code, structure fields correspond to the column names of the table.
sponge %s dao --module-name=yourModuleName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
sponge %s dao --module-name=yourModuleName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
# generate dao code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
sponge %s dao --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
sponge %s dao --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
`, parentName, parentName, parentName, parentName),
SilenceErrors: true,
SilenceUsage: true,
@ -96,10 +96,10 @@ using help:
},
}
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql")
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
//_ = cmd.MarkFlagRequired("module-name")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database")
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database. Note: if db-driver=sqlite, db-dsn must be a local sqlite db file, e.g. --db-dsn=/tmp/sponge_sqlite.db") //nolint
_ = cmd.MarkFlagRequired("db-dsn")
cmd.Flags().StringVarP(&dbTables, "db-table", "t", "", "table name, multiple names separated by commas")
_ = cmd.MarkFlagRequired("db-table")
@ -187,10 +187,6 @@ func (g *daoGenerator) addFields(r replacer.Replacer) []replacer.Field {
New: g.codes[parser.TableName],
IsCaseSensitive: true,
},
{
Old: "github.com/zhufuyi/sponge/pkg/ggorm",
New: "user/pkg/ggorm",
},
}...)
return fields

View File

@ -37,16 +37,16 @@ func HandlerPbCommand() *cobra.Command {
Examples:
# generate handler and protobuf code and embed gorm.model struct.
sponge web handler-pb --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge web handler-pb --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
# generate handler and protobuf code with multiple table names.
sponge web handler-pb --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
sponge web handler-pb --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
# generate handler and protobuf code, structure fields correspond to the column names of the table.
sponge web handler-pb --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
sponge web handler-pb --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
# generate handler and protobuf code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
sponge web handler-pb --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
sponge web handler-pb --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
`,
SilenceErrors: true,
SilenceUsage: true,
@ -103,12 +103,12 @@ using help:
},
}
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql")
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
//_ = cmd.MarkFlagRequired("module-name")
cmd.Flags().StringVarP(&serverName, "server-name", "s", "", "server name")
//_ = cmd.MarkFlagRequired("server-name")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database")
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database. Note: if db-driver=sqlite, db-dsn must be a local sqlite db file, e.g. --db-dsn=/tmp/sponge_sqlite.db") //nolint
_ = cmd.MarkFlagRequired("db-dsn")
cmd.Flags().StringVarP(&dbTables, "db-table", "t", "", "table name, multiple names separated by commas")
_ = cmd.MarkFlagRequired("db-table")
@ -237,10 +237,6 @@ func (g *handlerPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
New: g.codes[parser.TableName],
IsCaseSensitive: true,
},
{
Old: "github.com/zhufuyi/sponge/pkg/ggorm",
New: "user/pkg/ggorm",
},
}...)
return fields

View File

@ -34,16 +34,16 @@ func HandlerCommand() *cobra.Command {
Examples:
# generate handler code and embed gorm.model struct.
sponge web handler --module-name=yourModuleName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge web handler --module-name=yourModuleName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
# generate handler code with multiple table names.
sponge web handler --module-name=yourModuleName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
sponge web handler --module-name=yourModuleName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
# generate handler code, structure fields correspond to the column names of the table.
sponge web handler --module-name=yourModuleName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
sponge web handler --module-name=yourModuleName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
# generate handler code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
sponge web handler --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
sponge web handler --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
`,
SilenceErrors: true,
SilenceUsage: true,
@ -91,10 +91,10 @@ using help:
},
}
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql")
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
//_ = cmd.MarkFlagRequired("module-name")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database")
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database. Note: if db-driver=sqlite, db-dsn must be a local sqlite db file, e.g. --db-dsn=/tmp/sponge_sqlite.db") //nolint
_ = cmd.MarkFlagRequired("db-dsn")
cmd.Flags().StringVarP(&dbTables, "db-table", "t", "", "table name, multiple names separated by commas")
_ = cmd.MarkFlagRequired("db-table")
@ -187,10 +187,6 @@ func (g *handlerGenerator) addFields(r replacer.Replacer) []replacer.Field {
New: g.codes[parser.TableName],
IsCaseSensitive: true,
},
{
Old: "github.com/zhufuyi/sponge/pkg/ggorm",
New: "user/pkg/ggorm",
},
}...)
return fields

View File

@ -162,7 +162,7 @@ func (g *httpPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
fields = append(fields, deleteFieldsMark(r, gitIgnoreFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, appConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
//fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+g.serverName)...)
fields = append(fields, []replacer.Field{
{ // replace the configuration of the *.yml file
@ -197,10 +197,10 @@ func (g *httpPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
Old: dockerComposeFileMark,
New: dockerComposeFileHTTPCode,
},
{ // replace the contents of the *-configmap.yml file
Old: deploymentConfigFileMark,
New: getDBConfigCode(DBDriverMysql, true),
},
//{ // replace the contents of the *-configmap.yml file
// Old: deploymentConfigFileMark,
// New: getDBConfigCode(DBDriverMysql, true),
//},
{ // replace the contents of the *-deployment.yml file
Old: k8sDeploymentFileMark,
New: k8sDeploymentFileHTTPCode,

View File

@ -38,19 +38,19 @@ func HTTPCommand() *cobra.Command {
Examples:
# generate web service code and embed gorm.model struct.
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
# generate web service code, structure fields correspond to the column names of the table.
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
# generate web service code with multiple table names.
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
# generate web service code and specify the output directory, Note: code generation will be canceled when the latest generated file already exists.
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
# generate web service code and specify the docker image repository address.
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge web http --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
`,
SilenceErrors: true,
SilenceUsage: true,
@ -123,14 +123,14 @@ using help:
},
}
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql")
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
_ = cmd.MarkFlagRequired("module-name")
cmd.Flags().StringVarP(&serverName, "server-name", "s", "", "server name")
_ = cmd.MarkFlagRequired("server-name")
cmd.Flags().StringVarP(&projectName, "project-name", "p", "", "project name")
_ = cmd.MarkFlagRequired("project-name")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database")
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database. Note: if db-driver=sqlite, db-dsn must be a local sqlite db file, e.g. --db-dsn=/tmp/sponge_sqlite.db") //nolint
_ = cmd.MarkFlagRequired("db-dsn")
cmd.Flags().StringVarP(&dbTables, "db-table", "t", "", "table name, multiple names separated by commas")
_ = cmd.MarkFlagRequired("db-table")
@ -180,6 +180,7 @@ func (g *httpGenerator) generateCode() (string, error) {
"doc.go", "cacheNameExample.go", "cacheNameExample_test.go", // internal/cache
"handler/userExample_logic.go", "handler/userExample_logic_test.go", // internal/handler
"scripts/image-rpc-test.sh", "scripts/patch.sh", "scripts/protoc.sh", "scripts/proto-doc.sh", // sponge/scripts
"init_test.go", // model
}
r.SetSubDirsAndFiles(subDirs, subFiles...)
@ -219,7 +220,7 @@ func (g *httpGenerator) addFields(r replacer.Replacer) []replacer.Field {
fields = append(fields, deleteFieldsMark(r, gitIgnoreFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, appConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
//fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+g.serverName)...)
fields = append(fields, []replacer.Field{
{ // replace the configuration of the *.yml file
@ -266,10 +267,10 @@ func (g *httpGenerator) addFields(r replacer.Replacer) []replacer.Field {
Old: dockerComposeFileMark,
New: dockerComposeFileHTTPCode,
},
{ // replace the contents of the *-configmap.yml file
Old: deploymentConfigFileMark,
New: getDBConfigCode(g.dbDriver, true),
},
//{ // replace the contents of the *-configmap.yml file
// Old: deploymentConfigFileMark,
// New: getDBConfigCode(g.dbDriver, true),
//},
{ // replace the contents of the *-deployment.yml file
Old: k8sDeploymentFileMark,
New: k8sDeploymentFileHTTPCode,
@ -356,6 +357,10 @@ func (g *httpGenerator) addFields(r replacer.Replacer) []replacer.Field {
Old: "root:123456@192.168.3.37:5432/account",
New: g.dbDSN,
},
{
Old: "test/sql/sqlite/sponge.db",
New: sqliteDSNAdaptation(g.dbDriver, g.dbDSN),
},
{
Old: "Makefile-for-http",
New: "Makefile",
@ -365,10 +370,6 @@ func (g *httpGenerator) addFields(r replacer.Replacer) []replacer.Field {
New: g.codes[parser.TableName],
IsCaseSensitive: true,
},
{
Old: "github.com/zhufuyi/sponge/pkg/ggorm",
New: "user/pkg/ggorm",
},
}...)
return fields

View File

@ -32,16 +32,16 @@ func ModelCommand(parentName string) *cobra.Command {
Examples:
# generate model code and embed gorm.model struct.
sponge %s model --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge %s model --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
# generate model code with multiple table names.
sponge %s model --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
sponge %s model --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
# generate model code, structure fields correspond to the column names of the table.
sponge %s model --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
sponge %s model --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
# generate model code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
sponge %s model --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
sponge %s model --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
`, parentName, parentName, parentName, parentName),
SilenceErrors: true,
SilenceUsage: true,
@ -78,8 +78,8 @@ using help:
},
}
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database")
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database. Note: if db-driver=sqlite, db-dsn must be a local sqlite db file, e.g. --db-dsn=/tmp/sponge_sqlite.db") //nolint
_ = cmd.MarkFlagRequired("db-dsn")
cmd.Flags().StringVarP(&dbTables, "db-table", "t", "", "table name, multiple names separated by commas")
_ = cmd.MarkFlagRequired("db-table")
@ -136,10 +136,6 @@ func (g *modelGenerator) addFields(r replacer.Replacer) []replacer.Field {
New: g.codes[parser.TableName],
IsCaseSensitive: true,
},
{
Old: "github.com/zhufuyi/sponge/pkg/ggorm",
New: "user/pkg/ggorm",
},
}...)
return fields

View File

@ -33,16 +33,16 @@ func ProtobufCommand() *cobra.Command {
Examples:
# generate protobuf code.
sponge micro protobuf --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge micro protobuf --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
# generate protobuf code with multiple table names.
sponge micro protobuf --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
sponge micro protobuf --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
# generate protobuf code that include router path and swagger info.
sponge micro protobuf --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --web-type=true
sponge micro protobuf --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --web-type=true
# generate protobuf code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
sponge micro protobuf --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
sponge micro protobuf --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
`,
SilenceErrors: true,
SilenceUsage: true,
@ -96,12 +96,12 @@ using help:
},
}
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql")
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
//_ = cmd.MarkFlagRequired("module-name")
cmd.Flags().StringVarP(&serverName, "server-name", "s", "", "server name")
//_ = cmd.MarkFlagRequired("server-name")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database")
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database. Note: if db-driver=sqlite, db-dsn must be a local sqlite db file, e.g. --db-dsn=/tmp/sponge_sqlite.db") //nolint
_ = cmd.MarkFlagRequired("db-dsn")
cmd.Flags().StringVarP(&dbTables, "db-table", "t", "", "table name, multiple names separated by commas")
_ = cmd.MarkFlagRequired("db-table")

View File

@ -161,7 +161,7 @@ func (g *rpcGwPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
fields = append(fields, deleteFieldsMark(r, gitIgnoreFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, appConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
//fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+g.serverName)...)
fields = append(fields, []replacer.Field{
{ // replace the configuration of the *.yml file
@ -200,10 +200,10 @@ func (g *rpcGwPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
Old: dockerComposeFileMark,
New: dockerComposeFileHTTPCode,
},
{ // replace the contents of the *-configmap.yml file
Old: deploymentConfigFileMark,
New: getDBConfigCode(DBDriverMysql, true),
},
//{ // replace the contents of the *-configmap.yml file
// Old: deploymentConfigFileMark,
// New: getDBConfigCode(DBDriverMysql, true),
//},
{ // replace the contents of the *-deployment.yml file
Old: k8sDeploymentFileMark,
New: k8sDeploymentFileHTTPCode,

View File

@ -156,7 +156,7 @@ func (g *rpcPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
fields = append(fields, deleteFieldsMark(r, gitIgnoreFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, appConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
//fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+g.serverName)...)
fields = append(fields, []replacer.Field{
{ // replace the configuration of the *.yml file
@ -191,10 +191,10 @@ func (g *rpcPbGenerator) addFields(r replacer.Replacer) []replacer.Field {
Old: dockerComposeFileMark,
New: dockerComposeFileGrpcCode,
},
{ // replace the contents of the *-configmap.yml file
Old: deploymentConfigFileMark,
New: getDBConfigCode(DBDriverMysql, true),
},
//{ // replace the contents of the *-configmap.yml file
// Old: deploymentConfigFileMark,
// New: getDBConfigCode(DBDriverMysql, true),
//},
{ // replace the contents of the *-deployment.yml file
Old: k8sDeploymentFileMark,
New: k8sDeploymentFileGrpcCode,

View File

@ -39,19 +39,19 @@ func RPCCommand() *cobra.Command {
Examples:
# generate grpc service code and embed gorm.model struct.
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
# generate grpc service code, structure fields correspond to the column names of the table.
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
# generate grpc service code with multiple table names.
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
# generate grpc service code and specify the output directory, Note: code generation will be canceled when the latest generated file already exists.
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
# generate grpc service code and specify the docker image repository address.
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge micro rpc --module-name=yourModuleName --server-name=yourServerName --project-name=yourProjectName --repo-addr=192.168.3.37:9443/user-name --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
`,
SilenceErrors: true,
SilenceUsage: true,
@ -127,14 +127,14 @@ using help:
},
}
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql")
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
_ = cmd.MarkFlagRequired("module-name")
cmd.Flags().StringVarP(&serverName, "server-name", "s", "", "server name")
_ = cmd.MarkFlagRequired("server-name")
cmd.Flags().StringVarP(&projectName, "project-name", "p", "", "project name")
_ = cmd.MarkFlagRequired("project-name")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database")
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database. Note: if db-driver=sqlite, db-dsn must be a local sqlite db file, e.g. --db-dsn=/tmp/sponge_sqlite.db") //nolint
_ = cmd.MarkFlagRequired("db-dsn")
cmd.Flags().StringVarP(&dbTables, "db-table", "t", "", "table name, multiple names separated by commas")
_ = cmd.MarkFlagRequired("db-table")
@ -185,6 +185,7 @@ func (g *rpcGenerator) generateCode() (string, error) {
"userExample_logic.go", "userExample_logic_test.go", "service/userExample_test.go", // internal/service
"scripts/swag-docs.sh", // sponge/scripts
"doc.go", "cacheNameExample.go", "cacheNameExample_test.go", // internal/cache
"init_test.go", // model
}
r.SetSubDirsAndFiles(subDirs, subFiles...)
@ -225,7 +226,7 @@ func (g *rpcGenerator) addFields(r replacer.Replacer) []replacer.Field {
fields = append(fields, deleteFieldsMark(r, gitIgnoreFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, protoShellFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteAllFieldsMark(r, appConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
//fields = append(fields, deleteFieldsMark(r, deploymentConfigFile, wellStartMark, wellEndMark)...)
fields = append(fields, replaceFileContentMark(r, readmeFile, "## "+g.serverName)...)
fields = append(fields, []replacer.Field{
{ // replace the configuration of the *.yml file
@ -288,10 +289,10 @@ func (g *rpcGenerator) addFields(r replacer.Replacer) []replacer.Field {
Old: dockerComposeFileMark,
New: dockerComposeFileGrpcCode,
},
{ // replace the contents of the *-configmap.yml file
Old: deploymentConfigFileMark,
New: getDBConfigCode(g.dbDriver, true),
},
//{ // replace the contents of the *-configmap.yml file
// Old: deploymentConfigFileMark,
// New: getDBConfigCode(g.dbDriver, true),
//},
{ // replace the contents of the *-deployment.yml file
Old: k8sDeploymentFileMark,
New: k8sDeploymentFileGrpcCode,
@ -379,15 +380,15 @@ func (g *rpcGenerator) addFields(r replacer.Replacer) []replacer.Field {
Old: "root:123456@192.168.3.37:5432/account",
New: g.dbDSN,
},
{
Old: "test/sql/sqlite/sponge.db",
New: sqliteDSNAdaptation(g.dbDriver, g.dbDSN),
},
{
Old: "UserExample",
New: g.codes[parser.TableName],
IsCaseSensitive: true,
},
{
Old: "github.com/zhufuyi/sponge/pkg/ggorm",
New: "user/pkg/ggorm",
},
}...)
return fields

View File

@ -36,16 +36,16 @@ func ServiceCommand() *cobra.Command {
Examples:
# generate service code and embed gorm.model struct.
sponge micro service --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
sponge micro service --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user
# generate service code with multiple table names.
sponge micro service --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
sponge micro service --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=t1,t2
# generate service code, structure fields correspond to the column names of the table.
sponge micro service --module-name=yourModuleName --server-name=yourServerName --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
sponge micro service --module-name=yourModuleName --server-name=yourServerName --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --embed=false
# generate service code and specify the server directory, Note: code generation will be canceled when the latest generated file already exists.
sponge micro service --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
sponge micro service --db-driver=mysql --db-dsn=root:123456@(192.168.3.37:3306)/test --db-table=user --out=./yourServerDir
`,
SilenceErrors: true,
SilenceUsage: true,
@ -102,12 +102,12 @@ using help:
},
}
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql")
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the go.mod file")
//_ = cmd.MarkFlagRequired("module-name")
cmd.Flags().StringVarP(&serverName, "server-name", "s", "", "server name")
//_ = cmd.MarkFlagRequired("server-name")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database")
cmd.Flags().StringVarP(&sqlArgs.DBDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&sqlArgs.DBDsn, "db-dsn", "d", "", "database content address, e.g. user:password@(host:port)/database. Note: if db-driver=sqlite, db-dsn must be a local sqlite db file, e.g. --db-dsn=/tmp/sponge_sqlite.db") //nolint
_ = cmd.MarkFlagRequired("db-dsn")
cmd.Flags().StringVarP(&dbTables, "db-table", "t", "", "table name, multiple names separated by commas")
_ = cmd.MarkFlagRequired("db-table")
@ -233,10 +233,6 @@ func (g *serviceGenerator) addFields(r replacer.Replacer) []replacer.Field {
New: g.codes[parser.TableName],
IsCaseSensitive: true,
},
{
Old: "github.com/zhufuyi/sponge/pkg/ggorm",
New: "user/pkg/ggorm",
},
}...)
return fields

View File

@ -421,7 +421,7 @@ grpcClient:
mysqlConfigCode = `# database setting
database:
driver: "mysql" # database driver, currently support mysql, postgres, tidb
driver: "mysql" # database driver, currently support mysql, postgres, tidb, sqlite
# mysql settings
mysql:
# dsn format, <user>:<pass>@(127.0.0.1:3306)/<db>?[k=v& ......]
@ -436,26 +436,26 @@ database:
#mastersDsn: # sets masters mysql dsn, array type, non-required field, if there is only one master, there is no need to set the mastersDsn field, the default dsn field is mysql master.
# - "your master dsn`
mysqlConfigForDeploymentCode = ` # database setting
database:
driver: "mysql" # database driver, currently support mysql, postgres, tidb
# mysql settings
mysql:
# dsn format, <user>:<pass>@(127.0.0.1:3306)/<db>?[k=v& ......]
dsn: "root:123456@(192.168.3.37:3306)/account?parseTime=true&loc=Local&charset=utf8,utf8mb4"
enableLog: true # whether to turn on printing of all logs
slowThreshold: 0 # if greater than 0, only print logs with a time greater than the threshold, with a higher priority than enableLog, in (ms)
maxIdleConns: 3 # set the maximum number of connections in the idle connection pool
maxOpenConns: 100 # set the maximum number of open database connections
connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes
#slavesDsn: # sets slaves mysql dsn, array type
# - "your slave dsn 1"
# - "your slave dsn 2"
#mastersDsn: # sets masters mysql dsn, array type, non-required field, if there is only one master, the default dsn field is mysql master.
# - "your master dsn"`
//mysqlConfigForDeploymentCode = ` # database setting
//database:
// driver: "mysql" # database driver, currently support mysql, postgres, tidb, sqlite
// # mysql settings
// mysql:
// # dsn format, <user>:<pass>@(127.0.0.1:3306)/<db>?[k=v& ......]
// dsn: "root:123456@(192.168.3.37:3306)/account?parseTime=true&loc=Local&charset=utf8,utf8mb4"
// enableLog: true # whether to turn on printing of all logs
// slowThreshold: 0 # if greater than 0, only print logs with a time greater than the threshold, with a higher priority than enableLog, in (ms)
// maxIdleConns: 3 # set the maximum number of connections in the idle connection pool
// maxOpenConns: 100 # set the maximum number of open database connections
// connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes
// #slavesDsn: # sets slaves mysql dsn, array type
// # - "your slave dsn 1"
// # - "your slave dsn 2"
// #mastersDsn: # sets masters mysql dsn, array type, non-required field, if there is only one master, the default dsn field is mysql master.
// # - "your master dsn"`
postgresqlConfigCode = `database:
driver: "postgresql" # database driver, currently support mysql, postgres, tidb
driver: "postgresql" # database driver, currently support mysql, postgres, tidb, sqlite
# postgresql settings
postgresql:
# dsn format, <user>:<pass>@127.0.0.1:5432/<db>?[k=v& ......]
@ -465,44 +465,38 @@ database:
maxOpenConns: 100 # set the maximum number of open database connections
connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes`
postgresqlConfigForDeploymentCode = ` # database setting
database:
driver: "postgresql" # database driver, currently support mysql, postgres, tidb
# postgresql settings
postgresql:
# dsn format, <user>:<pass>@127.0.0.1:5432/<db>?[k=v& ......]
dsn: "root:123456@192.168.3.37:5432/account?sslmode=disable"
enableLog: true # whether to turn on printing of all logs
maxIdleConns: 10 # set the maximum number of connections in the idle connection pool
maxOpenConns: 100 # set the maximum number of open database connections
connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes`
sqliteConfigCode = `database:
driver: "sqlite" # database driver, currently support mysql, postgres, tidb, sqlite
# sqlite settings
sqlite:
dbFile: "test/sql/sqlite/sponge.db"
enableLog: true # whether to turn on printing of all logs
maxIdleConns: 10 # set the maximum number of connections in the idle connection pool
maxOpenConns: 100 # set the maximum number of open database connections
connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes`
//postgresqlConfigForDeploymentCode = ` # database setting
//database:
// driver: "postgresql" # database driver, currently support mysql, postgres, tidb, sqlite
// # postgresql settings
// postgresql:
// # dsn format, <user>:<pass>@127.0.0.1:5432/<db>?[k=v& ......]
// dsn: "root:123456@192.168.3.37:5432/account?sslmode=disable"
// enableLog: true # whether to turn on printing of all logs
// maxIdleConns: 10 # set the maximum number of connections in the idle connection pool
// maxOpenConns: 100 # set the maximum number of open database connections
// connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes`
modelInitDBFileMysqlCode = `// InitDB connect database
func InitDB() {
switch strings.ToLower(config.Get().Database.Driver) {
case "mysql", "tidb":
case ggorm.DBDriverMysql, ggorm.DBDriverTidb:
InitMysql()
default:
panic("unsupported database driver: " + config.Get().Database.Driver)
}
}
// GetDB get db
func GetDB() *gorm.DB {
if db == nil {
once1.Do(func() {
switch strings.ToLower(config.Get().Database.Driver) {
case "mysql", "tidb":
InitMysql()
default:
panic("unsupported database driver: " + config.Get().Database.Driver)
}
})
}
return db
}
// InitMysql connect mysql
func InitMysql() {
opts := []ggorm.Option{
@ -542,29 +536,13 @@ func InitMysql() {
modelInitDBFilePostgresqlCode = `// InitDB connect database
func InitDB() {
switch strings.ToLower(config.Get().Database.Driver) {
case "postgresql":
case ggorm.DBDriverPostgresql:
InitPostgresql()
default:
panic("unsupported database driver: " + config.Get().Database.Driver)
}
}
// GetDB get db
func GetDB() *gorm.DB {
if db == nil {
once1.Do(func() {
switch strings.ToLower(config.Get().Database.Driver) {
case "postgresql":
InitPostgresql()
default:
panic("unsupported database driver: " + config.Get().Database.Driver)
}
})
}
return db
}
// InitPostgresql connect postgresql
func InitPostgresql() {
opts := []ggorm.Option{
@ -594,6 +572,41 @@ func InitPostgresql() {
}
}`
modelInitDBFileSqliteCode = `// InitDB connect database
func InitDB() {
switch strings.ToLower(config.Get().Database.Driver) {
case ggorm.DBDriverSqlite:
InitSqlite()
default:
panic("unsupported database driver: " + config.Get().Database.Driver)
}
}
// InitSqlite connect sqlite
func InitSqlite() {
opts := []ggorm.Option{
ggorm.WithMaxIdleConns(config.Get().Database.Sqlite.MaxIdleConns),
ggorm.WithMaxOpenConns(config.Get().Database.Sqlite.MaxOpenConns),
ggorm.WithConnMaxLifetime(time.Duration(config.Get().Database.Sqlite.ConnMaxLifetime) * time.Minute),
}
if config.Get().Database.Sqlite.EnableLog {
opts = append(opts,
ggorm.WithLogging(logger.Get()),
ggorm.WithLogRequestIDKey("request_id"),
)
}
if config.Get().App.EnableTrace {
opts = append(opts, ggorm.WithEnableTrace())
}
var err error
db, err = ggorm.InitSqlite(config.Get().Database.Sqlite.DBFile, opts...)
if err != nil {
panic("ggorm.InitSqlite error: " + err.Error())
}
}`
embedTimeCode = ` value.CreatedAt = record.CreatedAt.Unix()
value.UpdatedAt = record.UpdatedAt.Unix()`
)

View File

@ -82,7 +82,7 @@ using help:
},
}
cmd.Flags().StringVarP(&dbDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb")
cmd.Flags().StringVarP(&dbDriver, "db-driver", "k", "mysql", "database driver, support mysql, postgresql, tidb, sqlite")
cmd.Flags().StringVarP(&moduleName, "module-name", "m", "", "module-name is the name of the module in the 'go.mod' file")
cmd.Flags().StringVarP(&outPath, "out", "o", "", "output directory, default is ./mysql-init_<time>, "+
"if you specify the directory where the web or microservice generated by sponge, the module-name flag can be ignored")

View File

@ -29,12 +29,6 @@ var (
saveDir = fmt.Sprintf("%s/.%s", getSpongeDir(), recordDirName)
)
const (
dbDriverMysql = "mysql"
dbDriverPostgresql = "postgresql"
dbDriverTidb = "tidb"
)
type dbInfoForm struct {
Dsn string `json:"dsn" binding:"required"`
DbDriver string `json:"dbDriver"`
@ -48,9 +42,10 @@ type kv struct {
// ListDbDrivers list db drivers
func ListDbDrivers(c *gin.Context) {
dbDrivers := []string{
dbDriverMysql,
dbDriverPostgresql,
dbDriverTidb,
ggorm.DBDriverMysql,
ggorm.DBDriverPostgresql,
ggorm.DBDriverTidb,
ggorm.DBDriverSqlite,
}
data := []kv{}
@ -75,10 +70,12 @@ func ListTables(c *gin.Context) {
var tables []string
switch strings.ToLower(form.DbDriver) {
case dbDriverMysql, dbDriverTidb:
case ggorm.DBDriverMysql, ggorm.DBDriverTidb:
tables, err = getMysqlTables(form.Dsn)
case dbDriverPostgresql:
case ggorm.DBDriverPostgresql:
tables, err = getPostgresqlTables(form.Dsn)
case ggorm.DBDriverSqlite:
tables, err = getSqliteTables(form.Dsn)
case "":
response.Error(c, ecode.InternalServerError.WithDetails("database type is empty"))
return
@ -379,7 +376,7 @@ func getMysqlTables(dsn string) ([]string, error) {
if err != nil {
return nil, err
}
defer ggorm.CloseDB(db) //nolint
defer ggorm.CloseSQLDB(db)
var tables []string
err = db.Raw("show tables").Scan(&tables).Error
@ -396,7 +393,7 @@ func getPostgresqlTables(dsn string) ([]string, error) {
if err != nil {
return nil, err
}
defer ggorm.CloseDB(db) //nolint
defer ggorm.CloseSQLDB(db)
var tables []string
err = db.Raw("SELECT table_name FROM information_schema.tables WHERE table_schema = ?", "public").Scan(&tables).Error
@ -406,3 +403,31 @@ func getPostgresqlTables(dsn string) ([]string, error) {
return tables, nil
}
func getSqliteTables(dbFile string) ([]string, error) {
if !gofile.IsExists(dbFile) {
return nil, fmt.Errorf("sqlite db file %s not found in local host", dbFile)
}
db, err := ggorm.InitSqlite(dbFile)
if err != nil {
return nil, err
}
defer ggorm.CloseSQLDB(db)
var tables []string
err = db.Raw("select name from sqlite_master where type = ?", "table").Scan(&tables).Error
if err != nil {
return nil, err
}
filteredTables := []string{}
for _, table := range tables {
if table == "sqlite_sequence" {
continue
}
filteredTables = append(filteredTables, table)
}
return filteredTables, nil
}

View File

@ -1,2 +1,2 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>sponge generate code</title><link rel=icon type=image/png sizes=32x32 href="/static/favicon.png?v=1.0"><script type=text/javascript src=/static/appConfig.js async></script><link href=/static/css/app.f965da2e3508ddc9ca932590fe4d1582.css rel=stylesheet></head><body style="margin: 0px; padding: 0px;"><style>.el-tooltip__popper {box-shadow: 3px 3px 10px 5px #d3d3d6;border-width: 0px !important;}
.el-tooltip__popper[x-placement^="top"] .popper__arrow:after {border-top-color: #dcdfe6 !important;}</style><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.d8cdb3748af43d2ae51a.js></script><script type=text/javascript src=/static/js/app.050e4b824a5634db92e7.js></script></body></html>
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>sponge generate code</title><link rel=icon type=image/png sizes=32x32 href="/static/favicon.png?v=1.0"><script type=text/javascript src=/static/appConfig.js async></script><link href=/static/css/app.0770f594d25eafd5003889c2b2fbef63.css rel=stylesheet></head><body style="margin: 0px; padding: 0px;"><style>.el-tooltip__popper {box-shadow: 3px 3px 10px 5px #d3d3d6;border-width: 0px !important;}
.el-tooltip__popper[x-placement^="top"] .popper__arrow:after {border-top-color: #dcdfe6 !important;}</style><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.d8cdb3748af43d2ae51a.js></script><script type=text/javascript src=/static/js/app.b1f9861bc47fae3f6319.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"sources":["webpack:///webpack/bootstrap 3ba9677dd8fa41dfdceb"],"names":["parentJsonpFunction","window","chunkIds","moreModules","executeModules","moduleId","chunkId","result","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","shift","__webpack_require__","s","installedModules","2","exports","module","l","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","p","oe","err","console","error"],"mappings":"aACA,IAAAA,EAAAC,OAAA,aACAA,OAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,IAAAC,EAAAC,EAAAC,EAAAC,EAAA,EAAAC,KACQD,EAAAN,EAAAQ,OAAoBF,IAC5BF,EAAAJ,EAAAM,GACAG,EAAAL,IACAG,EAAAG,KAAAD,EAAAL,GAAA,IAEAK,EAAAL,GAAA,EAEA,IAAAD,KAAAF,EACAU,OAAAC,UAAAC,eAAAC,KAAAb,EAAAE,KACAY,EAAAZ,GAAAF,EAAAE,IAIA,IADAL,KAAAE,EAAAC,EAAAC,GACAK,EAAAC,QACAD,EAAAS,OAAAT,GAEA,GAAAL,EACA,IAAAI,EAAA,EAAYA,EAAAJ,EAAAM,OAA2BF,IACvCD,EAAAY,IAAAC,EAAAhB,EAAAI,IAGA,OAAAD,GAIA,IAAAc,KAGAV,GACAW,EAAA,GAIA,SAAAH,EAAAd,GAGA,GAAAgB,EAAAhB,GACA,OAAAgB,EAAAhB,GAAAkB,QAGA,IAAAC,EAAAH,EAAAhB,IACAG,EAAAH,EACAoB,GAAA,EACAF,YAUA,OANAN,EAAAZ,GAAAW,KAAAQ,EAAAD,QAAAC,IAAAD,QAAAJ,GAGAK,EAAAC,GAAA,EAGAD,EAAAD,QAKAJ,EAAAO,EAAAT,EAGAE,EAAAQ,EAAAN,EAGAF,EAAAS,EAAA,SAAAL,EAAAM,EAAAC,GACAX,EAAAY,EAAAR,EAAAM,IACAhB,OAAAmB,eAAAT,EAAAM,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAX,EAAAiB,EAAA,SAAAZ,GACA,IAAAM,EAAAN,KAAAa,WACA,WAA2B,OAAAb,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAL,EAAAS,EAAAE,EAAA,IAAAA,GACAA,GAIAX,EAAAY,EAAA,SAAAO,EAAAC,GAAsD,OAAA1B,OAAAC,UAAAC,eAAAC,KAAAsB,EAAAC,IAGtDpB,EAAAqB,EAAA,IAGArB,EAAAsB,GAAA,SAAAC,GAA8D,MAApBC,QAAAC,MAAAF,GAAoBA","file":"static/js/manifest.2ae2e69a05c33dfc65f8.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 3ba9677dd8fa41dfdceb"],"sourceRoot":""}
{"version":3,"sources":["webpack:///webpack/bootstrap 99587f43dd0528e70169"],"names":["parentJsonpFunction","window","chunkIds","moreModules","executeModules","moduleId","chunkId","result","i","resolves","length","installedChunks","push","Object","prototype","hasOwnProperty","call","modules","shift","__webpack_require__","s","installedModules","2","exports","module","l","m","c","d","name","getter","o","defineProperty","configurable","enumerable","get","n","__esModule","object","property","p","oe","err","console","error"],"mappings":"aACA,IAAAA,EAAAC,OAAA,aACAA,OAAA,sBAAAC,EAAAC,EAAAC,GAIA,IADA,IAAAC,EAAAC,EAAAC,EAAAC,EAAA,EAAAC,KACQD,EAAAN,EAAAQ,OAAoBF,IAC5BF,EAAAJ,EAAAM,GACAG,EAAAL,IACAG,EAAAG,KAAAD,EAAAL,GAAA,IAEAK,EAAAL,GAAA,EAEA,IAAAD,KAAAF,EACAU,OAAAC,UAAAC,eAAAC,KAAAb,EAAAE,KACAY,EAAAZ,GAAAF,EAAAE,IAIA,IADAL,KAAAE,EAAAC,EAAAC,GACAK,EAAAC,QACAD,EAAAS,OAAAT,GAEA,GAAAL,EACA,IAAAI,EAAA,EAAYA,EAAAJ,EAAAM,OAA2BF,IACvCD,EAAAY,IAAAC,EAAAhB,EAAAI,IAGA,OAAAD,GAIA,IAAAc,KAGAV,GACAW,EAAA,GAIA,SAAAH,EAAAd,GAGA,GAAAgB,EAAAhB,GACA,OAAAgB,EAAAhB,GAAAkB,QAGA,IAAAC,EAAAH,EAAAhB,IACAG,EAAAH,EACAoB,GAAA,EACAF,YAUA,OANAN,EAAAZ,GAAAW,KAAAQ,EAAAD,QAAAC,IAAAD,QAAAJ,GAGAK,EAAAC,GAAA,EAGAD,EAAAD,QAKAJ,EAAAO,EAAAT,EAGAE,EAAAQ,EAAAN,EAGAF,EAAAS,EAAA,SAAAL,EAAAM,EAAAC,GACAX,EAAAY,EAAAR,EAAAM,IACAhB,OAAAmB,eAAAT,EAAAM,GACAI,cAAA,EACAC,YAAA,EACAC,IAAAL,KAMAX,EAAAiB,EAAA,SAAAZ,GACA,IAAAM,EAAAN,KAAAa,WACA,WAA2B,OAAAb,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAL,EAAAS,EAAAE,EAAA,IAAAA,GACAA,GAIAX,EAAAY,EAAA,SAAAO,EAAAC,GAAsD,OAAA1B,OAAAC,UAAAC,eAAAC,KAAAsB,EAAAC,IAGtDpB,EAAAqB,EAAA,IAGArB,EAAAsB,GAAA,SAAAC,GAA8D,MAApBC,QAAAC,MAAAF,GAAoBA","file":"static/js/manifest.2ae2e69a05c33dfc65f8.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t2: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 99587f43dd0528e70169"],"sourceRoot":""}

View File

@ -85,7 +85,7 @@ logger:
# delete the templates code start
# database setting
database:
driver: "mysql" # database driver, currently support mysql, postgres, tidb
driver: "mysql" # database driver, currently support mysql, postgres, tidb, sqlite
# mysql settings
mysql:
# dsn format, <user>:<pass>@(127.0.0.1:3306)/<db>?[k=v& ......]
@ -93,7 +93,7 @@ database:
enableLog: true # whether to turn on printing of all logs
maxIdleConns: 10 # set the maximum number of connections in the idle connection pool
maxOpenConns: 100 # set the maximum number of open database connections
connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes
connMaxLifetime: 10 # sets the maximum time for which the connection can be reused, in minutes
#slavesDsn: # sets slaves mysql dsn, array type
# - "your slave dsn 1"
# - "your slave dsn 2"
@ -107,7 +107,15 @@ database:
enableLog: true # whether to turn on printing of all logs
maxIdleConns: 10 # set the maximum number of connections in the idle connection pool
maxOpenConns: 100 # set the maximum number of open database connections
connMaxLifetime: 30 # sets the maximum time for which the connection can be reused, in minutes
connMaxLifetime: 10 # sets the maximum time for which the connection can be reused, in minutes
# sqlite settings
sqlite:
dbFile: "test/sql/sqlite/sponge.db" # if you are in a windows environment, the path separator is \\
enableLog: true # whether to turn on printing of all logs
maxIdleConns: 10 # set the maximum number of connections in the idle connection pool
maxOpenConns: 100 # set the maximum number of open database connections
connMaxLifetime: 10 # sets the maximum time for which the connection can be reused, in minutes
# delete the templates code end

4
go.mod
View File

@ -54,9 +54,10 @@ require (
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.5.1
gorm.io/driver/postgres v1.5.4
gorm.io/driver/sqlite v1.5.4
gorm.io/gorm v1.25.5
gorm.io/plugin/dbresolver v1.4.7
// todo generate the local sponge template code version here
// todo generate the local sponge template code version here
)
require (
@ -134,6 +135,7 @@ require (
github.com/mailru/easyjson v0.7.6 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.17 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect

8
go.sum
View File

@ -472,6 +472,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
@ -1171,11 +1173,17 @@ gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
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.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0=
gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E=
gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE=
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.2/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=
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde h1:9DShaph9qhkIYw7QF91I/ynrr4cOO2PZra2PFD7Mfeg=
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/plugin/dbresolver v1.4.7 h1:ZwtwmJQxTx9us7o6zEHFvH1q4OeEo1pooU7efmnunJA=
gorm.io/plugin/dbresolver v1.4.7/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -102,6 +102,14 @@ type GrpcClient struct {
RegistryDiscoveryType string `yaml:"registryDiscoveryType" json:"registryDiscoveryType"`
}
type Sqlite struct {
ConnMaxLifetime int `yaml:"connMaxLifetime" json:"connMaxLifetime"`
DBFile string `yaml:"dbFile" json:"dbFile"`
EnableLog bool `yaml:"enableLog" json:"enableLog"`
MaxIdleConns int `yaml:"maxIdleConns" json:"maxIdleConns"`
MaxOpenConns int `yaml:"maxOpenConns" json:"maxOpenConns"`
}
type Mysql struct {
ConnMaxLifetime int `yaml:"connMaxLifetime" json:"connMaxLifetime"`
Dsn string `yaml:"dsn" json:"dsn"`
@ -131,6 +139,7 @@ type Database struct {
Driver string `yaml:"driver" json:"driver"`
Mysql Mysql `yaml:"mysql" json:"mysql"`
Postgresql Postgresql `yaml:"postgresql" json:"postgresql"`
Sqlite Sqlite `yaml:"sqlite" json:"sqlite"`
}
type Grpc struct {

View File

@ -3,6 +3,7 @@ package handler
import (
"context"
"errors"
"math"
"strings"
serverNameExampleV1 "github.com/zhufuyi/sponge/api/serverNameExample/v1"
@ -223,6 +224,9 @@ func (h *userExamplePbHandler) ListByLastID(ctx context.Context, req *serverName
logger.Warn("req.Validate error", logger.Err(err), logger.Any("req", req), middleware.CtxRequestIDField(ctx))
return nil, ecode.InvalidParams.Err()
}
if req.LastID == 0 {
req.LastID = math.MaxInt32
}
records, err := h.userExampleDao.GetByLastID(ctx, req.LastID, int(req.Limit), req.Sort)
if err != nil {

View File

@ -114,33 +114,17 @@ func CloseRedis() error {
// InitDB connect database
func InitDB() {
switch strings.ToLower(config.Get().Database.Driver) {
case "mysql", "tidb":
case ggorm.DBDriverMysql, ggorm.DBDriverTidb:
InitMysql()
case "postgres", "postgresql":
case ggorm.DBDriverPostgresql:
InitPostgresql()
case ggorm.DBDriverSqlite:
InitSqlite()
default:
panic("unsupported database driver: " + config.Get().Database.Driver)
}
}
// GetDB get db
func GetDB() *gorm.DB {
if db == nil {
once1.Do(func() {
switch strings.ToLower(config.Get().Database.Driver) {
case "mysql", "tidb":
InitMysql()
case "postgres", "postgresql":
InitPostgresql()
default:
panic("unsupported database driver: " + config.Get().Database.Driver)
}
})
}
return db
}
// InitMysql connect mysql
func InitMysql() {
opts := []ggorm.Option{
@ -206,8 +190,44 @@ func InitPostgresql() {
}
}
// InitSqlite connect sqlite
func InitSqlite() {
opts := []ggorm.Option{
ggorm.WithMaxIdleConns(config.Get().Database.Sqlite.MaxIdleConns),
ggorm.WithMaxOpenConns(config.Get().Database.Sqlite.MaxOpenConns),
ggorm.WithConnMaxLifetime(time.Duration(config.Get().Database.Sqlite.ConnMaxLifetime) * time.Minute),
}
if config.Get().Database.Sqlite.EnableLog {
opts = append(opts,
ggorm.WithLogging(logger.Get()),
ggorm.WithLogRequestIDKey("request_id"),
)
}
if config.Get().App.EnableTrace {
opts = append(opts, ggorm.WithEnableTrace())
}
var err error
db, err = ggorm.InitSqlite(config.Get().Database.Sqlite.DBFile, opts...)
if err != nil {
panic("ggorm.InitSqlite error: " + err.Error())
}
}
// delete the templates code end
// GetDB get db
func GetDB() *gorm.DB {
if db == nil {
once1.Do(func() {
InitDB()
})
}
return db
}
// CloseDB close db
func CloseDB() error {
return ggorm.CloseDB(db)

View File

@ -7,14 +7,13 @@ import (
"github.com/zhufuyi/sponge/configs"
"github.com/zhufuyi/sponge/internal/config"
"github.com/zhufuyi/sponge/pkg/utils"
"github.com/stretchr/testify/assert"
"gorm.io/gorm"
)
func TestInitMysql(t *testing.T) {
func TestGetDB(t *testing.T) {
err := config.Init(configs.Path("serverNameExample.yml"))
if err != nil {
panic(err)
@ -51,6 +50,29 @@ func TestInitMysqlError(t *testing.T) {
})
}
func TestInitPostgresqlError(t *testing.T) {
_ = config.Init(configs.Path("serverNameExample.yml"))
// change config error test
config.Get().Database.Postgresql.Dsn = "root:123456@(127.0.0.1:5432)/test"
utils.SafeRunWithTimeout(time.Second*2, func(cancel context.CancelFunc) {
_ = CloseDB()
InitPostgresql()
assert.NotNil(t, db)
cancel()
})
}
func TestInitSqliteError(t *testing.T) {
_ = config.Init(configs.Path("serverNameExample.yml"))
utils.SafeRunWithTimeout(time.Second*2, func(cancel context.CancelFunc) {
InitSqlite()
assert.NotNil(t, db)
cancel()
})
}
func TestCloseDB(t *testing.T) {
defer func() { recover() }()
db = &gorm.DB{}

View File

@ -1,12 +1,14 @@
### ggorm
## ggorm
`ggorm` library wrapped in [gorm](gorm.io/gorm), with added features such as tracer, paging queries, etc.
Support `mysql`, `postgresql`, `tidb`, `clickhouse`, `sqlite`.
Support `mysql`, `postgresql`, `tidb`, `sqlite`.
<br>
### Example of use
## Examples of use
### mysql
#### Initializing the connection
@ -15,13 +17,13 @@ Support `mysql`, `postgresql`, `tidb`, `clickhouse`, `sqlite`.
"github.com/zhufuyi/sponge/pkg/ggorm"
)
var dsn = "root:123456@(192.168.1.6:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
var dsn = "root:123456@(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
// (1) connect to the database using the default settings
db, err := ggorm.InitMysql(dsn)
// (2) customised settings to connect to the database
db, err := ggorm.Init(
db, err := ggorm.InitMysql(
dsn,
ggorm.WithLogging(logger.Get()), // print log
ggorm.WithLogRequestIDKey("request_id"), // print request_id
@ -57,7 +59,7 @@ type UserExample struct {
// TableName get table name
func (table *UserExample) TableName() string {
return gorm.GetTableName(table)
return ggorm.GetTableName(table)
}
```
@ -98,6 +100,66 @@ func (table *UserExample) TableName() string {
```
<br>
### Postgresql
```go
import (
"github.com/zhufuyi/sponge/pkg/ggorm"
"github.com/zhufuyi/sponge/pkg/utils"
)
func InitSqlite() {
opts := []ggorm.Option{
ggorm.WithMaxIdleConns(10),
ggorm.WithMaxOpenConns(100),
ggorm.WithConnMaxLifetime(time.Duration(10) * time.Minute),
ggorm.WithLogging(logger.Get()),
ggorm.WithLogRequestIDKey("request_id"),
}
dsn := "root:123456@127.0.0.1:5432/test"
dsn = utils.AdaptivePostgresqlDsn(dsn)
db, err := ggorm.InitPostgresql(dsn, opts...)
if err != nil {
panic("ggorm.InitPostgresql error: " + err.Error())
}
}
```
<br>
### Tidb
Tidb is mysql compatible, just use **InitMysql**.
<br>
### Sqlite
```go
import (
"github.com/zhufuyi/sponge/pkg/ggorm"
)
func InitSqlite() {
opts := []ggorm.Option{
ggorm.WithMaxIdleConns(10),
ggorm.WithMaxOpenConns(100),
ggorm.WithConnMaxLifetime(time.Duration(10) * time.Minute),
ggorm.WithLogging(logger.Get()),
ggorm.WithLogRequestIDKey("request_id"),
}
dbFile: = "test.db"
db, err := ggorm.InitSqlite(dbFile, opts...)
if err != nil {
panic("ggorm.InitSqlite error: " + err.Error())
}
}
```
<br>
### gorm User Guide
- https://gorm.io/zh_CN/docs/index.html

View File

@ -12,12 +12,24 @@ import (
"github.com/uptrace/opentelemetry-go-extra/otelgorm"
mysqlDriver "gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"gorm.io/plugin/dbresolver"
)
const (
// DBDriverMysql mysql driver
DBDriverMysql = "mysql"
// DBDriverPostgresql postgresql driver
DBDriverPostgresql = "postgresql"
// DBDriverTidb tidb driver
DBDriverTidb = "tidb"
// DBDriverSqlite sqlite driver
DBDriverSqlite = "sqlite"
)
// InitMysql init mysql or tidb
func InitMysql(dsn string, opts ...Option) (*gorm.DB, error) {
o := defaultOptions()
@ -106,15 +118,36 @@ func InitTidb(dsn string, opts ...Option) (*gorm.DB, error) {
return InitMysql(dsn, opts...)
}
// InitClickhouse init clickhouse
//func InitClickhouse(dsn string, opts ...Option) (*gorm.DB, error) {
// return InitMysql(dsn, opts...)
//}
// InitSqlite init sqlite
//func InitSqlite(dsn string, opts ...Option) (*gorm.DB, error) {
// panic("not implemented")
//}
func InitSqlite(dbFile string, opts ...Option) (*gorm.DB, error) {
o := defaultOptions()
o.apply(opts...)
dsn := fmt.Sprintf("%s?_journal=WAL&_vacuum=incremental", dbFile)
db, err := gorm.Open(sqlite.Open(dsn), gormConfig(o))
if err != nil {
return nil, err
}
db.Set("gorm:auto_increment", true)
// register trace plugin
if o.enableTrace {
err = db.Use(otelgorm.NewPlugin())
if err != nil {
return nil, fmt.Errorf("using gorm opentelemetry, err: %v", err)
}
}
// register plugins
for _, plugin := range o.plugins {
err = db.Use(plugin)
if err != nil {
return nil, err
}
}
return db, nil
}
// CloseDB close gorm db
func CloseDB(db *gorm.DB) error {
@ -136,7 +169,7 @@ func checkInUse(sqlDB *sql.DB, duration time.Duration) {
ctx, _ := context.WithTimeout(context.Background(), duration) //nolint
for {
select {
case <-time.After(time.Millisecond * 500):
case <-time.After(time.Millisecond * 100):
if v := sqlDB.Stats().InUse; v == 0 {
return
}
@ -146,6 +179,15 @@ func checkInUse(sqlDB *sql.DB, duration time.Duration) {
}
}
// CloseSQLDB close sql db
func CloseSQLDB(db *gorm.DB) {
sqlDB, err := db.DB()
if err != nil {
return
}
_ = sqlDB.Close()
}
// gorm setting
func gormConfig(o *options) *gorm.Config {
config := &gorm.Config{

View File

@ -36,11 +36,24 @@ func TestInitTidb(t *testing.T) {
t.Logf("%+v", db.Name())
}
func TestInitSqlite(t *testing.T) {
dbFile := "test_sqlite.db"
db, err := InitSqlite(dbFile)
if err != nil {
// ignore test error about not being able to connect to real sqlite
t.Logf(fmt.Sprintf("connect to sqlite failed, err=%v, dbFile=%s", err, dbFile))
return
}
defer CloseDB(db)
t.Logf("%+v", db.Name())
}
func TestInitPostgresql(t *testing.T) {
dsn = "host=192.168.3.37 user=root password=123456 dbname=account port=5432 sslmode=disable TimeZone=Asia/Shanghai"
db, err := InitPostgresql(dsn, WithEnableTrace())
if err != nil {
// ignore test error about not being able to connect to real mysql
// ignore test error about not being able to connect to real postgresql
t.Logf(fmt.Sprintf("connect to postgresql failed, err=%v, dsn=%s", err, dsn))
return
}
@ -100,5 +113,11 @@ func TestCloseDB(t *testing.T) {
checkInUse(sqlDB, time.Millisecond*600)
db := new(gorm.DB)
defer func() { recover() }()
CloseDB(db)
_ = CloseDB(db)
}
func TestCloseSqlDB(t *testing.T) {
db := new(gorm.DB)
defer func() { recover() }()
CloseSQLDB(db)
}

BIN
pkg/ggorm/test_sqlite.db Normal file

Binary file not shown.

View File

@ -86,6 +86,9 @@ func (r *replacerInfo) SetReplacementFields(fields []Field) {
var newFields []Field
for _, field := range fields {
if field.IsCaseSensitive && isFirstAlphabet(field.Old) { // splitting the initial case field
if field.New == "" {
continue
}
newFields = append(newFields,
Field{ // convert the first letter to upper case
Old: strings.ToUpper(field.Old[:1]) + field.Old[1:],

View File

@ -41,6 +41,8 @@ const (
DBDriverPostgresql = "postgresql"
// DBDriverTidb tidb driver
DBDriverTidb = "tidb"
// DBDriverSqlite sqlite driver
DBDriverSqlite = "sqlite"
)
// Codes content
@ -307,7 +309,7 @@ func makeCode(stmt *ast.CreateTableStmt, opt options) (*codeText, error) {
if opt.GormType {
gormTag.WriteString(";type:")
switch opt.DBDriver {
case DBDriverMysql, DBDriverTidb:
case DBDriverMysql, DBDriverTidb, DBDriverSqlite:
gormTag.WriteString(col.Tp.InfoSchemaStr())
case DBDriverPostgresql:
gormTag.WriteString(opt.FieldTypes[colName])

View File

@ -172,7 +172,7 @@ func Test_initTemplate(t *testing.T) {
initTemplate()
}
func TestGetTableInfo(t *testing.T) {
func TestGetMysqlTableInfo(t *testing.T) {
info, err := GetMysqlTableInfo("root:123456@(192.168.3.37:3306)/test", "user")
t.Log(err, info)
}
@ -184,6 +184,11 @@ func TestGetPostgresqlTableInfo(t *testing.T) {
t.Log(sql, fieldTypes)
}
func TestGetSqliteTableInfo(t *testing.T) {
info, err := GetSqliteTableInfo("..\\..\\..\\test\\sql\\sqlite\\sponge.db", "user_example")
t.Log(err, info)
}
func TestConvertToMysqlTable(t *testing.T) {
fields := []*PGField{
{Name: "id", Type: "smallint"},

View File

@ -8,6 +8,7 @@ import (
"gorm.io/gorm"
)
// PGField postgresql field
type PGField struct {
Name string `gorm:"column:name;" json:"name"`
Type string `gorm:"column:type;" json:"type"`
@ -23,6 +24,7 @@ func GetPostgresqlTableInfo(dsn string, tableName string) ([]*PGField, error) {
if err != nil {
return nil, fmt.Errorf("GetPostgresqlTableInfo error: %v", err)
}
defer closeDB(db)
return getPostgresqlTableFields(db, tableName)
}
@ -116,3 +118,11 @@ func getType(field *PGField) string {
}
return field.Type
}
func closeDB(db *gorm.DB) {
sqlDB, err := db.DB()
if err != nil {
return
}
_ = sqlDB.Close()
}

View File

@ -0,0 +1,49 @@
package parser
import (
"strings"
"github.com/zhufuyi/sponge/pkg/ggorm"
)
var sqliteToMysqlTypeMap = map[string]string{
" INTEGER ": " INT ",
" REAL ": " FLOAT ",
" BOOLEAN ": " TINYINT ",
" integer ": " INT ",
" real ": " FLOAT ",
" boolean ": " TINYINT ",
}
// GetSqliteTableInfo get table info from sqlite
func GetSqliteTableInfo(dbFile string, tableName string) (string, error) {
db, err := ggorm.InitSqlite(dbFile)
if err != nil {
return "", err
}
defer closeDB(db)
var sql string
err = db.Raw("select sql from sqlite_master where type = ? and name = ?", "table", tableName).Scan(&sql).Error
if err != nil {
return "", err
}
//sql = handleID(sql)
for k, v := range sqliteToMysqlTypeMap {
sql = strings.ReplaceAll(sql, k, v)
}
return sql, nil
}
//func handleID(sql string) string {
// re := regexp.MustCompile(`id\s+INTEGER`)
// matches := re.FindAllStringSubmatch(sql, -1)
//
// for _, match := range matches {
// sql = strings.ReplaceAll(sql, match[0], " id bigint unsigned")
// }
//
// return sql
//}

View File

@ -9,6 +9,7 @@ import (
"os"
"strings"
"github.com/zhufuyi/sponge/pkg/gofile"
"github.com/zhufuyi/sponge/pkg/sql2code/parser"
"github.com/zhufuyi/sponge/pkg/utils"
)
@ -20,7 +21,7 @@ type Args struct {
DDLFile string // DDL file
DBDriver string // db driver name, such as mysql, postgres, default is mysql
DBDsn string // connecting to mysql's dsn
DBDsn string // connecting to mysql's dsn, if DBDriver is sqlite, DBDsn is local db file
DBTable string // table name
fieldTypes map[string]string // field name:type
@ -46,6 +47,10 @@ func (a *Args) checkValid() error {
}
if a.DBDriver == "" {
a.DBDriver = parser.DBDriverMysql
} else if a.DBDriver == parser.DBDriverSqlite {
if !gofile.IsExists(a.DBDsn) {
return fmt.Errorf("sqlite db file %s not found in local host", a.DBDsn)
}
}
return nil
}
@ -84,6 +89,9 @@ func getSQL(args *Args) (string, map[string]string, error) {
}
sqlStr, pgTypeMap := parser.ConvertToMysqlTable(args.DBTable, fields)
return sqlStr, pgTypeMap, nil
case parser.DBDriverSqlite:
sqlStr, err := parser.GetSqliteTableInfo(args.DBDsn, args.DBTable)
return sqlStr, nil, err
default:
return "", nil, fmt.Errorf("unsupported database driver: " + dbDriverName)
}
@ -184,6 +192,9 @@ func Generate(args *Args) (map[string]string, error) {
if fieldTypes != nil {
args.fieldTypes = fieldTypes
}
if sql == "" {
return nil, fmt.Errorf("get sql from %s error, maybe the table %s doesn't exist", args.DBDriver, args.DBTable)
}
opt := setOptions(args)

View File

@ -13,6 +13,10 @@ function checkResult() {
fi
}
function importPkg() {
go mod tidy
}
function generateTypesPbCode() {
sponge patch gen-types-pb --out=./
checkResult $?
@ -21,16 +25,19 @@ function generateTypesPbCode() {
function generateInitMysqlCode() {
sponge patch gen-db-init --db-driver=mysql --out=./
checkResult $?
importPkg
}
function generateInitTidbCode() {
sponge patch gen-db-init --db-driver=tidb --out=./
checkResult $?
importPkg
}
function generateInitPostgresqlCode() {
sponge patch gen-db-init --db-driver=postgresql --out=./
checkResult $?
importPkg
}
if [ "$patchType" = "$typesPb" ]; then

BIN
test/sql/sqlite/sponge.db Normal file

Binary file not shown.