summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rddb/nulltime.go103
-rw-r--r--rddb/rddb.go12
2 files changed, 108 insertions, 7 deletions
diff --git a/rddb/nulltime.go b/rddb/nulltime.go
new file mode 100644
index 0000000..e34e5f2
--- /dev/null
+++ b/rddb/nulltime.go
@@ -0,0 +1,103 @@
+//
+// rhrd-go
+//
+// The Radio Helsinki Rivendell Go Package
+//
+//
+// Copyright (C) 2016 Christian Pointner <equinox@helsinki.at>
+//
+// This file is part of rhrd-go.
+//
+// rhrd-go is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// rhrd-go is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with rhrd-go. If not, see <http://www.gnu.org/licenses/>.
+//
+
+package rddb
+
+import (
+ "database/sql/driver"
+ "fmt"
+ "time"
+)
+
+//
+// This is from github.com/go-sql-driver/mysql
+//
+
+const (
+ timeFormat = "2006-01-02 15:04:05.999999"
+)
+
+// This NullTime implementation is not driver-specific
+type NullTime struct {
+ Time time.Time
+ Valid bool // Valid is true if Time is not NULL
+}
+
+// Scan implements the Scanner interface.
+// The value type must be time.Time or string / []byte (formatted time-string),
+// otherwise Scan fails.
+func (nt *NullTime) Scan(value interface{}) (err error) {
+ if value == nil {
+ nt.Time, nt.Valid = time.Time{}, false
+ return
+ }
+
+ switch v := value.(type) {
+ case time.Time:
+ nt.Time, nt.Valid = v, true
+ return
+ case []byte:
+ nt.Time, err = parseDateTime(string(v), time.UTC)
+ nt.Valid = (err == nil)
+ return
+ case string:
+ nt.Time, err = parseDateTime(v, time.UTC)
+ nt.Valid = (err == nil)
+ return
+ }
+
+ nt.Valid = false
+ return fmt.Errorf("Can't convert %T to time.Time", value)
+}
+
+// Value implements the driver Valuer interface.
+func (nt NullTime) Value() (driver.Value, error) {
+ if !nt.Valid {
+ return nil, nil
+ }
+ return nt.Time, nil
+}
+
+func parseDateTime(str string, loc *time.Location) (t time.Time, err error) {
+ base := "0000-00-00 00:00:00.0000000"
+ switch len(str) {
+ case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM"
+ if str == base[:len(str)] {
+ return
+ }
+ t, err = time.Parse(timeFormat[:len(str)], str)
+ default:
+ err = fmt.Errorf("invalid time string: %s", str)
+ return
+ }
+
+ // Adjust location
+ if err == nil && loc != time.UTC {
+ y, mo, d := t.Date()
+ h, mi, s := t.Clock()
+ t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
+ }
+
+ return
+}
diff --git a/rddb/rddb.go b/rddb/rddb.go
index d6cd2d3..80cbb38 100644
--- a/rddb/rddb.go
+++ b/rddb/rddb.go
@@ -124,9 +124,9 @@ type CutListEntry struct {
Evergreen bool
Description string
Duration time.Duration
- // Imported time.Time
- NumPlayed uint
- // LastPlayed time.Time
+ Imported NullTime
+ NumPlayed uint
+ LastPlayed NullTime
}
type CartListEntry struct {
@@ -209,8 +209,7 @@ func (db *DB) init() (err error) {
if db.getCartInfoStmt, err = db.dbh.Prepare("select TITLE from CART where TYPE=1 and NUMBER = ?"); err != nil {
return
}
- // if db.getCutInfoStmt, err = db.dbh.Prepare("select CUT_NAME, EVERGREEN, DESCRIPTION, LENGTH, ORIGIN_DATETIME, PLAY_COUNTER, LAST_PLAY_DATETIME from CUTS where CART_NUMBER = ?"); err != nil {
- if db.getCutInfoStmt, err = db.dbh.Prepare("select CUT_NAME, EVERGREEN, DESCRIPTION, LENGTH, PLAY_COUNTER from CUTS where CART_NUMBER = ?"); err != nil {
+ if db.getCutInfoStmt, err = db.dbh.Prepare("select CUT_NAME, EVERGREEN, DESCRIPTION, LENGTH, ORIGIN_DATETIME, PLAY_COUNTER, LAST_PLAY_DATETIME from CUTS where CART_NUMBER = ?"); err != nil {
return
}
@@ -368,8 +367,7 @@ func (db *DB) getCutInfo(cart uint) (cuts []CutListEntry, err error) {
var cutName, evergreen string
var length uint
- // if err = rows.Scan(&cutName, &evergreen, &cut.Description, &length, &cut.Imported, &cut.NumPlayed, &cut.LastPlayed); err != nil {
- if err = rows.Scan(&cutName, &evergreen, &cut.Description, &length, &cut.NumPlayed); err != nil {
+ if err = rows.Scan(&cutName, &evergreen, &cut.Description, &length, &cut.Imported, &cut.NumPlayed, &cut.LastPlayed); err != nil {
return
}