create separate method for each currentVersion of class_sqlThread module #1715

Open
navjotcis wants to merge 2 commits from navjotcis/bug-fixes18 into v0.6
Showing only changes of commit 74188cfbf4 - Show all commits

View File

@ -20,14 +20,21 @@ from debug import logger
# pylint: disable=attribute-defined-outside-init,protected-access # pylint: disable=attribute-defined-outside-init,protected-access
def execute_setting_table(func): upgrade_dict = {}
"""this method is used as a decorator"""
def inner(*args, **kwars):
reference = args[0] def db_upgrade(*args, **kwargs): # pylint: disable=unused-argument
item = '''SELECT value FROM settings WHERE key='version';''' """upgrade the migration"""
parameters = '' version_dict = kwargs
PeterSurda commented 2021-01-21 09:30:59 +01:00 (Migrated from github.com)
Review

this looks weird

this looks weird
reference.cur.execute(item, parameters)
func(reference) def inner(func):
"""this is inner method"""
upgrade_dict.update(version_dict)
def wrapped(*args):
"""used for calling main method"""
func(*args)
return wrapped
return inner return inner
@ -38,8 +45,10 @@ class sqlThread(threading.Thread):
threading.Thread.__init__(self, name="SQL") threading.Thread.__init__(self, name="SQL")
def update_sent(self): def update_sent(self):
# After code refactoring, the possible status values for sent messages """
# have changed. After code refactoring, the possible status values for sent messages
have changed.
"""
self.cur.execute( self.cur.execute(
'''update sent set status='doingmsgpow' where status='doingpow' ''') '''update sent set status='doingmsgpow' where status='doingpow' ''')
self.cur.execute( self.cur.execute(
@ -50,209 +59,233 @@ class sqlThread(threading.Thread):
'''update sent set status='broadcastqueued' where status='broadcastpending' ''') '''update sent set status='broadcastqueued' where status='broadcastpending' ''')
self.conn.commit() self.conn.commit()
@execute_setting_table def inventory_upgrade(self):
def versionTwo(self): """Adding a new column to the inventory table to store tags."""
# Let's get rid of the first20bytesofencryptedmessage field in logger.debug(
# the inventory table. 'In messages.dat database, adding tag field to'
if int(self.cur.fetchall()[0][0]) == 2: ' the inventory table.')
logger.debug( item = '''ALTER TABLE inventory ADD tag blob DEFAULT '' '''
'In messages.dat database, removing an obsolete field from' param = ''
' the inventory table.') self.cur.execute(item, param)
self.cur.execute( item = '''update settings set value=? WHERE key='version';'''
'''CREATE TEMPORARY TABLE inventory_backup''' parameters = (4,)
'''(hash blob, objecttype text, streamnumber int, payload blob,''' self.cur.execute(item, parameters)
''' receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE);''')
self.cur.execute(
'''INSERT INTO inventory_backup SELECT hash, objecttype, streamnumber, payload, receivedtime'''
''' FROM inventory;''')
self.cur.execute('''DROP TABLE inventory''')
self.cur.execute(
'''CREATE TABLE inventory'''
''' (hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer,'''
''' UNIQUE(hash) ON CONFLICT REPLACE)''')
self.cur.execute(
'''INSERT INTO inventory SELECT hash, objecttype, streamnumber, payload, receivedtime'''
''' FROM inventory_backup;''')
self.cur.execute('''DROP TABLE inventory_backup;''')
item = '''update settings set value=? WHERE key='version';'''
parameters = (3,)
self.cur.execute(item, parameters)
@execute_setting_table @db_upgrade(version_one=1)
def versionThree(self): def version_one(self):
# Add a new column to the inventory table to store tags. """version_one for upgrading inventory"""
currentVersion = int(self.cur.fetchall()[0][0]) self.inventory_upgrade()
if currentVersion == 1 or currentVersion == 3:
logger.debug(
'In messages.dat database, adding tag field to'
' the inventory table.')
item = '''ALTER TABLE inventory ADD tag blob DEFAULT '' '''
parameters = ''
self.cur.execute(item, parameters)
item = '''update settings set value=? WHERE key='version';'''
parameters = (4,)
self.cur.execute(item, parameters)
@execute_setting_table @db_upgrade(version_two=2)
def versionFour(self): def version_two(self):
# Add a new column to the pubkeys table to store the address version. """
# We're going to trash all of our pubkeys and let them be redownloaded. method for getting rid of the first20bytesofencryptedmessage field in
currentVersion = int(self.cur.fetchall()[0][0]) the inventory table.
if currentVersion == 4: """
self.cur.execute('''DROP TABLE pubkeys''') logger.debug(
self.cur.execute( 'In messages.dat database, removing an obsolete field from'
'''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int,''' ' the inventory table.')
'''usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''') self.cur.execute(
self.cur.execute( '''CREATE TEMPORARY TABLE inventory_backup'''
'''delete from inventory where objecttype = 'pubkey';''') '''(hash blob, objecttype text, streamnumber int, payload blob,'''
item = '''update settings set value=? WHERE key='version';''' ''' receivedtime integer, UNIQUE(hash) ON CONFLICT REPLACE);''')
parameters = (5,) self.cur.execute(
self.cur.execute(item, parameters) '''INSERT INTO inventory_backup SELECT hash, objecttype, streamnumber, payload, receivedtime'''
''' FROM inventory;''')
self.cur.execute('''DROP TABLE inventory''')
self.cur.execute(
'''CREATE TABLE inventory'''
''' (hash blob, objecttype text, streamnumber int, payload blob, receivedtime integer,'''
''' UNIQUE(hash) ON CONFLICT REPLACE)''')
self.cur.execute(
'''INSERT INTO inventory SELECT hash, objecttype, streamnumber, payload, receivedtime'''
''' FROM inventory_backup;''')
self.cur.execute('''DROP TABLE inventory_backup;''')
item = '''update settings set value=? WHERE key='version';'''
parameters = (3,)
self.cur.execute(item, parameters)
@execute_setting_table @db_upgrade(version_three=3)
def versionFive(self): def version_three(self):
# Add a new table: objectprocessorqueue with which to hold objects """version_three for upgrading inventory"""
# that have yet to be processed if the user shuts down Bitmessage. self.inventory_upgrade()
currentVersion = int(self.cur.fetchall()[0][0])
if currentVersion == 5:
self.cur.execute('''DROP TABLE knownnodes''')
self.cur.execute(
'''CREATE TABLE objectprocessorqueue'''
''' (objecttype text, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''')
item = '''update settings set value=? WHERE key='version';'''
parameters = (6,)
self.cur.execute(item, parameters)
@execute_setting_table @db_upgrade(versio_four=4)
PeterSurda commented 2021-01-21 09:31:14 +01:00 (Migrated from github.com)
Review

typo

typo
def versionSix(self): def versio_four(self):
# changes related to protocol v3 """
# In table inventory and objectprocessorqueue, objecttype is now Add a new column to the pubkeys table to store the address version.
# an integer (it was a human-friendly string previously) We're going to trash all of our pubkeys and let them be redownloaded.
currentVersion = int(self.cur.fetchall()[0][0]) """
if currentVersion == 6: self.cur.execute('''DROP TABLE pubkeys''')
logger.debug( self.cur.execute(
'In messages.dat database, dropping and recreating' '''CREATE TABLE pubkeys (hash blob, addressversion int, transmitdata blob, time int,'''
' the inventory table.') '''usedpersonally text, UNIQUE(hash, addressversion) ON CONFLICT REPLACE)''')
self.cur.execute('''DROP TABLE inventory''') self.cur.execute(
self.cur.execute( '''delete from inventory where objecttype = 'pubkey';''')
'''CREATE TABLE inventory''' item = '''update settings set value=? WHERE key='version';'''
''' (hash blob, objecttype int, streamnumber int, payload blob, expirestime integer,''' parameters = (5,)
''' tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''') self.cur.execute(item, parameters)
self.cur.execute('''DROP TABLE objectprocessorqueue''')
self.cur.execute(
'''CREATE TABLE objectprocessorqueue'''
''' (objecttype int, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''')
item = '''update settings set value=? WHERE key='version';'''
parameters = (7,)
self.cur.execute(item, parameters)
logger.debug(
'Finished dropping and recreating the inventory table.')
@execute_setting_table @db_upgrade(versio_five=5)
PeterSurda commented 2021-01-21 09:31:24 +01:00 (Migrated from github.com)
Review

typo

typo
def versionSeven(self): def versio_five(self):
# The format of data stored in the pubkeys table has changed. Let's """
# clear it, and the pubkeys from inventory, so that they'll Add a new table: objectprocessorqueue with which to hold objects
# be re-downloaded. that have yet to be processed if the user shuts down Bitmessage.
currentVersion = int(self.cur.fetchall()[0][0]) """
if currentVersion == 7: self.cur.execute('''DROP TABLE knownnodes''')
logger.debug( self.cur.execute(
'In messages.dat database, clearing pubkeys table' '''CREATE TABLE objectprocessorqueue'''
' because the data format has been updated.') ''' (objecttype text, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''')
self.cur.execute( item = '''update settings set value=? WHERE key='version';'''
'''delete from inventory where objecttype = 1;''') parameters = (6,)
self.cur.execute( self.cur.execute(item, parameters)
'''delete from pubkeys;''')
# Any sending messages for which we *thought* that we had
# the pubkey must be rechecked.
self.cur.execute(
'''UPDATE sent SET status='msgqueued' WHERE status='doingmsgpow' or status='badkey';''')
query = '''update settings set value=? WHERE key='version';'''
parameters = (8,)
self.cur.execute(query, parameters)
logger.debug('Finished clearing currently held pubkeys.')
@execute_setting_table @db_upgrade(version_six=6)
def versionEight(self): def version_six(self):
# Add a new column to the inbox table to store the hash of """
# the message signature. We'll use this as temporary message UUID changes related to protocol v3
# in order to detect duplicates. In table inventory and objectprocessorqueue, objecttype is now
currentVersion = int(self.cur.fetchall()[0][0]) an integer (it was a human-friendly string previously)
if currentVersion == 8: """
logger.debug( logger.debug(
'In messages.dat database, adding sighash field to' 'In messages.dat database, dropping and recreating'
' the inbox table.') ' the inventory table.')
item = '''ALTER TABLE inbox ADD sighash blob DEFAULT '' ''' self.cur.execute('''DROP TABLE inventory''')
parameters = '' self.cur.execute(
self.cur.execute(item, parameters) '''CREATE TABLE inventory'''
item = '''update settings set value=? WHERE key='version';''' ''' (hash blob, objecttype int, streamnumber int, payload blob, expirestime integer,'''
parameters = (9,) ''' tag blob, UNIQUE(hash) ON CONFLICT REPLACE)''')
self.cur.execute(item, parameters) self.cur.execute('''DROP TABLE objectprocessorqueue''')
self.cur.execute(
'''CREATE TABLE objectprocessorqueue'''
''' (objecttype int, data blob, UNIQUE(objecttype, data) ON CONFLICT REPLACE)''')
item = '''update settings set value=? WHERE key='version';'''
parameters = (7,)
self.cur.execute(item, parameters)
logger.debug(
'Finished dropping and recreating the inventory table.')
@execute_setting_table @db_upgrade(version_seven=7)
def versionNine(self): def version_seven(self):
# We'll also need a `sleeptill` field and a `ttl` field. Also we """
# can combine the pubkeyretrynumber and msgretrynumber into one. The format of data stored in the pubkeys table has changed. Let's
currentVersion = int(self.cur.fetchall()[0][0]) clear it, and the pubkeys from inventory, so that they'll
if currentVersion == 9: be re-downloaded.
logger.info( """
'In messages.dat database, making TTL-related changes:' logger.debug(
' combining the pubkeyretrynumber and msgretrynumber' 'In messages.dat database, clearing pubkeys table'
' fields into the retrynumber field and adding the' ' because the data format has been updated.')
' sleeptill and ttl fields...') self.cur.execute(
self.cur.execute( '''delete from inventory where objecttype = 1;''')
'''CREATE TEMPORARY TABLE sent_backup''' self.cur.execute(
''' (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text,''' '''delete from pubkeys;''')
''' ackdata blob, lastactiontime integer, status text, retrynumber integer,''' # Any sending messages for which we *thought* that we had
''' folder text, encodingtype int)''') # the pubkey must be rechecked.
self.cur.execute( self.cur.execute(
'''INSERT INTO sent_backup SELECT msgid, toaddress, toripe, fromaddress,''' '''UPDATE sent SET status='msgqueued' WHERE status='doingmsgpow' or status='badkey';''')
''' subject, message, ackdata, lastactiontime,''' query = '''update settings set value=? WHERE key='version';'''
''' status, 0, folder, encodingtype FROM sent;''') parameters = (8,)
self.cur.execute('''DROP TABLE sent''') self.cur.execute(query, parameters)
self.cur.execute( logger.debug('Finished clearing currently held pubkeys.')
'''CREATE TABLE sent'''
''' (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text,''' @db_upgrade(version_eight=8)
''' ackdata blob, senttime integer, lastactiontime integer, sleeptill int, status text,''' def version_eight(self):
''' retrynumber integer, folder text, encodingtype int, ttl int)''') """
self.cur.execute( Add a new column to the inbox table to store the hash of
'''INSERT INTO sent SELECT msgid, toaddress, toripe, fromaddress, subject, message, ackdata,''' the message signature. We'll use this as temporary message UUID
''' lastactiontime, lastactiontime, 0, status, 0, folder, encodingtype, 216000 FROM sent_backup;''') in order to detect duplicates.
self.cur.execute('''DROP TABLE sent_backup''') """
logger.info('In messages.dat database, finished making TTL-related changes.') logger.debug(
logger.debug('In messages.dat database, adding address field to the pubkeys table.') 'In messages.dat database, adding sighash field to'
# We're going to have to calculate the address for each row in the pubkeys ' the inbox table.')
# table. Then we can take out the hash field. item = '''ALTER TABLE inbox ADD sighash blob DEFAULT '' '''
self.cur.execute('''ALTER TABLE pubkeys ADD address text DEFAULT '' ''') param = ''
self.cur.execute('''SELECT hash, addressversion FROM pubkeys''') self.cur.execute(item, param)
queryResult = self.cur.fetchall() item = '''update settings set value=? WHERE key='version';'''
from addresses import encodeAddress parameters = (9,)
for row in queryResult: self.cur.execute(item, parameters)
addressHash, addressVersion = row
address = encodeAddress(addressVersion, 1, hash) @db_upgrade(version_nine=9)
item = '''UPDATE pubkeys SET address=? WHERE hash=?;''' def version_nine(self):
parameters = (address, addressHash) """
self.cur.execute(item, parameters) We'll also need a `sleeptill` field and a `ttl` field. Also we
# Now we can remove the hash field from the pubkeys table. can combine the pubkeyretrynumber and msgretrynumber into one.
self.cur.execute( """
'''CREATE TEMPORARY TABLE pubkeys_backup''' logger.info(
''' (address text, addressversion int, transmitdata blob, time int,''' 'In messages.dat database, making TTL-related changes:'
''' usedpersonally text, UNIQUE(address) ON CONFLICT REPLACE)''') ' combining the pubkeyretrynumber and msgretrynumber'
self.cur.execute( ' fields into the retrynumber field and adding the'
'''INSERT INTO pubkeys_backup''' ' sleeptill and ttl fields...')
''' SELECT address, addressversion, transmitdata, time, usedpersonally FROM pubkeys;''') self.cur.execute(
self.cur.execute('''DROP TABLE pubkeys''') '''CREATE TEMPORARY TABLE sent_backup'''
self.cur.execute( ''' (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text,'''
'''CREATE TABLE pubkeys''' ''' ackdata blob, lastactiontime integer, status text, retrynumber integer,'''
''' (address text, addressversion int, transmitdata blob, time int, usedpersonally text,''' ''' folder text, encodingtype int)''')
''' UNIQUE(address) ON CONFLICT REPLACE)''') self.cur.execute(
self.cur.execute( '''INSERT INTO sent_backup SELECT msgid, toaddress, toripe, fromaddress,'''
'''INSERT INTO pubkeys SELECT''' ''' subject, message, ackdata, lastactiontime,'''
''' address, addressversion, transmitdata, time, usedpersonally FROM pubkeys_backup;''') ''' status, 0, folder, encodingtype FROM sent;''')
self.cur.execute('''DROP TABLE pubkeys_backup''') self.cur.execute('''DROP TABLE sent''')
logger.debug( self.cur.execute(
'In messages.dat database, done adding address field to the pubkeys table' '''CREATE TABLE sent'''
' and removing the hash field.') ''' (msgid blob, toaddress text, toripe blob, fromaddress text, subject text, message text,'''
self.cur.execute('''update settings set value=10 WHERE key='version';''') ''' ackdata blob, senttime integer, lastactiontime integer, sleeptill int, status text,'''
''' retrynumber integer, folder text, encodingtype int, ttl int)''')
self.cur.execute(
'''INSERT INTO sent SELECT msgid, toaddress, toripe, fromaddress, subject, message, ackdata,'''
''' lastactiontime, lastactiontime, 0, status, 0, folder, encodingtype, 216000 FROM sent_backup;''')
self.cur.execute('''DROP TABLE sent_backup''')
logger.info('In messages.dat database, finished making TTL-related changes.')
logger.debug('In messages.dat database, adding address field to the pubkeys table.')
# We're going to have to calculate the address for each row in the pubkeys
# table. Then we can take out the hash field.
self.cur.execute('''ALTER TABLE pubkeys ADD address text DEFAULT '' ''')
self.cur.execute('''SELECT hash, addressversion FROM pubkeys''')
queryResult = self.cur.fetchall()
from addresses import encodeAddress
for row in queryResult:
addressHash, addressVersion = row
address = encodeAddress(addressVersion, 1, hash)
item = '''UPDATE pubkeys SET address=? WHERE hash=?;'''
parameters = (address, addressHash)
self.cur.execute(item, parameters)
# Now we can remove the hash field from the pubkeys table.
self.cur.execute(
'''CREATE TEMPORARY TABLE pubkeys_backup'''
''' (address text, addressversion int, transmitdata blob, time int,'''
''' usedpersonally text, UNIQUE(address) ON CONFLICT REPLACE)''')
self.cur.execute(
'''INSERT INTO pubkeys_backup'''
''' SELECT address, addressversion, transmitdata, time, usedpersonally FROM pubkeys;''')
self.cur.execute('''DROP TABLE pubkeys''')
self.cur.execute(
'''CREATE TABLE pubkeys'''
''' (address text, addressversion int, transmitdata blob, time int, usedpersonally text,'''
''' UNIQUE(address) ON CONFLICT REPLACE)''')
self.cur.execute(
'''INSERT INTO pubkeys SELECT'''
''' address, addressversion, transmitdata, time, usedpersonally FROM pubkeys_backup;''')
self.cur.execute('''DROP TABLE pubkeys_backup''')
logger.debug(
'In messages.dat database, done adding address field to the pubkeys table'
' and removing the hash field.')
self.cur.execute('''update settings set value=10 WHERE key='version';''')
@db_upgrade(version_ten=10)
def version_ten(self):
"""Update the address colunm to unique in addressbook table"""
logger.debug(
'In messages.dat database, updating address column to UNIQUE'
' in the addressbook table.')
self.cur.execute(
'''ALTER TABLE addressbook RENAME TO old_addressbook''')
self.cur.execute(
'''CREATE TABLE addressbook'''
''' (label text, address text, UNIQUE(address) ON CONFLICT IGNORE)''')
self.cur.execute(
'''INSERT INTO addressbook SELECT label, address FROM old_addressbook;''')
self.cur.execute('''DROP TABLE old_addressbook''')
self.cur.execute('''update settings set value=11 WHERE key='version';''')
def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-statements def run(self): # pylint: disable=too-many-locals, too-many-branches, too-many-statements
"""Process SQL queries from `.helper_sql.sqlSubmitQueue`""" """Process SQL queries from `.helper_sql.sqlSubmitQueue`"""
@ -396,21 +429,14 @@ class sqlThread(threading.Thread):
self.update_sent() self.update_sent()
self.versionTwo() item = '''SELECT value FROM settings WHERE key='version';'''
parameters = ''
self.cur.execute(item, parameters)
currentVersion = int(self.cur.fetchall()[0][0])
temp_dict = {val: key for key, val in upgrade_dict.items()}
self.versionThree() if temp_dict.get(currentVersion):
getattr(self, temp_dict.get(currentVersion))()
self.versionFour()
self.versionFive()
self.versionSix()
self.versionSeven()
self.versionEight()
self.versionNine()
# Are you hoping to add a new option to the keys.dat file of existing # Are you hoping to add a new option to the keys.dat file of existing
# Bitmessage users or modify the SQLite database? Add it right # Bitmessage users or modify the SQLite database? Add it right