From 5ea6c6277e7319d1b8ad4e8846b08e183b8f24fc Mon Sep 17 00:00:00 2001 From: Ubasic Date: Sat, 8 Mar 2014 22:38:34 +0800 Subject: [PATCH 01/12] Fix. the mysql drop index syntax error --- base.go | 6 +++--- dialect.go | 4 ++-- hood.go | 2 +- mysql.go | 4 ++++ 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/base.go b/base.go index 2bfe6f8..749265d 100644 --- a/base.go +++ b/base.go @@ -410,12 +410,12 @@ func (d *base) CreateIndexSql(name, table string, unique bool, columns ...string return strings.Join(a, " ") } -func (d *base) DropIndex(hood *Hood, name string) error { - _, err := hood.Exec(d.Dialect.DropIndexSql(name)) +func (d *base) DropIndex(hood *Hood, table_name string, name string) error { + _, err := hood.Exec(d.Dialect.DropIndexSql(table_name, name)) return err } -func (d *base) DropIndexSql(name string) string { +func (d *base) DropIndexSql(table_name, name string) string { return fmt.Sprintf("DROP INDEX %v", d.Dialect.Quote(name)) } diff --git a/dialect.go b/dialect.go index 13edf59..f9fbd49 100644 --- a/dialect.go +++ b/dialect.go @@ -114,10 +114,10 @@ type Dialect interface { CreateIndexSql(name, table string, unique bool, columns ...string) string // DropIndex drops the index. - DropIndex(hood *Hood, name string) error + DropIndex(hood *Hood, table_name string, name string) error // DropIndexSql returns the sql for dropping the index. - DropIndexSql(name string) string + DropIndexSql(table_name, name string) string // KeywordNotNull returns the dialect specific keyword for 'NOT NULL'. KeywordNotNull() string diff --git a/hood.go b/hood.go index 149436d..ce09e5c 100644 --- a/hood.go +++ b/hood.go @@ -1241,7 +1241,7 @@ func (hood *Hood) DropIndex(table interface{}, name string) error { if hood.dryRun { return nil } - return hood.Dialect.DropIndex(hood, name) + return hood.Dialect.DropIndex(hood, tn, name) } func (hood *Hood) substituteMarkers(query string) string { diff --git a/mysql.go b/mysql.go index 64e7514..4300e72 100644 --- a/mysql.go +++ b/mysql.go @@ -63,3 +63,7 @@ func (d *mysql) SqlType(f interface{}, size int) string { func (d *mysql) KeywordAutoIncrement() string { return "AUTO_INCREMENT" } + +func (d *mysql) DropIndexSql(table_name, name string) string { + return fmt.Sprintf("DROP INDEX %v on %v", d.Quote(name), d.Quote(table_name)) +} From 1dd88a786096711762fe3506a38aede6e6dc1483 Mon Sep 17 00:00:00 2001 From: Ubasic Date: Sat, 8 Mar 2014 22:40:25 +0800 Subject: [PATCH 02/12] add mysql godrv --- mysql.go | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql.go b/mysql.go index 4300e72..a50a62d 100644 --- a/mysql.go +++ b/mysql.go @@ -4,6 +4,7 @@ import ( "fmt" "reflect" "time" + //_ "github.com/ziutek/mymysql/godrv" ) func init() { From 19be413f66df70d931a3ee2b1a2389a4cd442bb9 Mon Sep 17 00:00:00 2001 From: HanHor Wu Date: Thu, 13 Mar 2014 15:27:04 +0800 Subject: [PATCH 03/12] update mysql collumn length & charset --- mysql.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mysql.go b/mysql.go index a50a62d..7983650 100644 --- a/mysql.go +++ b/mysql.go @@ -4,7 +4,7 @@ import ( "fmt" "reflect" "time" - //_ "github.com/ziutek/mymysql/godrv" +_ "github.com/ziutek/mymysql/godrv" ) func init() { @@ -36,7 +36,7 @@ func (d *mysql) ParseBool(value reflect.Value) bool { func (d *mysql) SqlType(f interface{}, size int) string { switch f.(type) { case Id: - return "bigint" + return "int" case time.Time, Created, Updated: return "timestamp" case bool: @@ -56,7 +56,7 @@ func (d *mysql) SqlType(f interface{}, size int) string { if size > 0 && size < 65532 { return fmt.Sprintf("varchar(%d)", size) } - return "longtext" + return "text" } panic("invalid sql type") } @@ -68,3 +68,8 @@ func (d *mysql) KeywordAutoIncrement() string { func (d *mysql) DropIndexSql(table_name, name string) string { return fmt.Sprintf("DROP INDEX %v on %v", d.Quote(name), d.Quote(table_name)) } + +func (d *mysql) CreateTable(hood *Hood, model *Model) error { + _, err := hood.Exec(d.CreateTableSql(model, false) + " CHARSET = 'utf8'") + return err +} From ad9c29e689fcb6f6e7b08d9e0d9131cd8719e287 Mon Sep 17 00:00:00 2001 From: HanHor Wu Date: Thu, 13 Mar 2014 15:40:47 +0800 Subject: [PATCH 04/12] update repo address & add sample install shell --- .gitignore | 1 + README.md | 13 ++++++++++--- cmd/templates/_migration.go | 4 ++-- cmd/templates/_runner.go | 2 +- hood.go | 2 +- install.sample.sh | 3 +++ install.sh | 2 +- 7 files changed, 19 insertions(+), 8 deletions(-) create mode 100755 install.sample.sh diff --git a/.gitignore b/.gitignore index 8ec89c8..63d0c0f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ profile example/example cmd/templates.go db/ +install.sh diff --git a/README.md b/README.md index 2143205..e93f63a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +## FYI +This is just a MySQL Patch for [eaigner/hood](https://github.com/eaigner/hood).Let us known if you have any questions. + +- - - + + If you are looking for something more lightweight and flexible, have a look at [jet](http://github.com/eaigner/jet) For questions, suggestions and general topics visit the [group](https://groups.google.com/forum/#!forum/golang-hood). @@ -44,11 +50,11 @@ You can find the documentation over at [GoDoc](http://godoc.org/github.com/eaign If the dialect is registered, you can open the database directly using hd, err := hood.Open("postgres", "user= dbname=") - + or you can pass an existing database and dialect to `hood.New(*sql.DB, hood.Dialect)` hd := hood.New(db, NewPostgres()) - + ## Schemas Schemas can be declared using the following syntax (only for demonstration purposes, would not produce valid SQL since it has 2 primary keys) @@ -112,6 +118,7 @@ To use migrations, you first have to install the `hood` tool. To do that run the go get github.com/eaigner/hood cd $GOPATH/src/github.com/eaigner/hood + cp install.sample.sh install.sh ./install.sh Assuming you have your `$GOPATH/bin` directory in your `PATH`, you can now invoke the hood tool with `hood`. @@ -206,7 +213,7 @@ Besides the `sql:` struct tag, you can specify a `validate:` tag for model valid - `presence` validates that a field is set - `len(min:max)` validates that a `string` field’s length lies within the specified range - - `len(min:)` validates that it has the specified min length, + - `len(min:)` validates that it has the specified min length, - `len(:max)` or max length - `range(min:max)` validates that an `int` value lies in the specific range - `range(min:)` validates that it has the specified min value, diff --git a/cmd/templates/_migration.go b/cmd/templates/_migration.go index 01bffe7..0957fd6 100644 --- a/cmd/templates/_migration.go +++ b/cmd/templates/_migration.go @@ -1,7 +1,7 @@ package main import ( - "github.com/eaigner/hood" + "github.com/xrangers/hood" ) func (m *M) {{.Name}}_{{.Timestamp}}_Up(hd *hood.Hood) { @@ -10,4 +10,4 @@ func (m *M) {{.Name}}_{{.Timestamp}}_Up(hd *hood.Hood) { func (m *M) {{.Name}}_{{.Timestamp}}_Down(hd *hood.Hood) { // TODO: implement -} \ No newline at end of file +} diff --git a/cmd/templates/_runner.go b/cmd/templates/_runner.go index 4be3bb3..5008789 100644 --- a/cmd/templates/_runner.go +++ b/cmd/templates/_runner.go @@ -2,7 +2,7 @@ package main import ( "flag" - "github.com/eaigner/hood" + "github.com/xrangers/hood" "io/ioutil" "log" "os/exec" diff --git a/hood.go b/hood.go index ce09e5c..c0dd487 100644 --- a/hood.go +++ b/hood.go @@ -569,7 +569,7 @@ L: "package db", "", "import (", - "\t\"github.com/eaigner/hood\"", + "\t\"github.com/xrangers/hood\"", } if timeRequired { head = append(head, "\t\"time\"") diff --git a/install.sample.sh b/install.sample.sh new file mode 100755 index 0000000..9e88a03 --- /dev/null +++ b/install.sample.sh @@ -0,0 +1,3 @@ +#!/bin/sh +go run cmd/gen/templates.go +go build -o $GOPATH/bin/hood github.com/xrangers/hood/cmd diff --git a/install.sh b/install.sh index 502d790..9e88a03 100755 --- a/install.sh +++ b/install.sh @@ -1,3 +1,3 @@ #!/bin/sh go run cmd/gen/templates.go -go build -o $GOPATH/bin/hood github.com/eaigner/hood/cmd +go build -o $GOPATH/bin/hood github.com/xrangers/hood/cmd From c4517782bfba647c78278ddee0fc2ff95d459b0c Mon Sep 17 00:00:00 2001 From: Ubasic Date: Sat, 22 Mar 2014 22:25:56 +0800 Subject: [PATCH 05/12] Add Autoincr for mysql --- hood.go | 6 ++++++ mysql.go | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/hood.go b/hood.go index c0dd487..c3e0861 100644 --- a/hood.go +++ b/hood.go @@ -184,6 +184,12 @@ func (field *ModelField) NotNull() bool { return ok } +// NotNull tests if the field is declared as NOT NULL +func (field *ModelField) AutoIncr() bool { + _, ok := field.SqlTags["autoincr"] + return ok +} + // Default returns the default value for the field func (field *ModelField) Default() string { return field.SqlTags["default"] diff --git a/mysql.go b/mysql.go index 7983650..ccc0609 100644 --- a/mysql.go +++ b/mysql.go @@ -3,6 +3,7 @@ package hood import ( "fmt" "reflect" + "strings" "time" _ "github.com/ziutek/mymysql/godrv" ) @@ -72,4 +73,35 @@ func (d *mysql) DropIndexSql(table_name, name string) string { func (d *mysql) CreateTable(hood *Hood, model *Model) error { _, err := hood.Exec(d.CreateTableSql(model, false) + " CHARSET = 'utf8'") return err + +func (d *mysql) CreateTableSql(model *Model, ifNotExists bool) string { + a := []string{"CREATE TABLE "} + if ifNotExists { + a = append(a, "IF NOT EXISTS ") + } + a = append(a, d.Quote(model.Table), " ( ") + for i, field := range model.Fields { + b := []string{ + d.Quote(field.Name), + d.SqlType(field.Value, field.Size()), + } + if field.NotNull() { + b = append(b, d.KeywordNotNull()) + } + if x := field.Default(); x != "" { + b = append(b, d.KeywordDefault(x)) + } + if field.PrimaryKey() { + b = append(b, d.KeywordPrimaryKey()) + } + if incKeyword := d.Dialect.KeywordAutoIncrement(); field.AutoIncr() && incKeyword != "" { + b = append(b, incKeyword) + } + a = append(a, strings.Join(b, " ")) + if i < len(model.Fields)-1 { + a = append(a, ", ") + } + } + a = append(a, " )") + return strings.Join(a, "") } From 1686ebbf63939a8b85419bc30490c7fb581ba453 Mon Sep 17 00:00:00 2001 From: Ubasic Date: Sat, 22 Mar 2014 22:26:40 +0800 Subject: [PATCH 06/12] switch the db to mysql default --- mysql.go | 1 + postgres.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql.go b/mysql.go index ccc0609..96dc3de 100644 --- a/mysql.go +++ b/mysql.go @@ -2,6 +2,7 @@ package hood import ( "fmt" + _ "github.com/ziutek/mymysql/godrv" "reflect" "strings" "time" diff --git a/postgres.go b/postgres.go index 5f171c4..69c36a2 100644 --- a/postgres.go +++ b/postgres.go @@ -2,7 +2,7 @@ package hood import ( "fmt" - _ "github.com/lib/pq" + // _ "github.com/lib/pq" "strings" "time" ) From b5f5893adaa27e125e4f790420561cd63648785e Mon Sep 17 00:00:00 2001 From: Ubasic Date: Mon, 24 Mar 2014 09:41:22 +0800 Subject: [PATCH 07/12] Fix. --- mysql.go | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql.go b/mysql.go index 96dc3de..968805c 100644 --- a/mysql.go +++ b/mysql.go @@ -74,6 +74,7 @@ func (d *mysql) DropIndexSql(table_name, name string) string { func (d *mysql) CreateTable(hood *Hood, model *Model) error { _, err := hood.Exec(d.CreateTableSql(model, false) + " CHARSET = 'utf8'") return err +} func (d *mysql) CreateTableSql(model *Model, ifNotExists bool) string { a := []string{"CREATE TABLE "} From 1ce6468b59f1f9216942e6d67d5c82767b5f3edb Mon Sep 17 00:00:00 2001 From: Ubasic Date: Mon, 24 Mar 2014 15:45:32 +0800 Subject: [PATCH 08/12] Add Hood.Insert --- hood.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/hood.go b/hood.go index c3e0861..2c97fcd 100644 --- a/hood.go +++ b/hood.go @@ -868,6 +868,56 @@ func callModelMethod(f interface{}, methodName string, isPrefix bool) error { return nil } +// INSERT + +func (hood *Hood) Insert(f interface{}) (Id, error) { + var ( + id Id = -1 + err error + ) + model, err := interfaceToModel(f) + if err != nil { + return id, err + } + err = model.Validate() + if err != nil { + return id, err + } + if model.Pk == nil { + panic("no primary key field") + } + err = callModelMethod(f, "BeforeInsert", false) + if err != nil { + return id, err + } + now := time.Now() + for _, f := range model.Fields { + switch f.Value.(type) { + case Created, Updated: + f.Value = now + } + } + id, err = hood.Dialect.Insert(hood, model) + if err == nil { + err = callModelMethod(f, "AfterInsert", false) + } + + if id != -1 { + // update model id after save + structValue := reflect.Indirect(reflect.ValueOf(f)) + for i := 0; i < structValue.NumField(); i++ { + field := structValue.Field(i) + switch field.Interface().(type) { + case Id: + field.SetInt(int64(id)) + case Created: + field.Set(reflect.ValueOf(Created{now})) + } + } + } + return id, err +} + // Save performs an INSERT, or UPDATE if the passed structs Id is set. func (hood *Hood) Save(f interface{}) (Id, error) { var ( From 007915667b924c3fffa16ca147294b977fce6dd4 Mon Sep 17 00:00:00 2001 From: Ubasic Date: Mon, 24 Mar 2014 15:46:19 +0800 Subject: [PATCH 09/12] Insert data with primarykey --- util.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/util.go b/util.go index 7a66e0e..93c7b9b 100644 --- a/util.go +++ b/util.go @@ -49,11 +49,9 @@ func columnsMarkersAndValuesForModel(dialect Dialect, model *Model, markerPos *i markers := make([]string, 0, len(columns)) values := make([]interface{}, 0, len(columns)) for _, column := range model.Fields { - if !column.PrimaryKey() { - columns = append(columns, column.Name) - markers = append(markers, dialect.NextMarker(markerPos)) - values = append(values, column.Value) - } + columns = append(columns, column.Name) + markers = append(markers, dialect.NextMarker(markerPos)) + values = append(values, column.Value) } return columns, markers, values } From c42f7998e485f8731b1c94c5c965e54563695874 Mon Sep 17 00:00:00 2001 From: Ubasic Date: Wed, 26 Mar 2014 13:35:52 +0800 Subject: [PATCH 10/12] ignore Exec when dryRun --- hood.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hood.go b/hood.go index 2c97fcd..9f08783 100644 --- a/hood.go +++ b/hood.go @@ -765,6 +765,9 @@ func (hood *Hood) FindSql(out interface{}, query string, args ...interface{}) er // Exec executes a raw sql query. func (hood *Hood) Exec(query string, args ...interface{}) (sql.Result, error) { + if hood.dryRun { + return nil, nil + } hood.mutex.Lock() defer hood.mutex.Unlock() defer hood.Reset() From e924bbb857e2aac33fcb7d29351d654b583f7c09 Mon Sep 17 00:00:00 2001 From: Ubasic Date: Tue, 1 Apr 2014 15:58:38 +0800 Subject: [PATCH 11/12] Fix. the autoincr --- cmd/templates/_runner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/templates/_runner.go b/cmd/templates/_runner.go index 5008789..f4d7045 100644 --- a/cmd/templates/_runner.go +++ b/cmd/templates/_runner.go @@ -56,7 +56,7 @@ func init() { type M struct{} type Migrations struct { - Id hood.Id + Id hood.Id `sql:"pk,autoincr"` Current int } From 8d4ffa19bc64351789dea4a329b34033cb248f14 Mon Sep 17 00:00:00 2001 From: Ubasic Date: Thu, 3 Apr 2014 15:49:50 +0800 Subject: [PATCH 12/12] use interface{} to replace Id --- base.go | 12 ++++++------ dialect.go | 6 +++--- dialects_test.go | 2 +- hood.go | 39 +++++++++++++++++++-------------------- postgres.go | 4 ++-- 5 files changed, 31 insertions(+), 32 deletions(-) diff --git a/base.go b/base.go index 749265d..c19163e 100644 --- a/base.go +++ b/base.go @@ -171,7 +171,7 @@ func (d *base) QuerySql(hood *Hood) (string, []interface{}) { return hood.substituteMarkers(strings.Join(query, " ")), args } -func (d *base) Insert(hood *Hood, model *Model) (Id, error) { +func (d *base) Insert(hood *Hood, model *Model) (interface{}, error) { sql, args := d.Dialect.InsertSql(model) result, err := hood.Exec(sql, args...) if err != nil { @@ -181,7 +181,7 @@ func (d *base) Insert(hood *Hood, model *Model) (Id, error) { if err != nil { return -1, err } - return Id(id), nil + return id, nil } func (d *base) InsertSql(model *Model) (string, []interface{}) { @@ -200,13 +200,13 @@ func (d *base) InsertSql(model *Model) (string, []interface{}) { return sql, values } -func (d *base) Update(hood *Hood, model *Model) (Id, error) { +func (d *base) Update(hood *Hood, model *Model) (interface{}, error) { sql, args := d.Dialect.UpdateSql(model) _, err := hood.Exec(sql, args...) if err != nil { return -1, err } - return model.Pk.Value.(Id), nil + return model.Pk.Value, nil } func (d *base) UpdateSql(model *Model) (string, []interface{}) { @@ -227,10 +227,10 @@ func (d *base) UpdateSql(model *Model) (string, []interface{}) { return sql, values } -func (d *base) Delete(hood *Hood, model *Model) (Id, error) { +func (d *base) Delete(hood *Hood, model *Model) (interface{}, error) { sql, args := d.Dialect.DeleteSql(model) _, err := hood.Exec(sql, args...) - return args[0].(Id), err + return args[0], err } func (d *base) DeleteSql(model *Model) (string, []interface{}) { diff --git a/dialect.go b/dialect.go index f9fbd49..5b06afd 100644 --- a/dialect.go +++ b/dialect.go @@ -35,20 +35,20 @@ type Dialect interface { QuerySql(hood *Hood) (sql string, args []interface{}) // Insert inserts the values in model and returns the inserted rows Id. - Insert(hood *Hood, model *Model) (Id, error) + Insert(hood *Hood, model *Model) (interface{}, error) // InsertSql returns the sql for inserting the passed model. InsertSql(model *Model) (sql string, args []interface{}) // Update updates the values in the specified model and returns the // updated rows Id. - Update(hood *Hood, model *Model) (Id, error) + Update(hood *Hood, model *Model) (interface{}, error) // UpdateSql returns the sql for updating the specified model. UpdateSql(model *Model) (string, []interface{}) // Delete drops the row matching the primary key of model and returns the affected Id. - Delete(hood *Hood, model *Model) (Id, error) + Delete(hood *Hood, model *Model) (interface{}, error) // DeleteSql returns the sql for deleting the row matching model's primary key. DeleteSql(model *Model) (string, []interface{}) diff --git a/dialects_test.go b/dialects_test.go index eafe357..1e8f6cd 100644 --- a/dialects_test.go +++ b/dialects_test.go @@ -414,7 +414,7 @@ func DoTestSaveDeleteAllAndHooks(t *testing.T, info dialectInfo) { t.Fatal("wrong id", x) } - hd.SaveAll(&models) // force update for hooks test + hd.SaveAll(&models) // force update for hooks test _, err = hd.DeleteAll(&models) if err != nil { diff --git a/hood.go b/hood.go index 9f08783..8f2c028 100644 --- a/hood.go +++ b/hood.go @@ -873,9 +873,9 @@ func callModelMethod(f interface{}, methodName string, isPrefix bool) error { // INSERT -func (hood *Hood) Insert(f interface{}) (Id, error) { +func (hood *Hood) Insert(f interface{}) (interface{}, error) { var ( - id Id = -1 + id int64 = -1 err error ) model, err := interfaceToModel(f) @@ -900,7 +900,8 @@ func (hood *Hood) Insert(f interface{}) (Id, error) { f.Value = now } } - id, err = hood.Dialect.Insert(hood, model) + ifd, err := hood.Dialect.Insert(hood, model) + id, _ = ifd.(int64) if err == nil { err = callModelMethod(f, "AfterInsert", false) } @@ -911,8 +912,6 @@ func (hood *Hood) Insert(f interface{}) (Id, error) { for i := 0; i < structValue.NumField(); i++ { field := structValue.Field(i) switch field.Interface().(type) { - case Id: - field.SetInt(int64(id)) case Created: field.Set(reflect.ValueOf(Created{now})) } @@ -922,10 +921,11 @@ func (hood *Hood) Insert(f interface{}) (Id, error) { } // Save performs an INSERT, or UPDATE if the passed structs Id is set. -func (hood *Hood) Save(f interface{}) (Id, error) { +func (hood *Hood) Save(f interface{}) (interface{}, error) { var ( - id Id = -1 + id int64 = -1 err error + ifd interface{} ) model, err := interfaceToModel(f) if err != nil { @@ -955,7 +955,7 @@ func (hood *Hood) Save(f interface{}) (Id, error) { f.Value = now } } - id, err = hood.Dialect.Update(hood, model) + ifd, err = hood.Dialect.Update(hood, model) if err == nil { err = callModelMethod(f, "AfterUpdate", false) } @@ -970,7 +970,8 @@ func (hood *Hood) Save(f interface{}) (Id, error) { f.Value = now } } - id, err = hood.Dialect.Insert(hood, model) + ifd, err = hood.Dialect.Insert(hood, model) + id, _ = ifd.(int64) if err == nil { err = callModelMethod(f, "AfterInsert", false) } @@ -978,14 +979,12 @@ func (hood *Hood) Save(f interface{}) (Id, error) { if err == nil { err = callModelMethod(f, "AfterSave", false) } - if id != -1 { + if id != -1 || ifd != nil { // update model id after save structValue := reflect.Indirect(reflect.ValueOf(f)) for i := 0; i < structValue.NumField(); i++ { field := structValue.Field(i) switch field.Interface().(type) { - case Id: - field.SetInt(int64(id)) case Updated: field.Set(reflect.ValueOf(Updated{now})) case Created: @@ -995,10 +994,10 @@ func (hood *Hood) Save(f interface{}) (Id, error) { } } } - return id, err + return ifd, err } -func (hood *Hood) doAll(f interface{}, doFunc func(f2 interface{}) (Id, error)) ([]Id, error) { +func (hood *Hood) doAll(f interface{}, doFunc func(f2 interface{}) (interface{}, error)) ([]interface{}, error) { panicMsg := "expected pointer to struct slice *[]struct" if reflect.TypeOf(f).Kind() != reflect.Ptr { panic(panicMsg) @@ -1008,7 +1007,7 @@ func (hood *Hood) doAll(f interface{}, doFunc func(f2 interface{}) (Id, error)) } sliceValue := reflect.ValueOf(f).Elem() sliceLen := sliceValue.Len() - ids := make([]Id, 0, sliceLen) + ids := make([]interface{}, 0, sliceLen) for i := 0; i < sliceLen; i++ { id, err := doFunc(sliceValue.Index(i).Addr().Interface()) if err != nil { @@ -1020,14 +1019,14 @@ func (hood *Hood) doAll(f interface{}, doFunc func(f2 interface{}) (Id, error)) } // SaveAll performs an INSERT or UPDATE on a slice of structs. -func (hood *Hood) SaveAll(f interface{}) ([]Id, error) { - return hood.doAll(f, func(f2 interface{}) (Id, error) { +func (hood *Hood) SaveAll(f interface{}) ([]interface{}, error) { + return hood.doAll(f, func(f2 interface{}) (interface{}, error) { return hood.Save(f2) }) } // Delete deletes the row matching the specified structs Id. -func (hood *Hood) Delete(f interface{}) (Id, error) { +func (hood *Hood) Delete(f interface{}) (interface{}, error) { model, err := interfaceToModel(f) if err != nil { return -1, err @@ -1047,8 +1046,8 @@ func (hood *Hood) Delete(f interface{}) (Id, error) { } // DeleteAll deletes the rows matching the specified struct slice Ids. -func (hood *Hood) DeleteAll(f interface{}) ([]Id, error) { - return hood.doAll(f, func(f2 interface{}) (Id, error) { +func (hood *Hood) DeleteAll(f interface{}) ([]interface{}, error) { + return hood.doAll(f, func(f2 interface{}) (interface{}, error) { return hood.Delete(f2) }) } diff --git a/postgres.go b/postgres.go index 69c36a2..1caa338 100644 --- a/postgres.go +++ b/postgres.go @@ -46,11 +46,11 @@ func (d *postgres) SqlType(f interface{}, size int) string { panic("invalid sql type") } -func (d *postgres) Insert(hood *Hood, model *Model) (Id, error) { +func (d *postgres) Insert(hood *Hood, model *Model) (interface{}, error) { sql, args := d.Dialect.InsertSql(model) var id int64 err := hood.QueryRow(sql, args...).Scan(&id) - return Id(id), err + return id, err } func (d *postgres) InsertSql(model *Model) (string, []interface{}) {