// // Create an index given the name (index) and a list of field positions // used to create a composite key. // // nilFirst specifies if nil values should sort first (lowest possible value) or last (highest possible value) // // The field position should corrispond to the entries in DataRecord ToFieldList() and FromFieldList() // func (t *Table) CreateIndex(index string, nilFirst bool, fields ...uint64) error { db := (*bolt.DB)(t.d) err := db.Update(func(tx *bolt.Tx) error { b := tx.Bucket(schema(t.name)) if b == nil { return NO_TABLE } b1, err := typedbuffer.Encode(nilFirst) if err != nil { return BAD_VALUES } b2, err := typedbuffer.Encode(fields) if err != nil { return BAD_VALUES } enc := append(b1, b2...) if err := b.Put([]byte(index), enc); err != nil { return err } if _, err := tx.CreateBucket(indices(index)); err != nil { return err } return nil }) if err == nil { t.indices[index] = indexinfo{ nilFirst: nilFirst, iplist: makeIndexPos(fields), } } return err }
// // Delete a record from the table, given the index and the key // func (t *Table) Delete(index string, key DataRecord) error { db := (*bolt.DB)(t.d) err := db.Update(func(tx *bolt.Tx) error { b := tx.Bucket(indices(index)) if b == nil { return NO_INDEX } info := t.indices[index] sk, _, err := info.marshalKeyValue(key.ToFieldList()) if err != nil { return err } if sk == nil { return NO_KEY } c := b.Cursor() k, v := c.Seek(sk) // Seek will return the next key if there is no match // so make sure we check we got the right record if bytes.Equal(sk, k) { if err := c.Delete(); err != nil { return err } fields, err := info.unmarshalKeyValue(k, v) if err != nil { return err } for i, info := range t.indices { if i == index { // already done continue } b := tx.Bucket(indices(i)) if b == nil { continue } // could use marshalKeyValue() instead vkey := make([]interface{}, len(info.iplist)) for _, ip := range info.iplist { vkey[ip.pos] = fields[ip.field] } dkey, err := typedbuffer.Encode(vkey...) if err != nil { return err } if err := b.Delete(dkey); err != nil { return err } } } return nil }) return err }