From 773e53ec2d6bba5b9c3303b103a76645c26581eb Mon Sep 17 00:00:00 2001 From: Mark Johnson Date: Tue, 10 Apr 2007 21:52:17 +0000 Subject: [PATCH] Add support for having multiple servers store seperate config information in the same database git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4660 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../admin/server/DatabaseConfigRegistry.java | 22 +++++++++++++-- .../admin/server/persist/ConfigDatum.java | 3 ++- .../server/persist/ConfigRepository.java | 27 +++++++++++++++---- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/java/com/threerings/admin/server/DatabaseConfigRegistry.java b/src/java/com/threerings/admin/server/DatabaseConfigRegistry.java index bc8934617..cab8b49a2 100644 --- a/src/java/com/threerings/admin/server/DatabaseConfigRegistry.java +++ b/src/java/com/threerings/admin/server/DatabaseConfigRegistry.java @@ -53,9 +53,26 @@ public class DatabaseConfigRegistry extends ConfigRegistry */ public DatabaseConfigRegistry (ConnectionProvider conprov, Invoker invoker) throws PersistenceException + { + this(conprov, invoker, ""); + } + + /** + * Creates a configuration registry and prepares it for operation. + * + * @param conprov will provide access to our JDBC database. + * @param invoker this will be used to perform all database activity + * (except first time initialization) so as to avoid blocking the + * distributed object thread. + * @param node if this config registry is accessed by multiple servers which + * wish to maintain seperate configs, then specificy a node for each server + */ + public DatabaseConfigRegistry (ConnectionProvider conprov, Invoker invoker, String node) + throws PersistenceException { _repo = new ConfigRepository(conprov); _invoker = invoker; + _node = StringUtil.isBlank(node) ? "" : node; } // documentation inherited @@ -81,7 +98,7 @@ public class DatabaseConfigRegistry extends ConfigRegistry // systems can predictably make use of the configuration // information that we load try { - _data = _repo.loadConfig(_path); + _data = _repo.loadConfig(_node, _path); } catch (PersistenceException pe) { Log.warning("Failed to load object configuration " + "[path=" + _path + "]."); @@ -246,7 +263,7 @@ public class DatabaseConfigRegistry extends ConfigRegistry _invoker.postUnit(new Invoker.Unit() { public boolean invoke () { try { - _repo.updateConfig(_path, field, value); + _repo.updateConfig(_node, _path, field, value); } catch (PersistenceException pe) { Log.warning("Failed to update object configuration " + "[path=" + _path + ", field=" + field + @@ -264,4 +281,5 @@ public class DatabaseConfigRegistry extends ConfigRegistry protected ConfigRepository _repo; protected Invoker _invoker; + protected String _node; } diff --git a/src/java/com/threerings/admin/server/persist/ConfigDatum.java b/src/java/com/threerings/admin/server/persist/ConfigDatum.java index 594c60997..365328ad2 100644 --- a/src/java/com/threerings/admin/server/persist/ConfigDatum.java +++ b/src/java/com/threerings/admin/server/persist/ConfigDatum.java @@ -26,11 +26,12 @@ package com.threerings.admin.server.persist; */ public class ConfigDatum { + public String node; public String object; public String field; public String value; public String toString () { - return object + "." + field + "=" + value + "]"; + return node + "." + object + "." + field + "=" + value + "]"; } } diff --git a/src/java/com/threerings/admin/server/persist/ConfigRepository.java b/src/java/com/threerings/admin/server/persist/ConfigRepository.java index b1998997c..1e3cf8ed9 100644 --- a/src/java/com/threerings/admin/server/persist/ConfigRepository.java +++ b/src/java/com/threerings/admin/server/persist/ConfigRepository.java @@ -23,6 +23,7 @@ package com.threerings.admin.server.persist; import java.sql.Connection; import java.sql.SQLException; +import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; @@ -59,11 +60,12 @@ public class ConfigRepository extends JORARepository * @return a map containing field/value pairs for all stored configuration * data. */ - public HashMap loadConfig (String object) + public HashMap loadConfig (String node, String object) throws PersistenceException { ArrayList list = loadAll( - _ctable, "where OBJECT = " + JDBCUtil.escape(object)); + _ctable, "where OBJECT = " + JDBCUtil.escape(object) + + " and NODE = " + JDBCUtil.escape(node)); HashMap data = new HashMap(); for (int ii = 0, ll = list.size(); ii < ll; ii++) { ConfigDatum datum = list.get(ii); @@ -75,10 +77,11 @@ public class ConfigRepository extends JORARepository /** * Updates the specified configuration datum. */ - public void updateConfig (String object, String field, String value) + public void updateConfig (String node, String object, String field, String value) throws PersistenceException { ConfigDatum datum = new ConfigDatum(); + datum.node = node; datum.object = object; datum.field = field; datum.value = value; @@ -90,11 +93,25 @@ public class ConfigRepository extends JORARepository throws SQLException, PersistenceException { JDBCUtil.createTableIfMissing(conn, "CONFIG", new String[] { + "NODE VARCHAR(64) NOT NULL", "OBJECT VARCHAR(128) NOT NULL", "FIELD VARCHAR(64) NOT NULL", "VALUE TEXT NOT NULL", - "PRIMARY KEY (OBJECT, FIELD)", + "PRIMARY KEY (NODE, OBJECT, FIELD)", }, ""); + + // TEMP: add NODE column + if (!JDBCUtil.tableContainsColumn(conn, "CONFIG", "NODE")) { + JDBCUtil.addColumn(conn, "CONFIG", "NODE", "VARCHAR(64) NOT NULL FIRST", null); + Statement stmt = conn.createStatement(); + try { + stmt.executeUpdate( + "alter table CONFIG drop PRIMARY KEY, add PRIMARY KEY (NODE, OBJECT, FIELD)"); + } finally { + stmt.close(); + } + } + // END TEMP } // documentation inherited @@ -102,7 +119,7 @@ public class ConfigRepository extends JORARepository { _ctable = new Table( ConfigDatum.class, "CONFIG", - new String[] { "OBJECT", "FIELD" }, true); + new String[] { "NODE", "OBJECT", "FIELD" }, true); } protected Table _ctable;