4 added + 2 modified, total 6 files
java/trunk/conditions
--- java/trunk/conditions/pom.xml 2014-03-12 01:25:44 UTC (rev 291)
+++ java/trunk/conditions/pom.xml 2014-03-12 02:04:24 UTC (rev 292)
@@ -1,11 +1,12 @@
<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
<modelVersion>4.0.0</modelVersion>
<artifactId>hps-conditions</artifactId>
<name>conditions</name>
<description>HPS conditions framework</description>
-
+
<parent>
<groupId>org.hps</groupId>
<artifactId>hps-parent</artifactId>
@@ -18,7 +19,21 @@
<connection>scm:svn:svn://svn.freehep.org/hps/java/trunk/conditions/</connection>
<developerConnection>scm:svn:svn://svn.freehep.org/hps/java/trunk/conditions/</developerConnection>
</scm>
-
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>org/hps/conditions/ConditionsDatabaseObjectTest.java</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
<dependencies>
<dependency>
<groupId>org.lcsim</groupId>
@@ -40,5 +55,5 @@
<version>5.1.26</version>
</dependency>
</dependencies>
-
+
</project>
java/trunk/conditions/src/main/java/org/hps/conditions
--- java/trunk/conditions/src/main/java/org/hps/conditions/AbstractConditionsDatabaseObject.java (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/AbstractConditionsDatabaseObject.java 2014-03-12 02:04:24 UTC (rev 292)
@@ -0,0 +1,194 @@
+package org.hps.conditions;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.LinkedHashMap;
+import java.util.Map.Entry;
+
+/**
+ * The abstract implementation of {@link ConditionsDatabaseObject}.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public abstract class AbstractConditionsDatabaseObject implements ConditionsDatabaseObject {
+
+ ConnectionManager _connectionManager = null;
+ ConditionsTableMetaData _tableMetaData = null;
+ int _rowId = -1;
+ int _setId = -1;
+ boolean _isDirty = false;
+ boolean _isReadOnly = false;
+ FieldValueMap _fieldValues = null;
+
+ /**
+ * Map of field names to their values.
+ */
+ public static final class FieldValueMap extends LinkedHashMap<String, Object> {
+ }
+
+ /**
+ * Constructor for a new object which cannot initially be read only as it must be inserted.
+ * @param tableMetaData
+ * @param fieldValues
+ * @param setId
+ * @param isReadOnly
+ */
+ public AbstractConditionsDatabaseObject(
+ ConnectionManager connectionManager,
+ ConditionsTableMetaData tableMetaData,
+ int setId,
+ FieldValueMap fieldValues) {
+
+ if (connectionManager == null) {
+ throw new IllegalArgumentException("The connectionManager is null.");
+ }
+ if (tableMetaData == null) {
+ throw new IllegalArgumentException("The tableMetaData is null");
+ }
+ if (setId <= 0) {
+ throw new IllegalArgumentException("The set ID value is invalid: " + setId);
+ }
+ _connectionManager = connectionManager;
+ _tableMetaData = tableMetaData;
+ _setId = setId;
+ _rowId = -1;
+ if (fieldValues != null) {
+ _fieldValues = fieldValues;
+ } else {
+ _fieldValues = new FieldValueMap();
+ }
+ }
+
+ /**
+ * Constructor for loading data from an existing object with a row ID.
+ * @param tableMetaData
+ * @param rowId
+ * @param isReadOnly
+ */
+ public AbstractConditionsDatabaseObject(
+ ConnectionManager connectionManager,
+ ConditionsTableMetaData tableMetaData,
+ int rowId,
+ boolean isReadOnly) {
+ if (connectionManager == null) {
+ throw new IllegalArgumentException("The connectionManager cannot be null!");
+ }
+ if (tableMetaData == null) {
+ throw new IllegalArgumentException("The tableMetaData cannot be null");
+ }
+ if (rowId <= 0) {
+ throw new IllegalArgumentException("Invalid row ID: " + rowId);
+ }
+ _connectionManager = connectionManager;
+ _tableMetaData = tableMetaData;
+ _rowId = rowId;
+ _isReadOnly = isReadOnly;
+ _fieldValues = new FieldValueMap();
+ }
+
+ public ConditionsTableMetaData getTableMetaData() {
+ return _tableMetaData;
+ }
+
+ public int getRowId() {
+ return _rowId;
+ }
+
+ public int getSetId() {
+ return _setId;
+ }
+
+ public boolean isReadOnly() {
+ return _isReadOnly;
+ }
+
+ public boolean isNew() {
+ return _rowId == -1;
+ }
+
+ public boolean isDirty() {
+ return _isDirty;
+ }
+
+ public void delete() throws ConditionsDatabaseObjectException {
+ if (isReadOnly()) {
+ throw new ConditionsDatabaseObjectException("This object cannot be deleted in read only mode.");
+ }
+ String query = "DELETE FROM " + _tableMetaData.getTableName() + " WHERE id = " + _rowId;
+ _connectionManager.update(query);
+ _rowId = -1;
+ }
+
+ public void insert() throws ConditionsDatabaseObjectException, SQLException {
+ if (!isNew()) {
+ throw new ConditionsDatabaseObjectException("Record already exists in database.");
+ }
+ if (isReadOnly()) {
+ throw new ConditionsDatabaseObjectException("Cannot insert in read only mode.");
+ }
+ if (_fieldValues.size() == 0) {
+ throw new ConditionsDatabaseObjectException("There are no field values to insert.");
+ }
+ StringBuffer buff = new StringBuffer();
+ buff.append("INSERT INTO " + _tableMetaData.getTableName() + "( set_id");
+ for (Entry<String, Object> entry : _fieldValues.entrySet()) {
+ buff.append(", " + entry.getKey());
+ }
+ buff.append(" ) VALUES ( ");
+ buff.append(_setId);
+ for (Entry<String, Object> entry : _fieldValues.entrySet()) {
+ buff.append(", " + entry.getValue());
+ }
+ buff.append(") ");
+ int key = _connectionManager.update(buff.toString());
+ _rowId = key;
+ }
+
+ public void select() throws ConditionsDatabaseObjectException, SQLException {
+ if (isNew()) {
+ throw new ConditionsDatabaseObjectException("Record has not been inserted into database yet.");
+ }
+ StringBuffer buff = new StringBuffer();
+ buff.append("SELECT ");
+ for (String fieldName : _tableMetaData.getFieldNames()) {
+ buff.append(fieldName + ", ");
+ }
+ buff.delete(buff.length()-2, buff.length()-1);
+ buff.append(" FROM " + _tableMetaData.getTableName());
+ buff.append(" WHERE id = " + _rowId);
+ ResultSet resultSet = _connectionManager.query(buff.toString());
+ ResultSetMetaData metadata = resultSet.getMetaData();
+ int ncolumns = metadata.getColumnCount();
+ if (resultSet.next()) {
+ for (int i=1; i<=ncolumns; i++) {
+ _fieldValues.put(metadata.getColumnName(i), resultSet.getObject(i));
+ }
+ }
+ }
+
+ public void update() throws ConditionsDatabaseObjectException {
+ if (isReadOnly()) {
+ throw new ConditionsDatabaseObjectException("Cannot update in read only mode.");
+ }
+ if (isNew()) {
+ throw new ConditionsDatabaseObjectException("Cannot update a new record.");
+ }
+ if (_fieldValues.size() == 0) {
+ throw new ConditionsDatabaseObjectException("No field values to update.");
+ }
+ StringBuffer buff = new StringBuffer();
+ buff.append("UPDATE " + _tableMetaData.getTableName() + " SET ");
+ for (Entry entry : _fieldValues.entrySet()) {
+ buff.append(entry.getKey() + " = '" + entry.getValue() + "', ");
+ }
+ buff.delete(buff.length()-2, buff.length()-1);
+ buff.append(" WHERE id = " + _rowId);
+ _connectionManager.update(buff.toString());
+ _isDirty = false;
+ }
+
+ public void setFieldValue(String key, Object value) {
+ _fieldValues.put(key, value);
+ _isDirty = true;
+ }
+}
java/trunk/conditions/src/main/java/org/hps/conditions
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDatabaseObject.java (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsDatabaseObject.java 2014-03-12 02:04:24 UTC (rev 292)
@@ -0,0 +1,82 @@
+package org.hps.conditions;
+
+import java.sql.SQLException;
+
+/**
+ * This is an interface for accessing conditions database information by row.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public interface ConditionsDatabaseObject {
+
+ /**
+ * Get the database table meta data associated to this object.
+ * @return The database table meta data associated to this object.
+ */
+ ConditionsTableMetaData getTableMetaData();
+
+ /**
+ * Get the row ID of this object.
+ * @return The database row ID.
+ */
+ int getRowId();
+
+ /**
+ * Get the set ID of this object identifying its collection.
+ * @return The collection ID.
+ */
+ int getSetId();
+
+ /**
+ * Update this row in the database using a SQL UPDATE statement.
+ */
+ void update() throws ConditionsDatabaseObjectException;
+
+ /**
+ * Delete this object's row in the database using a SQL DELETE statement.
+ */
+ void delete() throws ConditionsDatabaseObjectException;
+
+ /**
+ * Insert this object into the database using a SQL INSERT statement.
+ */
+ void insert() throws ConditionsDatabaseObjectException, SQLException;
+
+ /**
+ * Select data into this object from the database using a SQL SELECT statement.
+ */
+ void select() throws ConditionsDatabaseObjectException, SQLException;
+
+ /**
+ * Return true if this object is read-only.
+ * @return True if object is read-only.
+ */
+ boolean isReadOnly();
+
+ /**
+ * Return true if this object is new and hasn't been inserted into the database yet.
+ * @return True if object is new.
+ */
+ boolean isNew();
+
+ /**
+ * Return true if this object's data has been modified without a database update.
+ * @return True if object is dirty.
+ */
+ boolean isDirty();
+
+ /**
+ * Generic set method. This will set the object to the 'dirty' state.
+ * @param fieldName The name of the field.
+ * @param fieldValue The field value.
+ */
+ void setFieldValue(String field, Object value);
+
+ /**
+ * Exception type throw by methods in this interface.
+ */
+ public static final class ConditionsDatabaseObjectException extends Exception {
+ public ConditionsDatabaseObjectException(String message) {
+ super(message);
+ }
+ }
+}
java/trunk/conditions/src/main/java/org/hps/conditions
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsTableMetaData.java (rev 0)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConditionsTableMetaData.java 2014-03-12 02:04:24 UTC (rev 292)
@@ -0,0 +1,24 @@
+package org.hps.conditions;
+
+import java.util.Set;
+
+public class ConditionsTableMetaData {
+
+ String _tableName;
+ Set<String> _fieldNames = null;
+
+ ConditionsTableMetaData(String tableName, Set<String> fieldNames) {
+ _tableName = tableName;
+ _fieldNames = fieldNames;
+ }
+
+ Set<String> getFieldNames() {
+ return _fieldNames;
+ }
+
+ String getTableName() {
+ return _tableName;
+ }
+
+ // TODO: Add method for getting next set ID.
+}
java/trunk/conditions/src/main/java/org/hps/conditions
--- java/trunk/conditions/src/main/java/org/hps/conditions/ConnectionManager.java 2014-03-12 01:25:44 UTC (rev 291)
+++ java/trunk/conditions/src/main/java/org/hps/conditions/ConnectionManager.java 2014-03-12 02:04:24 UTC (rev 292)
@@ -23,12 +23,11 @@
private Connection connection = null;
/**
- * Class constructor which is private so singleton must be used.
+ * Class constructor. Override at your own risk!
*/
- private ConnectionManager() {
- setupFromProperties();
+ protected ConnectionManager() {
}
-
+
/**
* Get the singleton instance of this class.
* @return The instance of this class.
@@ -63,6 +62,7 @@
Connection createConnection() {
Connection newConnection = connectionParameters.createConnection();
try {
+ System.out.println("USE " + connectionParameters.getDatabase());
newConnection.createStatement().execute("USE " + connectionParameters.getDatabase());
} catch (SQLException e) {
throw new RuntimeException("Failed to connect to database.", e);
@@ -113,6 +113,9 @@
* @return The ResultSet from the query or null.
*/
public ResultSet query(String query) {
+
+ System.out.println(query);
+
if (connection == null)
connection = createConnection();
ResultSet result = null;
@@ -125,6 +128,32 @@
return result;
}
+ /**
+ * Perform a query with an update SQL command like INSERT, DELETE or UPDATE.
+ * @return query The SQL query string.
+ * @return The number of rows affected.
+ */
+ public int update(String query) {
+
+ System.out.println(query);
+
+ if (connection == null)
+ connection = createConnection();
+ int key = -1;
+ try {
+ // NOTE: Assumes only one row is updated!
+ Statement statement = connection.createStatement();
+ statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
+ ResultSet resultSet = statement.getGeneratedKeys();
+ if (resultSet.next()) {
+ key = resultSet.getInt(1);
+ }
+ } catch (SQLException x) {
+ throw new RuntimeException("Error in query: " + query, x);
+ }
+ return key;
+ }
+
public void disconnect() {
cleanup(connection);
}
@@ -132,6 +161,7 @@
/**
* Setup the object from a properties file.
*/
+ /*
private void setupFromProperties() {
Object obj = System.getProperties().get("hps.conditions.db.configuration");
if (obj != null) {
@@ -147,4 +177,20 @@
connectionParameters = ConnectionParameters.fromProperties(p);
}
}
+ */
+ public void setupFromProperties(File propertiesFile) {
+ //Object obj = System.getProperties().get("hps.conditions.db.configuration");
+ //if (obj != null) {
+ //String config = obj.toString();
+ Properties p = new Properties();
+ try {
+ p.load(new FileInputStream(propertiesFile));
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ connectionParameters = ConnectionParameters.fromProperties(p);
+ //}
+ }
}
java/trunk/conditions/src/test/java/org/hps/conditions
--- java/trunk/conditions/src/test/java/org/hps/conditions/ConditionsDatabaseObjectTest.java (rev 0)
+++ java/trunk/conditions/src/test/java/org/hps/conditions/ConditionsDatabaseObjectTest.java 2014-03-12 02:04:24 UTC (rev 292)
@@ -0,0 +1,102 @@
+package org.hps.conditions;
+
+import java.io.File;
+import java.sql.ResultSet;
+import java.util.HashSet;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.hps.conditions.AbstractConditionsDatabaseObject.FieldValueMap;
+import org.hps.conditions.ConditionsDatabaseObject.ConditionsDatabaseObjectException;
+
+/**
+ * Test the basic functionality of a {@link ConditionsDatabaseObject} on a dummy database.
+ * @author Jeremy McCormick <[log in to unmask]>
+ */
+public class ConditionsDatabaseObjectTest extends TestCase {
+
+ String dummyTableName = "dummy_table";
+ String dummyFieldName = "dummy_field1";
+ float firstValue = 1.234f;
+ float secondValue = 5.678f;
+
+ public void testDummy() {
+
+ // Connect to local test database.
+ ConnectionManager connectionManager = new ConnectionManager();
+ //ConnectionManager connectionManager = new DummyConnectionManager();
+ connectionManager.setupFromProperties(new File("dummy_db.properties"));
+
+ // Setup table meta data information.
+ Set<String> dummyFieldNames = new HashSet<String>();
+ dummyFieldNames.add(dummyFieldName);
+ ConditionsTableMetaData tableMetaData = new ConditionsTableMetaData(dummyTableName, dummyFieldNames);
+
+ // Create a dummy data object with a single field value.
+ FieldValueMap fieldValues = new FieldValueMap();
+ fieldValues.put(dummyFieldName, firstValue);
+ ConditionsDatabaseObject dummyObject = new DummyConditionsObject(connectionManager, tableMetaData, 1, fieldValues);
+
+ try {
+ // Insert the object into the database.
+ dummyObject.insert();
+ int key = dummyObject.getRowId();
+
+ // Set a new field value and push update to the database.
+ dummyObject.setFieldValue(dummyFieldName, secondValue);
+ dummyObject.update();
+
+ // Load an object in read only mode.
+ DummyConditionsObject readOnlyObject = new DummyConditionsObject(connectionManager, tableMetaData, key);
+ readOnlyObject.select();
+ try {
+ readOnlyObject.delete();
+ throw new RuntimeException("Should not get here.");
+ } catch (ConditionsDatabaseObjectException x) {
+ System.out.println("Caught error: " + x.getMessage());
+ }
+
+ // Delete the object from the database.
+ dummyObject.delete();
+
+ } catch (Exception x) {
+ throw new RuntimeException(x);
+ }
+ }
+
+ public static class DummyConditionsObject extends AbstractConditionsDatabaseObject {
+
+ // Create a new object.
+ DummyConditionsObject(ConnectionManager connectionManager,
+ ConditionsTableMetaData tableMetaData,
+ int setId,
+ FieldValueMap fieldValues) {
+ super(connectionManager, tableMetaData, setId, fieldValues);
+ }
+
+ // Load an existing object in read only mode.
+ DummyConditionsObject(
+ ConnectionManager connectionManager,
+ ConditionsTableMetaData tableMetaData,
+ int rowId) {
+ super(connectionManager, tableMetaData, rowId, true);
+ }
+
+ }
+
+ public class DummyConnectionManager extends ConnectionManager {
+
+ public ResultSet query(String query) {
+ System.out.println("Dummy query method ...");
+ System.out.println(query);
+ return null;
+ }
+
+ public int update(String query) {
+ System.out.println("Dummy update method ...");
+ System.out.println(query);
+ return 1;
+ }
+ }
+}
SVNspam 0.1