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