Permalink
Browse files

represent BSON date as time.Time

  • Loading branch information...
1 parent d9f1a23 commit 43e24c17eea49d74cc3df4ddd3c3391129140cd3 @mikejs committed Nov 22, 2009
Showing with 32 additions and 13 deletions.
  1. +12 −10 bson.go
  2. +7 −3 bson_struct.go
  3. +13 −0 bson_test.go
View
22 bson.go
@@ -11,6 +11,7 @@ import (
"io";
"fmt";
"math";
+ "time";
"bytes";
"strconv";
"encoding/binary";
@@ -47,7 +48,7 @@ type BSON interface {
String() string;
OID() []byte;
Bool() bool;
- Date() int64;
+ Date() *time.Time;
Regex() (string, string);
Int() int32;
Long() int64;
@@ -68,7 +69,7 @@ func (*_Null) Number() float64 { return 0 }
func (*_Null) String() string { return "null" }
func (*_Null) OID() []byte { return nil }
func (*_Null) Bool() bool { return false }
-func (*_Null) Date() int64 { return 0 }
+func (*_Null) Date() *time.Time { return nil }
func (*_Null) Regex() (string, string) { return "", "" }
func (*_Null) Int() int32 { return 0 }
func (*_Null) Long() int64 { return 0 }
@@ -205,15 +206,16 @@ func (b *_Boolean) Bytes() []byte {
}
type _Date struct {
- value int64;
+ value *time.Time;
_Null;
}
-func (d *_Date) Kind() int { return DateKind }
-func (d *_Date) Date() int64 { return d.value }
+func (d *_Date) Kind() int { return DateKind }
+func (d *_Date) Date() *time.Time { return d.value }
func (d *_Date) Bytes() []byte {
b := []byte{0, 0, 0, 0, 0, 0, 0, 0};
- binary.LittleEndian.PutUint64(b, uint64(d.value));
+ mtime := d.value.Seconds() * 1000;
+ binary.LittleEndian.PutUint64(b, uint64(mtime));
return b;
}
@@ -320,7 +322,7 @@ type Builder interface {
Float64(f float64);
String(s string);
Bool(b bool);
- Date(d int64);
+ Date(d *time.Time);
OID(o []byte);
Regex(regex, options string);
Null();
@@ -373,7 +375,7 @@ func (bb *_BSONBuilder) String(s string) { bb.Put(&_String{s, _Null{}}) }
func (bb *_BSONBuilder) Object() { bb.Put(&_Object{make(map[string]BSON), _Null{}}) }
func (bb *_BSONBuilder) Array() { bb.Put(&_Array{vector.New(0), _Null{}}) }
func (bb *_BSONBuilder) Bool(b bool) { bb.Put(&_Boolean{b, _Null{}}) }
-func (bb *_BSONBuilder) Date(d int64) { bb.Put(&_Date{d, _Null{}}) }
+func (bb *_BSONBuilder) Date(t *time.Time) { bb.Put(&_Date{t, _Null{}}) }
func (bb *_BSONBuilder) Null() { bb.Put(Null) }
func (bb *_BSONBuilder) Regex(regex, options string) {
bb.Put(&_Regex{regex, options, _Null{}})
@@ -461,9 +463,9 @@ func Parse(buf *bytes.Buffer, builder Builder) (err os.Error) {
b2.Bool(false)
}
case DateKind:
- bits, _ := io.ReadAll(io.LimitReader(buf, 4));
+ bits, _ := io.ReadAll(io.LimitReader(buf, 8));
ui64 := binary.LittleEndian.Uint64(bits);
- b2.Date(int64(ui64));
+ b2.Date(time.SecondsToUTC(int64(ui64) / 1000));
case RegexKind:
regex := readCString(buf);
options := readCString(buf);
View
@@ -12,6 +12,7 @@ import (
"fmt";
"os";
"bytes";
+ "time";
"container/vector";
)
@@ -92,12 +93,13 @@ func (b *structBuilder) Int64(i int64) {
}
}
-func (b *structBuilder) Date(d int64) {
+func (b *structBuilder) Date(t *time.Time) {
if b == nil {
return
}
- v := b.val;
- setint(v, d);
+ if v, ok := b.val.(*reflect.PtrValue); ok {
+ v.PointTo(reflect.Indirect(reflect.NewValue(t)))
+ }
}
func (b *structBuilder) Int32(i int32) {
@@ -283,6 +285,8 @@ func Marshal(val interface{}) (BSON, os.Error) {
return &_Long{v, _Null{}}, nil
case int:
return &_Long{int64(v), _Null{}}, nil
+ case *time.Time:
+ return &_Date{v, _Null{}}, nil
}
var value reflect.Value;
View
@@ -8,6 +8,7 @@ import (
"testing";
"mongo";
"fmt";
+ "time";
)
func assertTrue(tf bool, msg string, t *testing.T) {
@@ -54,6 +55,10 @@ func TestUnmarshal(t *testing.T) {
assertTrue(es.Fifth.F == "i" && es.Fifth.V == "e", "unmarshal struct", t);
}
+type ExampleStruct2 struct {
+ Date *time.Time;
+}
+
func TestMarshal(t *testing.T) {
var es1 ExampleStruct;
mongo.Unmarshal(b, &es1);
@@ -69,4 +74,12 @@ func TestMarshal(t *testing.T) {
assertTrue(arr.Elem(0).Long() == 1, "array marshal (0)", t);
assertTrue(arr.Elem(1).Long() == 2, "array marshal (1)", t);
assertTrue(arr.Elem(2).Long() == 3, "array marshal (2)", t);
+
+ d := time.UTC();
+ es2 := &ExampleStruct2{d};
+ bs2, _ = mongo.Marshal(es2);
+ assertTrue(bs2.Get("date").Date().Seconds() == d.Seconds(), "date marshal", t);
+ es2 = new(ExampleStruct2);
+ mongo.Unmarshal(bs2.Bytes(), es2);
+ assertTrue(es2.Date.Seconds() == d.Seconds(), "date unmarshal", t);
}

0 comments on commit 43e24c1

Please sign in to comment.