feat: support to use a different db schema for pg (#2281)

This commit is contained in:
Tower He 2023-09-01 18:00:17 +08:00 committed by Yang Luo
parent 0c7b911ce7
commit bbf2db2e00
5 changed files with 50 additions and 14 deletions

View File

@ -151,7 +151,7 @@ func (adapter *Adapter) InitAdapter() error {
if adapter.Adapter == nil { if adapter.Adapter == nil {
var dataSourceName string var dataSourceName string
if adapter.builtInAdapter() { if adapter.isBuiltIn() {
dataSourceName = conf.GetConfigString("dataSourceName") dataSourceName = conf.GetConfigString("dataSourceName")
if adapter.DatabaseType == "mysql" { if adapter.DatabaseType == "mysql" {
dataSourceName = dataSourceName + adapter.Database dataSourceName = dataSourceName + adapter.Database
@ -183,6 +183,14 @@ func (adapter *Adapter) InitAdapter() error {
var err error var err error
engine, err := xorm.NewEngine(adapter.DatabaseType, dataSourceName) 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) adapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(engine, adapter.getTable(), adapter.TableNamePrefix)
if err != nil { if err != nil {
return err return err
@ -211,7 +219,7 @@ func adapterChangeTrigger(oldName string, newName string) error {
return session.Commit() return session.Commit()
} }
func (adapter *Adapter) builtInAdapter() bool { func (adapter *Adapter) isBuiltIn() bool {
if adapter.Owner != "built-in" { if adapter.Owner != "built-in" {
return false return false
} }

View File

@ -155,6 +155,21 @@ func createDatabaseForPostgres(driverName string, dataSourceName string, dbName
return err 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 return nil
} else { } else {
@ -187,6 +202,12 @@ func (a *Ormer) open() {
if err != nil { if err != nil {
panic(err) panic(err)
} }
if a.driverName == "postgres" {
schema := util.GetValueFromDataSourceName("search_path", dataSourceName)
if schema != "" {
engine.SetSchema(schema)
}
}
a.Engine = engine a.Engine = engine
} }

View File

@ -79,9 +79,7 @@ func (p *Permission) setEnforcerAdapter(enforcer *casbin.Enforcer) error {
} }
} }
tableNamePrefix := conf.GetConfigString("tableNamePrefix") tableNamePrefix := conf.GetConfigString("tableNamePrefix")
driverName := conf.GetConfigString("driverName") adapter, err := xormadapter.NewAdapterByEngineWithTableName(ormer.Engine, tableName, tableNamePrefix)
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
adapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
if err != nil { if err != nil {
return err return err
} }

View File

@ -23,6 +23,7 @@ import (
"math/rand" "math/rand"
"os" "os"
"path/filepath" "path/filepath"
"regexp"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -315,3 +316,13 @@ func ParseIdToString(input interface{}) (string, error) {
return "", fmt.Errorf("unsupported id type: %T", input) 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 ""
}

View File

@ -210,15 +210,13 @@ class PlanEditPage extends React.Component {
{Setting.getLabel(i18next.t("plan:Period"), i18next.t("plan:Period - Tooltip"))} : {Setting.getLabel(i18next.t("plan:Period"), i18next.t("plan:Period - Tooltip"))} :
</Col> </Col>
<Col span={22} > <Col span={22} >
<Select <Select virtual={false} style={{width: "100%"}} value={this.state.plan.period} onChange={value => {
defaultValue={this.state.plan.period === "" ? "Monthly" : this.state.plan.period} this.updatePlanField("period", value);
onChange={value => { }}
this.updatePlanField("period", value); options={[
}} {value: "Monthly", label: "Monthly"},
options={[ {value: "Yearly", label: "Yearly"},
{value: "Monthly", label: "Monthly"}, ]}
{value: "Yearly", label: "Yearly"},
]}
/> />
</Col> </Col>
</Row> </Row>