func (tf *typeFilter) Save() ([]datastore.Property, error) { props := []datastore.Property{} for name, propList := range tf.pm { if len(name) != 0 && name[0] == '$' { continue } multiple := len(propList) > 1 for _, prop := range propList { toAdd := datastore.Property{ Name: name, Multiple: multiple, NoIndex: prop.IndexSetting() == ds.NoIndex, } switch prop.Type() { case ds.PTBytes: v := prop.Value().([]byte) if prop.IndexSetting() == ds.ShouldIndex { toAdd.Value = datastore.ByteString(v) } else { toAdd.Value = v } case ds.PTKey: toAdd.Value = dsF2R(prop.Value().(ds.Key)) case ds.PTBlobKey: toAdd.Value = appengine.BlobKey(prop.Value().(bs.Key)) case ds.PTGeoPoint: toAdd.Value = appengine.GeoPoint(prop.Value().(ds.GeoPoint)) default: toAdd.Value = prop.Value() } props = append(props, toAdd) } } return props, nil }
func dsF2RProp(ctx context.Context, in ds.Property) (datastore.Property, error) { err := error(nil) ret := datastore.Property{ NoIndex: in.IndexSetting() == ds.NoIndex, } switch in.Type() { case ds.PTBytes: v := in.Value().([]byte) if in.IndexSetting() == ds.ShouldIndex { ret.Value = datastore.ByteString(v) } else { ret.Value = v } case ds.PTKey: ret.Value, err = dsF2R(ctx, in.Value().(*ds.Key)) case ds.PTBlobKey: ret.Value = appengine.BlobKey(in.Value().(bs.Key)) case ds.PTGeoPoint: ret.Value = appengine.GeoPoint(in.Value().(ds.GeoPoint)) default: ret.Value = in.Value() } return ret, err }
for _, v := range vs { ss, err := s.SearchService.ByView(ctx, v) if err != nil { return err } if len(ss) != 0 { continue } err = s.SearchService.Create(ctx, &Search{ Name: "#now", ViewID: v.ID, Query: "#now AND IsArchived: false", ViewRank: datastore.ByteString("0"), }) if err != nil { return err } err = s.SearchService.Create(ctx, &Search{ Name: "Incoming", ViewID: v.ID, Query: "NOT #now AND NOT #next AND NOT #later AND IsArchived: false", ViewRank: datastore.ByteString("1"), }) if err != nil { return err }
func (s *SearchService) Create(ctx context.Context, se *Search) error { span := trace.FromContext(ctx).NewChild("trythings.search.Create") defer span.Finish() if se.ID != "" { return fmt.Errorf("se already has id %q", se.ID) } if se.CreatedAt.IsZero() { se.CreatedAt = time.Now() } if se.Name == "" { return errors.New("Name is required") } if se.ViewID == "" { return errors.New("ViewID is required") } v, err := s.ViewService.ByID(ctx, se.ViewID) if err != nil { return err } if se.SpaceID == "" { se.SpaceID = v.SpaceID } if se.SpaceID != v.SpaceID { return errors.New("Search's SpaceID must match View's") } if len(se.ViewRank) != 0 { return fmt.Errorf("se already has a view rank %x", se.ViewRank) } // TODO#Performance: Add a shared or per-request cache to support these small, repeated queries. if se.Query == "" { return errors.New("Query is required") } rootKey := datastore.NewKey(ctx, "Root", "root", 0, nil) // Create a ViewRank for the search. // It should come after every other search in the view. var ranks []*struct { ViewRank datastore.ByteString } _, err = datastore.NewQuery("Search"). Ancestor(rootKey). Filter("ViewID =", se.ViewID). Project("ViewRank"). Order("-ViewRank"). Limit(1). GetAll(ctx, &ranks) if err != nil { return err } maxViewRank := MinRank if len(ranks) != 0 { maxViewRank = Rank(ranks[0].ViewRank) } rank, err := NewRank(maxViewRank, MaxRank) if err != nil { return err } se.ViewRank = datastore.ByteString(rank) ok, err := s.IsVisible(ctx, se) if err != nil { return err } if !ok { return errors.New("cannot access view to create search") } id, _, err := datastore.AllocateIDs(ctx, "Search", nil, 1) if err != nil { return err } se.ID = fmt.Sprintf("%x", id) k := datastore.NewKey(ctx, "Search", se.ID, 0, rootKey) k, err = datastore.Put(ctx, k, se) if err != nil { return err } return nil }