Exemple #1
0
func (d *Driver) SyncPut(key *datastore.Key, src Syncable) (*datastore.Key, error) {
	t := time.Now()
	typ := reflect.Indirect(reflect.ValueOf(src)).Type() // Get the struct type
	fieldName := src.TimestampFieldName()
	reflect.Indirect(reflect.ValueOf(src)).FieldByName(fieldName).Set(reflect.ValueOf(t))
	if _, err := d.Put(key, src); err != nil {
		return nil, err
	} else {
		var _src = reflect.New(typ).Interface()
		err := wcg.RetryUntil(func() error {
			if err := d.Get(key, _src); err != nil {
				return err
			} else {
				t := reflect.Indirect(reflect.ValueOf(src)).FieldByName(fieldName).Interface().(time.Time)
				if t.Unix() == t.Unix() {
					return nil
				} else {
					return fmt.Errorf("put not synched.")
				}
			}
		}, d.Timeout*2, 500*time.Millisecond)
		if err != nil {
			return nil, &timeoutErr{err}
		} else {
			return key, nil
		}
	}
}
Exemple #2
0
func (d *Driver) SyncDelete(key *datastore.Key) error {
	if err := d.Delete(key); err != nil {
		return err
	} else {
		q := d.NewQuery().Filter("__key__ =", key)
		err := wcg.RetryUntil(func() error {
			if i, err := q.Count(); i == 0 {
				return nil
			} else {
				return fmt.Errorf("delete not synched: internal error?(%v)", err)
			}
		}, d.Timeout*2, 500*time.Millisecond)
		if err != nil {
			return &timeoutErr{err}
		} else {
			return nil
		}
	}
}
Exemple #3
0
func CleanupDatastore(ctx appengine.Context) error {
	var dummy []interface{}
	logger := wcg.NewLogger(nil)
	logger.Debug("[Fixture] --------- CleanupDatastore ---------")
	return wcg.RetryUntil(func() error {
		if keys, err := datastore.NewQuery("").KeysOnly().GetAll(ctx, dummy); err != nil {
			return err
		} else {
			if err := datastore.DeleteMulti(ctx, keys); err != nil {
				return err
			}
			count, _ := datastore.NewQuery("").KeysOnly().Count(ctx)
			if count == 0 {
				return nil
			} else {
				return fmt.Errorf("Still have %d keys.", count)
			}
		}
	}, 10*time.Second, 100*time.Millisecond)
}
Exemple #4
0
func loadJsonToDatastore(ctx appengine.Context, pkey *datastore.Key, data map[string]interface{}, logger wcg.Logger) error {
	var kind string
	var ns string
	var keyval interface{}
	var key *datastore.Key
	var ok bool
	var err error
	if _, ok = data["_kind"]; !ok {
		return fmt.Errorf("Missing key `_kind`")
	} else {
		kind = data["_kind"].(string)
	}
	if keyval, ok = data["_key"]; !ok {
		return fmt.Errorf("Missing key `_key`")
	}
	if _, ok = data["_ns"]; ok {
		ns = data["_ns"].(string)
		ctx, err = appengine.Namespace(ctx, ns)
		if err != nil {
			return err
		}
	}

	switch keyval.(type) {
	case int64:
		key = datastore.NewKey(ctx, kind, "", keyval.(int64), pkey)
	case string:
		key = datastore.NewKey(ctx, kind, keyval.(string), 0, pkey)
	default:
		return fmt.Errorf("Invalid `_key` type.")
	}
	if _, err := datastore.Put(ctx, key, JsonSaver(data)); err != nil {
		return err
	}
	// Check the data is actually stored.
	if err := wcg.RetryUntil(func() error {
		var v JsonSaver
		if err := datastore.Get(ctx, key, &v); err != nil {
			return fmt.Errorf(
				"fixture is not synched on '%s:[%s]': internal error?(%v) on ",
				kind, keyval, err,
			)
		}
		return nil
	}, 5*time.Second, 500*time.Millisecond); err != nil {
		return err
	}
	logger.Debug("[Fixture] %s%s -- %v", ns, key, data)

	for _, v := range data {
		// Child object
		if child, ok := v.(map[string]interface{}); ok {
			if err := loadJsonToDatastore(ctx, key, child, logger); err != nil {
				return err
			}
			continue
		}
		// Array
		if children, ok := v.([]interface{}); ok {
			for _, child := range children {
				if c, ok := child.(map[string]interface{}); ok {
					if err := loadJsonToDatastore(ctx, key, c, logger); err != nil {
						return err
					}
				}
			}
			continue
		}
	}
	return nil
}