From 020e7911ba019c6f88ba1be0c9f49d9208048851 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Thu, 2 Feb 2012 18:27:58 +0000 Subject: [PATCH] Added support for disabling schema migrations for a PersistenceContext. This allows two separate services which share a database to assign "control" of the schema to one of the services. The non-controlling service can be configured to simply fail if new code is deployed to said service before new code is deployed to the controlling service, rather than have the non-controlling service migrate the schema out from under the controlling service. --- .../samskivert/depot/PersistenceContext.java | 57 +++++++++++++++---- .../depot/impl/DepotMarshaller.java | 14 +++++ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/samskivert/depot/PersistenceContext.java b/src/main/java/com/samskivert/depot/PersistenceContext.java index d284267..011602a 100644 --- a/src/main/java/com/samskivert/depot/PersistenceContext.java +++ b/src/main/java/com/samskivert/depot/PersistenceContext.java @@ -54,6 +54,18 @@ public class PersistenceContext /** Map {@link TableGenerator} instances by name. */ public Map tableGenerators = Maps.newHashMap(); + /** Used by {@link #setCanMigrate}. */ + public static enum CanMigrate { + /** Schema migrations are allowed (the default). */ + ALLOWED, + /** Schema migrations are disallowed and warnings are issued if it is discovered at runtime + * that they are needed, but cannot be peformed. */ + WARN, + /** Schema migrations are disallowed and a runtime exception will be thrown if a record + * that requires migrations is used at runtime. */ + FAIL + }; + /** * A cache listener is notified when cache entries change. Its purpose is typically to do * further invalidation of dependent entries in other caches. @@ -114,6 +126,36 @@ public class PersistenceContext protected abstract boolean testForEviction (Serializable key, T record); } + /** + * Creates an uninitialized persistence context. {@link #init} must later be called on this + * context to prepare it for operation. + */ + public PersistenceContext () + { + this(CanMigrate.ALLOWED); + } + + /** + * Creates an uninitialized persistence context. {@link #init} must later be called on this + * context to prepare it for operation. + * + * @param canMigrate configures whether schema migrations are allowed for this persistence + * context. See {@link CanMigrate} for details. + */ + public PersistenceContext (CanMigrate canMigrate) + { + _canMigrate = canMigrate; + } + + /** + * Creates and initializes a persistence context. See {@link #init}. + */ + public PersistenceContext (String ident, ConnectionProvider conprov, CacheAdapter adapter) + { + this(CanMigrate.ALLOWED); + init(ident, conprov, adapter); + } + /** * Returns the cache adapter used by this context or null if caching is disabled. */ @@ -123,19 +165,11 @@ public class PersistenceContext } /** - * Creates an uninitialized persistence context. {@link #init} must later be called on this - * context to prepare it for operation. + * Returns whether schema migrations are allowed in this context. */ - public PersistenceContext () + public CanMigrate canMigrate () { - } - - /** - * Creates and initializes a persistence context. See {@link #init}. - */ - public PersistenceContext (String ident, ConnectionProvider conprov, CacheAdapter adapter) - { - init(ident, conprov, adapter); + return _canMigrate; } /** @@ -636,6 +670,7 @@ public class PersistenceContext } } + protected final CanMigrate _canMigrate; protected String _ident; protected ConnectionProvider _conprov; protected DatabaseLiaison _liaison; diff --git a/src/main/java/com/samskivert/depot/impl/DepotMarshaller.java b/src/main/java/com/samskivert/depot/impl/DepotMarshaller.java index e374ca3..c6f715c 100644 --- a/src/main/java/com/samskivert/depot/impl/DepotMarshaller.java +++ b/src/main/java/com/samskivert/depot/impl/DepotMarshaller.java @@ -529,6 +529,20 @@ public class DepotMarshaller implements QueryMarshal return; } + // check whether migrations are allowed by our context + switch (ctx.canMigrate()) { + case WARN: + log.warning(_pClass.getName() + " requires migration, which is disallowed. " + + "Failures may be encountered later."); + return; + case FAIL: + throw new DatabaseException( + _pClass.getName() + " requires migration, which is disallowed."); + case ALLOWED: + // great, fall through and do our migrations + break; + } + // try to update migratingVersion to the new version to indicate to other processes // that we are handling the migration and that they should wait if (_meta.updateMigratingVersion(getTableName(), currentVersion, _schemaVersion, 0)) {