github.com/dgraph-io/dgraph@v1.2.8/types/scalar_types.go (about) 1 /* 2 * Copyright 2016-2018 Dgraph Labs, Inc. and Contributors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package types 18 19 import ( 20 "time" 21 22 "github.com/dgraph-io/dgraph/protos/pb" 23 geom "github.com/twpayne/go-geom" 24 ) 25 26 const nanoSecondsInSec = 1000000000 27 28 // Note: These ids are stored in the posting lists to indicate the type 29 // of the data. The order *cannot* be changed without breaking existing 30 // data. When adding a new type *always* add to the end of this list. 31 // Never delete anything from this list even if it becomes unused. 32 const ( 33 // DefaultID represents the default type. 34 DefaultID = TypeID(pb.Posting_DEFAULT) 35 // BinaryID represents the binary data type. 36 BinaryID = TypeID(pb.Posting_BINARY) 37 // IntID represents the integer type. 38 IntID = TypeID(pb.Posting_INT) 39 // FloatID represents the floating-point number type. 40 FloatID = TypeID(pb.Posting_FLOAT) 41 // FloatID represents the boolean type. 42 BoolID = TypeID(pb.Posting_BOOL) 43 // DateTimeID represents the datetime type. 44 DateTimeID = TypeID(pb.Posting_DATETIME) 45 // GeoID represents the geo-location data type. 46 GeoID = TypeID(pb.Posting_GEO) 47 // UidID represents the uid type. 48 UidID = TypeID(pb.Posting_UID) 49 // PasswordID represents the password type. 50 PasswordID = TypeID(pb.Posting_PASSWORD) 51 // StringID represents the string type. 52 StringID = TypeID(pb.Posting_STRING) 53 // UndefinedID represents the undefined type. 54 UndefinedID = TypeID(100) 55 ) 56 57 var typeNameMap = map[string]TypeID{ 58 "default": DefaultID, 59 "binary": BinaryID, 60 "int": IntID, 61 "float": FloatID, 62 "bool": BoolID, 63 "datetime": DateTimeID, 64 "geo": GeoID, 65 "uid": UidID, 66 "string": StringID, 67 "password": PasswordID, 68 } 69 70 // TypeID represents the type of the data. 71 type TypeID pb.Posting_ValType 72 73 // Enum takes a TypeID value and returns the corresponding ValType enum value. 74 func (t TypeID) Enum() pb.Posting_ValType { 75 return pb.Posting_ValType(t) 76 } 77 78 // Name returns the name of the type. 79 func (t TypeID) Name() string { 80 switch t { 81 case DefaultID: 82 return "default" 83 case BinaryID: 84 return "binary" 85 case IntID: 86 return "int" 87 case FloatID: 88 return "float" 89 case BoolID: 90 return "bool" 91 case DateTimeID: 92 return "datetime" 93 case GeoID: 94 return "geo" 95 case UidID: 96 return "uid" 97 case StringID: 98 return "string" 99 case PasswordID: 100 return "password" 101 } 102 return "" 103 } 104 105 // Val is a value with type information. 106 type Val struct { 107 Tid TypeID 108 Value interface{} 109 } 110 111 // Safe ensures that Val's Value is not nil. This is useful when doing type 112 // assertions and default values might be involved. 113 // This function won't change the original v.Value, may it be nil. 114 // See: "Default value vars" in `fillVars()` 115 // Returns a safe v.Value suitable for type assertions. 116 func (v Val) Safe() interface{} { 117 if v.Value == nil { 118 // get zero value for this v.Tid 119 va := ValueForType(v.Tid) 120 return va.Value 121 } 122 return v.Value 123 } 124 125 // TypeForName returns the type corresponding to the given name. 126 // If name is not recognized, it returns nil. 127 func TypeForName(name string) (TypeID, bool) { 128 t, ok := typeNameMap[name] 129 return t, ok 130 } 131 132 // IsScalar returns whether the type is a scalar type. 133 func (t TypeID) IsScalar() bool { 134 return t != UidID 135 } 136 137 // IsNumber returns whether the type is a number type. 138 func (t TypeID) IsNumber() bool { 139 return t == IntID || t == FloatID 140 } 141 142 // ValueForType returns the zero value for a type id 143 func ValueForType(id TypeID) Val { 144 switch id { 145 case BinaryID: 146 var b []byte 147 return Val{BinaryID, &b} 148 149 case IntID: 150 var i int64 151 return Val{IntID, &i} 152 153 case FloatID: 154 var f float64 155 return Val{FloatID, &f} 156 157 case BoolID: 158 var b bool 159 return Val{BoolID, &b} 160 161 case DateTimeID: 162 var t time.Time 163 return Val{DateTimeID, &t} 164 165 case StringID: 166 var s string 167 return Val{StringID, s} 168 169 case DefaultID: 170 var s string 171 return Val{DefaultID, s} 172 173 case GeoID: 174 var g geom.T 175 return Val{GeoID, &g} 176 177 case UidID: 178 var i uint64 179 return Val{UidID, &i} 180 181 case PasswordID: 182 var p string 183 return Val{PasswordID, p} 184 185 default: 186 return Val{} 187 } 188 } 189 190 // ParseTime parses the time from string trying various datetime formats. 191 // By default, Go parses time in UTC unless specified in the data itself. 192 func ParseTime(val string) (time.Time, error) { 193 var t time.Time 194 if err := t.UnmarshalText([]byte(val)); err == nil { 195 return t, err 196 } 197 if t, err := time.Parse(dateFormatYMDZone, val); err == nil { 198 return t, err 199 } 200 // try without timezone 201 if t, err := time.Parse(dateTimeFormat, val); err == nil { 202 return t, err 203 } 204 if t, err := time.Parse(dateFormatYMD, val); err == nil { 205 return t, err 206 } 207 if t, err := time.Parse(dateFormatYM, val); err == nil { 208 return t, err 209 } 210 return time.Parse(dateFormatY, val) 211 } 212 213 const dateFormatYMDZone = "2006-01-02 15:04:05 -0700 MST" 214 const dateFormatYMD = "2006-01-02" 215 const dateFormatYM = "2006-01" 216 const dateFormatY = "2006" 217 const dateTimeFormat = "2006-01-02T15:04:05"