witten
/
luminotes
Archived
1
0
Fork 0
This repository has been archived on 2023-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
luminotes/tools/verifyconvertdb.py

187 lines
6.4 KiB
Python
Executable File

#!/usr/bin/python2.5
import os
import os.path
import psycopg2 as psycopg
from controller.Old_database import Old_database
from controller.Scheduler import Scheduler
def quote( value ):
if value is None:
return "null"
value = unicode( value )
return "'%s'" % value.replace( "'", "''" ).replace( "\\", "\\\\" )
class Verifier( object ):
"""
Verifies a conversion of a Luminotes database from bsddb to PostgreSQL that was performed with
convertdb.py.
"""
def __init__( self, scheduler, database ):
self.scheduler = scheduler
self.database = database
self.conn = psycopg.connect( "dbname=luminotes user=luminotes password=dev" )
self.cursor = self.conn.cursor()
thread = self.verify_database()
self.scheduler.add( thread )
self.scheduler.wait_for( thread )
def verify_database( self ):
inserts = set()
for key in self.database._Old_database__db.keys():
if not self.database._Old_database__db.get( key ):
continue
self.database.load( key, self.scheduler.thread )
value = ( yield Scheduler.SLEEP )
class_name = value.__class__.__name__
if class_name == "Notebook":
self.verify_notebook( value )
elif class_name == "Note":
self.cursor.execute(
"select * from note where id = %s and revision = %s;" % ( quote( value.object_id ), quote( value.revision ) )
)
for row in self.cursor.fetchmany():
assert row[ 0 ] == value.object_id
assert row[ 1 ].replace( tzinfo = None ) == value.revision
assert row[ 2 ] == ( value.title and value.title.encode( "utf8" ) or None )
assert row[ 3 ] == ( value.contents and value.contents.encode( "utf8" ) or None )
# not checking for existence of row 4 (notebook_id), because notes deleted from the trash don't have a notebook id
assert row[ 5 ] is not None
assert row[ 6 ] == ( value.deleted_from or None )
if row[ 5 ] is True: # if this is a startup note, it should have a rank
assert row[ 7 ] is not None
elif class_name == "User":
# skip demo users
if value.username is None: continue
self.cursor.execute(
"select * from luminotes_user where id = %s and revision = %s;" % ( quote( value.object_id ), quote( value.revision ) )
)
for row in self.cursor.fetchmany():
assert row[ 0 ] == value.object_id
assert row[ 1 ].replace( tzinfo = None ) == value.revision
assert row[ 2 ] == value.username
assert row[ 3 ] == value._User__salt
assert row[ 4 ] == value._User__password_hash
assert row[ 5 ] == value.email_address
assert row[ 6 ] == value.storage_bytes
assert row[ 7 ] == value.rate_plan
for notebook in value.notebooks:
if notebook is None: continue
read_write = ( notebook.__class__.__name__ == "Notebook" )
self.cursor.execute(
"select * from user_notebook where user_id = %s and notebook_id = %s;" % ( quote( value.object_id ), quote( notebook.object_id ) )
)
for row in self.cursor.fetchmany():
assert row[ 0 ] == value.object_id
assert row[ 1 ] == notebook.object_id
assert row[ 2 ] == read_write
if notebook.trash:
self.cursor.execute(
"select * from user_notebook where user_id = %s and notebook_id = %s;" % ( quote( value.object_id ), quote( notebook.trash.object_id ) )
)
for row in self.cursor.fetchmany():
assert row[ 0 ] == value.object_id
assert row[ 1 ] == notebook.trash.object_id
assert row[ 2 ] == read_write
self.verify_notebook( notebook )
elif class_name == "Read_only_notebook":
self.verify_notebook( value._Read_only_notebook__wrapped )
elif class_name == "Password_reset":
# skip password resets that are already redeemed
if value.redeemed: continue
self.cursor.execute(
"select * from password_reset where id = %s;" % quote( value.object_id )
)
for row in self.cursor.fetchmany():
assert row[ 0 ] == value.object_id
assert row[ 1 ] == value.email_address
assert row[ 2 ] == False
elif class_name == "User_list":
pass
else:
raise Exception( "Unverified value of type %s" % class_name )
self.conn.commit()
yield None
def verify_notebook( self, value ):
self.cursor.execute(
"select * from notebook where id = %s and revision = %s;" % ( quote( value.object_id ), quote( value.revision ) )
)
for row in self.cursor.fetchmany():
assert row[ 0 ] == value.object_id
assert row[ 1 ].replace( tzinfo = None ) == value.revision
assert row[ 2 ] == value.name
if value.trash:
assert row[ 3 ] == value.trash.object_id
else:
assert row[ 3 ] == None
startup_note_ids = [ note.object_id for note in value.startup_notes ]
for note in value.notes:
self.cursor.execute(
"select * from note where id = %s and revision = %s;" % ( quote( note.object_id ), quote( value.revision ) )
)
for row in self.cursor.fetchmany():
assert row[ 0 ] == note.object_id
assert row[ 1 ].replace( tzinfo = None ) == note.revision
assert row[ 2 ] == note.title
assert row[ 3 ] == note.contents
assert row[ 4 ] == value.object_id
assert row[ 5 ] == ( note.object_id in startup_note_ids )
assert row[ 6 ] == note.deleted_from
if row[ 5 ] is True: # if this is a startup note, it should have a rank
assert row[ 7 ] is not None
for note in value.startup_notes:
self.cursor.execute(
"select * from note where id = %s and revision = %s order by rank;" % ( quote( note.object_id ), quote( value.revision ) )
)
rank = 0
for row in self.cursor.fetchmany():
assert row[ 0 ] == note.object_id
assert row[ 1 ].replace( tzinfo = None ) == note.revision
assert row[ 2 ] == note.title
assert row[ 3 ] == note.contents
assert row[ 4 ] == value.object_id
assert row[ 5 ] == True
assert row[ 6 ] == note.deleted_from
assert row[ 7 ] == rank
rank += 1
def main():
scheduler = Scheduler()
database = Old_database( scheduler, "data.db" )
initializer = Verifier( scheduler, database )
scheduler.wait_until_idle()
if __name__ == "__main__":
main()