def add_relationship(self, query): labels, properties, direction, rel_type, rel_props = self._parser.parse( query) label_first = Label(self._id, labels[0]) label_second = Label(self._id, labels[1]) properties_first = [] for p in properties[0]: v = Property(self._id, PropertyType.STRING, label_first, p, None) properties_first.append(v) if len(properties_first) > 1: properties_first[0].next_prop = properties_first[1] properties_second = [] for p in properties[1]: v = Property(self._id, PropertyType.STRING, label_second, p, None) properties_second.append(v) if len(properties_second) > 1: properties_second[0].next_prop = properties_second[1] node1 = (label_first, properties_first[0]) node2 = (label_second, properties_second[0]) rel_label = Label(self._id, rel_type) rel_properties = [] if rel_props is not None: for p in rel_props: v = Property(self._id, PropertyType.STRING, rel_label, p, None) rel_properties.append(v) if len(rel_properties) > 1: rel_properties[0].next_prop = rel_properties[1] relationship = (rel_label, rel_properties[0], direction) self._engine.create_relationship(node1, node2, relationship)
def test_del_relation(self): io = Io() value = "You spin my head right ground right ground" label = Label(cfg.INV_ID, value) label = io.write_label(label) prop_value = True property = Property(cfg.INV_ID, PropertyType.BOOL, label, prop_value, None) property = io.write_property(property) node = Node(cfg.INV_ID, label, property, None) node2 = Node(cfg.INV_ID, label, property, None) written1 = io.write_node(node) written2 = io.write_node(node2) relation = Relationship(cfg.INV_ID, False, written1, written2, label, property, None, None, None, None) written = io.write_relation(relation) io.del_relation(written.id) retrived = io.get_relations_by_id([written.id]) node1 = io.read_node(written1.id) node2 = io.read_node(written2.id) self.assertEqual(len(retrived), 0) print(node1.next_rel) print(node2.next_rel) self.assertEqual(node1.next_rel is None, True) self.assertEqual(node2.next_rel is None, True)
def test_relation_io(self): io = Io() value = "You spin my head right ground right ground" label = Label(cfg.INV_ID, value) label = io.write_label(label) prop_value = True property = Property(cfg.INV_ID, PropertyType.BOOL, label, prop_value, None) property = io.write_property(property) node = Node(cfg.INV_ID, label, property, None) node2 = Node(cfg.INV_ID, label, property, None) written1 = io.write_node(node) written2 = io.write_node(node2) relation = Relationship(cfg.INV_ID, False, written1, written2, label, property, None, None, None, None) written = io.write_relation(relation) retrieved = io.read_relation(written.id) written1 = io.read_node(written1.id) written2 = io.read_node(written2.id) self.assertEqual(retrieved.label.value, value) self.assertEqual(retrieved.next_prop.value, prop_value) self.assertEqual(retrieved.first_node.id, written1.id) self.assertEqual(retrieved.second_node.id, written2.id) self.assertEqual(written2.next_rel, retrieved.id) self.assertEqual(written1.next_rel, retrieved.id)
def test_label_io(self): io = Io() value = "I LOVE ADB" label = Label(cfg.INV_ID, value) written = io.write_label(label) retrieved = io.read_label(written.id) self.assertEqual(label.id, retrieved.id) self.assertEqual(label.value, retrieved.value)
def test_create_index(self): engine = GraphEngine() label1 = Label(cfg.INV_ID, 'Figure') label2 = Label(cfg.INV_ID, 'x') label3 = Label(cfg.INV_ID, 'y') limit = 10000 property2 = property1 = None for _ in range(limit): property2 = Property(cfg.INV_ID, PropertyType.INT, label2, randint(0, 1000000), None) property1 = Property(cfg.INV_ID, PropertyType.INT, label3, randint(0, 1000000), property2) engine.create_node((label1, property1)) start = time.time() retrieved_node1 = engine.match_pattern([(label1, property1)], None)[0].pop() end = time.time() time_no_index = end - start self.assertEqual(label1.value, retrieved_node1.label.value) self.assertEqual(property1.value, retrieved_node1.next_prop.value) self.assertEqual(property2.value, retrieved_node1.next_prop.next_prop.value) engine.create_index((label1, property1)) start = time.time() retrieved_node1 = engine.match_pattern([(label1, property1)], None)[0].pop() end = time.time() time_index = end - start print(time_no_index) print(time_index) self.assertEqual(label1.value, retrieved_node1.label.value) self.assertEqual(property1.value, retrieved_node1.next_prop.value) self.assertEqual(property2.value, retrieved_node1.next_prop.next_prop.value) self.assertLess(time_index, time_no_index)
def test_create_node(self): engine = GraphEngine() label1 = Label(cfg.INV_ID, 'Figure') label2 = Label(cfg.INV_ID, 'x') label3 = Label(cfg.INV_ID, 'y') property2 = Property(cfg.INV_ID, PropertyType.INT, label2, randint(0, 1000000), None) property1 = Property(cfg.INV_ID, PropertyType.INT, label3, randint(0, 1000000), property2) engine.create_node((label1, property1)) retrieved_node1 = engine.match_pattern([(label1, property1)], None)[0].pop() self.assertEqual(label1.value, retrieved_node1.label.value) self.assertEqual(property1.value, retrieved_node1.next_prop.value) self.assertEqual(property2.value, retrieved_node1.next_prop.next_prop.value)
def write_label(self, label: Label) -> Label: """ Writes property to file. Creates dynamic store if needed by property type. Inlines otherwise. :param label: - to write :return label with generated id """ if label.id == cfg.INV_ID: label.id = self._get_label_id() store_pointer = self.write_store(label.value) value = Packer.pack_label(store_pointer, label) self._write_bytes(self.labels, label.id * cfg.LABEL_SIZE, value) return label
def test_node_deletion(self): io = Io() value = "Graph DB is AWESOME" label = Label(cfg.INV_ID, value) prop_value = True property = Property(cfg.INV_ID, PropertyType.BOOL, label, prop_value, None) node = Node(cfg.INV_ID, label, property, cfg.INV_ID) written = io.write_node(node) io.del_node(written.id) retrieved = io.get_nodes_by_id([written.id]) self.assertEqual(len(retrieved), 0)
def _create_relations(self, objects): relationCreator = RelationCreator() relationCreator.add_objects(objects) for obj in objects: left, right, up, down = relationCreator.get_relations( obj) # left = [label, properties[0]] if None != left: self._engine.create_relationship( (obj[0], obj[1]), (left[0], left[1]), (Label(self._id, 'left'), None, 1)) if None != right: self._engine.create_relationship( (obj[0], obj[1]), (right[0], right[1]), (Label(self._id, 'right'), None, 1)) if None != up: self._engine.create_relationship( (obj[0], obj[1]), (up[0], up[1]), (Label(self._id, 'up'), None, 1)) if None != down: self._engine.create_relationship( (obj[0], obj[1]), (down[0], down[1]), (Label(self._id, 'down'), None, 1))
def test_create_relationship(self): engine = GraphEngine() label1 = Label(cfg.INV_ID, 'Figure') label2 = Label(cfg.INV_ID, 'x') label3 = Label(cfg.INV_ID, 'y') label4 = Label(cfg.INV_ID, 'Right') property2 = Property(cfg.INV_ID, PropertyType.INT, label2, randint(0, 1000000), None) property1 = Property(cfg.INV_ID, PropertyType.INT, label3, randint(0, 1000000), property2) property4 = Property(cfg.INV_ID, PropertyType.INT, label2, randint(0, 1000000), None) property3 = Property(cfg.INV_ID, PropertyType.INT, label3, randint(0, 1000000), property4) property6 = Property(cfg.INV_ID, PropertyType.INT, label2, randint(0, 1000000), None) property5 = Property(cfg.INV_ID, PropertyType.INT, label3, randint(0, 1000000), property6) engine.create_node((label1, property1)) engine.create_node((label1, property3)) engine.create_node((label1, property5)) engine.create_relationship((label1, property1), (label1, property5), (label4, None, 0)) retrieved_relationship = engine.match_pattern([(label1, property1), (label1, property5)], [(label4, None, 1)]) start_node = retrieved_relationship[0].pop() end_node = retrieved_relationship[1].pop() self.assertEqual(start_node.label.value, label1.value) self.assertEqual(start_node.next_prop.value, property1.value) self.assertEqual(start_node.next_prop.next_prop.value, property2.value) self.assertEqual(end_node.label.value, label1.value) self.assertEqual(end_node.next_prop.value, property5.value) self.assertEqual(end_node.next_prop.next_prop.value, property6.value)
def execute_removing(self, query): label, values = self._parser.parse(query) label = Label(self._id, label) properties = [] for p in values: v = Property(self._id, PropertyType.STRING, label, p, None) properties.append(v) # for i in range(len(properties) - 2): # properties[i].next_prop = properties[i+1] if len(properties) > 1: properties[0].next_prop = properties[1] assert (len(values) == len(properties)) return self._engine.delete_node((label, properties[0]))
def execute_indexing(self, query): label, values = self._parser.parse(query) label = Label(self._id, label) properties = [] for p in values: v = Property(self._id, PropertyType.STRING, label, None, None) properties.append(v) # for i in range(len(properties) - 2): # properties[i].next_prop(properties[i+1]) if len(properties) > 1: properties[0].next_prop = properties[1] assert (len(values) == len(properties)) self._engine.create_index((label, properties[0]))
def test_int_property_io(self): io = Io() value3 = "I LOVE ADB3" value2 = "I LOVE ADB2" value1 = "I LOVE ADB1" prop_value = 1 label3 = Label(cfg.INV_ID, value3) label2 = Label(cfg.INV_ID, value2) label1 = Label(cfg.INV_ID, value1) property = Property(cfg.INV_ID, PropertyType.INT, label1, 1, None) property2 = Property(cfg.INV_ID, PropertyType.INT, label2, 2, property) property3 = Property(cfg.INV_ID, PropertyType.INT, label3, 3, property2) written = io.write_property(property3) retrieved = io.read_property(written.id) self.assertEqual(property3.id, retrieved.id) self.assertEqual(property3.value, retrieved.value) self.assertEqual(property3.type.value, retrieved.type.value) self.assertEqual(property3.label.value, retrieved.label.value) self.assertEqual(property3.next_prop.id, retrieved.next_prop.id)
def test_string_property_io(self): io = Io() value = "I LOVE ADB" label = Label(cfg.INV_ID, value) label = io.write_label(label) property = Property(cfg.INV_ID, PropertyType.STRING, label, value, None) written = io.write_property(property) retrieved = io.read_property(written.id) self.assertEqual(property.id, retrieved.id) self.assertEqual(property.value, retrieved.value) self.assertEqual(property.type.value, retrieved.type.value) self.assertEqual(property.label.value, retrieved.label.value) self.assertEqual(property.next_prop, retrieved.next_prop)
def test_get_nodes_io(self): io = Io() nodes = [] for i in range(0, 10): value = "Macarena" label = Label(cfg.INV_ID, value) label = io.write_label(label) node = Node(cfg.INV_ID, label, None, None) node = io.write_node(node) nodes.append(node.id) node_list = io.get_nodes_by_id(set(nodes)) for id, node in enumerate(node_list): self.assertEqual(node.id, nodes[id]) self.assertEqual(node.label.value, "Macarena")
def test_node_io(self): io = Io() value = "Graph DB is AWESOME" label = Label(cfg.INV_ID, value) prop_value = True property = Property(cfg.INV_ID, PropertyType.BOOL, label, prop_value, None) node = Node(cfg.INV_ID, label, property, cfg.INV_ID) written = io.write_node(node) retrived = io.read_node(written.id) self.assertEqual(node.id, retrived.id) self.assertEqual(node.next_prop.id, retrived.next_prop.id) self.assertEqual(node.next_prop.label.value, property.label.value) self.assertEqual(node.label.value, retrived.label.value) self.assertEqual(node.label.id, retrived.label.id)
def read_label(self, id) -> Label or None: """ Reads single label by it's id :param id: offset of label to read :return: Label unpacked """ if id > self.last_label_id: raise Exception('Label ID is out of range') label_bytes = self._read_bytes(self.labels, id, cfg.LABEL_SIZE) in_use, store_id = Unpacker.unpack_label(label_bytes) if in_use: value = self.read_store(store_id) return Label(id, value) else: return None
def execute_creation(self, queries): objects = [] for query in queries: label, node_data, types = self._parser.parse(query) label = Label(self._id, label) properties = [] for p in node_data: v = Property(self._id, PropertyType.STRING, label, p, None) properties.append(v) # for i in range(0, len(properties) - 2): # properties[i].next_prop = properties[i+1] if len(properties) > 1: properties[0].next_prop = properties[1] assert (len(node_data) == len(properties)) self._engine.create_node((label, properties[0])) objects.append([label, properties[0]]) self._create_relations(objects)
def test_multirelation_deletion(self): io = Io() value = "You spin my head right ground right ground" label = Label(cfg.INV_ID, value) label = io.write_label(label) prop_value = True property = Property(cfg.INV_ID, PropertyType.BOOL, label, prop_value, None) property = io.write_property(property) node = Node(cfg.INV_ID, label, property, None) node2 = Node(cfg.INV_ID, label, property, None) written_node1 = io.write_node(node) written_node2 = io.write_node(node2) relation1 = Relationship(cfg.INV_ID, False, written_node1, written_node2, label, property, None, None, None, None) relation2 = Relationship(cfg.INV_ID, False, written_node1, written_node2, label, property, None, None, None, None) written_rel1 = io.write_relation(relation1) written_rel2 = io.write_relation(relation2) io.del_node(written_node1.id) retrived = io.get_relations_by_id([written_rel1.id, written_rel2.id]) self.assertEqual(len(retrived), 0)
def execute_getting(self, query, checkExistence=False): if checkExistence: label, data = self._parser.parse(query) label = Label(self._id, label) properties = [] for p in data: v = Property(self._id, PropertyType.STRING, label, p, None) properties.append(v) # for i in range(len(properties) - 2): # properties[i].next_prop(properties[i+1]) if len(properties) > 1: properties[0].next_prop = properties[1] assert (len(data) == len(properties)) return self._engine.match_pattern((label, properties[0]), []) else: if "[:" in query: node_label, node_values, relations = self._parser.parse(query) node_label = Label(self._id, node_label) properties = [] for p in node_values: v = Property(self._id, PropertyType.STRING, node_label, p, None) properties.append(v) # for i in range(len(properties) - 2): # properties[i].next_prop(properties[i+1]) if len(properties) > 1: properties[0].next_prop = properties[1] assert (len(node_values) == len(properties)) nodes = [(node_label, properties[0])] relationships = [] if len(relations) > 2: direction = relations[0] label = Label(self._id, relations[1]) properties = [] for p in relations[2]: v = Property(self._id, PropertyType.STRING, label, p, None) properties.append(v) # for i in range(len(properties) - 2): # properties[i].next_prop = properties[i+1] if len(properties) > 1: properties[0].next_prop = properties[1] assert (len(relations[2]) == len(properties)) relationships.append((label, properties[0], direction)) else: direction = relations[0] label = Label(self._id, relations[1]) relationships.append((label, None, direction)) return self._engine.match_pattern(nodes, relationships) else: node_label, node_values = self._parser.parse(query) node_label = Label(self._id, node_label) properties = [] for p in node_values: v = Property(self._id, PropertyType.STRING, node_label, p, None) properties.append(v) # for i in range(len(properties) - 2): # properties[i].next_prop(properties[i+1]) if len(properties) > 1: properties[0].next_prop = properties[1] assert (len(node_values) == len(properties)) if len(properties) == 0: nodes = [(node_label, None)] else: nodes = [(node_label, properties[0])] return self._engine.match_pattern(nodes, None)