org.jumpmind.symmetric.io.data.writer.AbstractBulkDatabaseWriterTest.java Source code

Java tutorial

Introduction

Here is the source code for org.jumpmind.symmetric.io.data.writer.AbstractBulkDatabaseWriterTest.java

Source

/**
 * Licensed to JumpMind Inc under one or more contributor
 * license agreements.  See the NOTICE file distributed
 * with this work for additional information regarding
 * copyright ownership.  JumpMind Inc licenses this file
 * to you under the GNU General Public License, version 3.0 (GPLv3)
 * (the "License"); you may not use this file except in compliance
 * with the License.
 *
 * You should have received a copy of the GNU General Public License,
 * version 3.0 (GPLv3) along with this library; if not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.jumpmind.symmetric.io.data.writer;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.ArrayUtils;
import org.jumpmind.db.platform.IDatabasePlatform;
import org.jumpmind.symmetric.io.AbstractWriterTest;
import org.jumpmind.symmetric.io.data.CsvData;
import org.jumpmind.symmetric.io.data.DataEventType;
import org.junit.Assert;
import org.junit.Test;

public abstract class AbstractBulkDatabaseWriterTest extends AbstractWriterTest {

    protected final static String[] TEST_COLUMNS = { "id", "string_value", "string_required_value", "char_value",
            "char_required_value", "date_value", "time_value", "boolean_value", "integer_value", "decimal_value",
            "double_value", "img_value" };

    @Override
    protected String getTestTable() {
        return "test_bulkload_table_2";
    }

    protected abstract boolean shouldTestRun(IDatabasePlatform platform);

    protected String encode(String str) {
        return new String(Base64.encodeBase64(str.getBytes()));
    }

    protected String encode(int[] bytes) {
        ByteBuffer bb = ByteBuffer.allocate(bytes.length);
        for (int b : bytes) {
            bb.put((byte) b);
        }
        return new String(Base64.encodeBase64(bb.array()));
    }

    protected void insertAndVerify(String[] values) {
        List<CsvData> data = new ArrayList<CsvData>();
        data.add(new CsvData(DataEventType.INSERT, (String[]) ArrayUtils.clone(values)));
        writeData(data);
        assertTestTableEquals(values[0], values);
    }

    protected abstract long writeData(List<CsvData> data);

    @Test
    public void testInsert() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), "string with space in it", "string-with-no-space",
                    "string with space in it", "string-with-no-space", "2007-01-02 00:00:00.000",
                    "2007-02-03 04:05:06.000", "0", "47", "67.89", "-0.0747663",
                    encode("string with space in it") };
            insertAndVerify(values);
        }
    }

    @Test
    public void testInsertAcrossMaxFlush() {
        if (shouldTestRun(platform)) {
            platform.getSqlTemplate().update("truncate table " + getTestTable());
            List<CsvData> data = new ArrayList<CsvData>();
            for (int i = 0; i < 30; i++) {
                String[] values = { getNextId(), "stri'ng2", "string not null2", "char2", "char not null2",
                        "2007-01-02 00:00:00.000", "2007-02-03 04:05:06.000", "0", "47", "67.89", "-0.0747663",
                        encode("string") };
                data.add(new CsvData(DataEventType.INSERT, values));
            }
            Assert.assertEquals(writeData(data), countRows(getTestTable()));
        }
    }

    @Test
    public void testInsertWithNull() {
        if (shouldTestRun(platform)) {
            for (int index : new int[] { 1, 3, 5, 6, 7, 8, 9, 10, 11 }) {
                String[] values = { "", "stri'ng2", "string not null2", "char2", "char not null2",
                        "2007-01-02 00:00:00.000", "2007-02-03 04:05:06.000", "0", "47", "67.89", "-0.0747663",
                        encode("string") };
                values[0] = getNextId();
                values[index] = null;
                insertAndVerify(values);
            }
        }
    }

    @Test
    public void testInsertWithBackslash() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), "back\\slash", "double\\\\back\\slash", "back\\slash",
                    "double\\\\back\\slash", "2007-01-02 00:00:00.000", "2007-02-03 04:05:06.000", "1", "47",
                    "67.89", "-0.0747663", encode("back\\slash") };
            insertAndVerify(values);
        }
    }

    @Test
    public void testInsertWithQuotes() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), "single'qoute", "double''single'quote", "single'quote",
                    "double''single'quote", "2007-01-02 00:00:00.000", "2007-02-03 04:05:06.000", "1", "47",
                    "67.89", "-0.0747663", encode("single'qoute") };
            insertAndVerify(values);
            String[] values2 = { getNextId(), "single\"qoute", "double\"\"single\"quote", "single\"quote",
                    "double\"\"single\"quote", "2007-01-02 00:00:00.000", "2007-02-03 04:05:06.000", "1", "47",
                    "67.89", "-0.0747663", encode("single\"quote") };
            insertAndVerify(values2);
        }
    }

    @Test
    public void testInsertWithCommas() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), "single,comma", "double,,comma,comma", "single,comma",
                    "double,,comma,comma", "2007-01-02 00:00:00.000", "2007-02-03 04:05:06.000", "1", "47", "67.89",
                    "-0.0747663", encode("single,comma") };
            insertAndVerify(values);
        }
    }

    @Test
    public void testInsertWithNonEscaped() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), null, "\n\0\r\t\f\'\"", null, "\n\0\r\t\f\'\"",
                    "2007-01-02 00:00:00.000", "2007-02-03 04:05:06.000", "1", "47", "67.89", "-0.0747663",
                    encode("\n\0\r\t\f\'\"") };
            insertAndVerify(values);
        }
    }

    @Test
    public void testInsertWithSpecialEscape() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), "\\n\\N\\0\\r\\t\\b\\f\\", "\\n\\N\\0\\r\\t\\b\\f\\",
                    "\\x31\\x32\\x33", "\\061\\062\\063", "2007-01-02 00:00:00.000", "2007-02-03 04:05:06.000", "1",
                    "47", "67.89", "-0.0747663", encode("\\n\\N\\0\\r\\t\\\n\r\t\b\f\0\\x31\\x32\\x33") };
            insertAndVerify(values);
        }
    }

    @Test
    public void testInsertWithUnicode() {
        if (shouldTestRun(platform)) {
            String unicode = "\u007E\u00A7\u2702\u28FF\uFFE6\uFFFC\uFFFF";
            String[] values = { getNextId(), null, "", null, "", "2007-01-02 00:00:00.000",
                    "2007-02-03 04:05:06.000", "1", "47", "67.89", "-0.0747663", encode(unicode) };
            insertAndVerify(values);
        }
    }

    @Test
    public void testInsertBlobInvalidUnicode() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), null, "x", null, "x", null, null, null, null, null, null, encode(
                    new int[] { 0x10, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0xF5 }) };
            insertAndVerify(values);
        }
    }

    @Test
    public void testInsertBlobRange() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), null, "x", null, "x", null, null, null, null, null, null, null };
            int[] bytes = new int[255 * 255];
            for (int i = 0; i <= 255; i++) {
                bytes[i] = i;
                for (int j = 0; j <= 255; j++) {
                    bytes[i + j + 1] = j;
                }
            }
            values[11] = encode(bytes);
            insertAndVerify(values);
        }
    }

    @Test
    public void testInsertBlobRandom() {
        if (shouldTestRun(platform)) {
            String[] values = { getNextId(), null, "x", null, "x", null, null, null, null, null, null, null };
            int[] bytes = new int[8192];
            Random randomGenerator = new Random();
            for (int i = 0; i < bytes.length; ++i) {
                bytes[i] = randomGenerator.nextInt(256);
            }
            values[11] = encode(bytes);
            insertAndVerify(values);
        }
    }

    @Override
    protected void assertTestTableEquals(String testTableId, String[] expectedValues) {
        String sql = "select " + getSelect(TEST_COLUMNS) + " from " + getTestTable() + " where "
                + getWhere(TEST_KEYS);
        Map<String, Object> results = platform.getSqlTemplate().queryForMap(sql, new Long(testTableId));

        if (expectedValues != null) {
            expectedValues[1] = translateExpectedString(expectedValues[1], false);
            expectedValues[2] = translateExpectedString(expectedValues[2], true);
            expectedValues[3] = translateExpectedCharString(expectedValues[3], 50, false);
            expectedValues[4] = translateExpectedCharString(expectedValues[4], 50, true);
            if (expectedValues[11] != null) {
                expectedValues[11] = new String(Hex.encodeHex(Base64.decodeBase64(expectedValues[11].getBytes())));
                results.put(TEST_COLUMNS[11], new String(Hex.encodeHex((byte[]) results.get(TEST_COLUMNS[11]))));
            }
        }
        assertEquals(TEST_COLUMNS, expectedValues, results);
    }

}