1// Copyright (C) MongoDB, Inc. 2017-present. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); you may 4// not use this file except in compliance with the License. You may obtain 5// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 6 7// Package primitive contains types similar to Go primitives for BSON types can do not have direct 8// Go primitive representations. 9package primitive // import "go.mongodb.org/mongo-driver/bson/primitive" 10 11import ( 12 "bytes" 13 "encoding/json" 14 "fmt" 15 "time" 16) 17 18// Binary represents a BSON binary value. 19type Binary struct { 20 Subtype byte 21 Data []byte 22} 23 24// Equal compares bp to bp2 and returns true is the are equal. 25func (bp Binary) Equal(bp2 Binary) bool { 26 if bp.Subtype != bp2.Subtype { 27 return false 28 } 29 return bytes.Equal(bp.Data, bp2.Data) 30} 31 32// IsZero returns if bp is the empty Binary 33func (bp Binary) IsZero() bool { 34 return bp.Subtype == 0 && len(bp.Data) == 0 35} 36 37// Undefined represents the BSON undefined value type. 38type Undefined struct{} 39 40// DateTime represents the BSON datetime value. 41type DateTime int64 42 43// MarshalJSON marshal to time type 44func (d DateTime) MarshalJSON() ([]byte, error) { 45 return json.Marshal(d.Time()) 46} 47 48// Time returns the date as a time type. 49func (d DateTime) Time() time.Time { 50 return time.Unix(int64(d)/1000, int64(d)%1000*1000000) 51} 52 53// NewDateTimeFromTime creates a new DateTime from a Time. 54func NewDateTimeFromTime(t time.Time) DateTime { 55 return DateTime(t.UnixNano() / 1000000) 56} 57 58// Null represents the BSON null value. 59type Null struct{} 60 61// Regex represents a BSON regex value. 62type Regex struct { 63 Pattern string 64 Options string 65} 66 67func (rp Regex) String() string { 68 return fmt.Sprintf(`{"pattern": "%s", "options": "%s"}`, rp.Pattern, rp.Options) 69} 70 71// Equal compares rp to rp2 and returns true is the are equal. 72func (rp Regex) Equal(rp2 Regex) bool { 73 return rp.Pattern == rp2.Pattern && rp.Options == rp.Options 74} 75 76// IsZero returns if rp is the empty Regex 77func (rp Regex) IsZero() bool { 78 return rp.Pattern == "" && rp.Options == "" 79} 80 81// DBPointer represents a BSON dbpointer value. 82type DBPointer struct { 83 DB string 84 Pointer ObjectID 85} 86 87func (d DBPointer) String() string { 88 return fmt.Sprintf(`{"db": "%s", "pointer": "%s"}`, d.DB, d.Pointer) 89} 90 91// Equal compares d to d2 and returns true is the are equal. 92func (d DBPointer) Equal(d2 DBPointer) bool { 93 return d.DB == d2.DB && bytes.Equal(d.Pointer[:], d2.Pointer[:]) 94} 95 96// IsZero returns if d is the empty DBPointer 97func (d DBPointer) IsZero() bool { 98 return d.DB == "" && d.Pointer.IsZero() 99} 100 101// JavaScript represents a BSON JavaScript code value. 102type JavaScript string 103 104// Symbol represents a BSON symbol value. 105type Symbol string 106 107// CodeWithScope represents a BSON JavaScript code with scope value. 108type CodeWithScope struct { 109 Code JavaScript 110 Scope interface{} 111} 112 113func (cws CodeWithScope) String() string { 114 return fmt.Sprintf(`{"code": "%s", "scope": %v}`, cws.Code, cws.Scope) 115} 116 117// Timestamp represents a BSON timestamp value. 118type Timestamp struct { 119 T uint32 120 I uint32 121} 122 123// Equal compares tp to tp2 and returns true is the are equal. 124func (tp Timestamp) Equal(tp2 Timestamp) bool { 125 return tp.T == tp2.T && tp.I == tp2.I 126} 127 128// IsZero returns if tp is the zero Timestamp 129func (tp Timestamp) IsZero() bool { 130 return tp.T == 0 && tp.I == 0 131} 132 133// CompareTimestamp returns an integer comparing two Timestamps, where T is compared first, followed by I. 134// Returns 0 if tp = tp2, 1 if tp > tp2, -1 if tp < tp2. 135func CompareTimestamp(tp, tp2 Timestamp) int { 136 if tp.Equal(tp2) { 137 return 0 138 } 139 140 if tp.T > tp2.T { 141 return 1 142 } 143 if tp.T < tp2.T { 144 return -1 145 } 146 // Compare I values because T values are equal 147 if tp.I > tp2.I { 148 return 1 149 } 150 return -1 151} 152 153// MinKey represents the BSON minkey value. 154type MinKey struct{} 155 156// MaxKey represents the BSON maxkey value. 157type MaxKey struct{} 158 159// D is an ordered representation of a BSON document. This type should be used when the order of the elements matters, 160// such as MongoDB command documents. If the order of the elements does not matter, an M should be used instead. 161// 162// Example usage: 163// 164// bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}} 165type D []E 166 167// Map creates a map from the elements of the D. 168func (d D) Map() M { 169 m := make(M, len(d)) 170 for _, e := range d { 171 m[e.Key] = e.Value 172 } 173 return m 174} 175 176// E represents a BSON element for a D. It is usually used inside a D. 177type E struct { 178 Key string 179 Value interface{} 180} 181 182// M is an unordered representation of a BSON document. This type should be used when the order of the elements does not 183// matter. This type is handled as a regular map[string]interface{} when encoding and decoding. Elements will be 184// serialized in an undefined, random order. If the order of the elements matters, a D should be used instead. 185// 186// Example usage: 187// 188// bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}. 189type M map[string]interface{} 190 191// An A is an ordered representation of a BSON array. 192// 193// Example usage: 194// 195// bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}} 196type A []interface{} 197