orm now can specify engine for mysql. add api SetMaxIdleConns/SetMaxOpenConns(go 1.2)
Showing
5 changed files
with
106 additions
and
35 deletions
| ... | @@ -12,17 +12,6 @@ type dbIndex struct { | ... | @@ -12,17 +12,6 @@ type dbIndex struct { |
| 12 | Sql string | 12 | Sql string |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | func getDbAlias(name string) *alias { | ||
| 16 | if al, ok := dataBaseCache.get(name); ok { | ||
| 17 | return al | ||
| 18 | } else { | ||
| 19 | fmt.Println(fmt.Sprintf("unknown DataBase alias name %s", name)) | ||
| 20 | os.Exit(2) | ||
| 21 | } | ||
| 22 | |||
| 23 | return nil | ||
| 24 | } | ||
| 25 | |||
| 26 | func getDbDropSql(al *alias) (sqls []string) { | 15 | func getDbDropSql(al *alias) (sqls []string) { |
| 27 | if len(modelCache.cache) == 0 { | 16 | if len(modelCache.cache) == 0 { |
| 28 | fmt.Println("no Model found, need register your model") | 17 | fmt.Println("no Model found, need register your model") |
| ... | @@ -180,7 +169,14 @@ func getDbCreateSql(al *alias) (sqls []string, tableIndexes map[string][]dbIndex | ... | @@ -180,7 +169,14 @@ func getDbCreateSql(al *alias) (sqls []string, tableIndexes map[string][]dbIndex |
| 180 | sql += "\n)" | 169 | sql += "\n)" |
| 181 | 170 | ||
| 182 | if al.Driver == DR_MySQL { | 171 | if al.Driver == DR_MySQL { |
| 183 | sql += " ENGINE=INNODB" | 172 | var engine string |
| 173 | if mi.model != nil { | ||
| 174 | engine = getTableEngine(mi.addrField) | ||
| 175 | } | ||
| 176 | if engine == "" { | ||
| 177 | engine = al.Engine | ||
| 178 | } | ||
| 179 | sql += " ENGINE=" + engine | ||
| 184 | } | 180 | } |
| 185 | 181 | ||
| 186 | sql += ";" | 182 | sql += ";" | ... | ... |
| ... | @@ -4,11 +4,13 @@ import ( | ... | @@ -4,11 +4,13 @@ import ( |
| 4 | "database/sql" | 4 | "database/sql" |
| 5 | "fmt" | 5 | "fmt" |
| 6 | "os" | 6 | "os" |
| 7 | "reflect" | ||
| 7 | "sync" | 8 | "sync" |
| 8 | "time" | 9 | "time" |
| 9 | ) | 10 | ) |
| 10 | 11 | ||
| 11 | const defaultMaxIdle = 30 | 12 | const defaultMaxIdleConns = 30 |
| 13 | const defaultMaxOpenConns = 50 | ||
| 12 | 14 | ||
| 13 | type DriverType int | 15 | type DriverType int |
| 14 | 16 | ||
| ... | @@ -76,26 +78,36 @@ func (ac *_dbCache) getDefault() (al *alias) { | ... | @@ -76,26 +78,36 @@ func (ac *_dbCache) getDefault() (al *alias) { |
| 76 | } | 78 | } |
| 77 | 79 | ||
| 78 | type alias struct { | 80 | type alias struct { |
| 79 | Name string | 81 | Name string |
| 80 | Driver DriverType | 82 | Driver DriverType |
| 81 | DriverName string | 83 | DriverName string |
| 82 | DataSource string | 84 | DataSource string |
| 83 | MaxIdle int | 85 | MaxIdleConns int |
| 84 | DB *sql.DB | 86 | MaxOpenConns int |
| 85 | DbBaser dbBaser | 87 | DB *sql.DB |
| 86 | TZ *time.Location | 88 | DbBaser dbBaser |
| 89 | TZ *time.Location | ||
| 90 | Engine string | ||
| 87 | } | 91 | } |
| 88 | 92 | ||
| 89 | func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { | 93 | // Setting the database connect params. Use the database driver self dataSource args. |
| 90 | if maxIdle <= 0 { | 94 | func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) { |
| 91 | maxIdle = defaultMaxIdle | 95 | maxIdleConns := defaultMaxIdleConns |
| 96 | maxOpenConns := defaultMaxOpenConns | ||
| 97 | |||
| 98 | for i, v := range params { | ||
| 99 | switch i { | ||
| 100 | case 0: | ||
| 101 | maxIdleConns = v | ||
| 102 | case 1: | ||
| 103 | maxOpenConns = v | ||
| 104 | } | ||
| 92 | } | 105 | } |
| 93 | 106 | ||
| 94 | al := new(alias) | 107 | al := new(alias) |
| 95 | al.Name = name | 108 | al.Name = aliasName |
| 96 | al.DriverName = driverName | 109 | al.DriverName = driverName |
| 97 | al.DataSource = dataSource | 110 | al.DataSource = dataSource |
| 98 | al.MaxIdle = maxIdle | ||
| 99 | 111 | ||
| 100 | var ( | 112 | var ( |
| 101 | err error | 113 | err error |
| ... | @@ -109,19 +121,17 @@ func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { | ... | @@ -109,19 +121,17 @@ func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { |
| 109 | goto end | 121 | goto end |
| 110 | } | 122 | } |
| 111 | 123 | ||
| 112 | if dataBaseCache.add(name, al) == false { | 124 | if dataBaseCache.add(aliasName, al) == false { |
| 113 | err = fmt.Errorf("db name `%s` already registered, cannot reuse", name) | 125 | err = fmt.Errorf("db name `%s` already registered, cannot reuse", aliasName) |
| 114 | goto end | 126 | goto end |
| 115 | } | 127 | } |
| 116 | 128 | ||
| 117 | al.DB, err = sql.Open(driverName, dataSource) | 129 | al.DB, err = sql.Open(driverName, dataSource) |
| 118 | if err != nil { | 130 | if err != nil { |
| 119 | err = fmt.Errorf("register db `%s`, %s", name, err.Error()) | 131 | err = fmt.Errorf("register db `%s`, %s", aliasName, err.Error()) |
| 120 | goto end | 132 | goto end |
| 121 | } | 133 | } |
| 122 | 134 | ||
| 123 | al.DB.SetMaxIdleConns(al.MaxIdle) | ||
| 124 | |||
| 125 | // orm timezone system match database | 135 | // orm timezone system match database |
| 126 | // default use Local | 136 | // default use Local |
| 127 | al.TZ = time.Local | 137 | al.TZ = time.Local |
| ... | @@ -137,8 +147,22 @@ func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { | ... | @@ -137,8 +147,22 @@ func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { |
| 137 | al.TZ = t.Location() | 147 | al.TZ = t.Location() |
| 138 | } | 148 | } |
| 139 | } | 149 | } |
| 150 | |||
| 151 | // get default engine from current database | ||
| 152 | row = al.DB.QueryRow("SELECT ENGINE, TRANSACTIONS FROM information_schema.engines WHERE SUPPORT = 'DEFAULT'") | ||
| 153 | var engine string | ||
| 154 | var tx bool | ||
| 155 | row.Scan(&engine, &tx) | ||
| 156 | |||
| 157 | if engine != "" { | ||
| 158 | al.Engine = engine | ||
| 159 | } else { | ||
| 160 | engine = "INNODB" | ||
| 161 | } | ||
| 162 | |||
| 140 | case DR_Sqlite: | 163 | case DR_Sqlite: |
| 141 | al.TZ = time.UTC | 164 | al.TZ = time.UTC |
| 165 | |||
| 142 | case DR_Postgres: | 166 | case DR_Postgres: |
| 143 | row := al.DB.QueryRow("SELECT current_setting('TIMEZONE')") | 167 | row := al.DB.QueryRow("SELECT current_setting('TIMEZONE')") |
| 144 | var tz string | 168 | var tz string |
| ... | @@ -149,9 +173,12 @@ func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { | ... | @@ -149,9 +173,12 @@ func RegisterDataBase(name, driverName, dataSource string, maxIdle int) { |
| 149 | } | 173 | } |
| 150 | } | 174 | } |
| 151 | 175 | ||
| 176 | SetMaxIdleConns(al.Name, maxIdleConns) | ||
| 177 | SetMaxOpenConns(al.Name, maxOpenConns) | ||
| 178 | |||
| 152 | err = al.DB.Ping() | 179 | err = al.DB.Ping() |
| 153 | if err != nil { | 180 | if err != nil { |
| 154 | err = fmt.Errorf("register db `%s`, %s", name, err.Error()) | 181 | err = fmt.Errorf("register db `%s`, %s", aliasName, err.Error()) |
| 155 | goto end | 182 | goto end |
| 156 | } | 183 | } |
| 157 | 184 | ||
| ... | @@ -162,6 +189,7 @@ end: | ... | @@ -162,6 +189,7 @@ end: |
| 162 | } | 189 | } |
| 163 | } | 190 | } |
| 164 | 191 | ||
| 192 | // Register a database driver use specify driver name, this can be definition the driver is which database type. | ||
| 165 | func RegisterDriver(driverName string, typ DriverType) { | 193 | func RegisterDriver(driverName string, typ DriverType) { |
| 166 | if t, ok := drivers[driverName]; ok == false { | 194 | if t, ok := drivers[driverName]; ok == false { |
| 167 | drivers[driverName] = typ | 195 | drivers[driverName] = typ |
| ... | @@ -173,11 +201,29 @@ func RegisterDriver(driverName string, typ DriverType) { | ... | @@ -173,11 +201,29 @@ func RegisterDriver(driverName string, typ DriverType) { |
| 173 | } | 201 | } |
| 174 | } | 202 | } |
| 175 | 203 | ||
| 176 | func SetDataBaseTZ(name string, tz *time.Location) { | 204 | // Change the database default used timezone |
| 177 | if al, ok := dataBaseCache.get(name); ok { | 205 | func SetDataBaseTZ(aliasName string, tz *time.Location) { |
| 206 | if al, ok := dataBaseCache.get(aliasName); ok { | ||
| 178 | al.TZ = tz | 207 | al.TZ = tz |
| 179 | } else { | 208 | } else { |
| 180 | fmt.Sprintf("DataBase name `%s` not registered\n", name) | 209 | fmt.Sprintf("DataBase name `%s` not registered\n", aliasName) |
| 181 | os.Exit(2) | 210 | os.Exit(2) |
| 182 | } | 211 | } |
| 183 | } | 212 | } |
| 213 | |||
| 214 | // Change the max idle conns for *sql.DB, use specify database alias name | ||
| 215 | func SetMaxIdleConns(aliasName string, maxIdleConns int) { | ||
| 216 | al := getDbAlias(aliasName) | ||
| 217 | al.MaxIdleConns = maxIdleConns | ||
| 218 | al.DB.SetMaxIdleConns(maxIdleConns) | ||
| 219 | } | ||
| 220 | |||
| 221 | // Change the max open conns for *sql.DB, use specify database alias name | ||
| 222 | func SetMaxOpenConns(aliasName string, maxOpenConns int) { | ||
| 223 | al := getDbAlias(aliasName) | ||
| 224 | al.MaxOpenConns = maxOpenConns | ||
| 225 | // for tip go 1.2 | ||
| 226 | if fun := reflect.ValueOf(al.DB).MethodByName("SetMaxOpenConns"); fun.IsValid() { | ||
| 227 | fun.Call([]reflect.Value{reflect.ValueOf(maxOpenConns)}) | ||
| 228 | } | ||
| 229 | } | ... | ... |
| ... | @@ -6,6 +6,15 @@ import ( | ... | @@ -6,6 +6,15 @@ import ( |
| 6 | "time" | 6 | "time" |
| 7 | ) | 7 | ) |
| 8 | 8 | ||
| 9 | func getDbAlias(name string) *alias { | ||
| 10 | if al, ok := dataBaseCache.get(name); ok { | ||
| 11 | return al | ||
| 12 | } else { | ||
| 13 | panic(fmt.Errorf("unknown DataBase alias name %s", name)) | ||
| 14 | } | ||
| 15 | return nil | ||
| 16 | } | ||
| 17 | |||
| 9 | func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interface{}, exist bool) { | 18 | func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interface{}, exist bool) { |
| 10 | fi := mi.fields.pk | 19 | fi := mi.fields.pk |
| 11 | 20 | ... | ... |
| ... | @@ -223,4 +223,10 @@ go test -v github.com/astaxie/beego/orm | ... | @@ -223,4 +223,10 @@ go test -v github.com/astaxie/beego/orm |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, 20) | 225 | RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, 20) |
| 226 | |||
| 227 | alias := getDbAlias("default") | ||
| 228 | if alias.Driver == DR_MySQL { | ||
| 229 | alias.Engine = "INNODB" | ||
| 230 | } | ||
| 231 | |||
| 226 | } | 232 | } | ... | ... |
| ... | @@ -26,6 +26,20 @@ func getTableName(val reflect.Value) string { | ... | @@ -26,6 +26,20 @@ func getTableName(val reflect.Value) string { |
| 26 | return snakeString(ind.Type().Name()) | 26 | return snakeString(ind.Type().Name()) |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | func getTableEngine(val reflect.Value) string { | ||
| 30 | fun := val.MethodByName("TableEngine") | ||
| 31 | if fun.IsValid() { | ||
| 32 | vals := fun.Call([]reflect.Value{}) | ||
| 33 | if len(vals) > 0 { | ||
| 34 | val := vals[0] | ||
| 35 | if val.Kind() == reflect.String { | ||
| 36 | return val.String() | ||
| 37 | } | ||
| 38 | } | ||
| 39 | } | ||
| 40 | return "" | ||
| 41 | } | ||
| 42 | |||
| 29 | func getTableIndex(val reflect.Value) [][]string { | 43 | func getTableIndex(val reflect.Value) [][]string { |
| 30 | fun := val.MethodByName("TableIndex") | 44 | fun := val.MethodByName("TableIndex") |
| 31 | if fun.IsValid() { | 45 | if fun.IsValid() { | ... | ... |
-
Please register or sign in to post a comment