/** * Asserts that the values of a row map those of the specified map. Uses * a ValueComparator to compare the values, thus making sure that the tests * succeed if for instance some database implementations return Long instances and some * Integer. * @param row DbRow instance * @param expectedValues Expected values in a map, having the column names as keys */ protected final void assertRowEquals(DbRow row, Map<String, Object> expectedValues) { HashMap<String, Object> rowValues = new HashMap<String, Object>(); for (int i = 0; i < row.getColumnCount(); i++) { rowValues.put(row.getColumnName(i), row.getValue(row.getColumnName(i))); } TestUtils.assertMapEquals(expectedValues, rowValues, ValueComparator.INSTANCE); }
@Override public int getColumnType(int index) { return this.baseRow.getColumnType(index); }
/** * Gets Val instances for all changed columns, i.e. columns that have non equal * original and changed values. * @return Array of Val instances that have changed values */ protected final Val[] getChangedColumns() { ArrayList<Val> changedVals = new ArrayList<Val>(); for (int i = 0; i < this.getRow().getColumnCount(); i++) { Val val = this.getVal(this.getRow().getColumnName(i)); if (val.hasChanged()) changedVals.add(val); } return (Val[])changedVals.toArray(new Val[0]); }
@Override public DbAction createUndoAction() { DbRowBuilder targetRowBuilder = DbRowUtils.newDbRow(); for (int i = 0; i < this.getRow().getColumnCount(); i++) { String columnName = this.getRow().getColumnName(i); targetRowBuilder.addValue(columnName, this.getRow().getColumnType(i), this.getVal(columnName).getValue()); } DbAction undoAction = new DeleteDbRowDbAction(this.getDbConnection(), targetRowBuilder.getRow(), this.getTableName()); return undoAction; } }
@Test public void testUpperAndLowerCase() { DbRow row = DbRowUtils.newDbRow() .addValue("lower", 1, "lower") .addValue("Mixed", 1, "Mixed") .addValue("UPPER", 1, "UPPER") .getRow(); Assert.assertEquals("LOWER", row.getColumnName(0)); Assert.assertEquals("MIXED", row.getColumnName(1)); Assert.assertEquals("UPPER", row.getColumnName(2)); Assert.assertEquals("lower", row.getValue("lower")); Assert.assertEquals("lower", row.getValue("Lower")); Assert.assertEquals("lower", row.getValue("LOWER")); }
@Override public Object getOriginalValue() { return AbstractDbRowDbAction.this.getRow().getValue(this.getColumnName()); }
@Override public String getColumnName(int index) { return this.baseRow.getColumnName(index); }
@Override public int getColumnCount() { return this.baseRow.getColumnCount(); }
Assert.assertFalse(r1Builder.getRow().equals(r2Builder.getRow())); Assert.assertFalse(r1Builder.getRow().hashCode() == r2Builder.getRow().hashCode()); Assert.assertFalse(r1Builder.getRow().equals(r2Builder.getRow())); Assert.assertFalse(r1Builder.getRow().hashCode() == r2Builder.getRow().hashCode()); Assert.assertFalse(r1Builder.getRow().equals(r2Builder.getRow())); Assert.assertFalse(r1Builder.getRow().hashCode() == r2Builder.getRow().hashCode()); Assert.assertTrue(r1Builder.getRow().equals(r3Builder.getRow())); Assert.assertTrue(r3Builder.getRow().equals(r1Builder.getRow())); Assert.assertTrue(r1Builder.getRow().equals(r1Builder.getRow())); Assert.assertFalse(r1Builder.getRow().equals(null)); Assert.assertFalse(r1Builder.getRow().equals(this));
/** * Creates a new DeleteDbRowDbAction based on the specified DbRow. * @param dbConn DbConnection instance * @param row DbRow instance * @param tableName Name of the row's table */ DeleteDbRowDbAction(DbConnection dbConn, DbRow row, String tableName) { super(dbConn, row, tableName); // Set all values to null. This will make working with the delete action easier, for instance // when trying to access changed values for (int i = 0; i < this.getRow().getColumnCount(); i++) { String columnName = this.getRow().getColumnName(i); this.setValue(columnName, null); } }
@Override public DbAction createUndoAction() { DbRowBuilder targetRowBuilder = DbRowUtils.newDbRow(); for (int i = 0; i < this.getRow().getColumnCount(); i++) { String columnName = this.getRow().getColumnName(i); targetRowBuilder.addValue(columnName, this.getRow().getColumnType(i), this.getVal(columnName).getValue()); } DbAction undoAction = new UpdateDbRowDbAction(this.getDbConnection(), targetRowBuilder.getRow(), this.getTableName()); for (Val val : this.getChangedColumns()) { undoAction.setValue(val.getColumnName(), val.getOriginalValue()); } return undoAction; } }
/** * Gets the original value (if set), otherwise returns the changed value. * @return Original value or changed value of the original value is null */ private Object getValuePrioOriginal() { if (AbstractDbRowDbAction.this.getRow().getValue(this.getColumnName()) != null) { return this.getOriginalValue(); } else { return this.getChangedValue(); } }
@Override public void execute() { XString insertQry = null; try { insertQry = new XString("INSERT INTO " + this.getTableName() + " ("); ArrayList<Object> values = new ArrayList<Object>(); XString valuesQry = new XString("VALUES ("); for (int i = 0; i < this.getRow().getColumnCount(); i++) { String columnName = this.getRow().getColumnName(i); insertQry.assertText("(", ", "); insertQry.addText(columnName); valuesQry.assertText("(", ", "); valuesQry.addText("?"); values.add(this.getVal(columnName).getValue()); } insertQry.addText(") "); insertQry.addText(valuesQry); insertQry.addText(")"); int res = this.getDbConnection().getQueryRunner().update(insertQry.toString(), (Object[])values.toArray(new Object[0])); if (res != 1) throw new JuDbException("Execution of query returned " + res + ", expected 1: " + insertQry); } catch (Exception ex) { throw new JuRuntimeException("Failed to execute insert: " + insertQry, ex); } }
@Test public void testNull() { DbRow row = DbRowUtils.newDbRow() .addValue("lower", 1, null) .getRow(); Assert.assertNull(row.getValue("lower")); Assert.assertNull(row.getValue("something")); Assert.assertNull(row.getValue(null)); try { DbRowUtils.newDbRow() .addValue(null, 1, null); Assert.fail("Adding null column should throw NullPointerException"); } catch (NullPointerException ex) { // Expected } } }