3 # Copyright (C) 2015 Ipsilon project Contributors, for license see COPYING
7 from jinja2 import Environment, FileSystemLoader
8 import ipsilon.util.sessions
9 from ipsilon.util.data import AdminStore, Store, UserStore, TranStore
10 from ipsilon.util.sessions import SqlSession
11 from ipsilon.root import Root
14 def _upgrade_database(datastore):
15 print 'Considering datastore %s' % datastore.__class__.__name__
16 # pylint: disable=protected-access
17 current_version = datastore._get_schema_version()
18 # pylint: disable=protected-access
19 code_schema_version = datastore._code_schema_version()
20 upgrade_required = False
21 if current_version is None:
23 print 'Initializing schema for %s' % datastore.__class__.__name__
24 upgrade_required = True
25 elif current_version != code_schema_version:
26 print 'Upgrading schema for %s' % datastore.__class__.__name__
27 upgrade_required = True
29 print 'Schema for %s is up-to-date' % datastore.__class__.__name__
31 if datastore.is_readonly:
32 print 'Datastore is readonly. Please fix manually!'
35 datastore.upgrade_database()
36 except Exception as ex: # pylint: disable=broad-except
37 # Error upgrading database
38 print 'Error upgrading datastore: %s' % ex
48 print 'Upgrade failed. Please fix errors above and retry'
49 raise Exception('Upgrading failed')
52 def execute_upgrade(cfgfile):
53 cherrypy.lib.sessions.SqlSession = ipsilon.util.sessions.SqlSession
54 cherrypy.config.update(cfgfile)
56 # pylint: disable=protected-access
57 Store._is_upgrade = True
59 datastore = AdminStore()
60 # First try to upgrade the config store before continuing
61 if not _upgrade_database(datastore):
62 return upgrade_failed()
64 admin_config = datastore.load_config()
65 for option in admin_config:
66 cherrypy.config[option] = admin_config[option]
68 # Initialize a minimal env
69 template_env = Environment(loader=FileSystemLoader(
70 os.path.join(cherrypy.config['base.dir'],
72 root = Root('default', template_env)
74 # Handle the session store if that is Sql
75 print 'Handling sessions datastore'
76 if cherrypy.config['tools.sessions.storage_type'] != 'sql':
77 print 'Not SQL-based, skipping'
79 dburi = cherrypy.config['tools.sessions.storage_dburi']
80 SqlSession.setup(storage_dburi=dburi)
81 if not _upgrade_database(SqlSession._store):
82 return upgrade_failed()
84 # Now handle the rest of the default datastores
85 for store in [UserStore, TranStore]:
87 print 'Handling default datastore %s' % store.__class__.__name__
88 if not _upgrade_database(store):
89 return upgrade_failed()
91 # And now datastores for any of the plugins
92 for facility in ['provider_config',
95 for plugin in root._site[facility].enabled:
96 print 'Handling plugin %s' % plugin
97 plugin = root._site[facility].available[plugin]
98 for store in plugin.used_datastores():
99 print 'Handling plugin datastore %s' % store.__class__.__name__
100 if not _upgrade_database(store):
101 return upgrade_failed()
103 # We are done with the init/upgrade
104 # pylint: disable=protected-access
105 Store._is_upgrade = False