1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.jumpmind.symmetric.load;
23
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.io.OutputStream;
27 import java.io.OutputStreamWriter;
28 import java.math.BigDecimal;
29 import java.text.DecimalFormat;
30 import java.text.SimpleDateFormat;
31 import java.util.Date;
32 import java.util.Map;
33
34 import org.apache.commons.lang.StringUtils;
35 import org.jumpmind.symmetric.common.Constants;
36 import org.jumpmind.symmetric.common.csv.CsvConstants;
37 import org.jumpmind.symmetric.service.IDataLoaderService;
38 import org.jumpmind.symmetric.service.IIncomingBatchService;
39 import org.jumpmind.symmetric.test.AbstractDatabaseTest;
40 import org.jumpmind.symmetric.test.TestConstants;
41 import org.jumpmind.symmetric.transport.mock.MockTransportManager;
42 import org.junit.Assert;
43 import org.springframework.dao.EmptyResultDataAccessException;
44
45 import com.csvreader.CsvWriter;
46
47 public abstract class AbstractDataLoaderTest extends AbstractDatabaseTest {
48
49 protected final static String TEST_TABLE = "test_dataloader_table";
50
51 protected final static String[] TEST_KEYS = { "id" };
52
53 protected final static String[] TEST_COLUMNS = { "id", "string_value", "string_required_value", "char_value",
54 "char_required_value", "date_value", "time_value", "boolean_value", "integer_value", "decimal_value",
55 "double_value"};
56
57 protected static int batchId = 10000;
58
59 protected static int sequenceId = 10000;
60
61 private IDataLoaderService dataLoaderService;
62
63 private IIncomingBatchService incomingBatchService;
64
65 private MockTransportManager transportManager;
66
67 public AbstractDataLoaderTest() throws Exception {
68 }
69
70 public AbstractDataLoaderTest(String dbType) {
71 super(dbType);
72 }
73
74 protected MockTransportManager getTransportManager() {
75 if (transportManager == null) {
76 transportManager = new MockTransportManager();
77 }
78 return transportManager;
79 }
80
81 protected IIncomingBatchService getIncomingBatchService() {
82 if (incomingBatchService == null) {
83 incomingBatchService = (IIncomingBatchService) find(Constants.INCOMING_BATCH_SERVICE);
84 }
85 return incomingBatchService;
86 }
87
88 protected IDataLoaderService getDataLoaderService() {
89 if (dataLoaderService == null) {
90 dataLoaderService = (IDataLoaderService) find(Constants.DATALOADER_SERVICE);
91 dataLoaderService.setTransportManager(transportManager);
92 }
93 return dataLoaderService;
94 }
95
96 protected String printDatabase() {
97 return " The database we are testing against is " + database + ".";
98 }
99
100 @SuppressWarnings("unchecked")
101 public void testSimple(String dmlType, String[] values, String[] expectedValues) throws Exception {
102 ByteArrayOutputStream out = new ByteArrayOutputStream();
103 CsvWriter writer = getWriter(out);
104 writer.writeRecord(new String[] { CsvConstants.NODEID, TestConstants.TEST_CLIENT_EXTERNAL_ID });
105 String nextBatchId = getNextBatchId();
106 writer.writeRecord(new String[] { CsvConstants.BATCH, nextBatchId });
107 writeTable(writer, TEST_TABLE, TEST_KEYS, TEST_COLUMNS);
108 writer.write(dmlType);
109 writer.writeRecord(values, true);
110 writer.writeRecord(new String[] { CsvConstants.COMMIT, nextBatchId });
111 writer.close();
112 load(out);
113 assertTestTableEquals(values[0], expectedValues);
114 }
115
116 protected CsvWriter getWriter(OutputStream out) {
117 CsvWriter writer = new CsvWriter(new OutputStreamWriter(out), ',');
118 writer.setEscapeMode(CsvWriter.ESCAPE_MODE_BACKSLASH);
119 return writer;
120 }
121
122 protected abstract void load(ByteArrayOutputStream out) throws Exception;
123
124 protected void writeTable(CsvWriter writer, String tableName, String[] keys, String[] columns) throws IOException {
125 writer.writeRecord(new String[] { "table", tableName });
126 writer.write("keys");
127 writer.writeRecord(keys);
128 writer.write("columns");
129 writer.writeRecord(columns);
130 }
131
132 @SuppressWarnings("unchecked")
133 protected void assertTestTableEquals(String testTableId, String[] expectedValues) {
134 String sql = "select " + getSelect(TEST_COLUMNS) + " from " + TEST_TABLE + " where " + getWhere(TEST_KEYS);
135 Map<String, Object> results = null;
136 try {
137 results = getJdbcTemplate().queryForMap(sql, new Object[] { new Long(testTableId) });
138 } catch (EmptyResultDataAccessException e) {
139 }
140 if (expectedValues != null) {
141 expectedValues[1] = translateExpectedString(expectedValues[1], false);
142 expectedValues[2] = translateExpectedString(expectedValues[2], true);
143 expectedValues[3] = translateExpectedCharString(expectedValues[3], 50, false);
144 expectedValues[4] = translateExpectedCharString(expectedValues[4], 50, true);
145 }
146 assertEquals(TEST_COLUMNS, expectedValues, results);
147 }
148
149 protected void assertEquals(String[] name, String[] expected, Map<String, Object> results) {
150 if (expected == null) {
151 Assert.assertNull("Expected empty results. " + printDatabase(), results);
152 } else {
153 Assert.assertNotNull("Expected non-empty results. " + printDatabase(), results);
154 for (int i = 0; i < expected.length; i++) {
155 Object resultObj = results.get(name[i]);
156 String resultValue = null;
157 if (resultObj instanceof BigDecimal && expected[i].indexOf(".") != -1) {
158 DecimalFormat df = new DecimalFormat("0.00####################################");
159 resultValue = df.format(resultObj);
160 } else if (resultObj instanceof Date) {
161 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.0");
162 resultValue = df.format(resultObj);
163 } else if (resultObj instanceof Boolean) {
164 resultValue = ((Boolean) resultObj) ? "1" : "0";
165 } else if (resultObj instanceof Double) {
166 resultValue = resultObj.toString();
167 } else if (resultObj != null) {
168 resultValue = resultObj.toString();
169 }
170
171 Assert.assertEquals(name[i] + ". " + printDatabase(), expected[i], resultValue);
172 }
173 }
174 }
175
176 protected String getSelect(String[] columns) {
177 StringBuilder str = new StringBuilder();
178 for (int i = 0; i < columns.length; i++) {
179 str.append(columns[i]).append(i + 1 < columns.length ? ", " : "");
180 }
181 return str.toString();
182 }
183
184 protected String getWhere(String[] columns) {
185 StringBuilder str = new StringBuilder();
186 for (int i = 0; i < columns.length; i++) {
187 str.append(columns[i]).append(" = ?").append(i + 1 < columns.length ? "," : "");
188 }
189 return str.toString();
190 }
191
192 protected String translateExpectedString(String value, boolean isRequired) {
193 if (isRequired && (value == null || (value.equals("") && getDbDialect().isEmptyStringNulled()))) {
194 return TableTemplate.REQUIRED_FIELD_NULL_SUBSTITUTE;
195 } else if (value != null && value.equals("") && getDbDialect().isEmptyStringNulled()) {
196 return null;
197 }
198 return value;
199 }
200
201 protected String translateExpectedCharString(String value, int size, boolean isRequired) {
202 if (isRequired && value == null) {
203 value = TableTemplate.REQUIRED_FIELD_NULL_SUBSTITUTE;
204 }
205 if (value != null && getDbDialect().isCharSpacePadded()) {
206 return StringUtils.rightPad(value, size);
207 } else if (value != null && getDbDialect().isCharSpaceTrimmed()) {
208 return value.replaceFirst(" *$", "");
209 }
210 return value;
211 }
212
213 protected synchronized String getNextBatchId() {
214 return Integer.toString(++batchId);
215 }
216
217 protected synchronized String getBatchId() {
218 return Integer.toString(batchId);
219 }
220
221 protected synchronized String getNextId() {
222 return Integer.toString(++sequenceId);
223 }
224
225 protected synchronized String getId() {
226 return Integer.toString(sequenceId);
227 }
228
229 }