go.mercari.io/datastore@v1.8.2/aedatastore/query.go (about)

     1  package aedatastore
     2  
     3  import (
     4  	"context"
     5  
     6  	w "go.mercari.io/datastore"
     7  	"go.mercari.io/datastore/internal/shared"
     8  	"google.golang.org/appengine/datastore"
     9  )
    10  
    11  var _ w.Query = (*queryImpl)(nil)
    12  var _ w.Iterator = (*iteratorImpl)(nil)
    13  var _ w.Cursor = (*cursorImpl)(nil)
    14  
    15  type queryImpl struct {
    16  	ctx context.Context
    17  	q   *datastore.Query
    18  
    19  	dump *w.QueryDump
    20  
    21  	firstError error
    22  }
    23  
    24  type iteratorImpl struct {
    25  	client    *datastoreImpl
    26  	q         *queryImpl
    27  	qDump     *w.QueryDump
    28  	t         *datastore.Iterator
    29  	cacheInfo *w.MiddlewareInfo
    30  
    31  	firstError error
    32  }
    33  
    34  type cursorImpl struct {
    35  	cursor datastore.Cursor
    36  }
    37  
    38  func (q *queryImpl) clone() *queryImpl {
    39  	x := *q
    40  	d := *q.dump
    41  	d.Filter = d.Filter[:]
    42  	d.Order = d.Order[:]
    43  	d.Project = d.Project[:]
    44  	x.dump = &d
    45  	return &x
    46  }
    47  
    48  func (q *queryImpl) Ancestor(ancestor w.Key) w.Query {
    49  	q = q.clone()
    50  	q.q = q.q.Ancestor(toOriginalKey(ancestor))
    51  	q.dump.Ancestor = ancestor
    52  	return q
    53  }
    54  
    55  func (q *queryImpl) EventualConsistency() w.Query {
    56  	q = q.clone()
    57  	q.q = q.q.EventualConsistency()
    58  	q.dump.EventualConsistency = true
    59  	return q
    60  }
    61  
    62  func (q *queryImpl) Namespace(ns string) w.Query {
    63  	q = q.clone()
    64  	q.dump.Namespace = ns
    65  	return q
    66  }
    67  
    68  func (q *queryImpl) Transaction(t w.Transaction) w.Query {
    69  	q = q.clone()
    70  	q.dump.Transaction = t
    71  	return q
    72  }
    73  
    74  func (q *queryImpl) Filter(filterStr string, value interface{}) w.Query {
    75  	q = q.clone()
    76  	var err error
    77  	if pt, ok := value.(w.PropertyTranslator); ok {
    78  		value, err = pt.ToPropertyValue(q.ctx)
    79  		if err != nil {
    80  			if q.firstError == nil {
    81  				q.firstError = err
    82  			}
    83  			return q
    84  		}
    85  	}
    86  	origV, err := toOriginalValue(value)
    87  	if err != nil {
    88  		if q.firstError == nil {
    89  			q.firstError = err
    90  		}
    91  		return q
    92  	}
    93  	q.q = q.q.Filter(filterStr, origV)
    94  	q.dump.Filter = append(q.dump.Filter, &w.QueryFilterCondition{
    95  		Filter: filterStr,
    96  		Value:  value,
    97  	})
    98  	return q
    99  }
   100  
   101  func (q *queryImpl) Order(fieldName string) w.Query {
   102  	q = q.clone()
   103  	q.q = q.q.Order(fieldName)
   104  	q.dump.Order = append(q.dump.Order, fieldName)
   105  	return q
   106  }
   107  
   108  func (q *queryImpl) Project(fieldNames ...string) w.Query {
   109  	q = q.clone()
   110  	q.q = q.q.Project(fieldNames...)
   111  	q.dump.Project = append([]string(nil), fieldNames...)
   112  	return q
   113  }
   114  
   115  func (q *queryImpl) DistinctOn(fieldNames ...string) w.Query {
   116  	q = q.clone()
   117  	q.q = q.q.DistinctOn(fieldNames...)
   118  	q.dump.DistinctOn = append([]string(nil), fieldNames...)
   119  	return q
   120  }
   121  
   122  func (q *queryImpl) Distinct() w.Query {
   123  	q = q.clone()
   124  	q.q = q.q.Distinct()
   125  	q.dump.Distinct = true
   126  	return q
   127  }
   128  
   129  func (q *queryImpl) KeysOnly() w.Query {
   130  	q = q.clone()
   131  	q.q = q.q.KeysOnly()
   132  	q.dump.KeysOnly = true
   133  	return q
   134  }
   135  
   136  func (q *queryImpl) Limit(limit int) w.Query {
   137  	q = q.clone()
   138  	q.q = q.q.Limit(limit)
   139  	q.dump.Limit = limit
   140  	return q
   141  }
   142  
   143  func (q *queryImpl) Offset(offset int) w.Query {
   144  	q = q.clone()
   145  	q.q = q.q.Offset(offset)
   146  	q.dump.Offset = offset
   147  	return q
   148  }
   149  
   150  func (q *queryImpl) Start(c w.Cursor) w.Query {
   151  	q = q.clone()
   152  	curImpl := c.(*cursorImpl)
   153  	q.q = q.q.Start(curImpl.cursor)
   154  	q.dump.Start = c
   155  	return q
   156  }
   157  
   158  func (q *queryImpl) End(c w.Cursor) w.Query {
   159  	q = q.clone()
   160  	curImpl := c.(*cursorImpl)
   161  	q.q = q.q.End(curImpl.cursor)
   162  	q.dump.End = c
   163  	return q
   164  }
   165  
   166  func (q *queryImpl) Dump() *w.QueryDump {
   167  	return q.dump
   168  }
   169  
   170  func (t *iteratorImpl) Next(dst interface{}) (w.Key, error) {
   171  	if t.firstError != nil {
   172  		return nil, t.firstError
   173  	}
   174  
   175  	cb := shared.NewCacheBridge(t.cacheInfo, &originalClientBridgeImpl{t.client}, nil, &originalIteratorBridgeImpl{t.qDump}, t.client.middlewares)
   176  	return shared.NextOps(t.client.ctx, t.qDump, dst, func(dst *w.PropertyList) (w.Key, error) {
   177  		return cb.Next(t.cacheInfo, t.q, t.qDump, t, dst)
   178  	})
   179  }
   180  
   181  func (t *iteratorImpl) Cursor() (w.Cursor, error) {
   182  	if t.firstError != nil {
   183  		return nil, t.firstError
   184  	}
   185  
   186  	cur, err := t.t.Cursor()
   187  	if err != nil {
   188  		return nil, toWrapperError(err)
   189  	}
   190  
   191  	return &cursorImpl{cursor: cur}, nil
   192  }
   193  
   194  func (cur *cursorImpl) String() string {
   195  	if cur == nil {
   196  		return ""
   197  	}
   198  	return cur.cursor.String()
   199  }