-
Notifications
You must be signed in to change notification settings - Fork 48
/
yo_db.yo.go
150 lines (129 loc) · 4.06 KB
/
yo_db.yo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Code generated by yo. DO NOT EDIT.
// Package models contains the types.
package models
import (
"context"
"errors"
"fmt"
"strconv"
"cloud.google.com/go/spanner"
"github.com/googleapis/gax-go/v2/apierror"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// YODB is the common interface for database operations.
type YODB interface {
ReadRow(ctx context.Context, table string, key spanner.Key, columns []string) (*spanner.Row, error)
Read(ctx context.Context, table string, keys spanner.KeySet, columns []string) *spanner.RowIterator
ReadUsingIndex(ctx context.Context, table, index string, keys spanner.KeySet, columns []string) (ri *spanner.RowIterator)
Query(ctx context.Context, statement spanner.Statement) *spanner.RowIterator
}
// YOLog provides the log func used by generated queries.
var YOLog = func(context.Context, string, ...interface{}) {}
func newError(method, table string, err error) error {
code := spanner.ErrCode(err)
return newErrorWithCode(code, method, table, err)
}
func newErrorWithCode(code codes.Code, method, table string, err error) error {
return &yoError{
method: method,
table: table,
err: err,
code: code,
}
}
type yoError struct {
err error
method string
table string
code codes.Code
}
func (e yoError) Error() string {
return fmt.Sprintf("yo error in %s(%s): %v", e.method, e.table, e.err)
}
func (e yoError) Unwrap() error {
return e.err
}
func (e yoError) DBTableName() string {
return e.table
}
// GRPCStatus implements a conversion to a gRPC status using `status.Convert(error)`.
// If the error is originated from the Spanner library, this returns a gRPC status of
// the original error. It may contain details of the status such as RetryInfo.
func (e yoError) GRPCStatus() *status.Status {
var ae *apierror.APIError
if errors.As(e.err, &ae) {
return status.Convert(ae)
}
return status.New(e.code, e.Error())
}
func (e yoError) Timeout() bool { return e.code == codes.DeadlineExceeded }
func (e yoError) Temporary() bool { return e.code == codes.DeadlineExceeded }
func (e yoError) NotFound() bool { return e.code == codes.NotFound }
// yoEncode encodes primitive types that spanner library does not support into spanner types before
// passing to spanner functions. Suppotted primitive types and user defined types that implement
// spanner.Encoder interface are handled in encoding phase inside spanner libirary.
func yoEncode(v interface{}) interface{} {
switch vv := v.(type) {
case int8:
return int64(vv)
case uint8:
return int64(vv)
case int16:
return int64(vv)
case uint16:
return int64(vv)
case int32:
return int64(vv)
case uint32:
return int64(vv)
case uint64:
return int64(vv)
default:
return v
}
}
// yoDecode wraps primitive types that spanner library does not support to decode from spanner types
// by yoPrimitiveDecoder before passing to spanner functions. Supported primitive types and
// user defined types that implement spanner.Decoder interface are handled in decoding phase inside
// spanner libirary.
func yoDecode(ptr interface{}) interface{} {
switch ptr.(type) {
case *int8, *uint8, *int16, *uint16, *int32, *uint32, *uint64:
return &yoPrimitiveDecoder{val: ptr}
default:
return ptr
}
}
type yoPrimitiveDecoder struct {
val interface{}
}
func (y *yoPrimitiveDecoder) DecodeSpanner(val interface{}) error {
strVal, ok := val.(string)
if !ok {
return spanner.ToSpannerError(status.Errorf(codes.FailedPrecondition, "failed to decode customField: %T(%v)", val, val))
}
intVal, err := strconv.ParseInt(strVal, 10, 64)
if err != nil {
return spanner.ToSpannerError(status.Errorf(codes.FailedPrecondition, "%v wasn't correctly encoded: <%v>", val, err))
}
switch vv := y.val.(type) {
case *int8:
*vv = int8(intVal)
case *uint8:
*vv = uint8(intVal)
case *int16:
*vv = int16(intVal)
case *uint16:
*vv = uint16(intVal)
case *int32:
*vv = int32(intVal)
case *uint32:
*vv = uint32(intVal)
case *uint64:
*vv = uint64(intVal)
default:
return status.Errorf(codes.Internal, "unexpected type for yoPrimitiveDecoder: %T", y.val)
}
return nil
}