diff --git a/README.md b/README.md index 49e5e89c..88e8dd80 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ Yet Another ORM library for Go, aims for developer friendly ## TODO * Perimary key -* Create table * Save and fill the record * Update * Delete @@ -21,7 +20,6 @@ Yet Another ORM library for Go, aims for developer friendly * Soft Delete * After/Before Save/Update/Create/Delete * FindOrInitialize / FindOrCreate -* Exec run SQL directly * SQL Log * Auto Migration * Index, Unique, Valiations diff --git a/main.go b/main.go index f64820b4..cc4c1372 100644 --- a/main.go +++ b/main.go @@ -6,17 +6,19 @@ import ( ) type DB struct { - Db *sql.DB + Db *sql.DB + Driver string } func Open(driver, source string) (db DB, err error) { db.Db, err = sql.Open(driver, source) + db.Driver = driver // SetMaxIdleConns pools return } func (s *DB) buildORM() *Orm { - orm := &Orm{db: s.Db} + orm := &Orm{db: s.Db, driver: s.Driver} return orm } diff --git a/model.go b/model.go index 9f8b13c3..62da0ea4 100644 --- a/model.go +++ b/model.go @@ -1,19 +1,43 @@ package gorm import ( - "regexp" - + "fmt" "reflect" + "regexp" + "strings" ) type Model struct { - Data interface{} + Data interface{} + driver string } -func toModel(value interface{}) *Model { - var model Model - model.Data = value - return &model +type Field struct { + Name string + Value interface{} + SqlType string + DbName string +} + +func (s *Orm) toModel(value interface{}) *Model { + return &Model{Data: value, driver: s.driver} +} + +func (m *Model) Fields() (fields []Field) { + typ := reflect.TypeOf(m.Data).Elem() + + for i := 0; i < typ.NumField(); i++ { + p := typ.Field(i) + if !p.Anonymous { + var field Field + field.Name = p.Name + field.DbName = toSnake(p.Name) + field.Value = reflect.ValueOf(m.Data).Elem().FieldByName(p.Name).Interface() + field.SqlType = getSqlType(m.driver, field.Value, 0) + fields = append(fields, field) + } + } + return } func (m *Model) ColumnsAndValues() (columns []string, values []interface{}) { @@ -47,19 +71,6 @@ func (m *Model) TableName() string { return reg.ReplaceAllString(toSnake(t.Name()), "s") } -func (m *Model) Columns() (columns []string) { - typ := reflect.TypeOf(m.Data).Elem() - - for i := 0; i < typ.NumField(); i++ { - p := typ.Field(i) - if !p.Anonymous { - columns = append(columns, toSnake(p.Name)) - } - } - - return -} - func (model *Model) MissingColumns() (results []string) { return } @@ -67,3 +78,17 @@ func (model *Model) MissingColumns() (results []string) { func (model *Model) ColumnType(column string) (result string) { return } + +func (model *Model) CreateTable() (sql string) { + var sqls []string + for _, field := range model.Fields() { + sqls = append(sqls, field.DbName+" "+field.SqlType) + } + + sql = fmt.Sprintf( + "CREATE TABLE \"%v\" (%v)", + model.TableName(), + strings.Join(sqls, ","), + ) + return +} diff --git a/orm.go b/orm.go index f19511a3..53d4aa24 100644 --- a/orm.go +++ b/orm.go @@ -16,6 +16,7 @@ type Orm struct { Model *Model db *sql.DB + driver string whereClause []map[string]interface{} selectStr string orderStr string @@ -25,7 +26,7 @@ type Orm struct { } func (s *Orm) setModel(model interface{}) (err error) { - s.Model = toModel(model) + s.Model = s.toModel(model) s.TableName = s.Model.TableName() s.PrimaryKey = "id" return @@ -130,5 +131,6 @@ func (s *Orm) Not(querystring interface{}, args ...interface{}) *Orm { } func (s *Orm) CreateTable(value interface{}) *Orm { + s.explain(value, "CreateTable").Exec() return s } diff --git a/orm_test.go b/orm_test.go index 350975d9..82876ff0 100644 --- a/orm_test.go +++ b/orm_test.go @@ -4,6 +4,7 @@ import "testing" type User struct { Name string + Id int64 } func getDB() DB { @@ -55,3 +56,13 @@ func TestWhere(t *testing.T) { t.Errorf("Shouldn't return error when looking for unexist records, %+v", users) } } + +func TestCreateTable(t *testing.T) { + db := getDB() + db.Exec("drop table users;") + + orm := db.CreateTable(&User{}) + if orm.Error != nil { + t.Errorf("No error should raise when create table, but got %+v", orm.Error) + } +} diff --git a/sql.go b/sql.go index 244b9206..0e74ff57 100644 --- a/sql.go +++ b/sql.go @@ -18,7 +18,7 @@ func (s *Orm) explain(value interface{}, operation string) *Orm { case "Query": s.querySql(value) case "CreateTable": - s.createTableSql(value) + s.Sql = s.Model.CreateTable() } return s } @@ -103,12 +103,3 @@ func (s *Orm) whereSql() (sql string) { } return } - -func (s *Orm) createTableSql(value interface{}) { - s.Sql = fmt.Sprintf( - "CREATE TABLE \"%v\" (%v)", - s.TableName, - "", - ) - return -} diff --git a/utils.go b/utils.go index a081554f..f2b9f612 100644 --- a/utils.go +++ b/utils.go @@ -7,6 +7,7 @@ import ( "strings" ) +// FIXME func valuesToBinVar(values []interface{}) string { var sqls []string for index, _ := range values {