Search in sources :

Example 6 with CsvData

use of org.jumpmind.symmetric.io.data.CsvData in project symmetric-ds by JumpMind.

the class TransformedData method buildTargetCsvData.

public CsvData buildTargetCsvData() {
    CsvData data = new CsvData(this.targetDmlType);
    if (targetDmlType != DataEventType.DELETE) {
        data.putParsedData(CsvData.ROW_DATA, getColumnValues());
    }
    if (targetDmlType == DataEventType.UPDATE || targetDmlType == DataEventType.DELETE) {
        data.putParsedData(CsvData.OLD_DATA, getOldColumnValues());
        data.putParsedData(CsvData.PK_DATA, getKeyValues());
    }
    data.putAttribute(getClass().getName(), this);
    return data;
}
Also used : CsvData(org.jumpmind.symmetric.io.data.CsvData)

Example 7 with CsvData

use of org.jumpmind.symmetric.io.data.CsvData in project symmetric-ds by JumpMind.

the class AbstractDatabaseWriterConflictResolver method needsResolved.

public void needsResolved(AbstractDatabaseWriter writer, CsvData data, LoadStatus loadStatus) {
    DataEventType originalEventType = data.getDataEventType();
    DatabaseWriterSettings writerSettings = writer.getWriterSettings();
    Conflict conflict = writerSettings.pickConflict(writer.getTargetTable(), writer.getBatch());
    Statistics statistics = writer.getStatistics().get(writer.getBatch());
    long statementCount = statistics.get(DataWriterStatisticConstants.STATEMENTCOUNT);
    long lineNumber = statistics.get(DataWriterStatisticConstants.LINENUMBER);
    ResolvedData resolvedData = writerSettings.getResolvedData(statementCount);
    logConflictHappened(conflict, data, writer, resolvedData, lineNumber);
    switch(originalEventType) {
        case INSERT:
            if (resolvedData != null) {
                attemptToResolve(resolvedData, data, writer, conflict);
            } else {
                switch(conflict.getResolveType()) {
                    case FALLBACK:
                        performFallbackToUpdate(writer, data, conflict, true);
                        break;
                    case NEWER_WINS:
                        if ((conflict.getDetectType() == DetectConflict.USE_TIMESTAMP && isTimestampNewer(conflict, writer, data)) || (conflict.getDetectType() == DetectConflict.USE_VERSION && isVersionNewer(conflict, writer, data))) {
                            performFallbackToUpdate(writer, data, conflict, true);
                        } else {
                            if (!conflict.isResolveRowOnly()) {
                                throw new IgnoreBatchException();
                            }
                        }
                        break;
                    case IGNORE:
                        ignore(writer, conflict);
                        break;
                    case MANUAL:
                    default:
                        attemptToResolve(resolvedData, data, writer, conflict);
                        break;
                }
            }
            break;
        case UPDATE:
            if (resolvedData != null) {
                attemptToResolve(resolvedData, data, writer, conflict);
            } else {
                switch(conflict.getResolveType()) {
                    case FALLBACK:
                        if (conflict.getDetectType() == DetectConflict.USE_PK_DATA) {
                            CsvData withoutOldData = data.copyWithoutOldData();
                            try {
                                // we already tried to update using the pk
                                performFallbackToInsert(writer, withoutOldData, conflict, true);
                            } catch (ConflictException ex) {
                                performFallbackToUpdate(writer, withoutOldData, conflict, true);
                            }
                        } else {
                            try {
                                performFallbackToUpdate(writer, data, conflict, true);
                            } catch (ConflictException ex) {
                                performFallbackToInsert(writer, data, conflict, true);
                            }
                        }
                        break;
                    case NEWER_WINS:
                        if ((conflict.getDetectType() == DetectConflict.USE_TIMESTAMP && isTimestampNewer(conflict, writer, data)) || (conflict.getDetectType() == DetectConflict.USE_VERSION && isVersionNewer(conflict, writer, data))) {
                            try {
                                performFallbackToUpdate(writer, data, conflict, false);
                            } catch (ConflictException ex) {
                                performFallbackToInsert(writer, data, conflict, true);
                            }
                        } else {
                            if (!conflict.isResolveRowOnly()) {
                                throw new IgnoreBatchException();
                            }
                        }
                        break;
                    case IGNORE:
                        ignore(writer, conflict);
                        break;
                    case MANUAL:
                    default:
                        attemptToResolve(resolvedData, data, writer, conflict);
                        break;
                }
            }
            break;
        case DELETE:
            switch(conflict.getResolveType()) {
                case FALLBACK:
                    LoadStatus status = LoadStatus.CONFLICT;
                    if (conflict.getDetectType() != DetectConflict.USE_PK_DATA) {
                        status = writer.delete(data, false);
                    }
                    if (status == LoadStatus.CONFLICT) {
                        writer.getStatistics().get(writer.getBatch()).increment(DataWriterStatisticConstants.MISSINGDELETECOUNT);
                    }
                    break;
                case IGNORE:
                    ignore(writer, conflict);
                    break;
                case NEWER_WINS:
                    // nothing to do ...
                    break;
                case MANUAL:
                default:
                    if (resolvedData != null) {
                        if (!resolvedData.isIgnoreRow()) {
                            writer.delete(data, false);
                        } else {
                            if (!conflict.isResolveRowOnly()) {
                                throw new IgnoreBatchException();
                            }
                        }
                    } else {
                        throw new ConflictException(data, writer.getTargetTable(), false, conflict, (Exception) writer.getContext().get(AbstractDatabaseWriter.CONFLICT_ERROR));
                    }
                    break;
            }
            break;
        default:
            break;
    }
    logConflictResolution(conflict, data, writer, resolvedData, lineNumber);
}
Also used : DetectConflict(org.jumpmind.symmetric.io.data.writer.Conflict.DetectConflict) LoadStatus(org.jumpmind.symmetric.io.data.writer.AbstractDatabaseWriter.LoadStatus) DataEventType(org.jumpmind.symmetric.io.data.DataEventType) Statistics(org.jumpmind.util.Statistics) CsvData(org.jumpmind.symmetric.io.data.CsvData)

Example 8 with CsvData

use of org.jumpmind.symmetric.io.data.CsvData in project symmetric-ds by JumpMind.

the class DatabaseWriterTest method testUpdateDetectOldDataManual.

@Test
public void testUpdateDetectOldDataManual() {
    Conflict setting = new Conflict();
    setting.setConflictId("unit.test");
    setting.setDetectType(DetectConflict.USE_OLD_DATA);
    setting.setResolveRowOnly(false);
    setting.setResolveChangesOnly(false);
    setting.setResolveType(ResolveConflict.MANUAL);
    writerSettings.setDefaultConflictSetting(setting);
    String origId = getNextId();
    String[] originalValues = massageExpectectedResultsForDialect(new String[] { origId, "string2", "changed value", "char2", "char not null2", "2007-01-02 03:20:10.000", "2012-03-12 07:00:00.000", "0", "2", "67.89", "-0.0747663" });
    CsvData data = new CsvData(DataEventType.INSERT, originalValues);
    writeData(data, originalValues);
    String[] oldData = CollectionUtils.copyOfRange(originalValues, 0, originalValues.length);
    oldData[2] = "original value";
    oldData = massageExpectectedResultsForDialect(oldData);
    String[] newData = CollectionUtils.copyOfRange(originalValues, 0, originalValues.length);
    newData[2] = "new value";
    newData = massageExpectectedResultsForDialect(newData);
    CsvData update = new CsvData(DataEventType.UPDATE);
    update.putParsedData(CsvData.ROW_DATA, newData);
    update.putParsedData(CsvData.OLD_DATA, oldData);
    try {
        writeData(update);
        Assert.fail("Should have received a conflict exception");
    } catch (ConflictException ex) {
        Statistics stats = lastDataWriterUsed.getStatistics().values().iterator().next();
        long statementNumber = stats.get(DataWriterStatisticConstants.STATEMENTCOUNT);
        ResolvedData resolvedData = new ResolvedData(statementNumber, update.getCsvData(CsvData.ROW_DATA), false);
        writerSettings.setResolvedData(resolvedData);
        writeData(update);
        Map<String, Object> row = queryForRow(origId);
        Assert.assertNotNull(row);
        Assert.assertEquals(newData[2], row.get("string_required_value"));
    }
}
Also used : ResolveConflict(org.jumpmind.symmetric.io.data.writer.Conflict.ResolveConflict) DetectConflict(org.jumpmind.symmetric.io.data.writer.Conflict.DetectConflict) Statistics(org.jumpmind.util.Statistics) Map(java.util.Map) CsvData(org.jumpmind.symmetric.io.data.CsvData) AbstractWriterTest(org.jumpmind.symmetric.io.AbstractWriterTest) Test(org.junit.Test)

Example 9 with CsvData

use of org.jumpmind.symmetric.io.data.CsvData in project symmetric-ds by JumpMind.

the class DatabaseWriterTest method testStringSpaces.

@Test
public void testStringSpaces() throws Exception {
    String[] values = new String[TEST_COLUMNS.length];
    values[0] = getNextId();
    values[1] = "  two spaces before";
    if (!(platform instanceof AseDatabasePlatform)) {
        values[2] = "two spaces after  ";
    }
    values[3] = " one space before";
    values[4] = "one space after ";
    writeData(new CsvData(DataEventType.INSERT, values), values);
}
Also used : AseDatabasePlatform(org.jumpmind.db.platform.ase.AseDatabasePlatform) CsvData(org.jumpmind.symmetric.io.data.CsvData) AbstractWriterTest(org.jumpmind.symmetric.io.AbstractWriterTest) Test(org.junit.Test)

Example 10 with CsvData

use of org.jumpmind.symmetric.io.data.CsvData in project symmetric-ds by JumpMind.

the class DatabaseWriterTest method testUpdateDetectTimestampNewerWins.

@Test
public void testUpdateDetectTimestampNewerWins() {
    Conflict setting = new Conflict();
    setting.setConflictId("unit.test");
    setting.setDetectType(DetectConflict.USE_TIMESTAMP);
    setting.setDetectExpression("time_value");
    setting.setResolveRowOnly(true);
    setting.setResolveChangesOnly(true);
    setting.setResolveType(ResolveConflict.NEWER_WINS);
    writerSettings.setDefaultConflictSetting(setting);
    String id = getNextId();
    String[] originalValues = massageExpectectedResultsForDialect(new String[] { id, "string2", "string not null2", "char2", "char not null2", "2007-01-02 03:20:10.000", "2012-03-12 07:00:00.000", "0", "47", "67.89", "-0.0747663" });
    CsvData data = new CsvData(DataEventType.INSERT, originalValues);
    writeData(data, originalValues);
    String[] updateShouldNotBeApplied = CollectionUtils.copyOfRange(originalValues, 0, originalValues.length);
    updateShouldNotBeApplied[2] = "updated string";
    updateShouldNotBeApplied[6] = "2012-03-12 06:00:00.0";
    data = new CsvData(DataEventType.UPDATE, massageExpectectedResultsForDialect(updateShouldNotBeApplied));
    writeData(data, originalValues);
    String[] updateShouldBeApplied = CollectionUtils.copyOfRange(originalValues, 0, originalValues.length);
    updateShouldBeApplied[2] = "string3";
    updateShouldBeApplied[6] = "2012-03-12 08:00:00.000";
    data = new CsvData(DataEventType.UPDATE, massageExpectectedResultsForDialect(updateShouldBeApplied));
    writeData(data, updateShouldBeApplied);
}
Also used : ResolveConflict(org.jumpmind.symmetric.io.data.writer.Conflict.ResolveConflict) DetectConflict(org.jumpmind.symmetric.io.data.writer.Conflict.DetectConflict) CsvData(org.jumpmind.symmetric.io.data.CsvData) AbstractWriterTest(org.jumpmind.symmetric.io.AbstractWriterTest) Test(org.junit.Test)

Aggregations

CsvData (org.jumpmind.symmetric.io.data.CsvData)54 Test (org.junit.Test)36 AbstractWriterTest (org.jumpmind.symmetric.io.AbstractWriterTest)23 ArrayList (java.util.ArrayList)15 Table (org.jumpmind.db.model.Table)13 OracleDatabasePlatform (org.jumpmind.db.platform.oracle.OracleDatabasePlatform)7 Batch (org.jumpmind.symmetric.io.data.Batch)7 DetectConflict (org.jumpmind.symmetric.io.data.writer.Conflict.DetectConflict)7 ResolveConflict (org.jumpmind.symmetric.io.data.writer.Conflict.ResolveConflict)6 Statistics (org.jumpmind.util.Statistics)6 CommonsDbcpNativeJdbcExtractor (org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor)5 Connection (java.sql.Connection)4 DataSource (javax.sql.DataSource)4 Column (org.jumpmind.db.model.Column)4 NativeJdbcExtractor (org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor)4 IOException (java.io.IOException)3 IoException (org.jumpmind.exception.IoException)3 DataContext (org.jumpmind.symmetric.io.data.DataContext)3 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2