Completed minimal Ledger implementation, first tests in chron-cli
This commit is contained in:
121
core/ledger.go
121
core/ledger.go
@@ -1,6 +1,10 @@
|
||||
package core
|
||||
|
||||
import ()
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Ledger struct {
|
||||
entryStore EntryStore
|
||||
@@ -14,10 +18,111 @@ func NewLedger(entryStore EntryStore, referenceStore ReferenceStore) (*Ledger, e
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (l *Ledger) Append() {}
|
||||
func (l *Ledger) AppendToReference() {}
|
||||
func (l *Ledger) Get() {}
|
||||
func (l *Ledger) GetFromReference() {}
|
||||
func (l *Ledger) SetHead() {}
|
||||
func (l *Ledger) SetReference() {}
|
||||
func (l *Ledger) RemoveReference() {}
|
||||
func (l *Ledger) Append(ctx context.Context, payload []byte) error {
|
||||
currentHeadEntryID, ok, err := l.referenceStore.Get(ctx, "HEAD")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
l.referenceStore.Set(ctx, "HEAD", EntryID{})
|
||||
currentHeadEntryID = EntryID{}
|
||||
}
|
||||
|
||||
entryTime := time.Now()
|
||||
entryID := ComputeEntryID(currentHeadEntryID, entryTime, payload)
|
||||
|
||||
entry := Entry{
|
||||
EntryID: entryID,
|
||||
Previous: currentHeadEntryID,
|
||||
Timestamp: entryTime,
|
||||
Payload: payload,
|
||||
}
|
||||
|
||||
if ComputeEntryID(entry.Previous, entry.Timestamp, entry.Payload) != entryID {
|
||||
panic("EntryID hash mismatch fuckup")
|
||||
}
|
||||
|
||||
err = l.entryStore.Store(ctx, entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = l.referenceStore.Set(ctx, "HEAD", entry.EntryID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Ledger) AppendTo(ctx context.Context, prevEntryID EntryID, payload []byte) error {
|
||||
entryTime := time.Now()
|
||||
entryID := ComputeEntryID(prevEntryID, entryTime, payload)
|
||||
|
||||
entry := Entry{
|
||||
EntryID: entryID,
|
||||
Previous: prevEntryID,
|
||||
Timestamp: entryTime,
|
||||
Payload: payload,
|
||||
}
|
||||
|
||||
if ComputeEntryID(entry.Previous, entry.Timestamp, entry.Payload) != entryID {
|
||||
panic("EntryID hash mismatch fuckup")
|
||||
}
|
||||
|
||||
err := l.entryStore.Store(ctx, entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Ledger) Get(ctx context.Context) (Entry, error) {
|
||||
headEntryID, ok, err := l.referenceStore.Get(ctx, "HEAD")
|
||||
if err != nil {
|
||||
return Entry{}, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return Entry{}, errors.New("HEAD not set")
|
||||
}
|
||||
|
||||
entry, err := l.entryStore.Load(ctx, headEntryID)
|
||||
if err != nil {
|
||||
return Entry{}, err
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
func (l *Ledger) GetFromReference(ctx context.Context, reference string) (Entry, error) {
|
||||
referenceEntryID, ok, err := l.referenceStore.Get(ctx, reference)
|
||||
if err != nil {
|
||||
return Entry{}, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
return Entry{}, errors.New("HEAD not set")
|
||||
}
|
||||
|
||||
entry, err := l.entryStore.Load(ctx, referenceEntryID)
|
||||
if err != nil {
|
||||
return Entry{}, err
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
func (l *Ledger) SetHead(ctx context.Context, entryID EntryID) error {
|
||||
return l.referenceStore.Set(ctx, "HEAD", entryID)
|
||||
}
|
||||
|
||||
func (l *Ledger) SetReference(ctx context.Context, reference string, entryID EntryID) error {
|
||||
return l.referenceStore.Set(ctx, reference, entryID)
|
||||
}
|
||||
|
||||
func (l *Ledger) RemoveReference(ctx context.Context, reference string) error {
|
||||
return l.referenceStore.Delete(ctx, reference)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user