Merge pull request #22 from Quentin-M/predcst

database: put missing predicates in consts and un-expose some of them
This commit is contained in:
Quentin Machu 2015-12-04 16:53:35 -05:00
commit f106b64bc4
8 changed files with 103 additions and 79 deletions

View File

@ -37,8 +37,8 @@ import (
) )
const ( const (
// FieldIs is the graph predicate defining the type of an entity. // fieldIs is the graph predicate defining the type of an entity.
FieldIs = "is" fieldIs = "is"
) )
var ( var (

View File

@ -49,13 +49,13 @@ func TestToValue(t *testing.T) {
assert.Equal(t, "", v, "toValue should return an error and an empty string if the path leads to multiple values") assert.Equal(t, "", v, "toValue should return an error and an empty string if the path leads to multiple values")
// toValues() // toValues()
vs, err := toValues(cayley.StartPath(store, "CoreOS").Out(FieldIs)) vs, err := toValues(cayley.StartPath(store, "CoreOS").Out(fieldIs))
assert.Nil(t, err, "toValues should work even if the requested path leads to nothing") assert.Nil(t, err, "toValues should work even if the requested path leads to nothing")
assert.Len(t, vs, 0, "toValue should return an empty array if the requested path leads to nothing") assert.Len(t, vs, 0, "toValue should return an empty array if the requested path leads to nothing")
words := []string{"powerful", "lightweight"} words := []string{"powerful", "lightweight"}
for i, word := range words { for i, word := range words {
store.AddQuad(cayley.Quad("CoreOS", FieldIs, word, "")) store.AddQuad(cayley.Quad("CoreOS", fieldIs, word, ""))
v, err := toValues(cayley.StartPath(store, "CoreOS").Out(FieldIs)) v, err := toValues(cayley.StartPath(store, "CoreOS").Out(fieldIs))
assert.Nil(t, err, "toValues should have worked") assert.Nil(t, err, "toValues should have worked")
assert.Len(t, v, i+1, "toValues did not return the right amount of values") assert.Len(t, v, i+1, "toValues did not return the right amount of values")
for _, e := range words[:i+1] { for _, e := range words[:i+1] {

View File

@ -19,6 +19,11 @@ import (
"github.com/google/cayley" "github.com/google/cayley"
) )
const (
fieldFlagValue = "value"
flagNodePrefix = "flag"
)
// UpdateFlag creates a flag or update an existing flag's value // UpdateFlag creates a flag or update an existing flag's value
func UpdateFlag(name, value string) error { func UpdateFlag(name, value string) error {
if name == "" || value == "" { if name == "" || value == "" {
@ -36,11 +41,11 @@ func UpdateFlag(name, value string) error {
} }
// Build transaction // Build transaction
name = "flag:" + name name = flagNodePrefix + ":" + name
if currentValue != "" { if currentValue != "" {
t.RemoveQuad(cayley.Quad(name, "value", currentValue, "")) t.RemoveQuad(cayley.Quad(name, fieldFlagValue, currentValue, ""))
} }
t.AddQuad(cayley.Quad(name, "value", value, "")) t.AddQuad(cayley.Quad(name, fieldFlagValue, value, ""))
// Apply transaction // Apply transaction
if err = store.ApplyTransaction(t); err != nil { if err = store.ApplyTransaction(t); err != nil {
@ -54,5 +59,5 @@ func UpdateFlag(name, value string) error {
// GetFlagValue returns the value of the flag given by its name (or an empty string if the flag does not exist) // GetFlagValue returns the value of the flag given by its name (or an empty string if the flag does not exist)
func GetFlagValue(name string) (string, error) { func GetFlagValue(name string) (string, error) {
return toValue(cayley.StartPath(store, "flag:"+name).Out("value")) return toValue(cayley.StartPath(store, flagNodePrefix+":"+name).Out(fieldFlagValue))
} }

View File

@ -25,16 +25,17 @@ import (
) )
const ( const (
FieldLayerIsValue = "layer"
FieldLayerID = "id" FieldLayerID = "id"
FieldLayerParent = "parent" FieldLayerParent = "parent"
FieldLayerSuccessors = "successors" FieldLayerSuccessors = "successors"
FieldLayerOS = "os" FieldLayerOS = "os"
FieldLayerInstalledPackages = "adds"
FieldLayerRemovedPackages = "removes"
FieldLayerEngineVersion = "engineVersion" FieldLayerEngineVersion = "engineVersion"
FieldLayerPackages = "adds/removes" FieldLayerPackages = "adds/removes"
// These fields are not selectable and are for internal use only.
fieldLayerIsValue = "layer"
fieldLayerInstalledPackages = "adds"
fieldLayerRemovedPackages = "removes"
) )
var FieldLayerAll = []string{FieldLayerID, FieldLayerParent, FieldLayerSuccessors, FieldLayerOS, FieldLayerPackages, FieldLayerEngineVersion} var FieldLayerAll = []string{FieldLayerID, FieldLayerParent, FieldLayerSuccessors, FieldLayerOS, FieldLayerPackages, FieldLayerEngineVersion}
@ -54,7 +55,7 @@ type Layer struct {
// GetNode returns the node name of a Layer // GetNode returns the node name of a Layer
// Requires the key field: ID // Requires the key field: ID
func (l *Layer) GetNode() string { func (l *Layer) GetNode() string {
return FieldLayerIsValue + ":" + utils.Hash(l.ID) return fieldLayerIsValue + ":" + utils.Hash(l.ID)
} }
// InsertLayer insert a single layer in the database // InsertLayer insert a single layer in the database
@ -97,17 +98,17 @@ func InsertLayer(layer *Layer) error {
if existingLayer == nil { if existingLayer == nil {
// Create case: add permanent nodes // Create case: add permanent nodes
t.AddQuad(cayley.Quad(layer.Node, FieldIs, FieldLayerIsValue, "")) t.AddQuad(cayley.Quad(layer.Node, fieldIs, fieldLayerIsValue, ""))
t.AddQuad(cayley.Quad(layer.Node, FieldLayerID, layer.ID, "")) t.AddQuad(cayley.Quad(layer.Node, FieldLayerID, layer.ID, ""))
t.AddQuad(cayley.Quad(layer.Node, FieldLayerParent, layer.ParentNode, "")) t.AddQuad(cayley.Quad(layer.Node, FieldLayerParent, layer.ParentNode, ""))
} else { } else {
// Update case: remove everything before we add updated data // Update case: remove everything before we add updated data
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerOS, existingLayer.OS, "")) t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerOS, existingLayer.OS, ""))
for _, pkg := range existingLayer.InstalledPackagesNodes { for _, pkg := range existingLayer.InstalledPackagesNodes {
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerInstalledPackages, pkg, "")) t.RemoveQuad(cayley.Quad(layer.Node, fieldLayerInstalledPackages, pkg, ""))
} }
for _, pkg := range existingLayer.RemovedPackagesNodes { for _, pkg := range existingLayer.RemovedPackagesNodes {
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerRemovedPackages, pkg, "")) t.RemoveQuad(cayley.Quad(layer.Node, fieldLayerRemovedPackages, pkg, ""))
} }
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerEngineVersion, strconv.Itoa(existingLayer.EngineVersion), "")) t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerEngineVersion, strconv.Itoa(existingLayer.EngineVersion), ""))
} }
@ -115,10 +116,10 @@ func InsertLayer(layer *Layer) error {
// Add OS/Packages // Add OS/Packages
t.AddQuad(cayley.Quad(layer.Node, FieldLayerOS, layer.OS, "")) t.AddQuad(cayley.Quad(layer.Node, FieldLayerOS, layer.OS, ""))
for _, pkg := range layer.InstalledPackagesNodes { for _, pkg := range layer.InstalledPackagesNodes {
t.AddQuad(cayley.Quad(layer.Node, FieldLayerInstalledPackages, pkg, "")) t.AddQuad(cayley.Quad(layer.Node, fieldLayerInstalledPackages, pkg, ""))
} }
for _, pkg := range layer.RemovedPackagesNodes { for _, pkg := range layer.RemovedPackagesNodes {
t.AddQuad(cayley.Quad(layer.Node, FieldLayerRemovedPackages, pkg, "")) t.AddQuad(cayley.Quad(layer.Node, fieldLayerRemovedPackages, pkg, ""))
} }
t.AddQuad(cayley.Quad(layer.Node, FieldLayerEngineVersion, strconv.Itoa(layer.EngineVersion), "")) t.AddQuad(cayley.Quad(layer.Node, FieldLayerEngineVersion, strconv.Itoa(layer.EngineVersion), ""))
@ -162,16 +163,16 @@ func deleteLayerTreeFrom(node string, t *graph.Transaction) error {
} }
// Remove layer. // Remove layer.
t.RemoveQuad(cayley.Quad(layer.Node, FieldIs, FieldLayerIsValue, "")) t.RemoveQuad(cayley.Quad(layer.Node, fieldIs, fieldLayerIsValue, ""))
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerID, layer.ID, "")) t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerID, layer.ID, ""))
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerParent, layer.ParentNode, "")) t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerParent, layer.ParentNode, ""))
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerOS, layer.OS, "")) t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerOS, layer.OS, ""))
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerEngineVersion, strconv.Itoa(layer.EngineVersion), "")) t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerEngineVersion, strconv.Itoa(layer.EngineVersion), ""))
for _, pkg := range layer.InstalledPackagesNodes { for _, pkg := range layer.InstalledPackagesNodes {
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerInstalledPackages, pkg, "")) t.RemoveQuad(cayley.Quad(layer.Node, fieldLayerInstalledPackages, pkg, ""))
} }
for _, pkg := range layer.RemovedPackagesNodes { for _, pkg := range layer.RemovedPackagesNodes {
t.RemoveQuad(cayley.Quad(layer.Node, FieldLayerRemovedPackages, pkg, "")) t.RemoveQuad(cayley.Quad(layer.Node, fieldLayerRemovedPackages, pkg, ""))
} }
// Apply transaction if root call. // Apply transaction if root call.
@ -199,7 +200,7 @@ func FindOneLayerByID(ID string, selectedFields []string) (*Layer, error) {
// FindOneLayerByNode finds and returns a single package by its node, selecting the specified fields // FindOneLayerByNode finds and returns a single package by its node, selecting the specified fields
func FindOneLayerByNode(node string, selectedFields []string) (*Layer, error) { func FindOneLayerByNode(node string, selectedFields []string) (*Layer, error) {
l, err := toLayers(cayley.StartPath(store, node).Has(FieldIs, FieldLayerIsValue), selectedFields) l, err := toLayers(cayley.StartPath(store, node).Has(fieldIs, fieldLayerIsValue), selectedFields)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -217,7 +218,7 @@ func FindOneLayerByNode(node string, selectedFields []string) (*Layer, error) {
// FindAllLayersByAddedPackageNodes finds and returns all layers that add the // FindAllLayersByAddedPackageNodes finds and returns all layers that add the
// given packages (by their nodes), selecting the specified fields // given packages (by their nodes), selecting the specified fields
func FindAllLayersByAddedPackageNodes(nodes []string, selectedFields []string) ([]*Layer, error) { func FindAllLayersByAddedPackageNodes(nodes []string, selectedFields []string) ([]*Layer, error) {
layers, err := toLayers(cayley.StartPath(store, nodes...).In(FieldLayerInstalledPackages), selectedFields) layers, err := toLayers(cayley.StartPath(store, nodes...).In(fieldLayerInstalledPackages), selectedFields)
if err != nil { if err != nil {
return []*Layer{}, err return []*Layer{}, err
} }
@ -234,7 +235,7 @@ func FindAllLayersByAddedPackageNodes(nodes []string, selectedFields []string) (
// } // }
// //
// // Get all the layers which remove the package // // Get all the layers which remove the package
// layersNodesRemoving, err := toValues(cayley.StartPath(store, node).In(FieldLayerRemovedPackages).Has(FieldIs, FieldLayerIsValue)) // layersNodesRemoving, err := toValues(cayley.StartPath(store, node).In(fieldLayerRemovedPackages).Has(fieldIs, fieldLayerIsValue))
// if err != nil { // if err != nil {
// return []*Layer{}, err // return []*Layer{}, err
// } // }
@ -243,7 +244,7 @@ func FindAllLayersByAddedPackageNodes(nodes []string, selectedFields []string) (
// layersNodesRemovingMap[l] = struct{}{} // layersNodesRemovingMap[l] = struct{}{}
// } // }
// //
// layersToBrowse, err := toLayers(cayley.StartPath(store, node).In(FieldLayerInstalledPackages).Has(FieldIs, FieldLayerIsValue), only) // layersToBrowse, err := toLayers(cayley.StartPath(store, node).In(fieldLayerInstalledPackages).Has(fieldIs, fieldLayerIsValue), only)
// if err != nil { // if err != nil {
// return []*Layer{}, err // return []*Layer{}, err
// } // }
@ -270,7 +271,7 @@ func FindAllLayersByAddedPackageNodes(nodes []string, selectedFields []string) (
func toLayers(path *path.Path, selectedFields []string) ([]*Layer, error) { func toLayers(path *path.Path, selectedFields []string) ([]*Layer, error) {
var layers []*Layer var layers []*Layer
saveFields(path, selectedFields, []string{FieldLayerSuccessors, FieldLayerPackages, FieldLayerInstalledPackages, FieldLayerRemovedPackages}) saveFields(path, selectedFields, []string{FieldLayerSuccessors, FieldLayerPackages, fieldLayerInstalledPackages, fieldLayerRemovedPackages})
it, _ := path.BuildIterator().Optimize() it, _ := path.BuildIterator().Optimize()
defer it.Close() defer it.Close()
for cayley.RawNext(it) { for cayley.RawNext(it) {
@ -295,16 +296,16 @@ func toLayers(path *path.Path, selectedFields []string) ([]*Layer, error) {
layer.OS = store.NameOf(tags[FieldLayerOS]) layer.OS = store.NameOf(tags[FieldLayerOS])
case FieldLayerPackages: case FieldLayerPackages:
var err error var err error
it, _ := cayley.StartPath(store, layer.Node).OutWithTags([]string{"predicate"}, FieldLayerInstalledPackages, FieldLayerRemovedPackages).BuildIterator().Optimize() it, _ := cayley.StartPath(store, layer.Node).OutWithTags([]string{"predicate"}, fieldLayerInstalledPackages, fieldLayerRemovedPackages).BuildIterator().Optimize()
defer it.Close() defer it.Close()
for cayley.RawNext(it) { for cayley.RawNext(it) {
tags := make(map[string]graph.Value) tags := make(map[string]graph.Value)
it.TagResults(tags) it.TagResults(tags)
predicate := store.NameOf(tags["predicate"]) predicate := store.NameOf(tags["predicate"])
if predicate == FieldLayerInstalledPackages { if predicate == fieldLayerInstalledPackages {
layer.InstalledPackagesNodes = append(layer.InstalledPackagesNodes, store.NameOf(it.Result())) layer.InstalledPackagesNodes = append(layer.InstalledPackagesNodes, store.NameOf(it.Result()))
} else if predicate == FieldLayerRemovedPackages { } else if predicate == fieldLayerRemovedPackages {
layer.RemovedPackagesNodes = append(layer.RemovedPackagesNodes, store.NameOf(it.Result())) layer.RemovedPackagesNodes = append(layer.RemovedPackagesNodes, store.NameOf(it.Result()))
} }
} }

View File

@ -25,6 +25,13 @@ import (
"github.com/google/cayley/graph/path" "github.com/google/cayley/graph/path"
) )
const (
fieldLockLocked = "locked"
fieldLockLockedValue = "locked"
fieldLockLockedBy = "locked_by"
fieldLockLockedUntil = "locked_until"
)
// Lock tries to set a temporary lock in the database. // Lock tries to set a temporary lock in the database.
// If a lock already exists with the given name/owner, then the lock is renewed // If a lock already exists with the given name/owner, then the lock is renewed
// //
@ -37,7 +44,7 @@ func Lock(name string, duration time.Duration, owner string) (bool, time.Time) {
untilString := strconv.FormatInt(until.Unix(), 10) untilString := strconv.FormatInt(until.Unix(), 10)
// Try to get the expiration time of a lock with the same name/owner // Try to get the expiration time of a lock with the same name/owner
currentExpiration, err := toValue(cayley.StartPath(store, name).Has("locked_by", owner).Out("locked_until")) currentExpiration, err := toValue(cayley.StartPath(store, name).Has(fieldLockLockedBy, owner).Out(fieldLockLockedUntil))
if err == nil && currentExpiration != "" { if err == nil && currentExpiration != "" {
// Renew our lock // Renew our lock
if currentExpiration == untilString { if currentExpiration == untilString {
@ -45,17 +52,17 @@ func Lock(name string, duration time.Duration, owner string) (bool, time.Time) {
} }
t := cayley.NewTransaction() t := cayley.NewTransaction()
t.RemoveQuad(cayley.Quad(name, "locked_until", currentExpiration, "")) t.RemoveQuad(cayley.Quad(name, fieldLockLockedUntil, currentExpiration, ""))
t.AddQuad(cayley.Quad(name, "locked_until", untilString, "")) t.AddQuad(cayley.Quad(name, fieldLockLockedUntil, untilString, ""))
// It is not necessary to verify if the lock is ours again in the transaction // It is not necessary to verify if the lock is ours again in the transaction
// because if someone took it, the lock's current expiration probably changed and the transaction will fail // because if someone took it, the lock's current expiration probably changed and the transaction will fail
return store.ApplyTransaction(t) == nil, until return store.ApplyTransaction(t) == nil, until
} }
t := cayley.NewTransaction() t := cayley.NewTransaction()
t.AddQuad(cayley.Quad(name, "locked", "locked", "")) // Necessary to make the transaction fails if the lock already exists (and has not been pruned) t.AddQuad(cayley.Quad(name, fieldLockLocked, fieldLockLockedValue, "")) // Necessary to make the transaction fails if the lock already exists (and has not been pruned)
t.AddQuad(cayley.Quad(name, "locked_until", untilString, "")) t.AddQuad(cayley.Quad(name, fieldLockLockedUntil, untilString, ""))
t.AddQuad(cayley.Quad(name, "locked_by", owner, "")) t.AddQuad(cayley.Quad(name, fieldLockLockedBy, owner, ""))
glog.SetStderrThreshold("FATAL") glog.SetStderrThreshold("FATAL")
success := store.ApplyTransaction(t) == nil success := store.ApplyTransaction(t) == nil
@ -67,16 +74,16 @@ func Lock(name string, duration time.Duration, owner string) (bool, time.Time) {
// Unlock unlocks a lock specified by its name if I own it // Unlock unlocks a lock specified by its name if I own it
func Unlock(name, owner string) { func Unlock(name, owner string) {
unlocked := 0 unlocked := 0
it, _ := cayley.StartPath(store, name).Has("locked", "locked").Has("locked_by", owner).Save("locked_until", "locked_until").BuildIterator().Optimize() it, _ := cayley.StartPath(store, name).Has(fieldLockLocked, fieldLockLockedValue).Has(fieldLockLockedBy, owner).Save(fieldLockLockedUntil, fieldLockLockedUntil).BuildIterator().Optimize()
defer it.Close() defer it.Close()
for cayley.RawNext(it) { for cayley.RawNext(it) {
tags := make(map[string]graph.Value) tags := make(map[string]graph.Value)
it.TagResults(tags) it.TagResults(tags)
t := cayley.NewTransaction() t := cayley.NewTransaction()
t.RemoveQuad(cayley.Quad(name, "locked", "locked", "")) t.RemoveQuad(cayley.Quad(name, fieldLockLocked, fieldLockLockedValue, ""))
t.RemoveQuad(cayley.Quad(name, "locked_until", store.NameOf(tags["locked_until"]), "")) t.RemoveQuad(cayley.Quad(name, fieldLockLockedUntil, store.NameOf(tags[fieldLockLockedUntil]), ""))
t.RemoveQuad(cayley.Quad(name, "locked_by", owner, "")) t.RemoveQuad(cayley.Quad(name, fieldLockLockedBy, owner, ""))
err := store.ApplyTransaction(t) err := store.ApplyTransaction(t)
if err != nil { if err != nil {
log.Errorf("failed transaction (Unlock): %s", err) log.Errorf("failed transaction (Unlock): %s", err)
@ -97,14 +104,14 @@ func Unlock(name, owner string) {
// LockInfo returns the owner of a lock specified by its name and its // LockInfo returns the owner of a lock specified by its name and its
// expiration time // expiration time
func LockInfo(name string) (string, time.Time, error) { func LockInfo(name string) (string, time.Time, error) {
it, _ := cayley.StartPath(store, name).Has("locked", "locked").Save("locked_until", "locked_until").Save("locked_by", "locked_by").BuildIterator().Optimize() it, _ := cayley.StartPath(store, name).Has(fieldLockLocked, fieldLockLockedValue).Save(fieldLockLockedUntil, fieldLockLockedUntil).Save(fieldLockLockedBy, fieldLockLockedBy).BuildIterator().Optimize()
defer it.Close() defer it.Close()
for cayley.RawNext(it) { for cayley.RawNext(it) {
tags := make(map[string]graph.Value) tags := make(map[string]graph.Value)
it.TagResults(tags) it.TagResults(tags)
tt, _ := strconv.ParseInt(store.NameOf(tags["locked_until"]), 10, 64) tt, _ := strconv.ParseInt(store.NameOf(tags[fieldLockLockedUntil]), 10, 64)
return store.NameOf(tags["locked_by"]), time.Unix(tt, 0), nil return store.NameOf(tags[fieldLockLockedBy]), time.Unix(tt, 0), nil
} }
if it.Err() != nil { if it.Err() != nil {
log.Errorf("failed query in LockInfo: %s", it.Err()) log.Errorf("failed query in LockInfo: %s", it.Err())
@ -119,24 +126,24 @@ func pruneLocks() {
now := time.Now() now := time.Now()
// Delete every expired locks // Delete every expired locks
it, _ := cayley.StartPath(store, "locked").In("locked").Save("locked_until", "locked_until").Save("locked_by", "locked_by").BuildIterator().Optimize() it, _ := cayley.StartPath(store, "locked").In("locked").Save(fieldLockLockedUntil, fieldLockLockedUntil).Save(fieldLockLockedBy, fieldLockLockedBy).BuildIterator().Optimize()
defer it.Close() defer it.Close()
for cayley.RawNext(it) { for cayley.RawNext(it) {
tags := make(map[string]graph.Value) tags := make(map[string]graph.Value)
it.TagResults(tags) it.TagResults(tags)
n := store.NameOf(it.Result()) n := store.NameOf(it.Result())
t := store.NameOf(tags["locked_until"]) t := store.NameOf(tags[fieldLockLockedUntil])
o := store.NameOf(tags["locked_by"]) o := store.NameOf(tags[fieldLockLockedBy])
tt, _ := strconv.ParseInt(t, 10, 64) tt, _ := strconv.ParseInt(t, 10, 64)
if now.Unix() > tt { if now.Unix() > tt {
log.Debugf("lock %s owned by %s has expired.", n, o) log.Debugf("lock %s owned by %s has expired.", n, o)
tr := cayley.NewTransaction() tr := cayley.NewTransaction()
tr.RemoveQuad(cayley.Quad(n, "locked", "locked", "")) tr.RemoveQuad(cayley.Quad(n, fieldLockLocked, fieldLockLockedValue, ""))
tr.RemoveQuad(cayley.Quad(n, "locked_until", t, "")) tr.RemoveQuad(cayley.Quad(n, fieldLockLockedUntil, t, ""))
tr.RemoveQuad(cayley.Quad(n, "locked_by", o, "")) tr.RemoveQuad(cayley.Quad(n, fieldLockLockedBy, o, ""))
err := store.ApplyTransaction(tr) err := store.ApplyTransaction(tr)
if err != nil { if err != nil {
log.Errorf("failed transaction (pruneLocks): %s", err) log.Errorf("failed transaction (pruneLocks): %s", err)

View File

@ -26,9 +26,16 @@ import (
"github.com/pborman/uuid" "github.com/pborman/uuid"
) )
const (
// maxNotifications is the number of notifications that InsertNotifications // maxNotifications is the number of notifications that InsertNotifications
// will accept at the same time. Above this number, notifications are ignored. // will accept at the same time. Above this number, notifications are ignored.
const maxNotifications = 100 maxNotifications = 100
fieldNotificationIsValue = "notification"
fieldNotificationType = "type"
fieldNotificationData = "data"
fieldNotificationIsSent = "isSent"
)
// A Notification defines an interface to a message that can be sent by a // A Notification defines an interface to a message that can be sent by a
// notifier.Notifier. // notifier.Notifier.
@ -331,11 +338,11 @@ func InsertNotifications(notifications []Notification, wrapper NotificationWrapp
return err return err
} }
node := "notification:" + uuid.New() node := fieldNotificationIsValue + ":" + uuid.New()
t.AddQuad(cayley.Quad(node, FieldIs, "notification", "")) t.AddQuad(cayley.Quad(node, fieldIs, fieldNotificationIsValue, ""))
t.AddQuad(cayley.Quad(node, "type", wrappedNotification.Type, "")) t.AddQuad(cayley.Quad(node, fieldNotificationType, wrappedNotification.Type, ""))
t.AddQuad(cayley.Quad(node, "data", wrappedNotification.Data, "")) t.AddQuad(cayley.Quad(node, fieldNotificationData, wrappedNotification.Data, ""))
t.AddQuad(cayley.Quad(node, "isSent", strconv.FormatBool(false), "")) t.AddQuad(cayley.Quad(node, fieldNotificationIsSent, strconv.FormatBool(false), ""))
} }
// Apply transaction // Apply transaction
@ -350,13 +357,13 @@ func InsertNotifications(notifications []Notification, wrapper NotificationWrapp
// FindOneNotificationToSend finds and returns a notification that is not sent // FindOneNotificationToSend finds and returns a notification that is not sent
// yet and not locked. Returns nil if there is none. // yet and not locked. Returns nil if there is none.
func FindOneNotificationToSend(wrapper NotificationWrapper) (string, Notification, error) { func FindOneNotificationToSend(wrapper NotificationWrapper) (string, Notification, error) {
it, _ := cayley.StartPath(store, "notification").In(FieldIs).Has("isSent", strconv.FormatBool(false)).Except(getLockedNodes()).Save("type", "type").Save("data", "data").BuildIterator().Optimize() it, _ := cayley.StartPath(store, fieldNotificationIsValue).In(fieldIs).Has(fieldNotificationIsSent, strconv.FormatBool(false)).Except(getLockedNodes()).Save(fieldNotificationType, fieldNotificationType).Save(fieldNotificationData, fieldNotificationData).BuildIterator().Optimize()
defer it.Close() defer it.Close()
for cayley.RawNext(it) { for cayley.RawNext(it) {
tags := make(map[string]graph.Value) tags := make(map[string]graph.Value)
it.TagResults(tags) it.TagResults(tags)
notification, err := wrapper.Unwrap(&NotificationWrap{Type: store.NameOf(tags["type"]), Data: store.NameOf(tags["data"])}) notification, err := wrapper.Unwrap(&NotificationWrap{Type: store.NameOf(tags[fieldNotificationType]), Data: store.NameOf(tags[fieldNotificationData])})
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
@ -376,7 +383,7 @@ func FindOneNotificationToSend(wrapper NotificationWrapper) (string, Notificatio
func CountNotificationsToSend() (int, error) { func CountNotificationsToSend() (int, error) {
c := 0 c := 0
it, _ := cayley.StartPath(store, "notification").In(FieldIs).Has("isSent", strconv.FormatBool(false)).BuildIterator().Optimize() it, _ := cayley.StartPath(store, fieldNotificationIsValue).In(fieldIs).Has(fieldNotificationIsSent, strconv.FormatBool(false)).BuildIterator().Optimize()
defer it.Close() defer it.Close()
for cayley.RawNext(it) { for cayley.RawNext(it) {
c = c + 1 c = c + 1
@ -394,8 +401,8 @@ func MarkNotificationAsSent(node string) {
// Initialize transaction // Initialize transaction
t := cayley.NewTransaction() t := cayley.NewTransaction()
t.RemoveQuad(cayley.Quad(node, "isSent", strconv.FormatBool(false), "")) t.RemoveQuad(cayley.Quad(node, fieldNotificationIsSent, strconv.FormatBool(false), ""))
t.AddQuad(cayley.Quad(node, "isSent", strconv.FormatBool(true), "")) t.AddQuad(cayley.Quad(node, fieldNotificationIsSent, strconv.FormatBool(true), ""))
// Apply transaction // Apply transaction
store.ApplyTransaction(t) store.ApplyTransaction(t)

View File

@ -26,12 +26,14 @@ import (
) )
const ( const (
FieldPackageIsValue = "package"
FieldPackageOS = "os" FieldPackageOS = "os"
FieldPackageName = "name" FieldPackageName = "name"
FieldPackageVersion = "version" FieldPackageVersion = "version"
FieldPackageNextVersion = "nextVersion" FieldPackageNextVersion = "nextVersion"
FieldPackagePreviousVersion = "previousVersion" FieldPackagePreviousVersion = "previousVersion"
// This field is not selectable and is for internal use only.
fieldPackageIsValue = "package"
) )
var FieldPackageAll = []string{FieldPackageOS, FieldPackageName, FieldPackageVersion, FieldPackageNextVersion, FieldPackagePreviousVersion} var FieldPackageAll = []string{FieldPackageOS, FieldPackageName, FieldPackageVersion, FieldPackageNextVersion, FieldPackagePreviousVersion}
@ -49,7 +51,7 @@ type Package struct {
// GetNode returns an unique identifier for the graph node // GetNode returns an unique identifier for the graph node
// Requires the key fields: OS, Name, Version // Requires the key fields: OS, Name, Version
func (p *Package) GetNode() string { func (p *Package) GetNode() string {
return FieldPackageIsValue + ":" + utils.Hash(p.Key()) return fieldPackageIsValue + ":" + utils.Hash(p.Key())
} }
// Key returns an unique string defining p // Key returns an unique string defining p
@ -154,7 +156,7 @@ func InsertPackages(packageParameters []*Package) error {
} }
endPackage.Node = endPackage.GetNode() endPackage.Node = endPackage.GetNode()
t.AddQuad(cayley.Quad(endPackage.Node, FieldIs, FieldPackageIsValue, "")) t.AddQuad(cayley.Quad(endPackage.Node, fieldIs, fieldPackageIsValue, ""))
t.AddQuad(cayley.Quad(endPackage.Node, FieldPackageOS, endPackage.OS, "")) t.AddQuad(cayley.Quad(endPackage.Node, FieldPackageOS, endPackage.OS, ""))
t.AddQuad(cayley.Quad(endPackage.Node, FieldPackageName, endPackage.Name, "")) t.AddQuad(cayley.Quad(endPackage.Node, FieldPackageName, endPackage.Name, ""))
t.AddQuad(cayley.Quad(endPackage.Node, FieldPackageVersion, endPackage.Version.String(), "")) t.AddQuad(cayley.Quad(endPackage.Node, FieldPackageVersion, endPackage.Version.String(), ""))
@ -170,7 +172,7 @@ func InsertPackages(packageParameters []*Package) error {
} }
newPackage.Node = newPackage.GetNode() newPackage.Node = newPackage.GetNode()
t.AddQuad(cayley.Quad(newPackage.Node, FieldIs, FieldPackageIsValue, "")) t.AddQuad(cayley.Quad(newPackage.Node, fieldIs, fieldPackageIsValue, ""))
t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageOS, newPackage.OS, "")) t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageOS, newPackage.OS, ""))
t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageName, newPackage.Name, "")) t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageName, newPackage.Name, ""))
t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageVersion, newPackage.Version.String(), "")) t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageVersion, newPackage.Version.String(), ""))
@ -187,7 +189,7 @@ func InsertPackages(packageParameters []*Package) error {
} }
startPackage.Node = startPackage.GetNode() startPackage.Node = startPackage.GetNode()
t.AddQuad(cayley.Quad(startPackage.Node, FieldIs, FieldPackageIsValue, "")) t.AddQuad(cayley.Quad(startPackage.Node, fieldIs, fieldPackageIsValue, ""))
t.AddQuad(cayley.Quad(startPackage.Node, FieldPackageOS, startPackage.OS, "")) t.AddQuad(cayley.Quad(startPackage.Node, FieldPackageOS, startPackage.OS, ""))
t.AddQuad(cayley.Quad(startPackage.Node, FieldPackageName, startPackage.Name, "")) t.AddQuad(cayley.Quad(startPackage.Node, FieldPackageName, startPackage.Name, ""))
t.AddQuad(cayley.Quad(startPackage.Node, FieldPackageVersion, startPackage.Version.String(), "")) t.AddQuad(cayley.Quad(startPackage.Node, FieldPackageVersion, startPackage.Version.String(), ""))
@ -211,7 +213,7 @@ func InsertPackages(packageParameters []*Package) error {
newPackage.Node = "package:" + utils.Hash(newPackage.Key()) newPackage.Node = "package:" + utils.Hash(newPackage.Key())
packageParameter.Node = newPackage.Node packageParameter.Node = newPackage.Node
t.AddQuad(cayley.Quad(newPackage.Node, FieldIs, FieldPackageIsValue, "")) t.AddQuad(cayley.Quad(newPackage.Node, fieldIs, fieldPackageIsValue, ""))
t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageOS, newPackage.OS, "")) t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageOS, newPackage.OS, ""))
t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageName, newPackage.Name, "")) t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageName, newPackage.Name, ""))
t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageVersion, newPackage.Version.String(), "")) t.AddQuad(cayley.Quad(newPackage.Node, FieldPackageVersion, newPackage.Version.String(), ""))
@ -265,7 +267,7 @@ func InsertPackages(packageParameters []*Package) error {
// FindOnePackage finds and returns a single package having the given OS, name and version, selecting the specified fields // FindOnePackage finds and returns a single package having the given OS, name and version, selecting the specified fields
func FindOnePackage(OS, name string, version types.Version, selectedFields []string) (*Package, error) { func FindOnePackage(OS, name string, version types.Version, selectedFields []string) (*Package, error) {
packageParameter := Package{OS: OS, Name: name, Version: version} packageParameter := Package{OS: OS, Name: name, Version: version}
p, err := toPackages(cayley.StartPath(store, packageParameter.GetNode()).Has(FieldIs, FieldPackageIsValue), selectedFields) p, err := toPackages(cayley.StartPath(store, packageParameter.GetNode()).Has(fieldIs, fieldPackageIsValue), selectedFields)
if err != nil { if err != nil {
return nil, err return nil, err
@ -286,7 +288,7 @@ func FindAllPackagesByNodes(nodes []string, selectedFields []string) ([]*Package
return []*Package{}, nil return []*Package{}, nil
} }
return toPackages(cayley.StartPath(store, nodes...).Has(FieldIs, FieldPackageIsValue), selectedFields) return toPackages(cayley.StartPath(store, nodes...).Has(fieldIs, fieldPackageIsValue), selectedFields)
} }
// FindAllPackagesByBranch finds and returns all packages that belong to the given Branch, selecting the specified fields // FindAllPackagesByBranch finds and returns all packages that belong to the given Branch, selecting the specified fields

View File

@ -24,7 +24,6 @@ import (
) )
const ( const (
FieldVulnerabilityIsValue = "vulnerability"
FieldVulnerabilityID = "id" FieldVulnerabilityID = "id"
FieldVulnerabilityLink = "link" FieldVulnerabilityLink = "link"
FieldVulnerabilityPriority = "priority" FieldVulnerabilityPriority = "priority"
@ -32,6 +31,9 @@ const (
FieldVulnerabilityFixedIn = "fixedIn" FieldVulnerabilityFixedIn = "fixedIn"
// FieldVulnerabilityCausedByPackage only makes sense with FindAllVulnerabilitiesByFixedIn. // FieldVulnerabilityCausedByPackage only makes sense with FindAllVulnerabilitiesByFixedIn.
FieldVulnerabilityCausedByPackage = "causedByPackage" FieldVulnerabilityCausedByPackage = "causedByPackage"
// This field is not selectable and is for internal use only.
fieldVulnerabilityIsValue = "vulnerability"
) )
var FieldVulnerabilityAll = []string{FieldVulnerabilityID, FieldVulnerabilityLink, FieldVulnerabilityPriority, FieldVulnerabilityDescription, FieldVulnerabilityFixedIn} var FieldVulnerabilityAll = []string{FieldVulnerabilityID, FieldVulnerabilityLink, FieldVulnerabilityPriority, FieldVulnerabilityDescription, FieldVulnerabilityFixedIn}
@ -51,7 +53,7 @@ type Vulnerability struct {
// GetNode returns an unique identifier for the graph node // GetNode returns an unique identifier for the graph node
// Requires the key field: ID // Requires the key field: ID
func (v *Vulnerability) GetNode() string { func (v *Vulnerability) GetNode() string {
return FieldVulnerabilityIsValue + ":" + utils.Hash(v.ID) return fieldVulnerabilityIsValue + ":" + utils.Hash(v.ID)
} }
// ToAbstractVulnerability converts a Vulnerability into an // ToAbstractVulnerability converts a Vulnerability into an
@ -150,7 +152,7 @@ func InsertVulnerabilities(vulnerabilities []*Vulnerability) ([]Notification, er
// Insert it // Insert it
vulnerability.Node = vulnerability.GetNode() vulnerability.Node = vulnerability.GetNode()
t.AddQuad(cayley.Quad(vulnerability.Node, FieldIs, FieldVulnerabilityIsValue, "")) t.AddQuad(cayley.Quad(vulnerability.Node, fieldIs, fieldVulnerabilityIsValue, ""))
t.AddQuad(cayley.Quad(vulnerability.Node, FieldVulnerabilityID, vulnerability.ID, "")) t.AddQuad(cayley.Quad(vulnerability.Node, FieldVulnerabilityID, vulnerability.ID, ""))
t.AddQuad(cayley.Quad(vulnerability.Node, FieldVulnerabilityLink, vulnerability.Link, "")) t.AddQuad(cayley.Quad(vulnerability.Node, FieldVulnerabilityLink, vulnerability.Link, ""))
t.AddQuad(cayley.Quad(vulnerability.Node, FieldVulnerabilityPriority, string(vulnerability.Priority), "")) t.AddQuad(cayley.Quad(vulnerability.Node, FieldVulnerabilityPriority, string(vulnerability.Priority), ""))
@ -297,7 +299,7 @@ func DeleteVulnerability(id string) error {
// FindOneVulnerability finds and returns a single vulnerability having the given ID selecting the specified fields // FindOneVulnerability finds and returns a single vulnerability having the given ID selecting the specified fields
func FindOneVulnerability(id string, selectedFields []string) (*Vulnerability, error) { func FindOneVulnerability(id string, selectedFields []string) (*Vulnerability, error) {
t := &Vulnerability{ID: id} t := &Vulnerability{ID: id}
v, err := toVulnerabilities(cayley.StartPath(store, t.GetNode()).Has(FieldIs, FieldVulnerabilityIsValue), selectedFields) v, err := toVulnerabilities(cayley.StartPath(store, t.GetNode()).Has(fieldIs, fieldVulnerabilityIsValue), selectedFields)
if err != nil { if err != nil {
return nil, err return nil, err