*/
public TableIterableBuilder newIterable();
+ /**
+ * @return an Iterable which returns an unmodifiable Iterator of the the
+ * TableMetaData for all tables in this Database.
+ * @throws RuntimeIOException if an IOException is thrown by one of the
+ * operations, the actual exception will be contained within
+ * @throws ConcurrentModificationException if a table is added to the
+ * database while an Iterator is in use.
+ * @usage _intermediate_method_
+ */
+ public Iterable<TableMetaData> newTableMetaDataIterable();
+
/**
* @param name User table name (case-insensitive)
* @return The Table, or null if it doesn't exist (or is a system table)
return new TableIterableBuilder(this);
}
+ @Override
+ public Iterable<TableMetaData> newTableMetaDataIterable() {
+ return new Iterable<TableMetaData>() {
+ @Override
+ public Iterator<TableMetaData> iterator() {
+ try {
+ return _tableFinder.iterateTableMetaData();
+ } catch(IOException e) {
+ throw new RuntimeIOException(e);
+ }
+ }
+ };
+ }
+
@Override
public TableImpl getTable(String name) throws IOException {
return getTable(name, false);
return false;
}
+ public int getNextFreeSyntheticId() throws IOException {
+ int maxSynthId = findMaxSyntheticId();
+ if(maxSynthId >= -1) {
+ // bummer, no more ids available
+ throw new IllegalStateException(withErrorContext(
+ "Too many database objects!"));
+ }
+ return maxSynthId + 1;
+ }
+
+ public Iterator<TableMetaData> iterateTableMetaData() throws IOException {
+ return new Iterator<TableMetaData>() {
+ private final Iterator<Row> _iter =
+ getTableNamesCursor().newIterable().setColumnNames(
+ SYSTEM_CATALOG_TABLE_DETAIL_COLUMNS).iterator();
+ private TableMetaData _next;
+
+ @Override
+ public boolean hasNext() {
+ if((_next == null) && _iter.hasNext()) {
+ _next = nextTableMetaData(_iter);
+ }
+ return (_next != null);
+ }
+
+ @Override
+ public TableMetaData next() {
+ if(!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ TableMetaData next = _next;
+ _next = null;
+ return next;
+ }
+ };
+ }
+
+ private TableMetaData nextTableMetaData(Iterator<Row> detailIter) {
+
+ while(detailIter.hasNext()) {
+ Row row = detailIter.next();
+
+ Short type = row.getShort(CAT_COL_TYPE);
+ if(!isTableType(type)) {
+ continue;
+ }
+
+ int parentId = row.getInt(CAT_COL_PARENT_ID);
+ if(parentId != _tableParentId) {
+ continue;
+ }
+
+ String realName = row.getString(CAT_COL_NAME);
+ Integer pageNumber = row.getInt(CAT_COL_ID);
+ int flags = row.getInt(CAT_COL_FLAGS);
+ String linkedDbName = row.getString(CAT_COL_DATABASE);
+ String linkedTableName = row.getString(CAT_COL_FOREIGN_NAME);
+
+ return createTableInfo(realName, pageNumber, flags, type, linkedDbName,
+ linkedTableName);
+ }
+
+ return null;
+ }
+
protected abstract Cursor findRow(Integer parentId, String name)
throws IOException;
throws IOException;
protected abstract int findMaxSyntheticId() throws IOException;
-
- public int getNextFreeSyntheticId() throws IOException
- {
- int maxSynthId = findMaxSyntheticId();
- if(maxSynthId >= -1) {
- // bummer, no more ids available
- throw new IllegalStateException(withErrorContext(
- "Too many database objects!"));
- }
- return maxSynthId + 1;
- }
}
/**
assertEquals("Row[1:1][{id=37,data=<null>}]", row.toString());
}
+ public void testIterateTableNames() throws Exception {
+ for (final TestDB testDB : SUPPORTED_DBS_TEST_FOR_READ) {
+ final Database db = open(testDB);
+
+ Set<String> names = new HashSet<>();
+ int sysCount = 0;
+ for(TableMetaData tmd : db.newTableMetaDataIterable()) {
+ if(tmd.isSystem()) {
+ ++sysCount;
+ continue;
+ }
+ assertFalse(tmd.isLinked());
+ assertNull(tmd.getLinkedTableName());
+ assertNull(tmd.getLinkedDbName());
+ names.add(tmd.getName());
+ }
+
+ assertTrue(sysCount > 4);
+ assertEquals(new HashSet<>(Arrays.asList("Table1", "Table2", "Table3",
+ "Table4")),
+ names);
+ }
+
+ for (final TestDB testDB : TestDB.getSupportedForBasename(Basename.LINKED)) {
+ final Database db = open(testDB);
+
+ Set<String> names = new HashSet<>();
+ for(TableMetaData tmd : db.newTableMetaDataIterable()) {
+ if(tmd.isSystem()) {
+ continue;
+ }
+ if("Table1".equals(tmd.getName())) {
+ assertFalse(tmd.isLinked());
+ assertNull(tmd.getLinkedTableName());
+ assertNull(tmd.getLinkedDbName());
+ } else {
+ assertTrue(tmd.isLinked());
+ assertEquals("Table1", tmd.getLinkedTableName());
+ assertEquals("Z:\\jackcess_test\\linkeeTest.accdb", tmd.getLinkedDbName());
+ }
+ names.add(tmd.getName());
+ }
+
+ assertEquals(new HashSet<>(Arrays.asList("Table1", "Table2")),
+ names);
+ }
+ }
+
private static void checkRawValue(String expected, Object val)
{
if(expected != null) {