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
					
				
					 28 changed files with 177 additions and 407 deletions
				
			
		
							
								
								
									
										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}} | ||||||
|  |  | ||||||
							
								
								
									
										5
									
								
								templates/install.tmpl
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								templates/install.tmpl
									
									
									
									
										vendored
									
									
								
							|  | @ -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}}"> | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							|  | @ -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 | ||||||
|  |  | ||||||
							
								
								
									
										120
									
								
								vendor/xorm.io/core/.drone.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										120
									
								
								vendor/xorm.io/core/.drone.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -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 | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								vendor/xorm.io/core/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/xorm.io/core/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -1,7 +1,7 @@ | ||||||
| Core is a lightweight wrapper of sql.DB. | Core is a lightweight wrapper of sql.DB. | ||||||
| 
 | 
 | ||||||
| [](https://drone.gitea.com/xorm/core) | [](https://drone.gitea.com/xorm/core) | ||||||
| [](http://gocover.io/xorm.io/core) | [](https://gocover.io/xorm.io/core) | ||||||
| [](https://goreportcard.com/report/xorm.io/core) | [](https://goreportcard.com/report/xorm.io/core) | ||||||
| 
 | 
 | ||||||
| # Open | # Open | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								vendor/xorm.io/core/column.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/xorm.io/core/column.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -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:         "", | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								vendor/xorm.io/core/index.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/xorm.io/core/index.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -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) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
							
								
								
									
										216
									
								
								vendor/xorm.io/xorm/.drone.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										216
									
								
								vendor/xorm.io/xorm/.drone.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -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 | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								vendor/xorm.io/xorm/dialect_postgres.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/xorm.io/xorm/dialect_postgres.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -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_") { | ||||||
|  |  | ||||||
							
								
								
									
										94
									
								
								vendor/xorm.io/xorm/session_insert.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										94
									
								
								vendor/xorm.io/xorm/session_insert.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -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() | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								vendor/xorm.io/xorm/session_update.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/xorm.io/xorm/session_update.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -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]) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								vendor/xorm.io/xorm/statement_exprparam.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/xorm.io/xorm/statement_exprparam.go
									
									
									
										generated
									
									
										vendored
									
									
								
							|  | @ -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 a new issue