You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DatabaseTest.java 41KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296
  1. /*
  2. Copyright (c) 2007 Health Market Science, Inc.
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with this library; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  14. USA
  15. You can contact Health Market Science at info@healthmarketscience.com
  16. or at the following address:
  17. Health Market Science
  18. 2700 Horizon Drive
  19. Suite 200
  20. King of Prussia, PA 19406
  21. */
  22. package com.healthmarketscience.jackcess;
  23. import java.io.File;
  24. import java.io.FileInputStream;
  25. import java.io.FileNotFoundException;
  26. import java.io.FileOutputStream;
  27. import java.io.IOException;
  28. import java.io.InputStream;
  29. import java.io.OutputStream;
  30. import java.io.PrintWriter;
  31. import java.math.BigDecimal;
  32. import java.nio.ByteBuffer;
  33. import java.sql.Types;
  34. import java.text.DateFormat;
  35. import java.text.SimpleDateFormat;
  36. import java.util.ArrayList;
  37. import java.util.Arrays;
  38. import java.util.Calendar;
  39. import java.util.Collections;
  40. import java.util.Date;
  41. import java.util.HashSet;
  42. import java.util.Iterator;
  43. import java.util.LinkedHashMap;
  44. import java.util.List;
  45. import java.util.Map;
  46. import java.util.Set;
  47. import java.util.UUID;
  48. import junit.framework.TestCase;
  49. import static com.healthmarketscience.jackcess.Database.*;
  50. import static com.healthmarketscience.jackcess.JetFormatTest.*;
  51. /**
  52. * @author Tim McCune
  53. */
  54. public class DatabaseTest extends TestCase {
  55. static boolean _autoSync = Database.DEFAULT_AUTO_SYNC;
  56. public DatabaseTest(String name) throws Exception {
  57. super(name);
  58. }
  59. public static Database open(final TestDB testDB) throws Exception {
  60. final Database db = Database.open(testDB.getFile(), true, _autoSync);
  61. assertEquals("Wrong JetFormat.", testDB.getExpectedFormat(), db.getFormat());
  62. assertEquals("Wrong FileFormat.", testDB.getExpectedFileFormat(),
  63. db.getFileFormat());
  64. return db;
  65. }
  66. public static Database create(final Database.FileFormat fileFormat) throws Exception {
  67. return create(fileFormat, false);
  68. }
  69. public static Database create(final Database.FileFormat fileFormat, boolean keep) throws Exception {
  70. return Database.create(fileFormat, createTempFile(keep), _autoSync);
  71. }
  72. public static Database openCopy(final TestDB testDB) throws Exception {
  73. return openCopy(testDB, false);
  74. }
  75. public static Database openCopy(final TestDB testDB, boolean keep)
  76. throws Exception
  77. {
  78. File tmp = createTempFile(keep);
  79. copyFile(testDB.getFile(), tmp);
  80. return Database.open(tmp, false, _autoSync);
  81. }
  82. public void testInvalidTableDefs() throws Exception {
  83. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  84. Database db = create(fileFormat);
  85. try {
  86. db.createTable("test", Collections.<Column>emptyList());
  87. fail("created table with no columns?");
  88. } catch(IllegalArgumentException e) {
  89. // success
  90. }
  91. try {
  92. new TableBuilder("test")
  93. .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
  94. .addColumn(new ColumnBuilder("a", DataType.MEMO).toColumn())
  95. .toTable(db);
  96. fail("created table with duplicate column names?");
  97. } catch(IllegalArgumentException e) {
  98. // success
  99. }
  100. try {
  101. new TableBuilder("test")
  102. .addColumn(new ColumnBuilder("A", DataType.TEXT)
  103. .setLengthInUnits(352).toColumn())
  104. .toTable(db);
  105. fail("created table with invalid column length?");
  106. } catch(IllegalArgumentException e) {
  107. // success
  108. }
  109. try {
  110. new TableBuilder("test")
  111. .addColumn(new ColumnBuilder("A_" + createString(70), DataType.TEXT)
  112. .toColumn())
  113. .toTable(db);
  114. fail("created table with too long column name?");
  115. } catch(IllegalArgumentException e) {
  116. // success
  117. }
  118. new TableBuilder("test")
  119. .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
  120. .toTable(db);
  121. try {
  122. new TableBuilder("Test")
  123. .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
  124. .toTable(db);
  125. fail("create duplicate tables?");
  126. } catch(IllegalArgumentException e) {
  127. // success
  128. }
  129. }
  130. }
  131. public void testReadDeletedRows() throws Exception {
  132. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.DEL)) {
  133. Table table = open(testDB).getTable("Table");
  134. int rows = 0;
  135. while (table.getNextRow() != null) {
  136. rows++;
  137. }
  138. assertEquals(2, rows);
  139. }
  140. }
  141. public void testGetColumns() throws Exception {
  142. for (final TestDB testDB : SUPPORTED_DBS_TEST) {
  143. List<Column> columns = open(testDB).getTable("Table1").getColumns();
  144. assertEquals(9, columns.size());
  145. checkColumn(columns, 0, "A", DataType.TEXT);
  146. checkColumn(columns, 1, "B", DataType.TEXT);
  147. checkColumn(columns, 2, "C", DataType.BYTE);
  148. checkColumn(columns, 3, "D", DataType.INT);
  149. checkColumn(columns, 4, "E", DataType.LONG);
  150. checkColumn(columns, 5, "F", DataType.DOUBLE);
  151. checkColumn(columns, 6, "G", DataType.SHORT_DATE_TIME);
  152. checkColumn(columns, 7, "H", DataType.MONEY);
  153. checkColumn(columns, 8, "I", DataType.BOOLEAN);
  154. }
  155. }
  156. static void checkColumn(List<Column> columns, int columnNumber, String name,
  157. DataType dataType)
  158. throws Exception
  159. {
  160. Column column = columns.get(columnNumber);
  161. assertEquals(name, column.getName());
  162. assertEquals(dataType, column.getType());
  163. }
  164. public void testGetNextRow() throws Exception {
  165. for (final TestDB testDB : SUPPORTED_DBS_TEST) {
  166. final Database db = open(testDB);
  167. assertEquals(4, db.getTableNames().size());
  168. final Table table = db.getTable("Table1");
  169. Map<String, Object> row1 = table.getNextRow();
  170. Map<String, Object> row2 = table.getNextRow();
  171. if(!"abcdefg".equals(row1.get("A"))) {
  172. Map<String, Object> tmpRow = row1;
  173. row1 = row2;
  174. row2 = tmpRow;
  175. }
  176. checkTestDBTable1RowABCDEFG(testDB, table, row1);
  177. checkTestDBTable1RowA(testDB, table, row2);
  178. }
  179. }
  180. static void checkTestDBTable1RowABCDEFG(final TestDB testDB, final Table table, final Map<String, Object> row)
  181. throws IOException {
  182. assertEquals("testDB: " + testDB + "; table: " + table, "abcdefg", row.get("A"));
  183. assertEquals("hijklmnop", row.get("B"));
  184. assertEquals(new Byte((byte) 2), row.get("C"));
  185. assertEquals(new Short((short) 222), row.get("D"));
  186. assertEquals(new Integer(333333333), row.get("E"));
  187. assertEquals(new Double(444.555d), row.get("F"));
  188. final Calendar cal = Calendar.getInstance();
  189. cal.setTime((Date) row.get("G"));
  190. assertEquals(Calendar.SEPTEMBER, cal.get(Calendar.MONTH));
  191. assertEquals(21, cal.get(Calendar.DAY_OF_MONTH));
  192. assertEquals(1974, cal.get(Calendar.YEAR));
  193. assertEquals(0, cal.get(Calendar.HOUR_OF_DAY));
  194. assertEquals(0, cal.get(Calendar.MINUTE));
  195. assertEquals(0, cal.get(Calendar.SECOND));
  196. assertEquals(0, cal.get(Calendar.MILLISECOND));
  197. assertEquals(Boolean.TRUE, row.get("I"));
  198. }
  199. static void checkTestDBTable1RowA(final TestDB testDB, final Table table, final Map<String, Object> row)
  200. throws IOException {
  201. assertEquals("testDB: " + testDB + "; table: " + table, "a", row.get("A"));
  202. assertEquals("b", row.get("B"));
  203. assertEquals(new Byte((byte) 0), row.get("C"));
  204. assertEquals(new Short((short) 0), row.get("D"));
  205. assertEquals(new Integer(0), row.get("E"));
  206. assertEquals(new Double(0d), row.get("F"));
  207. final Calendar cal = Calendar.getInstance();
  208. cal.setTime((Date) row.get("G"));
  209. assertEquals(Calendar.DECEMBER, cal.get(Calendar.MONTH));
  210. assertEquals(12, cal.get(Calendar.DAY_OF_MONTH));
  211. assertEquals(1981, cal.get(Calendar.YEAR));
  212. assertEquals(0, cal.get(Calendar.HOUR_OF_DAY));
  213. assertEquals(0, cal.get(Calendar.MINUTE));
  214. assertEquals(0, cal.get(Calendar.SECOND));
  215. assertEquals(0, cal.get(Calendar.MILLISECOND));
  216. assertEquals(Boolean.FALSE, row.get("I"));
  217. }
  218. public void testCreate() throws Exception {
  219. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  220. Database db = create(fileFormat);
  221. assertEquals(0, db.getTableNames().size());
  222. }
  223. }
  224. public void testWriteAndRead() throws Exception {
  225. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  226. Database db = create(fileFormat);
  227. createTestTable(db);
  228. Object[] row = createTestRow();
  229. row[3] = null;
  230. Table table = db.getTable("Test");
  231. int count = 1000;
  232. for (int i = 0; i < count; i++) {
  233. table.addRow(row);
  234. }
  235. for (int i = 0; i < count; i++) {
  236. Map<String, Object> readRow = table.getNextRow();
  237. assertEquals(row[0], readRow.get("A"));
  238. assertEquals(row[1], readRow.get("B"));
  239. assertEquals(row[2], readRow.get("C"));
  240. assertEquals(row[3], readRow.get("D"));
  241. assertEquals(row[4], readRow.get("E"));
  242. assertEquals(row[5], readRow.get("F"));
  243. assertEquals(row[6], readRow.get("G"));
  244. assertEquals(row[7], readRow.get("H"));
  245. }
  246. }
  247. }
  248. public void testWriteAndReadInBatch() throws Exception {
  249. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  250. Database db = create(fileFormat);
  251. createTestTable(db);
  252. int count = 1000;
  253. List<Object[]> rows = new ArrayList<Object[]>(count);
  254. Object[] row = createTestRow();
  255. for (int i = 0; i < count; i++) {
  256. rows.add(row);
  257. }
  258. Table table = db.getTable("Test");
  259. table.addRows(rows);
  260. for (int i = 0; i < count; i++) {
  261. Map<String, Object> readRow = table.getNextRow();
  262. assertEquals(row[0], readRow.get("A"));
  263. assertEquals(row[1], readRow.get("B"));
  264. assertEquals(row[2], readRow.get("C"));
  265. assertEquals(row[3], readRow.get("D"));
  266. assertEquals(row[4], readRow.get("E"));
  267. assertEquals(row[5], readRow.get("F"));
  268. assertEquals(row[6], readRow.get("G"));
  269. assertEquals(row[7], readRow.get("H"));
  270. }
  271. }
  272. }
  273. public void testDeleteCurrentRow() throws Exception {
  274. // make sure correct row is deleted
  275. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  276. Database db = create(fileFormat);
  277. createTestTable(db);
  278. Object[] row1 = createTestRow("Tim1");
  279. Object[] row2 = createTestRow("Tim2");
  280. Object[] row3 = createTestRow("Tim3");
  281. Table table = db.getTable("Test");
  282. table.addRows(Arrays.asList(row1, row2, row3));
  283. assertRowCount(3, table);
  284. table.reset();
  285. table.getNextRow();
  286. table.getNextRow();
  287. table.deleteCurrentRow();
  288. table.reset();
  289. Map<String, Object> outRow = table.getNextRow();
  290. assertEquals("Tim1", outRow.get("A"));
  291. outRow = table.getNextRow();
  292. assertEquals("Tim3", outRow.get("A"));
  293. assertRowCount(2, table);
  294. // test multi row delete/add
  295. db = create(fileFormat);
  296. createTestTable(db);
  297. Object[] row = createTestRow();
  298. table = db.getTable("Test");
  299. for (int i = 0; i < 10; i++) {
  300. row[3] = i;
  301. table.addRow(row);
  302. }
  303. row[3] = 1974;
  304. assertRowCount(10, table);
  305. table.reset();
  306. table.getNextRow();
  307. table.deleteCurrentRow();
  308. assertRowCount(9, table);
  309. table.reset();
  310. table.getNextRow();
  311. table.deleteCurrentRow();
  312. assertRowCount(8, table);
  313. table.reset();
  314. for (int i = 0; i < 8; i++) {
  315. table.getNextRow();
  316. }
  317. table.deleteCurrentRow();
  318. assertRowCount(7, table);
  319. table.addRow(row);
  320. assertRowCount(8, table);
  321. table.reset();
  322. for (int i = 0; i < 3; i++) {
  323. table.getNextRow();
  324. }
  325. table.deleteCurrentRow();
  326. assertRowCount(7, table);
  327. table.reset();
  328. assertEquals(2, table.getNextRow().get("D"));
  329. }
  330. }
  331. public void testReadLongValue() throws Exception {
  332. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.TEST2)) {
  333. Database db = open(testDB);
  334. Table table = db.getTable("MSP_PROJECTS");
  335. Map<String, Object> row = table.getNextRow();
  336. assertEquals("Jon Iles this is a a vawesrasoih aksdkl fas dlkjflkasjd flkjaslkdjflkajlksj dfl lkasjdf lkjaskldfj lkas dlk lkjsjdfkl; aslkdf lkasjkldjf lka skldf lka sdkjfl;kasjd falksjdfljaslkdjf laskjdfk jalskjd flkj aslkdjflkjkjasljdflkjas jf;lkasjd fjkas dasdf asd fasdf asdf asdmhf lksaiyudfoi jasodfj902384jsdf9 aw90se fisajldkfj lkasj dlkfslkd jflksjadf as", row.get("PROJ_PROP_AUTHOR"));
  337. assertEquals("T", row.get("PROJ_PROP_COMPANY"));
  338. assertEquals("Standard", row.get("PROJ_INFO_CAL_NAME"));
  339. assertEquals("Project1", row.get("PROJ_PROP_TITLE"));
  340. byte[] foundBinaryData = (byte[])row.get("RESERVED_BINARY_DATA");
  341. byte[] expectedBinaryData =
  342. toByteArray(new File("test/data/test2BinData.dat"));
  343. assertTrue(Arrays.equals(expectedBinaryData, foundBinaryData));
  344. }
  345. }
  346. public void testWriteLongValue() throws Exception {
  347. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  348. Database db = create(fileFormat);
  349. Table table =
  350. new TableBuilder("test")
  351. .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
  352. .addColumn(new ColumnBuilder("B", DataType.MEMO).toColumn())
  353. .addColumn(new ColumnBuilder("C", DataType.OLE).toColumn())
  354. .toTable(db);
  355. String testStr = "This is a test";
  356. String longMemo = createString(2030);
  357. byte[] oleValue = toByteArray(new File("test/data/test2BinData.dat"));
  358. table.addRow(testStr, testStr, null);
  359. table.addRow(testStr, longMemo, oleValue);
  360. table.reset();
  361. Map<String, Object> row = table.getNextRow();
  362. assertEquals(testStr, row.get("A"));
  363. assertEquals(testStr, row.get("B"));
  364. assertNull(row.get("C"));
  365. row = table.getNextRow();
  366. assertEquals(testStr, row.get("A"));
  367. assertEquals(longMemo, row.get("B"));
  368. assertTrue(Arrays.equals(oleValue, (byte[])row.get("C")));
  369. }
  370. }
  371. public void testManyMemos() throws Exception {
  372. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  373. Database db = create(fileFormat);
  374. final int numColumns = 126;
  375. TableBuilder bigTableBuilder = new TableBuilder("test");
  376. for (int i = 0; i < numColumns; i++)
  377. {
  378. Column column = new ColumnBuilder("column_" + i, DataType.MEMO)
  379. .toColumn();
  380. bigTableBuilder.addColumn(column);
  381. }
  382. Table bigTable = bigTableBuilder.toTable(db);
  383. List<Object[]> expectedRows = new ArrayList<Object[]>();
  384. for (int j = 0; j < 3; j++)
  385. {
  386. Object[] rowData = new String[numColumns];
  387. for (int i = 0; i < numColumns; i++)
  388. {
  389. rowData[i] = "v_" + i + ";" + (j + 999);
  390. }
  391. expectedRows.add(rowData);
  392. bigTable.addRow(rowData);
  393. }
  394. String extra1 = createString(100);
  395. String extra2 = createString(2050);
  396. for (int j = 0; j < 1; j++)
  397. {
  398. Object[] rowData = new String[numColumns];
  399. for (int i = 0; i < numColumns; i++)
  400. {
  401. rowData[i] = "v_" + i + ";" + (j + 999) + extra2;
  402. }
  403. expectedRows.add(rowData);
  404. bigTable.addRow(rowData);
  405. }
  406. for (int j = 0; j < 2; j++)
  407. {
  408. Object[] rowData = new String[numColumns];
  409. for (int i = 0; i < numColumns; i++)
  410. {
  411. String tmp = "v_" + i + ";" + (j + 999);
  412. if((i % 3) == 0) {
  413. tmp += extra1;
  414. } else if((i % 7) == 0) {
  415. tmp += extra2;
  416. }
  417. rowData[i] = tmp;
  418. }
  419. expectedRows.add(rowData);
  420. bigTable.addRow(rowData);
  421. }
  422. bigTable.reset();
  423. Iterator<Object[]> expIter = expectedRows.iterator();
  424. for(Map<?,?> row : bigTable) {
  425. Object[] expectedRow = expIter.next();
  426. assertEquals(Arrays.asList(expectedRow),
  427. new ArrayList<Object>(row.values()));
  428. }
  429. db.close();
  430. }
  431. }
  432. public void testMissingFile() throws Exception {
  433. File bogusFile = new File("fooby-dooby.mdb");
  434. assertTrue(!bogusFile.exists());
  435. try {
  436. Database.open(bogusFile, true, _autoSync);
  437. fail("FileNotFoundException should have been thrown");
  438. } catch(FileNotFoundException e) {
  439. }
  440. assertTrue(!bogusFile.exists());
  441. }
  442. public void testReadWithDeletedCols() throws Exception {
  443. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.DEL_COL)) {
  444. Table table = open(testDB).getTable("Table1");
  445. Map<String, Object> expectedRow0 = new LinkedHashMap<String, Object>();
  446. expectedRow0.put("id", 0);
  447. expectedRow0.put("id2", 2);
  448. expectedRow0.put("data", "foo");
  449. expectedRow0.put("data2", "foo2");
  450. Map<String, Object> expectedRow1 = new LinkedHashMap<String, Object>();
  451. expectedRow1.put("id", 3);
  452. expectedRow1.put("id2", 5);
  453. expectedRow1.put("data", "bar");
  454. expectedRow1.put("data2", "bar2");
  455. int rowNum = 0;
  456. Map<String, Object> row = null;
  457. while ((row = table.getNextRow()) != null) {
  458. if(rowNum == 0) {
  459. assertEquals(expectedRow0, row);
  460. } else if(rowNum == 1) {
  461. assertEquals(expectedRow1, row);
  462. } else if(rowNum >= 2) {
  463. fail("should only have 2 rows");
  464. }
  465. rowNum++;
  466. }
  467. }
  468. }
  469. public void testCurrency() throws Exception {
  470. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  471. Database db = create(fileFormat);
  472. Table table = new TableBuilder("test")
  473. .addColumn(new ColumnBuilder("A", DataType.MONEY).toColumn())
  474. .toTable(db);
  475. table.addRow(new BigDecimal("-2341234.03450"));
  476. table.addRow(37L);
  477. table.addRow("10000.45");
  478. table.reset();
  479. List<Object> foundValues = new ArrayList<Object>();
  480. Map<String, Object> row = null;
  481. while((row = table.getNextRow()) != null) {
  482. foundValues.add(row.get("A"));
  483. }
  484. assertEquals(Arrays.asList(
  485. new BigDecimal("-2341234.0345"),
  486. new BigDecimal("37.0000"),
  487. new BigDecimal("10000.4500")),
  488. foundValues);
  489. try {
  490. table.addRow(new BigDecimal("342523234145343543.3453"));
  491. fail("IOException should have been thrown");
  492. } catch(IOException e) {
  493. // ignored
  494. }
  495. }
  496. }
  497. public void testGUID() throws Exception
  498. {
  499. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  500. Database db = create(fileFormat);
  501. Table table = new TableBuilder("test")
  502. .addColumn(new ColumnBuilder("A", DataType.GUID).toColumn())
  503. .toTable(db);
  504. table.addRow("{32A59F01-AA34-3E29-453F-4523453CD2E6}");
  505. table.addRow("{32a59f01-aa34-3e29-453f-4523453cd2e6}");
  506. table.addRow("{11111111-1111-1111-1111-111111111111}");
  507. table.addRow(" {FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF} ");
  508. table.addRow(UUID.fromString("32a59f01-1234-3e29-4aaf-4523453cd2e6"));
  509. table.reset();
  510. List<Object> foundValues = new ArrayList<Object>();
  511. Map<String, Object> row = null;
  512. while((row = table.getNextRow()) != null) {
  513. foundValues.add(row.get("A"));
  514. }
  515. assertEquals(Arrays.asList(
  516. "{32A59F01-AA34-3E29-453F-4523453CD2E6}",
  517. "{32A59F01-AA34-3E29-453F-4523453CD2E6}",
  518. "{11111111-1111-1111-1111-111111111111}",
  519. "{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}",
  520. "{32A59F01-1234-3E29-4AAF-4523453CD2E6}"),
  521. foundValues);
  522. try {
  523. table.addRow("3245234");
  524. fail("IOException should have been thrown");
  525. } catch(IOException e) {
  526. // ignored
  527. }
  528. }
  529. }
  530. public void testNumeric() throws Exception
  531. {
  532. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  533. Database db = create(fileFormat);
  534. Column col = new ColumnBuilder("A", DataType.NUMERIC)
  535. .setScale(4).setPrecision(8).toColumn();
  536. assertTrue(col.isVariableLength());
  537. Table table = new TableBuilder("test")
  538. .addColumn(col)
  539. .addColumn(new ColumnBuilder("B", DataType.NUMERIC)
  540. .setScale(8).setPrecision(28).toColumn())
  541. .toTable(db);
  542. table.addRow(new BigDecimal("-1234.03450"),
  543. new BigDecimal("23923434453436.36234219"));
  544. table.addRow(37L, 37L);
  545. table.addRow("1000.45", "-3452345321000");
  546. table.reset();
  547. List<Object> foundSmallValues = new ArrayList<Object>();
  548. List<Object> foundBigValues = new ArrayList<Object>();
  549. Map<String, Object> row = null;
  550. while((row = table.getNextRow()) != null) {
  551. foundSmallValues.add(row.get("A"));
  552. foundBigValues.add(row.get("B"));
  553. }
  554. assertEquals(Arrays.asList(
  555. new BigDecimal("-1234.0345"),
  556. new BigDecimal("37.0000"),
  557. new BigDecimal("1000.4500")),
  558. foundSmallValues);
  559. assertEquals(Arrays.asList(
  560. new BigDecimal("23923434453436.36234219"),
  561. new BigDecimal("37.00000000"),
  562. new BigDecimal("-3452345321000.00000000")),
  563. foundBigValues);
  564. try {
  565. table.addRow(new BigDecimal("3245234.234"),
  566. new BigDecimal("3245234.234"));
  567. fail("IOException should have been thrown");
  568. } catch(IOException e) {
  569. // ignored
  570. }
  571. }
  572. }
  573. public void testFixedNumeric() throws Exception
  574. {
  575. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.FIXED_NUMERIC)) {
  576. Database db = openCopy(testDB);
  577. Table t = db.getTable("test");
  578. boolean first = true;
  579. for(Column col : t.getColumns()) {
  580. if(first) {
  581. assertTrue(col.isVariableLength());
  582. assertEquals(DataType.MEMO, col.getType());
  583. first = false;
  584. } else {
  585. assertFalse(col.isVariableLength());
  586. assertEquals(DataType.NUMERIC, col.getType());
  587. }
  588. }
  589. Map<String, Object> row = t.getNextRow();
  590. assertEquals("some data", row.get("col1"));
  591. assertEquals(new BigDecimal("1"), row.get("col2"));
  592. assertEquals(new BigDecimal("0"), row.get("col3"));
  593. assertEquals(new BigDecimal("0"), row.get("col4"));
  594. assertEquals(new BigDecimal("4"), row.get("col5"));
  595. assertEquals(new BigDecimal("-1"), row.get("col6"));
  596. assertEquals(new BigDecimal("1"), row.get("col7"));
  597. Object[] tmpRow = new Object[]{
  598. "foo", new BigDecimal("1"), new BigDecimal(3), new BigDecimal("13"),
  599. new BigDecimal("-17"), new BigDecimal("0"), new BigDecimal("8734")};
  600. t.addRow(tmpRow);
  601. t.reset();
  602. t.getNextRow();
  603. row = t.getNextRow();
  604. assertEquals(tmpRow[0], row.get("col1"));
  605. assertEquals(tmpRow[1], row.get("col2"));
  606. assertEquals(tmpRow[2], row.get("col3"));
  607. assertEquals(tmpRow[3], row.get("col4"));
  608. assertEquals(tmpRow[4], row.get("col5"));
  609. assertEquals(tmpRow[5], row.get("col6"));
  610. assertEquals(tmpRow[6], row.get("col7"));
  611. db.close();
  612. }
  613. }
  614. public void testMultiPageTableDef() throws Exception
  615. {
  616. for (final TestDB testDB : SUPPORTED_DBS_TEST) {
  617. List<Column> columns = open(testDB).getTable("Table2").getColumns();
  618. assertEquals(89, columns.size());
  619. }
  620. }
  621. public void testOverflow() throws Exception
  622. {
  623. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.OVERFLOW)) {
  624. Database mdb = open(testDB);
  625. Table table = mdb.getTable("Table1");
  626. // 7 rows, 3 and 5 are overflow
  627. table.getNextRow();
  628. table.getNextRow();
  629. Map<String, Object> row = table.getNextRow();
  630. assertEquals(Arrays.<Object>asList(
  631. null, "row3col3", null, null, null, null, null,
  632. "row3col9", null),
  633. new ArrayList<Object>(row.values()));
  634. table.getNextRow();
  635. row = table.getNextRow();
  636. assertEquals(Arrays.<Object>asList(
  637. null, "row5col2", null, null, null, null, null, null,
  638. null),
  639. new ArrayList<Object>(row.values()));
  640. table.reset();
  641. assertRowCount(7, table);
  642. }
  643. }
  644. public void testLongValueAsMiddleColumn() throws Exception
  645. {
  646. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  647. Database db = create(fileFormat);
  648. Table newTable = new TableBuilder("NewTable")
  649. .addColumn(new ColumnBuilder("a").setSQLType(Types.INTEGER).toColumn())
  650. .addColumn(new ColumnBuilder("b").setSQLType(Types.LONGVARCHAR).toColumn())
  651. .addColumn(new ColumnBuilder("c").setSQLType(Types.VARCHAR).toColumn())
  652. .toTable(db);
  653. String lval = createString(2000); // "--2000 chars long text--";
  654. String tval = createString(40); // "--40chars long text--";
  655. newTable.addRow(new Integer(1), lval, tval);
  656. newTable = db.getTable("NewTable");
  657. Map<String, Object> readRow = newTable.getNextRow();
  658. assertEquals(new Integer(1), readRow.get("a"));
  659. assertEquals(lval, readRow.get("b"));
  660. assertEquals(tval, readRow.get("c"));
  661. }
  662. }
  663. public void testUsageMapPromotion() throws Exception {
  664. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.PROMOTION)) {
  665. Database db = openCopy(testDB);
  666. Table t = db.getTable("jobDB1");
  667. String lval = createString(255); // "--255 chars long text--";
  668. if (FileFormat.V2007.equals(testDB.getExpectedFileFormat())) {
  669. // @todo Field order differs with V2007
  670. System.err.println("\n*** TODO: " + getName()
  671. + "(): Is OK that " + testDB.getExpectedFileFormat().name() + " field order differs? ***");
  672. }
  673. for(int i = 0; i < 1000; ++i) {
  674. if (FileFormat.V2007.equals(testDB.getExpectedFileFormat())) {
  675. // @todo Field order differs with V2007
  676. t.addRow(i, 13, 57, lval, lval, lval, lval, lval, lval, 47.0d);
  677. } else {
  678. t.addRow(i, 13, 57, 47.0d, lval, lval, lval, lval, lval, lval);
  679. }
  680. }
  681. Set<Integer> ids = new HashSet<Integer>();
  682. for(Map<String,Object> row : t) {
  683. ids.add((Integer)row.get("ID"));
  684. }
  685. assertEquals(1000, ids.size());
  686. db.close();
  687. }
  688. }
  689. public void testLargeTableDef() throws Exception {
  690. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  691. Database db = create(fileFormat);
  692. final int numColumns = 90;
  693. List<Column> columns = new ArrayList<Column>();
  694. List<String> colNames = new ArrayList<String>();
  695. for(int i = 0; i < numColumns; ++i) {
  696. String colName = "MyColumnName" + i;
  697. colNames.add(colName);
  698. columns.add(new ColumnBuilder(colName, DataType.TEXT).toColumn());
  699. }
  700. db.createTable("test", columns);
  701. Table t = db.getTable("test");
  702. List<String> row = new ArrayList<String>();
  703. Map<String,Object> expectedRowData = new LinkedHashMap<String, Object>();
  704. for(int i = 0; i < numColumns; ++i) {
  705. String value = "" + i + " some row data";
  706. row.add(value);
  707. expectedRowData.put(colNames.get(i), value);
  708. }
  709. t.addRow(row.toArray());
  710. t.reset();
  711. assertEquals(expectedRowData, t.getNextRow());
  712. db.close();
  713. }
  714. }
  715. public void testAutoNumber() throws Exception {
  716. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  717. Database db = create(fileFormat);
  718. Table table = new TableBuilder("test")
  719. .addColumn(new ColumnBuilder("a", DataType.LONG)
  720. .setAutoNumber(true).toColumn())
  721. .addColumn(new ColumnBuilder("b", DataType.TEXT).toColumn())
  722. .toTable(db);
  723. doTestAutoNumber(table);
  724. db.close();
  725. }
  726. }
  727. public void testAutoNumberPK() throws Exception {
  728. for (final TestDB testDB : SUPPORTED_DBS_TEST) {
  729. Database db = openCopy(testDB);
  730. Table table = db.getTable("Table3");
  731. doTestAutoNumber(table);
  732. db.close();
  733. }
  734. }
  735. private void doTestAutoNumber(Table table) throws Exception
  736. {
  737. table.addRow(null, "row1");
  738. table.addRow(13, "row2");
  739. table.addRow("flubber", "row3");
  740. table.reset();
  741. table.addRow(Column.AUTO_NUMBER, "row4");
  742. table.addRow(Column.AUTO_NUMBER, "row5");
  743. table.reset();
  744. List<Map<String, Object>> expectedRows =
  745. createExpectedTable(
  746. createExpectedRow(
  747. "a", 1,
  748. "b", "row1"),
  749. createExpectedRow(
  750. "a", 2,
  751. "b", "row2"),
  752. createExpectedRow(
  753. "a", 3,
  754. "b", "row3"),
  755. createExpectedRow(
  756. "a", 4,
  757. "b", "row4"),
  758. createExpectedRow(
  759. "a", 5,
  760. "b", "row5"));
  761. assertTable(expectedRows, table);
  762. }
  763. public void testWriteAndReadDate() throws Exception {
  764. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  765. Database db = create(fileFormat);
  766. Table table = new TableBuilder("test")
  767. .addColumn(new ColumnBuilder("name", DataType.TEXT).toColumn())
  768. .addColumn(new ColumnBuilder("date", DataType.SHORT_DATE_TIME)
  769. .toColumn())
  770. .toTable(db);
  771. // since jackcess does not really store millis, shave them off before
  772. // storing the current date/time
  773. long curTimeNoMillis = (System.currentTimeMillis() / 1000L);
  774. curTimeNoMillis *= 1000L;
  775. DateFormat df = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
  776. List<Date> dates =
  777. new ArrayList<Date>(
  778. Arrays.asList(
  779. df.parse("19801231 00:00:00"),
  780. df.parse("19930513 14:43:27"),
  781. null,
  782. df.parse("20210102 02:37:00"),
  783. new Date(curTimeNoMillis)));
  784. Calendar c = Calendar.getInstance();
  785. for(int year = 1801; year < 2050; year +=3) {
  786. for(int month = 0; month <= 12; ++month) {
  787. for(int day = 1; day < 29; day += 3) {
  788. c.clear();
  789. c.set(Calendar.YEAR, year);
  790. c.set(Calendar.MONTH, month);
  791. c.set(Calendar.DAY_OF_MONTH, day);
  792. dates.add(c.getTime());
  793. }
  794. }
  795. }
  796. for(Date d : dates) {
  797. table.addRow("row " + d, d);
  798. }
  799. List<Date> foundDates = new ArrayList<Date>();
  800. for(Map<String,Object> row : table) {
  801. foundDates.add((Date)row.get("date"));
  802. }
  803. assertEquals(dates.size(), foundDates.size());
  804. for(int i = 0; i < dates.size(); ++i) {
  805. Date expected = dates.get(i);
  806. Date found = foundDates.get(i);
  807. if(expected == null) {
  808. assertNull(found);
  809. } else {
  810. // there are some rounding issues due to dates being stored as
  811. // doubles, but it results in a 1 millisecond difference, so i'm not
  812. // going to worry about it
  813. long expTime = expected.getTime();
  814. long foundTime = found.getTime();
  815. try {
  816. assertTrue((expTime == foundTime) ||
  817. (Math.abs(expTime - foundTime) <= 1));
  818. } catch(Error e) {
  819. System.err.println("Expected " + expTime + ", found " + foundTime);
  820. throw e;
  821. }
  822. }
  823. }
  824. }
  825. }
  826. public void testSystemTable() throws Exception
  827. {
  828. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  829. Database db = create(fileFormat);
  830. if (!FileFormat.V2003.equals(fileFormat)
  831. && !FileFormat.V2007.equals(fileFormat)) {
  832. assertNotNull("file format: " + fileFormat, db.getSystemTable("MSysAccessObjects"));
  833. } else {
  834. // @todo Does is matter that v2003, v2007 template files have no "MSysAccessObjects" table?
  835. System.err.println("\n*** TODO: " + getName()
  836. + "(): Is OK that " + fileFormat.name() + " template file has no \"MSysAccessObjects\" table? ***");
  837. assertNull("file format: " + fileFormat, db.getSystemTable("MSysAccessObjects"));
  838. }
  839. assertNotNull(db.getSystemTable("MSysObjects"));
  840. assertNotNull(db.getSystemTable("MSysQueries"));
  841. assertNotNull(db.getSystemTable("MSysACES"));
  842. assertNotNull(db.getSystemTable("MSysRelationships"));
  843. assertNull(db.getSystemTable("MSysBogus"));
  844. db.close();
  845. }
  846. }
  847. public void testUpdateRow() throws Exception
  848. {
  849. for (final FileFormat fileFormat : SUPPORTED_FILEFORMATS) {
  850. Database db = create(fileFormat);
  851. Table t = new TableBuilder("test")
  852. .addColumn(new ColumnBuilder("name", DataType.TEXT).toColumn())
  853. .addColumn(new ColumnBuilder("id", DataType.LONG)
  854. .setAutoNumber(true).toColumn())
  855. .addColumn(new ColumnBuilder("data", DataType.TEXT)
  856. .setLength(JetFormat.TEXT_FIELD_MAX_LENGTH).toColumn())
  857. .toTable(db);
  858. for(int i = 0; i < 10; ++i) {
  859. t.addRow("row" + i, Column.AUTO_NUMBER, "initial data");
  860. }
  861. Cursor c = Cursor.createCursor(t);
  862. c.reset();
  863. c.moveNextRows(2);
  864. Map<String,Object> row = c.getCurrentRow();
  865. assertEquals(createExpectedRow("name", "row1",
  866. "id", 2,
  867. "data", "initial data"),
  868. row);
  869. c.updateCurrentRow(Column.KEEP_VALUE, Column.AUTO_NUMBER, "new data");
  870. c.moveNextRows(3);
  871. row = c.getCurrentRow();
  872. assertEquals(createExpectedRow("name", "row4",
  873. "id", 5,
  874. "data", "initial data"),
  875. row);
  876. c.updateCurrentRow(Column.KEEP_VALUE, Column.AUTO_NUMBER, "a larger amount of new data");
  877. c.reset();
  878. c.moveNextRows(2);
  879. row = c.getCurrentRow();
  880. assertEquals(createExpectedRow("name", "row1",
  881. "id", 2,
  882. "data", "new data"),
  883. row);
  884. c.moveNextRows(3);
  885. row = c.getCurrentRow();
  886. assertEquals(createExpectedRow("name", "row4",
  887. "id", 5,
  888. "data", "a larger amount of new data"),
  889. row);
  890. t.reset();
  891. String str = createString(100);
  892. for(int i = 10; i < 50; ++i) {
  893. t.addRow("row" + i, Column.AUTO_NUMBER, "big data_" + str);
  894. }
  895. c.reset();
  896. c.moveNextRows(9);
  897. row = c.getCurrentRow();
  898. assertEquals(createExpectedRow("name", "row8",
  899. "id", 9,
  900. "data", "initial data"),
  901. row);
  902. String newText = "updated big data_" + createString(200);
  903. c.setCurrentRowValue(t.getColumn("data"), newText);
  904. c.reset();
  905. c.moveNextRows(9);
  906. row = c.getCurrentRow();
  907. assertEquals(createExpectedRow("name", "row8",
  908. "id", 9,
  909. "data", newText),
  910. row);
  911. db.close();
  912. }
  913. }
  914. public void testFixedText() throws Exception
  915. {
  916. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.FIXED_TEXT)) {
  917. Database db = openCopy(testDB);
  918. Table t = db.getTable("users");
  919. Column c = t.getColumn("c_flag_");
  920. assertEquals(DataType.TEXT, c.getType());
  921. assertEquals(false, c.isVariableLength());
  922. assertEquals(2, c.getLength());
  923. Map<String,Object> row = t.getNextRow();
  924. assertEquals("N", row.get("c_flag_"));
  925. t.addRow(3, "testFixedText", "boo", "foo", "bob", 3, 5, 9, "Y",
  926. new Date());
  927. t.getNextRow();
  928. row = t.getNextRow();
  929. assertEquals("testFixedText", row.get("c_user_login"));
  930. assertEquals("Y", row.get("c_flag_"));
  931. db.close();
  932. }
  933. }
  934. static Object[] createTestRow(String col1Val) {
  935. return new Object[] {col1Val, "R", "McCune", 1234, (byte) 0xad, 555.66d,
  936. 777.88f, (short) 999, new Date()};
  937. }
  938. static Object[] createTestRow() {
  939. return createTestRow("Tim");
  940. }
  941. static void createTestTable(Database db) throws Exception {
  942. new TableBuilder("test")
  943. .addColumn(new ColumnBuilder("A", DataType.TEXT).toColumn())
  944. .addColumn(new ColumnBuilder("B", DataType.TEXT).toColumn())
  945. .addColumn(new ColumnBuilder("C", DataType.TEXT).toColumn())
  946. .addColumn(new ColumnBuilder("D", DataType.LONG).toColumn())
  947. .addColumn(new ColumnBuilder("E", DataType.BYTE).toColumn())
  948. .addColumn(new ColumnBuilder("F", DataType.DOUBLE).toColumn())
  949. .addColumn(new ColumnBuilder("G", DataType.FLOAT).toColumn())
  950. .addColumn(new ColumnBuilder("H", DataType.INT).toColumn())
  951. .addColumn(new ColumnBuilder("I", DataType.SHORT_DATE_TIME).toColumn())
  952. .toTable(db);
  953. }
  954. static String createString(int len) {
  955. StringBuilder builder = new StringBuilder(len);
  956. for(int i = 0; i < len; ++i) {
  957. builder.append((char)('a' + (i % 26)));
  958. }
  959. return builder.toString();
  960. }
  961. static void assertRowCount(int expectedRowCount, Table table)
  962. throws Exception
  963. {
  964. assertEquals(expectedRowCount, countRows(table));
  965. assertEquals(expectedRowCount, table.getRowCount());
  966. }
  967. static int countRows(Table table) throws Exception {
  968. int rtn = 0;
  969. for(Map<String, Object> row : Cursor.createCursor(table)) {
  970. rtn++;
  971. }
  972. return rtn;
  973. }
  974. static void assertTable(List<Map<String, Object>> expectedTable, Table table)
  975. {
  976. assertCursor(expectedTable, Cursor.createCursor(table));
  977. }
  978. static void assertCursor(List<Map<String, Object>> expectedTable,
  979. Cursor cursor)
  980. {
  981. List<Map<String, Object>> foundTable =
  982. new ArrayList<Map<String, Object>>();
  983. for(Map<String, Object> row : cursor) {
  984. foundTable.add(row);
  985. }
  986. assertEquals(expectedTable, foundTable);
  987. }
  988. static Map<String, Object> createExpectedRow(Object... rowElements) {
  989. Map<String, Object> row = new LinkedHashMap<String, Object>();
  990. for(int i = 0; i < rowElements.length; i += 2) {
  991. row.put((String)rowElements[i],
  992. rowElements[i + 1]);
  993. }
  994. return row;
  995. }
  996. @SuppressWarnings("unchecked")
  997. static List<Map<String, Object>> createExpectedTable(Map... rows) {
  998. return Arrays.<Map<String, Object>>asList(rows);
  999. }
  1000. static void dumpDatabase(Database mdb) throws Exception {
  1001. dumpDatabase(mdb, new PrintWriter(System.out, true));
  1002. }
  1003. static void dumpTable(Table table) throws Exception {
  1004. dumpTable(table, new PrintWriter(System.out, true));
  1005. }
  1006. static void dumpDatabase(Database mdb, PrintWriter writer) throws Exception {
  1007. writer.println("DATABASE:");
  1008. for(Table table : mdb) {
  1009. dumpTable(table, writer);
  1010. }
  1011. }
  1012. static void dumpTable(Table table, PrintWriter writer) throws Exception {
  1013. // make sure all indexes are read
  1014. for(Index index : table.getIndexes()) {
  1015. index.initialize();
  1016. }
  1017. writer.println("TABLE: " + table.getName());
  1018. List<String> colNames = new ArrayList<String>();
  1019. for(Column col : table.getColumns()) {
  1020. colNames.add(col.getName());
  1021. }
  1022. writer.println("COLUMNS: " + colNames);
  1023. for(Map<String, Object> row : Cursor.createCursor(table)) {
  1024. // make byte[] printable
  1025. for(Map.Entry<String, Object> entry : row.entrySet()) {
  1026. Object v = entry.getValue();
  1027. if(v instanceof byte[]) {
  1028. byte[] bv = (byte[])v;
  1029. entry.setValue(ByteUtil.toHexString(ByteBuffer.wrap(bv), bv.length));
  1030. }
  1031. }
  1032. writer.println(row);
  1033. }
  1034. }
  1035. static void dumpIndex(Index index) throws Exception {
  1036. dumpIndex(index, new PrintWriter(System.out, true));
  1037. }
  1038. static void dumpIndex(Index index, PrintWriter writer) throws Exception {
  1039. writer.println("INDEX: " + index);
  1040. Index.EntryCursor ec = index.cursor();
  1041. Index.Entry lastE = ec.getLastEntry();
  1042. Index.Entry e = null;
  1043. while((e = ec.getNextEntry()) != lastE) {
  1044. writer.println(e);
  1045. }
  1046. }
  1047. static void copyFile(File srcFile, File dstFile)
  1048. throws IOException
  1049. {
  1050. // FIXME should really be using commons io FileUtils here, but don't want
  1051. // to add dep for one simple test method
  1052. byte[] buf = new byte[1024];
  1053. OutputStream ostream = new FileOutputStream(dstFile);
  1054. InputStream istream = new FileInputStream(srcFile);
  1055. try {
  1056. int numBytes = 0;
  1057. while((numBytes = istream.read(buf)) >= 0) {
  1058. ostream.write(buf, 0, numBytes);
  1059. }
  1060. } finally {
  1061. ostream.close();
  1062. }
  1063. }
  1064. static File createTempFile(boolean keep) throws Exception {
  1065. File tmp = File.createTempFile("databaseTest", ".mdb");
  1066. if(keep) {
  1067. System.out.println("Created " + tmp);
  1068. } else {
  1069. tmp.deleteOnExit();
  1070. }
  1071. return tmp;
  1072. }
  1073. static byte[] toByteArray(File file)
  1074. throws IOException
  1075. {
  1076. // FIXME should really be using commons io IOUtils here, but don't want
  1077. // to add dep for one simple test method
  1078. FileInputStream istream = new FileInputStream(file);
  1079. try {
  1080. byte[] bytes = new byte[(int)file.length()];
  1081. istream.read(bytes);
  1082. return bytes;
  1083. } finally {
  1084. istream.close();
  1085. }
  1086. }
  1087. }