diff options
author | John Gallagher <johnkgallagher@gmail.com> | 2012-04-07 00:17:54 -0400 |
---|---|---|
committer | John Gallagher <johnkgallagher@gmail.com> | 2012-04-07 00:29:24 -0400 |
commit | 3abc337b8e5b94bb6c70aacf053fa3d6c1cc1caf (patch) | |
tree | c3e411dc9523017e034af5a9efbe57f21ae9ef8a /sqlite3.go | |
parent | Fix typo (Tailed -> Failed). (diff) | |
download | golite-3abc337b8e5b94bb6c70aacf053fa3d6c1cc1caf.tar.gz golite-3abc337b8e5b94bb6c70aacf053fa3d6c1cc1caf.tar.xz |
Handle time.Time values with "timestamp" columns.
Diffstat (limited to 'sqlite3.go')
-rw-r--r-- | sqlite3.go | 42 |
1 files changed, 36 insertions, 6 deletions
@@ -23,9 +23,13 @@ import ( "database/sql/driver" "errors" "io" + "strings" + "time" "unsafe" ) +const SQLiteTimestampFormat = "2006-01-02 15:04:05" + func init() { sql.Register("sqlite3", &SQLiteDriver{}) } @@ -194,6 +198,9 @@ func (s *SQLiteStmt) bind(args []driver.Value) error { p = &v[0] } rv = C._sqlite3_bind_blob(s.s, n, unsafe.Pointer(p), C.int(len(v))) + case time.Time: + b := []byte(v.Format(SQLiteTimestampFormat)) + rv = C._sqlite3_bind_text(s.s, n, (*C.char)(unsafe.Pointer(&b[0])), C.int(len(b))) } if rv != C.SQLITE_OK { return errors.New(C.GoString(C.sqlite3_errmsg(s.c.db))) @@ -206,7 +213,7 @@ func (s *SQLiteStmt) Query(args []driver.Value) (driver.Rows, error) { if err := s.bind(args); err != nil { return nil, err } - return &SQLiteRows{s, int(C.sqlite3_column_count(s.s)), nil}, nil + return &SQLiteRows{s, int(C.sqlite3_column_count(s.s)), nil, nil}, nil } type SQLiteResult struct { @@ -233,9 +240,10 @@ func (s *SQLiteStmt) Exec(args []driver.Value) (driver.Result, error) { } type SQLiteRows struct { - s *SQLiteStmt - nc int - cols []string + s *SQLiteStmt + nc int + cols []string + decltype []string } func (rc *SQLiteRows) Close() error { @@ -264,10 +272,23 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error { if rv != C.SQLITE_ROW { return errors.New(C.GoString(C.sqlite3_errmsg(rc.s.c.db))) } + + if rc.decltype == nil { + rc.decltype = make([]string, rc.nc) + for i := 0; i < rc.nc; i++ { + rc.decltype[i] = strings.ToLower(C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))) + } + } + for i := range dest { switch C.sqlite3_column_type(rc.s.s, C.int(i)) { case C.SQLITE_INTEGER: - dest[i] = int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) + val := int64(C.sqlite3_column_int64(rc.s.s, C.int(i))) + if rc.decltype[i] == "timestamp" { + dest[i] = time.Unix(val, 0) + } else { + dest[i] = val + } case C.SQLITE_FLOAT: dest[i] = float64(C.sqlite3_column_double(rc.s.s, C.int(i))) case C.SQLITE_BLOB: @@ -277,7 +298,16 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error { case C.SQLITE_NULL: dest[i] = nil case C.SQLITE_TEXT: - dest[i] = C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i))))) + var err error + s := C.GoString((*C.char)(unsafe.Pointer(C.sqlite3_column_text(rc.s.s, C.int(i))))) + if rc.decltype[i] == "timestamp" { + dest[i], err = time.Parse(SQLiteTimestampFormat, s) + if err != nil { + return err + } + } else { + dest[i] = s + } } } return nil |