From 9ef4316dd65f31b81e1593eafdc600b725a9d1ea Mon Sep 17 00:00:00 2001 From: hns Date: Fri, 18 Mar 2005 02:05:24 +0000 Subject: [PATCH] Cleaned up embedded database code: Cleaned up IDatabase interface, moved code into XmlDatabase, removed IDGenerator code from NodeManager and Transactor. --- src/helma/objectmodel/IDatabase.java | 84 ++++++++-------- src/helma/objectmodel/db/NodeManager.java | 73 +------------- src/helma/objectmodel/db/Transactor.java | 7 -- src/helma/objectmodel/db/XmlDatabase.java | 111 +++++++++++++++++----- 4 files changed, 136 insertions(+), 139 deletions(-) diff --git a/src/helma/objectmodel/IDatabase.java b/src/helma/objectmodel/IDatabase.java index 62b24625..7691fccf 100644 --- a/src/helma/objectmodel/IDatabase.java +++ b/src/helma/objectmodel/IDatabase.java @@ -16,89 +16,91 @@ package helma.objectmodel; -import helma.objectmodel.INode; -import helma.objectmodel.db.IDGenerator; +import helma.framework.core.Application; + import java.io.IOException; +import java.io.File; /** * Interface that is implemented by Database wrappers */ public interface IDatabase { - // db-related + + /** + * Initialize the database with the given db directory and application. + * + * @param dbHome + * @param app + */ + public void init(File dbHome, Application app); + + /** + * Let the database know we're shutting down. + */ public void shutdown(); - // id-related + /** + * Get the next ID from the db's ID generator + * @return a unique id + * @throws ObjectNotFoundException + */ public String nextID() throws ObjectNotFoundException; - /** - * - * - * @param transaction ... - * - * @return ... - * - * @throws IOException ... - */ - public IDGenerator getIDGenerator(ITransaction transaction) - throws IOException, ObjectNotFoundException; /** + * Get the node from the database specified by the given key. * - * - * @param transaction ... - * @param idgen ... - * - * @throws IOException ... + * @param transaction + * @param key + * @return + * @throws IOException + * @throws ObjectNotFoundException if no object exists for the key. */ - public void saveIDGenerator(ITransaction transaction, IDGenerator idgen) - throws IOException; - - // node-related public INode getNode(ITransaction transaction, String key) throws IOException, ObjectNotFoundException; /** + * Save a node with the given key * - * - * @param transaction ... - * @param key ... - * @param node ... - * - * @throws IOException ... + * @param transaction + * @param key + * @param node + * @throws IOException */ public void saveNode(ITransaction transaction, String key, INode node) throws IOException; /** - * + * Delete the node specified by the given key. * * @param transaction ... * @param key ... - * * @throws IOException ... */ public void deleteNode(ITransaction transaction, String key) throws IOException; - // transaction-related + /** + * Begin a new transaction. + * + * @return the transaction + */ public ITransaction beginTransaction(); /** + * Commit a transaction, making all changes persistent * - * - * @param transaction ... - * - * @throws DatabaseException ... + * @param transaction + * @throws DatabaseException */ public void commitTransaction(ITransaction transaction) throws DatabaseException; /** + * Abort a transaction, rolling back all changes. * - * - * @param transaction ... - * - * @throws DatabaseException ... + * @param transaction + * @throws DatabaseException */ public void abortTransaction(ITransaction transaction) throws DatabaseException; diff --git a/src/helma/objectmodel/db/NodeManager.java b/src/helma/objectmodel/db/NodeManager.java index e7dd0bb6..0962737f 100644 --- a/src/helma/objectmodel/db/NodeManager.java +++ b/src/helma/objectmodel/db/NodeManager.java @@ -22,6 +22,7 @@ import helma.objectmodel.*; import java.io.IOException; import java.io.Reader; import java.io.StringReader; +import java.io.File; import java.math.BigDecimal; import java.sql.*; import java.util.*; @@ -39,8 +40,6 @@ public final class NodeManager { protected Application app; private ObjectCache cache; protected IDatabase db; - protected IDGenerator idgen; - private long idBaseValue = 1L; private boolean logSql; private Log sqlLog = null; protected boolean logReplication; @@ -62,7 +61,7 @@ public final class NodeManager { * application properties. An embedded database will be * created in dbHome if one doesn't already exist. */ - public void init(String dbHome, Properties props) + public void init(File dbHome, Properties props) throws DatabaseException, ClassNotFoundException, IllegalAccessException, InstantiationException { String cacheImpl = props.getProperty("cacheimpl", "helma.util.CacheMap"); @@ -85,19 +84,8 @@ public final class NodeManager { addNodeChangeListener(replicator); } - // get the initial id generator value - String idb = props.getProperty("idBaseValue"); - - if (idb != null) { - try { - idBaseValue = Long.parseLong(idb); - idBaseValue = Math.max(1L, idBaseValue); // 0 and 1 are reserved for root nodes - } catch (NumberFormatException ignore) { - } - } - - db = new XmlDatabase(dbHome, this); - initDb(); + db = new XmlDatabase(); + db.init(dbHome, app); } /** @@ -114,59 +102,6 @@ public final class NodeManager { * Method used to create the root node and id-generator, if they don't exist already. */ public void initDb() throws DatabaseException { - ITransaction txn = null; - - try { - txn = db.beginTransaction(); - - try { - idgen = db.getIDGenerator(txn); - - if (idgen.getValue() < idBaseValue) { - idgen.setValue(idBaseValue); - db.saveIDGenerator(txn, idgen); - } - } catch (ObjectNotFoundException notfound) { - // will start with idBaseValue+1 - idgen = new IDGenerator(idBaseValue); - db.saveIDGenerator(txn, idgen); - } - - // check if we need to set the id generator to a base value - Node node = null; - - try { - node = (Node) db.getNode(txn, "0"); - node.nmgr = safe; - } catch (ObjectNotFoundException notfound) { - node = new Node("root", "0", "Root", safe); - node.setDbMapping(app.getDbMapping("root")); - db.saveNode(txn, node.getID(), node); - registerNode(node); // register node with nodemanager cache - } - - try { - node = (Node) db.getNode(txn, "1"); - node.nmgr = safe; - } catch (ObjectNotFoundException notfound) { - node = new Node("users", "1", null, safe); - node.setDbMapping(app.getDbMapping("__userroot__")); - db.saveNode(txn, node.getID(), node); - registerNode(node); // register node with nodemanager cache - } - - db.commitTransaction(txn); - } catch (Exception x) { - System.err.println(x); - x.printStackTrace(); - - try { - db.abortTransaction(txn); - } catch (Exception ignore) { - } - - throw (new DatabaseException("Error initializing db")); - } } /** diff --git a/src/helma/objectmodel/db/Transactor.java b/src/helma/objectmodel/db/Transactor.java index 241a207a..03aa8475 100644 --- a/src/helma/objectmodel/db/Transactor.java +++ b/src/helma/objectmodel/db/Transactor.java @@ -309,13 +309,6 @@ public class Transactor extends Thread { dbm.setLastDataChange(now); } } - - // save the id-generator for the embedded db, if necessary - if (nmgr.idgen.dirty) { - nmgr.db.saveIDGenerator(txn, nmgr.idgen); - nmgr.idgen.dirty = false; - } - } long now = System.currentTimeMillis(); diff --git a/src/helma/objectmodel/db/XmlDatabase.java b/src/helma/objectmodel/db/XmlDatabase.java index fac2ab10..26d8375d 100644 --- a/src/helma/objectmodel/db/XmlDatabase.java +++ b/src/helma/objectmodel/db/XmlDatabase.java @@ -20,6 +20,7 @@ import helma.objectmodel.*; import helma.objectmodel.dom.IDGenParser; import helma.objectmodel.dom.XmlDatabaseReader; import helma.objectmodel.dom.XmlWriter; +import helma.framework.core.Application; import java.io.File; import java.io.FileOutputStream; @@ -32,27 +33,24 @@ import java.util.ArrayList; */ public final class XmlDatabase implements IDatabase { - private File dbHomeDir; - private NodeManager nmgr; - private IDGenerator idgen; + protected File dbHomeDir; + protected Application app; + protected NodeManager nmgr; + protected IDGenerator idgen; // character encoding to use when writing files. // use standard encoding by default. - private String encoding = null; + protected String encoding = null; /** - * Creates a new XmlDatabase object. - * - * @param dbHome ... - * @param nmgr ... - * - * @throws DatabaseException ... - * @throws RuntimeException ... + * Initializes the database from an application. + * @param app + * @throws DatabaseException */ - public XmlDatabase(String dbHome, NodeManager nmgr) - throws DatabaseException { - this.nmgr = nmgr; - dbHomeDir = new File(dbHome); + public void init(File dbHome, Application app) throws DatabaseException { + this.app = app; + nmgr = app.getNodeManager(); + dbHomeDir = dbHome; if (!dbHomeDir.exists() && !dbHomeDir.mkdirs()) { throw new DatabaseException("Can't create database directory "+dbHomeDir); @@ -68,7 +66,70 @@ public final class XmlDatabase implements IDatabase { copyStylesheet(stylesheet); } - this.encoding = nmgr.app.getCharset(); + this.encoding = app.getCharset(); + + // get the initial id generator value + long idBaseValue; + try { + idBaseValue = Long.parseLong(app.getProperty("idBaseValue", "1")); + // 0 and 1 are reserved for root nodes + idBaseValue = Math.max(1L, idBaseValue); + } catch (NumberFormatException ignore) { + idBaseValue = 1L; + } + + ITransaction txn = null; + + try { + txn = beginTransaction(); + + try { + idgen = getIDGenerator(txn); + + if (idgen.getValue() < idBaseValue) { + idgen.setValue(idBaseValue); + } + } catch (ObjectNotFoundException notfound) { + // will start with idBaseValue+1 + idgen = new IDGenerator(idBaseValue); + } + + // check if we need to set the id generator to a base value + Node node = null; + + try { + node = (Node) getNode(txn, "0"); + node.nmgr = nmgr.safe; + } catch (ObjectNotFoundException notfound) { + node = new Node("root", "0", "Root", nmgr.safe); + node.setDbMapping(app.getDbMapping("root")); + saveNode(txn, node.getID(), node); + // register node with nodemanager cache + nmgr.registerNode(node); + } + + try { + node = (Node) getNode(txn, "1"); + node.nmgr = nmgr.safe; + } catch (ObjectNotFoundException notfound) { + node = new Node("users", "1", null, nmgr.safe); + node.setDbMapping(app.getDbMapping("__userroot__")); + saveNode(txn, node.getID(), node); + // register node with nodemanager cache + nmgr.registerNode(node); + } + + commitTransaction(txn); + } catch (Exception x) { + x.printStackTrace(); + + try { + abortTransaction(txn); + } catch (Exception ignore) { + } + + throw (new DatabaseException("Error initializing db")); + } } /** @@ -123,6 +184,14 @@ public final class XmlDatabase implements IDatabase { * @throws DatabaseException */ public void commitTransaction(ITransaction txn) throws DatabaseException { + if (idgen.dirty) { + try { + saveIDGenerator(txn); + idgen.dirty = false; + } catch (IOException x) { + throw new DatabaseException(x.toString()); + } + } txn.commit(); } @@ -170,15 +239,13 @@ public final class XmlDatabase implements IDatabase { * Write the id-generator to file. * * @param txn - * @param idgen * @throws IOException */ - public void saveIDGenerator(ITransaction txn, IDGenerator idgen) + public void saveIDGenerator(ITransaction txn) throws IOException { File tmp = File.createTempFile("idgen.xml.", ".tmp", dbHomeDir); IDGenParser.saveIDGenerator(idgen, tmp); - this.idgen = idgen; File file = new File(dbHomeDir, "idgen.xml"); if (file.exists() && !file.canWrite()) { @@ -211,7 +278,7 @@ public final class XmlDatabase implements IDatabase { return node; } catch (Exception x) { - nmgr.app.logError("Error reading " +f, x); + app.logError("Error reading " +f, x); throw new IOException(x.toString()); } } @@ -303,8 +370,8 @@ public final class XmlDatabase implements IDatabase { res.tmpfile.delete(); } else { // error - leave tmp file and print a message - nmgr.app.logError("*** Error committing "+res.file); - nmgr.app.logError("*** Committed version is in "+res.tmpfile); + app.logError("*** Error committing "+res.file); + app.logError("*** Committed version is in "+res.tmpfile); } } catch (SecurityException ignore) { // shouldn't happen