forked from Gitlink/gitea-1156
Add support for database schema in PostgreSQL (#8819)
* Add support for database schema * Require setting search_path for the db user * Add schema setting to admin/config.tmpl * Use a schema different from default for psql tests * Update postgres scripts to use custom schema * Update to xorm/core 0.7.3 and xorm/xorm c37aff9b3a * Fix migration test Co-authored-by: Antoine GIRARD <sapk@users.noreply.github.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
6d6f1d568e
commit
ad1b6d439f
2
Makefile
2
Makefile
|
@ -79,6 +79,7 @@ TEST_PGSQL_HOST ?= pgsql:5432
|
||||||
TEST_PGSQL_DBNAME ?= testgitea
|
TEST_PGSQL_DBNAME ?= testgitea
|
||||||
TEST_PGSQL_USERNAME ?= postgres
|
TEST_PGSQL_USERNAME ?= postgres
|
||||||
TEST_PGSQL_PASSWORD ?= postgres
|
TEST_PGSQL_PASSWORD ?= postgres
|
||||||
|
TEST_PGSQL_SCHEMA ?= gtestschema
|
||||||
TEST_MSSQL_HOST ?= mssql:1433
|
TEST_MSSQL_HOST ?= mssql:1433
|
||||||
TEST_MSSQL_DBNAME ?= gitea
|
TEST_MSSQL_DBNAME ?= gitea
|
||||||
TEST_MSSQL_USERNAME ?= sa
|
TEST_MSSQL_USERNAME ?= sa
|
||||||
|
@ -306,6 +307,7 @@ generate-ini-pgsql:
|
||||||
-e 's|{{TEST_PGSQL_DBNAME}}|${TEST_PGSQL_DBNAME}|g' \
|
-e 's|{{TEST_PGSQL_DBNAME}}|${TEST_PGSQL_DBNAME}|g' \
|
||||||
-e 's|{{TEST_PGSQL_USERNAME}}|${TEST_PGSQL_USERNAME}|g' \
|
-e 's|{{TEST_PGSQL_USERNAME}}|${TEST_PGSQL_USERNAME}|g' \
|
||||||
-e 's|{{TEST_PGSQL_PASSWORD}}|${TEST_PGSQL_PASSWORD}|g' \
|
-e 's|{{TEST_PGSQL_PASSWORD}}|${TEST_PGSQL_PASSWORD}|g' \
|
||||||
|
-e 's|{{TEST_PGSQL_SCHEMA}}|${TEST_PGSQL_SCHEMA}|g' \
|
||||||
integrations/pgsql.ini.tmpl > integrations/pgsql.ini
|
integrations/pgsql.ini.tmpl > integrations/pgsql.ini
|
||||||
|
|
||||||
.PHONY: test-pgsql
|
.PHONY: test-pgsql
|
||||||
|
|
|
@ -336,6 +336,10 @@ NAME = gitea
|
||||||
USER = root
|
USER = root
|
||||||
; Use PASSWD = `your password` for quoting if you use special characters in the password.
|
; Use PASSWD = `your password` for quoting if you use special characters in the password.
|
||||||
PASSWD =
|
PASSWD =
|
||||||
|
; For Postgres, schema to use if different from "public". The schema must exist beforehand,
|
||||||
|
; the user must have creation privileges on it, and the user search path must be set
|
||||||
|
; to the look into the schema first. e.g.:ALTER USER user SET SEARCH_PATH = schema_name,"$user",public;
|
||||||
|
SCHEMA =
|
||||||
; For Postgres, either "disable" (default), "require", or "verify-full"
|
; For Postgres, either "disable" (default), "require", or "verify-full"
|
||||||
; For MySQL, either "false" (default), "true", or "skip-verify"
|
; For MySQL, either "false" (default), "true", or "skip-verify"
|
||||||
SSL_MODE = disable
|
SSL_MODE = disable
|
||||||
|
|
|
@ -209,6 +209,9 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
- `NAME`: **gitea**: Database name.
|
- `NAME`: **gitea**: Database name.
|
||||||
- `USER`: **root**: Database username.
|
- `USER`: **root**: Database username.
|
||||||
- `PASSWD`: **\<empty\>**: Database user password. Use \`your password\` for quoting if you use special characters in the password.
|
- `PASSWD`: **\<empty\>**: Database user password. Use \`your password\` for quoting if you use special characters in the password.
|
||||||
|
- `SCHEMA`: **\<empty\>**: For PostgreSQL only, schema to use if different from "public". The schema must exist beforehand,
|
||||||
|
the user must have creation privileges on it, and the user search path must be set to the look into the schema first
|
||||||
|
(e.g. `ALTER USER user SET SEARCH_PATH = schema_name,"$user",public;`).
|
||||||
- `SSL_MODE`: **disable**: For PostgreSQL and MySQL only.
|
- `SSL_MODE`: **disable**: For PostgreSQL and MySQL only.
|
||||||
- `CHARSET`: **utf8**: For MySQL only, either "utf8" or "utf8mb4", default is "utf8". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
|
- `CHARSET`: **utf8**: For MySQL only, either "utf8" or "utf8mb4", default is "utf8". NOTICE: for "utf8mb4" you must use MySQL InnoDB > 5.6. Gitea is unable to check this.
|
||||||
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
|
- `PATH`: **data/gitea.db**: For SQLite3 only, the database file path.
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -112,6 +112,6 @@ require (
|
||||||
mvdan.cc/xurls/v2 v2.1.0
|
mvdan.cc/xurls/v2 v2.1.0
|
||||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
|
||||||
xorm.io/builder v0.3.6
|
xorm.io/builder v0.3.6
|
||||||
xorm.io/core v0.7.2
|
xorm.io/core v0.7.3
|
||||||
xorm.io/xorm v0.8.1
|
xorm.io/xorm v0.8.2-0.20200120024500-c37aff9b3a4a
|
||||||
)
|
)
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -760,7 +760,9 @@ xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8=
|
||||||
xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU=
|
xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU=
|
||||||
xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=
|
xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=
|
||||||
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
||||||
|
xorm.io/core v0.7.3 h1:W8ws1PlrnkS1CZU1YWaYLMQcQilwAmQXU0BJDJon+H0=
|
||||||
|
xorm.io/core v0.7.3/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
||||||
xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM=
|
xorm.io/xorm v0.8.0 h1:iALxgJrX8O00f8Jk22GbZwPmxJNgssV5Mv4uc2HL9PM=
|
||||||
xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY=
|
xorm.io/xorm v0.8.0/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY=
|
||||||
xorm.io/xorm v0.8.1 h1:4f2KXuQxVdaX3RdI3Fw81NzMiSpZeyCZt8m3sEVeIkQ=
|
xorm.io/xorm v0.8.2-0.20200120024500-c37aff9b3a4a h1:hzGd080rlkZ5a7v6Tr3x8PJJnWPfKxGMMl92c8DNcww=
|
||||||
xorm.io/xorm v0.8.1/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY=
|
xorm.io/xorm v0.8.2-0.20200120024500-c37aff9b3a4a/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY=
|
||||||
|
|
|
@ -153,18 +153,53 @@ func initIntegrationTest() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("sql.Open: %v", err)
|
log.Fatalf("sql.Open: %v", err)
|
||||||
}
|
}
|
||||||
rows, err := db.Query(fmt.Sprintf("SELECT 1 FROM pg_database WHERE datname = '%s'", setting.Database.Name))
|
dbrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM pg_database WHERE datname = '%s'", setting.Database.Name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("db.Query: %v", err)
|
log.Fatalf("db.Query: %v", err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer dbrows.Close()
|
||||||
|
|
||||||
if rows.Next() {
|
if !dbrows.Next() {
|
||||||
|
if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)); err != nil {
|
||||||
|
log.Fatalf("db.Exec: CREATE DATABASE: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if we need to setup a specific schema
|
||||||
|
if len(setting.Database.Schema) == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)); err != nil {
|
db.Close()
|
||||||
log.Fatalf("db.Exec: %v", err)
|
|
||||||
|
db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
|
||||||
|
setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode))
|
||||||
|
// This is a different db object; requires a different Close()
|
||||||
|
defer db.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("sql.Open: %v", err)
|
||||||
}
|
}
|
||||||
|
schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("db.Query: %v", err)
|
||||||
|
}
|
||||||
|
defer schrows.Close()
|
||||||
|
|
||||||
|
if !schrows.Next() {
|
||||||
|
// Create and setup a DB schema
|
||||||
|
if _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema)); err != nil {
|
||||||
|
log.Fatalf("db.Exec: CREATE SCHEMA: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the user's default search path the created schema; this will affect new connections
|
||||||
|
if _, err = db.Exec(fmt.Sprintf(`ALTER USER "%s" SET search_path = %s`, setting.Database.User, setting.Database.Schema)); err != nil {
|
||||||
|
log.Fatalf("db.Exec: ALTER USER SET search_path: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the current connection's search the created schema
|
||||||
|
if _, err = db.Exec(fmt.Sprintf(`SET search_path = %s`, setting.Database.Schema)); err != nil {
|
||||||
|
log.Fatalf("db.Exec: ALTER USER SET search_path: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
case setting.Database.UseMSSQL:
|
case setting.Database.UseMSSQL:
|
||||||
host, port := setting.ParseMSSQLHostPort(setting.Database.Host)
|
host, port := setting.ParseMSSQLHostPort(setting.Database.Host)
|
||||||
db, err := sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;",
|
db, err := sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;",
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -168,6 +168,32 @@ func restoreOldDB(t *testing.T, version string) bool {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
db.Close()
|
db.Close()
|
||||||
|
|
||||||
|
// Check if we need to setup a specific schema
|
||||||
|
if len(setting.Database.Schema) != 0 {
|
||||||
|
db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
|
||||||
|
setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode))
|
||||||
|
if !assert.NoError(t, err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema))
|
||||||
|
if !assert.NoError(t, err) || !assert.NotEmpty(t, schrows) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !schrows.Next() {
|
||||||
|
// Create and setup a DB schema
|
||||||
|
_, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
schrows.Close()
|
||||||
|
|
||||||
|
// Make the user's default search path the created schema; this will affect new connections
|
||||||
|
_, err = db.Exec(fmt.Sprintf(`ALTER USER "%s" SET search_path = %s`, setting.Database.User, setting.Database.Schema))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
db.Close()
|
||||||
|
}
|
||||||
|
|
||||||
db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
|
db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
|
||||||
setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode))
|
setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
|
@ -7,6 +7,7 @@ HOST = {{TEST_PGSQL_HOST}}
|
||||||
NAME = {{TEST_PGSQL_DBNAME}}
|
NAME = {{TEST_PGSQL_DBNAME}}
|
||||||
USER = {{TEST_PGSQL_USERNAME}}
|
USER = {{TEST_PGSQL_USERNAME}}
|
||||||
PASSWD = {{TEST_PGSQL_PASSWORD}}
|
PASSWD = {{TEST_PGSQL_PASSWORD}}
|
||||||
|
SCHEMA = {{TEST_PGSQL_SCHEMA}}
|
||||||
SSL_MODE = disable
|
SSL_MODE = disable
|
||||||
|
|
||||||
[indexer]
|
[indexer]
|
||||||
|
|
|
@ -128,7 +128,12 @@ func getEngine() (*xorm.Engine, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return xorm.NewEngine(setting.Database.Type, connStr)
|
engine, err := xorm.NewEngine(setting.Database.Type, connStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
engine.SetSchema(setting.Database.Schema)
|
||||||
|
return engine, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTestEngine sets a new test xorm.Engine
|
// NewTestEngine sets a new test xorm.Engine
|
||||||
|
|
|
@ -25,6 +25,7 @@ type InstallForm struct {
|
||||||
SSLMode string
|
SSLMode string
|
||||||
Charset string `binding:"Required;In(utf8,utf8mb4)"`
|
Charset string `binding:"Required;In(utf8,utf8mb4)"`
|
||||||
DbPath string
|
DbPath string
|
||||||
|
DbSchema string
|
||||||
|
|
||||||
AppName string `binding:"Required" locale:"install.app_name"`
|
AppName string `binding:"Required" locale:"install.app_name"`
|
||||||
RepoRootPath string `binding:"Required"`
|
RepoRootPath string `binding:"Required"`
|
||||||
|
|
|
@ -30,6 +30,7 @@ var (
|
||||||
Name string
|
Name string
|
||||||
User string
|
User string
|
||||||
Passwd string
|
Passwd string
|
||||||
|
Schema string
|
||||||
SSLMode string
|
SSLMode string
|
||||||
Path string
|
Path string
|
||||||
LogSQL bool
|
LogSQL bool
|
||||||
|
@ -75,6 +76,7 @@ func InitDBConfig() {
|
||||||
if len(Database.Passwd) == 0 {
|
if len(Database.Passwd) == 0 {
|
||||||
Database.Passwd = sec.Key("PASSWD").String()
|
Database.Passwd = sec.Key("PASSWD").String()
|
||||||
}
|
}
|
||||||
|
Database.Schema = sec.Key("SCHEMA").String()
|
||||||
Database.SSLMode = sec.Key("SSL_MODE").MustString("disable")
|
Database.SSLMode = sec.Key("SSL_MODE").MustString("disable")
|
||||||
Database.Charset = sec.Key("CHARSET").In("utf8", []string{"utf8", "utf8mb4"})
|
Database.Charset = sec.Key("CHARSET").In("utf8", []string{"utf8", "utf8mb4"})
|
||||||
Database.Path = sec.Key("PATH").MustString(filepath.Join(AppDataPath, "gitea.db"))
|
Database.Path = sec.Key("PATH").MustString(filepath.Join(AppDataPath, "gitea.db"))
|
||||||
|
|
|
@ -102,6 +102,8 @@ user = Username
|
||||||
password = Password
|
password = Password
|
||||||
db_name = Database Name
|
db_name = Database Name
|
||||||
db_helper = Note to MySQL users: please use the InnoDB storage engine and if you use "utf8mb4", your InnoDB version must be greater than 5.6 .
|
db_helper = Note to MySQL users: please use the InnoDB storage engine and if you use "utf8mb4", your InnoDB version must be greater than 5.6 .
|
||||||
|
db_schema = Schema
|
||||||
|
db_schema_helper = Leave blank for database default ("public").
|
||||||
ssl_mode = SSL
|
ssl_mode = SSL
|
||||||
charset = Charset
|
charset = Charset
|
||||||
path = Path
|
path = Path
|
||||||
|
@ -1953,6 +1955,7 @@ config.db_type = Type
|
||||||
config.db_host = Host
|
config.db_host = Host
|
||||||
config.db_name = Name
|
config.db_name = Name
|
||||||
config.db_user = Username
|
config.db_user = Username
|
||||||
|
config.db_schema = Schema
|
||||||
config.db_ssl_mode = SSL
|
config.db_ssl_mode = SSL
|
||||||
config.db_path = Path
|
config.db_path = Path
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ func Install(ctx *context.Context) {
|
||||||
form.DbPasswd = setting.Database.Passwd
|
form.DbPasswd = setting.Database.Passwd
|
||||||
form.DbName = setting.Database.Name
|
form.DbName = setting.Database.Name
|
||||||
form.DbPath = setting.Database.Path
|
form.DbPath = setting.Database.Path
|
||||||
|
form.DbSchema = setting.Database.Schema
|
||||||
form.Charset = setting.Database.Charset
|
form.Charset = setting.Database.Charset
|
||||||
|
|
||||||
ctx.Data["CurDbOption"] = "MySQL"
|
ctx.Data["CurDbOption"] = "MySQL"
|
||||||
|
@ -147,6 +148,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) {
|
||||||
setting.Database.User = form.DbUser
|
setting.Database.User = form.DbUser
|
||||||
setting.Database.Passwd = form.DbPasswd
|
setting.Database.Passwd = form.DbPasswd
|
||||||
setting.Database.Name = form.DbName
|
setting.Database.Name = form.DbName
|
||||||
|
setting.Database.Schema = form.DbSchema
|
||||||
setting.Database.SSLMode = form.SSLMode
|
setting.Database.SSLMode = form.SSLMode
|
||||||
setting.Database.Charset = form.Charset
|
setting.Database.Charset = form.Charset
|
||||||
setting.Database.Path = form.DbPath
|
setting.Database.Path = form.DbPath
|
||||||
|
@ -267,6 +269,7 @@ func InstallPost(ctx *context.Context, form auth.InstallForm) {
|
||||||
cfg.Section("database").Key("NAME").SetValue(setting.Database.Name)
|
cfg.Section("database").Key("NAME").SetValue(setting.Database.Name)
|
||||||
cfg.Section("database").Key("USER").SetValue(setting.Database.User)
|
cfg.Section("database").Key("USER").SetValue(setting.Database.User)
|
||||||
cfg.Section("database").Key("PASSWD").SetValue(setting.Database.Passwd)
|
cfg.Section("database").Key("PASSWD").SetValue(setting.Database.Passwd)
|
||||||
|
cfg.Section("database").Key("SCHEMA").SetValue(setting.Database.Schema)
|
||||||
cfg.Section("database").Key("SSL_MODE").SetValue(setting.Database.SSLMode)
|
cfg.Section("database").Key("SSL_MODE").SetValue(setting.Database.SSLMode)
|
||||||
cfg.Section("database").Key("CHARSET").SetValue(setting.Database.Charset)
|
cfg.Section("database").Key("CHARSET").SetValue(setting.Database.Charset)
|
||||||
cfg.Section("database").Key("PATH").SetValue(setting.Database.Path)
|
cfg.Section("database").Key("PATH").SetValue(setting.Database.Path)
|
||||||
|
|
|
@ -128,6 +128,8 @@
|
||||||
<dd>{{if .DbCfg.User}}{{.DbCfg.User}}{{else}}-{{end}}</dd>
|
<dd>{{if .DbCfg.User}}{{.DbCfg.User}}{{else}}-{{end}}</dd>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if eq .DbCfg.Type "postgres"}}
|
{{if eq .DbCfg.Type "postgres"}}
|
||||||
|
<dt>{{.i18n.Tr "admin.config.db_schema"}}</dt>
|
||||||
|
<dd>{{if .DbCfg.Schema}}{{.DbCfg.Schema}}{{else}}-{{end}}</dd>
|
||||||
<dt>{{.i18n.Tr "admin.config.db_ssl_mode"}}</dt>
|
<dt>{{.i18n.Tr "admin.config.db_ssl_mode"}}</dt>
|
||||||
<dd>{{if .DbCfg.SSLMode}}{{.DbCfg.SSLMode}}{{else}}-{{end}}</dd>
|
<dd>{{if .DbCfg.SSLMode}}{{.DbCfg.SSLMode}}{{else}}-{{end}}</dd>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -62,6 +62,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="inline field {{if .Err_DbSetting}}error{{end}}">
|
||||||
|
<label for="db_schema">{{.i18n.Tr "install.db_schema"}}</label>
|
||||||
|
<input id="db_schema" name="db_schema" value="{{.db_schema}}">
|
||||||
|
<span class="help">{{.i18n.Tr "install.db_schema_helper"}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="mysql_settings" class="{{if not (eq .CurDbOption "MySQL")}}hide{{end}}">
|
<div id="mysql_settings" class="{{if not (eq .CurDbOption "MySQL")}}hide{{end}}">
|
||||||
|
|
|
@ -613,7 +613,7 @@ mvdan.cc/xurls/v2
|
||||||
strk.kbt.io/projects/go/libravatar
|
strk.kbt.io/projects/go/libravatar
|
||||||
# xorm.io/builder v0.3.6
|
# xorm.io/builder v0.3.6
|
||||||
xorm.io/builder
|
xorm.io/builder
|
||||||
# xorm.io/core v0.7.2
|
# xorm.io/core v0.7.3
|
||||||
xorm.io/core
|
xorm.io/core
|
||||||
# xorm.io/xorm v0.8.1
|
# xorm.io/xorm v0.8.2-0.20200120024500-c37aff9b3a4a
|
||||||
xorm.io/xorm
|
xorm.io/xorm
|
||||||
|
|
|
@ -1,128 +1,8 @@
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: go1.10
|
|
||||||
|
|
||||||
platform:
|
|
||||||
os: linux
|
|
||||||
arch: amd64
|
|
||||||
|
|
||||||
clone:
|
|
||||||
disable: true
|
|
||||||
|
|
||||||
workspace:
|
|
||||||
base: /go
|
|
||||||
path: src/xorm.io/core
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: git
|
|
||||||
pull: default
|
|
||||||
image: plugins/git:next
|
|
||||||
settings:
|
|
||||||
depth: 50
|
|
||||||
tags: true
|
|
||||||
|
|
||||||
- name: test
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
commands:
|
|
||||||
- go get github.com/stretchr/testify/assert
|
|
||||||
- go get github.com/go-xorm/sqlfiddle
|
|
||||||
- go get github.com/go-sql-driver/mysql
|
|
||||||
- go get github.com/mattn/go-sqlite3
|
|
||||||
- go vet
|
|
||||||
- "go test -v -race -coverprofile=coverage.txt -covermode=atomic -dbConn=\"root:@tcp(mysql:3306)/core_test?charset=utf8mb4\""
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
services:
|
|
||||||
- name: mysql
|
|
||||||
pull: default
|
|
||||||
image: mysql:5.7
|
|
||||||
environment:
|
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
|
||||||
MYSQL_DATABASE: core_test
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: go1.11
|
|
||||||
|
|
||||||
platform:
|
|
||||||
os: linux
|
|
||||||
arch: amd64
|
|
||||||
|
|
||||||
clone:
|
|
||||||
disable: true
|
|
||||||
|
|
||||||
workspace:
|
|
||||||
base: /go
|
|
||||||
path: src/xorm.io/core
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: git
|
|
||||||
pull: default
|
|
||||||
image: plugins/git:next
|
|
||||||
settings:
|
|
||||||
depth: 50
|
|
||||||
tags: true
|
|
||||||
|
|
||||||
- name: test
|
|
||||||
pull: default
|
|
||||||
image: golang:1.11
|
|
||||||
commands:
|
|
||||||
- go vet
|
|
||||||
- "go test -v -race -coverprofile=coverage.txt -covermode=atomic -dbConn=\"root:@tcp(mysql:3306)/core_test?charset=utf8mb4\""
|
|
||||||
environment:
|
|
||||||
GO111MODULE: "on"
|
|
||||||
GOPROXY: https://goproxy.cn
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
services:
|
|
||||||
- name: mysql
|
|
||||||
pull: default
|
|
||||||
image: mysql:5.7
|
|
||||||
environment:
|
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
|
||||||
MYSQL_DATABASE: core_test
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: go1.12
|
name: go1.12
|
||||||
|
|
||||||
platform:
|
|
||||||
os: linux
|
|
||||||
arch: amd64
|
|
||||||
|
|
||||||
clone:
|
|
||||||
disable: true
|
|
||||||
|
|
||||||
workspace:
|
|
||||||
base: /go
|
|
||||||
path: src/xorm.io/core
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: git
|
|
||||||
pull: default
|
|
||||||
image: plugins/git:next
|
|
||||||
settings:
|
|
||||||
depth: 50
|
|
||||||
tags: true
|
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
pull: default
|
pull: default
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Core is a lightweight wrapper of sql.DB.
|
Core is a lightweight wrapper of sql.DB.
|
||||||
|
|
||||||
[![Build Status](https://drone.gitea.com/api/badges/xorm/core/status.svg)](https://drone.gitea.com/xorm/core)
|
[![Build Status](https://drone.gitea.com/api/badges/xorm/core/status.svg)](https://drone.gitea.com/xorm/core)
|
||||||
[![](http://gocover.io/_badge/xorm.io/core)](http://gocover.io/xorm.io/core)
|
[![Test Coverage](https://gocover.io/_badge/xorm.io/core)](https://gocover.io/xorm.io/core)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/xorm.io/core)
|
[![Go Report Card](https://goreportcard.com/badge/code.gitea.io/gitea)](https://goreportcard.com/report/xorm.io/core)
|
||||||
|
|
||||||
# Open
|
# Open
|
||||||
|
|
|
@ -37,7 +37,7 @@ type Column struct {
|
||||||
IsDeleted bool
|
IsDeleted bool
|
||||||
IsCascade bool
|
IsCascade bool
|
||||||
IsVersion bool
|
IsVersion bool
|
||||||
DefaultIsEmpty bool
|
DefaultIsEmpty bool // false means column has no default set, but not default value is empty
|
||||||
EnumOptions map[string]int
|
EnumOptions map[string]int
|
||||||
SetOptions map[string]int
|
SetOptions map[string]int
|
||||||
DisableTimeZone bool
|
DisableTimeZone bool
|
||||||
|
@ -65,7 +65,7 @@ func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable
|
||||||
IsDeleted: false,
|
IsDeleted: false,
|
||||||
IsCascade: false,
|
IsCascade: false,
|
||||||
IsVersion: false,
|
IsVersion: false,
|
||||||
DefaultIsEmpty: false,
|
DefaultIsEmpty: true, // default should be no default
|
||||||
EnumOptions: make(map[string]int),
|
EnumOptions: make(map[string]int),
|
||||||
Comment: "",
|
Comment: "",
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,8 @@ type Index struct {
|
||||||
func (index *Index) XName(tableName string) string {
|
func (index *Index) XName(tableName string) string {
|
||||||
if !strings.HasPrefix(index.Name, "UQE_") &&
|
if !strings.HasPrefix(index.Name, "UQE_") &&
|
||||||
!strings.HasPrefix(index.Name, "IDX_") {
|
!strings.HasPrefix(index.Name, "IDX_") {
|
||||||
tableName = strings.Replace(tableName, `"`, "", -1)
|
tableParts := strings.Split(strings.Replace(tableName, `"`, "", -1), ".")
|
||||||
tableName = strings.Replace(tableName, `.`, "_", -1)
|
tableName = tableParts[len(tableParts)-1]
|
||||||
if index.Type == UniqueType {
|
if index.Type == UniqueType {
|
||||||
return fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
|
return fmt.Sprintf("UQE_%v_%v", tableName, index.Name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,204 +1,14 @@
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
name: go1.10-test
|
name: testing
|
||||||
workspace:
|
|
||||||
base: /go
|
|
||||||
path: src/gitea.com/xorm/xorm
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: build
|
- name: test-vet
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.10
|
image: golang:1.12
|
||||||
commands:
|
|
||||||
- go get -t -d -v
|
|
||||||
- go build -v
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-sqlite
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- build
|
|
||||||
commands:
|
|
||||||
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -coverprofile=coverage1-1.txt -covermode=atomic"
|
|
||||||
- "go test -v -race -db=\"sqlite3\" -conn_str=\"./test.db\" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-mysql
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- build
|
|
||||||
commands:
|
|
||||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -coverprofile=coverage2-1.txt -covermode=atomic"
|
|
||||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test\" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-mysql-utf8mb4
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- test-mysql
|
|
||||||
commands:
|
|
||||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -coverprofile=coverage2.1-1.txt -covermode=atomic"
|
|
||||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(mysql)/xorm_test?charset=utf8mb4\" -cache=true -coverprofile=coverage2.1-2.txt -covermode=atomic"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-mymysql
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- test-mysql-utf8mb4
|
|
||||||
commands:
|
|
||||||
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -coverprofile=coverage3-1.txt -covermode=atomic"
|
|
||||||
- "go test -v -race -db=\"mymysql\" -conn_str=\"tcp:mysql:3306*xorm_test/root/\" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-postgres
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- build
|
|
||||||
commands:
|
|
||||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -coverprofile=coverage4-1.txt -covermode=atomic"
|
|
||||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-postgres-schema
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- build
|
|
||||||
commands:
|
|
||||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -coverprofile=coverage5-1.txt -covermode=atomic"
|
|
||||||
- "go test -v -race -db=\"postgres\" -conn_str=\"postgres://postgres:@pgsql/xorm_test?sslmode=disable\" -schema=xorm -cache=true -coverprofile=coverage5-2.txt -covermode=atomic"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-mssql
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- build
|
|
||||||
commands:
|
|
||||||
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -coverprofile=coverage6-1.txt -covermode=atomic"
|
|
||||||
- "go test -v -race -db=\"mssql\" -conn_str=\"server=mssql;user id=sa;password=yourStrong(!)Password;database=xorm_test\" -cache=true -coverprofile=coverage6-2.txt -covermode=atomic"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-tidb
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- build
|
|
||||||
commands:
|
|
||||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -coverprofile=coverage7-1.txt -covermode=atomic"
|
|
||||||
- "go test -v -race -db=\"mysql\" -conn_str=\"root:@tcp(tidb:4000)/xorm_test\" -ignore_select_update=true -cache=true -coverprofile=coverage7-2.txt -covermode=atomic"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: test-end
|
|
||||||
pull: default
|
|
||||||
image: golang:1.10
|
|
||||||
depends_on:
|
|
||||||
- test-sqlite
|
|
||||||
- test-mysql
|
|
||||||
- test-mysql-utf8mb4
|
|
||||||
- test-mymysql
|
|
||||||
- test-postgres
|
|
||||||
- test-postgres-schema
|
|
||||||
- test-mssql
|
|
||||||
- test-tidb
|
|
||||||
commands:
|
|
||||||
- echo "go1.10 build end"
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
services:
|
|
||||||
- name: mysql
|
|
||||||
pull: default
|
|
||||||
image: mysql:5.7
|
|
||||||
environment:
|
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
|
||||||
MYSQL_DATABASE: xorm_test
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: pgsql
|
|
||||||
pull: default
|
|
||||||
image: postgres:9.5
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: xorm_test
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: mssql
|
|
||||||
pull: default
|
|
||||||
image: microsoft/mssql-server-linux:latest
|
|
||||||
environment:
|
|
||||||
ACCEPT_EULA: Y
|
|
||||||
SA_PASSWORD: yourStrong(!)Password
|
|
||||||
MSSQL_PID: Developer
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: tidb
|
|
||||||
pull: default
|
|
||||||
image: pingcap/tidb:v3.0.3
|
|
||||||
when:
|
|
||||||
event:
|
|
||||||
- push
|
|
||||||
- tag
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: go1.13-test
|
|
||||||
steps:
|
|
||||||
- name: build
|
|
||||||
pull: default
|
|
||||||
image: golang:1.13
|
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: "on"
|
GO111MODULE: "on"
|
||||||
GOPROXY: "https://goproxy.cn"
|
GOPROXY: "https://goproxy.cn"
|
||||||
commands:
|
commands:
|
||||||
- go build -v
|
|
||||||
- go vet
|
- go vet
|
||||||
when:
|
when:
|
||||||
event:
|
event:
|
||||||
|
@ -207,7 +17,7 @@ steps:
|
||||||
|
|
||||||
- name: test-sqlite
|
- name: test-sqlite
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: "on"
|
GO111MODULE: "on"
|
||||||
GOPROXY: "https://goproxy.cn"
|
GOPROXY: "https://goproxy.cn"
|
||||||
|
@ -221,7 +31,7 @@ steps:
|
||||||
|
|
||||||
- name: test-mysql
|
- name: test-mysql
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: "on"
|
GO111MODULE: "on"
|
||||||
GOPROXY: "https://goproxy.cn"
|
GOPROXY: "https://goproxy.cn"
|
||||||
|
@ -235,7 +45,7 @@ steps:
|
||||||
|
|
||||||
- name: test-mysql-utf8mb4
|
- name: test-mysql-utf8mb4
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
depends_on:
|
depends_on:
|
||||||
- test-mysql
|
- test-mysql
|
||||||
environment:
|
environment:
|
||||||
|
@ -251,7 +61,7 @@ steps:
|
||||||
|
|
||||||
- name: test-mymysql
|
- name: test-mymysql
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
depends_on:
|
depends_on:
|
||||||
- test-mysql-utf8mb4
|
- test-mysql-utf8mb4
|
||||||
environment:
|
environment:
|
||||||
|
@ -267,7 +77,7 @@ steps:
|
||||||
|
|
||||||
- name: test-postgres
|
- name: test-postgres
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: "on"
|
GO111MODULE: "on"
|
||||||
GOPROXY: "https://goproxy.cn"
|
GOPROXY: "https://goproxy.cn"
|
||||||
|
@ -281,7 +91,7 @@ steps:
|
||||||
|
|
||||||
- name: test-postgres-schema
|
- name: test-postgres-schema
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: "on"
|
GO111MODULE: "on"
|
||||||
GOPROXY: "https://goproxy.cn"
|
GOPROXY: "https://goproxy.cn"
|
||||||
|
@ -295,7 +105,7 @@ steps:
|
||||||
|
|
||||||
- name: test-mssql
|
- name: test-mssql
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: "on"
|
GO111MODULE: "on"
|
||||||
GOPROXY: "https://goproxy.cn"
|
GOPROXY: "https://goproxy.cn"
|
||||||
|
@ -309,7 +119,7 @@ steps:
|
||||||
|
|
||||||
- name: test-tidb
|
- name: test-tidb
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: "on"
|
GO111MODULE: "on"
|
||||||
GOPROXY: "https://goproxy.cn"
|
GOPROXY: "https://goproxy.cn"
|
||||||
|
@ -323,12 +133,12 @@ steps:
|
||||||
|
|
||||||
- name: merge_coverage
|
- name: merge_coverage
|
||||||
pull: default
|
pull: default
|
||||||
image: golang:1.13
|
image: golang:1.12
|
||||||
environment:
|
environment:
|
||||||
GO111MODULE: "on"
|
GO111MODULE: "on"
|
||||||
GOPROXY: "https://goproxy.cn"
|
GOPROXY: "https://goproxy.cn"
|
||||||
depends_on:
|
depends_on:
|
||||||
- build
|
- test-vet
|
||||||
- test-sqlite
|
- test-sqlite
|
||||||
- test-mysql
|
- test-mysql
|
||||||
- test-mysql-utf8mb4
|
- test-mysql-utf8mb4
|
||||||
|
|
|
@ -901,7 +901,7 @@ func (db *postgres) TableCheckSql(tableName string) (string, []interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *postgres) ModifyColumnSql(tableName string, col *core.Column) string {
|
func (db *postgres) ModifyColumnSql(tableName string, col *core.Column) string {
|
||||||
if len(db.Schema) == 0 {
|
if len(db.Schema) == 0 || strings.Contains(tableName, ".") {
|
||||||
return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s",
|
return fmt.Sprintf("alter table %s ALTER COLUMN %s TYPE %s",
|
||||||
tableName, col.Name, db.SqlType(col))
|
tableName, col.Name, db.SqlType(col))
|
||||||
}
|
}
|
||||||
|
@ -913,8 +913,8 @@ func (db *postgres) DropIndexSql(tableName string, index *core.Index) string {
|
||||||
quote := db.Quote
|
quote := db.Quote
|
||||||
idxName := index.Name
|
idxName := index.Name
|
||||||
|
|
||||||
tableName = strings.Replace(tableName, `"`, "", -1)
|
tableParts := strings.Split(strings.Replace(tableName, `"`, "", -1), ".")
|
||||||
tableName = strings.Replace(tableName, `.`, "_", -1)
|
tableName = tableParts[len(tableParts)-1]
|
||||||
|
|
||||||
if !strings.HasPrefix(idxName, "UQE_") &&
|
if !strings.HasPrefix(idxName, "UQE_") &&
|
||||||
!strings.HasPrefix(idxName, "IDX_") {
|
!strings.HasPrefix(idxName, "IDX_") {
|
||||||
|
|
|
@ -729,66 +729,7 @@ func (session *Session) insertMapInterface(m map[string]interface{}) (int64, err
|
||||||
args = append(args, m[colName])
|
args = append(args, m[colName])
|
||||||
}
|
}
|
||||||
|
|
||||||
w := builder.NewWriter()
|
return session.insertMap(columns, args)
|
||||||
if session.statement.cond.IsValid() {
|
|
||||||
if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (", session.engine.Quote(tableName))); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := writeStrings(w, append(columns, exprs.colNames...), "`", "`"); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := w.WriteString(") SELECT "); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := session.statement.writeArgs(w, args); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(exprs.args) > 0 {
|
|
||||||
if _, err := w.WriteString(","); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
if err := exprs.writeArgs(w); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := w.WriteString(fmt.Sprintf(" FROM %s WHERE ", session.engine.Quote(tableName))); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := session.statement.cond.WriteTo(w); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qm := strings.Repeat("?,", len(columns))
|
|
||||||
qm = qm[:len(qm)-1]
|
|
||||||
|
|
||||||
if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (`%s`) VALUES (%s)", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
w.Append(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
sql := w.String()
|
|
||||||
args = w.Args()
|
|
||||||
|
|
||||||
if err := session.cacheInsert(tableName); err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
res, err := session.exec(sql, args...)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
affected, err := res.RowsAffected()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return affected, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) insertMapString(m map[string]string) (int64, error) {
|
func (session *Session) insertMapString(m map[string]string) (int64, error) {
|
||||||
|
@ -808,6 +749,7 @@ func (session *Session) insertMapString(m map[string]string) (int64, error) {
|
||||||
columns = append(columns, k)
|
columns = append(columns, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(columns)
|
sort.Strings(columns)
|
||||||
|
|
||||||
var args = make([]interface{}, 0, len(m))
|
var args = make([]interface{}, 0, len(m))
|
||||||
|
@ -815,7 +757,18 @@ func (session *Session) insertMapString(m map[string]string) (int64, error) {
|
||||||
args = append(args, m[colName])
|
args = append(args, m[colName])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return session.insertMap(columns, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (session *Session) insertMap(columns []string, args []interface{}) (int64, error) {
|
||||||
|
tableName := session.statement.TableName()
|
||||||
|
if len(tableName) <= 0 {
|
||||||
|
return 0, ErrTableNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
exprs := session.statement.exprColumns
|
||||||
w := builder.NewWriter()
|
w := builder.NewWriter()
|
||||||
|
// if insert where
|
||||||
if session.statement.cond.IsValid() {
|
if session.statement.cond.IsValid() {
|
||||||
if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (", session.engine.Quote(tableName))); err != nil {
|
if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (", session.engine.Quote(tableName))); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -853,10 +806,29 @@ func (session *Session) insertMapString(m map[string]string) (int64, error) {
|
||||||
qm := strings.Repeat("?,", len(columns))
|
qm := strings.Repeat("?,", len(columns))
|
||||||
qm = qm[:len(qm)-1]
|
qm = qm[:len(qm)-1]
|
||||||
|
|
||||||
if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (`%s`) VALUES (%s)", session.engine.Quote(tableName), strings.Join(columns, "`,`"), qm)); err != nil {
|
if _, err := w.WriteString(fmt.Sprintf("INSERT INTO %s (", session.engine.Quote(tableName))); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := writeStrings(w, append(columns, exprs.colNames...), "`", "`"); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if _, err := w.WriteString(fmt.Sprintf(") VALUES (%s", qm)); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
w.Append(args...)
|
w.Append(args...)
|
||||||
|
if len(exprs.args) > 0 {
|
||||||
|
if _, err := w.WriteString(","); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if err := exprs.writeArgs(w); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := w.WriteString(")"); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sql := w.String()
|
sql := w.String()
|
||||||
|
|
|
@ -239,14 +239,20 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
for i, colName := range exprColumns.colNames {
|
for i, colName := range exprColumns.colNames {
|
||||||
switch tp := exprColumns.args[i].(type) {
|
switch tp := exprColumns.args[i].(type) {
|
||||||
case string:
|
case string:
|
||||||
colNames = append(colNames, session.engine.Quote(colName)+" = "+tp)
|
if len(tp) == 0 {
|
||||||
|
tp = "''"
|
||||||
|
}
|
||||||
|
colNames = append(colNames, session.engine.Quote(colName)+"="+tp)
|
||||||
case *builder.Builder:
|
case *builder.Builder:
|
||||||
subQuery, subArgs, err := builder.ToSQL(tp)
|
subQuery, subArgs, err := builder.ToSQL(tp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
colNames = append(colNames, session.engine.Quote(colName)+" = ("+subQuery+")")
|
colNames = append(colNames, session.engine.Quote(colName)+"=("+subQuery+")")
|
||||||
args = append(args, subArgs...)
|
args = append(args, subArgs...)
|
||||||
|
default:
|
||||||
|
colNames = append(colNames, session.engine.Quote(colName)+"=?")
|
||||||
|
args = append(args, exprColumns.args[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,10 +69,18 @@ func (exprs *exprParams) writeArgs(w *builder.BytesWriter) error {
|
||||||
if _, err := w.WriteString(")"); err != nil {
|
if _, err := w.WriteString(")"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
default:
|
case string:
|
||||||
|
if arg == "" {
|
||||||
|
arg = "''"
|
||||||
|
}
|
||||||
if _, err := w.WriteString(fmt.Sprintf("%v", arg)); err != nil {
|
if _, err := w.WriteString(fmt.Sprintf("%v", arg)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
if _, err := w.WriteString("?"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.Append(arg)
|
||||||
}
|
}
|
||||||
if i != len(exprs.args)-1 {
|
if i != len(exprs.args)-1 {
|
||||||
if _, err := w.WriteString(","); err != nil {
|
if _, err := w.WriteString(","); err != nil {
|
||||||
|
|
Loading…
Reference in New Issue