diff --git a/base.go b/base.go index 639aec5..8e5e1ab 100644 --- a/base.go +++ b/base.go @@ -47,7 +47,14 @@ func (d *base) SetModelValue(driverValue, fieldValue reflect.Value) error { case reflect.Float32, reflect.Float64: fieldValue.SetFloat(driverValue.Elem().Float()) case reflect.String: - fieldValue.SetString(string(driverValue.Elem().Bytes())) + //shoud be string(...) + fieldValue.SetString(string(driverValue.Elem().Bytes())) + // kind := reflect.TypeOf(driverValue.Elem()) + // if _,ok := kind.FieldByName("val"); ok { + // fieldValue.SetString(string(driverValue.Elem().Bytes())) + // }else { + // fieldValue.SetString(string(driverValue.Elem().Bytes())) + // } case reflect.Slice: if reflect.TypeOf(driverValue.Interface()).Elem().Kind() == reflect.Uint8 { fieldValue.SetBytes(driverValue.Elem().Bytes()) diff --git a/hood.go b/hood.go index ea3f16e..b6ef14a 100644 --- a/hood.go +++ b/hood.go @@ -680,6 +680,24 @@ func (hood *Hood) Find(out interface{}) error { query, args := hood.Dialect.QuerySql(hood) return hood.FindSql(out, query, args...) } +func (hood *Hood) FindOne(out interface{}) error { + hood.Limit(1) + panicMsg := errors.New("expected pointer to struct slice") + if x := reflect.TypeOf(out).Kind(); x != reflect.Ptr { + panic(panicMsg) + } + ptrVal := reflect.Indirect(reflect.ValueOf(out)) + if x := ptrVal.Kind(); x != reflect.Struct { + panic(panicMsg) + } + sType := reflect.MakeSlice(reflect.SliceOf(ptrVal.Type()), 0, 0) + pSlice := reflect.New(sType.Type()).Interface() + err := hood.Find(pSlice) + found := reflect.Indirect(reflect.ValueOf(pSlice)).Index(0).Interface() + reflect.ValueOf(out).Elem().Set(reflect.ValueOf(found)) + + return err +} // FindSql performs a find using the specified custom sql query and arguments and // writes the results to the specified out interface{}. diff --git a/sqlite3.go b/sqlite3.go new file mode 100644 index 0000000..871c42c --- /dev/null +++ b/sqlite3.go @@ -0,0 +1,65 @@ +package hood + +import ( + "fmt" + "reflect" + "time" +) + +func init() { + RegisterDialect("sqlite3", NewSqlite3()) +} + +type sqlite3 struct { + base +} + +func NewSqlite3() Dialect { + d := &sqlite3{} + d.base.Dialect = d + return d +} + +func (d *sqlite3) NextMarker(pos *int) string { + return "?" +} + +func (d *sqlite3) Quote(s string) string { + return fmt.Sprintf("`%s`", s) +} + +func (d *sqlite3) ParseBool(value reflect.Value) bool { + return value.Int() != 0 +} + +func (d *sqlite3) SqlType(f interface{}, size int) string { + switch f.(type) { + case Id: + return "INTEGER" + case time.Time, Created, Updated: + return "timestamp" + case bool: + return "boolean" + case int, int8, int16, int32, uint, uint8, uint16, uint32: + return "int" + case int64, uint64: + return "bigint" + case float32, float64: + return "double" + case []byte: + if size > 0 && size < 65532 { + return fmt.Sprintf("varbinary(%d)", size) + } + return "longblob" + case string: + if size > 0 && size < 65532 { + return fmt.Sprintf("varchar(%d)", size) + } + return "longtext" + } + panic("invalid sql type") +} + +func (d *sqlite3) KeywordAutoIncrement() string { + return "AUTOINCREMENT" +}