LISTSERV mailing list manager LISTSERV 16.5

Help for HPS-SVN Archives


HPS-SVN Archives

HPS-SVN Archives


HPS-SVN@LISTSERV.SLAC.STANFORD.EDU


View:

Message:

[

First

|

Previous

|

Next

|

Last

]

By Topic:

[

First

|

Previous

|

Next

|

Last

]

By Author:

[

First

|

Previous

|

Next

|

Last

]

Font:

Proportional Font

LISTSERV Archives

LISTSERV Archives

HPS-SVN Home

HPS-SVN Home

HPS-SVN  April 2015

HPS-SVN April 2015

Subject:

r2744 - in /java/branches/conditions-HPSJAVA-488/src: main/java/org/hps/conditions/apinew/ test/java/org/hps/conditions/apinew/

From:

[log in to unmask]

Reply-To:

Notification of commits to the hps svn repository <[log in to unmask]>

Date:

Sat, 18 Apr 2015 00:20:50 -0000

Content-Type:

text/plain

Parts/Attachments:

Parts/Attachments

text/plain (1257 lines)

Author: [log in to unmask]
Date: Fri Apr 17 17:20:40 2015
New Revision: 2744

Log:
Add refactored API classes to conditions branch.

Added:
    java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/
    java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/BaseConditionsObject.java
    java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/BaseConditionsObjectCollection.java
    java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/ConditionsObject.java
    java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/ConditionsObjectCollection.java
    java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/FieldValues.java
    java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/FieldValuesMap.java
    java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/TableMetaData.java
    java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/
    java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/BaseConditionsObjectCollectionTest.java
    java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/BaseConditionsObjectTest.java

Added: java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/BaseConditionsObject.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/BaseConditionsObject.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/BaseConditionsObject.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,356 @@
+package org.hps.conditions.apinew;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.hps.conditions.api.ConditionsObjectException;
+
+/**
+ * This is a basic ORM class for performing CRUD (create, read, update, delete) operations on objects in the conditions
+ * system. Each object is mapped to a single row in a database table.
+ *
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
+public class BaseConditionsObject implements ConditionsObject {
+
+    /**
+     * Field name for collection ID.
+     */
+    static final String COLLECTION_ID_FIELD = "collection_id";
+
+    /**
+     * Date formatting for insert statement.
+     */
+    static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss");
+
+    static final int UNSET_COLLECTION_ID = -1;
+
+    static final int UNSET_ID = -1;
+
+    protected static String defaultToString(final BaseConditionsObject object) {
+        final StringBuffer sb = new StringBuffer();
+        sb.append("id: " + object.getId() + ", ");
+        for (final String field : object.getFieldValues().getFieldNames()) {
+            sb.append(field + "=" + object.getValue(Object.class, field) + ", ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append('\n');
+        return sb.toString();
+    }
+
+    /**
+     * The JDBC database connection.
+     */
+    private Connection connection;
+
+    /**
+     * The field values.
+     */
+    private final FieldValues fields;
+
+    /**
+     * The row ID of the object in its table. This will be -1 for new objects that are not in the database.
+     */
+    private int id = UNSET_ID;
+
+    /**
+     * Flag to indicate object is locally changed and database update has not been executed.
+     */
+    private boolean isDirty;
+
+    /**
+     * The information about the associated table such as the table and column names.
+     */
+    private TableMetaData tableMetaData;
+
+    protected BaseConditionsObject() {
+        this.fields = new FieldValuesMap();
+    }
+
+    /**
+     * Class constructor.
+     * <p>
+     * This should be used when creating new objects without a list of field values. A new <code>FieldValues</code>
+     * object will be automatically created from the table information.
+     *
+     * @param connection
+     * @param tableMetaData
+     */
+    public BaseConditionsObject(final Connection connection, final TableMetaData tableMetaData) {
+        this.connection = connection;
+        this.tableMetaData = tableMetaData;
+        this.fields = new FieldValuesMap(tableMetaData);
+    }
+
+    /**
+     * Class constructor.
+     * <p>
+     * This should be used when creating new objects with a list of field values.
+     *
+     * @param connection
+     * @param tableMetaData
+     * @param fields
+     */
+    public BaseConditionsObject(final Connection connection, final TableMetaData tableMetaData, final FieldValues fields) {
+        this.connection = connection;
+        this.tableMetaData = tableMetaData;
+        this.fields = fields;
+    }
+
+    /**
+     * Class constructor.
+     * <p>
+     * This should be used when the object is already in the database and the row ID is known. A SQL SELECT operation
+     * will be performed to get data into this object from the database.
+     *
+     * @param connection
+     * @param rowId
+     * @param tableMetaData
+     * @throw ConditionsObjectException if getting data into this object fails
+     * @throw SQLException if there is an SQL error when executing the SELECT operation
+     */
+    public BaseConditionsObject(final Connection connection, final TableMetaData tableMetaData, final int rowId)
+            throws ConditionsObjectException, SQLException {
+        this.connection = connection;
+        this.tableMetaData = tableMetaData;
+        this.fields = new FieldValuesMap(tableMetaData);
+        final boolean selected = select(rowId);
+        if (!selected) {
+            throw new ConditionsObjectException("Failed to select data into object using row ID " + rowId);
+        }
+    }
+
+    @Override
+    public final boolean delete() throws ConditionsObjectException, SQLException {
+        if (isNew()) {
+            throw new ConditionsObjectException("Object is not in database and so cannot be deleted.");
+        }
+        final String sql = "DELETE FROM " + this.tableMetaData.getTableName() + " WHERE id=" + this.getId();
+        // if (this.verbose) {
+        // System.out.println(sql);
+        // }
+        Statement statement = null;
+        int rowsUpdated;
+        try {
+            statement = this.connection.createStatement();
+            rowsUpdated = statement.executeUpdate(sql);
+        } finally {
+            if (statement != null) {
+                statement.close();
+            }
+        }
+        return rowsUpdated != 0;
+    }
+
+    @Override
+    public final int getCollectionId() {
+        if (this.fields.isNonNull(COLLECTION_ID_FIELD)) {
+            return getValue(Integer.class, COLLECTION_ID_FIELD);
+        } else {
+            return UNSET_COLLECTION_ID;
+        }
+    }
+
+    @Override
+    public FieldValues getFieldValues() {
+        return this.fields;
+    }
+
+    @Override
+    public final int getId() {
+        return this.id;
+    }
+
+    @Override
+    public final TableMetaData getTableMetaData() {
+        return this.tableMetaData;
+    }
+
+    @Override
+    public final <T> T getValue(final Class<T> type, final String name) {
+        return type.cast(this.fields.getValue(type, name));
+    }
+
+    @Override
+    public final boolean insert() throws ConditionsObjectException, SQLException {
+        if (!isNew()) {
+            throw new ConditionsObjectException("Cannot insert an existing record.");
+        }
+        final StringBuffer sb = new StringBuffer();
+        sb.append("INSERT INTO " + this.tableMetaData.getTableName() + " (");
+        for (final String fieldName : this.fields.getFieldNames()) {
+            sb.append(fieldName + ", ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(") VALUES (");
+        for (final Object value : this.fields.getValues()) {
+            if (value instanceof Date) {
+                sb.append("STR_TO_DATE( '" + DATE_FORMAT.format((Date) value) + "', '%Y-%m-%d %H:%i:%S' ), ");
+            } else {
+                sb.append("'" + value + "', ");
+            }
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(")");
+        final String sql = sb.toString();
+        // if (this.verbose) {
+        // System.out.println(sql);
+        // }
+        Statement statement = null;
+        ResultSet resultSet = null;
+        int rowsUpdated = 0;
+        try {
+            statement = this.connection.createStatement();
+            rowsUpdated = statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
+            resultSet = statement.getGeneratedKeys();
+            while (resultSet.next()) {
+                final int key = resultSet.getInt(1);
+                this.id = key;
+                break;
+            }
+        } finally {
+            if (resultSet != null) {
+                resultSet.close();
+            }
+            if (statement != null) {
+                statement.close();
+            }
+        }
+        return rowsUpdated != 0;
+    }
+
+    @Override
+    public final boolean isDirty() {
+        return this.isDirty;
+    }
+
+    @Override
+    public final boolean isNew() {
+        return getId() == UNSET_ID;
+    }
+
+    @Override
+    public final boolean select(final int id) throws ConditionsObjectException, SQLException {
+        this.id = id;
+        if (id < 1) {
+            throw new IllegalArgumentException("bad row ID value: " + id);
+        }
+        final StringBuffer sb = new StringBuffer();
+        sb.append("SELECT");
+        for (final String fieldName : this.tableMetaData.getFieldNames()) {
+            sb.append(" " + fieldName + ",");
+        }
+        sb.setLength(sb.length() - 1);
+        sb.append(" FROM " + this.tableMetaData.getTableName());
+        sb.append(" WHERE id = " + this.getId());
+        final String sql = sb.toString();
+        // if (this.verbose) {
+        // System.out.println(sql);
+        // }
+        Statement statement = null;
+        ResultSet resultSet = null;
+        boolean selected = false;
+        try {
+            statement = this.connection.createStatement();
+            resultSet = statement.executeQuery(sql);
+            while (resultSet.next()) {
+                for (int columnIndex = 1; columnIndex <= this.tableMetaData.getFieldNames().length; columnIndex++) {
+                    this.setValue(this.tableMetaData.getFieldNames()[columnIndex - 1], resultSet.getObject(columnIndex));
+                }
+                selected = true;
+            }
+        } finally {
+            if (resultSet != null) {
+                resultSet.close();
+            }
+            if (statement != null) {
+                statement.close();
+            }
+        }
+        return selected;
+    }
+
+    @Override
+    public void setCollectionId(final int collectionId) throws ConditionsObjectException {
+        if (this.getCollectionId() != UNSET_COLLECTION_ID) {
+            throw new ConditionsObjectException("The collection ID is already set on this object.");
+        }
+        if (collectionId <= UNSET_COLLECTION_ID) {
+            throw new ConditionsObjectException("Invalid collection ID value: " + collectionId);
+        }
+        this.setValue(COLLECTION_ID_FIELD, collectionId);
+    }
+
+    @Override
+    public final void setConnection(final Connection connection) {
+        this.connection = connection;
+    }
+
+    @Override
+    public void setId(final int id) {
+        this.id = id;
+    }
+
+    @Override
+    public final void setTableMetaData(final TableMetaData tableMetaData) {
+        this.tableMetaData = tableMetaData;
+    }
+
+    @Override
+    public final void setValue(final String name, final Object value) {
+        this.fields.setValue(name, value);
+        this.isDirty = true;
+    }
+
+    @Override
+    public String toString() {
+        return defaultToString(this);
+    }
+
+    @Override
+    public final boolean update() throws ConditionsObjectException, SQLException {
+        if (isDirty()) {
+            if (isNew()) {
+                throw new ConditionsObjectException("Cannot update a new object.");
+            }
+            final StringBuffer sb = new StringBuffer();
+            sb.append("UPDATE " + this.tableMetaData.getTableName() + " SET ");
+            for (final String fieldName : this.fields.getFieldNames()) {
+                sb.append(fieldName + "=");
+                final Object value = this.fields.getValue(fieldName);
+                if (value instanceof Date) {
+                    // FIXME: Is there a more generic way to handle this?
+                    sb.append("STR_TO_DATE( '" + DATE_FORMAT.format((Date) value) + "', '%Y-%m-%d %H:%i:%S' ), ");
+                } else {
+                    sb.append("'" + value + "', ");
+                }
+            }
+            sb.setLength(sb.length() - 2);
+            sb.append(" WHERE id=" + this.getId());
+            final String sql = sb.toString();
+            // if (this.verbose) {
+            // System.out.println(sql);
+            // }
+            Statement statement = null;
+            int rowsUpdated = 0;
+            try {
+                statement = this.connection.createStatement();
+                rowsUpdated = statement.executeUpdate(sql);
+                if (rowsUpdated > 0) {
+                    this.isDirty = false;
+                }
+            } finally {
+                if (statement != null) {
+                    statement.close();
+                }
+            }
+            return rowsUpdated != 0;
+        } else {
+            return false;
+        }
+    }
+}

Added: java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/BaseConditionsObjectCollection.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/BaseConditionsObjectCollection.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/BaseConditionsObjectCollection.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,241 @@
+package org.hps.conditions.apinew;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.hps.conditions.api.ConditionsObjectException;
+
+/**
+ *
+ */
+public class BaseConditionsObjectCollection<ObjectType extends ConditionsObject> implements
+        ConditionsObjectCollection<ObjectType> {
+
+    private int collectionId;
+    private Connection connection;
+    private final Set<ObjectType> objects = new LinkedHashSet<ObjectType>();
+    private TableMetaData tableMetaData;
+
+    protected BaseConditionsObjectCollection() {
+    }
+
+    public BaseConditionsObjectCollection(final Connection connection, final TableMetaData tableMetaData,
+            final int collectionId) throws SQLException, ConditionsObjectException {
+        this.connection = connection;
+        this.tableMetaData = tableMetaData;
+        this.collectionId = collectionId;
+        if (collectionId != -1) {
+            select(collectionId);
+        }
+    }
+
+    @Override
+    public void add(final ObjectType object) throws ConditionsObjectException {
+        // System.out.println("adding object " + object + " to collection " + getCollectionId());
+        if (getCollectionId() != BaseConditionsObject.UNSET_COLLECTION_ID) {
+            if (object.getCollectionId() != BaseConditionsObject.UNSET_ID) {
+                if (object.getCollectionId() != this.collectionId) {
+                    throw new ConditionsObjectException("Cannot add object with different collection ID: "
+                            + object.getCollectionId());
+                }
+            } else {
+                // System.out.println("object.setCollectionId - " + this.collectionId);
+                object.setCollectionId(this.collectionId);
+            }
+        }
+        this.objects.add(object);
+    }
+
+    /**
+     * @throws ConditionsObjectException
+     * @throws SQLException
+     */
+    @Override
+    public void deleteAll() throws ConditionsObjectException, SQLException {
+        Statement statement = null;
+        try {
+            final String sql = "DELETE FROM `" + this.tableMetaData.getTableName() + "` WHERE collection_id = '"
+                    + getCollectionId() + "'";
+            statement = this.connection.createStatement();
+            statement.executeUpdate(sql);
+            // System.out.println("result from delete: " + result);
+            this.connection.commit();
+        } catch (final SQLException e) {
+            e.printStackTrace();
+        } finally {
+            if (statement != null) {
+                statement.close();
+            }
+        }
+    }
+
+    @Override
+    public ObjectType get(final int index) {
+        if (index + 1 > this.size() || index < 0) {
+            throw new IndexOutOfBoundsException("index out of bounds: " + index);
+        }
+        int current = 0;
+        final Iterator<ObjectType> iterator = this.objects.iterator();
+        ObjectType object = iterator.next();
+        while (current != index && iterator.hasNext()) {
+            object = iterator.next();
+            current++;
+        }
+        return object;
+    }
+
+    @Override
+    public int getCollectionId() {
+        return this.collectionId;
+    }
+
+    @Override
+    public Collection<ObjectType> getObjects() {
+        return this.objects;
+    }
+
+    @Override
+    public TableMetaData getTableMetaData() {
+        return this.tableMetaData;
+    }
+
+    /**
+     * @param collectionId
+     * @throws ConditionsObjectException
+     * @throws SQLException
+     */
+    @Override
+    public void insertAll(final int collectionId) throws ConditionsObjectException, SQLException {
+        if (this.collectionId != -1) {
+            throw new RuntimeException("collection already exists");
+        }
+        this.collectionId = collectionId;
+
+        PreparedStatement insertObjects = null;
+        final StringBuffer sb = new StringBuffer();
+        sb.append("INSERT INTO " + this.getTableMetaData().getTableName() + " (");
+        for (final String field : this.getTableMetaData().getFieldNames()) {
+            sb.append(field + ", ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(") VALUES (");
+        for (int fieldIndex = 0; fieldIndex < this.getTableMetaData().getFieldNames().length; fieldIndex++) {
+            sb.append("?, ");
+        }
+        sb.setLength(sb.length() - 2);
+        sb.append(")");
+        final String updateStatement = sb.toString();
+        // System.out.println(updateStatement);
+        try {
+            this.connection.setAutoCommit(false);
+            insertObjects = this.connection.prepareStatement(updateStatement, Statement.RETURN_GENERATED_KEYS);
+            for (final ObjectType object : this.getObjects()) {
+                for (int fieldIndex = 0; fieldIndex < this.getTableMetaData().getFieldNames().length; fieldIndex++) {
+                    final String fieldName = this.getTableMetaData().getFieldNames()[fieldIndex];
+                    object.getValue(getTableMetaData().getFieldType(fieldName), fieldName);
+                    // System.out.println(fieldName + "=" + value);
+                    if (fieldName.equals(BaseConditionsObject.COLLECTION_ID_FIELD)) {
+                        insertObjects.setObject(fieldIndex + 1, getCollectionId());
+                    } else {
+                        insertObjects.setObject(fieldIndex + 1,
+                                object.getValue(getTableMetaData().getFieldType(fieldName), fieldName));
+                    }
+                }
+                insertObjects.executeUpdate();
+                this.connection.commit();
+                final ResultSet resultSet = insertObjects.getGeneratedKeys();
+                resultSet.next();
+                object.setId(resultSet.getInt(1));
+                // System.out.println("set id to " + resultSet.getInt(1) + " from generated keys");
+                resultSet.close();
+            }
+        } catch (final SQLException e1) {
+            e1.printStackTrace();
+            if (this.connection != null) {
+                try {
+                    System.err.println("Transaction is being rolled back ...");
+                    this.connection.rollback();
+                    System.err.println("Done rolling back transaction!");
+                } catch (final SQLException e2) {
+                    e2.printStackTrace();
+                }
+            }
+        } finally {
+            if (insertObjects != null) {
+                insertObjects.close();
+            }
+        }
+    }
+
+    @Override
+    public boolean remove(final int index) {
+        final ObjectType object = get(index);
+        if (object != null) {
+            return this.objects.remove(object);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public void select(final int collectionId) throws SQLException, ConditionsObjectException {
+        // System.out.println("BaseConditionsObjectCollection.select - " + collectionId);
+        this.collectionId = collectionId;
+        Statement statement = null;
+        try {
+            statement = this.connection.createStatement();
+            final StringBuffer sb = new StringBuffer();
+            sb.append("SELECT id, ");
+            for (final String fieldName : this.tableMetaData.getFieldNames()) {
+                sb.append(fieldName + ", ");
+            }
+            sb.setLength(sb.length() - 2);
+            sb.append(" FROM " + this.tableMetaData.getTableName() + " WHERE collection_id=" + collectionId);
+            final String sql = sb.toString();
+            // System.out.println(sql);
+            final ResultSet resultSet = statement.executeQuery(sql);
+            while (resultSet.next()) {
+                try {
+                    final ObjectType newObject = (ObjectType) this.tableMetaData.getObjectClass().newInstance();
+                    newObject.setConnection(this.connection);
+                    newObject.setTableMetaData(this.tableMetaData);
+                    final int id = resultSet.getInt(1);
+                    newObject.setId(id);
+                    for (int fieldIndex = 0; fieldIndex < this.tableMetaData.getFieldNames().length; fieldIndex++) {
+                        final String fieldName = this.tableMetaData.getFieldNames()[fieldIndex];
+                        newObject.setValue(fieldName, resultSet.getObject(fieldIndex + 2));
+                    }
+                    add(newObject);
+                } catch (InstantiationException | IllegalAccessException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        } finally {
+            if (statement != null) {
+                statement.close();
+            }
+        }
+    }
+
+    @Override
+    public int size() {
+        return this.objects.size();
+    }
+
+    @Override
+    // FIXME: Should execute prepared statement in transaction.
+    public void updateAll() throws ConditionsObjectException, SQLException {
+        for (final ObjectType object : this.objects) {
+            if (object.isDirty()) {
+                object.update();
+            }
+        }
+    }
+}

Added: java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/ConditionsObject.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/ConditionsObject.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/ConditionsObject.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,86 @@
+package org.hps.conditions.apinew;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.hps.conditions.api.ConditionsObjectException;
+
+public interface ConditionsObject {
+
+    /**
+     * @return
+     * @throws ConditionsObjectException
+     * @throws SQLException
+     */
+    boolean delete() throws ConditionsObjectException, SQLException;
+
+    /**
+     * @return
+     */
+    int getCollectionId();
+
+    FieldValues getFieldValues();
+
+    /**
+     * @return
+     */
+    int getId();
+
+    /**
+     * @return
+     */
+    TableMetaData getTableMetaData();
+
+    /**
+     * @param type
+     * @param name
+     * @return
+     */
+    <T> T getValue(final Class<T> type, final String name);
+
+    /**
+     * @return
+     * @throws ConditionsObjectException
+     * @throws SQLException
+     */
+    boolean insert() throws ConditionsObjectException, SQLException;
+
+    /**
+     * @return
+     */
+    boolean isDirty();
+
+    /**
+     * @return
+     */
+    boolean isNew();
+
+    boolean select(final int rowId) throws ConditionsObjectException, SQLException;
+
+    /**
+     * @param collectionId
+     * @throws ConditionsObjectException
+     */
+    void setCollectionId(int collectionId) throws ConditionsObjectException;
+
+    /**
+     * @param connection
+     */
+    void setConnection(Connection connection);
+
+    void setId(int id);
+
+    void setTableMetaData(TableMetaData tableMetaData);
+
+    /**
+     * @param name
+     * @param value
+     */
+    void setValue(String name, Object value);
+
+    /**
+     * @return
+     * @throws ConditionsObjectException
+     */
+    boolean update() throws ConditionsObjectException, SQLException;
+}

Added: java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/ConditionsObjectCollection.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/ConditionsObjectCollection.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/ConditionsObjectCollection.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,31 @@
+package org.hps.conditions.apinew;
+
+import java.sql.SQLException;
+import java.util.Collection;
+
+import org.hps.conditions.api.ConditionsObjectException;
+
+public interface ConditionsObjectCollection<ObjectType extends ConditionsObject> {
+
+    void add(final ObjectType object) throws ConditionsObjectException;
+
+    void deleteAll() throws ConditionsObjectException, SQLException;
+
+    ObjectType get(final int index);
+
+    int getCollectionId();
+
+    Collection<ObjectType> getObjects();
+
+    TableMetaData getTableMetaData();
+
+    void insertAll(final int collectionId) throws ConditionsObjectException, SQLException;
+
+    boolean remove(final int index);
+
+    void select(final int collectionId) throws ConditionsObjectException, SQLException;
+
+    int size();
+
+    void updateAll() throws ConditionsObjectException, SQLException;
+}

Added: java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/FieldValues.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/FieldValues.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/FieldValues.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,26 @@
+package org.hps.conditions.apinew;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
+public interface FieldValues {
+
+    Set<String> getFieldNames();
+
+    <T> T getValue(Class<T> type, String name);
+
+    Object getValue(String name);
+
+    Collection<Object> getValues();
+
+    boolean hasField(String name);
+
+    boolean isNonNull(String name);
+
+    void setValue(String name, Object value);
+
+    int size();
+}

Added: java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/FieldValuesMap.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/FieldValuesMap.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/FieldValuesMap.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,63 @@
+package org.hps.conditions.apinew;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
+public class FieldValuesMap implements FieldValues {
+
+    Map<String, Object> data = new HashMap<String, Object>();
+
+    FieldValuesMap() {
+    }
+
+    FieldValuesMap(final TableMetaData tableMetaData) {
+        for (final String fieldName : tableMetaData.getFieldNames()) {
+            this.data.put(fieldName, null);
+        }
+    }
+
+    @Override
+    public Set<String> getFieldNames() {
+        return this.data.keySet();
+    }
+
+    @Override
+    public <T> T getValue(final Class<T> type, final String name) {
+        return type.cast(this.data.get(name));
+    }
+
+    @Override
+    public Object getValue(final String name) {
+        return this.data.get(name);
+    }
+
+    @Override
+    public Collection<Object> getValues() {
+        return this.data.values();
+    }
+
+    @Override
+    public boolean hasField(final String name) {
+        return this.data.containsKey(name);
+    }
+
+    @Override
+    public boolean isNonNull(final String name) {
+        return this.data.get(name) != null;
+    }
+
+    @Override
+    public void setValue(final String name, final Object value) {
+        this.data.put(name, value);
+    }
+
+    @Override
+    public int size() {
+        return this.data.size();
+    }
+}

Added: java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/TableMetaData.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/TableMetaData.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/main/java/org/hps/conditions/apinew/TableMetaData.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,208 @@
+package org.hps.conditions.apinew;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * <p>
+ * This class provides meta data about a conditions table, including a list of conditions data fields. The list of
+ * fields does not include the collection ID or row ID, which are implicitly assumed to exist.
+ * <p>
+ * It also has references to the implementation classes which are used for the ORM onto {@link ConditionsObject} and
+ * {@link ConditionsObjectCollection}.
+ *
+ * @see org.hps.conditions.api.ConditionsObject
+ * @see org.hps.conditions.api.BaseConditionsObjectCollection
+ * @author <a href="mailto:[log in to unmask]">Jeremy McCormick</a>
+ */
+public final class TableMetaData {
+
+    /**
+     * Find table meta data by object type.
+     *
+     * @param tableMetaDataList the list of table meta data e.g. from the registry
+     * @param objectType the type of the object
+     * @return the list of table meta data that have that object type
+     */
+    public static List<TableMetaData> findByObjectType(final List<TableMetaData> tableMetaDataList,
+            final Class<? extends ConditionsObject> objectType) {
+        final List<TableMetaData> list = new ArrayList<TableMetaData>();
+        for (final TableMetaData tableMetaData : tableMetaDataList) {
+            if (tableMetaData.getObjectClass().equals(objectType)) {
+
+                list.add(tableMetaData);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * The collection class.
+     */
+    private Class<? extends BaseConditionsObjectCollection<?>> collectionClass;
+
+    /**
+     * The set of field names.
+     */
+    private Set<String> fieldNames = new LinkedHashSet<String>();
+
+    /**
+     * The map of field names to their types.
+     */
+    private Map<String, Class<?>> fieldTypes = new HashMap<String, Class<?>>();
+
+    /**
+     * The conditions key named (unused???).
+     */
+    private String key;
+
+    /**
+     * The object class.
+     */
+    private Class<? extends ConditionsObject> objectClass;
+
+    /**
+     * The table name.
+     */
+    private String tableName;
+
+    public TableMetaData() {
+    }
+
+    /**
+     * Fully qualified constructor.
+     *
+     * @param key the conditions key
+     * @param tableName the table name
+     * @param objectClass the object class
+     * @param collectionClass the collection class
+     * @param fieldNames the field names
+     * @param fieldTypes the field types
+     */
+    public TableMetaData(final String key, final String tableName, final Class<? extends ConditionsObject> objectClass,
+            final Class<? extends BaseConditionsObjectCollection<?>> collectionClass, final Set<String> fieldNames,
+            final Map<String, Class<?>> fieldTypes) {
+        if (key == null) {
+            throw new IllegalArgumentException("key is null");
+        }
+        if (tableName == null) {
+            throw new IllegalArgumentException("tableName is null");
+        }
+        if (objectClass == null) {
+            throw new IllegalArgumentException("objectClass is null");
+        }
+        if (fieldNames == null) {
+            throw new IllegalArgumentException("fieldNames is null");
+        }
+        if (collectionClass == null) {
+            throw new IllegalArgumentException("collectionClass is null");
+        }
+        if (fieldTypes == null) {
+            throw new IllegalArgumentException("fieldTypes is null");
+        }
+        this.key = key;
+        this.tableName = tableName;
+        this.objectClass = objectClass;
+        this.collectionClass = collectionClass;
+        this.fieldNames = fieldNames;
+        this.fieldTypes = fieldTypes;
+    }
+
+    /**
+     * Get the type of collection this table maps onto.
+     *
+     * @return the collection class
+     */
+    public Class<? extends BaseConditionsObjectCollection<?>> getCollectionClass() {
+        return this.collectionClass;
+    }
+
+    /**
+     * Get the names of the fields. Types are implied from the database tables.
+     *
+     * @return the names of the fields
+     */
+    public String[] getFieldNames() {
+        return this.fieldNames.toArray(new String[] {});
+    }
+
+    /**
+     * Get the type of the field called <code>fieldName</code>.
+     *
+     * @return the type of the field
+     */
+    public Class<?> getFieldType(final String fieldName) {
+        return this.fieldTypes.get(fieldName);
+    }
+
+    /**
+     * Get the key of this conditions type. May be different from table name but is usually the same.
+     *
+     * @return the key name of the conditions type
+     */
+    public String getKey() {
+        return this.key;
+    }
+
+    /**
+     * Get the type of object this table maps onto.
+     *
+     * @return the type of object
+     */
+    public Class<? extends ConditionsObject> getObjectClass() {
+        return this.objectClass;
+    }
+
+    /**
+     * Get the name of the table.
+     *
+     * @return the name of the table
+     */
+    public String getTableName() {
+        return this.tableName;
+    }
+
+    void setFieldNames(final String[] fieldNames) {
+        this.fieldNames = new HashSet<String>();
+        for (final String fieldName : fieldNames) {
+            this.fieldNames.add(fieldName);
+        }
+    }
+
+    void setFieldType(final String fieldName, final Class<?> fieldType) {
+        this.fieldTypes.put(fieldName, fieldType);
+    }
+
+    void setObjectClass(final Class<? extends ConditionsObject> objectClass) {
+        this.objectClass = objectClass;
+    }
+
+    void setTableName(final String tableName) {
+        this.tableName = tableName;
+    }
+
+    /**
+     * Convert to a string.
+     *
+     * @return This object converted to a string.
+     */
+    @Override
+    public String toString() {
+        final StringBuffer buff = new StringBuffer();
+        buff.append("tableMetaData: tableName = " + this.getTableName());
+        buff.append(", objectClass = " + this.getObjectClass().getCanonicalName());
+        buff.append(", collectionClass = " + this.getCollectionClass().getCanonicalName());
+        buff.append(", fieldNames = ");
+        for (final String field : this.getFieldNames()) {
+            buff.append(field + " ");
+        }
+        buff.setLength(buff.length() - 1);
+        buff.append('\n');
+        return buff.toString();
+    }
+}

Added: java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/BaseConditionsObjectCollectionTest.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/BaseConditionsObjectCollectionTest.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/BaseConditionsObjectCollectionTest.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,97 @@
+package org.hps.conditions.apinew;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import junit.framework.TestCase;
+
+import org.hps.conditions.api.ConditionsObjectException;
+import org.hps.conditions.database.DatabaseConditionsManager;
+
+public class BaseConditionsObjectCollectionTest extends TestCase {
+
+    /**
+     * A dummy conditions object type.
+     */
+    static class DummyConditionsObject extends BaseConditionsObject {
+
+        public DummyConditionsObject() {
+        }
+
+        DummyConditionsObject(final Connection connection, final TableMetaData tableMetaData) {
+            super(connection, tableMetaData);
+        }
+    }
+
+    /**
+     * A dummy conditions object collection type.
+     */
+    static class DummyConditionsObjectCollection extends BaseConditionsObjectCollection<DummyConditionsObject> {
+        public DummyConditionsObjectCollection() {
+        }
+
+        DummyConditionsObjectCollection(final Connection connection, final TableMetaData tableMetaData)
+                throws SQLException, ConditionsObjectException {
+            super(connection, tableMetaData, -1);
+        }
+    }
+
+    public void testBaseConditionsObjectCollection() throws Exception {
+
+        // Configure the conditions system.
+        final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
+        manager.setConnectionResource("/org/hps/conditions/config/jeremym_dev_connection.prop");
+        manager.setXmlConfig("/org/hps/conditions/config/conditions_database_no_svt.xml");
+        final Connection connection = manager.getConnection();
+
+        // Setup basic table meta data.
+        final TableMetaData tableMetaData = new TableMetaData();
+        tableMetaData.setTableName("dummy");
+        tableMetaData.setFieldNames(new String[] {"collection_id", "dummy"});
+        tableMetaData.setFieldType("collection_id", Integer.class);
+        tableMetaData.setFieldType("dummy", Double.class);
+        tableMetaData.setObjectClass(DummyConditionsObject.class);
+
+        // Create a new collection.
+        final DummyConditionsObjectCollection collection = new DummyConditionsObjectCollection(connection,
+                tableMetaData);
+
+        // Add object to collection.
+        final DummyConditionsObject object1 = new DummyConditionsObject(connection, tableMetaData);
+        object1.setValue("dummy", 1.0);
+        collection.add(object1);
+
+        // Add object to collection.
+        final DummyConditionsObject object2 = new DummyConditionsObject(connection, tableMetaData);
+        object2.setValue("dummy", 2.0);
+        collection.add(object2);
+
+        final int collectionId = 1001;
+
+        // Insert all objects into the database.
+        System.out.println("inserting objects from new collection ID " + collectionId);
+        collection.insertAll(collectionId);
+
+        System.out.println("inserted " + collection.size() + " objects");
+
+        // Create another collection.
+        final DummyConditionsObjectCollection anotherCollection = new DummyConditionsObjectCollection(connection,
+                tableMetaData);
+
+        // Select the previously created objects into this collection by using the collection_id value.
+        anotherCollection.select(collectionId);
+        System.out.println("selected " + anotherCollection.size() + " objects into collection");
+
+        // TODO: change objects in collection and then call updateAll
+        anotherCollection.get(0).setValue("dummy", 3.0);
+        anotherCollection.get(1).setValue("dummy", 4.0);
+
+        // Update all objects.
+        System.out.println("updating objects from collection " + collection.getCollectionId());
+        anotherCollection.updateAll();
+
+        // Delete all objects.
+        System.out.println("deleting objects from collection " + collection.getCollectionId());
+        collection.deleteAll();
+    }
+}

Added: java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/BaseConditionsObjectTest.java
 =============================================================================
--- java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/BaseConditionsObjectTest.java	(added)
+++ java/branches/conditions-HPSJAVA-488/src/test/java/org/hps/conditions/apinew/BaseConditionsObjectTest.java	Fri Apr 17 17:20:40 2015
@@ -0,0 +1,75 @@
+package org.hps.conditions.apinew;
+
+import java.sql.Connection;
+
+import junit.framework.TestCase;
+
+import org.hps.conditions.database.DatabaseConditionsManager;
+
+public class BaseConditionsObjectTest extends TestCase {
+
+    /**
+     * A dummy conditions object type.
+     */
+    static class DummyConditionsObject extends BaseConditionsObject {
+        DummyConditionsObject(final Connection connection, final TableMetaData tableMetaData) {
+            super(connection, tableMetaData);
+        }
+    }
+
+    /**
+     * Perform basic CRUD operations on the <code>BaseConditionsObject</code> class.
+     *
+     * @throws Exception if some test error occurs
+     */
+    public void testBaseConditionsObject() throws Exception {
+
+        // Configure the conditions system.
+        final DatabaseConditionsManager manager = DatabaseConditionsManager.getInstance();
+        manager.setConnectionResource("/org/hps/conditions/config/jeremym_dev_connection.prop");
+        manager.setXmlConfig("/org/hps/conditions/config/conditions_database_no_svt.xml");
+
+        // Open the database connection.
+        final Connection connection = manager.getConnection();
+
+        // Setup basic table meta data.
+        final TableMetaData tableMetaData = new TableMetaData();
+        tableMetaData.setTableName("dummy");
+        tableMetaData.setFieldNames(new String[] {"collection_id", "dummy"});
+
+        // Insert a new object.
+        final DummyConditionsObject newObject = new DummyConditionsObject(connection, tableMetaData);
+        newObject.setValue("collection_id", 1);
+        newObject.setValue("dummy", 1.0);
+        final boolean inserted = newObject.insert();
+        assertTrue("Insert failed.", inserted);
+        System.out.println("Inserted new object with id " + newObject.getId());
+
+        // Update the same object.
+        newObject.setValue("dummy", 2.0);
+        boolean updated = newObject.update();
+        assertTrue("Update failed.", updated);
+
+        // Update which should be ignored on non-dirty record.
+        updated = newObject.update();
+        assertTrue("Update should not have been executed.", !updated);
+        System.out.println("Update ignored on non-dirty record.");
+
+        // Select into another object using the row ID.
+        final DummyConditionsObject anotherObject = new DummyConditionsObject(connection, tableMetaData);
+        final boolean selected = anotherObject.select(newObject.getId());
+        assertTrue("Select failed.", selected);
+        assertEquals("Select object has wrong row ID.", newObject.getId(), anotherObject.getId());
+        assertEquals("Select object has wrong collcetion ID.", newObject.getValue(Integer.class, "collection_id"),
+                anotherObject.getValue(Integer.class, "collection_id"));
+        assertEquals("Select object has wrong value.", newObject.getValue(Double.class, "dummy"),
+                anotherObject.getValue(Double.class, "dummy"));
+
+        // Delete the object.
+        final boolean deleted = newObject.delete();
+        assertTrue("Delete failed.", deleted);
+
+        // Close the database connection.
+        connection.close();
+    }
+}

Top of Message | Previous Page | Permalink

Advanced Options


Options

Log In

Log In

Get Password

Get Password


Search Archives

Search Archives


Subscribe or Unsubscribe

Subscribe or Unsubscribe


Archives

November 2017
August 2017
July 2017
January 2017
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
December 2013
November 2013

ATOM RSS1 RSS2



LISTSERV.SLAC.STANFORD.EDU

Secured by F-Secure Anti-Virus CataList Email List Search Powered by the LISTSERV Email List Manager

Privacy Notice, Security Notice and Terms of Use