94 lines
1.9 KiB
Go
94 lines
1.9 KiB
Go
package ramdb
|
|
|
|
import "github.com/google/btree"
|
|
|
|
// Get validates that the table and index for the given column exists and searches for the given key in the tree.
|
|
func (t *table) Get(column, key string) (r *Record, err error) {
|
|
if !t.exists {
|
|
return nil, ErrNoTable
|
|
}
|
|
|
|
if !t.HasIndex(column) {
|
|
return nil, ErrNoIndex
|
|
}
|
|
|
|
return t.keyLookup(key, t.indexes[column])
|
|
}
|
|
|
|
// keyLookup tries to find the given key in the tree. It returns ErrNoRecord if not found.
|
|
func (t *table) keyLookup(key string, index *index) (r *Record, err error) {
|
|
item := &Record{id: keyHash(key)}
|
|
result := index.tree.Get(item)
|
|
if result == nil {
|
|
return nil, ErrNoRecord
|
|
}
|
|
|
|
return result.(*Record), nil
|
|
}
|
|
|
|
// Select returns all of the Records in the database sorted in ascending order by id.
|
|
func (t *table) Select(column string) (rr []*Record, err error) {
|
|
if !t.exists {
|
|
return nil, ErrNoTable
|
|
}
|
|
|
|
if !t.HasIndex(column) {
|
|
return nil, ErrNoIndex
|
|
}
|
|
|
|
t.indexes[column].tree.Ascend(func(item btree.Item) bool {
|
|
r := item.(*Record)
|
|
rr = append(rr, r)
|
|
return true
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
// Insert adds the Record to the database. It returns ErrRecordExists if the Record already exists. Insert is thread safe.
|
|
func (t *table) Insert(r *Record) error {
|
|
if !t.exists {
|
|
return ErrNoTable
|
|
}
|
|
|
|
if !t.HasIndex(r.keyColumn) {
|
|
return ErrNoIndex
|
|
}
|
|
|
|
index := t.indexes[r.keyColumn]
|
|
|
|
if has := index.tree.Has(r); has {
|
|
return ErrRecordExists
|
|
}
|
|
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
index.tree.ReplaceOrInsert(r)
|
|
return nil
|
|
|
|
}
|
|
|
|
// Delete removes the item from the database. It returns ErrNoRecord if the Record does not exist and ErrNotDeleted if the removal fails. Delete is thread safe.
|
|
func (t *table) Delete(r *Record) error {
|
|
if !t.exists {
|
|
return ErrNoTable
|
|
}
|
|
|
|
if !t.HasIndex(r.keyColumn) {
|
|
return ErrNoIndex
|
|
}
|
|
|
|
index := t.indexes[r.keyColumn]
|
|
|
|
if has := index.tree.Has(r); !has {
|
|
return ErrNoRecord
|
|
}
|
|
|
|
t.mutex.Lock()
|
|
defer t.mutex.Unlock()
|
|
|
|
index.tree.Delete(r)
|
|
return nil
|
|
}
|