Example #1
0
    def test_import_database_type_0(self):
        """
        test import database (type 0) to current database

        :return:
        """
        self._set_text_logger()

        # clean test directory
        if os.path.exists(self.output_test_path + self.TEST_DB_FILENAME_OLD):
            os.remove(self.output_test_path + self.TEST_DB_FILENAME_OLD)

        # create old db with structure type 0
        self.conn = sqlite3.connect(self.output_test_path +
                                    self.TEST_DB_FILENAME_OLD)
        self.cursor = self.conn.cursor()
        self.cursor.execute("""CREATE TABLE history 
            (
                command  TEXT,
                counter BIGINT,
                description TEXT,
                tags TEXT
            )
            """)
        # add data with old structure (type 0)
        self.cursor.execute("INSERT INTO history values (?, ?, ?, ?)",
                            ("test1", 2, "description", "#tag1#tag2#tag3"))
        self.cursor.execute("INSERT INTO history values (?, ?, ?, ?)",
                            ("test2", 4, "only description", ""))
        self.cursor.execute("INSERT INTO history values (?, ?, ?, ?)",
                            ("test3", 4, "", "#only-tags"))
        self.conn.commit()
        self.conn.close()

        # initialize new db
        db = DatabaseSQLite(self.output_test_path,
                            self.TEST_DB_FILENAME, [],
                            delete_all_data_from_db=True)
        result_import = db.import_external_database(self.output_test_path +
                                                    self.TEST_DB_FILENAME_OLD)

        # check if the number of element matches
        self.assertEqual(result_import, 3)
        # test search for command
        res = db.get_last_n_filtered_elements(generic_filters=["test1"])
        self.assertEqual(len(res), 1)
        # test search for tag
        res = db.get_last_n_filtered_elements(generic_filters=["only-tags"])
        self.assertEqual(len(res), 1)
        # test search for description
        res = db.get_last_n_filtered_elements(
            generic_filters=["only description"])
        self.assertEqual(len(res), 1)
Example #2
0
    def test_import_not_existing_database(self):
        # clean test directory
        if os.path.exists(self.output_test_path + self.TEST_DB_FILENAME_OLD):
            os.remove(self.output_test_path + self.TEST_DB_FILENAME_OLD)

        db = DatabaseSQLite(self.output_test_path,
                            self.TEST_DB_FILENAME,
                            old_db_relative_paths=None,
                            delete_all_data_from_db=True)
        result_import = db.import_external_database(self.output_test_path +
                                                    self.TEST_DB_FILENAME_OLD +
                                                    "")
        self.assertEqual(result_import, -1)
Example #3
0
    def test_import_database_type_1(self):
        """
        test import database (type 1) to current database

        :return:
        """
        self._set_text_logger()

        # clean test directory
        if os.path.exists(self.output_test_path + self.TEST_DB_FILENAME_OLD):
            os.remove(self.output_test_path + self.TEST_DB_FILENAME_OLD)

        # create old db with structure type 0
        self.conn = sqlite3.connect(self.output_test_path +
                                    self.TEST_DB_FILENAME_OLD)
        self.cursor = self.conn.cursor()
        self.cursor.execute("""CREATE TABLE history 
            (
                command  TEXT,
                description TEXT,
                tags TEXT,
                counter INTEGER,
                date INTEGER,
                synced TINYINT
            )
            """)
        # add data with old structure (type 0)
        self.cursor.execute(
            "INSERT INTO history values (?, ?, ?, ?, ?, ?)",
            ("test1", "description", "ǁtag1ǁtag2ǁtag3", 2, 1551202801, 0))
        self.cursor.execute(
            "INSERT INTO history values (?, ?, ?, ?, ?, ?)",
            ("test2", "only description", "", 4, int(time.time()), 0))
        self.cursor.execute(
            "INSERT INTO history values (?, ?, ?, ?, ?, ?)",
            ("test3", "", "ǁonly-tags", 4, int(time.time()), 0))
        self.cursor.execute(
            "INSERT INTO history values (?, ?, ?, ?, ?, ?)",
            (
                "test4-existing-item",
                "test4-new",
                "ǁtag4-new",
                4,
                1551202801,  # note: this is older than the item in the local database
                0))
        self.conn.commit()
        self.conn.close()

        # initialize new db
        db = DatabaseSQLite(self.output_test_path,
                            self.TEST_DB_FILENAME, [],
                            delete_all_data_from_db=True)
        # add element to create a merge conflict
        db.add_element("test4-existing-item",
                       "test4-old", ["tag4-old"],
                       7,
                       date=1551202920,
                       synced=0)
        res = db.get_column_field("test4-existing-item", "rowid")
        item_local_rowid = int(res)

        # import the database twice (this should give the same result as importing it once)
        db.import_external_database(self.output_test_path +
                                    self.TEST_DB_FILENAME_OLD)
        result_import = db.import_external_database(self.output_test_path +
                                                    self.TEST_DB_FILENAME_OLD)

        # check if the number of element matches
        self.assertEqual(result_import, 4)
        # test search for command
        res = db.get_last_n_filtered_elements(generic_filters=["test1"])
        self.assertEqual(len(res), 1)
        # test search for tag
        res = db.get_last_n_filtered_elements(generic_filters=["only-tags"])
        self.assertEqual(len(res), 1)
        # test search for description
        res = db.get_last_n_filtered_elements(
            generic_filters=["only description"])
        self.assertEqual(len(res), 1)
        res = db.get_last_n_filtered_elements(
            tags_filters=["tag4-old", "tag4-new"])
        self.assertEqual(len(res), 1)

        # check counter value
        res = db.get_column_field("test1", "counter")
        self.assertEqual(int(res), 2)

        res = db.get_column_field("test4-existing-item", "counter")
        self.assertEqual(int(res), 7)  # note: the kept value is the local one

        # check date value
        res = db.get_column_field("test1", "date")
        self.assertEqual(int(res), 1551202801)

        res = db.get_column_field("test4-existing-item", "date")
        self.assertEqual(int(res),
                         1551202920)  # note: the kept value is the newest one

        # check if row id value is kept the same
        res = db.get_column_field("test4-existing-item", "rowid")
        self.assertEqual(int(res), item_local_rowid)
Example #4
0
class DataManager(object):
    """
	Class use to manage data and interact with the database
	"""
    MIN_LENGTH_SEARCH_FOR_DESC = 3

    class OPTION:
        INDEX_CMD = 0
        INDEX_DESC = 1
        INDEX_TAGS = 2

    DATABASE_MODE_SQLITE = 0
    DATABASE_MODE_MYSQL = 1

    DUMMY_INPUT_DATA = Input(False, "", [])

    def __init__(self,
                 project_path,
                 db_relative_path,
                 old_db_relative_paths,
                 mode=DATABASE_MODE_SQLITE):
        self.last_search = None
        self.filtered_data = None
        if mode == self.DATABASE_MODE_SQLITE:
            from database.databaseSQLite import DatabaseSQLite
            self.database = DatabaseSQLite(project_path, db_relative_path,
                                           old_db_relative_paths)
        else:
            logging.error("database mode not selected")
        # set dummy as default
        self.search_filters = self.DUMMY_INPUT_DATA
        # define special chars based on the chosen database
        self.forbidden_chars = ['\n', '\r', self.database.CHAR_DIVIDER]

    def get_search_filters(self):
        """
		return parsed filters calculated in the last "filter" call

		:return: [cmd_filter, description_filter, array_tag_filter]
		"""
        return self.search_filters

    def get_forbidden_chars(self):
        """
		the database uses a special chars and these cannot be use as input to avoid ambiguity
		:return:	array of forbidden chars
		"""
        return self.forbidden_chars

    def filter(self, search, n=100):
        """
		get filtered commands array
		:param n: 		max number of returned rows
		:param search:	filter text
		:return:		array with [cmd, description, tags array, bool advanced]
		"""
        # put all to lower case
        search = search.lower()

        # parse input search text
        input_data = InputParser.parse_input(search, is_search_cmd=True)

        if input_data:
            self.search_filters = input_data

            if not input_data.is_advanced():
                filtered_data = self.database.get_last_n_filtered_elements(
                    generic_filters=input_data.get_main_words(), n=n)
            else:
                filtered_data = self.database.get_last_n_filtered_elements(
                    generic_filters=input_data.get_main_words(),
                    description_filters=input_data.get_description_words(
                        strict=True),
                    tags_filters=input_data.get_tags(strict=True),
                    n=n)
            if filtered_data:
                return filtered_data
            else:
                return []
        else:
            # the string inserted does not match the regex and a dummy response is returned
            self.search_filters = self.DUMMY_INPUT_DATA
            return []

    def add_new_element(self, cmd, description, tags):
        """
		add a new command to db
		:param cmd:			bash command
		:param description:	description (or none)
		:param tags:		list of tags (or none)
		:return:			true if value has been stored correctly
		"""
        return self.database.add_element(cmd, description, tags)

    def update_command(self, cmd, new_cmd):
        """
		update command string of a command
		:param cmd:
		:param new_cmd:
		:return:
		"""
        return self.database.update_command_field(cmd, new_cmd)

    def update_tags(self, cmd, tags):
        """
		update tag list of a command
		:param cmd:		command to update
		:param tags:	new tag array
		:return:		True is the database was successfully changed, False otherwise
		"""
        return self.database.update_tags_field(cmd, tags)

    def update_description(self, cmd, description):
        """
		update description of a command
		:param cmd:			command to update
		:param description: new description
		:return:			True is the database was successfully changed, False otherwise
		"""
        return self.database.update_description_field(cmd, description)

    def update_element_order(self, cmd):
        """
		after a command was selected update the order
		:param cmd:		command to update
		:return:		True is the database was successfully changed, False otherwise
		"""
        return self.database.update_position_element(cmd)

    def delete_element(self, cmd):
        """
		delete a command from db
		:param cmd:		cmd to delete
		:return:		True is the database was successfully changed, False otherwise
		"""
        return self.database.remove_element(cmd)

    def get_data_from_db(self):
        """
		this is a SLOW method to call as less as possible
		:param self:
		:return:
		"""
        return self.database.get_all_data()

    def import_data_to_db(self, db_abs_path):
        """
		import data from old or backed up database file
		:param db_abs_path:	database absolute path
		:return:
		"""
        return self.database.import_external_database(db_abs_path)