// Store records in the database. In combination with a queue or // numbered database the append flags causes the keys of the records // to be set to fresh record numbers, for any other database it // prevents an existing record with the same key from being // overwritten. func (db Database) Put(txn Transaction, append bool, recs ...proto.Message) (err error) { dbtype, err := db.Type() if err != nil { return } var key, data C.DBT var flags C.u_int32_t = 0 if append { key.flags |= C.DB_DBT_USERMEM switch dbtype { case Numbered, Queue: flags |= C.DB_APPEND default: flags |= C.DB_NOOVERWRITE } } else { key.flags |= C.DB_DBT_READONLY } data.flags |= C.DB_DBT_READONLY for _, rec := range recs { err = db.marshalData(&data, rec) if err != nil { return } err = db.marshalKey(&key, rec) if err == nil { key.ulen = key.size } else { return } err = check(C.db_put(db.ptr, txn.ptr, &key, &data, flags)) if err != nil { return } } return }
// Get records from the database. The consume flag makes sense only in // combination with a queue database and causes the operation to wait // for and obtain the next enqueued record. func (db Database) Get(txn Transaction, consume bool, recs ...proto.Message) (err error) { var key, data C.DBT var flags C.u_int32_t = 0 if consume { key.flags |= C.DB_DBT_USERMEM flags |= C.DB_CONSUME_WAIT } else { key.flags |= C.DB_DBT_READONLY } data.flags |= C.DB_DBT_REALLOC defer C.free(data.data) for _, rec := range recs { err = db.marshalKey(&key, rec) if err == nil { key.ulen = key.size } else { return } err = check(C.db_get(db.ptr, txn.ptr, &key, &data, flags)) if err != nil { return } err = db.unmarshalData(&data, rec) if err != nil { return } err = db.unmarshalKey(&key, rec) if err != nil { return } } return }