Implement produce service
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user