def __init__(self, size=4, json_db=None, hashfunction=None): super(HashDataBase, self).__init__() self.size = size self.container = [] self.collisions = [] self.numbers = {} self.last_names = {} for item in range(0, size): # self.container.append(BTree()) self.container.append({}) self.collisions.append(0) self.hashfunction = hashBase64 if hashfunction is None else hashfunction if json_db is not None and path.isfile(json_db): with open(json_db, "r") as database: data = json.load(database) for rid, register in data.items(): verbose("Register: {0}".format(register)) element = self.Register( name=register["name"], last_name=register["last_name"], address=register["address"], cellphone=register["cellphone"], email=register["email"], social_network=register["social_network"]) self.insert(register=element) elif json_db is not None and not path.isfile(json_db): error("{0} must be a valid json file to load the registers")
def _update_field(self, register): """Update a specific field of the register :register: TODO :returns: TODO """ status("Please select the field you want to update") valid = False while not valid: answer = input("""Please select a valid option: 1) Last name 2) Address 3) Cellphone 4) Email 5) Social Network 6) All : """) try: value = int(answer) if value < 1 or value > 6: error("Not a valid option {0}".format(value)) continue hashvalue = self.hashfunction(register.name) if value == 6: register.last_name = input("Enter last name: ") register.address = input("Enter address: ") register.cellphone = input("Enter cellphone: ") register.email = input("Enter email address: ") register.social_network = input("Enter social network: ") else: if value == 1: self.last_names[register.last_name].remove(hashvalue) register.last_name = input("enter last name: ") if register.last_name not in self.last_names: self.last_names[register.last_name] = [hashvalue] else: self.last_names[register.last_name].append( hashvalue) elif value == 2: register.address = input("Enter address: ") elif value == 3: self.numbers.pop(register.cellphone, None) register.cellphone = input("Enter cellphone: ") self.numbers[register.cellphone] = hashvalue elif value == 4: register.email = input("Enter email address: ") elif value == 5: register.social_network = input( "Enter social network: ") valid = True except Exception: error("Please select a valid option from the menu from 1 to 6") return register
def insert(self, register=None): """TODO: Docstring for insert. :register: TODO :returns: TODO """ if register is None: valid = False while not valid: name = input("Enter name: ") last_name = input("Enter last name: ") address = input("Enter address: ") cellphone = input("Enter cellphone: ") if cellphone in self.numbers: error("This cellphone is already in use") continue valid = True email = input("Enter email address: ") social_network = input("Enter social network: ") register = self.Register(name, last_name, address, cellphone, email, social_network) rc = False start = time() hashvalue = self.hashfunction(register.name) isEmpty = False # TODO: This must be changed for the tree if len(self.container[hashvalue]) == 0: isEmpty = True # TODO: This must be changed for the tree self.container[hashvalue][register.name] = register self.numbers[register.cellphone] = hashvalue if register.last_name not in self.last_names: self.last_names[register.last_name] = [hashvalue] else: self.last_names[register.last_name].append(hashvalue) if not isEmpty: self.collisions[hashvalue] += 1 verbose("Collisions in container {0}: {1}".format( hashvalue, self.collisions[hashvalue])) rc = True status("Register inserted") end = time() verbose("Insertion time {0}".format(end - start)) return rc
def main(): """Main CLI function :returns: TODO """ global debug_mode global start_time cli_args = __parse_arguments() if cli_args.version: status("Current version {0}".format(__version__)) return 0 messages.debug_mode = cli_args.verbose messages.quiet = cli_args.quiet messages.logger = cli_args.logger if cli_args.hash == 1: hashfunction = hashAscii else: hashfunction = hashBase64 verbose("Hash function {0}".format(repr(hashfunction.__name__))) action = "" table = HashDataBase(hashfunction=hashfunction, json_db=cli_args.json) # While True is always a bad idea while action.upper() != "E": action = input(MAIN_MENU) if action == "1": table.insert() elif action == "2": result = table.search() if result is not None and len(result) == 0: status("Register: {0}".format(result)) elif result is not None and len(result) > 0: for item in result: status("Register: {0}".format(item)) else: error("Element was not found") elif action == "3": table.update() elif action == "4": table.delete() elif action == "5": for item in table.container: for name, register in item.items(): status("Register: {0}".format(register)) elif action.upper() != "E": status("Sin acción en {action}".format(action=action))
def delete(self, register=None, name=None, last_name=None, cellphone=None): """TODO: Docstring for insert. :register: TODO :returns: TODO """ selected_type = -1 if register is None and name is None and last_name is None and cellphone is None: parameter, selected_type = self._select_search_type() elif register is not None: parameter = register.name selected_type = 0 elif name is not None: parameter = name selected_type = 0 elif last_name is not None: parameter = last_name selected_type = 1 elif cellphone is not None: parameter = cellphone selected_type = 2 rc = False start = time() if selected_type == 0: register = self.search(name=parameter) elif selected_type == 1: register = self.search(last_name=parameter) elif selected_type == 2: register = self.search(cellphone=parameter) if register is not None: # Register is not None so if its len is 0 then is just one register hashvalue = self.hashfunction(register.name) if len(register) == 0: self._delete_register(register, hashvalue) else: for item in register: self._delete_register(item, hashvalue) else: error("{0} could not be deleted".format(parameter)) end = time() verbose("Deletion time {0}".format(end - start)) return rc
def update(self, register=None, name=None, last_name=None, cellphone=None): """TODO: Docstring for insert. :register: TODO :returns: TODO """ selected_type = -1 if register is None and name is None and last_name is None and cellphone is None: parameter, selected_type = self._select_search_type() elif register is not None: parameter = register.name selected_type = 0 elif name is not None: parameter = name selected_type = 0 elif last_name is not None: parameter = last_name selected_type = 1 elif cellphone is not None: parameter = cellphone selected_type = 2 rc = False start = time() hashvalue = self.hashfunction(parameter, selected_type) # register = self.container[hashvalue].search(parameter, selected_type) if parameter in self.container[hashvalue]: register = self.container[hashvalue][parameter] register = self._update_field(register) self.container[hashvalue][parameter] = register status("Register updated") else: # if register is None: error("{0} doesn't exists".format(parameter, selected_type)) # else: # pass end = time() verbose("Update time {0}".format(end - start)) return rc
def _select_search_type(self): """TODO: Docstring for _select_search_type. :returns: TODO """ selection = "" types = ["Name", "Last name", "Cellphone"] while selection != "1" and selection != "2" and selection != "3": selection = input("""Please select an option: 1) {0} 2) {1} 3) {2} : """.format(types[0], types[1], types[2])) if selection != "1" and selection != "2" and selection != "3": error("Please select a valid option {0}".format(selection)) search_element = input("Enter the {0}: ".format(types[int(selection) - 1])) return (search_element, int(selection) - 1)
def search(self, register=None, name=None, last_name=None, cellphone=None): """TODO: Docstring for insert. :register: TODO :returns: TODO """ selected_type = -1 if register is None and name is None and last_name is None and cellphone is None: parameter, selected_type = self._select_search_type() elif register is not None and type(register) is self.Register: parameter = register.name selected_type = 0 elif name is not None: parameter = name selected_type = 0 elif last_name is not None: parameter = last_name selected_type = 1 elif cellphone is not None: parameter = cellphone selected_type = 2 else: # We fall here if register is not None and is not a Register type raise Exception("Unknown type {0}".format(repr(register))) start = time() register = None verbose("Searching for: {0}".format(parameter)) if selected_type == 0: hashvalue = self.hashfunction(parameter) # TODO: This must be changed for the tree verbose("Name {0}".format(parameter)) if parameter in self.container[hashvalue]: register = self.container[hashvalue][parameter] else: error("The register {0} doesn't exists".format(parameter)) elif selected_type == 1: if parameter in self.last_names: verbose("Last name {0}".format(parameter)) containers = self.last_names[parameter] verbose("List of containers {0}".format(containers)) # Since last names are not unic, the dictionary has a list with all the containers with the last name register = [] for container in containers: # TODO: This must be changed for the tree for key, value in self.container[container].items(): if value.last_name == parameter: register.append( self.container[container][parameter]) # status("Please select a register") else: error("The register {0} doesn't exists".format(parameter)) elif selected_type == 2: if parameter in self.numbers: verbose("Number to find {0}".format(parameter)) # TODO: This must be changed for the tree container = self.numbers[parameter] for key, value in self.container[container].items(): if value.cellphone == parameter: register = self.container[container][value.name] break else: error("The register {0} doesn't exists".format(parameter)) else: raise Exception("Not a valid option {0}".format(selected_type)) # register = self.container[hashvalue].search(parameter, selected_type) # if register is not None: # return register # error("{0} doesn't exists".format(parameter, selected_type)) end = time() verbose("Search time {0}".format(end - start)) return register