You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

309 lines
10 KiB

  1. /*
  2. Copyright 2017 Google LLC
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package spanner
  14. import (
  15. "fmt"
  16. "reflect"
  17. proto3 "github.com/golang/protobuf/ptypes/struct"
  18. sppb "google.golang.org/genproto/googleapis/spanner/v1"
  19. "google.golang.org/grpc/codes"
  20. )
  21. // A Row is a view of a row of data returned by a Cloud Spanner read.
  22. // It consists of a number of columns; the number depends on the columns
  23. // used to construct the read.
  24. //
  25. // The column values can be accessed by index. For instance, if the read specified
  26. // []string{"photo_id", "caption"}, then each row will contain two
  27. // columns: "photo_id" with index 0, and "caption" with index 1.
  28. //
  29. // Column values are decoded by using one of the Column, ColumnByName, or
  30. // Columns methods. The valid values passed to these methods depend on the
  31. // column type. For example:
  32. //
  33. // var photoID int64
  34. // err := row.Column(0, &photoID) // Decode column 0 as an integer.
  35. //
  36. // var caption string
  37. // err := row.Column(1, &caption) // Decode column 1 as a string.
  38. //
  39. // // Decode all the columns.
  40. // err := row.Columns(&photoID, &caption)
  41. //
  42. // Supported types and their corresponding Cloud Spanner column type(s) are:
  43. //
  44. // *string(not NULL), *NullString - STRING
  45. // *[]string, *[]NullString - STRING ARRAY
  46. // *[]byte - BYTES
  47. // *[][]byte - BYTES ARRAY
  48. // *int64(not NULL), *NullInt64 - INT64
  49. // *[]int64, *[]NullInt64 - INT64 ARRAY
  50. // *bool(not NULL), *NullBool - BOOL
  51. // *[]bool, *[]NullBool - BOOL ARRAY
  52. // *float64(not NULL), *NullFloat64 - FLOAT64
  53. // *[]float64, *[]NullFloat64 - FLOAT64 ARRAY
  54. // *time.Time(not NULL), *NullTime - TIMESTAMP
  55. // *[]time.Time, *[]NullTime - TIMESTAMP ARRAY
  56. // *Date(not NULL), *NullDate - DATE
  57. // *[]civil.Date, *[]NullDate - DATE ARRAY
  58. // *[]*some_go_struct, *[]NullRow - STRUCT ARRAY
  59. // *GenericColumnValue - any Cloud Spanner type
  60. //
  61. // For TIMESTAMP columns, the returned time.Time object will be in UTC.
  62. //
  63. // To fetch an array of BYTES, pass a *[][]byte. To fetch an array of (sub)rows, pass
  64. // a *[]spanner.NullRow or a *[]*some_go_struct where some_go_struct holds all
  65. // information of the subrow, see spanner.Row.ToStruct for the mapping between a
  66. // Cloud Spanner row and a Go struct. To fetch an array of other types, pass a
  67. // *[]spanner.NullXXX type of the appropriate type. Use GenericColumnValue when you
  68. // don't know in advance what column type to expect.
  69. //
  70. // Row decodes the row contents lazily; as a result, each call to a getter has
  71. // a chance of returning an error.
  72. //
  73. // A column value may be NULL if the corresponding value is not present in
  74. // Cloud Spanner. The spanner.NullXXX types (spanner.NullInt64 et al.) allow fetching
  75. // values that may be null. A NULL BYTES can be fetched into a *[]byte as nil.
  76. // It is an error to fetch a NULL value into any other type.
  77. type Row struct {
  78. fields []*sppb.StructType_Field
  79. vals []*proto3.Value // keep decoded for now
  80. }
  81. // errNamesValuesMismatch returns error for when columnNames count is not equal
  82. // to columnValues count.
  83. func errNamesValuesMismatch(columnNames []string, columnValues []interface{}) error {
  84. return spannerErrorf(codes.FailedPrecondition,
  85. "different number of names(%v) and values(%v)", len(columnNames), len(columnValues))
  86. }
  87. // NewRow returns a Row containing the supplied data. This can be useful for
  88. // mocking Cloud Spanner Read and Query responses for unit testing.
  89. func NewRow(columnNames []string, columnValues []interface{}) (*Row, error) {
  90. if len(columnValues) != len(columnNames) {
  91. return nil, errNamesValuesMismatch(columnNames, columnValues)
  92. }
  93. r := Row{
  94. fields: make([]*sppb.StructType_Field, len(columnValues)),
  95. vals: make([]*proto3.Value, len(columnValues)),
  96. }
  97. for i := range columnValues {
  98. val, typ, err := encodeValue(columnValues[i])
  99. if err != nil {
  100. return nil, err
  101. }
  102. r.fields[i] = &sppb.StructType_Field{
  103. Name: columnNames[i],
  104. Type: typ,
  105. }
  106. r.vals[i] = val
  107. }
  108. return &r, nil
  109. }
  110. // Size is the number of columns in the row.
  111. func (r *Row) Size() int {
  112. return len(r.fields)
  113. }
  114. // ColumnName returns the name of column i, or empty string for invalid column.
  115. func (r *Row) ColumnName(i int) string {
  116. if i < 0 || i >= len(r.fields) {
  117. return ""
  118. }
  119. return r.fields[i].Name
  120. }
  121. // ColumnIndex returns the index of the column with the given name. The
  122. // comparison is case-sensitive.
  123. func (r *Row) ColumnIndex(name string) (int, error) {
  124. found := false
  125. var index int
  126. if len(r.vals) != len(r.fields) {
  127. return 0, errFieldsMismatchVals(r)
  128. }
  129. for i, f := range r.fields {
  130. if f == nil {
  131. return 0, errNilColType(i)
  132. }
  133. if name == f.Name {
  134. if found {
  135. return 0, errDupColName(name)
  136. }
  137. found = true
  138. index = i
  139. }
  140. }
  141. if !found {
  142. return 0, errColNotFound(name)
  143. }
  144. return index, nil
  145. }
  146. // ColumnNames returns all column names of the row.
  147. func (r *Row) ColumnNames() []string {
  148. var n []string
  149. for _, c := range r.fields {
  150. n = append(n, c.Name)
  151. }
  152. return n
  153. }
  154. // errColIdxOutOfRange returns error for requested column index is out of the
  155. // range of the target Row's columns.
  156. func errColIdxOutOfRange(i int, r *Row) error {
  157. return spannerErrorf(codes.OutOfRange, "column index %d out of range [0,%d)", i, len(r.vals))
  158. }
  159. // errDecodeColumn returns error for not being able to decode a indexed column.
  160. func errDecodeColumn(i int, err error) error {
  161. if err == nil {
  162. return nil
  163. }
  164. se, ok := toSpannerError(err).(*Error)
  165. if !ok {
  166. return spannerErrorf(codes.InvalidArgument, "failed to decode column %v, error = <%v>", i, err)
  167. }
  168. se.decorate(fmt.Sprintf("failed to decode column %v", i))
  169. return se
  170. }
  171. // errFieldsMismatchVals returns error for field count isn't equal to value count in a Row.
  172. func errFieldsMismatchVals(r *Row) error {
  173. return spannerErrorf(codes.FailedPrecondition, "row has different number of fields(%v) and values(%v)",
  174. len(r.fields), len(r.vals))
  175. }
  176. // errNilColType returns error for column type for column i being nil in the row.
  177. func errNilColType(i int) error {
  178. return spannerErrorf(codes.FailedPrecondition, "column(%v)'s type is nil", i)
  179. }
  180. // Column fetches the value from the ith column, decoding it into ptr.
  181. // See the Row documentation for the list of acceptable argument types.
  182. // see Client.ReadWriteTransaction for an example.
  183. func (r *Row) Column(i int, ptr interface{}) error {
  184. if len(r.vals) != len(r.fields) {
  185. return errFieldsMismatchVals(r)
  186. }
  187. if i < 0 || i >= len(r.fields) {
  188. return errColIdxOutOfRange(i, r)
  189. }
  190. if r.fields[i] == nil {
  191. return errNilColType(i)
  192. }
  193. if err := decodeValue(r.vals[i], r.fields[i].Type, ptr); err != nil {
  194. return errDecodeColumn(i, err)
  195. }
  196. return nil
  197. }
  198. // errDupColName returns error for duplicated column name in the same row.
  199. func errDupColName(n string) error {
  200. return spannerErrorf(codes.FailedPrecondition, "ambiguous column name %q", n)
  201. }
  202. // errColNotFound returns error for not being able to find a named column.
  203. func errColNotFound(n string) error {
  204. return spannerErrorf(codes.NotFound, "column %q not found", n)
  205. }
  206. // ColumnByName fetches the value from the named column, decoding it into ptr.
  207. // See the Row documentation for the list of acceptable argument types.
  208. func (r *Row) ColumnByName(name string, ptr interface{}) error {
  209. index, err := r.ColumnIndex(name)
  210. if err != nil {
  211. return err
  212. }
  213. return r.Column(index, ptr)
  214. }
  215. // errNumOfColValue returns error for providing wrong number of values to Columns.
  216. func errNumOfColValue(n int, r *Row) error {
  217. return spannerErrorf(codes.InvalidArgument,
  218. "Columns(): number of arguments (%d) does not match row size (%d)", n, len(r.vals))
  219. }
  220. // Columns fetches all the columns in the row at once.
  221. //
  222. // The value of the kth column will be decoded into the kth argument to Columns. See
  223. // Row for the list of acceptable argument types. The number of arguments must be
  224. // equal to the number of columns. Pass nil to specify that a column should be
  225. // ignored.
  226. func (r *Row) Columns(ptrs ...interface{}) error {
  227. if len(ptrs) != len(r.vals) {
  228. return errNumOfColValue(len(ptrs), r)
  229. }
  230. if len(r.vals) != len(r.fields) {
  231. return errFieldsMismatchVals(r)
  232. }
  233. for i, p := range ptrs {
  234. if p == nil {
  235. continue
  236. }
  237. if err := r.Column(i, p); err != nil {
  238. return err
  239. }
  240. }
  241. return nil
  242. }
  243. // errToStructArgType returns error for p not having the correct data type(pointer to Go struct) to
  244. // be the argument of Row.ToStruct.
  245. func errToStructArgType(p interface{}) error {
  246. return spannerErrorf(codes.InvalidArgument, "ToStruct(): type %T is not a valid pointer to Go struct", p)
  247. }
  248. // ToStruct fetches the columns in a row into the fields of a struct.
  249. // The rules for mapping a row's columns into a struct's exported fields
  250. // are:
  251. //
  252. // 1. If a field has a `spanner: "column_name"` tag, then decode column
  253. // 'column_name' into the field. A special case is the `spanner: "-"`
  254. // tag, which instructs ToStruct to ignore the field during decoding.
  255. //
  256. // 2. Otherwise, if the name of a field matches the name of a column (ignoring case),
  257. // decode the column into the field.
  258. //
  259. // The fields of the destination struct can be of any type that is acceptable
  260. // to spanner.Row.Column.
  261. //
  262. // Slice and pointer fields will be set to nil if the source column is NULL, and a
  263. // non-nil value if the column is not NULL. To decode NULL values of other types, use
  264. // one of the spanner.NullXXX types as the type of the destination field.
  265. //
  266. // If ToStruct returns an error, the contents of p are undefined. Some fields may
  267. // have been successfully populated, while others were not; you should not use any of
  268. // the fields.
  269. func (r *Row) ToStruct(p interface{}) error {
  270. // Check if p is a pointer to a struct
  271. if t := reflect.TypeOf(p); t == nil || t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
  272. return errToStructArgType(p)
  273. }
  274. if len(r.vals) != len(r.fields) {
  275. return errFieldsMismatchVals(r)
  276. }
  277. // Call decodeStruct directly to decode the row as a typed proto.ListValue.
  278. return decodeStruct(
  279. &sppb.StructType{Fields: r.fields},
  280. &proto3.ListValue{Values: r.vals},
  281. p,
  282. )
  283. }