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.

CursorTest.java 42KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336
  1. /*
  2. Copyright (c) 2007 Health Market Science, Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package com.healthmarketscience.jackcess;
  14. import java.util.ArrayList;
  15. import java.util.Arrays;
  16. import java.util.Collections;
  17. import java.util.Iterator;
  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.NoSuchElementException;
  21. import java.util.TreeSet;
  22. import static com.healthmarketscience.jackcess.Database.*;
  23. import static com.healthmarketscience.jackcess.DatabaseTest.*;
  24. import com.healthmarketscience.jackcess.impl.ColumnImpl;
  25. import com.healthmarketscience.jackcess.impl.JetFormatTest;
  26. import static com.healthmarketscience.jackcess.impl.JetFormatTest.*;
  27. import com.healthmarketscience.jackcess.impl.RowIdImpl;
  28. import com.healthmarketscience.jackcess.util.CaseInsensitiveColumnMatcher;
  29. import com.healthmarketscience.jackcess.util.ColumnMatcher;
  30. import com.healthmarketscience.jackcess.util.RowFilterTest;
  31. import com.healthmarketscience.jackcess.util.SimpleColumnMatcher;
  32. import junit.framework.TestCase;
  33. /**
  34. * @author James Ahlborn
  35. */
  36. public class CursorTest extends TestCase {
  37. static final List<TestDB> INDEX_CURSOR_DBS =
  38. TestDB.getSupportedForBasename(Basename.INDEX_CURSOR);
  39. public CursorTest(String name) throws Exception {
  40. super(name);
  41. }
  42. @Override
  43. protected void setUp() {
  44. DatabaseTest.setTestAutoSync(false);
  45. }
  46. @Override
  47. protected void tearDown() {
  48. DatabaseTest.clearTestAutoSync();
  49. }
  50. private static List<Map<String,Object>> createTestTableData()
  51. throws Exception
  52. {
  53. List<Map<String,Object>> expectedRows =
  54. new ArrayList<Map<String,Object>>();
  55. for(int i = 0; i < 10; ++i) {
  56. expectedRows.add(createExpectedRow("id", i, "value", "data" + i));
  57. }
  58. return expectedRows;
  59. }
  60. private static List<Map<String,Object>> createTestTableData(
  61. int startIdx,
  62. int endIdx)
  63. throws Exception
  64. {
  65. List<Map<String,Object>> expectedRows = createTestTableData();
  66. expectedRows.subList(endIdx, expectedRows.size()).clear();
  67. expectedRows.subList(0, startIdx).clear();
  68. return expectedRows;
  69. }
  70. private static Database createTestTable(final FileFormat fileFormat)
  71. throws Exception
  72. {
  73. Database db = createMem(fileFormat);
  74. Table table = new TableBuilder("test")
  75. .addColumn(new ColumnBuilder("id", DataType.LONG))
  76. .addColumn(new ColumnBuilder("value", DataType.TEXT))
  77. .toTable(db);
  78. for(Map<String,Object> row : createTestTableData()) {
  79. table.addRow(row.get("id"), row.get("value"));
  80. }
  81. return db;
  82. }
  83. private static List<Map<String,Object>> createUnorderedTestTableData()
  84. throws Exception
  85. {
  86. List<Map<String,Object>> expectedRows =
  87. new ArrayList<Map<String,Object>>();
  88. int[] ids = new int[]{3, 7, 6, 1, 2, 9, 0, 5, 4, 8};
  89. for(int i : ids) {
  90. expectedRows.add(createExpectedRow("id", i, "value", "data" + i));
  91. }
  92. return expectedRows;
  93. }
  94. static Database createTestIndexTable(final TestDB indexCursorDB)
  95. throws Exception
  96. {
  97. Database db = openCopy(indexCursorDB);
  98. Table table = db.getTable("test");
  99. for(Map<String,Object> row : createUnorderedTestTableData()) {
  100. table.addRow(row.get("id"), row.get("value"));
  101. }
  102. return db;
  103. }
  104. private static List<Map<String,Object>> createDupeTestTableData()
  105. throws Exception
  106. {
  107. List<Map<String,Object>> expectedRows =
  108. new ArrayList<Map<String,Object>>();
  109. int[] ids = new int[]{3, 7, 6, 1, 2, 9, 0, 5, 4, 8};
  110. for(int i : ids) {
  111. expectedRows.add(createExpectedRow("id", i, "value", "data" + (i % 3)));
  112. }
  113. for(int i : ids) {
  114. expectedRows.add(createExpectedRow("id", i, "value", "data" + (i % 5)));
  115. }
  116. return expectedRows;
  117. }
  118. private static Database createDupeTestTable(final FileFormat fileFormat)
  119. throws Exception
  120. {
  121. Database db = createMem(fileFormat);
  122. Table table = new TableBuilder("test")
  123. .addColumn(new ColumnBuilder("id", DataType.LONG))
  124. .addColumn(new ColumnBuilder("value", DataType.TEXT))
  125. .toTable(db);
  126. for(Map<String,Object> row : createDupeTestTableData()) {
  127. table.addRow(row.get("id"), row.get("value"));
  128. }
  129. return db;
  130. }
  131. static Database createDupeTestTable(final TestDB indexCursorDB)
  132. throws Exception
  133. {
  134. Database db = openCopy(indexCursorDB);
  135. Table table = db.getTable("test");
  136. for(Map<String,Object> row : createDupeTestTableData()) {
  137. table.addRow(row.get("id"), row.get("value"));
  138. }
  139. return db;
  140. }
  141. private static Cursor createIndexSubRangeCursor(Table table,
  142. Index idx,
  143. int type)
  144. throws Exception
  145. {
  146. return table.newCursor()
  147. .setIndex(idx)
  148. .setStartEntry(3 - type)
  149. .setStartRowInclusive(type == 0)
  150. .setEndEntry(8 + type)
  151. .setEndRowInclusive(type == 0)
  152. .toCursor();
  153. }
  154. public void testRowId() throws Exception {
  155. // test special cases
  156. RowIdImpl rowId1 = new RowIdImpl(1, 2);
  157. RowIdImpl rowId2 = new RowIdImpl(1, 3);
  158. RowIdImpl rowId3 = new RowIdImpl(2, 1);
  159. List<RowIdImpl> sortedRowIds =
  160. new ArrayList<RowIdImpl>(new TreeSet<RowIdImpl>(
  161. Arrays.asList(rowId1, rowId2, rowId3, RowIdImpl.FIRST_ROW_ID,
  162. RowIdImpl.LAST_ROW_ID)));
  163. assertEquals(Arrays.asList(RowIdImpl.FIRST_ROW_ID, rowId1, rowId2, rowId3,
  164. RowIdImpl.LAST_ROW_ID),
  165. sortedRowIds);
  166. }
  167. public void testSimple() throws Exception {
  168. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  169. Database db = createTestTable(fileFormat);
  170. Table table = db.getTable("test");
  171. Cursor cursor = CursorBuilder.createCursor(table);
  172. doTestSimple(cursor, null);
  173. db.close();
  174. }
  175. }
  176. private static void doTestSimple(Cursor cursor,
  177. List<Map<String, Object>> expectedRows)
  178. throws Exception
  179. {
  180. if(expectedRows == null) {
  181. expectedRows = createTestTableData();
  182. }
  183. List<Map<String, Object>> foundRows =
  184. new ArrayList<Map<String, Object>>();
  185. for(Map<String, Object> row : cursor) {
  186. foundRows.add(row);
  187. }
  188. assertEquals(expectedRows, foundRows);
  189. }
  190. public void testMove() throws Exception {
  191. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  192. Database db = createTestTable(fileFormat);
  193. Table table = db.getTable("test");
  194. Cursor cursor = CursorBuilder.createCursor(table);
  195. doTestMove(cursor, null);
  196. db.close();
  197. }
  198. }
  199. private static void doTestMove(Cursor cursor,
  200. List<Map<String, Object>> expectedRows)
  201. throws Exception
  202. {
  203. if(expectedRows == null) {
  204. expectedRows = createTestTableData();
  205. }
  206. expectedRows.subList(1, 4).clear();
  207. List<Map<String, Object>> foundRows =
  208. new ArrayList<Map<String, Object>>();
  209. assertTrue(cursor.isBeforeFirst());
  210. assertFalse(cursor.isAfterLast());
  211. foundRows.add(cursor.getNextRow());
  212. assertEquals(3, cursor.moveNextRows(3));
  213. assertFalse(cursor.isBeforeFirst());
  214. assertFalse(cursor.isAfterLast());
  215. Map<String,Object> expectedRow = cursor.getCurrentRow();
  216. Cursor.Savepoint savepoint = cursor.getSavepoint();
  217. assertEquals(2, cursor.movePreviousRows(2));
  218. assertEquals(2, cursor.moveNextRows(2));
  219. assertTrue(cursor.moveToNextRow());
  220. assertTrue(cursor.moveToPreviousRow());
  221. assertEquals(expectedRow, cursor.getCurrentRow());
  222. while(cursor.moveToNextRow()) {
  223. foundRows.add(cursor.getCurrentRow());
  224. }
  225. assertEquals(expectedRows, foundRows);
  226. assertFalse(cursor.isBeforeFirst());
  227. assertTrue(cursor.isAfterLast());
  228. assertEquals(0, cursor.moveNextRows(3));
  229. cursor.beforeFirst();
  230. assertTrue(cursor.isBeforeFirst());
  231. assertFalse(cursor.isAfterLast());
  232. cursor.afterLast();
  233. assertFalse(cursor.isBeforeFirst());
  234. assertTrue(cursor.isAfterLast());
  235. cursor.restoreSavepoint(savepoint);
  236. assertEquals(expectedRow, cursor.getCurrentRow());
  237. }
  238. public void testMoveNoReset() throws Exception {
  239. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  240. Database db = createTestTable(fileFormat);
  241. Table table = db.getTable("test");
  242. Cursor cursor = CursorBuilder.createCursor(table);
  243. doTestMoveNoReset(cursor);
  244. db.close();
  245. }
  246. }
  247. private static void doTestMoveNoReset(Cursor cursor)
  248. throws Exception
  249. {
  250. List<Map<String, Object>> expectedRows = createTestTableData();
  251. List<Map<String, Object>> foundRows = new ArrayList<Map<String, Object>>();
  252. Iterator<Row> iter = cursor.newIterable().iterator();
  253. for(int i = 0; i < 6; ++i) {
  254. foundRows.add(iter.next());
  255. }
  256. iter = cursor.newIterable().reset(false).reverse().iterator();
  257. iter.next();
  258. Map<String, Object> row = iter.next();
  259. assertEquals(expectedRows.get(4), row);
  260. iter = cursor.newIterable().reset(false).iterator();
  261. iter.next();
  262. row = iter.next();
  263. assertEquals(expectedRows.get(5), row);
  264. iter.next();
  265. iter = cursor.newIterable().reset(false).iterator();
  266. for(int i = 6; i < 10; ++i) {
  267. foundRows.add(iter.next());
  268. }
  269. assertEquals(expectedRows, foundRows);
  270. }
  271. public void testSearch() throws Exception {
  272. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  273. Database db = createTestTable(fileFormat);
  274. Table table = db.getTable("test");
  275. Cursor cursor = CursorBuilder.createCursor(table);
  276. doTestSearch(table, cursor, null, 42, -13);
  277. db.close();
  278. }
  279. }
  280. private static void doTestSearch(Table table, Cursor cursor, Index index,
  281. Integer... outOfRangeValues)
  282. throws Exception
  283. {
  284. assertTrue(cursor.findFirstRow(table.getColumn("id"), 3));
  285. assertEquals(createExpectedRow("id", 3,
  286. "value", "data" + 3),
  287. cursor.getCurrentRow());
  288. assertTrue(cursor.findFirstRow(createExpectedRow(
  289. "id", 6,
  290. "value", "data" + 6)));
  291. assertEquals(createExpectedRow("id", 6,
  292. "value", "data" + 6),
  293. cursor.getCurrentRow());
  294. assertFalse(cursor.findFirstRow(createExpectedRow(
  295. "id", 8,
  296. "value", "data" + 13)));
  297. assertFalse(cursor.findFirstRow(table.getColumn("id"), 13));
  298. assertEquals(createExpectedRow("id", 6,
  299. "value", "data" + 6),
  300. cursor.getCurrentRow());
  301. assertTrue(cursor.findFirstRow(createExpectedRow(
  302. "value", "data" + 7)));
  303. assertEquals(createExpectedRow("id", 7,
  304. "value", "data" + 7),
  305. cursor.getCurrentRow());
  306. assertTrue(cursor.findFirstRow(table.getColumn("value"), "data" + 4));
  307. assertEquals(createExpectedRow("id", 4,
  308. "value", "data" + 4),
  309. cursor.getCurrentRow());
  310. for(Integer outOfRangeValue : outOfRangeValues) {
  311. assertFalse(cursor.findFirstRow(table.getColumn("id"),
  312. outOfRangeValue));
  313. assertFalse(cursor.findFirstRow(table.getColumn("value"),
  314. "data" + outOfRangeValue));
  315. assertFalse(cursor.findFirstRow(createExpectedRow(
  316. "id", outOfRangeValue,
  317. "value", "data" + outOfRangeValue)));
  318. }
  319. assertEquals("data" + 5,
  320. CursorBuilder.findValue(table,
  321. table.getColumn("value"),
  322. table.getColumn("id"), 5));
  323. assertEquals(createExpectedRow("id", 5,
  324. "value", "data" + 5),
  325. CursorBuilder.findRow(table,
  326. createExpectedRow("id", 5)));
  327. if(index != null) {
  328. assertEquals("data" + 5,
  329. CursorBuilder.findValue(index,
  330. table.getColumn("value"),
  331. table.getColumn("id"), 5));
  332. assertEquals(createExpectedRow("id", 5,
  333. "value", "data" + 5),
  334. CursorBuilder.findRow(index,
  335. createExpectedRow("id", 5)));
  336. assertNull(CursorBuilder.findValue(index,
  337. table.getColumn("value"),
  338. table.getColumn("id"),
  339. -17));
  340. assertNull(CursorBuilder.findRow(index,
  341. createExpectedRow("id", 13)));
  342. }
  343. }
  344. public void testReverse() throws Exception {
  345. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  346. Database db = createTestTable(fileFormat);
  347. Table table = db.getTable("test");
  348. Cursor cursor = CursorBuilder.createCursor(table);
  349. doTestReverse(cursor, null);
  350. db.close();
  351. }
  352. }
  353. private static void doTestReverse(Cursor cursor,
  354. List<Map<String, Object>> expectedRows)
  355. throws Exception
  356. {
  357. if(expectedRows == null) {
  358. expectedRows = createTestTableData();
  359. }
  360. Collections.reverse(expectedRows);
  361. List<Map<String, Object>> foundRows =
  362. new ArrayList<Map<String, Object>>();
  363. for(Map<String, Object> row : cursor.newIterable().reverse()) {
  364. foundRows.add(row);
  365. }
  366. assertEquals(expectedRows, foundRows);
  367. }
  368. public void testLiveAddition() throws Exception {
  369. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  370. Database db = createTestTable(fileFormat);
  371. Table table = db.getTable("test");
  372. Cursor cursor1 = CursorBuilder.createCursor(table);
  373. Cursor cursor2 = CursorBuilder.createCursor(table);
  374. doTestLiveAddition(table, cursor1, cursor2, 11);
  375. db.close();
  376. }
  377. }
  378. private static void doTestLiveAddition(Table table,
  379. Cursor cursor1,
  380. Cursor cursor2,
  381. Integer newRowNum) throws Exception
  382. {
  383. cursor1.moveNextRows(11);
  384. cursor2.moveNextRows(11);
  385. assertTrue(cursor1.isAfterLast());
  386. assertTrue(cursor2.isAfterLast());
  387. table.addRow(newRowNum, "data" + newRowNum);
  388. Map<String,Object> expectedRow =
  389. createExpectedRow("id", newRowNum, "value", "data" + newRowNum);
  390. assertFalse(cursor1.isAfterLast());
  391. assertFalse(cursor2.isAfterLast());
  392. assertEquals(expectedRow, cursor1.getCurrentRow());
  393. assertEquals(expectedRow, cursor2.getCurrentRow());
  394. assertFalse(cursor1.moveToNextRow());
  395. assertFalse(cursor2.moveToNextRow());
  396. assertTrue(cursor1.isAfterLast());
  397. assertTrue(cursor2.isAfterLast());
  398. }
  399. public void testLiveDeletion() throws Exception {
  400. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  401. Database db = createTestTable(fileFormat);
  402. Table table = db.getTable("test");
  403. Cursor cursor1 = CursorBuilder.createCursor(table);
  404. Cursor cursor2 = CursorBuilder.createCursor(table);
  405. Cursor cursor3 = CursorBuilder.createCursor(table);
  406. Cursor cursor4 = CursorBuilder.createCursor(table);
  407. doTestLiveDeletion(cursor1, cursor2, cursor3, cursor4, 1);
  408. db.close();
  409. }
  410. }
  411. private static void doTestLiveDeletion(
  412. Cursor cursor1,
  413. Cursor cursor2,
  414. Cursor cursor3,
  415. Cursor cursor4,
  416. int firstValue) throws Exception
  417. {
  418. assertEquals(2, cursor1.moveNextRows(2));
  419. assertEquals(3, cursor2.moveNextRows(3));
  420. assertEquals(3, cursor3.moveNextRows(3));
  421. assertEquals(4, cursor4.moveNextRows(4));
  422. Map<String,Object> expectedPrevRow =
  423. createExpectedRow("id", firstValue, "value", "data" + firstValue);
  424. ++firstValue;
  425. Map<String,Object> expectedDeletedRow =
  426. createExpectedRow("id", firstValue, "value", "data" + firstValue);
  427. ++firstValue;
  428. Map<String,Object> expectedNextRow =
  429. createExpectedRow("id", firstValue, "value", "data" + firstValue);
  430. assertEquals(expectedDeletedRow, cursor2.getCurrentRow());
  431. assertEquals(expectedDeletedRow, cursor3.getCurrentRow());
  432. assertFalse(cursor2.isCurrentRowDeleted());
  433. assertFalse(cursor3.isCurrentRowDeleted());
  434. cursor2.deleteCurrentRow();
  435. assertTrue(cursor2.isCurrentRowDeleted());
  436. assertTrue(cursor3.isCurrentRowDeleted());
  437. assertEquals(expectedNextRow, cursor1.getNextRow());
  438. assertEquals(expectedNextRow, cursor2.getNextRow());
  439. assertEquals(expectedNextRow, cursor3.getNextRow());
  440. assertEquals(expectedPrevRow, cursor3.getPreviousRow());
  441. assertTrue(cursor3.moveToNextRow());
  442. cursor3.deleteCurrentRow();
  443. assertTrue(cursor3.isCurrentRowDeleted());
  444. firstValue += 2;
  445. expectedNextRow =
  446. createExpectedRow("id", firstValue, "value", "data" + firstValue);
  447. assertTrue(cursor3.moveToNextRow());
  448. assertEquals(expectedNextRow, cursor3.getNextRow());
  449. cursor1.beforeFirst();
  450. assertTrue(cursor1.moveToNextRow());
  451. cursor1.deleteCurrentRow();
  452. assertFalse(cursor1.isBeforeFirst());
  453. assertFalse(cursor1.isAfterLast());
  454. assertFalse(cursor1.moveToPreviousRow());
  455. assertTrue(cursor1.isBeforeFirst());
  456. assertFalse(cursor1.isAfterLast());
  457. cursor1.afterLast();
  458. assertTrue(cursor1.moveToPreviousRow());
  459. cursor1.deleteCurrentRow();
  460. assertFalse(cursor1.isBeforeFirst());
  461. assertFalse(cursor1.isAfterLast());
  462. assertFalse(cursor1.moveToNextRow());
  463. assertFalse(cursor1.isBeforeFirst());
  464. assertTrue(cursor1.isAfterLast());
  465. cursor1.beforeFirst();
  466. while(cursor1.moveToNextRow()) {
  467. cursor1.deleteCurrentRow();
  468. }
  469. assertTrue(cursor1.isAfterLast());
  470. assertTrue(cursor2.isCurrentRowDeleted());
  471. assertTrue(cursor3.isCurrentRowDeleted());
  472. assertTrue(cursor4.isCurrentRowDeleted());
  473. }
  474. public void testSimpleIndex() throws Exception {
  475. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  476. Database db = createTestIndexTable(indexCursorDB);
  477. Table table = db.getTable("test");
  478. Index idx = table.getIndexes().get(0);
  479. assertTable(createUnorderedTestTableData(), table);
  480. Cursor cursor = CursorBuilder.createCursor(idx);
  481. doTestSimple(cursor, null);
  482. db.close();
  483. }
  484. }
  485. public void testMoveIndex() throws Exception {
  486. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  487. Database db = createTestIndexTable(indexCursorDB);
  488. Table table = db.getTable("test");
  489. Index idx = table.getIndexes().get(0);
  490. Cursor cursor = CursorBuilder.createCursor(idx);
  491. doTestMove(cursor, null);
  492. db.close();
  493. }
  494. }
  495. public void testReverseIndex() throws Exception {
  496. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  497. Database db = createTestIndexTable(indexCursorDB);
  498. Table table = db.getTable("test");
  499. Index idx = table.getIndexes().get(0);
  500. Cursor cursor = CursorBuilder.createCursor(idx);
  501. doTestReverse(cursor, null);
  502. db.close();
  503. }
  504. }
  505. public void testSearchIndex() throws Exception {
  506. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  507. Database db = createTestIndexTable(indexCursorDB);
  508. Table table = db.getTable("test");
  509. Index idx = table.getIndexes().get(0);
  510. Cursor cursor = CursorBuilder.createCursor(idx);
  511. doTestSearch(table, cursor, idx, 42, -13);
  512. db.close();
  513. }
  514. }
  515. public void testLiveAdditionIndex() throws Exception {
  516. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  517. Database db = createTestIndexTable(indexCursorDB);
  518. Table table = db.getTable("test");
  519. Index idx = table.getIndexes().get(0);
  520. Cursor cursor1 = CursorBuilder.createCursor(idx);
  521. Cursor cursor2 = CursorBuilder.createCursor(idx);
  522. doTestLiveAddition(table, cursor1, cursor2, 11);
  523. db.close();
  524. }
  525. }
  526. public void testLiveDeletionIndex() throws Exception {
  527. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  528. Database db = createTestIndexTable(indexCursorDB);
  529. Table table = db.getTable("test");
  530. Index idx = table.getIndexes().get(0);
  531. Cursor cursor1 = CursorBuilder.createCursor(idx);
  532. Cursor cursor2 = CursorBuilder.createCursor(idx);
  533. Cursor cursor3 = CursorBuilder.createCursor(idx);
  534. Cursor cursor4 = CursorBuilder.createCursor(idx);
  535. doTestLiveDeletion(cursor1, cursor2, cursor3, cursor4, 1);
  536. db.close();
  537. }
  538. }
  539. public void testSimpleIndexSubRange() throws Exception {
  540. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  541. for(int i = 0; i < 2; ++i) {
  542. Database db = createTestIndexTable(indexCursorDB);
  543. Table table = db.getTable("test");
  544. Index idx = table.getIndexes().get(0);
  545. Cursor cursor = createIndexSubRangeCursor(table, idx, i);
  546. List<Map<String,Object>> expectedRows =
  547. createTestTableData(3, 9);
  548. doTestSimple(cursor, expectedRows);
  549. db.close();
  550. }
  551. }
  552. }
  553. public void testMoveIndexSubRange() throws Exception {
  554. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  555. for(int i = 0; i < 2; ++i) {
  556. Database db = createTestIndexTable(indexCursorDB);
  557. Table table = db.getTable("test");
  558. Index idx = table.getIndexes().get(0);
  559. Cursor cursor = createIndexSubRangeCursor(table, idx, i);
  560. List<Map<String,Object>> expectedRows =
  561. createTestTableData(3, 9);
  562. doTestMove(cursor, expectedRows);
  563. db.close();
  564. }
  565. }
  566. }
  567. public void testSearchIndexSubRange() throws Exception {
  568. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  569. for(int i = 0; i < 2; ++i) {
  570. Database db = createTestIndexTable(indexCursorDB);
  571. Table table = db.getTable("test");
  572. Index idx = table.getIndexes().get(0);
  573. Cursor cursor = createIndexSubRangeCursor(table, idx, i);
  574. doTestSearch(table, cursor, idx, 2, 9);
  575. db.close();
  576. }
  577. }
  578. }
  579. public void testReverseIndexSubRange() throws Exception {
  580. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  581. for(int i = 0; i < 2; ++i) {
  582. Database db = createTestIndexTable(indexCursorDB);
  583. Table table = db.getTable("test");
  584. Index idx = table.getIndexes().get(0);
  585. Cursor cursor = createIndexSubRangeCursor(table, idx, i);
  586. List<Map<String,Object>> expectedRows =
  587. createTestTableData(3, 9);
  588. doTestReverse(cursor, expectedRows);
  589. db.close();
  590. }
  591. }
  592. }
  593. public void testLiveAdditionIndexSubRange() throws Exception {
  594. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  595. for(int i = 0; i < 2; ++i) {
  596. Database db = createTestIndexTable(indexCursorDB);
  597. Table table = db.getTable("test");
  598. Index idx = table.getIndexes().get(0);
  599. Cursor cursor1 = createIndexSubRangeCursor(table, idx, i);
  600. Cursor cursor2 = createIndexSubRangeCursor(table, idx, i);
  601. doTestLiveAddition(table, cursor1, cursor2, 8);
  602. db.close();
  603. }
  604. }
  605. }
  606. public void testLiveDeletionIndexSubRange() throws Exception {
  607. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  608. for(int i = 0; i < 2; ++i) {
  609. Database db = createTestIndexTable(indexCursorDB);
  610. Table table = db.getTable("test");
  611. Index idx = table.getIndexes().get(0);
  612. Cursor cursor1 = createIndexSubRangeCursor(table, idx, i);
  613. Cursor cursor2 = createIndexSubRangeCursor(table, idx, i);
  614. Cursor cursor3 = createIndexSubRangeCursor(table, idx, i);
  615. Cursor cursor4 = createIndexSubRangeCursor(table, idx, i);
  616. doTestLiveDeletion(cursor1, cursor2, cursor3, cursor4, 4);
  617. db.close();
  618. }
  619. }
  620. }
  621. public void testFindAllIndex() throws Exception {
  622. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  623. Database db = createDupeTestTable(fileFormat);
  624. Table table = db.getTable("test");
  625. Cursor cursor = CursorBuilder.createCursor(table);
  626. doTestFindAll(table, cursor, null);
  627. db.close();
  628. }
  629. }
  630. public void testFindAll() throws Exception {
  631. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  632. Database db = createDupeTestTable(indexCursorDB);
  633. Table table = db.getTable("test");
  634. Index idx = table.getIndexes().get(0);
  635. Cursor cursor = CursorBuilder.createCursor(idx);
  636. doTestFindAll(table, cursor, idx);
  637. db.close();
  638. }
  639. }
  640. private static void doTestFindAll(Table table, Cursor cursor, Index index)
  641. throws Exception
  642. {
  643. List<? extends Map<String,Object>> rows = RowFilterTest.toList(
  644. cursor.newIterable().setMatchPattern("value", "data2"));
  645. List<? extends Map<String, Object>> expectedRows = null;
  646. if(index == null) {
  647. expectedRows =
  648. createExpectedTable(
  649. createExpectedRow(
  650. "id", 2, "value", "data2"),
  651. createExpectedRow(
  652. "id", 5, "value", "data2"),
  653. createExpectedRow(
  654. "id", 8, "value", "data2"),
  655. createExpectedRow(
  656. "id", 7, "value", "data2"),
  657. createExpectedRow(
  658. "id", 2, "value", "data2"));
  659. } else {
  660. expectedRows =
  661. createExpectedTable(
  662. createExpectedRow(
  663. "id", 2, "value", "data2"),
  664. createExpectedRow(
  665. "id", 2, "value", "data2"),
  666. createExpectedRow(
  667. "id", 5, "value", "data2"),
  668. createExpectedRow(
  669. "id", 7, "value", "data2"),
  670. createExpectedRow(
  671. "id", 8, "value", "data2"));
  672. }
  673. assertEquals(expectedRows, rows);
  674. Column valCol = table.getColumn("value");
  675. rows = RowFilterTest.toList(
  676. cursor.newIterable().setMatchPattern(valCol, "data4"));
  677. if(index == null) {
  678. expectedRows =
  679. createExpectedTable(
  680. createExpectedRow(
  681. "id", 9, "value", "data4"),
  682. createExpectedRow(
  683. "id", 4, "value", "data4"));
  684. } else {
  685. expectedRows =
  686. createExpectedTable(
  687. createExpectedRow(
  688. "id", 4, "value", "data4"),
  689. createExpectedRow(
  690. "id", 9, "value", "data4"));
  691. }
  692. assertEquals(expectedRows, rows);
  693. rows = RowFilterTest.toList(
  694. cursor.newIterable().setMatchPattern(valCol, "data9"));
  695. assertTrue(rows.isEmpty());
  696. rows = RowFilterTest.toList(
  697. cursor.newIterable().setMatchPattern(
  698. Collections.singletonMap("id", 8)));
  699. expectedRows =
  700. createExpectedTable(
  701. createExpectedRow(
  702. "id", 8, "value", "data2"),
  703. createExpectedRow(
  704. "id", 8, "value", "data3"));
  705. assertEquals(expectedRows, rows);
  706. for(Map<String,Object> row : table) {
  707. List<Map<String,Object>> tmpRows = new ArrayList<Map<String,Object>>();
  708. for(Map<String,Object> tmpRow : cursor) {
  709. if(row.equals(tmpRow)) {
  710. tmpRows.add(tmpRow);
  711. }
  712. }
  713. expectedRows = tmpRows;
  714. assertFalse(expectedRows.isEmpty());
  715. rows = RowFilterTest.toList(cursor.newIterable().setMatchPattern(row));
  716. assertEquals(expectedRows, rows);
  717. }
  718. rows = RowFilterTest.toList(
  719. cursor.newIterable().addMatchPattern("id", 8)
  720. .addMatchPattern("value", "data13"));
  721. assertTrue(rows.isEmpty());
  722. }
  723. public void testId() throws Exception
  724. {
  725. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  726. Database db = createTestIndexTable(indexCursorDB);
  727. Table table = db.getTable("test");
  728. Index idx = table.getIndexes().get(0);
  729. Cursor tCursor = CursorBuilder.createCursor(table);
  730. Cursor iCursor = CursorBuilder.createCursor(idx);
  731. Cursor.Savepoint tSave = tCursor.getSavepoint();
  732. Cursor.Savepoint iSave = iCursor.getSavepoint();
  733. tCursor.restoreSavepoint(tSave);
  734. iCursor.restoreSavepoint(iSave);
  735. try {
  736. tCursor.restoreSavepoint(iSave);
  737. fail("IllegalArgumentException should have been thrown");
  738. } catch(IllegalArgumentException e) {
  739. // success
  740. }
  741. try {
  742. iCursor.restoreSavepoint(tSave);
  743. fail("IllegalArgumentException should have been thrown");
  744. } catch(IllegalArgumentException e) {
  745. // success
  746. }
  747. Cursor tCursor2 = CursorBuilder.createCursor(table);
  748. Cursor iCursor2 = CursorBuilder.createCursor(idx);
  749. tCursor2.restoreSavepoint(tSave);
  750. iCursor2.restoreSavepoint(iSave);
  751. db.close();
  752. }
  753. }
  754. public void testColumnMatcher() throws Exception {
  755. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  756. Database db = createTestTable(fileFormat);
  757. Table table = db.getTable("test");
  758. doTestMatchers(table, SimpleColumnMatcher.INSTANCE, false);
  759. doTestMatchers(table, CaseInsensitiveColumnMatcher.INSTANCE, true);
  760. Cursor cursor = CursorBuilder.createCursor(table);
  761. doTestMatcher(table, cursor, SimpleColumnMatcher.INSTANCE, false);
  762. doTestMatcher(table, cursor, CaseInsensitiveColumnMatcher.INSTANCE,
  763. true);
  764. db.close();
  765. }
  766. }
  767. private static void doTestMatchers(Table table, ColumnMatcher columnMatcher,
  768. boolean caseInsensitive)
  769. throws Exception
  770. {
  771. assertTrue(columnMatcher.matches(table, "value", null, null));
  772. assertFalse(columnMatcher.matches(table, "value", "foo", null));
  773. assertFalse(columnMatcher.matches(table, "value", null, "foo"));
  774. assertTrue(columnMatcher.matches(table, "value", "foo", "foo"));
  775. assertTrue(columnMatcher.matches(table, "value", "foo", "Foo")
  776. == caseInsensitive);
  777. assertFalse(columnMatcher.matches(table, "value", 13, null));
  778. assertFalse(columnMatcher.matches(table, "value", null, 13));
  779. assertTrue(columnMatcher.matches(table, "value", 13, 13));
  780. }
  781. private static void doTestMatcher(Table table, Cursor cursor,
  782. ColumnMatcher columnMatcher,
  783. boolean caseInsensitive)
  784. throws Exception
  785. {
  786. cursor.setColumnMatcher(columnMatcher);
  787. assertTrue(cursor.findFirstRow(table.getColumn("id"), 3));
  788. assertEquals(createExpectedRow("id", 3,
  789. "value", "data" + 3),
  790. cursor.getCurrentRow());
  791. assertTrue(cursor.findFirstRow(createExpectedRow(
  792. "id", 6,
  793. "value", "data" + 6)));
  794. assertEquals(createExpectedRow("id", 6,
  795. "value", "data" + 6),
  796. cursor.getCurrentRow());
  797. assertTrue(cursor.findFirstRow(createExpectedRow(
  798. "id", 6,
  799. "value", "Data" + 6)) == caseInsensitive);
  800. if(caseInsensitive) {
  801. assertEquals(createExpectedRow("id", 6,
  802. "value", "data" + 6),
  803. cursor.getCurrentRow());
  804. }
  805. assertFalse(cursor.findFirstRow(createExpectedRow(
  806. "id", 8,
  807. "value", "data" + 13)));
  808. assertFalse(cursor.findFirstRow(table.getColumn("id"), 13));
  809. assertEquals(createExpectedRow("id", 6,
  810. "value", "data" + 6),
  811. cursor.getCurrentRow());
  812. assertTrue(cursor.findFirstRow(createExpectedRow(
  813. "value", "data" + 7)));
  814. assertEquals(createExpectedRow("id", 7,
  815. "value", "data" + 7),
  816. cursor.getCurrentRow());
  817. assertTrue(cursor.findFirstRow(createExpectedRow(
  818. "value", "Data" + 7)) == caseInsensitive);
  819. if(caseInsensitive) {
  820. assertEquals(createExpectedRow("id", 7,
  821. "value", "data" + 7),
  822. cursor.getCurrentRow());
  823. }
  824. assertTrue(cursor.findFirstRow(table.getColumn("value"), "data" + 4));
  825. assertEquals(createExpectedRow("id", 4,
  826. "value", "data" + 4),
  827. cursor.getCurrentRow());
  828. assertTrue(cursor.findFirstRow(table.getColumn("value"), "Data" + 4)
  829. == caseInsensitive);
  830. if(caseInsensitive) {
  831. assertEquals(createExpectedRow("id", 4,
  832. "value", "data" + 4),
  833. cursor.getCurrentRow());
  834. }
  835. assertEquals(Arrays.asList(createExpectedRow("id", 4,
  836. "value", "data" + 4)),
  837. RowFilterTest.toList(
  838. cursor.newIterable()
  839. .setMatchPattern("value", "data4")
  840. .setColumnMatcher(SimpleColumnMatcher.INSTANCE)));
  841. assertEquals(Arrays.asList(createExpectedRow("id", 3,
  842. "value", "data" + 3)),
  843. RowFilterTest.toList(
  844. cursor.newIterable()
  845. .setMatchPattern("value", "DaTa3")
  846. .setColumnMatcher(CaseInsensitiveColumnMatcher.INSTANCE)));
  847. assertEquals(Arrays.asList(createExpectedRow("id", 2,
  848. "value", "data" + 2)),
  849. RowFilterTest.toList(
  850. cursor.newIterable()
  851. .addMatchPattern("value", "DaTa2")
  852. .addMatchPattern("id", 2)
  853. .setColumnMatcher(CaseInsensitiveColumnMatcher.INSTANCE)));
  854. }
  855. public void testIndexCursor() throws Exception
  856. {
  857. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX)) {
  858. Database db = openMem(testDB);
  859. Table t1 = db.getTable("Table1");
  860. Index idx = t1.getIndex(IndexBuilder.PRIMARY_KEY_NAME);
  861. IndexCursor cursor = CursorBuilder.createCursor(idx);
  862. assertFalse(cursor.findFirstRowByEntry(-1));
  863. cursor.findClosestRowByEntry(-1);
  864. assertEquals(0, cursor.getCurrentRow().get("id"));
  865. assertTrue(cursor.findFirstRowByEntry(1));
  866. assertEquals(1, cursor.getCurrentRow().get("id"));
  867. cursor.findClosestRowByEntry(2);
  868. assertEquals(2, cursor.getCurrentRow().get("id"));
  869. assertFalse(cursor.findFirstRowByEntry(4));
  870. cursor.findClosestRowByEntry(4);
  871. assertTrue(cursor.isAfterLast());
  872. db.close();
  873. }
  874. }
  875. public void testIndexCursorDelete() throws Exception
  876. {
  877. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX)) {
  878. Database db = openCopy(testDB);
  879. Table t1 = db.getTable("Table1");
  880. Index idx = t1.getIndex("Table2Table1");
  881. IndexCursor cursor = CursorBuilder.createCursor(idx);
  882. List<String> expectedData = new ArrayList<String>();
  883. for(Row row : cursor.newEntryIterable(1)
  884. .addColumnNames("data")) {
  885. expectedData.add(row.getString("data"));
  886. }
  887. assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData);
  888. expectedData = new ArrayList<String>();
  889. for(Iterator<? extends Row> iter =
  890. cursor.newEntryIterable(1).iterator();
  891. iter.hasNext(); ) {
  892. expectedData.add(iter.next().getString("data"));
  893. iter.remove();
  894. try {
  895. iter.remove();
  896. fail("IllegalArgumentException should have been thrown");
  897. } catch(IllegalStateException e) {
  898. // success
  899. }
  900. if(!iter.hasNext()) {
  901. try {
  902. iter.next();
  903. fail("NoSuchElementException should have been thrown");
  904. } catch(NoSuchElementException e) {
  905. // success
  906. }
  907. }
  908. }
  909. assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData);
  910. expectedData = new ArrayList<String>();
  911. for(Row row : cursor.newEntryIterable(1)
  912. .addColumnNames("data")) {
  913. expectedData.add(row.getString("data"));
  914. }
  915. assertTrue(expectedData.isEmpty());
  916. db.close();
  917. }
  918. }
  919. public void testCursorDelete() throws Exception
  920. {
  921. for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.INDEX)) {
  922. Database db = openCopy(testDB);
  923. Table t1 = db.getTable("Table1");
  924. Cursor cursor = CursorBuilder.createCursor(t1);
  925. List<String> expectedData = new ArrayList<String>();
  926. for(Row row : cursor.newIterable().setColumnNames(
  927. Arrays.asList("otherfk1", "data"))) {
  928. if(row.get("otherfk1").equals(1)) {
  929. expectedData.add(row.getString("data"));
  930. }
  931. }
  932. assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData);
  933. expectedData = new ArrayList<String>();
  934. for(Iterator<? extends Row> iter = cursor.iterator();
  935. iter.hasNext(); ) {
  936. Row row = iter.next();
  937. if(row.get("otherfk1").equals(1)) {
  938. expectedData.add(row.getString("data"));
  939. iter.remove();
  940. try {
  941. iter.remove();
  942. fail("IllegalArgumentException should have been thrown");
  943. } catch(IllegalStateException e) {
  944. // success
  945. }
  946. }
  947. if(!iter.hasNext()) {
  948. try {
  949. iter.next();
  950. fail("NoSuchElementException should have been thrown");
  951. } catch(NoSuchElementException e) {
  952. // success
  953. }
  954. }
  955. }
  956. assertEquals(Arrays.asList("baz11", "baz11-2"), expectedData);
  957. expectedData = new ArrayList<String>();
  958. for(Row row : cursor.newIterable().setColumnNames(
  959. Arrays.asList("otherfk1", "data"))) {
  960. if(row.get("otherfk1").equals(1)) {
  961. expectedData.add(row.getString("data"));
  962. }
  963. }
  964. assertTrue(expectedData.isEmpty());
  965. db.close();
  966. }
  967. }
  968. public void testFindByRowId() throws Exception {
  969. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  970. Database db = createTestTable(fileFormat);
  971. Table table = db.getTable("test");
  972. Cursor cursor = CursorBuilder.createCursor(table);
  973. doTestFindByRowId(cursor);
  974. db.close();
  975. }
  976. }
  977. public void testFindByRowIdIndex() throws Exception {
  978. for (final TestDB indexCursorDB : INDEX_CURSOR_DBS) {
  979. Database db = createTestIndexTable(indexCursorDB);
  980. Table table = db.getTable("test");
  981. Index idx = table.getIndexes().get(0);
  982. assertTable(createUnorderedTestTableData(), table);
  983. Cursor cursor = CursorBuilder.createCursor(idx);
  984. doTestFindByRowId(cursor);
  985. db.close();
  986. }
  987. }
  988. private static void doTestFindByRowId(Cursor cursor)
  989. throws Exception
  990. {
  991. for(int i = 0; i < 3; ++i) {
  992. cursor.moveToNextRow();
  993. }
  994. Row r1 = cursor.getCurrentRow();
  995. for(int i = 0; i < 3; ++i) {
  996. cursor.moveToNextRow();
  997. }
  998. Row r2 = cursor.getCurrentRow();
  999. doTestFindByRowId(cursor, r1, 2);
  1000. doTestFindByRowId(cursor, r2, 5);
  1001. }
  1002. private static void doTestFindByRowId(Cursor cursor, Row row, int id)
  1003. throws Exception
  1004. {
  1005. cursor.reset();
  1006. assertTrue(cursor.findRow(row.getId()));
  1007. Row rFound = cursor.getCurrentRow();
  1008. assertEquals(id, rFound.get("id"));
  1009. assertEquals(row, rFound);
  1010. Cursor.Savepoint save = cursor.getSavepoint();
  1011. assertTrue(cursor.moveToNextRow());
  1012. assertEquals(id + 1, cursor.getCurrentRow().get("id"));
  1013. cursor.restoreSavepoint(save);
  1014. assertTrue(cursor.moveToPreviousRow());
  1015. assertEquals(id - 1, cursor.getCurrentRow().get("id"));
  1016. assertFalse(cursor.findRow(RowIdImpl.FIRST_ROW_ID));
  1017. assertEquals(id - 1, cursor.getCurrentRow().get("id"));
  1018. }
  1019. public void testIterationEarlyExit() throws Exception {
  1020. for (final FileFormat fileFormat : JetFormatTest.SUPPORTED_FILEFORMATS) {
  1021. Database db = createMem(fileFormat);
  1022. Table table = new TableBuilder("test")
  1023. .addColumn(new ColumnBuilder("id", DataType.LONG))
  1024. .addColumn(new ColumnBuilder("value", DataType.TEXT))
  1025. .addColumn(new ColumnBuilder("memo", DataType.MEMO))
  1026. .addIndex(new IndexBuilder("value_idx")
  1027. .addColumns("value"))
  1028. .toTable(db);
  1029. for(int i = 0; i < 20; ++i) {
  1030. Object memo = "memo-" + i;
  1031. table.addRow(i, "val-" + (i/2), memo);
  1032. }
  1033. // generate an "invalid" memo
  1034. byte[] b = new byte[12];
  1035. b[3] = (byte)0xC0;
  1036. table.addRow(20, "val-9", ColumnImpl.rawDataWrapper(b));
  1037. IndexCursor cursor = CursorBuilder.createCursor(
  1038. table.getIndex("value_idx"));
  1039. try {
  1040. cursor.newIterable()
  1041. .addMatchPattern("value", "val-9")
  1042. .addMatchPattern("memo", "anything")
  1043. .iterator().hasNext();
  1044. fail("RuntimeIOException should have been thrown");
  1045. } catch(RuntimeIOException ignored) {
  1046. // success
  1047. }
  1048. List<Row> rows = new ArrayList<Row>();
  1049. for (Row row : cursor.newIterable()
  1050. .addMatchPattern("value", "val-5")
  1051. .addMatchPattern("memo", "memo-11")) {
  1052. rows.add(row);
  1053. }
  1054. assertEquals(rows, createExpectedTable(
  1055. createExpectedRow("id", 11,
  1056. "value", "val-5",
  1057. "memo", "memo-11")));
  1058. assertFalse(cursor.newIterable()
  1059. .addMatchPattern("value", "val-31")
  1060. .addMatchPattern("memo", "anything")
  1061. .iterator().hasNext());
  1062. db.close();
  1063. }
  1064. }
  1065. }