diff --git a/callbacks/query.go b/callbacks/query.go index baacbd24..21b58aaf 100644 --- a/callbacks/query.go +++ b/callbacks/query.go @@ -1,6 +1,7 @@ package callbacks import ( + "database/sql" "reflect" "github.com/jinzhu/gorm" @@ -15,9 +16,31 @@ func Query(db *gorm.DB) { } rows, err := db.DB.QueryContext(db.Context, db.Statement.SQL.String(), db.Statement.Vars...) - db.AddError(err) - _ = rows - // scan rows + if err != nil { + db.AddError(err) + return + } + defer rows.Close() + + columns, _ := rows.Columns() + values := make([]interface{}, len(columns)) + + for idx, column := range columns { + if field, ok := db.Statement.Schema.FieldsByDBName[column]; ok { + values[idx] = field.ReflectValueOf(db.Statement.ReflectValue).Addr().Interface() + } else { + values[idx] = sql.RawBytes{} + } + } + + for rows.Next() { + db.RowsAffected++ + rows.Scan(values...) + } + + if db.RowsAffected == 0 && db.Statement.RaiseErrorOnNotFound { + db.AddError(gorm.ErrRecordNotFound) + } } func Preload(db *gorm.DB) { diff --git a/dialects/sqlite/sqlite.go b/dialects/sqlite/sqlite.go index a6aba066..5f9d49df 100644 --- a/dialects/sqlite/sqlite.go +++ b/dialects/sqlite/sqlite.go @@ -59,8 +59,10 @@ func (dialector Dialector) DataTypeOf(field *schema.Field) string { } case schema.Float: return "real" - case schema.String, schema.Time: + case schema.String: return "text" + case schema.Time: + return "datetime" case schema.Bytes: return "blob" } diff --git a/finisher_api.go b/finisher_api.go index 72c3d2aa..83988546 100644 --- a/finisher_api.go +++ b/finisher_api.go @@ -28,6 +28,7 @@ func (db *DB) First(out interface{}, where ...interface{}) (tx *DB) { Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey}, Desc: true, }) + tx.Statement.RaiseErrorOnNotFound = true tx.Statement.Dest = out tx.callbacks.Query().Execute(tx) return @@ -35,7 +36,8 @@ func (db *DB) First(out interface{}, where ...interface{}) (tx *DB) { // Take return a record that match given conditions, the order will depend on the database implementation func (db *DB) Take(out interface{}, where ...interface{}) (tx *DB) { - tx = db.getInstance() + tx = db.getInstance().Limit(1) + tx.Statement.RaiseErrorOnNotFound = true tx.Statement.Dest = out tx.callbacks.Query().Execute(tx) return @@ -46,6 +48,7 @@ func (db *DB) Last(out interface{}, where ...interface{}) (tx *DB) { tx = db.getInstance().Limit(1).Order(clause.OrderByColumn{ Column: clause.Column{Table: clause.CurrentTable, Name: clause.PrimaryKey}, }) + tx.Statement.RaiseErrorOnNotFound = true tx.Statement.Dest = out tx.callbacks.Query().Execute(tx) return @@ -54,6 +57,8 @@ func (db *DB) Last(out interface{}, where ...interface{}) (tx *DB) { // Find find records that match given conditions func (db *DB) Find(out interface{}, where ...interface{}) (tx *DB) { tx = db.getInstance() + tx.Statement.Dest = out + tx.callbacks.Query().Execute(tx) return } diff --git a/statement.go b/statement.go index ad30ed08..bad83717 100644 --- a/statement.go +++ b/statement.go @@ -40,16 +40,17 @@ func (inst *Instance) AddError(err error) { // Statement statement type Statement struct { - Table string - Model interface{} - Dest interface{} - ReflectValue reflect.Value - Clauses map[string]clause.Clause - Selects []string // selected columns - Omits []string // omit columns - Settings sync.Map - DB *DB - Schema *schema.Schema + Table string + Model interface{} + Dest interface{} + ReflectValue reflect.Value + Clauses map[string]clause.Clause + Selects []string // selected columns + Omits []string // omit columns + Settings sync.Map + DB *DB + Schema *schema.Schema + RaiseErrorOnNotFound bool // SQL Builder SQL strings.Builder diff --git a/tests/tests.go b/tests/tests.go index 53700710..5e47c09e 100644 --- a/tests/tests.go +++ b/tests/tests.go @@ -18,7 +18,6 @@ func RunTestsSuit(t *testing.T, db *gorm.DB) { func TestCreate(t *testing.T, db *gorm.DB) { db.AutoMigrate(&User{}) - db = db.Debug() t.Run("Create", func(t *testing.T) { var user = User{