From dcd44f511811bacb58241dd4de752177e7286967 Mon Sep 17 00:00:00 2001 From: lye Date: Sat, 3 Nov 2012 19:45:58 -0500 Subject: [PATCH] Add support for extracting 2006-01-02 formatted timestamps. SQLite3 stores timestamps very naively -- they're completely untyped, and can contain any value. The previous implementation always inserts values in the 'datetime' format, and returns an error when attempting to extract a field with a different format. Some legacy databases, unfortunately, were generated using the 'date' SQLite3 function, which produces rows in the '2006-01-02' format. This patch adds a special case so that these rows can be extracted without error. --- sqlite3.go | 6 ++++- sqlite3_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/sqlite3.go b/sqlite3.go index 270403d..90a1241 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -27,6 +27,7 @@ import ( ) const SQLiteTimestampFormat = "2006-01-02 15:04:05" +const SQLiteDateFormat = "2006-01-02" func init() { sql.Register("sqlite3", &SQLiteDriver{}) @@ -313,7 +314,10 @@ func (rc *SQLiteRows) Next(dest []driver.Value) error { if rc.decltype[i] == "timestamp" { dest[i], err = time.Parse(SQLiteTimestampFormat, s) if err != nil { - return err + dest[i], err = time.Parse(SQLiteDateFormat, s) + if err != nil { + return err + } } } else { dest[i] = s diff --git a/sqlite3_test.go b/sqlite3_test.go index aaeb096..4ff8d6c 100644 --- a/sqlite3_test.go +++ b/sqlite3_test.go @@ -400,3 +400,63 @@ func TestBoolean(t *testing.T) { t.Error("Expected error from \"nonsense\" bool") } } + +func TestDateOnlyTimestamp(t *testing.T) { + // make sure that timestamps without times are extractable. these are generated when + // e.g., you use the sqlite `DATE()` built-in. + + db, er := sql.Open("sqlite3", "db.sqlite") + if er != nil { + t.Fatal(er) + } + defer func() { + db.Close() + os.Remove("db.sqlite") + }() + + _, er = db.Exec(` + CREATE TABLE test + ( entry_id INTEGER PRIMARY KEY AUTOINCREMENT + , entry_published TIMESTAMP NOT NULL + ) + `) + if er != nil { + t.Fatal(er) + } + + _, er = db.Exec(` + INSERT INTO test VALUES ( 1, '2012-11-04') + `) + if er != nil { + t.Fatal(er) + } + + rows, er := db.Query("SELECT entry_id, entry_published FROM test") + if er != nil { + t.Fatal(er) + } + defer rows.Close() + + if !rows.Next() { + if er := rows.Err() ; er != nil { + t.Fatal(er) + } else { + t.Fatalf("Unable to extract row containing date-only timestamp") + } + } + + var entryId int64 + var entryPublished time.Time + + if er := rows.Scan(&entryId, &entryPublished) ; er != nil { + t.Fatal(er) + } + + if entryId != 1 { + t.Errorf("EntryId does not match inserted value") + } + + if entryPublished.Year() != 2012 || entryPublished.Month() != 11 || entryPublished.Day() != 4 { + t.Errorf("Extracted time does not match inserted value") + } +}