Çöñţéñţ Šţöŕé
Ţĥé Çöñţéñţ Šţöŕé îš ţĥé ṽéŕšîöñéđ, çöñţéñţ-àđđŕéššàƃļé þéŕšîšţéñçé ļàýéŕ ƒöŕ Ƃöŵŕàîñ þŕöĵéçţš.
Àŕçĥîţéçţüŕé
Ţĥé šţöŕé šîţš ƃéţŵééñ çöññéçţöŕš, ŵĥîçĥ þüļļ àñđ þüšĥ éẋţéŕñàļ çöñţéñţ, àñđ ţĥé þŕöçéššîñĝ þîþéļîñé: ƒļöŵš, ţööļš, çöñţéñţ ḿéḿöŕý àñđ ţéŕḿš. Ṽéŕšîöñš ŕéçöŕđ ñàḿéđ šñàþšĥöţš öƒ ţĥé šţöŕé.
Ķéý Çöñçéþţš
- ƂļöçķÎđéñţîţý: çöñţéñţ-àđđŕéššàƃļé ĥàšĥîñĝ (ŠĤÀ-256) ƒöŕ ƃļöçķ đéđüþļîçàţîöñ àñđ çĥàñĝé đéţéçţîöñ
- ÇöñţéñţŔéƒ: ļîñķš ƃļöçķš ţö ţĥéîŕ éẋţéŕñàļ çöññéçţöŕ šöüŕçé ŵîţĥ šýñç ţŕàçķîñĝ
- ĐîšþļàýĤîñţ: ÜÎ ŕéñđéŕîñĝ ĝüîđàñçé (þŕéṽîéŵ, çöñţéẋţ, ḿàẋ ļéñĝţĥ, çöñţéñţ ţýþé)
- Ṽéŕšîöñ: ñàḿéđ šñàþšĥöţ öƒ þŕöĵéçţ šţàţé ŵîţĥ ƃļöçķ-ļéṽéļ đîñĝ
ÇöñţéñţŠţöŕé Îñţéŕƒàçé
ContentStore (bowrain/core/store/store.go) îš ţĥé üñîöñ öƒ ŕöļé
îñţéŕƒàçéš, öñé þéŕ çöñçéŕñ. Àļļ çöñţéñţ öþéŕàţîöñš àŕé šţŕéàḿ-šçöþéđ: àñ
éḿþţý šţŕéàḿ ñàḿé đéƒàüļţš ţö "main", ŵĥîçĥ éṽéŕý þŕöĵéçţ îḿþļîçîţļý ĥàš.
// ContentStore is the primary persistence interface for content,
// the union of the role interfaces. All content operations are stream-scoped.
type ContentStore interface {
ProjectStore // projects: create, get, list, update, delete
StreamStore // streams within a project
CollectionStore // collections (stream-scoped)
ItemStore // items (stream-scoped)
BlockStore // blocks, notes, history (stream-scoped)
VersionStore // named versions + diffs (stream-scoped)
ChangeFeed // incremental sync change log (stream-scoped)
AssetStore // assets and locale variants
Close() error
}
Ŕéþŕéšéñţàţîṽé šîĝñàţüŕéš; ñöţé ţĥé stream þàŕàḿéţéŕ ţĥŕöüĝĥöüţ:
// BlockStore
StoreBlocks(ctx context.Context, projectID, stream string, blocks []*model.Block) error
GetBlocks(ctx context.Context, query BlockQuery) ([]*StoredBlock, error)
// VersionStore
CreateVersion(ctx context.Context, projectID, stream, label, description string) (*Version, error)
Diff(ctx context.Context, fromVersion, toVersion string) (*VersionDiff, error)
Ƃàçķéñđš
Ţŵö ƃàçķéñđš îḿþļéḿéñţ ContentStore, ŵîţĥ đéŕéñţ ŕöļéš:
- ÞöšţĝŕéŠǪĻ îš ţĥé šéŕṽéŕ'š öñļý ƃàçķéñđ.
bowrain-serverŕéƒüšéš ţö šţàŕţ ŵîţĥöüţ àpostgres://đàţàƃàšé ÜŔĻ àñđ ƃüîļđš àļļ öƒ îţš šţöŕéš öñ ţĥàţ çöññéçţîöñ. Ţĥîš îš ţĥé šöüŕçé öƒ ţŕüţĥ ƒöŕ éṽéŕý ŵöŕķšþàçé. - ŠǪĻîţé (
bowrain/store/sqlitestore) ƃàçķš ţĥé đéšķţöþ àþþ'š ļöçàļ ŵöŕķîñĝ çöþý: à çàçĥé ƒöŕ šþééđ àñđ öƒƒļîñé éđîţš ţĥàţ ḿîŕŕöŕš ţĥé šéŕṽéŕ àñđ îš ñéṽéŕ à šöüŕçé öƒ ţŕüţĥ.
import "github.com/neokapi/neokapi/bowrain/store/sqlitestore"
store, err := sqlitestore.NewSQLiteStore("working-copy.db")
if err != nil {
log.Fatal(err)
}
defer store.Close()
Ƃöţĥ ƃàçķéñđš šĥàŕé öñé ļöĝîçàļ šçĥéḿà: þŕöĵéçţš, šţŕéàḿš, çöļļéçţîöñš, îţéḿš, ƃļöçķš, ṽéŕšîöñš, ţĥé çĥàñĝé ļöĝ, àñđ àššéţš.
Ĥéļđ ƃļöçķ ŵŕîţéš
Ţĥé šéŕṽéŕ'š çĥàñĝé šéŕṽîçé ŕéàđš àñđ ŵŕîţéš à šţŕéàḿ'š ƃļöçķš ţĥŕöüĝĥ
BlockWriteStore, ŵĥîçĥ ţĥé ÞöšţĝŕéŠǪĻ ƃàçķéñđ îḿþļéḿéñţš àñđ ţĥé
éṽéñţ-éḿîţţîñĝ đéçöŕàţöŕ ƒöŕŵàŕđš:
// BlockWriteStore
ItemBlocks(ctx context.Context, projectID, stream, itemName string, keys []string) ([]*StoredBlock, error)
BeginBlockWrite(ctx context.Context, projectID, stream string) (BlockWrite, error)
// BlockWrite
Hold(ctx context.Context, itemName string, keys []string) ([]*StoredBlock, error)
Store(ctx context.Context, blocks []*StoredBlock) error
Commit() error
Rollback() error
keys ñàḿéš ƃļöçķš ƃý ţĥéîŕ đüŕàƃļé ķéý, ţĥéîŕ ñàḿé öŕ ţĥéîŕ ŕöŵ îđ. À
BlockWrite îš öñé ţŕàñšàçţîöñ üñđéŕ ţĥé šţŕéàḿ'š šĥàŕéđ ŵŕîţé ļöçķ. Hold
ŕéàđš àñ îţéḿ'š ƃļöçķš àñđ ļöçķš ţĥéîŕ ŕöŵš üñţîļ ţĥé ŵŕîţé éñđš. Store
ŵŕîţéš ţĥé çĥàñĝéđ ƃļöçķš ƃàçķ ţö ţĥöšé ŕöŵš ŵîţĥ ţĥéîŕ ĥîšţöŕý àñđ çĥàñĝé-ļöĝ
éñţŕîéš, àñđ đéļéţéš ţĥé ŕöŵ öƒ éàçĥ ţŕàñšļàţîöñ ţĥé çĥàñĝé ŕéḿöṽéđ, ŕéçöŕđîñĝ
ţĥé ŕéḿöṽàļ àš target_removed. Ţĥé çĥàñĝé šéŕṽîçé ĥöļđš éṽéŕý îţéḿ à çĥàñĝé
šéţ ñàḿéš öñ öñé BlockWrite àñđ çöḿþàŕéš ţĥé ŕéṽîšîöñ éàçĥ öþéŕàţîöñ ñàḿéš
àĝàîñšţ ţĥé ĥéļđ ŕöŵš, šö ñö öţĥéŕ ŵŕîţé ļàñđš ƃéţŵééñ ţĥàţ çöḿþàŕîšöñ àñđ ţĥé
çöḿḿîţ, àñđ ţĥé çĥàñĝé šéţ ļàñđš ŵĥöļé öñ öñé çöññéçţîöñ.
Ŕéṽéŕţ, ŕéšţöŕé-ţö-þöîñţ àñđ ŕöļļƃàçķ ŕéàđ à ţŕàñšļàţîöñ'š ĥîšţöŕý ƃý ţĥé ŕöŵš
ţĥàţ ŕéçöŕđ îţš çöñţéñţ (target_added, target_modified, target_removed).
À target_removed ŕöŵ ŕéšţöŕéš ñö ţŕàñšļàţîöñ, àñđ à đéçîšîöñ ŕöŵ ŕéšţöŕéš
ñöţĥîñĝ.
Ƃļöçķ Îđéñţîţý
Éṽéŕý šţöŕéđ ƃļöçķ ĝéţš à çöñţéñţ-àđđŕéššàƃļé îđéñţîţý çöḿþüţéđ ƒŕöḿ îţš šöüŕçé ţéẋţ:
identity := model.ComputeIdentity(block)
// identity.ContentHash = SHA-256 of normalized source text
// identity.ContextHash = SHA-256 of block name, type, and properties
Ţĥîš éñàƃļéš:
- Đéđüþļîçàţîöñ: îđéñţîçàļ šöüŕçé ţéẋţ šĥàŕéš ţĥé šàḿé çöñţéñţ ĥàšĥ
- Çĥàñĝé đéţéçţîöñ: ṽéŕšîöñ đš çöḿþàŕé çöñţéñţ ĥàšĥéš îñšţéàđ öƒ ƒüļļ ţéẋţ
- Çàçĥé îñṽàļîđàţîöñ: ŕéšüļţš çàñ ƃé çàçĥéđ ƃý çöñţéñţ ĥàšĥ
Ṽéŕšîöñ Ţŕàçķîñĝ
Ṽéŕšîöñš àŕé ñàḿéđ šñàþšĥöţš öƒ à þŕöĵéçţ'š ƃļöçķ šţàţé:
// Create a snapshot of a stream
v, err := store.CreateVersion(ctx, projectID, "main", "v1.0", "Initial release")
// List a stream's versions
versions, err := store.ListVersions(ctx, projectID, "main")
// Diff two versions
diff, err := store.Diff(ctx, v1.ID, v2.ID)
for _, change := range diff.Changes {
fmt.Printf("%s: %s\n", change.BlockID, change.ChangeType)
}
Ƒļöŵ Îñţéĝŕàţîöñ
Šéŕṽéŕ-šîđé ƒļöŵš ŕéàđ ƒŕöḿ àñđ ŵŕîţé ţö ţĥé çöñţéñţ šţöŕé ţĥŕöüĝĥ ţĥé ƒļöŵ šéŕṽîçé: à ŕüñ ļöàđš ţĥé þŕöĵéçţ'š ƃļöçķš ƒŕöḿ ţĥé šţöŕé, éẋéçüţéš ţĥé ƒļöŵ, àñđ šţöŕéš ţĥé þŕöđüçéđ ţàŕĝéţš ƃàçķ. Šéé Šéŕṽéŕ-šîđé ƒļöŵš.