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"