def test_modify_rel(self):
     """
     Test L{QueryEvaluator.modify_rel} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label' : 'Person', 'Name' : 'Alice'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Bob'}
     attrs3 = {'Label' : 'Person', 'Name' : 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     edge_attrs1 = {'rel_type' : 'friend'}
     edge_attrs2 = {'rel_type' : 'friend', 'fam' : 'cousin'}
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     # Tests adding attributes to relationship
     q.modify_rel(edge_attrs2, {'like' : 'no'}, True)
     match_lst1 = q.match_rel(edge_attrs2)
     result1 = [(node2[0], node3[0], {'rel_type' : 'friend', 
                                         'fam' : 'cousin',
                                         'like' : 'no'})]
     self.assertEqual(sorted(match_lst1), sorted(result1))
     # Tests deleting attributes to relationship
     q.modify_rel(edge_attrs2, {'like' : 'no'}, False)
     match_lst2 = q.match_rel(edge_attrs2)
     result2 = [(node2[0], node3[0], edge_attrs2)]
     self.assertEqual(sorted(match_lst2), sorted(result2))
Example #2
0
    def test_match_node_rel(self):
        """
        Tests L{QueryEvaluator.match_node_rel} method for L{QueryEvaluator}.
        """
        gs = GraphStructure()
        q = QueryEvaluator(gs)
        attrs1 = {'Label': 'Person', 'Name': 'Alice'}
        attrs2 = {'Label': 'Person', 'Name': 'Bob'}
        attrs3 = {'Label': 'Person', 'Name': 'John'}
        node1 = q.add_node(attrs1)
        node2 = q.add_node(attrs2)
        node3 = q.add_node(attrs3)
        edge_attrs1 = {'rel_type': 'friend'}
        edge_attrs2 = {'rel_type': 'friend', 'fam': 'cousin'}
        edge1 = q.add_relationship(node1, node2, edge_attrs1)
        edge2 = q.add_relationship(node2, node3, edge_attrs2)
        edge3 = q.add_relationship(node2, node1, edge_attrs1)
        # Test matching with no results
        match_lst1 = q.match_node_rel(node1[1], edge_attrs2)
        result1 = []
        self.assertEqual(match_lst1, result1)
        # Test matching with single result
        match_lst2 = q.match_node_rel(node2[1], edge_attrs2)
        result2 = [(node2[0], node3[0], edge_attrs2)]
        self.assertEqual(match_lst2, result2)
        # Test matching with multiple result
        match_lst3 = q.match_node_rel(node2[1], {'rel_type': 'friend'})
        result3 = [(node2[0], node1[0], edge_attrs1),
                   (node2[0], node3[0], edge_attrs2)]

        self.assertEqual(match_lst3, result3)
 def test_delete_rel(self):
     """
     Tests L{QueryEvaluator.delete_rel} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label' : 'Person', 'Name' : 'Alice'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Bob'}
     attrs3 = {'Label' : 'Person', 'Name' : 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     edge_attrs1 = {'rel_type' : 'friend'}
     edge_attrs2 = {'rel_type' : 'friend', 'fam' : 'cousin'}
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     # Tests deleting no relationship
     q.delete_rel({'rel_type' : 'friend', 'fam' : 'dad'})
     match_lst1 = q.match({}, {}, {})
     result1 = [(node1[0], node2[0], edge_attrs1),
                 (node2[0], node3[0], edge_attrs2)]
     self.assertEqual(match_lst1, result1)
     # Tests deleting relationship
     q.delete_rel(edge_attrs1)
     match_lst2 = q.match({}, {}, {})
     result2 = []
     self.assertEqual(match_lst2, result2)
Example #4
0
 def test_modify_node(self):
     """
     Tests L{QueryEvaluator.modify_node} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label': 'Person', 'Name': 'Alice'}
     attrs2 = {'Label': 'Person', 'Name': 'Bob'}
     attrs3 = {'Label': 'Person', 'Name': 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     edge_attrs1 = {'rel_type': 'friend'}
     edge_attrs2 = {'rel_type': 'friend', 'fam': 'cousin'}
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     # Tests adding attributes to node
     q.modify_node(attrs1, {'Age': '10'}, True)
     match_lst1 = q.match_node(attrs1)
     result1 = [(node1[0], {
         'Label': 'Person',
         'Name': 'Alice',
         'Age': '10'
     })]
     self.assertEqual(match_lst1, result1)
     # Tests removing attributes to node
     q.modify_node(attrs1, {'Age': '10'}, False)
     match_lst2 = q.match_node(attrs1)
     result2 = [(node1[0], attrs1)]
     self.assertEqual(match_lst2, result2)
Example #5
0
 def test_modify_rel(self):
     """
     Test L{QueryEvaluator.modify_rel} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label': 'Person', 'Name': 'Alice'}
     attrs2 = {'Label': 'Person', 'Name': 'Bob'}
     attrs3 = {'Label': 'Person', 'Name': 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     edge_attrs1 = {'rel_type': 'friend'}
     edge_attrs2 = {'rel_type': 'friend', 'fam': 'cousin'}
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     # Tests adding attributes to relationship
     q.modify_rel(edge_attrs2, {'like': 'no'}, True)
     match_lst1 = q.match_rel(edge_attrs2)
     result1 = [(node2[0], node3[0], {
         'rel_type': 'friend',
         'fam': 'cousin',
         'like': 'no'
     })]
     self.assertEqual(sorted(match_lst1), sorted(result1))
     # Tests deleting attributes to relationship
     q.modify_rel(edge_attrs2, {'like': 'no'}, False)
     match_lst2 = q.match_rel(edge_attrs2)
     result2 = [(node2[0], node3[0], edge_attrs2)]
     self.assertEqual(sorted(match_lst2), sorted(result2))
Example #6
0
 def test_match_node_project_node(self):
     """
     Tests applying a project to a simple match node query for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     proj = Project()
     attrs1 = {'Label': 'Person', 'Name': 'Alice', 'Salary': '500'}
     attrs2 = {'Label': 'Person', 'Name': 'Bob', 'Salary': '1000'}
     attrs3 = {'Label': 'Person', 'Name': 'John', 'Salary': '20000'}
     attrs4 = {'Label': 'Person', 'Name': 'Donnie', 'Salary': '100000000'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     node4 = q.add_node(attrs4)
     # Test matching all nodes and then projecting to a single attribute.
     match_lst1 = q.match_node({'Label': 'Person'})
     # Project on salary field.
     filtered_lst1 = proj.project(match_lst1, ['Salary'])
     self.assertEqual(filtered_lst1, [{
         'Salary': '500'
     }, {
         'Salary': '1000'
     }, {
         'Salary': '20000'
     }, {
         'Salary': '100000000'
     }])
     # Test matching a single node and then projecting to a single attribute.
     match_lst2 = q.match_node({'Name': 'Alice'})
     filtered_lst2 = proj.project(match_lst2, ['Salary'])
     self.assertEqual(filtered_lst2, [{'Salary': '500'}])
 def test_match_node_project_node(self):
     """
     Tests applying a project to a simple match node query for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     proj = Project()
     attrs1 = {'Label' : 'Person', 'Name' : 'Alice', 'Salary' : '500'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Bob', 'Salary' : '1000'}
     attrs3 = {'Label' : 'Person', 'Name' : 'John', 'Salary' : '20000'}
     attrs4 = {'Label' : 'Person', 'Name' : 'Donnie', 'Salary' : '100000000'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     node4 = q.add_node(attrs4)
     # Test matching all nodes and then projecting to a single attribute. 
     match_lst1 = q.match_node({'Label' : 'Person'})
     # Project on salary field. 
     filtered_lst1 = proj.project(match_lst1, ['Salary'])
     self.assertEqual(filtered_lst1, [{'Salary' : '500'}, 
                                      {'Salary' : '1000'}, 
                                      {'Salary' : '20000'}, 
                                      {'Salary' : '100000000'}])
     # Test matching a single node and then projecting to a single attribute. 
     match_lst2 = q.match_node({'Name' : 'Alice'})
     filtered_lst2 = proj.project(match_lst2, ['Salary'])
     self.assertEqual(filtered_lst2, [{'Salary' : '500'}])
 def test_modify_node(self):
     """
     Tests L{QueryEvaluator.modify_node} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label' : 'Person', 'Name' : 'Alice'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Bob'}
     attrs3 = {'Label' : 'Person', 'Name' : 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     edge_attrs1 = {'rel_type' : 'friend'}
     edge_attrs2 = {'rel_type' : 'friend', 'fam' : 'cousin'}
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     # Tests adding attributes to node
     q.modify_node(attrs1, {'Age' : '10'}, True)
     match_lst1 = q.match_node(attrs1)
     result1 = [(node1[0], {'Label' : 'Person', 'Name' : 'Alice', 'Age' : '10'})]
     self.assertEqual(match_lst1, result1)
     # Tests removing attributes to node
     q.modify_node(attrs1, {'Age' : '10'}, False)
     match_lst2 = q.match_node(attrs1)
     result2 = [(node1[0], attrs1)]
     self.assertEqual(match_lst2, result2)
    def test_match_node_rel(self):
        """
        Tests L{QueryEvaluator.match_node_rel} method for L{QueryEvaluator}.
        """
        gs = GraphStructure()
        q = QueryEvaluator(gs)
        attrs1 = {'Label' : 'Person', 'Name' : 'Alice'}
        attrs2 = {'Label' : 'Person', 'Name' : 'Bob'}
        attrs3 = {'Label' : 'Person', 'Name' : 'John'}
        node1 = q.add_node(attrs1)
        node2 = q.add_node(attrs2)
        node3 = q.add_node(attrs3)
        edge_attrs1 = {'rel_type' : 'friend'}
        edge_attrs2 = {'rel_type' : 'friend', 'fam' : 'cousin'}
        edge1 = q.add_relationship(node1, node2, edge_attrs1)
        edge2 = q.add_relationship(node2, node3, edge_attrs2)
        edge3 = q.add_relationship(node2, node1, edge_attrs1)
        # Test matching with no results
        match_lst1 = q.match_node_rel(node1[1], edge_attrs2)
        result1 = []
        self.assertEqual(match_lst1, result1)
        # Test matching with single result
        match_lst2 = q.match_node_rel(node2[1], edge_attrs2)
        result2 = [(node2[0], node3[0], edge_attrs2)]
        self.assertEqual(match_lst2, result2)
        # Test matching with multiple result
        match_lst3 = q.match_node_rel(node2[1], {'rel_type' : 'friend'})
        result3 = [(node2[0], node1[0], edge_attrs1),
                    (node2[0], node3[0], edge_attrs2)]

        self.assertEqual(match_lst3, result3)
Example #10
0
 def test_delete_rel(self):
     """
     Tests L{QueryEvaluator.delete_rel} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label': 'Person', 'Name': 'Alice'}
     attrs2 = {'Label': 'Person', 'Name': 'Bob'}
     attrs3 = {'Label': 'Person', 'Name': 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     edge_attrs1 = {'rel_type': 'friend'}
     edge_attrs2 = {'rel_type': 'friend', 'fam': 'cousin'}
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     # Tests deleting no relationship
     q.delete_rel({'rel_type': 'friend', 'fam': 'dad'})
     match_lst1 = q.match({}, {}, {})
     result1 = [(node1[0], node2[0], edge_attrs1),
                (node2[0], node3[0], edge_attrs2)]
     self.assertEqual(match_lst1, result1)
     # Tests deleting relationship
     q.delete_rel(edge_attrs1)
     match_lst2 = q.match({}, {}, {})
     result2 = []
     self.assertEqual(match_lst2, result2)
Example #11
0
 def test_match_node(self):
     """
     Tests L{QueryEvaluator.match_node} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label': 'Person', 'Name': 'Alice'}
     attrs2 = {'Label': 'Person', 'Name': 'Bob'}
     attrs3 = {'Label': 'Person', 'Name': 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     # Test matching all node
     match_lst1 = q.match_node({'Label': 'Person'})
     self.assertEqual(match_lst1, [node1, node2, node3])
     # Test matching single node
     match_lst2 = q.match_node({'Name': 'Alice'})
     self.assertEqual(match_lst2, [node1])
 def test_match_node(self):
     """
     Tests L{QueryEvaluator.match_node} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label' : 'Person', 'Name' : 'Alice'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Bob'}
     attrs3 = {'Label' : 'Person', 'Name' : 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     # Test matching all node
     match_lst1 = q.match_node({'Label' : 'Person'})
     self.assertEqual(match_lst1, [node1, node2, node3])
     # Test matching single node
     match_lst2 = q.match_node({'Name' : 'Alice'})
     self.assertEqual(match_lst2, [node1])
Example #13
0
 def test_multi_match(self):
     """
     Test L{QueryEvaluator.multi_match} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label': 'Person', 'Name': 'Alice'}
     attrs2 = {'Label': 'Person', 'Name': 'Bob'}
     attrs3 = {'Label': 'Person', 'Name': 'John'}
     attrs4 = {'Label': 'Person', 'Name': 'Rick'}
     attrs5 = {'Label': 'Person', 'Name': 'Cat'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     node4 = q.add_node(attrs4)
     node5 = q.add_node(attrs5)
     edge_attrs1 = {'rel_type': 'friend'}
     edge_attrs2 = {'rel_type': 'friend', 'fam': 'cousin'}
     edge_attrs3 = {'rel_type': 'dad'}
     edge_attrs4 = {'rel_type': 'mom'}
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     edge3 = q.add_relationship(node3, node4, edge_attrs3)
     edge4 = q.add_relationship(node4, node5, edge_attrs4)
     # Test no match for multiple length query
     result1 = q.multi_match([attrs1, attrs2, attrs3],
                             [edge_attrs3, edge_attrs1])
     self.assertEqual(result1, None)
     # Test single match for multiple length query
     result2 = q.multi_match([attrs1, attrs2, attrs3],
                             [edge_attrs1, edge_attrs2])
     self.assertEqual(result2, [(1, 3)])
     # Tests many matches for multiple length query
     result3 = q.multi_match([{
         'Label': 'Person'
     }, {
         'Label': 'Person'
     }], [edge_attrs1])
     self.assertEqual(result3, [edge1, edge2])
     # Test all matches for multiple length query
     result4 = q.multi_match([{}, {}], [{}])
     self.assertEqual(result4, [edge1, edge2, edge3, edge4])
Example #14
0
 def test_add_relationship(self):
     """
     Tests L{QueryEvaluator.add_relationship} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label': 'Person', 'Name': 'Alice'}
     attrs2 = {'Label': 'Person', 'Name': 'Bob'}
     attrs3 = {'Label': 'Person', 'Name': 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     edge_attrs1 = {'rel_type': 'friend'}
     edge_attrs2 = {'rel_type': 'cousin'}
     # Test first edge
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     self.assertEqual(edge1, (node1[0], node2[0], edge_attrs1))
     # Test second edge
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     self.assertEqual(edge2, (node2[0], node3[0], edge_attrs2))
 def test_add_relationship(self):
     """
     Tests L{QueryEvaluator.add_relationship} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label' : 'Person', 'Name' : 'Alice'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Bob'}
     attrs3 = {'Label' : 'Person', 'Name' : 'John'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     edge_attrs1 = {'rel_type' : 'friend'}
     edge_attrs2 = {'rel_type' : 'cousin'}
     # Test first edge
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     self.assertEqual(edge1, (node1[0], node2[0], edge_attrs1))
     # Test second edge
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     self.assertEqual(edge2, (node2[0], node3[0], edge_attrs2))
 def test_add_node(self):
     """ 
     Tests L{QueryEvaluator.add_node} method of L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label' : 'Person', 'Name' : 'You'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Me'}
     attrs3 = {'Label' : 'Person', 'Name' : 'She', 'Age' : 23}
     # Test first node
     node1 = q.add_node(attrs1)
     self.assertEqual(node1[0], 1)
     self.assertEqual(node1[1], attrs1)
     # Test second node
     node2 = q.add_node(attrs2)
     self.assertEqual(node2[0], 2)
     self.assertEqual(node2[1], attrs2)
     # Test third node
     node3 = q.add_node(attrs3)
     self.assertEqual(node3[0], 3)
     self.assertEqual(node3[1], attrs3)
Example #17
0
 def test_add_node(self):
     """ 
     Tests L{QueryEvaluator.add_node} method of L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label': 'Person', 'Name': 'You'}
     attrs2 = {'Label': 'Person', 'Name': 'Me'}
     attrs3 = {'Label': 'Person', 'Name': 'She', 'Age': 23}
     # Test first node
     node1 = q.add_node(attrs1)
     self.assertEqual(node1[0], 1)
     self.assertEqual(node1[1], attrs1)
     # Test second node
     node2 = q.add_node(attrs2)
     self.assertEqual(node2[0], 2)
     self.assertEqual(node2[1], attrs2)
     # Test third node
     node3 = q.add_node(attrs3)
     self.assertEqual(node3[0], 3)
     self.assertEqual(node3[1], attrs3)
 def test_multi_match(self):
     """
     Test L{QueryEvaluator.multi_match} method for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     attrs1 = {'Label' : 'Person', 'Name' : 'Alice'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Bob'}
     attrs3 = {'Label' : 'Person', 'Name' : 'John'}
     attrs4 = {'Label' : 'Person', 'Name' : 'Rick'}
     attrs5 = {'Label' : 'Person', 'Name' : 'Cat'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     node4 = q.add_node(attrs4)
     node5 = q.add_node(attrs5)
     edge_attrs1 = {'rel_type' : 'friend'}
     edge_attrs2 = {'rel_type' : 'friend', 'fam' : 'cousin'}
     edge_attrs3 = {'rel_type' : 'dad'}
     edge_attrs4 = {'rel_type' : 'mom'}
     edge1 = q.add_relationship(node1, node2, edge_attrs1)
     edge2 = q.add_relationship(node2, node3, edge_attrs2)
     edge3 = q.add_relationship(node3, node4, edge_attrs3)
     edge4 = q.add_relationship(node4, node5, edge_attrs4)
     # Test no match for multiple length query
     result1 = q.multi_match([attrs1, attrs2, attrs3], [edge_attrs3, edge_attrs1])
     self.assertEqual(result1, None)
     # Test single match for multiple length query
     result2 = q.multi_match([attrs1, attrs2, attrs3], 
         [edge_attrs1, edge_attrs2])
     self.assertEqual(result2, [(1, 3)])
     # Tests many matches for multiple length query
     result3 = q.multi_match([{'Label' : 'Person'}, {'Label' : 'Person'}], 
         [edge_attrs1])
     self.assertEqual(result3, [edge1, edge2])
     # Test all matches for multiple length query
     result4 = q.multi_match([{}, {}], [{}])
     self.assertEqual(result4, [edge1, edge2, edge3, edge4])
 def test_match_node_predicate(self):
     """
     Tests applying a predicate to a simple match node query for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     pred = Predicates(gs)
     attrs1 = {'Label' : 'Person', 'Name' : 'Alice', 'Salary' : '500'}
     attrs2 = {'Label' : 'Person', 'Name' : 'Bob', 'Salary' : '1000'}
     attrs3 = {'Label' : 'Person', 'Name' : 'John', 'Salary' : '20000'}
     attrs4 = {'Label' : 'Person', 'Name' : 'Donnie', 'Salary' : '100000000'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     node4 = q.add_node(attrs4)
     # Test matching all nodes and then filtering with a predicate
     match_lst1 = q.match_node({'Label' : 'Person'})
     # The predicate is salary > 2000 
     filtered_lst1 = pred.filter(match_lst1, 'Salary', '2000', '>')
     self.assertEqual(filtered_lst1, [node3, node4])
     # Test matching a single node and then filtering with a predicate
     match_lst2 = q.match_node({'Name' : 'Alice'})
     filtered_lst2 = pred.filter(match_lst2, 'Salary', '500', '=')
     self.assertEqual(filtered_lst2, [node1])
Example #20
0
 def test_match_node_predicate(self):
     """
     Tests applying a predicate to a simple match node query for L{QueryEvaluator}.
     """
     gs = GraphStructure()
     q = QueryEvaluator(gs)
     pred = Predicates(gs)
     attrs1 = {'Label': 'Person', 'Name': 'Alice', 'Salary': '500'}
     attrs2 = {'Label': 'Person', 'Name': 'Bob', 'Salary': '1000'}
     attrs3 = {'Label': 'Person', 'Name': 'John', 'Salary': '20000'}
     attrs4 = {'Label': 'Person', 'Name': 'Donnie', 'Salary': '100000000'}
     node1 = q.add_node(attrs1)
     node2 = q.add_node(attrs2)
     node3 = q.add_node(attrs3)
     node4 = q.add_node(attrs4)
     # Test matching all nodes and then filtering with a predicate
     match_lst1 = q.match_node({'Label': 'Person'})
     # The predicate is salary > 2000
     filtered_lst1 = pred.filter(match_lst1, 'Salary', '2000', '>')
     self.assertEqual(filtered_lst1, [node3, node4])
     # Test matching a single node and then filtering with a predicate
     match_lst2 = q.match_node({'Name': 'Alice'})
     filtered_lst2 = pred.filter(match_lst2, 'Salary', '500', '=')
     self.assertEqual(filtered_lst2, [node1])
Example #21
0
class LoadData:
    """
    Class is responsible for taking a text file in a certain format
    and loading add the nodes and edges into the in memory Graph Database.
    """

    def __init__(self, gs):
        """
        Takes a L{GraphStructure} object to load the data into.

        @type gs: L{GraphStructure} object
        @param gs: L{GraphStructure} object that is used to store nodes and 
        edges in.
        """
        self.gs = gs
        self.gstorage = GraphStorage(self.gs)

        # Loads data on disk
        self.graph_file = 'graph_file'
        self.id_file = 'id_file'
        self.load_data()

        # Sets up a QueryEvaluator object to perform the loading operations
        self.q_eval = QueryEvaluator(gs)

    def load_data(self):
        """
        Loads persisted data on disk, if it exists, into our L{GraphStructure}
        object.
        """
        if Utilities.files_exist(self.graph_file, self.id_file):
            self.gstorage.load_graph(self.graph_file, self.id_file)


    def load_text_file(self, text_file):
        """
        Loads the data from the text file into the in memory graph 
        structure stored in the L{QueryEvaluator} object and saves the
        data onto disk.
        """
        # Stores a set of nodes and edges
        node = set()
        edge = set()

        f = open(text_file, 'r')
        for line in f:
            # Skips commented lines in text file
            if line[0] == '#':
                continue
            # Stores nodes and edges in our set data structure
            line = line.strip().split('\t')
            node1, node2 = line[0], line[1]
            node.add(node1)
            node.add(node2)
            edge.add((node1, node2))

        f.close()

        # Stores return value when a node is added
        node_dict = {}

        # Adds node and edges between the nodes in our graph database
        for n in node:
            n1 = self.q_eval.add_node({'id' : n})
            node_dict[n] = n1

        for node1,node2 in edge:
            self.q_eval.add_relationship(node_dict[node1], node_dict[node2], {})

        # Saves the file to disk
        self.gstorage.write_graph(self.graph_file, self.id_file)
Example #22
0
class Linker:
    """ A basic linker class. """

    """
    REL ATTR = e: a b:c
    ID ATTR = n: a a:b
    BOOL = b: a val:0/1
    ID = n: a () ()

    METHODS TO IMPLEMENT
    CREATE          ID ATTR ..
    CREATEEDGE      ID ATTR REL ATTR ID ATTR
    MATCH           ID ATTR REL ATTR ID ATTR REL ATTR ID ATTR ...
    MODIFYNODE      ID ATTR ID ATTR BOOL
    MODIFYEDGE      REL ATTR REL ATTR BOOL
    DELETENODE      ID ATTR
    DELETEEDGE      REL ATTR
    RETURN          ID ID ...
    HASPATH         ID ATTR ID ATTR
    CLEAR
    SHORTESTPATH    ID ATTR ID ATTR
    NEIGHBOR        ID ATTR
    HASEDGE         ID ATTR ID ATTR
    COMMONNEIGHBORS ID ATTR ID ATTR
    RESET
    FLUSH

    # EXTRA
    AGG             [id attr (<, >, =) id attr () val ...]

    METHODS IMPLEMENTED
    CREATE          ID ATTR ..
    CREATEEDGE      ID ATTR REL ATTR ID ATTR
    MATCH           ID ATTR REL ATTR ID ATTR REL ATTR ID ATTR ...
    MODIFYNODE      ID ATTR ID ATTR BOOL
    MODIFYEDGE      REL ATTR REL ATTR BOOL

    DELETENODE      ID ATTR
    DELETEEDGE      REL ATTR
    RETURN          ID ID ...
    HASPATH         ID ATTR ID ATTR
    CLEAR
    SHORTESTPATH    ID ATTR ID ATTR

    """




    def __init__(self, object_list, gs):
        """
        This class is the linker for microDB. It takes in a list of 
        L{Command_Struct} objects that is generated by the parser, and a 
        L{GraphStructure} object. 


        @type object_list: List of L{Command_Struct} objects
        @param object_list: List of packaged commands that should be 
        generated by the parser. 
        @type: gs: L{GraphStructure} object
        @param gs: The current internal graph representation. 
        """

        self.list_objects = object_list;
        self.gs = gs
        self.query_evaluator = QueryEvaluator(gs)   
        self.pred = Predicates(gs)   

    def PrintNodes(self, nodes):   
        """
        Prints a list of nodes.       

        @type nodes: List 
        @param nodes: Node tuples to be printed.     
        """   
        if nodes == []:   
            print bcolors.FAIL + "No matches found" + bcolors.ENDC
        else:
            print bcolors.OKGREEN + "NODE MATCHES:" + bcolors.ENDC   
            node_num = 1
            for node in nodes:  
                print bcolors.OKBLUE + "Node " + str(node_num) + \
                " = " + str(node) + bcolors.ENDC   
                node_num += 1   

    def PrintNode_ids(self, node_ids):   
        """
        Prints a list of nodes.       

        @type nodes: List 
        @param nodes: Node tuples to be printed.     
        """   
        nodes = []
        for node_id in node_ids:   
            nodes.append((node_id, 
                self.query_evaluator.get_node_attrs(node_id)))   
        self.PrintNodes(nodes)   

    def PrintEdges(self, edges):   
        """
        Prints a list of edges.       

        @type edges: List 
        @param edges: Edge tuples to be printed.     
        """   
        if edges == []:   
            print bcolors.FAIL + "No matches found" + bcolors.ENDC
        else:   
            print bcolors.OKGREEN + "EDGE MATCHES:" + bcolors.ENDC
            edge_num = 1   
            for edge in edges:   
                edge_tup = (self.query_evaluator.get_node_attrs(
                    edge[0]), edge[2], 
                    self.query_evaluator.get_node_attrs(edge[1]))   
                print bcolors.OKBLUE + "Edge " + str(edge_num) + " = " + \
                str(edge_tup) + bcolors.ENDC   
                edge_num += 1         

    def CreateNode(self, attribute_list):   
        """
        Creates a node and sets the identifier to   
        refer to the created node using the passed   
        in parsed attribute list.    

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """   
        for node in attribute_list:
            curr_id = node[1]   
            curr_attrs = node[2]
            self.gs.set_identifier(curr_id, 
                self.query_evaluator.add_node(curr_attrs))   

    def CreateEdge(self, attribute_list):   
        """
        Creates an edge between the specified nodes and with   
        the specified relationship attributes, all contained   
        in the parsed attribute list    

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """   
        counter = 0
        [nodes1_identifier, nodes1, edge_identifier, edge_attrs, 
        nodes1_identifier, nodes2] = [0]*6
        for item in attribute_list:
            if (counter % 3) == 0:   
                nodes1 = self.query_evaluator.match_node(item[2])
            elif (counter % 3) == 1:
                edge_identifier = item[1]
                edge_attrs = item[2]   
            elif (counter % 3) == 2:   
                nodes2 = self.query_evaluator.match_node(item[2]) 
                for node1 in nodes1:
                    for node2 in nodes2:  
                        self.query_evaluator.add_relationship(node1,
                             node2, edge_attrs)
            counter += 1   

    def PredNodeFilters(self, nodes, keyvals):   
        """
        Checks that the specified predicate attribute is present in the   
        attributes of all of the nodes     

        @type nodes: List 
        @param nodes: List of nodes   
        @type keyvals: keyvals 
        @param keyvals: List of attribute names to check for   
        """  
        filtered_nodes = [] 
        for node in nodes:   
            allpreds = True    
            for keyval in keyvals:      
                if keyval not in node[1].keys():   
                    allpreds = False   
            if allpreds:   
                filtered_nodes.append(node)
        return filtered_nodes

    def getPredAttrs (self, predicates):   
        """
        Get the list of predicate attributes from the predicates list    

        @type predicates: List 
        @param nodes: List of predicate parsed objects     
        """   
        counter = 0
        PredAttrList = []
        for item in predicates:   
            if (counter) % 2 == 0:   
                PredAttrList.append(item[0])   
            counter += 1   
        return PredAttrList

    def MatchSingleItem(self, attribute_list, predicates):   
        """
        Matches a single item, either a node or a relationship, by   
        calling the appropriate query_evaluator method.   
        Then prints out the results of the match query     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """   
        item = attribute_list[0] 
        curr_id = item[1]  
        if item[0] == "n:":   
            nodes = self.query_evaluator.match_node(item[2])    
            if (predicates != []):   
                PredAttrs = self.getPredAttrs(predicates[0])
                prednodes = self.PredNodeFilters(nodes, PredAttrs)
                filtered_nodes = self.Filter_Preds(prednodes, predicates[0])
                self.gs.set_identifier(curr_id, filtered_nodes)
                self.PrintNodes(filtered_nodes)   
            else:   
                self.gs.set_identifier(curr_id, nodes)
                self.PrintNodes(nodes)
        elif item[0] == "e:":      
            edges = self.query_evaluator.match(None, None, item[2])
            self.gs.set_identifier(curr_id, edges)   
            self.PrintEdges(edges)   

    def Filter_Preds(self, nodeids, predicates):   
        """
        Filter nodes based on parsed predicate objects       

        @type node_ids: List
        @param node_ids: Nodes to filter   
        @type predicates: List
        @param pred_list: Parsed predicate objects to filter on    
        """   
        if len(predicates) < 2:
            return self.pred.filter(nodeids, predicates[0][0], 
                predicates[0][2], predicates[0][1])   
        else:
            lenpred = len(predicates)
            counter = 0   
            pred_list = []   
            bool_list = []   
            for item in predicates: 
                if (counter) % 2 == 0:   
                    pred_list.append(item)   
                elif (counter) % 2 == 1:   
                    bool_list.append(item)   
                counter += 1     
            return self.getFilteredNodes(nodeids, pred_list, bool_list)

    def getFilteredNodes(self, nodeids, pred_list, bool_list):   
        """
        Given a list of the predicate objects and a list of boolean arguments,   
        return the list of filtered nodes based on the predicates       

        @type node_ids: List
        @param node_ids: Nodes to filter   
        @type pred_list: List
        @param pred_list: Predicates to filer on
        @type bool_list: List
        @param bool_list: AND or OR strings to combine predicates  
        """   
        filtered_nodes = []  
        for x in range(len(pred_list) - 1):   
            if x == 0:   
                pred0 = pred_list[x]   
                pred1 = pred_list[x + 1]
                filter1 = self.pred.filter(nodeids, 
                    pred0[0], pred0[2], pred0[1]) 
                filter2 = self.pred.filter(nodeids, 
                    pred1[0], pred1[2], pred1[1])
                if bool_list[x] == 'AND':      
                    filtered_nodes = [val for val in filter1 if val in filter2]   
                elif bool_list[x] == 'OR':   
                    for fltr in filter2:   
                        if fltr not in filter1:
                            filter1.append(fltr)
                    filtered_nodes = filter1    
            else:   
                pred = pred_list[x + 1]   
                fltr = self.pred.filter(filtered_nodes, pred[0], 
                    pred[2], pred[1])   
                if bool_list[x] == 'AND':      
                    filtered_nodes = [val for val in filtered_nodes 
                    if val in fltr]   
                elif bool_list[x] == 'OR':   
                    filtered_nodes = list(set(filtered_nodes + fltr))
        return filtered_nodes   

    def TwoItemsFilter(self, item, preds):   
        nodes = self.query_evaluator.match_node(item[2])
        PredAttrs = self.getPredAttrs(preds)
        prednodes = self.PredNodeFilters(nodes, PredAttrs)
        filtered_nodes = self.Filter_Preds(prednodes, preds)   
        return filtered_nodes

    def MatchTwoItems(self, attribute_list, predicates):   
        """
        Matches a pair of nodes and edges.     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """   
        item1 = attribute_list[0]   
        item2 = attribute_list[1]   
        curr_id = item1[1]
        if item1[0] == "n:":         
            filtered_nodes = None
            if (predicates != []):   
                filtered_nodes = self.TwoItemsFilter(item1, predicates[0])   
            edges = self.query_evaluator.match_node_rel(item1[2], item2[2], 
                filtered_nodes)  
            self.gs.set_identifier(curr_id, edges)   
            self.PrintEdges(edges)   
        else:   
            filtered_nodes = None   
            if (predicates != []):   
                filtered_nodes = self.TwoItemsFilter(item2, predicates[0])      
            edges = self.query_evaluator.match_node_rel(item2[2], item1[2], 
                filtered_nodes)
            self.gs.set_identifier(curr_id, edges)   
            self.PrintEdges(edges)   


    def MatchThreeItems(self, attribute_list, predicates):   
        """
        Matches a node, edge, node sequence in that order     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """   
        item1 = attribute_list[0]   
        item2 = attribute_list[1]   
        item3 = attribute_list[2]   
        filtered_nodes1 = None
        filtered_nodes2 = None   
        if (len(predicates) == 2):  
            filtered_nodes1 = self.TwoItemsFilter(item1, predicates[0])  
            filtered_nodes2 = self.TwoItemsFilter(item3, predicates[1])
        elif (len(predicates) == 1):   
            if (item1[1] == predicates[0][0][3]):   
                filtered_nodes1 = self.TwoItemsFilter(item1, predicates[0])   
            else:   
                filtered_nodes2 = self.TwoItemsFilter(item3, predicates[0]) 
        edges = self.query_evaluator.match_node_node_rel(item1[2], item3[2], 
            item2[2], filtered_nodes1, filtered_nodes2)   
        self.gs.set_identifier(item1[1], edges)
        self.PrintEdges(edges)   

    def getIdList(self, attribute_list):   
        """
        Gets the list of identifiers from the attribute list     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """ 
        counter = 0  
        IdList = []
        for item in attribute_list: 
            if (counter % 2) == 0:   
                IdList.append(item[1])  
            counter += 1 
        return IdList

    def getPredOrder(self, attribute_list, predicates):   
        """
        Calculates the order in which the predicates must be applied   
        to the nodes     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        @type predicates: List 
        @param predicates: List of parsed predicate objects  
        """   
        IdList = self.getIdList(attribute_list)   
        predIdList = []
        PredOrder = []
        for pred in predicates:   
            predIdList.append(pred[0][3])   
        for predId in predIdList:   
            PredOrder.append(IdList.index(predId))   
        return PredOrder


    def MatchChain(self, attribute_list, predicates):   
        """
        Matches a chain of node, edge, node, edge, node...     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """   
        counter = 0   
        node_attr_list = []   
        edge_attr_list = []   
        for item in attribute_list:   
            if (counter) % 2 == 0:   
                node_attr_list.append(item[2])   
            elif (counter) % 2 == 1:   
                edge_attr_list.append(item[2])   
            counter += 1   
        predOrder = []     
        filtered_nodes = [None] * len(node_attr_list)
        if predicates != []:   
            predOrder = self.getPredOrder(attribute_list, predicates)  
            for x in predOrder:   
                nodes1 = self.query_evaluator.match_node(node_attr_list[x])   
                PredAttrs1 = self.getPredAttrs(predicates[0])
                prednodes1 = self.PredNodeFilters(nodes1, PredAttrs1)   
                filtered_nodes1 = self.Filter_Preds(prednodes1, predicates[0])
                filtered_nodes[x] = filtered_nodes1   
                predicates.pop(0)
        nodes = self.query_evaluator.multi_match(node_attr_list, 
            edge_attr_list, filtered_nodes)
        self.gs.set_identifier(attribute_list[0][1], nodes)      
        if nodes == None:   
             print bcolors.FAIL + "No matches found" + bcolors.ENDC  
        else:
            print bcolors.OKGREEN + "NODE MATCHES:" + bcolors.ENDC   
            node_num = 1
            for node in nodes:
                node_tup = (node[0], 
                    self.query_evaluator.get_node_attrs(node[0]))  
                print bcolors.OKBLUE + "Node " + str(node_num) + \
                " = " + str(node_tup) + bcolors.ENDC   
                node_num += 1      

    def GeneralMatch(self, attribute_list, predicates):   
        """
        Calls the corresponding match function to match a set of ndoes     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        @type predicates: List 
        @param predicates: List of parsed predicate objects  
        """   
        if (len(attribute_list) == 1):   
            self.MatchSingleItem(attribute_list, predicates)      
        elif(len(attribute_list) == 2):      
            self.MatchTwoItems(attribute_list, predicates)
        elif(len(attribute_list) == 3):   
            self.MatchThreeItems(attribute_list, predicates)  
        else:   
            self.MatchChain(attribute_list, predicates)   

    def ModifyNode(self, attribute_list, predicates):   
        """
        Modifies the specified nodes by either adding or removing attribtues     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        @type predicates: List 
        @param predicates: List of parsed predicate objects  
        """   
        nodes_modified = attribute_list[0]   
        attrs_changed = attribute_list[1]   
        modify_boolean = attribute_list[2]   
        self.query_evaluator.modify_node(nodes_modified[2], 
            attrs_changed[2], int ((modify_boolean[2])['val']))   

    def ModifyEdge(self, attribute_list, predicates):   
        """
        Modifies the specified edges by either adding or removing attribtues     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        @type predicates: List 
        @param predicates: List of parsed predicate objects  
        """   
        edges_modified = attribute_list[0]   
        attrs_changed = attribute_list[1]   
        modify_boolean = attribute_list[2]   
        self.query_evaluator.modify_rel(edges_modified[2], 
            attrs_changed[2], int ((modify_boolean[2])['val']))   

    def ReturnIdent(self, attribute_list):   
        """
        Returns the specified identifier     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """   
        for item in attribute_list:    
            print bcolors.OKBLUE + str(item[1]) + " = " \
            + str(self.gs.get_identifier(item[1])) + bcolors.ENDC   

    def HasPath(self, attribute_list):   
        """
        Checks if a path exists between two ndoes.      

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """   
        item1 = attribute_list[0]   
        item2 = attribute_list[1]   
        nodes1 = self.query_evaluator.match(item1[2], None, None)   
        nodes2 = self.query_evaluator.match(item2[2], None, None)      
        for node1 in nodes1:   
            for node2 in nodes2:   
                if (self.query_evaluator.check_path(node1[0], node2[0])):   
                    print bcolors.OKBLUE + "A path exists between " \
                    + str(node1) + " and " + str(node2) + bcolors.ENDC   
                else:   
                    print bcolors.FAIL + "No path exists between " \
                    + str(node1) + " and " + str(node2) + bcolors.ENDC   

    def ShortestPath(self, attribute_list):   
        """
        Returns the shortest path between two nodes      

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """   
        item1 = attribute_list[0]   
        item2 = attribute_list[1]   
        nodes1 = self.query_evaluator.match(item1[2], None, None)   
        nodes2 = self.query_evaluator.match(item2[2], None, None)   
        for node1 in nodes1:   
            for node2 in nodes2:   
                if (self.query_evaluator.check_path(node1[0], node2[0])):
                    path_list = self.query_evaluator.get_shortest_path\
                    (node1[0], node2[0])
                    print bcolors.OKGREEN \
                    + "The nodes in the path between " + str(node1) \
                    + " and " + str(node2) + " are: " + bcolors.ENDC    
                    for node_id in path_list:   
                        print bcolors.OKBLUE \
                        + str((node_id, 
                            self.query_evaluator.get_node_attrs\
                            (node_id))) + bcolors.ENDC     
                else:   
                    print bcolors.FAIL + "No path exists between " + \
                    str(node1)+ " and " + str(node2) + bcolors.ENDC   

    def getNeighbors(self, attribute_list):   
        """
        Get the neighbors of the specified nodes      

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """   
        item1 = attribute_list[0]   
        nodes = self.query_evaluator.match(item1[2], None, None)   
        if nodes == None:   
            print bcolors.FAIL + "No Node matches found" + bcolors.ENDC   
        else:   
            print bcolors.OKGREEN + "NODE Neighbors:" + bcolors.ENDC   
            node_num = 1       
            for node1 in nodes:           
                neighbor_ids = self.query_evaluator.get_neighbors(node1[0])   
                if (neighbor_ids == []): 
                    print bcolors.FAIL + "Neighbors for Node " + \
                    str(node_num) + " = " + "No neighbors for Node(s)" + \
                    bcolors.ENDC   
                else:   
                    neighbors = []   
                    for neighbor_id in neighbor_ids:
                        neighbors.append((neighbor_id, 
                            self.query_evaluator.get_node_attrs(neighbor_id)))   
                    print bcolors.OKBLUE + "Neighbors for Node " + \
                    str(node_num) + " = " + str(neighbors) + bcolors.ENDC   
            node_num += 1   

    def HasEdge(self, attribute_list):   
        """
        Checks if a direct edge exists between two nodes      

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """   
        item1 = attribute_list[0]   
        item2 = attribute_list[1]   
        nodes1 = self.query_evaluator.match(item1[2], None, None)   
        nodes2 = self.query_evaluator.match(item2[2], None, None)      
        for node1 in nodes1:   
            for node2 in nodes2:   
                if (self.query_evaluator.check_path(node1[0], node2[0])):   
                    print bcolors.OKBLUE + \
                    "A direct edge exists between " + str(node1) + \
                    " and " + str(node2) + bcolors.ENDC   
                else:   
                    print bcolors.FAIL + "No direct edge exists between " + \
                    str(node1) + " and " + str(node2) + bcolors.ENDC 

    def execute(self):
        """
        Executes commands that were extracted by the parser. 
        """
        # iterate through objects returned by parser to execute queries
        for obj in self.list_objects:
            command_name = obj.get_command()
            attribute_list = obj.get_attr_list()   
            predicates = obj.get_names()
            if command_name == "CREATE":
                self.CreateNode(attribute_list)   
            elif command_name == "CREATEEDGE":   
                self.CreateEdge(attribute_list)   
            elif command_name == "MATCH":   
                self.GeneralMatch(attribute_list, predicates)
            elif command_name == "MODIFYNODE":   
                self.ModifyNode(attribute_list, predicates)    
            elif command_name == "MODIFYEDGE":   
                self.ModifyEdge(attribute_list, predicates)
            elif command_name == "DELETENODE":   
                node_deleted = attribute_list[0]   
                self.query_evaluator.delete_node(node_deleted[2])   
            elif command_name == "DELETEEDGE":   
                edge_deleted = attribute_list[0]   
                self.query_evaluator.delete_rel(edge_deleted[2])   
            elif command_name == "RETURN":  
                self.ReturnIdent(attribute_list)   
            elif command_name == "HASPATH":   
                self.HasPath(attribute_list)
            elif command_name == "CLEAR":   
                self.query_evaluator.clear()   
            elif command_name == "SHORTESTPATH":   
                self.ShortestPath(attribute_list)
            elif command_name == "SHOW":
                self.gs.display()
            elif command_name == "VISUALIZE":
                self.query_evaluator.create_visual()   
            elif command_name == "NEIGHBOR":
                self.getNeighbors(attribute_list)
            elif command_name == "HASEDGE":   
                self.HasEdge(attribute_list)
Example #23
0
class Linker:
    """ A basic linker class. """
    """
    REL ATTR = e: a b:c
    ID ATTR = n: a a:b
    BOOL = b: a val:0/1
    ID = n: a () ()

    METHODS TO IMPLEMENT
    CREATE          ID ATTR ..
    CREATEEDGE      ID ATTR REL ATTR ID ATTR
    MATCH           ID ATTR REL ATTR ID ATTR REL ATTR ID ATTR ...
    MODIFYNODE      ID ATTR ID ATTR BOOL
    MODIFYEDGE      REL ATTR REL ATTR BOOL
    DELETENODE      ID ATTR
    DELETEEDGE      REL ATTR
    RETURN          ID ID ...
    HASPATH         ID ATTR ID ATTR
    CLEAR
    SHORTESTPATH    ID ATTR ID ATTR
    NEIGHBOR        ID ATTR
    HASEDGE         ID ATTR ID ATTR
    COMMONNEIGHBORS ID ATTR ID ATTR
    RESET
    FLUSH

    # EXTRA
    AGG             [id attr (<, >, =) id attr () val ...]

    METHODS IMPLEMENTED
    CREATE          ID ATTR ..
    CREATEEDGE      ID ATTR REL ATTR ID ATTR
    MATCH           ID ATTR REL ATTR ID ATTR REL ATTR ID ATTR ...
    MODIFYNODE      ID ATTR ID ATTR BOOL
    MODIFYEDGE      REL ATTR REL ATTR BOOL

    DELETENODE      ID ATTR
    DELETEEDGE      REL ATTR
    RETURN          ID ID ...
    HASPATH         ID ATTR ID ATTR
    CLEAR
    SHORTESTPATH    ID ATTR ID ATTR

    """
    def __init__(self, object_list, gs):
        """
        This class is the linker for microDB. It takes in a list of 
        L{Command_Struct} objects that is generated by the parser, and a 
        L{GraphStructure} object. 


        @type object_list: List of L{Command_Struct} objects
        @param object_list: List of packaged commands that should be 
        generated by the parser. 
        @type: gs: L{GraphStructure} object
        @param gs: The current internal graph representation. 
        """

        self.list_objects = object_list
        self.gs = gs
        self.query_evaluator = QueryEvaluator(gs)
        self.pred = Predicates(gs)

    def PrintNodes(self, nodes):
        """
        Prints a list of nodes.       

        @type nodes: List 
        @param nodes: Node tuples to be printed.     
        """
        if nodes == []:
            print bcolors.FAIL + "No matches found" + bcolors.ENDC
        else:
            print bcolors.OKGREEN + "NODE MATCHES:" + bcolors.ENDC
            node_num = 1
            for node in nodes:
                print bcolors.OKBLUE + "Node " + str(node_num) + \
                " = " + str(node) + bcolors.ENDC
                node_num += 1

    def PrintNode_ids(self, node_ids):
        """
        Prints a list of nodes.       

        @type nodes: List 
        @param nodes: Node tuples to be printed.     
        """
        nodes = []
        for node_id in node_ids:
            nodes.append(
                (node_id, self.query_evaluator.get_node_attrs(node_id)))
        self.PrintNodes(nodes)

    def PrintEdges(self, edges):
        """
        Prints a list of edges.       

        @type edges: List 
        @param edges: Edge tuples to be printed.     
        """
        if edges == []:
            print bcolors.FAIL + "No matches found" + bcolors.ENDC
        else:
            print bcolors.OKGREEN + "EDGE MATCHES:" + bcolors.ENDC
            edge_num = 1
            for edge in edges:
                edge_tup = (self.query_evaluator.get_node_attrs(edge[0]),
                            edge[2],
                            self.query_evaluator.get_node_attrs(edge[1]))
                print bcolors.OKBLUE + "Edge " + str(edge_num) + " = " + \
                str(edge_tup) + bcolors.ENDC
                edge_num += 1

    def CreateNode(self, attribute_list):
        """
        Creates a node and sets the identifier to   
        refer to the created node using the passed   
        in parsed attribute list.    

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """
        for node in attribute_list:
            curr_id = node[1]
            curr_attrs = node[2]
            self.gs.set_identifier(curr_id,
                                   self.query_evaluator.add_node(curr_attrs))

    def CreateEdge(self, attribute_list):
        """
        Creates an edge between the specified nodes and with   
        the specified relationship attributes, all contained   
        in the parsed attribute list    

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """
        counter = 0
        [
            nodes1_identifier, nodes1, edge_identifier, edge_attrs,
            nodes1_identifier, nodes2
        ] = [0] * 6
        for item in attribute_list:
            if (counter % 3) == 0:
                nodes1 = self.query_evaluator.match_node(item[2])
            elif (counter % 3) == 1:
                edge_identifier = item[1]
                edge_attrs = item[2]
            elif (counter % 3) == 2:
                nodes2 = self.query_evaluator.match_node(item[2])
                for node1 in nodes1:
                    for node2 in nodes2:
                        self.query_evaluator.add_relationship(
                            node1, node2, edge_attrs)
            counter += 1

    def PredNodeFilters(self, nodes, keyvals):
        """
        Checks that the specified predicate attribute is present in the   
        attributes of all of the nodes     

        @type nodes: List 
        @param nodes: List of nodes   
        @type keyvals: keyvals 
        @param keyvals: List of attribute names to check for   
        """
        filtered_nodes = []
        for node in nodes:
            allpreds = True
            for keyval in keyvals:
                if keyval not in node[1].keys():
                    allpreds = False
            if allpreds:
                filtered_nodes.append(node)
        return filtered_nodes

    def getPredAttrs(self, predicates):
        """
        Get the list of predicate attributes from the predicates list    

        @type predicates: List 
        @param nodes: List of predicate parsed objects     
        """
        counter = 0
        PredAttrList = []
        for item in predicates:
            if (counter) % 2 == 0:
                PredAttrList.append(item[0])
            counter += 1
        return PredAttrList

    def MatchSingleItem(self, attribute_list, predicates):
        """
        Matches a single item, either a node or a relationship, by   
        calling the appropriate query_evaluator method.   
        Then prints out the results of the match query     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """
        item = attribute_list[0]
        curr_id = item[1]
        if item[0] == "n:":
            nodes = self.query_evaluator.match_node(item[2])
            if (predicates != []):
                PredAttrs = self.getPredAttrs(predicates[0])
                prednodes = self.PredNodeFilters(nodes, PredAttrs)
                filtered_nodes = self.Filter_Preds(prednodes, predicates[0])
                self.gs.set_identifier(curr_id, filtered_nodes)
                self.PrintNodes(filtered_nodes)
            else:
                self.gs.set_identifier(curr_id, nodes)
                self.PrintNodes(nodes)
        elif item[0] == "e:":
            edges = self.query_evaluator.match(None, None, item[2])
            self.gs.set_identifier(curr_id, edges)
            self.PrintEdges(edges)

    def Filter_Preds(self, nodeids, predicates):
        """
        Filter nodes based on parsed predicate objects       

        @type node_ids: List
        @param node_ids: Nodes to filter   
        @type predicates: List
        @param pred_list: Parsed predicate objects to filter on    
        """
        if len(predicates) < 2:
            return self.pred.filter(nodeids, predicates[0][0],
                                    predicates[0][2], predicates[0][1])
        else:
            lenpred = len(predicates)
            counter = 0
            pred_list = []
            bool_list = []
            for item in predicates:
                if (counter) % 2 == 0:
                    pred_list.append(item)
                elif (counter) % 2 == 1:
                    bool_list.append(item)
                counter += 1
            return self.getFilteredNodes(nodeids, pred_list, bool_list)

    def getFilteredNodes(self, nodeids, pred_list, bool_list):
        """
        Given a list of the predicate objects and a list of boolean arguments,   
        return the list of filtered nodes based on the predicates       

        @type node_ids: List
        @param node_ids: Nodes to filter   
        @type pred_list: List
        @param pred_list: Predicates to filer on
        @type bool_list: List
        @param bool_list: AND or OR strings to combine predicates  
        """
        filtered_nodes = []
        for x in range(len(pred_list) - 1):
            if x == 0:
                pred0 = pred_list[x]
                pred1 = pred_list[x + 1]
                filter1 = self.pred.filter(nodeids, pred0[0], pred0[2],
                                           pred0[1])
                filter2 = self.pred.filter(nodeids, pred1[0], pred1[2],
                                           pred1[1])
                if bool_list[x] == 'AND':
                    filtered_nodes = [val for val in filter1 if val in filter2]
                elif bool_list[x] == 'OR':
                    for fltr in filter2:
                        if fltr not in filter1:
                            filter1.append(fltr)
                    filtered_nodes = filter1
            else:
                pred = pred_list[x + 1]
                fltr = self.pred.filter(filtered_nodes, pred[0], pred[2],
                                        pred[1])
                if bool_list[x] == 'AND':
                    filtered_nodes = [
                        val for val in filtered_nodes if val in fltr
                    ]
                elif bool_list[x] == 'OR':
                    filtered_nodes = list(set(filtered_nodes + fltr))
        return filtered_nodes

    def TwoItemsFilter(self, item, preds):
        nodes = self.query_evaluator.match_node(item[2])
        PredAttrs = self.getPredAttrs(preds)
        prednodes = self.PredNodeFilters(nodes, PredAttrs)
        filtered_nodes = self.Filter_Preds(prednodes, preds)
        return filtered_nodes

    def MatchTwoItems(self, attribute_list, predicates):
        """
        Matches a pair of nodes and edges.     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """
        item1 = attribute_list[0]
        item2 = attribute_list[1]
        curr_id = item1[1]
        if item1[0] == "n:":
            filtered_nodes = None
            if (predicates != []):
                filtered_nodes = self.TwoItemsFilter(item1, predicates[0])
            edges = self.query_evaluator.match_node_rel(
                item1[2], item2[2], filtered_nodes)
            self.gs.set_identifier(curr_id, edges)
            self.PrintEdges(edges)
        else:
            filtered_nodes = None
            if (predicates != []):
                filtered_nodes = self.TwoItemsFilter(item2, predicates[0])
            edges = self.query_evaluator.match_node_rel(
                item2[2], item1[2], filtered_nodes)
            self.gs.set_identifier(curr_id, edges)
            self.PrintEdges(edges)

    def MatchThreeItems(self, attribute_list, predicates):
        """
        Matches a node, edge, node sequence in that order     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """
        item1 = attribute_list[0]
        item2 = attribute_list[1]
        item3 = attribute_list[2]
        filtered_nodes1 = None
        filtered_nodes2 = None
        if (len(predicates) == 2):
            filtered_nodes1 = self.TwoItemsFilter(item1, predicates[0])
            filtered_nodes2 = self.TwoItemsFilter(item3, predicates[1])
        elif (len(predicates) == 1):
            if (item1[1] == predicates[0][0][3]):
                filtered_nodes1 = self.TwoItemsFilter(item1, predicates[0])
            else:
                filtered_nodes2 = self.TwoItemsFilter(item3, predicates[0])
        edges = self.query_evaluator.match_node_node_rel(
            item1[2], item3[2], item2[2], filtered_nodes1, filtered_nodes2)
        self.gs.set_identifier(item1[1], edges)
        self.PrintEdges(edges)

    def getIdList(self, attribute_list):
        """
        Gets the list of identifiers from the attribute list     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """
        counter = 0
        IdList = []
        for item in attribute_list:
            if (counter % 2) == 0:
                IdList.append(item[1])
            counter += 1
        return IdList

    def getPredOrder(self, attribute_list, predicates):
        """
        Calculates the order in which the predicates must be applied   
        to the nodes     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        @type predicates: List 
        @param predicates: List of parsed predicate objects  
        """
        IdList = self.getIdList(attribute_list)
        predIdList = []
        PredOrder = []
        for pred in predicates:
            predIdList.append(pred[0][3])
        for predId in predIdList:
            PredOrder.append(IdList.index(predId))
        return PredOrder

    def MatchChain(self, attribute_list, predicates):
        """
        Matches a chain of node, edge, node, edge, node...     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".  
        """
        counter = 0
        node_attr_list = []
        edge_attr_list = []
        for item in attribute_list:
            if (counter) % 2 == 0:
                node_attr_list.append(item[2])
            elif (counter) % 2 == 1:
                edge_attr_list.append(item[2])
            counter += 1
        predOrder = []
        filtered_nodes = [None] * len(node_attr_list)
        if predicates != []:
            predOrder = self.getPredOrder(attribute_list, predicates)
            for x in predOrder:
                nodes1 = self.query_evaluator.match_node(node_attr_list[x])
                PredAttrs1 = self.getPredAttrs(predicates[0])
                prednodes1 = self.PredNodeFilters(nodes1, PredAttrs1)
                filtered_nodes1 = self.Filter_Preds(prednodes1, predicates[0])
                filtered_nodes[x] = filtered_nodes1
                predicates.pop(0)
        nodes = self.query_evaluator.multi_match(node_attr_list,
                                                 edge_attr_list,
                                                 filtered_nodes)
        self.gs.set_identifier(attribute_list[0][1], nodes)
        if nodes == None:
            print bcolors.FAIL + "No matches found" + bcolors.ENDC
        else:
            print bcolors.OKGREEN + "NODE MATCHES:" + bcolors.ENDC
            node_num = 1
            for node in nodes:
                node_tup = (node[0],
                            self.query_evaluator.get_node_attrs(node[0]))
                print bcolors.OKBLUE + "Node " + str(node_num) + \
                " = " + str(node_tup) + bcolors.ENDC
                node_num += 1

    def GeneralMatch(self, attribute_list, predicates):
        """
        Calls the corresponding match function to match a set of ndoes     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        @type predicates: List 
        @param predicates: List of parsed predicate objects  
        """
        if (len(attribute_list) == 1):
            self.MatchSingleItem(attribute_list, predicates)
        elif (len(attribute_list) == 2):
            self.MatchTwoItems(attribute_list, predicates)
        elif (len(attribute_list) == 3):
            self.MatchThreeItems(attribute_list, predicates)
        else:
            self.MatchChain(attribute_list, predicates)

    def ModifyNode(self, attribute_list, predicates):
        """
        Modifies the specified nodes by either adding or removing attribtues     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        @type predicates: List 
        @param predicates: List of parsed predicate objects  
        """
        nodes_modified = attribute_list[0]
        attrs_changed = attribute_list[1]
        modify_boolean = attribute_list[2]
        self.query_evaluator.modify_node(nodes_modified[2], attrs_changed[2],
                                         int((modify_boolean[2])['val']))

    def ModifyEdge(self, attribute_list, predicates):
        """
        Modifies the specified edges by either adding or removing attribtues     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        @type predicates: List 
        @param predicates: List of parsed predicate objects  
        """
        edges_modified = attribute_list[0]
        attrs_changed = attribute_list[1]
        modify_boolean = attribute_list[2]
        self.query_evaluator.modify_rel(edges_modified[2], attrs_changed[2],
                                        int((modify_boolean[2])['val']))

    def ReturnIdent(self, attribute_list):
        """
        Returns the specified identifier     

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """
        for item in attribute_list:
            print bcolors.OKBLUE + str(item[1]) + " = " \
            + str(self.gs.get_identifier(item[1])) + bcolors.ENDC

    def HasPath(self, attribute_list):
        """
        Checks if a path exists between two ndoes.      

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """
        item1 = attribute_list[0]
        item2 = attribute_list[1]
        nodes1 = self.query_evaluator.match(item1[2], None, None)
        nodes2 = self.query_evaluator.match(item2[2], None, None)
        for node1 in nodes1:
            for node2 in nodes2:
                if (self.query_evaluator.check_path(node1[0], node2[0])):
                    print bcolors.OKBLUE + "A path exists between " \
                    + str(node1) + " and " + str(node2) + bcolors.ENDC
                else:
                    print bcolors.FAIL + "No path exists between " \
                    + str(node1) + " and " + str(node2) + bcolors.ENDC

    def ShortestPath(self, attribute_list):
        """
        Returns the shortest path between two nodes      

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """
        item1 = attribute_list[0]
        item2 = attribute_list[1]
        nodes1 = self.query_evaluator.match(item1[2], None, None)
        nodes2 = self.query_evaluator.match(item2[2], None, None)
        for node1 in nodes1:
            for node2 in nodes2:
                if (self.query_evaluator.check_path(node1[0], node2[0])):
                    path_list = self.query_evaluator.get_shortest_path\
                    (node1[0], node2[0])
                    print bcolors.OKGREEN \
                    + "The nodes in the path between " + str(node1) \
                    + " and " + str(node2) + " are: " + bcolors.ENDC
                    for node_id in path_list:
                        print bcolors.OKBLUE \
                        + str((node_id,
                            self.query_evaluator.get_node_attrs\
                            (node_id))) + bcolors.ENDC
                else:
                    print bcolors.FAIL + "No path exists between " + \
                    str(node1)+ " and " + str(node2) + bcolors.ENDC

    def getNeighbors(self, attribute_list):
        """
        Get the neighbors of the specified nodes      

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """
        item1 = attribute_list[0]
        nodes = self.query_evaluator.match(item1[2], None, None)
        if nodes == None:
            print bcolors.FAIL + "No Node matches found" + bcolors.ENDC
        else:
            print bcolors.OKGREEN + "NODE Neighbors:" + bcolors.ENDC
            node_num = 1
            for node1 in nodes:
                neighbor_ids = self.query_evaluator.get_neighbors(node1[0])
                if (neighbor_ids == []):
                    print bcolors.FAIL + "Neighbors for Node " + \
                    str(node_num) + " = " + "No neighbors for Node(s)" + \
                    bcolors.ENDC
                else:
                    neighbors = []
                    for neighbor_id in neighbor_ids:
                        neighbors.append(
                            (neighbor_id,
                             self.query_evaluator.get_node_attrs(neighbor_id)))
                    print bcolors.OKBLUE + "Neighbors for Node " + \
                    str(node_num) + " = " + str(neighbors) + bcolors.ENDC
            node_num += 1

    def HasEdge(self, attribute_list):
        """
        Checks if a direct edge exists between two nodes      

        @type attribute_list: List 
        @param attribute_list: List of parsed objects, where each
        element is of the form "Type: Identifier dictionary_attributes".   
        """
        item1 = attribute_list[0]
        item2 = attribute_list[1]
        nodes1 = self.query_evaluator.match(item1[2], None, None)
        nodes2 = self.query_evaluator.match(item2[2], None, None)
        for node1 in nodes1:
            for node2 in nodes2:
                if (self.query_evaluator.check_path(node1[0], node2[0])):
                    print bcolors.OKBLUE + \
                    "A direct edge exists between " + str(node1) + \
                    " and " + str(node2) + bcolors.ENDC
                else:
                    print bcolors.FAIL + "No direct edge exists between " + \
                    str(node1) + " and " + str(node2) + bcolors.ENDC

    def execute(self):
        """
        Executes commands that were extracted by the parser. 
        """
        # iterate through objects returned by parser to execute queries
        for obj in self.list_objects:
            command_name = obj.get_command()
            attribute_list = obj.get_attr_list()
            predicates = obj.get_names()
            if command_name == "CREATE":
                self.CreateNode(attribute_list)
            elif command_name == "CREATEEDGE":
                self.CreateEdge(attribute_list)
            elif command_name == "MATCH":
                self.GeneralMatch(attribute_list, predicates)
            elif command_name == "MODIFYNODE":
                self.ModifyNode(attribute_list, predicates)
            elif command_name == "MODIFYEDGE":
                self.ModifyEdge(attribute_list, predicates)
            elif command_name == "DELETENODE":
                node_deleted = attribute_list[0]
                self.query_evaluator.delete_node(node_deleted[2])
            elif command_name == "DELETEEDGE":
                edge_deleted = attribute_list[0]
                self.query_evaluator.delete_rel(edge_deleted[2])
            elif command_name == "RETURN":
                self.ReturnIdent(attribute_list)
            elif command_name == "HASPATH":
                self.HasPath(attribute_list)
            elif command_name == "CLEAR":
                self.query_evaluator.clear()
            elif command_name == "SHORTESTPATH":
                self.ShortestPath(attribute_list)
            elif command_name == "SHOW":
                self.gs.display()
            elif command_name == "VISUALIZE":
                self.query_evaluator.create_visual()
            elif command_name == "NEIGHBOR":
                self.getNeighbors(attribute_list)
            elif command_name == "HASEDGE":
                self.HasEdge(attribute_list)