Esempio n. 1
0
// Commit commits the delete operation
func (multi *DeleteMulti) Commit(req *wcg.Request) ([]*datastore.Key, error) {
	driver, err := multi.base.kind.NewDriver(req)
	if err != nil {
		return nil, err
	}
	// prepare keys
	var datastoreKeys = make([]*datastore.Key, len(multi.base.stringKeys))
	for i, skey := range multi.base.stringKeys {
		datastoreKeys[i] = driver.NewKey(skey, 0, multi.base.parent)
	}

	// delete from datastore
	if err := driver.DeleteMulti(datastoreKeys); ds.IsDatastoreError(err) {
		req.Logger.Errorf("[%s] Could not delete from datastore: %v", multi.base.kind, err)
		return nil, err
	}

	// TODO: check the key is deleted
	if multi.sync {
	}
	req.Logger.Infof("[%s] Entities deleted (keys=%v)", multi.base.kind, datastoreKeys)

	multi.base.invalidateKeys(req, multi.base.stringKeys...)
	return datastoreKeys, nil
}
Esempio n. 2
0
// Commit commits the delete operation
func (query *DeleteQuery) Commit(req *wcg.Request) (int, error) {
	p, err := query.query.Execute(req)
	if err != nil {
		return -1, err
	}
	c := p.Length()
	driver, err := query.Kind().NewDriver(req)
	if err != nil {
		return -1, err
	}
	if err = driver.DeleteMulti(p.Keys); ds.IsDatastoreError(err) {
		req.Logger.Errorf("[%s] Could not delete from datastore: %v", c, err)
		return -1, err
	}
	req.Logger.Infof("[%s] %d entities deleted by query", query.Kind(), c)
	return c, nil
}
Esempio n. 3
0
// List commits the getmulti operation and returns the list of keys, entities, and error.
func (multi *GetMulti) List(req *wcg.Request) ([]*datastore.Key, interface{}, error) {
	var ent = multi.base.kind.NewSliceWithLength(len(multi.base.stringKeys)) // must be []*Entity
	var cache = multi.base.kind.NewCacheDriver(req)
	driver, err := multi.base.kind.NewDriver(req)
	if err != nil {
		return nil, nil, err
	}
	// prepare keys
	var dsGetKeys []*datastore.Key
	var datastoreKeys []*datastore.Key
	var memcacheKeys []string
	if l := len(multi.base.stringKeys); l > 0 {
		datastoreKeys = make([]*datastore.Key, l)
		memcacheKeys = make([]string, l)
		for i, skey := range multi.base.stringKeys {
			datastoreKeys[i] = driver.NewKey(multi.base.stringKeys[i], 0, multi.base.parent)
			memcacheKeys[i] = multi.base.kind.GetMemcacheKey(skey)
		}
	} else if l := len(multi.base.datastoreKeys); l > 0 {
		datastoreKeys = make([]*datastore.Key, l)
		memcacheKeys = make([]string, l)
		for i, key := range multi.base.datastoreKeys {
			datastoreKeys[i] = key
			memcacheKeys[i] = multi.base.kind.GetMemcacheKey(key.StringID())
		}
	} else {
		return nil, nil, ErrNoKeys
	}

	// memcache
	if multi.useCache {
		if err = cache.GetMulti(memcacheKeys, ent); err != nil {
			req.Logger.Warnf("[GETm %s%s] Error loading memcache keys: %v (keys=%v)",
				multi.base.kind.Namespace, multi.base.kind, err, memcacheKeys)
		}
		// check ent
		entValue := reflect.ValueOf(ent)
		for i := range memcacheKeys {
			if entValue.Index(i).IsNil() {
				dsGetKeys = append(
					dsGetKeys,
					datastoreKeys[i],
				)
			}
		}
		if len(dsGetKeys) == 0 {
			return datastoreKeys, ent, nil
		}
		req.Logger.Debugf("[GETm %s%s] cache missing. fail back to access datastore.",
			multi.base.kind.Namespace, datastoreKeys)
	} else {
		dsGetKeys = datastoreKeys
	}
	dsEnt := multi.base.kind.NewSliceWithLength(len(dsGetKeys))
	// datastore
	if err = driver.GetMulti(dsGetKeys, dsEnt); err != nil {
		if ds.IsDatastoreError(err) {
			return datastoreKeys, nil, err
		}
		if multi.useCache {
			// merge ent with dsEnt
			entValue := reflect.ValueOf(ent)
			dsEntValue := reflect.ValueOf(dsEnt)
			j := 0
			for i := 0; i < len(multi.base.stringKeys); i++ {
				if entValue.Index(i).IsNil() {
					entValue.Index(i).Set(dsEntValue.Index(j))
					j++
				}
			}
			createCache(req, multi.base.kind, cache, ent, memcacheKeys...)
		} else {
			ent = dsEnt
		}
		if multi.useDefaultIfNil {
			entValue := reflect.ValueOf(ent)
			for i := 0; i < len(multi.base.stringKeys); i++ {
				if entValue.Index(i).IsNil() {
					req.Logger.Debugf("key:%s does not exist but returns the end with defaults", multi.base.stringKeys[i])
					entValue.Index(i).Set(reflect.ValueOf(multi.base.kind.NewEntityWithDefaults()))
					multi.base.kind.updateIDField(entValue.Index(i).Interface(), multi.base.stringKeys[i])
				}
			}
		}
		return datastoreKeys, reflect.Indirect(reflect.ValueOf(ent)).Interface(), nil
	}
	if multi.useCache {
		// merge ent with dsEnt
		entValue := reflect.ValueOf(ent)
		dsEntValue := reflect.ValueOf(dsEnt)
		j := 0
		for i := 0; i < len(multi.base.stringKeys); i++ {
			if entValue.Index(i).IsNil() {
				entValue.Index(i).Set(dsEntValue.Index(j))
				j++
			}
		}
		createCache(req, multi.base.kind, cache, ent, memcacheKeys...)
	} else {
		ent = dsEnt
	}
	return datastoreKeys, reflect.Indirect(reflect.ValueOf(ent)).Interface(), nil
}