mirror of
https://github.com/astaxie/beego.git
synced 2024-12-23 01:00:50 +00:00
orm support auto create db
This commit is contained in:
parent
1fedaf21ec
commit
c38abf35da
144
orm/cmd.go
Normal file
144
orm/cmd.go
Normal file
@ -0,0 +1,144 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type commander interface {
|
||||
Parse([]string)
|
||||
Run()
|
||||
}
|
||||
|
||||
var (
|
||||
commands = make(map[string]commander)
|
||||
)
|
||||
|
||||
func printHelp(errs ...string) {
|
||||
content := `orm command usage:
|
||||
|
||||
syncdb - auto create tables
|
||||
sqlall - print sql of create tables
|
||||
help - print this help
|
||||
`
|
||||
|
||||
if len(errs) > 0 {
|
||||
fmt.Println(errs[0])
|
||||
}
|
||||
fmt.Println(content)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
func RunCommand() {
|
||||
if len(os.Args) < 2 || os.Args[1] != "orm" {
|
||||
return
|
||||
}
|
||||
|
||||
BootStrap()
|
||||
|
||||
args := argString(os.Args[2:])
|
||||
name := args.Get(0)
|
||||
|
||||
if name == "help" {
|
||||
printHelp()
|
||||
}
|
||||
|
||||
if cmd, ok := commands[name]; ok {
|
||||
cmd.Parse(os.Args[3:])
|
||||
cmd.Run()
|
||||
os.Exit(0)
|
||||
} else {
|
||||
if name == "" {
|
||||
printHelp()
|
||||
} else {
|
||||
printHelp(fmt.Sprintf("unknown command %s", name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type commandSyncDb struct {
|
||||
al *alias
|
||||
force bool
|
||||
verbose bool
|
||||
}
|
||||
|
||||
func (d *commandSyncDb) Parse(args []string) {
|
||||
var name string
|
||||
|
||||
flagSet := flag.NewFlagSet("orm command: syncdb", flag.ExitOnError)
|
||||
flagSet.StringVar(&name, "db", "default", "DataBase alias name")
|
||||
flagSet.BoolVar(&d.force, "force", false, "drop tables before create")
|
||||
flagSet.BoolVar(&d.verbose, "v", false, "verbose info")
|
||||
flagSet.Parse(args)
|
||||
|
||||
d.al = getDbAlias(name)
|
||||
}
|
||||
|
||||
func (d *commandSyncDb) Run() {
|
||||
var drops []string
|
||||
if d.force {
|
||||
drops = getDbDropSql(d.al)
|
||||
}
|
||||
|
||||
db := d.al.DB
|
||||
|
||||
if d.force {
|
||||
for i, mi := range modelCache.allOrdered() {
|
||||
query := drops[i]
|
||||
_, err := db.Exec(query)
|
||||
result := ""
|
||||
if err != nil {
|
||||
result = err.Error()
|
||||
}
|
||||
fmt.Printf("drop table `%s` %s\n", mi.table, result)
|
||||
if d.verbose {
|
||||
fmt.Printf(" %s\n\n", query)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tables := getDbCreateSql(d.al)
|
||||
|
||||
for i, mi := range modelCache.allOrdered() {
|
||||
query := tables[i]
|
||||
_, err := db.Exec(query)
|
||||
fmt.Printf("create table `%s` \n", mi.table)
|
||||
if d.verbose {
|
||||
query = " " + strings.Join(strings.Split(query, "\n"), "\n ")
|
||||
fmt.Println(query)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Printf(" %s\n", err.Error())
|
||||
}
|
||||
if d.verbose {
|
||||
fmt.Println("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type commandSqlAll struct {
|
||||
al *alias
|
||||
}
|
||||
|
||||
func (d *commandSqlAll) Parse(args []string) {
|
||||
var name string
|
||||
|
||||
flagSet := flag.NewFlagSet("orm command: sqlall", flag.ExitOnError)
|
||||
flagSet.StringVar(&name, "db", "default", "DataBase alias name")
|
||||
flagSet.Parse(args)
|
||||
|
||||
d.al = getDbAlias(name)
|
||||
}
|
||||
|
||||
func (d *commandSqlAll) Run() {
|
||||
sqls := getDbCreateSql(d.al)
|
||||
sql := strings.Join(sqls, "\n\n")
|
||||
fmt.Println(sql)
|
||||
}
|
||||
|
||||
func init() {
|
||||
commands["syncdb"] = new(commandSyncDb)
|
||||
commands["sqlall"] = new(commandSqlAll)
|
||||
}
|
142
orm/cmd_utils.go
Normal file
142
orm/cmd_utils.go
Normal file
@ -0,0 +1,142 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func getDbAlias(name string) *alias {
|
||||
if al, ok := dataBaseCache.get(name); ok {
|
||||
return al
|
||||
} else {
|
||||
fmt.Println(fmt.Sprintf("unknown DataBase alias name %s", name))
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDbDropSql(al *alias) (sqls []string) {
|
||||
if len(modelCache.cache) == 0 {
|
||||
fmt.Println("no Model found, need register your model")
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
Q := al.DbBaser.TableQuote()
|
||||
|
||||
for _, mi := range modelCache.allOrdered() {
|
||||
sqls = append(sqls, fmt.Sprintf(`DROP TABLE IF EXISTS %s%s%s`, Q, mi.table, Q))
|
||||
}
|
||||
return sqls
|
||||
}
|
||||
|
||||
func getDbCreateSql(al *alias) (sqls []string) {
|
||||
if len(modelCache.cache) == 0 {
|
||||
fmt.Println("no Model found, need register your model")
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
Q := al.DbBaser.TableQuote()
|
||||
T := al.DbBaser.DbTypes()
|
||||
|
||||
for _, mi := range modelCache.allOrdered() {
|
||||
sql := fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
|
||||
sql += fmt.Sprintf("-- Table Structure for `%s`\n", mi.fullName)
|
||||
sql += fmt.Sprintf("-- %s\n", strings.Repeat("-", 50))
|
||||
|
||||
sql += fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s%s%s (\n", Q, mi.table, Q)
|
||||
|
||||
columns := make([]string, 0, len(mi.fields.fieldsDB))
|
||||
|
||||
for _, fi := range mi.fields.fieldsDB {
|
||||
|
||||
fieldType := fi.fieldType
|
||||
column := fmt.Sprintf(" %s%s%s ", Q, fi.column, Q)
|
||||
col := ""
|
||||
|
||||
checkColumn:
|
||||
switch fieldType {
|
||||
case TypeBooleanField:
|
||||
col = T["bool"]
|
||||
case TypeCharField:
|
||||
col = fmt.Sprintf(T["string"], fi.size)
|
||||
case TypeTextField:
|
||||
col = T["string-text"]
|
||||
case TypeDateField:
|
||||
col = T["time.Time-date"]
|
||||
case TypeDateTimeField:
|
||||
col = T["time.Time"]
|
||||
case TypeBitField:
|
||||
col = T["int8"]
|
||||
case TypeSmallIntegerField:
|
||||
col = T["int16"]
|
||||
case TypeIntegerField:
|
||||
col = T["int32"]
|
||||
case TypeBigIntegerField:
|
||||
if al.Driver == DR_Sqlite {
|
||||
fieldType = TypeIntegerField
|
||||
goto checkColumn
|
||||
}
|
||||
col = T["int64"]
|
||||
case TypePositiveBitField:
|
||||
col = T["uint8"]
|
||||
case TypePositiveSmallIntegerField:
|
||||
col = T["uint16"]
|
||||
case TypePositiveIntegerField:
|
||||
col = T["uint32"]
|
||||
case TypePositiveBigIntegerField:
|
||||
col = T["uint64"]
|
||||
case TypeFloatField:
|
||||
col = T["float64"]
|
||||
case TypeDecimalField:
|
||||
s := T["float64-decimal"]
|
||||
if strings.Index(s, "%d") == -1 {
|
||||
col = s
|
||||
} else {
|
||||
col = fmt.Sprintf(s, fi.digits, fi.decimals)
|
||||
}
|
||||
case RelForeignKey, RelOneToOne:
|
||||
fieldType = fi.relModelInfo.fields.pk.fieldType
|
||||
goto checkColumn
|
||||
}
|
||||
|
||||
if fi.auto {
|
||||
if al.Driver == DR_Postgres {
|
||||
column += T["auto"]
|
||||
} else {
|
||||
column += col + " " + T["auto"]
|
||||
}
|
||||
} else if fi.pk {
|
||||
column += col + " " + T["pk"]
|
||||
} else {
|
||||
column += col
|
||||
|
||||
if fi.null == false {
|
||||
column += " " + "NOT NULL"
|
||||
}
|
||||
|
||||
if fi.unique {
|
||||
column += " " + "UNIQUE"
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Index(column, "%COL%") != -1 {
|
||||
column = strings.Replace(column, "%COL%", fi.column, -1)
|
||||
}
|
||||
|
||||
columns = append(columns, column)
|
||||
}
|
||||
|
||||
sql += strings.Join(columns, ",\n")
|
||||
sql += "\n)"
|
||||
|
||||
if al.Driver == DR_MySQL {
|
||||
sql += " ENGINE=INNODB"
|
||||
}
|
||||
|
||||
sqls = append(sqls, sql)
|
||||
}
|
||||
|
||||
return sqls
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func printHelp() {
|
||||
|
||||
}
|
||||
|
||||
func getSqlAll() (sql string) {
|
||||
for _, mi := range modelCache.allOrdered() {
|
||||
_ = mi
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func runCommand() {
|
||||
if len(os.Args) < 2 || os.Args[1] != "orm" {
|
||||
return
|
||||
}
|
||||
|
||||
_ = flag.NewFlagSet("orm command", flag.ExitOnError)
|
||||
|
||||
args := argString(os.Args[2:])
|
||||
cmd := args.Get(0)
|
||||
|
||||
switch cmd {
|
||||
case "syncdb":
|
||||
case "sqlall":
|
||||
sql := getSqlAll()
|
||||
fmt.Println(sql)
|
||||
default:
|
||||
if cmd != "" {
|
||||
fmt.Printf("unknown command %s", cmd)
|
||||
} else {
|
||||
printHelp()
|
||||
}
|
||||
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
@ -805,7 +805,7 @@ setValue:
|
||||
_, err = str.Int32()
|
||||
case TypeBigIntegerField:
|
||||
_, err = str.Int64()
|
||||
case TypePostiveBitField:
|
||||
case TypePositiveBitField:
|
||||
_, err = str.Uint8()
|
||||
case TypePositiveSmallIntegerField:
|
||||
_, err = str.Uint16()
|
||||
@ -1112,3 +1112,7 @@ func (d *dbBase) TimeFromDB(t *time.Time, tz *time.Location) {
|
||||
func (d *dbBase) TimeToDB(t *time.Time, tz *time.Location) {
|
||||
*t = t.In(tz)
|
||||
}
|
||||
|
||||
func (d *dbBase) DbTypes() map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
@ -17,6 +17,26 @@ var mysqlOperators = map[string]string{
|
||||
"iendswith": "LIKE ?",
|
||||
}
|
||||
|
||||
var mysqlTypes = map[string]string{
|
||||
"auto": "AUTO_INCREMENT NOT NULL PRIMARY KEY",
|
||||
"pk": "NOT NULL PRIMARY KEY",
|
||||
"bool": "bool",
|
||||
"string": "varchar(%d)",
|
||||
"string-text": "longtext",
|
||||
"time.Time-date": "date",
|
||||
"time.Time": "datetime",
|
||||
"int8": "tinyint",
|
||||
"int16": "smallint",
|
||||
"int32": "integer",
|
||||
"int64": "bigint",
|
||||
"uint8": "tinyint unsigned",
|
||||
"uint16": "smallint unsigned",
|
||||
"uint32": "integer unsigned",
|
||||
"uint64": "bigint unsigned",
|
||||
"float64": "double precision",
|
||||
"float64-decimal": "numeric(%d, %d)",
|
||||
}
|
||||
|
||||
type dbBaseMysql struct {
|
||||
dbBase
|
||||
}
|
||||
@ -27,6 +47,10 @@ func (d *dbBaseMysql) OperatorSql(operator string) string {
|
||||
return mysqlOperators[operator]
|
||||
}
|
||||
|
||||
func (d *dbBaseMysql) DbTypes() map[string]string {
|
||||
return mysqlTypes
|
||||
}
|
||||
|
||||
func newdbBaseMysql() dbBaser {
|
||||
b := new(dbBaseMysql)
|
||||
b.ins = b
|
||||
|
@ -20,6 +20,26 @@ var postgresOperators = map[string]string{
|
||||
"iendswith": "LIKE UPPER(?)",
|
||||
}
|
||||
|
||||
var postgresTypes = map[string]string{
|
||||
"auto": "serial NOT NULL PRIMARY KEY",
|
||||
"pk": "NOT NULL PRIMARY KEY",
|
||||
"bool": "bool",
|
||||
"string": "varchar(%d)",
|
||||
"string-text": "text",
|
||||
"time.Time-date": "date",
|
||||
"time.Time": "timestamp with time zone",
|
||||
"int8": `smallint CHECK("%COL%" >= -127 AND "%COL%" <= 128)`,
|
||||
"int16": "smallint",
|
||||
"int32": "integer",
|
||||
"int64": "bigint",
|
||||
"uint8": `smallint CHECK("%COL%" >= 0 AND "%COL%" <= 255)`,
|
||||
"uint16": `integer CHECK("%COL%" >= 0)`,
|
||||
"uint32": `bigint CHECK("%COL%" >= 0)`,
|
||||
"uint64": `bigint CHECK("%COL%" >= 0)`,
|
||||
"float64": "double precision",
|
||||
"float64-decimal": "numeric(%d, %d)",
|
||||
}
|
||||
|
||||
type dbBasePostgres struct {
|
||||
dbBase
|
||||
}
|
||||
@ -87,6 +107,10 @@ func (d *dbBasePostgres) HasReturningID(mi *modelInfo, query *string) (has bool)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *dbBasePostgres) DbTypes() map[string]string {
|
||||
return postgresTypes
|
||||
}
|
||||
|
||||
func newdbBasePostgres() dbBaser {
|
||||
b := new(dbBasePostgres)
|
||||
b.ins = b
|
||||
|
@ -19,6 +19,26 @@ var sqliteOperators = map[string]string{
|
||||
"iendswith": "LIKE ? ESCAPE '\\'",
|
||||
}
|
||||
|
||||
var sqliteTypes = map[string]string{
|
||||
"auto": "NOT NULL PRIMARY KEY AUTOINCREMENT",
|
||||
"pk": "NOT NULL PRIMARY KEY",
|
||||
"bool": "bool",
|
||||
"string": "varchar(%d)",
|
||||
"string-text": "text",
|
||||
"time.Time-date": "date",
|
||||
"time.Time": "datetime",
|
||||
"int8": "tinyint",
|
||||
"int16": "smallint",
|
||||
"int32": "integer",
|
||||
"int64": "bigint",
|
||||
"uint8": "tinyint unsigned",
|
||||
"uint16": "smallint unsigned",
|
||||
"uint32": "integer unsigned",
|
||||
"uint64": "bigint unsigned",
|
||||
"float64": "real",
|
||||
"float64-decimal": "decimal",
|
||||
}
|
||||
|
||||
type dbBaseSqlite struct {
|
||||
dbBase
|
||||
}
|
||||
@ -43,6 +63,10 @@ func (d *dbBaseSqlite) MaxLimit() uint64 {
|
||||
return 9223372036854775807
|
||||
}
|
||||
|
||||
func (d *dbBaseSqlite) DbTypes() map[string]string {
|
||||
return sqliteTypes
|
||||
}
|
||||
|
||||
func newdbBaseSqlite() dbBaser {
|
||||
b := new(dbBaseSqlite)
|
||||
b.ins = b
|
||||
|
@ -84,3 +84,10 @@ func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo {
|
||||
}
|
||||
return mii
|
||||
}
|
||||
|
||||
func (mc *_modelCache) clean() {
|
||||
mc.orders = make([]string, 0)
|
||||
mc.cache = make(map[string]*modelInfo)
|
||||
mc.cacheByFN = make(map[string]*modelInfo)
|
||||
mc.done = false
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func registerModel(model interface{}) {
|
||||
func registerModel(model interface{}, prefix string) {
|
||||
val := reflect.ValueOf(model)
|
||||
ind := reflect.Indirect(val)
|
||||
typ := ind.Type()
|
||||
@ -17,20 +17,25 @@ func registerModel(model interface{}) {
|
||||
panic(fmt.Sprintf("<orm.RegisterModel> cannot use non-ptr model struct `%s`", getFullName(typ)))
|
||||
}
|
||||
|
||||
info := newModelInfo(val)
|
||||
table := getTableName(val)
|
||||
|
||||
if prefix != "" {
|
||||
table = prefix + table
|
||||
}
|
||||
|
||||
name := getFullName(typ)
|
||||
if _, ok := modelCache.getByFN(name); ok {
|
||||
fmt.Printf("<orm.RegisterModel> model `%s` redeclared, must be unique\n", name)
|
||||
fmt.Printf("<orm.RegisterModel> model `%s` repeat register, must be unique\n", name)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
table := getTableName(val)
|
||||
if _, ok := modelCache.get(table); ok {
|
||||
fmt.Printf("<orm.RegisterModel> table name `%s` redeclared, must be unique\n", table)
|
||||
fmt.Printf("<orm.RegisterModel> table name `%s` repeat register, must be unique\n", table)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
info := newModelInfo(val)
|
||||
|
||||
if info.fields.pk == nil {
|
||||
outFor:
|
||||
for _, fi := range info.fields.fieldsDB {
|
||||
@ -58,6 +63,7 @@ func registerModel(model interface{}) {
|
||||
info.pkg = typ.PkgPath()
|
||||
info.model = model
|
||||
info.manual = true
|
||||
|
||||
modelCache.set(table, info)
|
||||
}
|
||||
|
||||
@ -72,7 +78,7 @@ func bootStrap() {
|
||||
)
|
||||
|
||||
if dataBaseCache.getDefault() == nil {
|
||||
err = fmt.Errorf("must have one register alias named `default`")
|
||||
err = fmt.Errorf("must have one register DataBase alias named `default`")
|
||||
goto end
|
||||
}
|
||||
|
||||
@ -97,7 +103,7 @@ func bootStrap() {
|
||||
switch fi.fieldType {
|
||||
case RelManyToMany:
|
||||
if fi.relThrough != "" {
|
||||
msg := fmt.Sprintf("filed `%s` wrong rel_through value `%s`", fi.fullName, fi.relThrough)
|
||||
msg := fmt.Sprintf("field `%s` wrong rel_through value `%s`", fi.fullName, fi.relThrough)
|
||||
if i := strings.LastIndex(fi.relThrough, "."); i != -1 && len(fi.relThrough) > (i+1) {
|
||||
pn := fi.relThrough[:i]
|
||||
mn := fi.relThrough[i+1:]
|
||||
@ -238,11 +244,22 @@ end:
|
||||
|
||||
func RegisterModel(models ...interface{}) {
|
||||
if modelCache.done {
|
||||
panic(fmt.Errorf("RegisterModel must be run begore BootStrap"))
|
||||
panic(fmt.Errorf("RegisterModel must be run before BootStrap"))
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
registerModel(model)
|
||||
registerModel(model, "")
|
||||
}
|
||||
}
|
||||
|
||||
// register model with a prefix
|
||||
func RegisterModelWithPrefix(prefix string, models ...interface{}) {
|
||||
if modelCache.done {
|
||||
panic(fmt.Errorf("RegisterModel must be run before BootStrap"))
|
||||
}
|
||||
|
||||
for _, model := range models {
|
||||
registerModel(model, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ const (
|
||||
// int64
|
||||
TypeBigIntegerField
|
||||
// uint8
|
||||
TypePostiveBitField
|
||||
TypePositiveBitField
|
||||
// uint16
|
||||
TypePositiveSmallIntegerField
|
||||
// uint32
|
||||
|
@ -399,7 +399,7 @@ checkType:
|
||||
_, err = v.Int32()
|
||||
case TypeBigIntegerField:
|
||||
_, err = v.Int64()
|
||||
case TypePostiveBitField:
|
||||
case TypePositiveBitField:
|
||||
_, err = v.Uint8()
|
||||
case TypePositiveSmallIntegerField:
|
||||
_, err = v.Uint16()
|
||||
|
@ -90,6 +90,9 @@ func newM2MModelInfo(m1, m2 *modelInfo) (info *modelInfo) {
|
||||
fa.auto = true
|
||||
fa.pk = true
|
||||
fa.dbcol = true
|
||||
fa.name = "Id"
|
||||
fa.column = "id"
|
||||
fa.fullName = info.fullName + "." + fa.name
|
||||
|
||||
f1.dbcol = true
|
||||
f2.dbcol = true
|
||||
|
@ -3,10 +3,8 @@ package orm
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
// _ "github.com/bylevel/pq"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
@ -153,325 +151,7 @@ var (
|
||||
|
||||
var dORM Ormer
|
||||
|
||||
var initSQLs = map[string]string{
|
||||
"mysql": "DROP TABLE IF EXISTS `user_profile`;\n" +
|
||||
"DROP TABLE IF EXISTS `user`;\n" +
|
||||
"DROP TABLE IF EXISTS `post`;\n" +
|
||||
"DROP TABLE IF EXISTS `tag`;\n" +
|
||||
"DROP TABLE IF EXISTS `post_tags`;\n" +
|
||||
"DROP TABLE IF EXISTS `comment`;\n" +
|
||||
"DROP TABLE IF EXISTS `data`;\n" +
|
||||
"DROP TABLE IF EXISTS `data_null`;\n" +
|
||||
"CREATE TABLE `user_profile` (\n" +
|
||||
" `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
|
||||
" `age` smallint NOT NULL,\n" +
|
||||
" `money` double precision NOT NULL\n" +
|
||||
") ENGINE=INNODB;\n" +
|
||||
"CREATE TABLE `user` (\n" +
|
||||
" `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
|
||||
" `user_name` varchar(30) NOT NULL UNIQUE,\n" +
|
||||
" `email` varchar(100) NOT NULL,\n" +
|
||||
" `password` varchar(100) NOT NULL,\n" +
|
||||
" `status` smallint NOT NULL,\n" +
|
||||
" `is_staff` bool NOT NULL,\n" +
|
||||
" `is_active` bool NOT NULL,\n" +
|
||||
" `created` date NOT NULL,\n" +
|
||||
" `updated` datetime NOT NULL,\n" +
|
||||
" `profile_id` integer\n" +
|
||||
") ENGINE=INNODB;\n" +
|
||||
"CREATE TABLE `post` (\n" +
|
||||
" `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
|
||||
" `user_id` integer NOT NULL,\n" +
|
||||
" `title` varchar(60) NOT NULL,\n" +
|
||||
" `content` longtext NOT NULL,\n" +
|
||||
" `created` datetime NOT NULL,\n" +
|
||||
" `updated` datetime NOT NULL\n" +
|
||||
") ENGINE=INNODB;\n" +
|
||||
"CREATE TABLE `tag` (\n" +
|
||||
" `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
|
||||
" `name` varchar(30) NOT NULL\n" +
|
||||
") ENGINE=INNODB;\n" +
|
||||
"CREATE TABLE `post_tags` (\n" +
|
||||
" `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
|
||||
" `post_id` integer NOT NULL,\n" +
|
||||
" `tag_id` integer NOT NULL,\n" +
|
||||
" UNIQUE (`post_id`, `tag_id`)\n" +
|
||||
") ENGINE=INNODB;\n" +
|
||||
"CREATE TABLE `comment` (\n" +
|
||||
" `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
|
||||
" `post_id` integer NOT NULL,\n" +
|
||||
" `content` longtext NOT NULL,\n" +
|
||||
" `parent_id` integer,\n" +
|
||||
" `created` datetime NOT NULL\n" +
|
||||
") ENGINE=INNODB;\n" +
|
||||
"CREATE TABLE `data` (\n" +
|
||||
" `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
|
||||
" `boolean` bool NOT NULL,\n" +
|
||||
" `char` varchar(50) NOT NULL,\n" +
|
||||
" `text` longtext NOT NULL,\n" +
|
||||
" `date` date NOT NULL,\n" +
|
||||
" `date_time` datetime NOT NULL,\n" +
|
||||
" `byte` tinyint unsigned NOT NULL,\n" +
|
||||
" `rune` integer NOT NULL,\n" +
|
||||
" `int` integer NOT NULL,\n" +
|
||||
" `int8` tinyint NOT NULL,\n" +
|
||||
" `int16` smallint NOT NULL,\n" +
|
||||
" `int32` integer NOT NULL,\n" +
|
||||
" `int64` bigint NOT NULL,\n" +
|
||||
" `uint` integer unsigned NOT NULL,\n" +
|
||||
" `uint8` tinyint unsigned NULL,\n" +
|
||||
" `uint16` smallint unsigned NOT NULL,\n" +
|
||||
" `uint32` integer unsigned NOT NULL,\n" +
|
||||
" `uint64` bigint unsigned NOT NULL,\n" +
|
||||
" `float32` double precision NOT NULL,\n" +
|
||||
" `float64` double precision NOT NULL,\n" +
|
||||
" `decimal` numeric(8,4) NOT NULL\n" +
|
||||
") ENGINE=INNODB;\n" +
|
||||
"CREATE TABLE `data_null` (\n" +
|
||||
" `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\n" +
|
||||
" `boolean` bool,\n" +
|
||||
" `char` varchar(50),\n" +
|
||||
" `text` longtext,\n" +
|
||||
" `date` date,\n" +
|
||||
" `date_time` datetime,\n" +
|
||||
" `byte` tinyint unsigned,\n" +
|
||||
" `rune` integer,\n" +
|
||||
" `int` integer,\n" +
|
||||
" `int8` tinyint,\n" +
|
||||
" `int16` smallint,\n" +
|
||||
" `int32` integer,\n" +
|
||||
" `int64` bigint,\n" +
|
||||
" `uint` integer unsigned,\n" +
|
||||
" `uint8` tinyint unsigned,\n" +
|
||||
" `uint16` smallint unsigned,\n" +
|
||||
" `uint32` integer unsigned,\n" +
|
||||
" `uint64` bigint unsigned,\n" +
|
||||
" `float32` double precision,\n" +
|
||||
" `float64` double precision,\n" +
|
||||
" `decimal` numeric(8,4)\n" +
|
||||
") ENGINE=INNODB;\n" +
|
||||
"CREATE INDEX `user_141c6eec` ON `user` (`profile_id`);\n" +
|
||||
"CREATE INDEX `post_fbfc09f1` ON `post` (`user_id`);\n" +
|
||||
"CREATE INDEX `comment_699ae8ca` ON `comment` (`post_id`);\n" +
|
||||
"CREATE INDEX `comment_63f17a16` ON `comment` (`parent_id`);",
|
||||
|
||||
"sqlite3": `
|
||||
DROP TABLE IF EXISTS "user_profile";
|
||||
DROP TABLE IF EXISTS "user";
|
||||
DROP TABLE IF EXISTS "post";
|
||||
DROP TABLE IF EXISTS "tag";
|
||||
DROP TABLE IF EXISTS "post_tags";
|
||||
DROP TABLE IF EXISTS "comment";
|
||||
DROP TABLE IF EXISTS "data";
|
||||
DROP TABLE IF EXISTS "data_null";
|
||||
CREATE TABLE "user_profile" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"age" smallint NOT NULL,
|
||||
"money" real NOT NULL
|
||||
);
|
||||
CREATE TABLE "user" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"user_name" varchar(30) NOT NULL UNIQUE,
|
||||
"email" varchar(100) NOT NULL,
|
||||
"password" varchar(100) NOT NULL,
|
||||
"status" smallint NOT NULL,
|
||||
"is_staff" bool NOT NULL,
|
||||
"is_active" bool NOT NULL,
|
||||
"created" date NOT NULL,
|
||||
"updated" datetime NOT NULL,
|
||||
"profile_id" integer
|
||||
);
|
||||
CREATE TABLE "post" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"user_id" integer NOT NULL,
|
||||
"title" varchar(60) NOT NULL,
|
||||
"content" text NOT NULL,
|
||||
"created" datetime NOT NULL,
|
||||
"updated" datetime NOT NULL
|
||||
);
|
||||
CREATE TABLE "tag" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"name" varchar(30) NOT NULL
|
||||
);
|
||||
CREATE TABLE "post_tags" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"post_id" integer NOT NULL,
|
||||
"tag_id" integer NOT NULL,
|
||||
UNIQUE ("post_id", "tag_id")
|
||||
);
|
||||
CREATE TABLE "comment" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"post_id" integer NOT NULL,
|
||||
"content" text NOT NULL,
|
||||
"parent_id" integer,
|
||||
"created" datetime NOT NULL
|
||||
);
|
||||
CREATE TABLE "data" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"boolean" bool NOT NULL,
|
||||
"char" varchar(50) NOT NULL,
|
||||
"text" text NOT NULL,
|
||||
"date" date NOT NULL,
|
||||
"date_time" datetime NOT NULL,
|
||||
"byte" tinyint unsigned NOT NULL,
|
||||
"rune" integer NOT NULL,
|
||||
"int" integer NOT NULL,
|
||||
"int8" tinyint NOT NULL,
|
||||
"int16" smallint NOT NULL,
|
||||
"int32" integer NOT NULL,
|
||||
"int64" bigint NOT NULL,
|
||||
"uint" integer unsigned NOT NULL,
|
||||
"uint8" tinyint unsigned NOT NULL,
|
||||
"uint16" smallint unsigned NOT NULL,
|
||||
"uint32" integer unsigned NOT NULL,
|
||||
"uint64" bigint unsigned NOT NULL,
|
||||
"float32" real NOT NULL,
|
||||
"float64" real NOT NULL,
|
||||
"decimal" decimal
|
||||
);
|
||||
CREATE TABLE "data_null" (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"boolean" bool,
|
||||
"char" varchar(50),
|
||||
"text" text,
|
||||
"date" date,
|
||||
"date_time" datetime,
|
||||
"byte" tinyint unsigned,
|
||||
"rune" integer,
|
||||
"int" integer,
|
||||
"int8" tinyint,
|
||||
"int16" smallint,
|
||||
"int32" integer,
|
||||
"int64" bigint,
|
||||
"uint" integer unsigned,
|
||||
"uint8" tinyint unsigned,
|
||||
"uint16" smallint unsigned,
|
||||
"uint32" integer unsigned,
|
||||
"uint64" bigint unsigned,
|
||||
"float32" real,
|
||||
"float64" real,
|
||||
"decimal" decimal
|
||||
);
|
||||
CREATE INDEX "user_141c6eec" ON "user" ("profile_id");
|
||||
CREATE INDEX "post_fbfc09f1" ON "post" ("user_id");
|
||||
CREATE INDEX "comment_699ae8ca" ON "comment" ("post_id");
|
||||
CREATE INDEX "comment_63f17a16" ON "comment" ("parent_id");
|
||||
`,
|
||||
|
||||
"postgres": `
|
||||
DROP TABLE IF EXISTS "user_profile";
|
||||
DROP TABLE IF EXISTS "user";
|
||||
DROP TABLE IF EXISTS "post";
|
||||
DROP TABLE IF EXISTS "tag";
|
||||
DROP TABLE IF EXISTS "post_tags";
|
||||
DROP TABLE IF EXISTS "comment";
|
||||
DROP TABLE IF EXISTS "data";
|
||||
DROP TABLE IF EXISTS "data_null";
|
||||
CREATE TABLE "user_profile" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"age" smallint NOT NULL,
|
||||
"money" double precision NOT NULL
|
||||
);
|
||||
CREATE TABLE "user" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"user_name" varchar(30) NOT NULL UNIQUE,
|
||||
"email" varchar(100) NOT NULL,
|
||||
"password" varchar(100) NOT NULL,
|
||||
"status" smallint NOT NULL,
|
||||
"is_staff" boolean NOT NULL,
|
||||
"is_active" boolean NOT NULL,
|
||||
"created" date NOT NULL,
|
||||
"updated" timestamp with time zone NOT NULL,
|
||||
"profile_id" integer
|
||||
);
|
||||
CREATE TABLE "post" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"user_id" integer NOT NULL,
|
||||
"title" varchar(60) NOT NULL,
|
||||
"content" text NOT NULL,
|
||||
"created" timestamp with time zone NOT NULL,
|
||||
"updated" timestamp with time zone NOT NULL
|
||||
);
|
||||
CREATE TABLE "tag" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"name" varchar(30) NOT NULL
|
||||
);
|
||||
CREATE TABLE "post_tags" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"post_id" integer NOT NULL,
|
||||
"tag_id" integer NOT NULL,
|
||||
UNIQUE ("post_id", "tag_id")
|
||||
);
|
||||
CREATE TABLE "comment" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"post_id" integer NOT NULL,
|
||||
"content" text NOT NULL,
|
||||
"parent_id" integer,
|
||||
"created" timestamp with time zone NOT NULL
|
||||
);
|
||||
CREATE TABLE "data" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"boolean" bool NOT NULL,
|
||||
"char" varchar(50) NOT NULL,
|
||||
"text" text NOT NULL,
|
||||
"date" date NOT NULL,
|
||||
"date_time" timestamp with time zone NOT NULL,
|
||||
"byte" smallint CHECK("byte" >= 0 AND "byte" <= 255) NOT NULL,
|
||||
"rune" integer NOT NULL,
|
||||
"int" integer NOT NULL,
|
||||
"int8" smallint CHECK("int8" >= -127 AND "int8" <= 128) NOT NULL,
|
||||
"int16" smallint NOT NULL,
|
||||
"int32" integer NOT NULL,
|
||||
"int64" bigint NOT NULL,
|
||||
"uint" bigint CHECK("uint" >= 0) NOT NULL,
|
||||
"uint8" smallint CHECK("uint8" >= 0 AND "uint8" <= 255) NOT NULL,
|
||||
"uint16" integer CHECK("uint16" >= 0) NOT NULL,
|
||||
"uint32" bigint CHECK("uint32" >= 0) NOT NULL,
|
||||
"uint64" bigint CHECK("uint64" >= 0) NOT NULL,
|
||||
"float32" double precision NOT NULL,
|
||||
"float64" double precision NOT NULL,
|
||||
"decimal" numeric(8, 4)
|
||||
);
|
||||
CREATE TABLE "data_null" (
|
||||
"id" serial NOT NULL PRIMARY KEY,
|
||||
"boolean" bool,
|
||||
"char" varchar(50),
|
||||
"text" text,
|
||||
"date" date,
|
||||
"date_time" timestamp with time zone,
|
||||
"byte" smallint CHECK("byte" >= 0 AND "byte" <= 255),
|
||||
"rune" integer,
|
||||
"int" integer,
|
||||
"int8" smallint CHECK("int8" >= -127 AND "int8" <= 128),
|
||||
"int16" smallint,
|
||||
"int32" integer,
|
||||
"int64" bigint,
|
||||
"uint" bigint CHECK("uint" >= 0),
|
||||
"uint8" smallint CHECK("uint8" >= 0 AND "uint8" <= 255),
|
||||
"uint16" integer CHECK("uint16" >= 0),
|
||||
"uint32" bigint CHECK("uint32" >= 0),
|
||||
"uint64" bigint CHECK("uint64" >= 0),
|
||||
"float32" double precision,
|
||||
"float64" double precision,
|
||||
"decimal" numeric(8, 4)
|
||||
);
|
||||
CREATE INDEX "user_profile_id" ON "user" ("profile_id");
|
||||
CREATE INDEX "post_user_id" ON "post" ("user_id");
|
||||
CREATE INDEX "comment_post_id" ON "comment" ("post_id");
|
||||
CREATE INDEX "comment_parent_id" ON "comment" ("parent_id");
|
||||
`}
|
||||
|
||||
func init() {
|
||||
// err := os.Setenv("TZ", "+00:00")
|
||||
// fmt.Println(err)
|
||||
|
||||
RegisterModel(new(Data), new(DataNull))
|
||||
RegisterModel(new(User))
|
||||
RegisterModel(new(Profile))
|
||||
RegisterModel(new(Post))
|
||||
RegisterModel(new(Tag))
|
||||
RegisterModel(new(Comment))
|
||||
|
||||
Debug, _ = StrTo(DBARGS.Debug).Bool()
|
||||
|
||||
if DBARGS.Driver == "" || DBARGS.Source == "" {
|
||||
@ -484,29 +164,35 @@ Default DB Drivers.
|
||||
sqlite3: https://github.com/mattn/go-sqlite3
|
||||
postgres: https://github.com/lib/pq
|
||||
|
||||
eg: mysql
|
||||
ORM_DRIVER=mysql ORM_SOURCE="root:root@/my_db?charset=utf8" go test github.com/astaxie/beego/orm
|
||||
usage:
|
||||
|
||||
go get -u github.com/astaxie/beego/orm
|
||||
go get -u github.com/go-sql-driver/mysql
|
||||
go get -u github.com/mattn/go-sqlite3
|
||||
go get -u github.com/lib/pq
|
||||
|
||||
#### MySQL
|
||||
mysql -u root -e 'create database orm_test;'
|
||||
export ORM_DRIVER=mysql
|
||||
export ORM_SOURCE="root:@/orm_test?charset=utf8"
|
||||
go test -v github.com/astaxie/beego/orm
|
||||
|
||||
|
||||
#### Sqlite3
|
||||
touch /path/to/orm_test.db
|
||||
export ORM_DRIVER=sqlite3
|
||||
export ORM_SOURCE=/path/to/orm_test.db
|
||||
go test -v github.com/astaxie/beego/orm
|
||||
|
||||
|
||||
#### PostgreSQL
|
||||
psql -c 'create database orm_test;' -U postgres
|
||||
export ORM_DRIVER=postgres
|
||||
export ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
|
||||
go test -v github.com/astaxie/beego/orm
|
||||
`)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, 20)
|
||||
|
||||
BootStrap()
|
||||
|
||||
dORM = NewOrm()
|
||||
|
||||
queries := strings.Split(initSQLs[DBARGS.Driver], ";")
|
||||
|
||||
for _, query := range queries {
|
||||
query = strings.TrimSpace(query)
|
||||
if len(query) == 0 {
|
||||
continue
|
||||
}
|
||||
_, err := dORM.Raw(query).Exec()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ func getFieldType(val reflect.Value) (ft int, err error) {
|
||||
case reflect.Int64:
|
||||
ft = TypeBigIntegerField
|
||||
case reflect.Uint8:
|
||||
ft = TypePostiveBitField
|
||||
ft = TypePositiveBitField
|
||||
case reflect.Uint16:
|
||||
ft = TypePositiveSmallIntegerField
|
||||
case reflect.Uint32, reflect.Uint:
|
||||
|
@ -189,6 +189,47 @@ func throwFailNow(t *testing.T, err error, args ...interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncDb(t *testing.T) {
|
||||
RegisterModel(new(Data), new(DataNull))
|
||||
RegisterModel(new(User))
|
||||
RegisterModel(new(Profile))
|
||||
RegisterModel(new(Post))
|
||||
RegisterModel(new(Tag))
|
||||
RegisterModel(new(Comment))
|
||||
|
||||
BootStrap()
|
||||
|
||||
al := dataBaseCache.getDefault()
|
||||
db := al.DB
|
||||
|
||||
drops := getDbDropSql(al)
|
||||
for _, query := range drops {
|
||||
_, err := db.Exec(query)
|
||||
throwFailNow(t, err, query)
|
||||
}
|
||||
|
||||
tables := getDbCreateSql(al)
|
||||
for _, query := range tables {
|
||||
_, err := db.Exec(query)
|
||||
throwFailNow(t, err, query)
|
||||
}
|
||||
|
||||
modelCache.clean()
|
||||
}
|
||||
|
||||
func TestRegisterModels(t *testing.T) {
|
||||
RegisterModel(new(Data), new(DataNull))
|
||||
RegisterModel(new(User))
|
||||
RegisterModel(new(Profile))
|
||||
RegisterModel(new(Post))
|
||||
RegisterModel(new(Tag))
|
||||
RegisterModel(new(Comment))
|
||||
|
||||
BootStrap()
|
||||
|
||||
dORM = NewOrm()
|
||||
}
|
||||
|
||||
func TestModelSyntax(t *testing.T) {
|
||||
user := &User{}
|
||||
ind := reflect.ValueOf(user).Elem()
|
||||
|
@ -132,4 +132,5 @@ type dbBaser interface {
|
||||
HasReturningID(*modelInfo, *string) bool
|
||||
TimeFromDB(*time.Time, *time.Location)
|
||||
TimeToDB(*time.Time, *time.Location)
|
||||
DbTypes() map[string]string
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user