Implement produce service

This commit is contained in:
2021-06-20 18:16:33 -04:00
parent c7cbd7df57
commit 0136e616fb
14 changed files with 537 additions and 37 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ indog := HotDog{
Brat: true,
}
// Create a new record and insert.
// Create a new Record and insert.
rec, _ := ramdb.NewRecord("1", "frank_id", indog)
_ = db.From("hotdogs").Insert(rec)
+11 -11
View File
@@ -3,7 +3,7 @@ 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) {
func (t *table) Get(column, key string) (r *Record, err error) {
if !t.exists {
return nil, ErrNoTable
}
@@ -16,18 +16,18 @@ func (t *table) Get(column, key string) (r *record, err error) {
}
// 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)}
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
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) {
// 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
}
@@ -37,7 +37,7 @@ func (t *table) Select(column string) (rr []*record, err error) {
}
t.indexes[column].tree.Ascend(func(item btree.Item) bool {
r := item.(*record)
r := item.(*Record)
rr = append(rr, r)
return true
})
@@ -45,8 +45,8 @@ func (t *table) Select(column string) (rr []*record, err error) {
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 {
// 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
}
@@ -69,8 +69,8 @@ func (t *table) Insert(r *record) error {
}
// 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 {
// 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
}
+15 -15
View File
@@ -14,7 +14,7 @@ func TestTable_Get(t *testing.T) {
tests := []struct {
test string
tableConfig func() *table
expectedRecord *record
expectedRecord *Record
expectedError error
}{
{
@@ -34,7 +34,7 @@ func TestTable_Get(t *testing.T) {
expectedError: ErrNoIndex,
},
{
test: "it should return ErrNoRecord if no record was found for key",
test: "it should return ErrNoRecord if no Record was found for key",
tableConfig: func() *table {
return &table{
exists: true,
@@ -48,7 +48,7 @@ func TestTable_Get(t *testing.T) {
expectedError: ErrNoRecord,
},
{
test: "it should return a record when one is found",
test: "it should return a Record when one is found",
tableConfig: func() *table {
tbl := &table{
exists: true,
@@ -65,7 +65,7 @@ func TestTable_Get(t *testing.T) {
tbl.indexes["test_column"].tree.ReplaceOrInsert(rec)
return tbl
},
expectedRecord: &record{
expectedRecord: &Record{
serialized: []uint8{0x7b, 0x7d},
key: "test_key",
keyColumn: "test_column",
@@ -78,9 +78,9 @@ func TestTable_Get(t *testing.T) {
t.Run(tc.test, func(t *testing.T) {
tbl := tc.tableConfig()
record, err := tbl.Get("test_column", "test_key")
Record, err := tbl.Get("test_column", "test_key")
assert.Equal(t, tc.expectedRecord, record)
assert.Equal(t, tc.expectedRecord, Record)
assert.Equal(t, tc.expectedError, err)
})
}
@@ -89,13 +89,13 @@ func TestTable_Get(t *testing.T) {
func TestTable_Select(t *testing.T) {
tests := []struct {
test string
tableConfig func() (*table, []*record)
expectedRecords []*record
tableConfig func() (*table, []*Record)
expectedRecords []*Record
expectedError error
}{
{
test: "it should return ErrNoTable if an invalid table is supplied",
tableConfig: func() (*table, []*record) {
tableConfig: func() (*table, []*Record) {
return &table{
mutex: &sync.Mutex{},
}, nil
@@ -104,7 +104,7 @@ func TestTable_Select(t *testing.T) {
},
{
test: "it should return ErrNoIndex if no index exists for column",
tableConfig: func() (*table, []*record) {
tableConfig: func() (*table, []*Record) {
return &table{
exists: true,
mutex: &sync.Mutex{},
@@ -114,8 +114,8 @@ func TestTable_Select(t *testing.T) {
expectedError: ErrNoIndex,
},
{
test: "it should return all records in the database",
tableConfig: func() (*table, []*record) {
test: "it should return all Records in the database",
tableConfig: func() (*table, []*Record) {
tbl := &table{
exists: true,
mutex: &sync.Mutex{},
@@ -126,7 +126,7 @@ func TestTable_Select(t *testing.T) {
},
}
expectedRecords := make([]*record, 0)
expectedRecords := make([]*Record, 0)
for i := 0; i < 10; i++ {
key := fmt.Sprintf("key-%d", i)
rec, err := NewRecord(key, "test_column", struct{}{})
@@ -185,7 +185,7 @@ func TestTable_Insert(t *testing.T) {
expectedError: ErrNoIndex,
},
{
test: "it should return ErrRecordExists if a record with key exists",
test: "it should return ErrRecordExists if a Record with key exists",
tableConfig: func() *table {
tbl := &table{
exists: true,
@@ -265,7 +265,7 @@ func TestTable_Delete(t *testing.T) {
expectedError: ErrNoIndex,
},
{
test: "it should return ErrNoRecord if the record does not exist",
test: "it should return ErrNoRecord if the Record does not exist",
tableConfig: func() *table {
return &table{
exists: true,
+8 -8
View File
@@ -8,21 +8,21 @@ import (
"github.com/google/btree"
)
type record struct {
type Record struct {
serialized []byte
keyColumn string
key string
id uint64
}
// NewRecord returns a pointer to a record populated with data, key, and a hash of the key used for ordering in the tree.
func NewRecord(key, keyColumn string, data interface{}) (*record, error) {
// NewRecord returns a pointer to a Record populated with data, key, and a hash of the key used for ordering in the tree.
func NewRecord(key, keyColumn string, data interface{}) (*Record, error) {
serialized, err := json.Marshal(data)
if err != nil {
return nil, err
}
var r record
var r Record
r.serialized = serialized
r.keyColumn = keyColumn
r.key = key
@@ -39,13 +39,13 @@ func keyHash(s string) uint64 {
}
// Deserialize unmarshals the serialized data into `into`.
func (r *record) Deserialize(into interface{}) error {
func (r *Record) Deserialize(into interface{}) error {
err := json.Unmarshal(r.serialized, &into)
return err
}
// Less is used to order items and for looking up records in the tree.
func (r *record) Less(than btree.Item) bool {
re := than.(*record)
// Less is used to order items and for looking up Records in the tree.
func (r *Record) Less(than btree.Item) bool {
re := than.(*Record)
return r.id < re.id
}
+2 -2
View File
@@ -12,7 +12,7 @@ func TestRecord_NewRecord(t *testing.T) {
key string
keyColumn string
data interface{}
expectedRecord *record
expectedRecord *Record
expectedError string
}{
{
@@ -29,7 +29,7 @@ func TestRecord_NewRecord(t *testing.T) {
key: "test-record",
keyColumn: "test-column",
data: struct{}{},
expectedRecord: &record{
expectedRecord: &Record{
serialized: []byte("{}"),
key: "test-record",
keyColumn: "test-column",