- current_version = self.load_options('dbinfo').get('scheme', None)
- if current_version is None or 'version' not in current_version:
- # No version stored, storing current version
- self.save_options('dbinfo', 'scheme',
- {'version': CURRENT_SCHEMA_VERSION})
- current_version = CURRENT_SCHEMA_VERSION
- else:
- current_version = int(current_version['version'])
- if current_version != CURRENT_SCHEMA_VERSION:
- self.debug('Upgrading database schema from %i to %i' % (
- current_version, CURRENT_SCHEMA_VERSION))
- self._upgrade_database_from(current_version)
-
- def _upgrade_database_from(self, old_schema_version):
- # Insert code here to upgrade from old_schema_version to
- # CURRENT_SCHEMA_VERSION
- raise Exception('Unable to upgrade database to current schema'
- ' version: version %i is unknown!' %
- old_schema_version)
+
+ current_version = self._get_schema_version()
+ if current_version is None:
+ self.error('Database initialization required! ' +
+ 'Please run ipsilon-upgrade-database')
+ raise DatabaseError('Database initialization required for %s' %
+ self.__class__.__name__)
+ if current_version != self._code_schema_version():
+ self.error('Database upgrade required! ' +
+ 'Please run ipsilon-upgrade-database')
+ raise DatabaseError('Database upgrade required for %s' %
+ self.__class__.__name__)
+
+ def _store_new_schema_version(self, new_version):
+ cls_name = self.__class__.__name__
+ self.save_options('dbinfo', '%s_schema' % cls_name,
+ {'version': new_version})
+
+ def _initialize_schema(self):
+ raise NotImplementedError()
+
+ def _upgrade_schema(self, old_version):
+ # Datastores need to figure out what to do with bigger old_versions
+ # themselves.
+ # They might implement downgrading if that's feasible, or just throw
+ # NotImplementedError
+ # Should return the new schema version
+ raise NotImplementedError()
+
+ def upgrade_database(self):
+ # Do whatever is needed to get schema to current version
+ old_schema_version = self._get_schema_version()
+ if old_schema_version is None:
+ # Just initialize a new schema
+ self._initialize_schema()
+ self._store_new_schema_version(self._code_schema_version())
+ elif old_schema_version == -1:
+ # This is a special-case from 1.0: we only created tables at the
+ # first time they were actually used, but the upgrade code assumes
+ # that the tables exist. So let's fix this.
+ self._initialize_schema()
+ # The old version was schema version 1
+ self._store_new_schema_version(1)
+ self.upgrade_database()
+ elif old_schema_version != self._code_schema_version():
+ # Upgrade from old_schema_version to code_schema_version
+ self.debug('Upgrading from schema version %i' % old_schema_version)
+ new_version = self._upgrade_schema(old_schema_version)
+ if not new_version:
+ error = ('Schema upgrade error: %s did not provide a ' +
+ 'new schema version number!' %
+ self.__class__.__name__)
+ self.error(error)
+ raise Exception(error)
+ self._store_new_schema_version(new_version)
+ # Check if we are now up-to-date
+ self.upgrade_database()