diff --git a/object/adapter.go b/object/adapter.go index 774b8e8f..76ed6b21 100644 --- a/object/adapter.go +++ b/object/adapter.go @@ -151,7 +151,7 @@ func (adapter *Adapter) InitAdapter() error { if adapter.Adapter == nil { var dataSourceName string - if adapter.builtInAdapter() { + if adapter.isBuiltIn() { dataSourceName = conf.GetConfigString("dataSourceName") if adapter.DatabaseType == "mysql" { dataSourceName = dataSourceName + adapter.Database @@ -183,6 +183,14 @@ func (adapter *Adapter) InitAdapter() error { var err error engine, err := xorm.NewEngine(adapter.DatabaseType, dataSourceName) + + if adapter.isBuiltIn() && adapter.DatabaseType == "postgres" { + schema := util.GetValueFromDataSourceName("search_path", dataSourceName) + if schema != "" { + engine.SetSchema(schema) + } + } + adapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(engine, adapter.getTable(), adapter.TableNamePrefix) if err != nil { return err @@ -211,7 +219,7 @@ func adapterChangeTrigger(oldName string, newName string) error { return session.Commit() } -func (adapter *Adapter) builtInAdapter() bool { +func (adapter *Adapter) isBuiltIn() bool { if adapter.Owner != "built-in" { return false } diff --git a/object/ormer.go b/object/ormer.go index 63900415..87d27a8e 100644 --- a/object/ormer.go +++ b/object/ormer.go @@ -155,6 +155,21 @@ func createDatabaseForPostgres(driverName string, dataSourceName string, dbName return err } } + schema := util.GetValueFromDataSourceName("search_path", dataSourceName) + if schema != "" { + db, err = sql.Open(driverName, dataSourceName) + if err != nil { + return err + } + defer db.Close() + + _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s;", schema)) + if err != nil { + if !strings.Contains(err.Error(), "already exists") { + return err + } + } + } return nil } else { @@ -187,6 +202,12 @@ func (a *Ormer) open() { if err != nil { panic(err) } + if a.driverName == "postgres" { + schema := util.GetValueFromDataSourceName("search_path", dataSourceName) + if schema != "" { + engine.SetSchema(schema) + } + } a.Engine = engine } diff --git a/object/permission_enforcer.go b/object/permission_enforcer.go index 68a41f88..e15ee5ce 100644 --- a/object/permission_enforcer.go +++ b/object/permission_enforcer.go @@ -79,9 +79,7 @@ func (p *Permission) setEnforcerAdapter(enforcer *casbin.Enforcer) error { } } tableNamePrefix := conf.GetConfigString("tableNamePrefix") - driverName := conf.GetConfigString("driverName") - dataSourceName := conf.GetConfigRealDataSourceName(driverName) - adapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true) + adapter, err := xormadapter.NewAdapterByEngineWithTableName(ormer.Engine, tableName, tableNamePrefix) if err != nil { return err } diff --git a/util/string.go b/util/string.go index d173b563..e3eb8843 100644 --- a/util/string.go +++ b/util/string.go @@ -23,6 +23,7 @@ import ( "math/rand" "os" "path/filepath" + "regexp" "strconv" "strings" "time" @@ -315,3 +316,13 @@ func ParseIdToString(input interface{}) (string, error) { return "", fmt.Errorf("unsupported id type: %T", input) } } + +func GetValueFromDataSourceName(key string, dataSourceName string) string { + reg := regexp.MustCompile(key + "=([^ ]+)") + matches := reg.FindStringSubmatch(dataSourceName) + if len(matches) >= 2 { + return matches[1] + } + + return "" +} diff --git a/web/src/PlanEditPage.js b/web/src/PlanEditPage.js index b3ec9dd1..e96abad3 100644 --- a/web/src/PlanEditPage.js +++ b/web/src/PlanEditPage.js @@ -210,15 +210,13 @@ class PlanEditPage extends React.Component { {Setting.getLabel(i18next.t("plan:Period"), i18next.t("plan:Period - Tooltip"))} :