blob: 452d7701abd62aadb6ed3bf08898ddbe57434123 [file] [log] [blame]
// Copyright 2015 The LUCI Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package datastore
import (
"fmt"
"github.com/luci/luci-go/common/errors"
"golang.org/x/net/context"
)
type checkFilter struct {
RawInterface
kc KeyContext
}
func (tcf *checkFilter) RunInTransaction(f func(c context.Context) error, opts *TransactionOptions) error {
if f == nil {
return fmt.Errorf("datastore: RunInTransaction function is nil")
}
return tcf.RawInterface.RunInTransaction(f, opts)
}
func (tcf *checkFilter) Run(fq *FinalizedQuery, cb RawRunCB) error {
if fq == nil {
return fmt.Errorf("datastore: Run query is nil")
}
if cb == nil {
return fmt.Errorf("datastore: Run callback is nil")
}
return tcf.RawInterface.Run(fq, cb)
}
func (tcf *checkFilter) GetMulti(keys []*Key, meta MultiMetaGetter, cb GetMultiCB) error {
if len(keys) == 0 {
return nil
}
if cb == nil {
return fmt.Errorf("datastore: GetMulti callback is nil")
}
lme := errors.NewLazyMultiError(len(keys))
for i, k := range keys {
var err error
switch {
case k.IsIncomplete():
err = MakeErrInvalidKey().Reason("key [%(key)s] is incomplete").
D("key", k).Err()
case !k.Valid(true, tcf.kc):
err = MakeErrInvalidKey().Reason("key [%(key)s] is not valid in context %(context)s").
D("key", k).D("context", tcf.kc).Err()
}
if err != nil {
lme.Assign(i, err)
}
}
if me := lme.Get(); me != nil {
for _, err := range me.(errors.MultiError) {
cb(nil, err)
}
return nil
}
return tcf.RawInterface.GetMulti(keys, meta, cb)
}
func (tcf *checkFilter) PutMulti(keys []*Key, vals []PropertyMap, cb NewKeyCB) error {
if len(keys) != len(vals) {
return fmt.Errorf("datastore: PutMulti with mismatched keys/vals lengths (%d/%d)", len(keys), len(vals))
}
if len(keys) == 0 {
return nil
}
if cb == nil {
return fmt.Errorf("datastore: PutMulti callback is nil")
}
lme := errors.NewLazyMultiError(len(keys))
for i, k := range keys {
if !k.PartialValid(tcf.kc) {
lme.Assign(i, MakeErrInvalidKey().Reason("key [%(key)s] is not partially valid in context %(context)s").
D("key", k).D("context", tcf.kc).Err())
continue
}
v := vals[i]
if v == nil {
lme.Assign(i, errors.New("datastore: PutMulti got nil vals entry"))
}
}
if me := lme.Get(); me != nil {
for _, err := range me.(errors.MultiError) {
cb(nil, err)
}
return nil
}
return tcf.RawInterface.PutMulti(keys, vals, cb)
}
func (tcf *checkFilter) DeleteMulti(keys []*Key, cb DeleteMultiCB) error {
if len(keys) == 0 {
return nil
}
if cb == nil {
return fmt.Errorf("datastore: DeleteMulti callback is nil")
}
lme := errors.NewLazyMultiError(len(keys))
for i, k := range keys {
var err error
switch {
case k.IsIncomplete():
err = MakeErrInvalidKey().Reason("key [%(key)s] is incomplete").
D("key", k).Err()
case !k.Valid(false, tcf.kc):
err = MakeErrInvalidKey().Reason("key [%(key)s] is not valid in context %(context)s").
D("key", k).D("context", tcf.kc).Err()
}
if err != nil {
lme.Assign(i, err)
}
}
if me := lme.Get(); me != nil {
for _, err := range me.(errors.MultiError) {
cb(err)
}
return nil
}
return tcf.RawInterface.DeleteMulti(keys, cb)
}
func applyCheckFilter(c context.Context, i RawInterface) RawInterface {
return &checkFilter{
RawInterface: i,
kc: GetKeyContext(c),
}
}