> metaFields = metaTable.getFields();
+ assertTrue(metaFields.containsAll(generatedTable.getFields()));
+
+ // Check if relations are correctly loaded (and typed) as well
+ // [#1977] Fix this, once the "main key" concept has been removed
+ if (generatedTable instanceof UpdatableTable && metaTable instanceof UpdatableTable) {
+ UpdatableTable> generatedUTable = (UpdatableTable>) generatedTable;
+ UpdatableTable> metaUTable = (UpdatableTable>) metaTable;
+
+ // [#1977] TODO: Add key checks
+ }
+
+ // Only truly updatable tables should be "Updatable"
+ else {
+ assertFalse(metaTable instanceof UpdatableTable);
+ }
+ }
+ }
+ }
+}
diff --git a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java
index 6a976ac9d5..9dbf69bad7 100644
--- a/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java
+++ b/jOOQ-test/src/org/jooq/test/jOOQAbstractTest.java
@@ -110,6 +110,7 @@ import org.jooq.test._.testcases.GroupByTests;
import org.jooq.test._.testcases.InsertUpdateTests;
import org.jooq.test._.testcases.JoinTests;
import org.jooq.test._.testcases.LoaderTests;
+import org.jooq.test._.testcases.MetaDataTests;
import org.jooq.test._.testcases.OrderByTests;
import org.jooq.test._.testcases.PlainSQLTests;
import org.jooq.test._.testcases.PredicateTests;
@@ -869,7 +870,12 @@ public abstract class jOOQAbstractTest<
@Test
public void testMetaModel() throws Exception {
- new GeneralTests(this).testMetaModel();
+ new MetaDataTests(this).testMetaModel();
+ }
+
+ @Test
+ public void testMetaData() throws Exception {
+ new MetaDataTests(this).testMetaData();
}
@Test
diff --git a/jOOQ/src/main/java/org/jooq/Meta.java b/jOOQ/src/main/java/org/jooq/Meta.java
new file mode 100644
index 0000000000..2e7d056da2
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/Meta.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
+ * All rights reserved.
+ *
+ * This software is licensed to you under the Apache License, Version 2.0
+ * (the "License"); You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name "jOOQ" nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jooq;
+
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.jooq.exception.DataAccessException;
+import org.jooq.impl.Executor;
+
+/**
+ * A wrapping object for {@link DatabaseMetaData}
+ *
+ * This object can be obtained through {@link Executor#meta()} in order to
+ * provide convenient access to your database meta data. This abstraction has
+ * two purposes:
+ *
+ *
+ * - To increase API convenience, as no checked {@link SQLException} is
+ * thrown, only the unchecked {@link DataAccessException}
+ * - To increase API convenience, as the returned objects are always jOOQ
+ * objects, not JDBC {@link ResultSet} objects with hard-to-remember API
+ * constraints
+ *
+ *
+ * @author Lukas Eder
+ */
+public interface Meta {
+
+ /**
+ * Get all schema objects from the underlying {@link DatabaseMetaData}
+ */
+ List getSchemas();
+
+ /**
+ * Get all table objects from the underlying {@link DatabaseMetaData}
+ */
+ List> getTables();
+}
diff --git a/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java
new file mode 100644
index 0000000000..b8cfbf1eca
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/impl/MetaImpl.java
@@ -0,0 +1,213 @@
+/**
+ * Copyright (c) 2009-2012, Lukas Eder, lukas.eder@gmail.com
+ * All rights reserved.
+ *
+ * This software is licensed to you under the Apache License, Version 2.0
+ * (the "License"); You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name "jOOQ" nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.jooq.impl;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+import org.jooq.ForeignKey;
+import org.jooq.Meta;
+import org.jooq.Record;
+import org.jooq.Result;
+import org.jooq.Schema;
+import org.jooq.Table;
+import org.jooq.TableField;
+import org.jooq.UniqueKey;
+import org.jooq.UpdatableTable;
+import org.jooq.exception.DataAccessException;
+
+/**
+ * @author Lukas Eder
+ */
+class MetaImpl implements Meta {
+
+ private final Executor executor;
+ private transient DatabaseMetaData meta;
+
+ MetaImpl(Executor executor) {
+ this.executor = executor;
+ }
+
+ private final DatabaseMetaData meta() {
+ if (meta == null) {
+ try {
+ meta = executor.getConnection().getMetaData();
+ }
+ catch (SQLException e) {
+ throw new DataAccessException("Error while accessing DatabaseMetaData", e);
+ }
+ }
+
+ return meta;
+ }
+
+ @Override
+ public final List getSchemas() {
+ try {
+ List result = new ArrayList();
+ Result schemas = executor.fetch(meta().getSchemas());
+
+ for (String name : schemas.getValues(0, String.class)) {
+ result.add(new MetaSchema(name));
+ }
+
+ return result;
+ }
+ catch (SQLException e) {
+ throw new DataAccessException("Error while accessing DatabaseMetaData", e);
+ }
+ }
+
+ @Override
+ public final List> getTables() {
+ List> result = new ArrayList>();
+
+ for (Schema schema : getSchemas()) {
+ result.addAll(schema.getTables());
+ }
+
+ return result;
+ }
+
+ private class MetaSchema extends SchemaImpl {
+
+ /**
+ * Generated UID
+ */
+ private static final long serialVersionUID = -2621899850912554198L;
+
+ MetaSchema(String name) {
+ super(name);
+ }
+
+ @Override
+ public final List> getTables() {
+ try {
+ List> result = new ArrayList>();
+ Result tables = executor.fetch(meta().getTables(null, getName(), "%", null));
+
+ for (Record table : tables) {
+ String catalog = table.getValue(0, String.class);
+ String schema = table.getValue(1, String.class);
+ String name = table.getValue(2, String.class);
+
+ Result pkColumns = executor.fetch(meta().getPrimaryKeys(catalog, schema, name))
+ .sortAsc("KEY_SEQ");
+
+ if (pkColumns.size() == 0) {
+ result.add(new MetaTable(name, this));
+ }
+ else {
+ result.add(new MetaUpdatableTable(name, this));
+ }
+ }
+
+ return result;
+ }
+ catch (SQLException e) {
+ throw new DataAccessException("Error while accessing DatabaseMetaData", e);
+ }
+ }
+ }
+
+ private class MetaTable extends TableImpl {
+
+ /**
+ * Generated UID
+ */
+ private static final long serialVersionUID = 4843841667753000233L;
+
+ MetaTable(String name, Schema schema) {
+ super(name, schema);
+
+ init();
+ }
+
+ private final void init() {
+ try {
+ Result columns = executor.fetch(meta().getColumns(null, getSchema().getName(), getName(), "%"));
+
+ for (Record column : columns) {
+ createField(column.getValue("COLUMN_NAME", String.class), SQLDataType.OTHER, this);
+ }
+ }
+ catch (SQLException e) {
+ throw new DataAccessException("Error while accessing DatabaseMetaData", e);
+ }
+ }
+ }
+
+ private class MetaUpdatableTable extends MetaTable implements UpdatableTable {
+
+ /**
+ * Generated UID
+ */
+ private static final long serialVersionUID = -4555457095396846609L;
+
+ MetaUpdatableTable(String name, Schema schema) {
+ super(name, schema);
+ }
+
+ @Override
+ public final UniqueKey getMainKey() {
+ return null;
+ }
+
+ @Override
+ public final List> getKeys() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public final List> getReferencesFrom(Table other) {
+ return other.getReferencesTo(this);
+ }
+
+ @Override
+ public final TableField getRecordVersion() {
+ return null;
+ }
+
+ @Override
+ public final TableField getRecordTimestamp() {
+ return null;
+ }
+ }
+}