1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.healthmarketscience.jackcess.impl;
18
19 import java.time.Instant;
20 import java.time.LocalDateTime;
21 import java.time.ZoneOffset;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Map;
25
26 import com.healthmarketscience.jackcess.Column;
27 import com.healthmarketscience.jackcess.ColumnBuilder;
28 import com.healthmarketscience.jackcess.Cursor;
29 import com.healthmarketscience.jackcess.CursorBuilder;
30 import com.healthmarketscience.jackcess.DataType;
31 import com.healthmarketscience.jackcess.Database;
32 import static com.healthmarketscience.jackcess.Database.*;
33 import com.healthmarketscience.jackcess.Row;
34 import com.healthmarketscience.jackcess.Table;
35 import com.healthmarketscience.jackcess.TableBuilder;
36 import static com.healthmarketscience.jackcess.TestUtil.*;
37 import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
38 import com.healthmarketscience.jackcess.util.RowFilterTest;
39 import junit.framework.TestCase;
40
41
42
43
44
45 public class DatabaseReadWriteTest extends TestCase
46 {
47
48 public DatabaseReadWriteTest(String name) throws Exception {
49 super(name);
50 }
51
52 public void testWriteAndRead() throws Exception {
53 for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
54 Database db = create(fileFormat);
55 doTestWriteAndRead(db);
56 db.close();
57 }
58 }
59
60 public void testWriteAndReadInMem() throws Exception {
61 for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
62 Database db = createMem(fileFormat);
63 doTestWriteAndRead(db);
64 db.close();
65 }
66 }
67
68 private static void doTestWriteAndRead(Database db) throws Exception {
69 createTestTable(db);
70 Object[] row = createTestRow();
71 row[3] = null;
72 Table table = db.getTable("Test");
73 int count = 1000;
74 ((DatabaseImpl)db).getPageChannel().startWrite();
75 try {
76 for (int i = 0; i < count; i++) {
77 table.addRow(row);
78 }
79 } finally {
80 ((DatabaseImpl)db).getPageChannel().finishWrite();
81 }
82 for (int i = 0; i < count; i++) {
83 Map<String, Object> readRow = table.getNextRow();
84 assertEquals(row[0], readRow.get("A"));
85 assertEquals(row[1], readRow.get("B"));
86 assertEquals(row[2], readRow.get("C"));
87 assertEquals(row[3], readRow.get("D"));
88 assertEquals(row[4], readRow.get("E"));
89 assertEquals(row[5], readRow.get("F"));
90 assertEquals(row[6], readRow.get("G"));
91 assertEquals(row[7], readRow.get("H"));
92 }
93 }
94
95 public void testWriteAndReadInBatch() throws Exception {
96 for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
97 Database db = createMem(fileFormat);
98 createTestTable(db);
99 int count = 1000;
100 List<Object[]> rows = new ArrayList<Object[]>(count);
101 Object[] row = createTestRow();
102 for (int i = 0; i < count; i++) {
103 rows.add(row);
104 }
105 Table table = db.getTable("Test");
106 table.addRows(rows);
107 for (int i = 0; i < count; i++) {
108 Map<String, Object> readRow = table.getNextRow();
109 assertEquals(row[0], readRow.get("A"));
110 assertEquals(row[1], readRow.get("B"));
111 assertEquals(row[2], readRow.get("C"));
112 assertEquals(row[3], readRow.get("D"));
113 assertEquals(row[4], readRow.get("E"));
114 assertEquals(row[5], readRow.get("F"));
115 assertEquals(row[6], readRow.get("G"));
116 assertEquals(row[7], readRow.get("H"));
117 }
118
119 db.close();
120 }
121 }
122
123 public void testUpdateRow() throws Exception
124 {
125 for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
126 Database db = createMem(fileFormat);
127
128 Table t = new TableBuilder("test")
129 .addColumn(new ColumnBuilder("name", DataType.TEXT))
130 .addColumn(new ColumnBuilder("id", DataType.LONG)
131 .setAutoNumber(true))
132 .addColumn(new ColumnBuilder("data", DataType.TEXT)
133 .setLength(JetFormat.TEXT_FIELD_MAX_LENGTH))
134 .toTable(db);
135
136 for(int i = 0; i < 10; ++i) {
137 t.addRow("row" + i, Column.AUTO_NUMBER, "initial data");
138 }
139
140 Cursor c = CursorBuilder.createCursor(t);
141 c.reset();
142 c.moveNextRows(2);
143 Map<String,Object> row = c.getCurrentRow();
144
145 assertEquals(createExpectedRow("name", "row1",
146 "id", 2,
147 "data", "initial data"),
148 row);
149
150 Map<String,Object> newRow = createExpectedRow(
151 "name", Column.KEEP_VALUE,
152 "id", Column.AUTO_NUMBER,
153 "data", "new data");
154 assertSame(newRow, c.updateCurrentRowFromMap(newRow));
155 assertEquals(createExpectedRow("name", "row1",
156 "id", 2,
157 "data", "new data"),
158 newRow);
159
160 c.moveNextRows(3);
161 row = c.getCurrentRow();
162
163 assertEquals(createExpectedRow("name", "row4",
164 "id", 5,
165 "data", "initial data"),
166 row);
167
168 c.updateCurrentRow(Column.KEEP_VALUE, Column.AUTO_NUMBER, "a larger amount of new data");
169
170 c.reset();
171 c.moveNextRows(2);
172 row = c.getCurrentRow();
173
174 assertEquals(createExpectedRow("name", "row1",
175 "id", 2,
176 "data", "new data"),
177 row);
178
179 c.moveNextRows(3);
180 row = c.getCurrentRow();
181
182 assertEquals(createExpectedRow("name", "row4",
183 "id", 5,
184 "data", "a larger amount of new data"),
185 row);
186
187 t.reset();
188
189 String str = createString(100);
190 for(int i = 10; i < 50; ++i) {
191 t.addRow("row" + i, Column.AUTO_NUMBER, "big data_" + str);
192 }
193
194 c.reset();
195 c.moveNextRows(9);
196 row = c.getCurrentRow();
197
198 assertEquals(createExpectedRow("name", "row8",
199 "id", 9,
200 "data", "initial data"),
201 row);
202
203 String newText = "updated big data_" + createString(200);
204
205 c.setCurrentRowValue(t.getColumn("data"), newText);
206
207 c.reset();
208 c.moveNextRows(9);
209 row = c.getCurrentRow();
210
211 assertEquals(createExpectedRow("name", "row8",
212 "id", 9,
213 "data", newText),
214 row);
215
216 List<Row> rows = RowFilterTest.toList(t);
217 assertEquals(50, rows.size());
218
219 for(Row r : rows) {
220 r.put("data", "final data " + r.get("id"));
221 }
222
223 for(Row r : rows) {
224 assertSame(r, t.updateRow(r));
225 }
226
227 t.reset();
228
229 for(Row r : t) {
230 assertEquals("final data " + r.get("id"), r.get("data"));
231 }
232
233 db.close();
234 }
235 }
236
237 public void testDateMath()
238 {
239 long now = System.currentTimeMillis();
240
241
242 doTestDateMath(now);
243
244
245 doTestDateMath(0L);
246
247
248 doTestDateMath(-ColumnImpl.MILLIS_BETWEEN_EPOCH_AND_1900);
249 }
250
251 private static void doTestDateMath(long testTime)
252 {
253 final long timeRange = 100000000L;
254 final long timeStep = 37L;
255
256 for(long time = testTime - timeRange; time < testTime + timeRange;
257 time += timeStep) {
258 double accTime = ColumnImpl.toLocalDateDouble(time);
259 long newTime = ColumnImpl.fromLocalDateDouble(accTime);
260 assertEquals(time, newTime);
261
262 Instant inst = Instant.ofEpochMilli(time);
263 LocalDateTime ldt = LocalDateTime.ofInstant(inst, ZoneOffset.UTC);
264
265 accTime = ColumnImpl.toDateDouble(ldt);
266 LocalDateTime newLdt = ColumnImpl.ldtFromLocalDateDouble(accTime);
267 assertEquals(ldt, newLdt);
268 }
269 }
270 }