diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py index 097a5095..586cc92d 100644 --- a/src/class_sqlThread.py +++ b/src/class_sqlThread.py @@ -1,7 +1,5 @@ -# pylint: disable=protected-access, too-many-locals, too-many-branches, too-many-statements - """ -sqlThread is defined here +SQLThread is defined here """ import logging @@ -38,87 +36,80 @@ class BitmessageDB(object): self.conn = None self.cur = None self._connection_build() - self.root_path = os.path.dirname(os.path.dirname(__file__)) def _connection_build(self): self._connection_build_internal('messages.dat', False) - def _connection_build_internal(self, file_name="messages.dat", memory=False): - """ - Stablish SQL connection - """ - if memory: - self.conn = sqlite3.connect(':memory:') - else: - self.conn = sqlite3.connect(os.path.join(state.appdata + file_name)) + def _connection_build_internal( + self, file_name="messages.dat", memory=False + ): + """Establish SQL connection""" + self.conn = sqlite3.connect( + ':memory:' if memory else os.path.join(state.appdata, file_name)) self.conn.text_factory = str self.cur = self.conn.cursor() - self.cur.execute('PRAGMA secure_delete = true') + self.cur.execute("PRAGMA secure_delete = true") def __get_current_settings_version(self): - """ - Get current setting Version - """ - query = "SELECT value FROM settings WHERE key='version'" - parameters = () - self.cur.execute(query, parameters) + """Get current setting Version""" + self.cur.execute( + "SELECT value FROM settings WHERE key='version'") try: return int(self.cur.fetchall()[0][0]) except (ValueError, IndexError): return 0 def _upgrade_one_level_sql_statement(self, file_name): - """ - Upgrade database versions with applying sql scripts - """ + """Upgrade database versions with applying sql scripts""" self.initialize_sql("init_version_{}".format(file_name)) def initialize_sql(self, file_name): - """ - Initializing sql - """ + """Initializing sql""" try: - with open(os.path.join(self.root_path, "pybitmessage/sql/{}.sql".format(file_name))) as sql_file: + with open(os.path.join( + paths.codePath(), 'sql', '{}.sql'.format(file_name)) + ) as sql_file: sql_as_string = sql_file.read() self.cur.executescript(sql_as_string) return True except OSError as err: - logger.debug('The file is missing. Error message: %s\n', str(err)) + logger.debug('The file is missing. Error message: %s\n', + str(err)) except IOError as err: logger.debug( - 'ERROR trying to initialize database. Error message: %s\n', str(err)) + 'ERROR trying to initialize database. Error message: %s\n', + str(err)) except sqlite3.Error as err: logger.error(err) except Exception as err: logger.debug( - 'ERROR trying to initialize database. Error message: %s\n', str(err)) + 'ERROR trying to initialize database. Error message: %s\n', + str(err)) return False @property def sql_schema_version(self): - """ - Getter for get current schema version - """ + """Getter for get current schema version""" return self.__get_current_settings_version() def upgrade_to_latest(self): - """ - Initialize upgrade level - """ - - query = "SELECT name FROM sqlite_master WHERE type='table' AND name='settings'" - parameters = () - self.cur.execute(query, parameters) - if self.cur.fetchall() == []: + """Initialize upgrade level""" + self.cur.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name='settings'") + if not self.cur.fetchall(): # The settings table doesn't exist. We need to make it. logger.debug( "In messages.dat database, creating new 'settings' table.") self.cur.execute( - '''CREATE TABLE settings (key text, value blob, UNIQUE(key) ON CONFLICT REPLACE)''') - self.cur.execute('''INSERT INTO settings VALUES('version','1')''') - self.cur.execute('''INSERT INTO settings VALUES('lastvacuumtime',?)''', ( - int(time.time()),)) - logger.debug('In messages.dat database, removing an obsolete field from the pubkeys table.') + "CREATE TABLE settings (key text, value blob, UNIQUE(key)" + " ON CONFLICT REPLACE)") + self.cur.execute("INSERT INTO settings VALUES('version','1')") + self.cur.execute( + "INSERT INTO settings VALUES('lastvacuumtime',?)", + (int(time.time()),)) + logger.debug( + 'In messages.dat database, removing an obsolete field' + 'from the pubkeys table.') # initiate sql file self.initialize_sql("upg_sc_if_old_ver_1") @@ -133,71 +124,65 @@ class BitmessageDB(object): self.conn.commit() def check_columns_can_store_binary_null(self): - """ - Check if sqlite can store binary zeros. - """ + """Check if sqlite can store binary zeros.""" try: testpayload = '\x00\x00' t = ('1234', 1, testpayload, '12345678', 'no') - self.cur.execute('''INSERT INTO pubkeys VALUES(?,?,?,?,?)''', t) + self.cur.execute("INSERT INTO pubkeys VALUES(?,?,?,?,?)", t) self.conn.commit() self.cur.execute( - '''SELECT transmitdata FROM pubkeys WHERE address='1234' ''') - queryreturn = self.cur.fetchall() - for row in queryreturn: - transmitdata, = row - self.cur.execute('''DELETE FROM pubkeys WHERE address='1234' ''') + "SELECT transmitdata FROM pubkeys WHERE address='1234' ") + transmitdata = self.cur.fetchall()[-1][0] + self.cur.execute("DELETE FROM pubkeys WHERE address='1234' ") self.conn.commit() - if transmitdata == '': + if transmitdata != testpayload: logger.fatal( - 'Problem: The version of SQLite you have cannot store Null values.' - ' Please download and install the latest revision of your version of Python' - ' (for example, the latest Python 2.7 revision) and try again.\n') + 'Problem: The version of SQLite you have cannot store Null' + 'values. Please download and install the latest revision' + 'of your version of Python (for example, the latest ' + 'Python 2.7 revision) and try again.\n') logger.fatal( 'PyBitmessage will now exit very abruptly.' - ' You may now see threading errors related to this abrupt exit' - ' but the problem you need to solve is related to SQLite.\n\n') - os._exit(0) + ' You may now see threading errors related to this abrupt' + 'exit but the problem you need to solve is related to' + 'SQLite.\n\n') + os._exit(1) except Exception as err: - sqlThread().error_handler(err, 'null value test') + sqlThread.error_handler(err, 'null value test') - def check_vacuum(self): # pylint: disable=too-many-locals, too-many-branches, too-many-statements, - # Redefinition-of-parameters-type-from-tuple-to-str, R0204, line-too-long, E501 + def check_vacuum(self): """ - Check vacuum and apply sql queries for different different conditions. - Let us check to see the last time we vaccumed the messages.dat file. - If it has been more than a month let's do it now. + Check vacuum and apply sql queries for different conditions. + Let us check to see the last time we vaccumed the messages.dat file. + If it has been more than a month let's do it now. """ - - query = "SELECT value FROM settings WHERE key='lastvacuumtime'" - parameters = () - self.cur.execute(query, parameters) - queryreturn = self.cur.fetchall() - for row in queryreturn: - value, = row - if int(value) < int(time.time()) - 86400: - logger.info('It has been a long time since the messages.dat file has been vacuumed. Vacuuming now...') - try: - self.cur.execute(''' VACUUM ''') - except Exception as err: - sqlThread().error_handler(err, 'VACUUM') - query = "update settings set value=? WHERE key='lastvacuumtime'" - parameters = (int(time.time()),) - self.cur.execute(query, parameters) + self.cur.execute( + "SELECT value FROM settings WHERE key='lastvacuumtime'") + try: + date = self.cur.fetchall()[-1][0] + except IndexError: + return + if int(date) < int(time.time()) - 86400: + logger.info( + 'It has been a long time since the messages.dat file' + ' has been vacuumed. Vacuuming now...') + try: + self.cur.execute(''' VACUUM ''') + except Exception as err: + sqlThread.error_handler(err, 'VACUUM') + self.cur.execute( + "UPDATE settings SET value=? WHERE key='lastvacuumtime'", + (int(time.time()),)) def upgrade_config_parser_setting_version(self, settingsversion): - """ - Upgrade schema with respect setting version - """ + """Upgrade schema with respect setting version""" self.initialize_sql("config_setting_ver_{}".format(settingsversion)) def initialize_schema(self): - """ - Initialize DB schema - """ + """Initialize DB schema""" try: - inbox_exists = list(self.cur.execute('PRAGMA table_info(inbox)')) + inbox_exists = list(self.cur.execute("PRAGMA table_info(inbox)")) if not inbox_exists: self.initialize_sql("initialize_schema") self.conn.commit() @@ -206,13 +191,13 @@ class BitmessageDB(object): if str(err) == 'table inbox already exists': logger.debug('Database file already exists.') else: - os._exit( - 'ERROR trying to create database file (message.dat). Error message: %s\n' % str(err)) + logger.fatal( + 'Error trying to create database file (message.dat).' + ' Error message: %s\n', str(err)) + os._exit(1) def create_sql_function(self): - """ - Apply create_function to DB - """ + """Apply create_function to DB""" try: self.conn.create_function("enaddr", 3, func=encodeAddress, deterministic=True) except (TypeError, sqlite3.NotSupportedError) as err: @@ -248,10 +233,10 @@ class sqlThread(threading.Thread): def upgrade_config_setting_version(self): """ - upgrade config parser setting version. - If the settings version is equal to 2 or 3 then the - sqlThread will modify the pubkeys table and change - the settings version to 4. + upgrade config parser setting version. + If the settings version is equal to 2 or 3 then the + sqlThread will modify the pubkeys table and change + the settings version to 4. """ while self.sql_config_settings_version < self.max_setting_level: self.db.upgrade_config_parser_setting_version(self.sql_config_settings_version) @@ -259,9 +244,7 @@ class sqlThread(threading.Thread): @staticmethod def error_handler(err, command, query=None, parameters=None): - """ - Common error handler - """ + """Common error handler""" if str(err) == 'database or disk is full': logger.fatal( "(While %s) Alert: Your disk or data storage volume is full. sqlThread will now exit.", command @@ -290,18 +273,14 @@ class sqlThread(threading.Thread): os._exit(0) def is_query_commit(self): - """ - When query == 'commit' - """ + """When query == 'commit'""" try: self.db.conn.commit() except Exception as err: self.error_handler(err, 'committing') def is_query_movemessagstoprog(self): - """ - When query == 'movemessagstoprogs' - """ + """When query == 'movemessagstoprogs'""" logger.debug('the sqlThread is moving the messages.dat file to the local program directory.') try: self.db.conn.commit() @@ -315,9 +294,7 @@ class sqlThread(threading.Thread): self.db.cur = self.db.conn.cursor() def is_query_deleteandvacuume(self): - """ - When query == 'deleteandvacuume' - """ + """When query == 'deleteandvacuume'""" try: self.db.cur.execute(''' VACUUM ''') except Exception as err: @@ -327,9 +304,7 @@ class sqlThread(threading.Thread): self.db.conn.commit() def is_query_other(self, query): - """ - When the query can be default or other ' - """ + """When the query can be default or other '""" parameters = helper_sql.sqlSubmitQueue.get() try: self.db.cur.execute(query, parameters) @@ -339,9 +314,7 @@ class sqlThread(threading.Thread): self.error_handler(err, 'cur.execute', query, parameters) def is_query_movemessagestoappdata(self): - """ - When query == 'movemessagestoappdata' - """ + """When query == 'movemessagestoappdata'""" logger.debug('the sqlThread is moving the messages.dat file to the Appdata folder.') try: self.db.conn.commit() @@ -355,16 +328,12 @@ class sqlThread(threading.Thread): self.db.cur = self.db.conn.cursor() def is_query_exit(self): - """ - When query == 'exit' - """ + """When query == 'exit'""" self.db.conn.close() logger.info('sqlThread exiting gracefully.') def loop_queue(self): - """ - Looping queue and process them - """ + """Looping queue and process them""" query = helper_sql.sqlSubmitQueue.get() if query == 'commit': self.is_query_commit() @@ -416,9 +385,8 @@ class sqlThread(threading.Thread): class TestDB(BitmessageDB): - """ - Database connection build for test e - """ + """Database connection build for test e""" + def _connection_build(self): self._connection_build_internal("memory", True) return self.conn, self.cur diff --git a/src/tests/test_sqlthread.py b/src/tests/test_sqlthread.py index 8cbf36c6..e61996ae 100644 --- a/src/tests/test_sqlthread.py +++ b/src/tests/test_sqlthread.py @@ -47,9 +47,7 @@ class TestFnBitmessageDB(TestSqlBase, unittest.TestCase): # pylint: disable=pro """ Test case for Sql function""" def setUp(self): - """ - setup for test case - """ + """setup for test case""" self._setup_db() def test_create_function(self):