Work toward improving solidity. Add a few more unit tests, and some toString()
[cfb.git] / test / net / jaekl / cfb / db / driver / DbDriverMock.java
index 75813b929e937d5065d289a983dbbfc363ad907c..86ae18c1785bcbbd454ba425573bdae0eb330a14 100644 (file)
@@ -8,6 +8,7 @@ import static org.junit.Assert.assertTrue;
 import java.sql.Connection;
 import java.sql.SQLException;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 
@@ -19,6 +20,7 @@ import net.jaekl.cfb.db.SequenceMock;
 import net.jaekl.cfb.db.Sort;
 import net.jaekl.cfb.db.Table;
 import net.jaekl.cfb.db.TableMock;
+import net.jaekl.cfb.db.TypeMismatchException;
 
 public class DbDriverMock extends DbDriver {
 
@@ -104,8 +106,109 @@ public class DbDriverMock extends DbDriver {
                assertNotNull(columns);
                assertNotNull(tables);
                
-               // TODO:  produce sensible output
-               return new ArrayList<Row>();
+               if (1 != tables.length) {
+                       throw new UnsupportedOperationException("DbDriverMock does not (yet) implement table joins");
+               }
+               
+               Table schemaTable = tables[0];
+               TableMock table = m_tables.get(schemaTable.getName());
+               if (null == table) {
+                       throw new SQLException("Could not find table \"" + schemaTable.getName() + "\" in schema.");
+               }
+               
+               ArrayList<Row> rows = table.mock_getRows();
+               if (null != conditions) {
+                       ArrayList<Row> filteredRows = new ArrayList<Row>();
+                       for (Row row : rows) {
+                               boolean match = true;
+                               for (Condition condition : conditions) {
+                                       try {
+                                               if (!conditionSatisfied(condition, row)) {
+                                                       match = false;
+                                               }
+                                       }
+                                       catch (TypeMismatchException exc) {
+                                               throw new SQLException(exc);
+                                       }
+                               }
+                               if (match) {
+                                       filteredRows.add(row);
+                               }
+                       }
+                       rows = filteredRows;
+               }
+               
+               ArrayList<Row> result = new ArrayList<Row>();
+               
+               // Now, convert the rows from select(*) to select(specified columns)
+               for (Row row : rows) {
+                       Object[] values = new Object[columns.length];
+                       
+                       for (int outIdx = 0; outIdx < columns.length; ++outIdx) {
+                               for (int inIdx = 0; inIdx < row.getNumColumns(); ++inIdx) {
+                                       if (row.getColumn(inIdx).getName().equals(columns[outIdx].getName())) {
+                                               values[outIdx] = row.getValue(inIdx);
+                                       }
+                               }
+                       }
+                       result.add(new Row(columns, values));
+               }
+               
+               return result;
+       }
+       
+       private boolean aLessThanB(Object a, Object b) 
+       {
+               if ((null == a) || (null == b)) {
+                       return false;
+               }
+               
+               if (a instanceof Number) {
+                       if (! (b instanceof Number)) {
+                               throw new UnsupportedOperationException("Incompatible types");
+                       }
+                       Number first = (Number)a;
+                       Number second = (Number)b;
+                       return first.doubleValue() < second.doubleValue();
+               }
+               
+               if (a instanceof Date) {
+                       if (! (b instanceof Date)) {
+                               throw new UnsupportedOperationException("Incompatible types");
+                       }
+                       Date first = (Date)a;
+                       Date second = (Date)b;
+                       int comp = first.compareTo(second);
+                       boolean result = (comp < 0);
+                       
+                       return (result);
+               }
+               
+               throw new UnsupportedOperationException("Incompatible types");
+       }
+       
+       private boolean conditionSatisfied(Condition condition, Row row) throws TypeMismatchException, SQLException
+       {
+               for (int idx = 0; idx < row.getNumColumns(); ++idx) {
+                       Column col = row.getColumn(idx);
+                       if (condition.getColumn().equals(col)) {
+                               switch(condition.getOperation()) {
+                               case EQUAL:
+                                       return (condition.getValue().equals(row.getValue(idx)));
+                               case GREATER_THAN:
+                                       return (aLessThanB(condition.getValue(), row.getValue(idx)));
+                               case LESS_THAN:
+                                       return (aLessThanB(row.getValue(idx), condition.getValue()));
+                               case NOT_NULL:
+                                       return (null != row.getValue(idx));
+                               case NULL:
+                                       return (null == row.getValue(idx));
+                               default:
+                                       throw new UnsupportedOperationException("This condition operation is not supported by DbDriverMock");
+                               }
+                       }
+               }
+               throw new SQLException("Could not locate column \"" + condition.getColumn().getName() + "\" in TableMock.");
        }
        
        // Returns the number of rows inserted