summaryrefslogtreecommitdiffstats
path: root/pkg/types/unix_milli.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/types/unix_milli.go')
-rw-r--r--pkg/types/unix_milli.go95
1 files changed, 95 insertions, 0 deletions
diff --git a/pkg/types/unix_milli.go b/pkg/types/unix_milli.go
new file mode 100644
index 0000000..203cdf6
--- /dev/null
+++ b/pkg/types/unix_milli.go
@@ -0,0 +1,95 @@
+package types
+
+import (
+ "database/sql"
+ "database/sql/driver"
+ "encoding"
+ "encoding/json"
+ "github.com/icinga/icingadb/internal"
+ "github.com/icinga/icingadb/pkg/utils"
+ "github.com/pkg/errors"
+ "strconv"
+ "time"
+)
+
+// UnixMilli is a nullable millisecond UNIX timestamp in databases and JSON.
+type UnixMilli time.Time
+
+// Time returns the time.Time conversion of UnixMilli.
+func (t UnixMilli) Time() time.Time {
+ return time.Time(t)
+}
+
+// MarshalJSON implements the json.Marshaler interface.
+// Marshals to milliseconds. Supports JSON null.
+func (t UnixMilli) MarshalJSON() ([]byte, error) {
+ if time.Time(t).IsZero() {
+ return nil, nil
+ }
+
+ return []byte(strconv.FormatInt(time.Time(t).UnixMilli(), 10)), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+func (t *UnixMilli) UnmarshalText(text []byte) error {
+ parsed, err := strconv.ParseFloat(string(text), 64)
+ if err != nil {
+ return internal.CantParseFloat64(err, string(text))
+ }
+
+ *t = UnixMilli(utils.FromUnixMilli(int64(parsed)))
+ return nil
+}
+
+// UnmarshalJSON implements the json.Unmarshaler interface.
+// Unmarshals from milliseconds. Supports JSON null.
+func (t *UnixMilli) UnmarshalJSON(data []byte) error {
+ if string(data) == "null" || len(data) == 0 {
+ return nil
+ }
+
+ ms, err := strconv.ParseFloat(string(data), 64)
+ if err != nil {
+ return internal.CantParseFloat64(err, string(data))
+ }
+ tt := utils.FromUnixMilli(int64(ms))
+ *t = UnixMilli(tt)
+
+ return nil
+}
+
+// Scan implements the sql.Scanner interface.
+// Scans from milliseconds. Supports SQL NULL.
+func (t *UnixMilli) Scan(src interface{}) error {
+ if src == nil {
+ return nil
+ }
+
+ v, ok := src.(int64)
+ if !ok {
+ return errors.Errorf("bad int64 type assertion from %#v", src)
+ }
+ tt := utils.FromUnixMilli(v)
+ *t = UnixMilli(tt)
+
+ return nil
+}
+
+// Value implements the driver.Valuer interface.
+// Returns milliseconds. Supports SQL NULL.
+func (t UnixMilli) Value() (driver.Value, error) {
+ if t.Time().IsZero() {
+ return nil, nil
+ }
+
+ return t.Time().UnixMilli(), nil
+}
+
+// Assert interface compliance.
+var (
+ _ json.Marshaler = (*UnixMilli)(nil)
+ _ encoding.TextUnmarshaler = (*UnixMilli)(nil)
+ _ json.Unmarshaler = (*UnixMilli)(nil)
+ _ sql.Scanner = (*UnixMilli)(nil)
+ _ driver.Valuer = (*UnixMilli)(nil)
+)