diff --git a/web/pgadmin/__init__.py b/web/pgadmin/__init__.py index c9131322a..283cb80e1 100644 --- a/web/pgadmin/__init__.py +++ b/web/pgadmin/__init__.py @@ -16,12 +16,13 @@ from flask.ext.security import Security, SQLAlchemyUserDatastore from flask_security.utils import login_user from flask_mail import Mail from htmlmin.minify import html_minify -from settings.settings_model import db, Role, User +from settings.settings_model import db, Role, User, Version from importlib import import_module from werkzeug.local import LocalProxy from pgadmin.utils import PgAdminModule from werkzeug.utils import find_modules import sys +import os import logging # Configuration settings @@ -162,7 +163,21 @@ def create_app(app_name=config.APP_NAME): # Setup Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) - Security(app, user_datastore) + security = Security(app, user_datastore) + + # Upgrade the schema (if required) + with app.app_context(): + version = Version.query.filter_by(name='ConfigDB').first() + + # Pre-flight checks + if int(version.value) < int(config.SETTINGS_SCHEMA_VERSION): + app.logger.info( + """Upgrading the database schema from version {0} to {1}.""".format( + version.value, config.SETTINGS_SCHEMA_VERSION + ) + ) + from setup import do_upgrade + do_upgrade(app, user_datastore, security, version) ########################################################################## # Load plugin modules diff --git a/web/setup.py b/web/setup.py index 31a99b585..055086288 100644 --- a/web/setup.py +++ b/web/setup.py @@ -21,23 +21,18 @@ import getpass, os, random, sys, string # Configuration settings import config -app = Flask(__name__) -app.config.from_object(config) -app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + config.SQLITE_PATH.replace('\\', '/') -db.init_app(app) - -def do_setup(): +def do_setup(app): """Create a new settings database from scratch""" if config.SERVER_MODE is False: - print "NOTE: Configuring authentication for DESKTOP mode." + print("NOTE: Configuring authentication for DESKTOP mode.") email = config.DESKTOP_USER p1 = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(32)]) else: - print "NOTE: Configuring authentication for SERVER mode.\n" + print("NOTE: Configuring authentication for SERVER mode.\n") # Prompt the user for their default username and password. - print "Enter the email address and password to use for the initial pgAdmin user account:\n" + print("Enter the email address and password to use for the initial pgAdmin user account:\n") email = '' while email == '': email = raw_input("Email address: ") @@ -73,72 +68,78 @@ def do_setup(): db.session.commit() # Done! - print "" - print "The configuration database has been created at %s" % config.SQLITE_PATH + print("") + print("The configuration database has been created at %s" % config.SQLITE_PATH) -def do_upgrade(): +def do_upgrade(app, datastore, security, version): """Upgrade an existing settings database""" - # Setup Flask-Security - user_datastore = SQLAlchemyUserDatastore(db, User, Role) - security = Security(app, user_datastore) + ####################################################################### + # Run whatever is required to update the database schema to the current + # version. + ####################################################################### - with app.app_context(): - version = Version.query.filter_by(name='ConfigDB').first() + # Changes introduced in schema version 2 + if int(version.value) < 2: + # Create the 'server' table + db.metadata.create_all(db.engine, tables=[Server.__table__]) + elif int(version.value) < 3: + db.engine.execute('ALTER TABLE server ADD COLUMN comment TEXT(1024)'); - # Pre-flight checks - if int(version.value) > int(config.SETTINGS_SCHEMA_VERSION): - print "The database schema version is %d, whilst the version required by the software is %d.\nExiting..." \ - % (version.value, config.SETTINGS_SCHEMA_VERSION) - sys.exit(1) - elif int(version.value) == int(config.SETTINGS_SCHEMA_VERSION): - print "The database schema version is %d as required.\nExiting..." % (version.value) - sys.exit(1) + # Finally, update the schema version + version.value = config.SETTINGS_SCHEMA_VERSION + db.session.merge(version) - print "NOTE: Upgrading database schema from version %d to %d." % (version.value, config.SETTINGS_SCHEMA_VERSION) - - ####################################################################### - # Run whatever is required to update the database schema to the current - # version. Always use "< REQUIRED_VERSION" as the test for readability - ####################################################################### - - # Changes introduced in schema version 2 - if int(version.value) < 2: - # Create the 'server' table - db.metadata.create_all(db.engine, tables=[Server.__table__]) - elif int(version.value) < 3: - db.engine.execute('ALTER TABLE server ADD COLUMN comment TEXT(1024)'); - - # Finally, update the schema version - version.value = config.SETTINGS_SCHEMA_VERSION - db.session.merge(version) - - db.session.commit() + db.session.commit() # Done! - print "" - print "The configuration database %s has been upgraded to version %d" % (config.SQLITE_PATH, config.SETTINGS_SCHEMA_VERSION) + print("") + print("The configuration database %s has been upgraded to version %d" % (config.SQLITE_PATH, config.SETTINGS_SCHEMA_VERSION)) ############################################################################### # Do stuff! ############################################################################### +if __name__ == '__main__': + app = Flask(__name__) + app.config.from_object(config) + app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + config.SQLITE_PATH.replace('\\', '/') + db.init_app(app) -print "pgAdmin 4 - Application Initialisation" -print "======================================\n" + print("pgAdmin 4 - Application Initialisation") + print("======================================\n") -local_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config_local.py') -if not os.path.isfile(local_config): - print "The configuration file %s does not exist.\n" % local_config - print "Before running this application, ensure that config_local.py has been created" - print "and sets values for SECRET_KEY, SECURITY_PASSWORD_SALT and CSRF_SESSION_KEY" - print "at bare minimum. See config.py for more information and a complete list of" - print "settings. Exiting..." - sys.exit(1) + local_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config_local.py') + if not os.path.isfile(local_config): + print("The configuration file %s does not exist.\n" % local_config) + print("Before running this application, ensure that config_local.py has been created") + print("and sets values for SECRET_KEY, SECURITY_PASSWORD_SALT and CSRF_SESSION_KEY") + print("at bare minimum. See config.py for more information and a complete list of") + print("settings. Exiting...") + sys.exit(1) -# Check if the database exists. If it does, tell the user and exit. -if os.path.isfile(config.SQLITE_PATH): - print "The configuration database %s already exists.\nEntering upgrade mode...\n" % config.SQLITE_PATH - do_upgrade() -else: - print "The configuration database %s does not exist.\nEntering initial setup mode...\n" % config.SQLITE_PATH - do_setup() + # Check if the database exists. If it does, tell the user and exit. + if os.path.isfile(config.SQLITE_PATH): + print("The configuration database %s already exists.\nEntering upgrade mode...\n" % config.SQLITE_PATH) + + # Setup Flask-Security + user_datastore = SQLAlchemyUserDatastore(db, User, Role) + security = Security(app, user_datastore) + + # Always use "< REQUIRED_VERSION" as the test for readability + with app.app_context(): + version = Version.query.filter_by(name='ConfigDB').first() + + # Pre-flight checks + if int(version.value) > int(config.SETTINGS_SCHEMA_VERSION): + print("The database schema version is %d, whilst the version required by the software is %d.\nExiting..." + % (version.value, config.SETTINGS_SCHEMA_VERSION)) + sys.exit(1) + elif int(version.value) == int(config.SETTINGS_SCHEMA_VERSION): + print("The database schema version is %d as required.\nExiting..." % (version.value)) + sys.exit(1) + + print("NOTE: Upgrading database schema from version %d to %d." % (version.value, config.SETTINGS_SCHEMA_VERSION)) + do_upgrade(app, user_datastore, security, version) + else: + print("The configuration database %s does not exist.\nEntering initial setup mode...\n" % config.SQLITE_PATH) + do_setup(app)