go.mercari.io/datastore@v1.8.2/clouddatastore/bridge.go (about) 1 package clouddatastore 2 3 import ( 4 "context" 5 "encoding/gob" 6 "errors" 7 8 "cloud.google.com/go/compute/metadata" 9 "cloud.google.com/go/datastore" 10 w "go.mercari.io/datastore" 11 "go.mercari.io/datastore/internal" 12 "go.mercari.io/datastore/internal/shared" 13 "google.golang.org/api/option" 14 ) 15 16 func init() { 17 //lint:ignore SA1019 for backward compatible 18 w.FromContext = FromContext 19 20 gob.Register(&keyImpl{}) 21 } 22 23 var projectID *string 24 25 func newClientSettings(opts ...w.ClientOption) *internal.ClientSettings { 26 if projectID == nil { 27 pID, err := metadata.ProjectID() 28 if err != nil { 29 // don't check again even if it was failed... 30 pID = internal.GetProjectID() 31 } 32 projectID = &pID 33 } 34 settings := &internal.ClientSettings{ 35 ProjectID: *projectID, 36 } 37 for _, opt := range opts { 38 opt.Apply(settings) 39 } 40 return settings 41 } 42 43 // FromContext make new Client by specified context. 44 // Deprecated: use FromClient instead of FromContext. FromContext implicitly creates original datastore.Client. 45 func FromContext(ctx context.Context, opts ...w.ClientOption) (w.Client, error) { 46 settings := newClientSettings(opts...) 47 origOpts := make([]option.ClientOption, 0, len(opts)) 48 if len(settings.Scopes) != 0 { 49 origOpts = append(origOpts, option.WithScopes(settings.Scopes...)) 50 } 51 if settings.TokenSource != nil { 52 origOpts = append(origOpts, option.WithTokenSource(settings.TokenSource)) 53 } 54 if settings.CredentialsFile != "" { 55 origOpts = append(origOpts, option.WithCredentialsFile(settings.CredentialsFile)) 56 } 57 if settings.HTTPClient != nil { 58 origOpts = append(origOpts, option.WithHTTPClient(settings.HTTPClient)) 59 } 60 if len(settings.GRPCDialOpts) != 0 { 61 for _, dialOpt := range settings.GRPCDialOpts { 62 origOpts = append(origOpts, option.WithGRPCDialOption(dialOpt)) 63 } 64 } 65 66 client, err := datastore.NewClient(ctx, settings.ProjectID, origOpts...) 67 if err != nil { 68 return nil, err 69 } 70 71 return &datastoreImpl{ctx: ctx, client: client}, nil 72 } 73 74 // FromClient make new Client by specified datastore.Client. 75 func FromClient(ctx context.Context, client *datastore.Client) (w.Client, error) { 76 return &datastoreImpl{ctx: ctx, client: client}, nil 77 } 78 79 // IsCloudDatastoreClient returns check result that client is this package's client or not. 80 func IsCloudDatastoreClient(client w.Client) bool { 81 _, ok := client.(*datastoreImpl) 82 return ok 83 } 84 85 var _ shared.OriginalClientBridge = &originalClientBridgeImpl{} 86 var _ shared.OriginalTransactionBridge = &originalTransactionBridgeImpl{} 87 var _ shared.OriginalIteratorBridge = &originalIteratorBridgeImpl{} 88 89 type originalClientBridgeImpl struct { 90 d *datastoreImpl 91 } 92 93 func (ocb *originalClientBridgeImpl) AllocateIDs(ctx context.Context, keys []w.Key) ([]w.Key, error) { 94 origKeys := toOriginalKeys(keys) 95 96 origKeys, err := ocb.d.client.AllocateIDs(ctx, origKeys) 97 return toWrapperKeys(origKeys), toWrapperError(err) 98 } 99 100 func (ocb *originalClientBridgeImpl) PutMulti(ctx context.Context, keys []w.Key, psList []w.PropertyList) ([]w.Key, error) { 101 origKeys := toOriginalKeys(keys) 102 origPss := toOriginalPropertyListList(psList) 103 104 origKeys, err := ocb.d.client.PutMulti(ctx, origKeys, origPss) 105 return toWrapperKeys(origKeys), toWrapperError(err) 106 } 107 108 func (ocb *originalClientBridgeImpl) GetMulti(ctx context.Context, keys []w.Key, psList []w.PropertyList) error { 109 origKeys := toOriginalKeys(keys) 110 origPss := toOriginalPropertyListList(psList) 111 112 err := ocb.d.client.GetMulti(ctx, origKeys, origPss) 113 wPss := toWrapperPropertyListList(origPss) 114 copy(psList, wPss) 115 return toWrapperError(err) 116 } 117 118 func (ocb *originalClientBridgeImpl) DeleteMulti(ctx context.Context, keys []w.Key) error { 119 origKeys := toOriginalKeys(keys) 120 121 err := ocb.d.client.DeleteMulti(ctx, origKeys) 122 return toWrapperError(err) 123 } 124 125 func (ocb *originalClientBridgeImpl) Run(ctx context.Context, q w.Query, qDump *w.QueryDump) w.Iterator { 126 qImpl := q.(*queryImpl) 127 iter := ocb.d.client.Run(ctx, qImpl.q) 128 129 return &iteratorImpl{ 130 client: ocb.d, 131 q: qImpl, 132 qDump: qDump, 133 t: iter, 134 cacheInfo: &w.MiddlewareInfo{ 135 Context: ctx, 136 Client: ocb.d, 137 Transaction: qDump.Transaction, 138 }, 139 firstError: qImpl.firstError, 140 } 141 } 142 143 func (ocb *originalClientBridgeImpl) GetAll(ctx context.Context, q w.Query, qDump *w.QueryDump, psList *[]w.PropertyList) ([]w.Key, error) { 144 qImpl := q.(*queryImpl) 145 146 var origPss []datastore.PropertyList 147 if !qDump.KeysOnly { 148 origPss = toOriginalPropertyListList(*psList) 149 } 150 origKeys, err := ocb.d.client.GetAll(ctx, qImpl.q, &origPss) 151 if err != nil { 152 return nil, toWrapperError(err) 153 } 154 155 wKeys := toWrapperKeys(origKeys) 156 157 if !qDump.KeysOnly { 158 *psList = toWrapperPropertyListList(origPss) 159 } 160 161 return wKeys, nil 162 } 163 164 func (ocb *originalClientBridgeImpl) Count(ctx context.Context, q w.Query, qDump *w.QueryDump) (int, error) { 165 qImpl, ok := q.(*queryImpl) 166 if !ok { 167 return 0, errors.New("invalid query type") 168 } 169 if qImpl.firstError != nil { 170 return 0, qImpl.firstError 171 } 172 173 count, err := ocb.d.client.Count(ctx, qImpl.q) 174 if err != nil { 175 return 0, toWrapperError(err) 176 } 177 178 return count, nil 179 } 180 181 type originalTransactionBridgeImpl struct { 182 tx *transactionImpl 183 } 184 185 func (otb *originalTransactionBridgeImpl) PutMulti(keys []w.Key, psList []w.PropertyList) ([]w.PendingKey, error) { 186 baseTx := getTx(otb.tx.client.ctx) 187 if baseTx == nil { 188 return nil, errors.New("unexpected context") 189 } 190 191 origKeys := toOriginalKeys(keys) 192 origPss := toOriginalPropertyListList(psList) 193 194 origPKeys, err := baseTx.PutMulti(origKeys, origPss) 195 if err != nil { 196 return nil, toWrapperError(err) 197 } 198 199 wPKeys := toWrapperPendingKeys(origPKeys) 200 201 return wPKeys, nil 202 } 203 204 func (otb *originalTransactionBridgeImpl) GetMulti(keys []w.Key, psList []w.PropertyList) error { 205 baseTx := getTx(otb.tx.client.ctx) 206 if baseTx == nil { 207 return errors.New("unexpected context") 208 } 209 210 origKeys := toOriginalKeys(keys) 211 origPss := toOriginalPropertyListList(psList) 212 213 err := baseTx.GetMulti(origKeys, origPss) 214 wPss := toWrapperPropertyListList(origPss) 215 copy(psList, wPss) 216 if err != nil { 217 return toWrapperError(err) 218 } 219 220 return nil 221 } 222 223 func (otb *originalTransactionBridgeImpl) DeleteMulti(keys []w.Key) error { 224 baseTx := getTx(otb.tx.client.ctx) 225 if baseTx == nil { 226 return errors.New("unexpected context") 227 } 228 229 origKeys := toOriginalKeys(keys) 230 231 err := baseTx.DeleteMulti(origKeys) 232 return toWrapperError(err) 233 } 234 235 type originalIteratorBridgeImpl struct { 236 qDump *w.QueryDump 237 } 238 239 func (oib *originalIteratorBridgeImpl) Next(iter w.Iterator, ps *w.PropertyList) (w.Key, error) { 240 iterImpl := iter.(*iteratorImpl) 241 242 var origPsPtr *datastore.PropertyList 243 if !oib.qDump.KeysOnly { 244 origPs := toOriginalPropertyList(*ps) 245 origPsPtr = &origPs 246 } 247 248 origKey, err := iterImpl.t.Next(origPsPtr) 249 if err != nil { 250 return nil, toWrapperError(err) 251 } 252 253 if !oib.qDump.KeysOnly { 254 *ps = toWrapperPropertyList(*origPsPtr) 255 } 256 257 return toWrapperKey(origKey), nil 258 }