class DBAccessor: def __init__(self): self.db = None self.image_table = None self.tree_table = None self.history_table = None def connect(self, region=None, aws_access_key_id=None, aws_secret_access_key=None, conn=None): self.db = DynamoDB() self.db.connect(region, aws_access_key_id, aws_secret_access_key, conn) def table_init(self, image_table_name, tree_table_name, history_table_name): self.image_table = self.db.get_table(image_table_name) self.tree_table = self.db.get_table(tree_table_name) self.history_table = self.db.get_table(history_table_name) def _table_existence_check(self, table): if not table: raise ValueError("Table not found: table init is required") return table def add_or_update_history(self, name, version, node_attrs): self._table_existence_check(self.history_table) item = self.db.get_item(self.history_table, name, range_key=version) if item: for attr in node_attrs.keys(): item[attr] = node_attrs[attr] else: item = self.db.add_item(self.history_table, name, node_attrs, range_key=version) self.db.commit(item) def add_or_update_image(self, name, parent_name, version, sha1, comment, create_date, committer, mail=" ", security_patch=" "): self._table_existence_check(self.image_table) content = {'version': version, 'commit_sha1': sha1, 'comment': comment, 'create_date': create_date, 'committer': committer, 'committer_mail': mail, 'security_patch': security_patch, 'parent_name': parent_name} item = self.db.get_item(self.image_table, name) if item: for attr in content.keys(): item[attr] = content[attr] else: item = self.db.add_item(self.image_table, name, content) self.db.commit(item) self.add_or_update_history(name, version, content) def _update_children_list(self, item, my_name): if type(item['children']) is set: children_list = list(item['children']) else: # empty originally - dynamodb doesn't support empty set or string as value children_list = list() if my_name not in children_list: children_list.append(my_name) item['children'] = set(children_list) def add_or_update_tree_node(self, my_name, parent_name): self._table_existence_check(self.tree_table) item = self.db.get_item(self.tree_table, parent_name) # update parent list if item: self._update_children_list(item, my_name) else: # check root item = self.db.get_item(self.tree_table, "root") if not item: item = self.db.add_item(self.tree_table, "root", {'children': set([my_name]), 'parent_name': "root"}) self._update_children_list(item, my_name) # add my node my_item = self.db.get_item(self.tree_table, my_name) if not my_item: my_item = self.db.add_item(self.tree_table, my_name, {'children': "NoChild", 'parent_name': parent_name}) self.db.commit(my_item) self.db.commit(item) def get_tree_children(self, name): children_list = list() parent_node = self.db.get_item(self.tree_table, name) if parent_node: if type(parent_node['children']) is set: children_list = list(parent_node['children']) else: pass return children_list def is_leaf(self, name): node = self.db.get_item(self.tree_table, name) is_leaf = True if type(node['children']) is set: is_leaf = False return is_leaf def get_image_item(self, name): return self.db.get_item(self.image_table, name) def exist_image(self, name): return self.db.get_item(self.image_table, name) def is_root(self, name): root = False item = self.db.get_item(self.image_table, name) if not item: root = True return root def get_version(self, name): version = None item = self.db.get_item(self.image_table, name) if item: version = item['version'] return version def _get_attr_by_item(self, item, attr): return item[attr] if attr in item.keys() else None def get_node_history(self, node_name, current_version): node_history = list() for version in reversed(range(1, int(current_version) + 1)): item = self.db.get_item(self.history_table, node_name, str(version).zfill(4)) if item: node_history.append(item) return node_history def get_all_image_name(self): images = list() for item in self.image_table.scan(): images.append(item['name']) return images
def connect(self, region=None, aws_access_key_id=None, aws_secret_access_key=None, conn=None): self.db = DynamoDB() self.db.connect(region, aws_access_key_id, aws_secret_access_key, conn)