forked from GNUsocial/gnu-social
		
	
		
			
	
	
		
			171 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			171 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								#!/usr/bin/env python
							 | 
						||
| 
								 | 
							
								# SQL Store Upgrade Script
							 | 
						||
| 
								 | 
							
								# for version 1.x to 2.0 of the OpenID library.
							 | 
						||
| 
								 | 
							
								# Doesn't depend on the openid library, so you can run this python
							 | 
						||
| 
								 | 
							
								# script to update databases for ruby or PHP as well.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# Testers note:
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#   A SQLite3 db with the 1.2 schema exists in
							 | 
						||
| 
								 | 
							
								#   openid/test/data/openid-1.2-consumer-sqlitestore.db if you want something
							 | 
						||
| 
								 | 
							
								#   to try upgrading.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								#   TODO:
							 | 
						||
| 
								 | 
							
								#    * test data for mysql and postgresql.
							 | 
						||
| 
								 | 
							
								#    * automated tests.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import os
							 | 
						||
| 
								 | 
							
								import getpass
							 | 
						||
| 
								 | 
							
								import sys
							 | 
						||
| 
								 | 
							
								from optparse import OptionParser
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def askForPassword():
							 | 
						||
| 
								 | 
							
								    return getpass.getpass("DB Password: ")
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def askForConfirmation(dbname,tablename):
							 | 
						||
| 
								 | 
							
								    print """The table %s from the database %s will be dropped, and
							 | 
						||
| 
								 | 
							
								    an empty table with the new nonce table schema will replace it."""%(
							 | 
						||
| 
								 | 
							
								    tablename, dbname)
							 | 
						||
| 
								 | 
							
								    return raw_input("Continue? ").lower().strip().startswith('y')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def doSQLiteUpgrade(db_conn, nonce_table_name='oid_nonces'):
							 | 
						||
| 
								 | 
							
								    cur = db_conn.cursor()
							 | 
						||
| 
								 | 
							
								    cur.execute('DROP TABLE %s'%nonce_table_name)
							 | 
						||
| 
								 | 
							
								    sql = """
							 | 
						||
| 
								 | 
							
								    CREATE TABLE %s (
							 | 
						||
| 
								 | 
							
								        server_url VARCHAR,
							 | 
						||
| 
								 | 
							
								        timestamp INTEGER,
							 | 
						||
| 
								 | 
							
								        salt CHAR(40),
							 | 
						||
| 
								 | 
							
								        UNIQUE(server_url, timestamp, salt)
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								    """%nonce_table_name
							 | 
						||
| 
								 | 
							
								    cur.execute(sql)
							 | 
						||
| 
								 | 
							
								    cur.close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def doMySQLUpgrade(db_conn, nonce_table_name='oid_nonces'):
							 | 
						||
| 
								 | 
							
								    cur = db_conn.cursor()
							 | 
						||
| 
								 | 
							
								    cur.execute('DROP TABLE %s'%nonce_table_name)
							 | 
						||
| 
								 | 
							
								    sql = """
							 | 
						||
| 
								 | 
							
								    CREATE TABLE %s (
							 | 
						||
| 
								 | 
							
								        server_url BLOB,
							 | 
						||
| 
								 | 
							
								        timestamp INTEGER,
							 | 
						||
| 
								 | 
							
								        salt CHAR(40),
							 | 
						||
| 
								 | 
							
								        PRIMARY KEY (server_url(255), timestamp, salt)
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								    TYPE=InnoDB;
							 | 
						||
| 
								 | 
							
								    """%nonce_table_name
							 | 
						||
| 
								 | 
							
								    cur.execute(sql)
							 | 
						||
| 
								 | 
							
								    cur.close()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def doPostgreSQLUpgrade(db_conn, nonce_table_name='oid_nonces'):
							 | 
						||
| 
								 | 
							
								    cur = db_conn.cursor()
							 | 
						||
| 
								 | 
							
								    cur.execute('DROP TABLE %s'%nonce_table_name)
							 | 
						||
| 
								 | 
							
								    sql = """
							 | 
						||
| 
								 | 
							
								    CREATE TABLE %s (
							 | 
						||
| 
								 | 
							
								        server_url VARCHAR(2047),
							 | 
						||
| 
								 | 
							
								        timestamp INTEGER,
							 | 
						||
| 
								 | 
							
								        salt CHAR(40),
							 | 
						||
| 
								 | 
							
								        PRIMARY KEY (server_url, timestamp, salt)
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								    """%nonce_table_name
							 | 
						||
| 
								 | 
							
								    cur.execute(sql)
							 | 
						||
| 
								 | 
							
								    cur.close()
							 | 
						||
| 
								 | 
							
								    db_conn.commit()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								def main(argv=None):
							 | 
						||
| 
								 | 
							
								    parser = OptionParser()
							 | 
						||
| 
								 | 
							
								    parser.add_option("-u", "--user", dest="username",
							 | 
						||
| 
								 | 
							
								                      default=os.environ.get('USER'),
							 | 
						||
| 
								 | 
							
								                      help="User name to use to connect to the DB.  "
							 | 
						||
| 
								 | 
							
								                      "Defaults to USER environment variable.")
							 | 
						||
| 
								 | 
							
								    parser.add_option('-t', '--table', dest='tablename', default='oid_nonces',
							 | 
						||
| 
								 | 
							
								                      help='The name of the nonce table to drop and recreate. '
							 | 
						||
| 
								 | 
							
								                      ' Defaults to "oid_nonces", the default table name for '
							 | 
						||
| 
								 | 
							
								                      'the openid stores.')
							 | 
						||
| 
								 | 
							
								    parser.add_option('--mysql', dest='mysql_db_name',
							 | 
						||
| 
								 | 
							
								                      help='Upgrade a table from this MySQL database.  '
							 | 
						||
| 
								 | 
							
								                      'Requires username for database.')
							 | 
						||
| 
								 | 
							
								    parser.add_option('--pg', '--postgresql', dest='postgres_db_name',
							 | 
						||
| 
								 | 
							
								                      help='Upgrade a table from this PostgreSQL database.  '
							 | 
						||
| 
								 | 
							
								                      'Requires username for database.')
							 | 
						||
| 
								 | 
							
								    parser.add_option('--sqlite', dest='sqlite_db_name',
							 | 
						||
| 
								 | 
							
								                      help='Upgrade a table from this SQLite database file.')
							 | 
						||
| 
								 | 
							
								    parser.add_option('--host', dest='db_host',
							 | 
						||
| 
								 | 
							
								                      default='localhost',
							 | 
						||
| 
								 | 
							
								                      help='Host on which to find MySQL or PostgreSQL DB.')
							 | 
						||
| 
								 | 
							
								    (options, args) = parser.parse_args(argv)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    db_conn = None
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if options.sqlite_db_name:
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            from pysqlite2 import dbapi2 as sqlite
							 | 
						||
| 
								 | 
							
								        except ImportError:
							 | 
						||
| 
								 | 
							
								            print "You must have pysqlite2 installed in your PYTHONPATH."
							 | 
						||
| 
								 | 
							
								            return 1
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            db_conn = sqlite.connect(options.sqlite_db_name)
							 | 
						||
| 
								 | 
							
								        except Exception, e:
							 | 
						||
| 
								 | 
							
								            print "Could not connect to SQLite database:", str(e)
							 | 
						||
| 
								 | 
							
								            return 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if askForConfirmation(options.sqlite_db_name, options.tablename):
							 | 
						||
| 
								 | 
							
								            doSQLiteUpgrade(db_conn, nonce_table_name=options.tablename)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if options.postgres_db_name:
							 | 
						||
| 
								 | 
							
								        if not options.username:
							 | 
						||
| 
								 | 
							
								            print "A username is required to open a PostgreSQL Database."
							 | 
						||
| 
								 | 
							
								            return 1
							 | 
						||
| 
								 | 
							
								        password = askForPassword()
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            import psycopg
							 | 
						||
| 
								 | 
							
								        except ImportError:
							 | 
						||
| 
								 | 
							
								            print "You need psycopg installed to update a postgres DB."
							 | 
						||
| 
								 | 
							
								            return 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            db_conn = psycopg.connect(database = options.postgres_db_name,
							 | 
						||
| 
								 | 
							
								                                      user = options.username,
							 | 
						||
| 
								 | 
							
								                                      host = options.db_host,
							 | 
						||
| 
								 | 
							
								                                      password = password)
							 | 
						||
| 
								 | 
							
								        except Exception, e:
							 | 
						||
| 
								 | 
							
								            print "Could not connect to PostgreSQL database:", str(e)
							 | 
						||
| 
								 | 
							
								            return 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if askForConfirmation(options.postgres_db_name, options.tablename):
							 | 
						||
| 
								 | 
							
								            doPostgreSQLUpgrade(db_conn, nonce_table_name=options.tablename)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if options.mysql_db_name:
							 | 
						||
| 
								 | 
							
								        if not options.username:
							 | 
						||
| 
								 | 
							
								            print "A username is required to open a MySQL Database."
							 | 
						||
| 
								 | 
							
								            return 1
							 | 
						||
| 
								 | 
							
								        password = askForPassword()
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            import MySQLdb
							 | 
						||
| 
								 | 
							
								        except ImportError:
							 | 
						||
| 
								 | 
							
								            print "You must have MySQLdb installed to update a MySQL DB."
							 | 
						||
| 
								 | 
							
								            return 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        try:
							 | 
						||
| 
								 | 
							
								            db_conn = MySQLdb.connect(options.db_host, options.username,
							 | 
						||
| 
								 | 
							
								                                      password, options.mysql_db_name)
							 | 
						||
| 
								 | 
							
								        except Exception, e:
							 | 
						||
| 
								 | 
							
								            print "Could not connect to MySQL database:", str(e)
							 | 
						||
| 
								 | 
							
								            return 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if askForConfirmation(options.mysql_db_name, options.tablename):
							 | 
						||
| 
								 | 
							
								            doMySQLUpgrade(db_conn, nonce_table_name=options.tablename)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if db_conn:
							 | 
						||
| 
								 | 
							
								        db_conn.close()
							 | 
						||
| 
								 | 
							
								    else:
							 | 
						||
| 
								 | 
							
								        parser.print_help()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if __name__ == '__main__':
							 | 
						||
| 
								 | 
							
								    retval = main()
							 | 
						||
| 
								 | 
							
								    sys.exit(retval)
							 |