// toLayers converts a path leading to one or multiple layers to Layer structs, // selecting the specified fields func toLayers(path *path.Path, selectedFields []string) ([]*Layer, error) { var layers []*Layer saveFields(path, selectedFields, []string{FieldLayerSuccessors, FieldLayerPackages, FieldLayerInstalledPackages, FieldLayerRemovedPackages}) it, _ := path.BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) layer := Layer{Node: store.NameOf(it.Result())} for _, selectedField := range selectedFields { switch selectedField { case FieldLayerID: layer.ID = store.NameOf(tags[FieldLayerID]) case FieldLayerParent: layer.ParentNode = store.NameOf(tags[FieldLayerParent]) case FieldLayerSuccessors: var err error layer.SuccessorsNodes, err = toValues(cayley.StartPath(store, layer.Node).In(FieldLayerParent)) if err != nil { log.Errorf("could not get successors of layer %s: %s.", layer.Node, err.Error()) return nil, err } case FieldLayerOS: layer.OS = store.NameOf(tags[FieldLayerOS]) case FieldLayerPackages: var err error it, _ := cayley.StartPath(store, layer.Node).OutWithTags([]string{"predicate"}, FieldLayerInstalledPackages, FieldLayerRemovedPackages).BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) predicate := store.NameOf(tags["predicate"]) if predicate == FieldLayerInstalledPackages { layer.InstalledPackagesNodes = append(layer.InstalledPackagesNodes, store.NameOf(it.Result())) } else if predicate == FieldLayerRemovedPackages { layer.RemovedPackagesNodes = append(layer.RemovedPackagesNodes, store.NameOf(it.Result())) } } if it.Err() != nil { log.Errorf("could not get installed/removed packages of layer %s: %s.", layer.Node, it.Err()) return nil, err } case FieldLayerEngineVersion: layer.EngineVersion, _ = strconv.Atoi(store.NameOf(tags[FieldLayerEngineVersion])) default: panic("unknown selectedField") } } layers = append(layers, &layer) } if it.Err() != nil { log.Errorf("failed query in toLayers: %s", it.Err()) return []*Layer{}, ErrBackendException } return layers, nil }
func (suite *GraphTestSuite) TestSave(t *C) { mTime := time.Now() ni := graph.NodeInfo{ Name: "child", ParentId: graph.RootNodeId, Mode: os.FileMode(0755), MTime: mTime, Type: "application/json", } node, err := suite.ng.NewNodeWithNodeInfo(ni) t.Check(err, IsNil) assertProperty := func(expected string, actual cayley.Iterator) { t.Check(cayley.RawNext(actual), Equals, true) t.Check(suite.ng.NameOf(actual.Result()), Equals, expected) } it := cayley.StartPath(suite.ng, node.Id).Out("isNamed").BuildIterator() assertProperty("child", it) it = cayley.StartPath(suite.ng, node.Id).Out("hasMTime").BuildIterator() assertProperty(mTime.Format(time.RFC3339Nano), it) it = cayley.StartPath(suite.ng, node.Id).Out("hasMode").BuildIterator() assertProperty(fmt.Sprint(0755), it) it = cayley.StartPath(suite.ng, node.Id).Out("hasType").BuildIterator() assertProperty("application/json", it) }
func (s *localSignallingLayer) AddServiceHost(service string, version string, uri string) (common.ServiceHost, error) { var h, err = s.base.AddServiceHost(service, version, uri) if err == nil { var svcDef, finderr = s.base.GetServiceDefinition(service) if finderr == nil { // find all affected api versions var startingNodeID = utils.CreateServiceVersionKey(service, version) var path = cayley.StartPath(s.graph, startingNodeID).Out(utils.InApiRel) it := path.BuildIterator() for cayley.RawNext(it) { var apiNodeID = s.graph.NameOf(it.Result()) var apiVersion = strings.TrimPrefix(apiNodeID, utils.CreateAPIVersionKey("")) var event = common.Event{} event.ActionCode = "ADD_ServiceHost" event.Data = map[string]string{ "version": apiVersion, "prefix": svcDef.Prefix, "uri": uri} s.signalOutput <- event } } } return h, err }
// pruneLocks removes every expired locks from the database func pruneLocks() { now := time.Now() // Delete every expired locks tr := cayley.NewTransaction() it, _ := cayley.StartPath(store, "locked").In("locked").Save("locked_until", "locked_until").Save("locked_by", "locked_by").BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) n := store.NameOf(it.Result()) t := store.NameOf(tags["locked_until"]) o := store.NameOf(tags["locked_by"]) tt, _ := strconv.ParseInt(t, 10, 64) if now.Unix() > tt { log.Debugf("Lock %s owned by %s has expired.", n, o) tr.RemoveQuad(cayley.Quad(n, "locked", "locked", "")) tr.RemoveQuad(cayley.Quad(n, "locked_until", t, "")) tr.RemoveQuad(cayley.Quad(n, "locked_by", o, "")) } } store.ApplyTransaction(tr) }
// Unlock unlocks a lock specified by its name if I own it func Unlock(name, owner string) { unlocked := 0 it, _ := cayley.StartPath(store, name).Has(fieldLockLocked, fieldLockLockedValue).Has(fieldLockLockedBy, owner).Save(fieldLockLockedUntil, fieldLockLockedUntil).BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) t := cayley.NewTransaction() t.RemoveQuad(cayley.Triple(name, fieldLockLocked, fieldLockLockedValue)) t.RemoveQuad(cayley.Triple(name, fieldLockLockedUntil, store.NameOf(tags[fieldLockLockedUntil]))) t.RemoveQuad(cayley.Triple(name, fieldLockLockedBy, owner)) err := store.ApplyTransaction(t) if err != nil { log.Errorf("failed transaction (Unlock): %s", err) } unlocked++ } if it.Err() != nil { log.Errorf("failed query in Unlock: %s", it.Err()) } if unlocked > 1 { // We should never see this, it would mean that our database doesn't ensure quad uniqueness // and that the entire lock system is jeopardized. log.Errorf("found inconsistency in Unlock: matched %d times a locked named: %s", unlocked, name) } }
/* * Searches for articles in the database * @param tags string[] The tags entered by the user.Currently only entity search has been implemented. Algorithm in Readme */ func SearchForArticles(tags []string, store *cayley.Handle) PairList { links := make(map[string]int) for _, tag := range tags { entities := extractArticleData.GetEntityInfo(tag, "") if len(entities) == 0 { continue } entitityInfo := entities[0] // Get the First Entity //TODO:- Change to Best Label Match for _, category := range entitityInfo.Categories { path := cayley.StartPath(store, category). In("has_category"). In("has_entity") it := path.BuildIterator() it, _ = it.Optimize() for cayley.RawNext(it) { link := store.NameOf(it.Result()) links[link] += 10 } } } return sortMapByValue(links) }
// pruneLocks removes every expired locks from the database func pruneLocks() { now := time.Now() // Delete every expired locks it, _ := cayley.StartPath(store, "locked").In("locked").Save(fieldLockLockedUntil, fieldLockLockedUntil).Save(fieldLockLockedBy, fieldLockLockedBy).BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) n := store.NameOf(it.Result()) t := store.NameOf(tags[fieldLockLockedUntil]) o := store.NameOf(tags[fieldLockLockedBy]) tt, _ := strconv.ParseInt(t, 10, 64) if now.Unix() > tt { log.Debugf("lock %s owned by %s has expired.", n, o) tr := cayley.NewTransaction() tr.RemoveQuad(cayley.Triple(n, fieldLockLocked, fieldLockLockedValue)) tr.RemoveQuad(cayley.Triple(n, fieldLockLockedUntil, t)) tr.RemoveQuad(cayley.Triple(n, fieldLockLockedBy, o)) err := store.ApplyTransaction(tr) if err != nil { log.Errorf("failed transaction (pruneLocks): %s", err) continue } log.Debugf("lock %s has been successfully pruned.", n) } } if it.Err() != nil { log.Errorf("failed query in Unlock: %s", it.Err()) } }
func (s *SocketServer) NotifyStop(t int64) { stopAt := strconv.FormatInt(t, 10) p := cayley.StartPath(s.storage, stopAt).In("free at") it := p.BuildIterator() for cayley.RawNext(it) { s.BroadcastTo(RoomName, "stop", s.storage.NameOf(it.Result())) } }
func (nd *Node) graphValue(key string) (value string) { it := cayley.StartPath(nd.graph, nd.Id).Out(key).BuildIterator() if cayley.RawNext(it) { value = nd.graph.NameOf(it.Result()) } return }
func (s *SocketServer) NotifyEnable(t int64) { stopedAt := strconv.FormatInt(t-models.Wait5Minutes, 10) p := cayley.StartPath(s.storage, stopedAt).In("free at") it := p.BuildIterator() for cayley.RawNext(it) { //TODO send to only one user s.BroadcastTo(RoomName, "enable", s.storage.NameOf(it.Result())) } }
func (a *ACL) GetProfilePerm(sourceprofileid, targetprofile string) []string { p := cayley.StartPath(a.profilestore, sourceprofileid).Out(targetprofile) it := p.BuildIterator() r := []string{} for cayley.RawNext(it) { r = append(r, a.profilestore.NameOf(it.Result())) } return r }
func (ng *NodeGraph) NodeWithName(parentId, name string) *Node { namePath := cayley.StartPath(ng, name).In(nameLink) parentpath := cayley.StartPath(ng, parentId).In(parentLink) it := namePath.And(parentpath).BuildIterator() if cayley.RawNext(it) { return ng.NodeWithId(ng.NameOf(it.Result())) } return nil }
func (nd *Node) BlockWithOffset(offset int64) string { if nd.IsDir() { return "" } it := cayley.StartPath(nd.graph, nd.Id).Out(fmt.Sprint("offset-", offset)).BuildIterator() if cayley.RawNext(it) { return nd.graph.NameOf(it.Result()) } else { return "" } }
func (s *Storage) GetUsersFreeAt(t int64) []*User { freeAt := strconv.FormatInt(t, 10) users := []*User{} p := cayley.StartPath(s, freeAt).In("free at") it := p.BuildIterator() for cayley.RawNext(it) { users = append(users, NewUser(s.NameOf(it.Result()))) } return users }
func (s *Storage) SaveUser(u *User) { s.AddQuad(cayley.Quad(u.Name, "is", "user", "")) p := cayley.StartPath(u.getStorage(), u.Name).Out("free at") iterationTime := u.IterationTime() it := p.BuildIterator() for cayley.RawNext(it) { s.RemoveQuad(cayley.Quad(u.Name, "free at", s.NameOf(it.Result()), "")) } s.AddQuad(cayley.Quad(u.Name, "free at", strconv.FormatInt(iterationTime, 10), "")) }
func (suite *GraphTestSuite) TestWriteData_removesExistingFingerprintForOffset(t *C) { child, _ := makeNode("child", suite.ng.RootNode.Id, time.Now(), suite.ng) dat := testutils.RandDat(1024) t.Check(child.WriteData(dat, 0), IsNil) dat = testutils.RandDat(1024) fingerprint := graph.Hash(dat) t.Check(child.WriteData(dat, 0), IsNil) it := cayley.StartPath(suite.ng, child.Id).Out("offset-0").BuildIterator() t.Check(cayley.RawNext(it), Equals, true) t.Check(suite.ng.NameOf(it.Result()), Equals, fingerprint) }
func (u *User) IterationTime() int64 { if u.iterationTime == 0 { p := cayley.StartPath(u.getStorage(), u.Name).Out("free at") it := p.BuildIterator() if cayley.RawNext(it) { u.iterationTime, _ = strconv.ParseInt(u.getStorage().NameOf(it.Result()), 10, 64) } else { u.iterationTime = time.Now().Unix() - Wait5Minutes } } return u.iterationTime }
// CountNotificationsToSend returns the number of pending notifications // Note that it also count the locked notifications. func CountNotificationsToSend() (int, error) { c := 0 it, _ := cayley.StartPath(store, "notification").In(FieldIs).Has("isSent", strconv.FormatBool(false)).BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { c = c + 1 } if it.Err() != nil { log.Errorf("failed query in CountNotificationsToSend: %s", it.Err()) return 0, ErrBackendException } return c, nil }
func (p *mgoPersistenceProvider) loadVersionsByAPI(apiVersion string, graph *cayley.Handle, session *mgo.Session, target common.IServiceRegistry) error { var startingNodeID = utils.CreateAPIVersionKey(apiVersion) var path = cayley.StartPath(graph, startingNodeID).Out(utils.ContainsVersionRel) it := path.BuildIterator() for cayley.RawNext(it) { var version serviceVersion err := session.DB("test").C("serviceVersions").Find(bson.M{"_id": graph.NameOf(it.Result())}).One(&version) if err != nil { return err } target.LinkServiceToAPI(version.Service, version.Version, apiVersion) } return nil }
func (p *mgoPersistenceProvider) loadVersionsByService(serviceIdentifier string, graph *cayley.Handle, session *mgo.Session, target common.IServiceRegistry) error { var startingNodeID = utils.CreateServiceDefinitionKey(serviceIdentifier) var path = cayley.StartPath(graph, startingNodeID).Out(utils.ContainsVersionRel) it := path.BuildIterator() for cayley.RawNext(it) { var version serviceVersion var serviceVersionNode = graph.NameOf(it.Result()) err := session.DB("test").C("serviceVersions").Find(bson.M{"_id": serviceVersionNode}).One(&version) if err != nil { return fmt.Errorf("Cannot find %s in collection 'serviceVersions': %s", serviceVersionNode, err.Error()) } target.AddServiceVersion(serviceIdentifier, version.Version) } return nil }
// LockInfo returns the owner of a lock specified by its name and its // expiration time 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() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) tt, _ := strconv.ParseInt(store.NameOf(tags["locked_until"]), 10, 64) return store.NameOf(tags["locked_by"]), time.Unix(tt, 0), nil } if it.Err() != nil { log.Errorf("failed query in LockInfo: %s", it.Err()) return "", time.Time{}, ErrBackendException } return "", time.Time{}, cerrors.ErrNotFound }
// toValues returns multiple values from a path // If the path does not lead to any value, an empty array is returned // If a database error occurs, an empty array and an error are returned func toValues(p *path.Path) ([]string, error) { var values []string it, _ := p.BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { if it.Result() != nil { values = append(values, store.NameOf(it.Result())) } } if it.Err() != nil { log.Errorf("failed query in toValues: %s", it.Err()) return []string{}, ErrBackendException } return values, nil }
func (nd *Node) Children() []*Node { if !nd.IsDir() { return make([]*Node, 0) } it := cayley.StartPath(nd.graph, nd.Id).In(parentLink).BuildIterator() children := make([]*Node, 0, 10) for cayley.RawNext(it) { child := nd.graph.NodeWithId(nd.graph.NameOf(it.Result())) child.parentId = nd.Id children = append(children, child) } Sort(children, Alphabetical) return children }
// Unlock unlocks a lock specified by its name if I own it func Unlock(name, owner string) { pruneLocks() t := cayley.NewTransaction() it, _ := cayley.StartPath(store, name).Has("locked", "locked").Has("locked_by", owner).Save("locked_until", "locked_until").BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) t.RemoveQuad(cayley.Quad(name, "locked", "locked", "")) t.RemoveQuad(cayley.Quad(name, "locked_until", store.NameOf(tags["locked_until"]), "")) t.RemoveQuad(cayley.Quad(name, "locked_by", owner, "")) } store.ApplyTransaction(t) }
// toPackages converts a path leading to one or multiple packages to Package structs, selecting the specified fields func toPackages(path *path.Path, selectedFields []string) ([]*Package, error) { var packages []*Package var err error saveFields(path, selectedFields, []string{FieldPackagePreviousVersion}) it, _ := path.BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) pkg := Package{Node: store.NameOf(it.Result())} for _, selectedField := range selectedFields { switch selectedField { case FieldPackageOS: pkg.OS = store.NameOf(tags[FieldPackageOS]) case FieldPackageName: pkg.Name = store.NameOf(tags[FieldPackageName]) case FieldPackageVersion: pkg.Version, err = types.NewVersion(store.NameOf(tags[FieldPackageVersion])) if err != nil { log.Warningf("could not parse version of package %s: %s", pkg.Node, err.Error()) } case FieldPackageNextVersion: pkg.NextVersionNode = store.NameOf(tags[FieldPackageNextVersion]) case FieldPackagePreviousVersion: pkg.PreviousVersionNode, err = toValue(cayley.StartPath(store, pkg.Node).In(FieldPackageNextVersion)) if err != nil { log.Warningf("could not get previousVersion on package %s: %s.", pkg.Node, err.Error()) return []*Package{}, ErrInconsistent } default: panic("unknown selectedField") } } packages = append(packages, &pkg) } if it.Err() != nil { log.Errorf("failed query in toPackages: %s", it.Err()) return []*Package{}, ErrBackendException } return packages, nil }
// toVulnerabilities converts a path leading to one or multiple vulnerabilities to Vulnerability structs, selecting the specified fields func toVulnerabilities(path *path.Path, selectedFields []string) ([]*Vulnerability, error) { var vulnerabilities []*Vulnerability saveFields(path, selectedFields, []string{FieldVulnerabilityFixedIn, FieldVulnerabilityCausedByPackage}) it, _ := path.BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) vulnerability := Vulnerability{Node: store.NameOf(it.Result())} for _, selectedField := range selectedFields { switch selectedField { case FieldVulnerabilityID: vulnerability.ID = store.NameOf(tags[FieldVulnerabilityID]) case FieldVulnerabilityLink: vulnerability.Link = store.NameOf(tags[FieldVulnerabilityLink]) case FieldVulnerabilityPriority: vulnerability.Priority = types.Priority(store.NameOf(tags[FieldVulnerabilityPriority])) case FieldVulnerabilityDescription: vulnerability.Description = store.NameOf(tags[FieldVulnerabilityDescription]) case FieldVulnerabilityFixedIn: var err error vulnerability.FixedInNodes, err = toValues(cayley.StartPath(store, vulnerability.Node).Out(FieldVulnerabilityFixedIn)) if err != nil { log.Errorf("could not get fixedIn on vulnerability %s: %s.", vulnerability.Node, err.Error()) return []*Vulnerability{}, err } case FieldVulnerabilityCausedByPackage: vulnerability.CausedByPackage = store.NameOf(tags[FieldVulnerabilityCausedByPackage]) default: panic("unknown selectedField") } } vulnerabilities = append(vulnerabilities, &vulnerability) } if it.Err() != nil { log.Errorf("failed query in toVulnerabilities: %s", it.Err()) return []*Vulnerability{}, ErrBackendException } return vulnerabilities, nil }
func open() { path := "./db" // Initialize the database graph.InitQuadStore("bolt", path, nil) // Open and use the database store, err := cayley.NewGraph("bolt", path, nil) if err != nil { log.Fatalln(err) } p := cayley.StartPath(store, "").Out("type").Is("Person") it := p.BuildIterator() for cayley.RawNext(it) { log.Println(store.NameOf(it.Result())) } }
// FindOneNotificationToSend finds and returns a notification that is not sent // yet and not locked. Returns nil if there is none. 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() defer it.Close() for cayley.RawNext(it) { tags := make(map[string]graph.Value) it.TagResults(tags) notification, err := wrapper.Unwrap(&NotificationWrap{Type: store.NameOf(tags["type"]), Data: store.NameOf(tags["data"])}) if err != nil { return "", nil, err } return store.NameOf(it.Result()), notification, nil } if it.Err() != nil { log.Errorf("failed query in FindOneNotificationToSend: %s", it.Err()) return "", nil, ErrBackendException } return "", nil, nil }
func (s *Storage) GetUsers(exclude ...*User) []*User { users := []*User{} p := cayley.StartPath(s, "user").In("is") it := p.BuildIterator() for cayley.RawNext(it) { name := s.NameOf(it.Result()) excluded := false if len(exclude) > 0 { for _, u := range exclude { if name == u.Name { excluded = true break } } } if !excluded { users = append(users, NewUser(name)) } } return users }
// toValue returns a single value from a path // If the path does not lead to a value, an empty string is returned // If the path leads to multiple values or if a database error occurs, an empty string and an error are returned func toValue(p *path.Path) (string, error) { var value string it, _ := p.BuildIterator().Optimize() defer it.Close() for cayley.RawNext(it) { if value != "" { log.Error("failed query in toValue: used on an iterator containing multiple values") return "", ErrInconsistent } if it.Result() != nil { value = store.NameOf(it.Result()) } } if it.Err() != nil { log.Errorf("failed query in toValue: %s", it.Err()) return "", ErrBackendException } return value, nil }