1/* 2Copyright 2017 Google LLC 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package spanner 18 19import ( 20 "bytes" 21 "fmt" 22 "time" 23 24 "cloud.google.com/go/civil" 25 proto3 "github.com/golang/protobuf/ptypes/struct" 26 sppb "google.golang.org/genproto/googleapis/spanner/v1" 27 "google.golang.org/grpc/codes" 28) 29 30// A Key can be either a Cloud Spanner row's primary key or a secondary index 31// key. It is essentially an interface{} array, which represents a set of Cloud 32// Spanner columns. A Key can be used as: 33// 34// - A primary key which uniquely identifies a Cloud Spanner row. 35// - A secondary index key which maps to a set of Cloud Spanner rows indexed under it. 36// - An endpoint of primary key/secondary index ranges; see the KeyRange type. 37// 38// Rows that are identified by the Key type are outputs of read operation or 39// targets of delete operation in a mutation. Note that for 40// Insert/Update/InsertOrUpdate/Update mutation types, although they don't 41// require a primary key explicitly, the column list provided must contain 42// enough columns that can comprise a primary key. 43// 44// Keys are easy to construct. For example, suppose you have a table with a 45// primary key of username and product ID. To make a key for this table: 46// 47// key := spanner.Key{"john", 16} 48// 49// See the description of Row and Mutation types for how Go types are mapped to 50// Cloud Spanner types. For convenience, Key type supports a wide range of Go 51// types: 52// - int, int8, int16, int32, int64, and NullInt64 are mapped to Cloud Spanner's INT64 type. 53// - uint8, uint16 and uint32 are also mapped to Cloud Spanner's INT64 type. 54// - float32, float64, NullFloat64 are mapped to Cloud Spanner's FLOAT64 type. 55// - bool and NullBool are mapped to Cloud Spanner's BOOL type. 56// - []byte is mapped to Cloud Spanner's BYTES type. 57// - string and NullString are mapped to Cloud Spanner's STRING type. 58// - time.Time and NullTime are mapped to Cloud Spanner's TIMESTAMP type. 59// - civil.Date and NullDate are mapped to Cloud Spanner's DATE type. 60type Key []interface{} 61 62// errInvdKeyPartType returns error for unsupported key part type. 63func errInvdKeyPartType(part interface{}) error { 64 return spannerErrorf(codes.InvalidArgument, "key part has unsupported type %T", part) 65} 66 67// keyPartValue converts a part of the Key (which is a valid Cloud Spanner type) 68// into a proto3.Value. Used for encoding Key type into protobuf. 69func keyPartValue(part interface{}) (pb *proto3.Value, err error) { 70 switch v := part.(type) { 71 case int: 72 pb, _, err = encodeValue(int64(v)) 73 case int8: 74 pb, _, err = encodeValue(int64(v)) 75 case int16: 76 pb, _, err = encodeValue(int64(v)) 77 case int32: 78 pb, _, err = encodeValue(int64(v)) 79 case uint8: 80 pb, _, err = encodeValue(int64(v)) 81 case uint16: 82 pb, _, err = encodeValue(int64(v)) 83 case uint32: 84 pb, _, err = encodeValue(int64(v)) 85 case float32: 86 pb, _, err = encodeValue(float64(v)) 87 case int64, float64, NullInt64, NullFloat64, bool, NullBool, []byte, string, NullString, time.Time, civil.Date, NullTime, NullDate: 88 pb, _, err = encodeValue(v) 89 case Encoder: 90 part, err = v.EncodeSpanner() 91 if err != nil { 92 return nil, err 93 } 94 pb, err = keyPartValue(part) 95 default: 96 return nil, errInvdKeyPartType(v) 97 } 98 return pb, err 99} 100 101// proto converts a spanner.Key into a proto3.ListValue. 102func (key Key) proto() (*proto3.ListValue, error) { 103 lv := &proto3.ListValue{} 104 lv.Values = make([]*proto3.Value, 0, len(key)) 105 for _, part := range key { 106 v, err := keyPartValue(part) 107 if err != nil { 108 return nil, err 109 } 110 lv.Values = append(lv.Values, v) 111 } 112 return lv, nil 113} 114 115// keySetProto lets a single Key act as a KeySet. 116func (key Key) keySetProto() (*sppb.KeySet, error) { 117 kp, err := key.proto() 118 if err != nil { 119 return nil, err 120 } 121 return &sppb.KeySet{Keys: []*proto3.ListValue{kp}}, nil 122} 123 124// String implements fmt.Stringer for Key. For string, []byte and NullString, it 125// prints the uninterpreted bytes of their contents, leaving caller with the 126// opportunity to escape the output. 127func (key Key) String() string { 128 b := &bytes.Buffer{} 129 fmt.Fprint(b, "(") 130 for i, part := range []interface{}(key) { 131 if i != 0 { 132 fmt.Fprint(b, ",") 133 } 134 key.elemString(b, part) 135 } 136 fmt.Fprint(b, ")") 137 return b.String() 138} 139 140func (key Key) elemString(b *bytes.Buffer, part interface{}) { 141 switch v := part.(type) { 142 case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, float32, float64, bool: 143 // Use %v to print numeric types and bool. 144 fmt.Fprintf(b, "%v", v) 145 case string: 146 fmt.Fprintf(b, "%q", v) 147 case []byte: 148 if v != nil { 149 fmt.Fprintf(b, "%q", v) 150 } else { 151 fmt.Fprint(b, nullString) 152 } 153 case NullInt64, NullFloat64, NullBool: 154 // The above types implement fmt.Stringer. 155 fmt.Fprintf(b, "%s", v) 156 case NullString, NullDate, NullTime: 157 // Quote the returned string if it is not null. 158 if v.(NullableValue).IsNull() { 159 fmt.Fprintf(b, "%s", nullString) 160 } else { 161 fmt.Fprintf(b, "%q", v) 162 } 163 case civil.Date: 164 fmt.Fprintf(b, "%q", v) 165 case time.Time: 166 fmt.Fprintf(b, "%q", v.Format(time.RFC3339Nano)) 167 case Encoder: 168 var err error 169 part, err = v.EncodeSpanner() 170 if err != nil { 171 fmt.Fprintf(b, "error") 172 } else { 173 key.elemString(b, part) 174 } 175 default: 176 fmt.Fprintf(b, "%v", v) 177 } 178} 179 180// AsPrefix returns a KeyRange for all keys where k is the prefix. 181func (key Key) AsPrefix() KeyRange { 182 return KeyRange{ 183 Start: key, 184 End: key, 185 Kind: ClosedClosed, 186 } 187} 188 189// KeyRangeKind describes the kind of interval represented by a KeyRange: 190// whether it is open or closed on the left and right. 191type KeyRangeKind int 192 193const ( 194 // ClosedOpen is closed on the left and open on the right: the Start 195 // key is included, the End key is excluded. 196 ClosedOpen KeyRangeKind = iota 197 198 // ClosedClosed is closed on the left and the right: both keys are included. 199 ClosedClosed 200 201 // OpenClosed is open on the left and closed on the right: the Start 202 // key is excluded, the End key is included. 203 OpenClosed 204 205 // OpenOpen is open on the left and the right: neither key is included. 206 OpenOpen 207) 208 209// A KeyRange represents a range of rows in a table or index. 210// 211// A range has a Start key and an End key. IncludeStart and IncludeEnd 212// indicate whether the Start and End keys are included in the range. 213// 214// For example, consider the following table definition: 215// 216// CREATE TABLE UserEvents ( 217// UserName STRING(MAX), 218// EventDate STRING(10), 219// ) PRIMARY KEY(UserName, EventDate); 220// 221// The following keys name rows in this table: 222// 223// spanner.Key{"Bob", "2014-09-23"} 224// spanner.Key{"Alfred", "2015-06-12"} 225// 226// Since the UserEvents table's PRIMARY KEY clause names two columns, each 227// UserEvents key has two elements; the first is the UserName, and the second 228// is the EventDate. 229// 230// Key ranges with multiple components are interpreted lexicographically by 231// component using the table or index key's declared sort order. For example, 232// the following range returns all events for user "Bob" that occurred in the 233// year 2015: 234// 235// spanner.KeyRange{ 236// Start: spanner.Key{"Bob", "2015-01-01"}, 237// End: spanner.Key{"Bob", "2015-12-31"}, 238// Kind: ClosedClosed, 239// } 240// 241// Start and end keys can omit trailing key components. This affects the 242// inclusion and exclusion of rows that exactly match the provided key 243// components: if IncludeStart is true, then rows that exactly match the 244// provided components of the Start key are included; if IncludeStart is false 245// then rows that exactly match are not included. IncludeEnd and End key 246// behave in the same fashion. 247// 248// For example, the following range includes all events for "Bob" that occurred 249// during and after the year 2000: 250// 251// spanner.KeyRange{ 252// Start: spanner.Key{"Bob", "2000-01-01"}, 253// End: spanner.Key{"Bob"}, 254// Kind: ClosedClosed, 255// } 256// 257// The next example retrieves all events for "Bob": 258// 259// spanner.Key{"Bob"}.AsPrefix() 260// 261// To retrieve events before the year 2000: 262// 263// spanner.KeyRange{ 264// Start: spanner.Key{"Bob"}, 265// End: spanner.Key{"Bob", "2000-01-01"}, 266// Kind: ClosedOpen, 267// } 268// 269// Although we specified a Kind for this KeyRange, we didn't need to, because 270// the default is ClosedOpen. In later examples we'll omit Kind if it is 271// ClosedOpen. 272// 273// The following range includes all rows in a table or under a 274// index: 275// 276// spanner.AllKeys() 277// 278// This range returns all users whose UserName begins with any 279// character from A to C: 280// 281// spanner.KeyRange{ 282// Start: spanner.Key{"A"}, 283// End: spanner.Key{"D"}, 284// } 285// 286// This range returns all users whose UserName begins with B: 287// 288// spanner.KeyRange{ 289// Start: spanner.Key{"B"}, 290// End: spanner.Key{"C"}, 291// } 292// 293// Key ranges honor column sort order. For example, suppose a table is defined 294// as follows: 295// 296// CREATE TABLE DescendingSortedTable { 297// Key INT64, 298// ... 299// ) PRIMARY KEY(Key DESC); 300// 301// The following range retrieves all rows with key values between 1 and 100 302// inclusive: 303// 304// spanner.KeyRange{ 305// Start: spanner.Key{100}, 306// End: spanner.Key{1}, 307// Kind: ClosedClosed, 308// } 309// 310// Note that 100 is passed as the start, and 1 is passed as the end, because 311// Key is a descending column in the schema. 312type KeyRange struct { 313 // Start specifies the left boundary of the key range; End specifies 314 // the right boundary of the key range. 315 Start, End Key 316 317 // Kind describes whether the boundaries of the key range include 318 // their keys. 319 Kind KeyRangeKind 320} 321 322// String implements fmt.Stringer for KeyRange type. 323func (r KeyRange) String() string { 324 var left, right string 325 switch r.Kind { 326 case ClosedClosed: 327 left, right = "[", "]" 328 case ClosedOpen: 329 left, right = "[", ")" 330 case OpenClosed: 331 left, right = "(", "]" 332 case OpenOpen: 333 left, right = "(", ")" 334 default: 335 left, right = "?", "?" 336 } 337 return fmt.Sprintf("%s%s,%s%s", left, r.Start, r.End, right) 338} 339 340// proto converts KeyRange into sppb.KeyRange. 341func (r KeyRange) proto() (*sppb.KeyRange, error) { 342 var err error 343 var start, end *proto3.ListValue 344 pb := &sppb.KeyRange{} 345 if start, err = r.Start.proto(); err != nil { 346 return nil, err 347 } 348 if end, err = r.End.proto(); err != nil { 349 return nil, err 350 } 351 if r.Kind == ClosedClosed || r.Kind == ClosedOpen { 352 pb.StartKeyType = &sppb.KeyRange_StartClosed{StartClosed: start} 353 } else { 354 pb.StartKeyType = &sppb.KeyRange_StartOpen{StartOpen: start} 355 } 356 if r.Kind == ClosedClosed || r.Kind == OpenClosed { 357 pb.EndKeyType = &sppb.KeyRange_EndClosed{EndClosed: end} 358 } else { 359 pb.EndKeyType = &sppb.KeyRange_EndOpen{EndOpen: end} 360 } 361 return pb, nil 362} 363 364// keySetProto lets a KeyRange act as a KeySet. 365func (r KeyRange) keySetProto() (*sppb.KeySet, error) { 366 rp, err := r.proto() 367 if err != nil { 368 return nil, err 369 } 370 return &sppb.KeySet{Ranges: []*sppb.KeyRange{rp}}, nil 371} 372 373// A KeySet defines a collection of Cloud Spanner keys and/or key ranges. All 374// the keys are expected to be in the same table or index. The keys need not be 375// sorted in any particular way. 376// 377// An individual Key can act as a KeySet, as can a KeyRange. Use the KeySets 378// function to create a KeySet consisting of multiple Keys and KeyRanges. To 379// obtain an empty KeySet, call KeySets with no arguments. 380// 381// If the same key is specified multiple times in the set (for example if two 382// ranges, two keys, or a key and a range overlap), the Cloud Spanner backend 383// behaves as if the key were only specified once. 384type KeySet interface { 385 keySetProto() (*sppb.KeySet, error) 386} 387 388// AllKeys returns a KeySet that represents all Keys of a table or a index. 389func AllKeys() KeySet { 390 return all{} 391} 392 393type all struct{} 394 395func (all) keySetProto() (*sppb.KeySet, error) { 396 return &sppb.KeySet{All: true}, nil 397} 398 399// KeySets returns the union of the KeySets. If any of the KeySets is AllKeys, 400// then the resulting KeySet will be equivalent to AllKeys. 401func KeySets(keySets ...KeySet) KeySet { 402 u := make(union, len(keySets)) 403 copy(u, keySets) 404 return u 405} 406 407// KeySetFromKeys returns a KeySet containing the given slice of keys. 408func KeySetFromKeys(keys ...Key) KeySet { 409 u := make(union, len(keys)) 410 for i, k := range keys { 411 u[i] = k 412 } 413 return u 414} 415 416type union []KeySet 417 418func (u union) keySetProto() (*sppb.KeySet, error) { 419 upb := &sppb.KeySet{} 420 for _, ks := range u { 421 pb, err := ks.keySetProto() 422 if err != nil { 423 return nil, err 424 } 425 if pb.All { 426 return pb, nil 427 } 428 upb.Keys = append(upb.Keys, pb.Keys...) 429 upb.Ranges = append(upb.Ranges, pb.Ranges...) 430 } 431 return upb, nil 432} 433