func (d *dataStoreData) putMulti(keys []*ds.Key, vals []ds.PropertyMap, cb ds.PutMultiCB) error { ns := keys[0].Namespace() for i, k := range keys { pmap, _ := vals[i].Save(false) dataBytes := serialize.ToBytes(pmap) k, err := func() (ret *ds.Key, err error) { d.Lock() defer d.Unlock() ents := d.mutableEntsLocked(ns) ret, err = d.fixKeyLocked(ents, k) if err != nil { return } if !d.disableSpecialEntities { incrementLocked(ents, groupMetaKey(ret), 1) } old := ents.Get(keyBytes(ret)) oldPM := ds.PropertyMap(nil) if old != nil { if oldPM, err = rpm(old); err != nil { return } } ents.Set(keyBytes(ret), dataBytes) updateIndexes(d.head, ret, oldPM, pmap) return }() if cb != nil { if err := cb(k, err); err != nil { if err == ds.Stop { return nil } return err } } } return nil }
func TestIndexRowGen(t *testing.T) { t.Parallel() Convey("Test Index Row Generation", t, func() { for _, tc := range rowGenTestCases { if tc.expected == nil { Convey(tc.name, nil) // shows up as 'skipped' continue } Convey(tc.name, func() { mvals := serialize.PropertyMapPartially(fakeKey, tc.pmap) idxs := []*ds.IndexDefinition(nil) if tc.withBuiltin { idxs = append(defaultIndexes("coolKind", tc.pmap), tc.idxs...) } else { idxs = tc.idxs } m := matcher{} for i, idx := range idxs { Convey(idx.String(), func() { iGen, ok := m.match(idx.GetFullSortOrder(), mvals) if len(tc.expected[i]) > 0 { So(ok, ShouldBeTrue) actual := make(serialize.SerializedPslice, 0, len(tc.expected[i])) iGen.permute(func(row, _ []byte) { actual = append(actual, row) }) So(len(actual), ShouldEqual, len(tc.expected[i])) sort.Sort(actual) for j, act := range actual { So(act, ShouldResemble, tc.expected[i][j]) } } else { So(ok, ShouldBeFalse) } }) } }) } }) Convey("default indexes", t, func() { Convey("nil collated", func() { Convey("defaultIndexes (nil)", func() { idxs := defaultIndexes("knd", ds.PropertyMap(nil)) So(len(idxs), ShouldEqual, 1) So(idxs[0].String(), ShouldEqual, "B:knd") }) Convey("indexEntries", func() { sip := serialize.PropertyMapPartially(fakeKey, nil) s := indexEntries(sip, "ns", defaultIndexes("knd", ds.PropertyMap(nil))) numItems, _ := s.GetCollection("idx").GetTotals() So(numItems, ShouldEqual, 1) itm := s.GetCollection("idx").MinItem(false) So(itm.Key, ShouldResemble, cat(indx("knd").PrepForIdxTable())) numItems, _ = s.GetCollection("idx:ns:" + string(itm.Key)).GetTotals() So(numItems, ShouldEqual, 1) }) Convey("defaultIndexes", func() { pm := ds.PropertyMap{ "wat": {propNI("thing"), prop("hat"), prop(100)}, "nerd": {prop(103.7)}, "spaz": {propNI(false)}, } idxs := defaultIndexes("knd", pm) So(len(idxs), ShouldEqual, 5) So(idxs[0].String(), ShouldEqual, "B:knd") So(idxs[1].String(), ShouldEqual, "B:knd/nerd") So(idxs[2].String(), ShouldEqual, "B:knd/wat") So(idxs[3].String(), ShouldEqual, "B:knd/-nerd") So(idxs[4].String(), ShouldEqual, "B:knd/-wat") }) }) }) }