Merge branch 'master' into feature/fasterJoin
Conflicts:
CHANGES.md
diff --git a/CHANGES.md b/CHANGES.md
index 2a5aa51..f5cb59a 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,7 @@
* [METAMODEL-1140] - Allowed SalesforceDataContext without a security token.
* [METAMODEL-1141] - Added RFC 4180 compliant CSV parsing.
* [METAMODEL-1144] - Optimized evaluation of conditional client-side JOIN statements.
+ * [METAMODEL-1145] - Fixed bug with modelling JDBC table relationships when there are multiple keys involved in the relationship.
### Apache MetaModel 4.6.0
diff --git a/README.md b/README.md
index e5cf17a..3156d74 100644
--- a/README.md
+++ b/README.md
@@ -1,40 +1,40 @@
-## Apache MetaModel
-
-MetaModel is a data access framework, providing a common interface for exploration and querying of different types of datastores.
-
-<div>
-<img src="http://metamodel.apache.org/img/logo.png" style="float: right; margin-left: 20px;" alt="MetaModel logo" />
-</div>
-
-### Mailing lists
-
- * Developer list: dev@metamodel.apache.org
- * User list: user@metamodel.apache.org
- * Commits list: commits@metamodel.apache.org
-
-### Website
-
-http://metamodel.apache.org/
-
-### Documentation
-
-Please check out our [wiki for user documentation](https://cwiki.apache.org/confluence/display/METAMODEL).
-
-### Building the code
-
-MetaModel uses maven as it's build tool. Code can be built with:
-
-```
-mvn clean install
-```
-
-### Running the integration tests
-
- 1. Copy the file 'example-metamodel-integrationtest-configuration.properties' to your user home.
- 2. Remove the 'example-' prefix from its filename
- 3. Modify the file to enable properties of the integration tests that you're interested in.
- 4. Re-run "mvn clean install".
-
-### Contributing
-
+## Apache MetaModel
+
+MetaModel is a data access framework, providing a common interface for exploration and querying of different types of datastores.
+
+<div>
+<img src="http://metamodel.apache.org/img/logo.png" style="float: right; margin-left: 20px;" alt="MetaModel logo" />
+</div>
+
+### Mailing lists
+
+ * Developer list: dev@metamodel.apache.org
+ * User list: user@metamodel.apache.org
+ * Commits list: commits@metamodel.apache.org
+
+### Website
+
+http://metamodel.apache.org/
+
+### Documentation
+
+Please check out our [wiki for user documentation](https://cwiki.apache.org/confluence/display/METAMODEL).
+
+### Building the code
+
+MetaModel uses maven as it's build tool. Code can be built with:
+
+```
+mvn clean install
+```
+
+### Running the integration tests
+
+ 1. Copy the file 'example-metamodel-integrationtest-configuration.properties' to your user home.
+ 2. Remove the 'example-' prefix from its filename
+ 3. Modify the file to enable properties of the integration tests that you're interested in.
+ 4. Re-run "mvn clean install".
+
+### Contributing
+
Please see [CONTRIBUTE.md](CONTRIBUTE.md)
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/metamodel/factory/DataContextPropertiesImpl.java b/core/src/main/java/org/apache/metamodel/factory/DataContextPropertiesImpl.java
index e66a811..13ce9c1 100644
--- a/core/src/main/java/org/apache/metamodel/factory/DataContextPropertiesImpl.java
+++ b/core/src/main/java/org/apache/metamodel/factory/DataContextPropertiesImpl.java
@@ -288,6 +288,9 @@
@Override
public SimpleTableDef[] getTableDefs() {
final Object obj = get(PROPERTY_TABLE_DEFS);
+ if (obj == null) {
+ return null;
+ }
if (obj instanceof SimpleTableDef[]) {
return (SimpleTableDef[]) obj;
}
diff --git a/jdbc/pom.xml b/jdbc/pom.xml
index 91aefc5..858e0ab 100644
--- a/jdbc/pom.xml
+++ b/jdbc/pom.xml
@@ -29,6 +29,10 @@
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
<!-- Test dependencies -->
<dependency>
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcMetadataLoader.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcMetadataLoader.java
index 837fb18..2c29405 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcMetadataLoader.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/JdbcMetadataLoader.java
@@ -22,7 +22,12 @@
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
@@ -58,7 +63,8 @@
private final Set<Integer> _loadedIndexes;
private final Set<Integer> _loadedPrimaryKeys;
- public JdbcMetadataLoader(JdbcDataContext dataContext, boolean usesCatalogsAsSchemas, String identifierQuoteString) {
+ public JdbcMetadataLoader(JdbcDataContext dataContext, boolean usesCatalogsAsSchemas,
+ String identifierQuoteString) {
_dataContext = dataContext;
_usesCatalogsAsSchemas = usesCatalogsAsSchemas;
_identifierQuoteString = identifierQuoteString;
@@ -92,7 +98,7 @@
}
private String getJdbcSchemaName(Schema schema) {
- if(_usesCatalogsAsSchemas) {
+ if (_usesCatalogsAsSchemas) {
return null;
} else {
return schema.getName();
@@ -100,7 +106,7 @@
}
private String getCatalogName(Schema schema) {
- if(_usesCatalogsAsSchemas) {
+ if (_usesCatalogsAsSchemas) {
return schema.getName();
} else {
return _dataContext.getCatalogName();
@@ -109,8 +115,8 @@
private void loadTables(JdbcSchema schema, DatabaseMetaData metaData, String[] types) {
try (ResultSet rs = metaData.getTables(getCatalogName(schema), getJdbcSchemaName(schema), null, types)) {
- logger.debug("Querying for table types {}, in catalog: {}, schema: {}", types,
- _dataContext.getCatalogName(), schema.getName());
+ logger.debug("Querying for table types {}, in catalog: {}, schema: {}", types, _dataContext
+ .getCatalogName(), schema.getName());
schema.clearTables();
int tableNumber = -1;
@@ -138,15 +144,15 @@
if (tablesReturned == 0) {
logger.info("No table metadata records returned for schema '{}'", schema.getName());
} else {
- logger.debug("Returned {} table metadata records for schema '{}'", new Object[] { tablesReturned,
- schema.getName() });
+ logger.debug("Returned {} table metadata records for schema '{}'", new Object[] { tablesReturned, schema
+ .getName() });
}
} catch (SQLException e) {
throw JdbcUtils.wrapException(e, "retrieve table metadata for " + schema.getName());
}
}
-
+
@Override
public void loadIndexes(JdbcTable jdbcTable) {
final int identity = System.identityHashCode(jdbcTable);
@@ -182,7 +188,7 @@
}
}
}
-
+
@Override
public void loadPrimaryKeys(JdbcTable jdbcTable) {
final int identity = System.identityHashCode(jdbcTable);
@@ -220,7 +226,8 @@
private void loadPrimaryKeys(JdbcTable table, DatabaseMetaData metaData) throws MetaModelException {
Schema schema = table.getSchema();
- try (ResultSet rs = metaData.getPrimaryKeys(getCatalogName(schema), getJdbcSchemaName(schema), table.getName());){
+ try (ResultSet rs = metaData.getPrimaryKeys(getCatalogName(schema), getJdbcSchemaName(schema), table
+ .getName());) {
while (rs.next()) {
String columnName = rs.getString(4);
if (columnName != null) {
@@ -242,7 +249,8 @@
// Ticket #170: IndexInfo is nice-to-have, not need-to-have, so
// we will do a nice failover on SQLExceptions
- try (ResultSet rs = metaData.getIndexInfo(getCatalogName(schema), getJdbcSchemaName(schema), table.getName(), false, true)) {
+ try (ResultSet rs = metaData.getIndexInfo(getCatalogName(schema), getJdbcSchemaName(schema), table.getName(),
+ false, true)) {
while (rs.next()) {
String columnName = rs.getString(9);
if (columnName != null) {
@@ -258,7 +266,7 @@
throw JdbcUtils.wrapException(e, "retrieve index information for " + table.getName());
}
}
-
+
@Override
public void loadColumns(JdbcTable jdbcTable) {
final int identity = System.identityHashCode(jdbcTable);
@@ -309,7 +317,8 @@
final boolean convertLobs = isLobConversionEnabled();
final Schema schema = table.getSchema();
- try (ResultSet rs = metaData.getColumns(getCatalogName(schema), getJdbcSchemaName(schema), table.getName(), null)) {
+ try (ResultSet rs = metaData.getColumns(getCatalogName(schema), getJdbcSchemaName(schema), table.getName(),
+ null)) {
if (logger.isDebugEnabled()) {
logger.debug("Querying for columns in table: " + table.getName());
}
@@ -327,8 +336,8 @@
final Integer columnSize = rs.getInt(7);
if (logger.isDebugEnabled()) {
- logger.debug("Found column: table=" + table.getName() + ",columnName=" + columnName
- + ",nativeType=" + nativeType + ",columnSize=" + columnSize);
+ logger.debug("Found column: table=" + table.getName() + ",columnName=" + columnName + ",nativeType="
+ + nativeType + ",columnSize=" + columnSize);
}
ColumnType columnType = _dataContext.getQueryRewriter().getColumnType(jdbcType, nativeType, columnSize);
@@ -362,17 +371,17 @@
final int columnsReturned = columnNumber + 1;
if (columnsReturned == 0) {
- logger.info("No column metadata records returned for table '{}' in schema '{}'", table.getName(),
- schema.getName());
+ logger.info("No column metadata records returned for table '{}' in schema '{}'", table.getName(), schema
+ .getName());
} else {
- logger.debug("Returned {} column metadata records for table '{}' in schema '{}'", columnsReturned,
- table.getName(), schema.getName());
+ logger.debug("Returned {} column metadata records for table '{}' in schema '{}'", columnsReturned, table
+ .getName(), schema.getName());
}
} catch (SQLException e) {
throw JdbcUtils.wrapException(e, "retrieve table metadata for " + table.getName());
}
}
-
+
@Override
public void loadRelations(JdbcSchema jdbcSchema) {
final int identity = System.identityHashCode(jdbcSchema);
@@ -412,7 +421,8 @@
private void loadRelations(Table table, DatabaseMetaData metaData) {
Schema schema = table.getSchema();
- try (ResultSet rs = metaData.getImportedKeys(getCatalogName(schema), getJdbcSchemaName(schema), table.getName())) {
+ try (ResultSet rs = metaData.getImportedKeys(getCatalogName(schema), getJdbcSchemaName(schema), table
+ .getName())) {
loadRelations(rs, schema);
} catch (SQLException e) {
throw JdbcUtils.wrapException(e, "retrieve imported keys for " + table.getName());
@@ -420,7 +430,12 @@
}
private void loadRelations(ResultSet rs, Schema schema) throws SQLException {
+ // by using nested maps, we can associate a list of pk/fk columns with
+ // the tables they belong to
+ // the result set comes flattened out.
+ Map<Table, Map<Table, ColumnsTuple>> relations = new HashMap<>();
while (rs.next()) {
+
String pkTableName = rs.getString(3);
String pkColumnName = rs.getString(4);
@@ -453,9 +468,42 @@
logger.error("pkColumn={}", pkColumn);
logger.error("fkColumn={}", fkColumn);
} else {
- MutableRelationship.createRelationship(new Column[] { pkColumn }, new Column[] { fkColumn });
+
+ if (!relations.containsKey(pkTable)) {
+ relations.put(pkTable, new HashMap<>());
+ }
+
+ // get or init the columns tuple
+ ColumnsTuple ct = relations.get(pkTable).get(fkTable);
+ if (Objects.isNull(ct)) {
+ ct = new ColumnsTuple();
+ relations.get(pkTable).put(fkTable, ct);
+ }
+ // we can now safely add the columns
+ ct.getPkCols().add(pkColumn);
+ ct.getFkCols().add(fkColumn);
}
}
+
+ relations.values().stream().flatMap(map -> map.values().stream()).forEach(ct -> MutableRelationship
+ .createRelationship(ct.getPkCols().toArray(new Column[0]), ct.getFkCols().toArray(new Column[0])));
+ }
+
+ /**
+ * Represents the columns of a relationship while it is being built from a
+ * {@link ResultSet}.
+ */
+ private static class ColumnsTuple {
+ private final List<Column> pkCols = new ArrayList<>();
+ private final List<Column> fkCols = new ArrayList<>();
+
+ public List<Column> getFkCols() {
+ return fkCols;
+ }
+
+ public List<Column> getPkCols() {
+ return pkCols;
+ }
}
}
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
index 90a2411..a9881fa 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/DefaultQueryRewriter.java
@@ -45,11 +45,10 @@
import org.slf4j.LoggerFactory;
/**
- * Generic query rewriter that adds syntax enhancements that are only possible
- * to resolve just before execution time.
+ * Generic query rewriter that adds syntax enhancements that are only possible to resolve just before execution time.
*/
public class DefaultQueryRewriter extends AbstractQueryRewriter {
-
+
private static final Logger logger = LoggerFactory.getLogger(DefaultQueryRewriter.class);
private static final String SPECIAL_ALIAS_CHARACTERS = "- ,.|*%()!#¤/\\=?;:~";
@@ -101,7 +100,7 @@
return super.rewriteColumnType(columnType, columnSize);
}
- private boolean needsQuoting(String alias, String identifierQuoteString) {
+ protected boolean needsQuoting(String alias, String identifierQuoteString) {
boolean result = false;
if (alias != null && identifierQuoteString != null) {
if (alias.indexOf(identifierQuoteString) == -1) {
@@ -139,11 +138,10 @@
// operand is a set of values (typically in combination with an
// IN or NOT IN operator). Each individual element must be escaped.
- assert OperatorType.IN.equals(item.getOperator()) ||
- OperatorType.NOT_IN.equals(item.getOperator());
+ assert OperatorType.IN.equals(item.getOperator()) || OperatorType.NOT_IN.equals(item.getOperator());
- @SuppressWarnings("unchecked")
- final List<Object> elements = (List<Object>) CollectionUtils.toList(operand);
+ @SuppressWarnings("unchecked") final List<Object> elements =
+ (List<Object>) CollectionUtils.toList(operand);
for (ListIterator<Object> it = elements.listIterator(); it.hasNext();) {
Object next = it.next();
@@ -169,8 +167,7 @@
}
/**
- * Rewrites a (non-compound) {@link FilterItem} when it's operand has
- * already been rewritten into a SQL literal.
+ * Rewrites a (non-compound) {@link FilterItem} when it's operand has already been rewritten into a SQL literal.
*
* @param item
* @param operandLiteral
@@ -187,11 +184,10 @@
}
/**
- * Rewrites a {@link Timestamp} into it's literal representation as known by
- * this SQL dialect.
+ * Rewrites a {@link Timestamp} into it's literal representation as known by this SQL dialect.
*
- * This default implementation returns the JDBC spec's escape syntax for a
- * timestamp: {ts 'yyyy-mm-dd hh:mm:ss.f . . .'}
+ * This default implementation returns the JDBC spec's escape syntax for a timestamp: {ts 'yyyy-mm-dd hh:mm:ss.f . .
+ * .'}
*
* @param ts
* @return
diff --git a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java
index 5d64b31..e98ec48 100644
--- a/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java
+++ b/jdbc/src/main/java/org/apache/metamodel/jdbc/dialects/HsqldbQueryRewriter.java
@@ -26,6 +26,8 @@
import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.ColumnType;
+import com.google.common.base.CharMatcher;
+
/**
* Query rewriter for HSQLDB
*/
@@ -99,4 +101,15 @@
return super.rewriteFilterItem(item);
}
+ /**
+ * HSQL converts all non-escaped characters to uppercases, this is prevented by always escaping
+ */
+ @Override
+ public boolean needsQuoting(String alias, String identifierQuoteString) {
+
+ boolean containsLowerCase = CharMatcher.JAVA_LOWER_CASE.matchesAnyOf(identifierQuoteString);
+
+ return containsLowerCase || super.needsQuoting(alias, identifierQuoteString);
+ }
+
}
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java
index 6e21ae5..d46bc31 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/H2databaseTest.java
@@ -22,6 +22,7 @@
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
+import java.sql.Statement;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -41,6 +42,7 @@
import org.apache.metamodel.query.SelectItem;
import org.apache.metamodel.schema.Column;
import org.apache.metamodel.schema.ColumnType;
+import org.apache.metamodel.schema.Relationship;
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
import org.apache.metamodel.update.Update;
@@ -52,12 +54,12 @@
* Test case that tests interaction with the H2 embedded database
*/
public class H2databaseTest extends TestCase {
-
+
public static final String DRIVER_CLASS = "org.h2.Driver";
public static final String URL_MEMORY_DATABASE = "jdbc:h2:mem:";
- private final String[] FIRST_NAMES = { "Suzy", "Barbara", "John", "Ken", "Billy", "Larry", "Joe", "Margareth", "Bobby",
- "Elizabeth" };
+ private final String[] FIRST_NAMES = { "Suzy", "Barbara", "John", "Ken", "Billy", "Larry", "Joe", "Margareth",
+ "Bobby", "Elizabeth" };
private final String[] LAST_NAMES = { "Doe", "Gates", "Jobs", "Ellison", "Trump" };
private Connection conn;
@@ -74,7 +76,7 @@
super.tearDown();
conn.close();
}
-
+
public void testCreateInsertAndUpdate() throws Exception {
JdbcDataContext dc = new JdbcDataContext(conn);
JdbcTestTemplates.simpleCreateInsertUpdateAndDrop(dc, "metamodel_test_simple");
@@ -84,14 +86,14 @@
JdbcDataContext dc = new JdbcDataContext(conn);
JdbcTestTemplates.compositeKeyCreation(dc, "metamodel_test_composite_keys");
}
-
+
public void testTimestampValueInsertSelect() throws Exception {
JdbcTestTemplates.timestampValueInsertSelect(conn, TimeUnit.NANOSECONDS);
}
public void testUsingSingleUpdates() throws Exception {
final JdbcDataContext dc = new JdbcDataContext(conn);
-
+
final Schema schema = dc.getDefaultSchema();
dc.executeUpdate(new CreateTable(schema, "test_table").withColumn("id").ofType(ColumnType.VARCHAR));
@@ -108,7 +110,6 @@
ds.close();
dc.executeUpdate(new DeleteFrom(table).where("id").eq("bar"));
-
ds = dc.query().from(table).selectCount().execute();
assertTrue(ds.next());
@@ -117,7 +118,7 @@
ds.close();
dc.executeUpdate(new Update(table).where("id").eq("foo").value("id", "baz"));
-
+
ds = dc.query().from(table).selectAll().execute();
assertTrue(ds.next());
assertEquals("Row[values=[baz]]", ds.getRow().toString());
@@ -166,7 +167,8 @@
Query q = dc.query().from(table).selectCount().and(FunctionType.MAX, ageColumn).and(FunctionType.MIN, ageColumn)
.toQuery();
- assertEquals("SELECT COUNT(*), MAX(\"TEST_TABLE\".\"AGE\"), MIN(\"TEST_TABLE\".\"AGE\") FROM PUBLIC.\"TEST_TABLE\"",
+ assertEquals(
+ "SELECT COUNT(*), MAX(\"TEST_TABLE\".\"AGE\"), MIN(\"TEST_TABLE\".\"AGE\") FROM PUBLIC.\"TEST_TABLE\"",
q.toSql());
assertEquals(1, dc.getFetchSizeCalculator().getFetchSize(q));
@@ -182,9 +184,10 @@
int minAge = ((Number) row.getValue(2)).intValue();
assertTrue("Minimum age was: " + minAge, minAge < 10 && minAge >= 0);
- q = dc.query().from(table).as("t").select(ageColumn).selectCount().where(ageColumn).greaterThan(50).groupBy(ageColumn)
- .toQuery();
- assertEquals("SELECT t.\"AGE\", COUNT(*) FROM PUBLIC.\"TEST_TABLE\" t WHERE t.\"AGE\" > 50 GROUP BY t.\"AGE\"", q.toSql());
+ q = dc.query().from(table).as("t").select(ageColumn).selectCount().where(ageColumn).greaterThan(50).groupBy(
+ ageColumn).toQuery();
+ assertEquals("SELECT t.\"AGE\", COUNT(*) FROM PUBLIC.\"TEST_TABLE\" t WHERE t.\"AGE\" > 50 GROUP BY t.\"AGE\"",
+ q.toSql());
ds = dc.executeQuery(q);
List<Object[]> objectArrays = ds.toObjectArrays();
@@ -232,8 +235,10 @@
@Override
public void run(UpdateCallback cb) {
- JdbcCreateTableBuilder createTableBuilder = (JdbcCreateTableBuilder) cb.createTable(schema, "test_table");
- Table writtenTable = createTableBuilder.withColumn("id").asPrimaryKey().ofType(ColumnType.INTEGER).execute();
+ JdbcCreateTableBuilder createTableBuilder = (JdbcCreateTableBuilder) cb.createTable(schema,
+ "test_table");
+ Table writtenTable = createTableBuilder.withColumn("id").asPrimaryKey().ofType(ColumnType.INTEGER)
+ .execute();
for (int i = 0; i < 10; i++) {
cb.insertInto(writtenTable).value("id", i + 1).execute();
@@ -276,12 +281,15 @@
@Override
public void run(UpdateCallback cb) {
- JdbcCreateTableBuilder createTableBuilder = (JdbcCreateTableBuilder) cb.createTable(schema, "test_table");
+ JdbcCreateTableBuilder createTableBuilder = (JdbcCreateTableBuilder) cb.createTable(schema,
+ "test_table");
Table writtenTable = createTableBuilder.withColumn("id").asPrimaryKey().ofType(ColumnType.INTEGER)
- .withColumn("name").ofSize(255).ofType(ColumnType.VARCHAR).withColumn("age").ofType(ColumnType.INTEGER)
- .execute();
+ .withColumn("name").ofSize(255).ofType(ColumnType.VARCHAR).withColumn("age").ofType(
+ ColumnType.INTEGER).execute();
String sql = createTableBuilder.createSqlStatement();
- assertEquals("CREATE TABLE PUBLIC.test_table (id INTEGER, name VARCHAR(255), age INTEGER, PRIMARY KEY(id))", sql);
+ assertEquals(
+ "CREATE TABLE PUBLIC.test_table (id INTEGER, name VARCHAR(255), age INTEGER, PRIMARY KEY(id))",
+ sql);
assertNotNull(writtenTable);
assertEquals("[ID, NAME, AGE]", Arrays.toString(writtenTable.getColumnNames()));
@@ -310,11 +318,13 @@
@Override
public void run(UpdateCallback cb) {
cb.insertInto(writtenTableRef.get()).value("age", 14).value("name", "hello").value("id", 1).execute();
- JdbcInsertBuilder insertBuilder = (JdbcInsertBuilder) cb.insertInto(writtenTableRef.get()).value("age", 15)
- .value("name", "wor'ld").value("id", 2);
- assertEquals("INSERT INTO PUBLIC.\"TEST_TABLE\" (ID,NAME,AGE) VALUES (?,?,?)", insertBuilder.createSqlStatement());
+ JdbcInsertBuilder insertBuilder = (JdbcInsertBuilder) cb.insertInto(writtenTableRef.get()).value("age",
+ 15).value("name", "wor'ld").value("id", 2);
+ assertEquals("INSERT INTO PUBLIC.\"TEST_TABLE\" (ID,NAME,AGE) VALUES (?,?,?)", insertBuilder
+ .createSqlStatement());
insertBuilder.execute();
- cb.insertInto(writtenTableRef.get()).value("age", 16).value("name", "escobar!").value("id", 3).execute();
+ cb.insertInto(writtenTableRef.get()).value("age", 16).value("name", "escobar!").value("id", 3)
+ .execute();
}
});
@@ -331,10 +341,10 @@
dc.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
- JdbcUpdateBuilder updateCallback = (JdbcUpdateBuilder) callback.update("test_table").value("age", 18).where("id")
- .greaterThan(1);
- assertEquals("UPDATE PUBLIC.\"TEST_TABLE\" SET AGE=? WHERE \"TEST_TABLE\".\"ID\" > ?",
- updateCallback.createSqlStatement());
+ JdbcUpdateBuilder updateCallback = (JdbcUpdateBuilder) callback.update("test_table").value("age", 18)
+ .where("id").greaterThan(1);
+ assertEquals("UPDATE PUBLIC.\"TEST_TABLE\" SET AGE=? WHERE \"TEST_TABLE\".\"ID\" > ?", updateCallback
+ .createSqlStatement());
updateCallback.execute();
}
});
@@ -388,8 +398,8 @@
dc.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
- Table table = callback.createTable(dc.getDefaultSchema(), "test_table").withColumn("foo")
- .ofType(ColumnType.INTEGER).withColumn("bar").ofType(ColumnType.VARCHAR).execute();
+ Table table = callback.createTable(dc.getDefaultSchema(), "test_table").withColumn("foo").ofType(
+ ColumnType.INTEGER).withColumn("bar").ofType(ColumnType.VARCHAR).execute();
callback.insertInto(table).value("foo", 1).value("bar", "hello").execute();
callback.insertInto(table).value("foo", 2).value("bar", "there").execute();
callback.insertInto(table).value("foo", 3).value("bar", "world").execute();
@@ -400,8 +410,8 @@
Query query = new Query().from(table, "a").from(table, "b");
query.select(table.getColumnByName("foo"), query.getFromClause().getItem(0));
query.select(table.getColumnByName("foo"), query.getFromClause().getItem(1));
- query.where(new SelectItem(table.getColumnByName("bar"), query.getFromClause().getItem(0)), OperatorType.EQUALS_TO,
- "hello");
+ query.where(new SelectItem(table.getColumnByName("bar"), query.getFromClause().getItem(0)),
+ OperatorType.EQUALS_TO, "hello");
assertEquals(
"SELECT a.\"FOO\", b.\"FOO\" FROM PUBLIC.\"TEST_TABLE\" a, PUBLIC.\"TEST_TABLE\" b WHERE a.\"BAR\" = 'hello'",
@@ -440,8 +450,8 @@
dc.executeUpdate(new UpdateScript() {
@Override
public void run(UpdateCallback callback) {
- Table table = callback.createTable(dc.getDefaultSchema(), "test_table").withColumn("foo")
- .ofType(ColumnType.INTEGER).withColumn("bar").ofType(ColumnType.VARCHAR).execute();
+ Table table = callback.createTable(dc.getDefaultSchema(), "test_table").withColumn("foo").ofType(
+ ColumnType.INTEGER).withColumn("bar").ofType(ColumnType.VARCHAR).execute();
callback.insertInto(table).value("foo", 1).value("bar", "hello").execute();
callback.insertInto(table).value("foo", 2).value("bar", "there").execute();
callback.insertInto(table).value("foo", 3).value("bar", "world").execute();
@@ -517,8 +527,36 @@
public void testCharOfSizeOne() throws Exception {
JdbcTestTemplates.meaningOfOneSizeChar(conn);
}
-
+
public void testInterpretationOfNull() throws Exception {
JdbcTestTemplates.interpretationOfNulls(conn);
}
+
+ public void testCompositeFkRelation() throws Exception {
+
+ try (Statement stmt = conn.createStatement()) {
+ stmt.execute(
+ "CREATE TABLE PARENT (P1 INTEGER, P2 INTEGER, P3 INTEGER, P4 INTEGER, PRIMARY KEY (P1,P2, P3, P4))");
+ stmt.execute(
+ "CREATE TABLE CHILD (C1 INTEGER PRIMARY KEY, CP1 INTEGER , CP2 INTEGER, CP3 INTEGER, CP4 INTEGER, FOREIGN KEY (CP1,CP2,CP3,CP4) REFERENCES PARENT(P1,P2,P3,P4))");
+ }
+
+ final JdbcDataContext dc = new JdbcDataContext(conn);
+
+ final Schema schema = dc.getDefaultSchema();
+
+ assertEquals(1, schema.getRelationships().length);
+
+ Relationship rel = schema.getRelationships()[0];
+
+ assertEquals("CP1", rel.getForeignColumns()[0].getName());
+ assertEquals("CP2", rel.getForeignColumns()[1].getName());
+ assertEquals("CP3", rel.getForeignColumns()[2].getName());
+ assertEquals("CP4", rel.getForeignColumns()[3].getName());
+
+ assertEquals("P1", rel.getPrimaryColumns()[0].getName());
+ assertEquals("P2", rel.getPrimaryColumns()[1].getName());
+ assertEquals("P3", rel.getPrimaryColumns()[2].getName());
+ assertEquals("P4", rel.getPrimaryColumns()[3].getName());
+ }
}
\ No newline at end of file
diff --git a/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java b/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
index 12d5fe2..d9f0587 100644
--- a/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
+++ b/jdbc/src/test/java/org/apache/metamodel/jdbc/HsqldbTest.java
@@ -23,12 +23,11 @@
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Arrays;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.swing.table.TableModel;
-import junit.framework.TestCase;
-
import org.apache.metamodel.DataContext;
import org.apache.metamodel.MetaModelHelper;
import org.apache.metamodel.UpdateCallback;
@@ -47,10 +46,11 @@
import org.apache.metamodel.schema.Schema;
import org.apache.metamodel.schema.Table;
+import junit.framework.TestCase;
+
/**
- * Test case that tests hsqldb interaction. The test uses an embedded copy of
- * the "pentaho sampledata" sample database that can be found at
- * http://pentaho.sourceforge.net.
+ * Test case that tests hsqldb interaction. The test uses an embedded copy of the "pentaho sampledata" sample database
+ * that can be found at http://pentaho.sourceforge.net.
*/
public class HsqldbTest extends TestCase {
@@ -71,7 +71,7 @@
super.tearDown();
_connection.close();
}
-
+
public void testApproximateCount() throws Exception {
final JdbcDataContext dataContext = new JdbcDataContext(_connection);
final DataSet dataSet = dataContext.executeQuery("SELECT APPROXIMATE COUNT(*) FROM customers");
@@ -79,7 +79,7 @@
assertEquals(122, dataSet.getRow().getValue(0));
assertFalse(dataSet.next());
}
-
+
public void testTimestampValueInsertSelect() throws Exception {
Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:" + getName(), USERNAME, PASSWORD);
JdbcTestTemplates.timestampValueInsertSelect(connection, TimeUnit.NANOSECONDS);
@@ -111,8 +111,7 @@
+ "Table[name=CUSTOMER_W_TER,type=TABLE,remarks=null], "
+ "Table[name=DEPARTMENT_MANAGERS,type=TABLE,remarks=null], "
+ "Table[name=DIM_TIME,type=TABLE,remarks=null], " + "Table[name=EMPLOYEES,type=TABLE,remarks=null], "
- + "Table[name=OFFICES,type=TABLE,remarks=null], "
- + "Table[name=ORDERDETAILS,type=TABLE,remarks=null], "
+ + "Table[name=OFFICES,type=TABLE,remarks=null], " + "Table[name=ORDERDETAILS,type=TABLE,remarks=null], "
+ "Table[name=ORDERFACT,type=TABLE,remarks=null], " + "Table[name=ORDERS,type=TABLE,remarks=null], "
+ "Table[name=PAYMENTS,type=TABLE,remarks=null], " + "Table[name=PRODUCTS,type=TABLE,remarks=null], "
+ "Table[name=QUADRANT_ACTUALS,type=TABLE,remarks=null], "
@@ -146,8 +145,8 @@
Table productsTable = schema.getTableByName("PRODUCTS");
Table factTable = schema.getTableByName("ORDERFACT");
- Query q = new Query().from(new FromItem(JoinType.INNER, productsTable.getRelationships(factTable)[0])).select(
- productsTable.getColumns()[0], factTable.getColumns()[0]);
+ Query q = new Query().from(new FromItem(JoinType.INNER, productsTable.getRelationships(factTable)[0]))
+ .select(productsTable.getColumns()[0], factTable.getColumns()[0]);
assertEquals(
"SELECT \"PRODUCTS\".\"PRODUCTCODE\", \"ORDERFACT\".\"ORDERNUMBER\" FROM PUBLIC.\"PRODUCTS\" INNER JOIN PUBLIC.\"ORDERFACT\" ON \"PRODUCTS\".\"PRODUCTCODE\" = \"ORDERFACT\".\"PRODUCTCODE\"",
q.toString());
@@ -158,8 +157,8 @@
assertEquals(2, tableModel.getColumnCount());
assertEquals(2996, tableModel.getRowCount());
- assertEquals(110, MetaModelHelper.executeSingleRowQuery(dc, new Query().selectCount().from(productsTable))
- .getValue(0));
+ assertEquals(110,
+ MetaModelHelper.executeSingleRowQuery(dc, new Query().selectCount().from(productsTable)).getValue(0));
}
public void testLimit() throws Exception {
@@ -215,23 +214,21 @@
Schema schema = dc.getSchemaByName("PUBLIC");
Table productsTable = schema.getTableByName("PRODUCTS");
- Query q = new Query().from(productsTable, "pro-ducts").select(
- new SelectItem(productsTable.getColumnByName("PRODUCTCODE")).setAlias("c|o|d|e"));
+ Query q = new Query().from(productsTable, "pro-ducts")
+ .select(new SelectItem(productsTable.getColumnByName("PRODUCTCODE")).setAlias("c|o|d|e"));
q.setMaxRows(5);
assertEquals("SELECT pro-ducts.\"PRODUCTCODE\" AS c|o|d|e FROM PUBLIC.\"PRODUCTS\" pro-ducts", q.toString());
String queryString = queryRewriter.rewriteQuery(q);
- assertEquals(
- "SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
+ assertEquals("SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
queryString);
// We have to test that no additional quoting characters are added every
// time we run the rewriting
queryString = queryRewriter.rewriteQuery(q);
queryString = queryRewriter.rewriteQuery(q);
- assertEquals(
- "SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
+ assertEquals("SELECT TOP 5 \"pro-ducts\".\"PRODUCTCODE\" AS \"c|o|d|e\" FROM PUBLIC.\"PRODUCTS\" \"pro-ducts\"",
queryString);
// Test that the original query is still the same (ie. it has been
@@ -248,9 +245,10 @@
Column column = dc.getDefaultSchema().getTableByName("PRODUCTS").getColumnByName("PRODUCTCODE");
assertEquals("PUBLIC.PRODUCTS.PRODUCTCODE", column.getQualifiedLabel());
- assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]", dc.getTableByQualifiedLabel("PUBLIC.PRODUCTS")
- .toString());
- assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]", dc.getTableByQualifiedLabel("PRODUCTS").toString());
+ assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]",
+ dc.getTableByQualifiedLabel("PUBLIC.PRODUCTS").toString());
+ assertEquals("Table[name=PRODUCTS,type=TABLE,remarks=null]",
+ dc.getTableByQualifiedLabel("PRODUCTS").toString());
assertEquals(
"Column[name=PRODUCTCODE,columnNumber=0,type=VARCHAR,nullable=false,nativeType=VARCHAR,columnSize=50]",
dc.getColumnByQualifiedLabel("PUBLIC.PRODUCTS.PRODUCTCODE").toString());
@@ -293,8 +291,8 @@
q = dc.query().from(table).selectCount().where("name").isEquals("m'jello").toQuery();
assertEquals("SELECT COUNT(*) FROM PUBLIC.\"TESTTABLE\" WHERE \"TESTTABLE\".\"NAME\" = 'm'jello'", q.toSql());
- assertEquals("SELECT COUNT(*) FROM PUBLIC.\"TESTTABLE\" WHERE \"TESTTABLE\".\"NAME\" = 'm''jello'", dc
- .getQueryRewriter().rewriteQuery(q));
+ assertEquals("SELECT COUNT(*) FROM PUBLIC.\"TESTTABLE\" WHERE \"TESTTABLE\".\"NAME\" = 'm''jello'",
+ dc.getQueryRewriter().rewriteQuery(q));
row = MetaModelHelper.executeSingleRowQuery(dc, q);
assertEquals(1, ((Number) row.getValue(0)).intValue());
@@ -335,8 +333,8 @@
}
public void testInsertOfDifferentTypes() throws Exception {
- Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:different_types_insert", USERNAME,
- PASSWORD);
+ Connection connection =
+ DriverManager.getConnection("jdbc:hsqldb:mem:different_types_insert", USERNAME, PASSWORD);
try {
connection.createStatement().execute("DROP TABLE my_table");
@@ -417,4 +415,69 @@
Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:interpretation_of_null", USERNAME, PASSWORD);
JdbcTestTemplates.interpretationOfNulls(conn);
}
+
+ public void testCapitalization() throws Exception {
+ try (Connection connection =
+ DriverManager.getConnection("jdbc:hsqldb:mem:different_types_insert", USERNAME, PASSWORD)) {
+
+ final JdbcDataContext dcon = new JdbcDataContext(connection);
+
+ final String mixedcap = "MixedCapitalization";
+ final String idCol = "Id";
+ final String nameCol = "name";
+ final String emailCol = "EMAIL";
+ final String createTable = "CREATE TABLE \"" + mixedcap + "\" (\"" + idCol + "\" INTEGER, \"" + nameCol
+ + "\" LONGVARCHAR, \"" + emailCol + "\" LONGVARCHAR)";
+
+ try (Statement stmt = connection.createStatement();) {
+
+ stmt.execute(createTable);
+
+ }
+
+ dcon.refreshSchemas();
+ assertEquals(mixedcap, dcon.getDefaultSchema().getTable(0).getName());
+ assertEquals(idCol, dcon.getDefaultSchema().getTable(0).getColumn(0).getName());
+
+ dcon.query().from(mixedcap).select(idCol, nameCol, emailCol).execute();
+
+ try (Statement stmt = connection.createStatement()) {
+ stmt.execute("DROP TABLE \"" + mixedcap + "\"");
+ }
+ dcon.refreshSchemas();
+ dcon.executeUpdate(new UpdateScript() {
+
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.createTable(dcon.getDefaultSchemaName(), mixedcap).withColumn(idCol).asPrimaryKey()
+ .ofType(ColumnType.INTEGER).withColumn(nameCol).ofType(ColumnType.STRING)
+ .withColumn(emailCol).ofType(ColumnType.STRING).execute();
+ }
+ });
+
+ dcon.executeUpdate(new UpdateScript() {
+
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.insertInto(mixedcap).value(idCol, 1).value(nameCol, "Sarah")
+ .value(emailCol, "sarah@example.com").execute();
+ }
+ });
+
+ String queryNoQuotes = "SELECT " + nameCol + ", " + idCol + ", " + emailCol + " FROM " + mixedcap
+ + " WHERE " + idCol + "= 1";
+ DataSet dsStringQueryNQ = dcon.executeQuery(queryNoQuotes);
+ List<Row> rowsQueryNoQuotes = dsStringQueryNQ.toRows();
+ assertEquals(1, rowsQueryNoQuotes.size());
+ List<Row> rowsQueryObject = dcon.query().from(mixedcap).select(nameCol).select(idCol).select(emailCol)
+ .where(idCol).eq(1).execute().toRows();
+ assertEquals(1, rowsQueryObject.size());
+
+ assertEquals(rowsQueryObject.get(0).getValue(0), rowsQueryNoQuotes.get(0).getValue(0));
+ assertEquals(rowsQueryObject.get(0).getValue(1), rowsQueryNoQuotes.get(0).getValue(1));
+ assertEquals(rowsQueryObject.get(0).getValue(2), rowsQueryNoQuotes.get(0).getValue(2));
+
+ }
+
+ }
}
\ No newline at end of file
diff --git a/pojo/src/main/java/org/apache/metamodel/pojo/PojoDataContext.java b/pojo/src/main/java/org/apache/metamodel/pojo/PojoDataContext.java
index 9369e96..340228f 100644
--- a/pojo/src/main/java/org/apache/metamodel/pojo/PojoDataContext.java
+++ b/pojo/src/main/java/org/apache/metamodel/pojo/PojoDataContext.java
@@ -49,6 +49,8 @@
public class PojoDataContext extends QueryPostprocessDataContext implements UpdateableDataContext, Serializable {
private static final long serialVersionUID = 1L;
+
+ public static final String DEFAULT_SCHEMA_NAME = "Schema";
private final Map<String, TableDataProvider<?>> _tables;
private final String _schemaName;
@@ -68,7 +70,7 @@
* @param tables
*/
public PojoDataContext(List<TableDataProvider<?>> tables) {
- this("Schema", tables);
+ this(DEFAULT_SCHEMA_NAME, tables);
}
/**
diff --git a/pojo/src/main/java/org/apache/metamodel/pojo/PojoDataContextFactory.java b/pojo/src/main/java/org/apache/metamodel/pojo/PojoDataContextFactory.java
new file mode 100644
index 0000000..35842bf
--- /dev/null
+++ b/pojo/src/main/java/org/apache/metamodel/pojo/PojoDataContextFactory.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.metamodel.pojo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.metamodel.ConnectionException;
+import org.apache.metamodel.DataContext;
+import org.apache.metamodel.factory.DataContextFactory;
+import org.apache.metamodel.factory.DataContextProperties;
+import org.apache.metamodel.factory.ResourceFactoryRegistry;
+import org.apache.metamodel.factory.UnsupportedDataContextPropertiesException;
+import org.apache.metamodel.util.SimpleTableDef;
+
+public class PojoDataContextFactory implements DataContextFactory {
+
+ public static final String PROPERTY_TYPE = "pojo";
+
+ @Override
+ public boolean accepts(DataContextProperties properties, ResourceFactoryRegistry resourceFactoryRegistry) {
+ return PROPERTY_TYPE.equals(properties.getDataContextType());
+ }
+
+ @Override
+ public DataContext create(DataContextProperties properties, ResourceFactoryRegistry resourceFactoryRegistry)
+ throws UnsupportedDataContextPropertiesException, ConnectionException {
+
+ assert accepts(properties, resourceFactoryRegistry);
+
+ final String schemaName;
+ if (properties.getDatabaseName() != null) {
+ schemaName = properties.getDatabaseName();
+ } else {
+ schemaName = "Schema";
+ }
+
+ final List<TableDataProvider<?>> tableDataProviders;
+
+ final SimpleTableDef[] tableDefs = properties.getTableDefs();
+ if (tableDefs == null) {
+ tableDataProviders = new ArrayList<>();
+ } else {
+ tableDataProviders = new ArrayList<>(tableDefs.length);
+ for (int i = 0; i < tableDefs.length; i++) {
+ final TableDataProvider<?> tableDataProvider = new ArrayTableDataProvider(tableDefs[i],
+ new ArrayList<Object[]>());
+ tableDataProviders.add(tableDataProvider);
+ }
+ }
+
+ return new PojoDataContext(schemaName, tableDataProviders);
+ }
+
+}
diff --git a/pojo/src/main/resources/META-INF/services/org.apache.metamodel.factory.DataContextFactory b/pojo/src/main/resources/META-INF/services/org.apache.metamodel.factory.DataContextFactory
new file mode 100644
index 0000000..76f808d
--- /dev/null
+++ b/pojo/src/main/resources/META-INF/services/org.apache.metamodel.factory.DataContextFactory
@@ -0,0 +1 @@
+org.apache.metamodel.pojo.PojoDataContextFactory
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 50f5674..6d66536 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,6 +29,7 @@
<hadoop.version>2.6.0</hadoop.version>
<jackson.version>2.6.3</jackson.version>
<easymock.version>3.2</easymock.version>
+ <spring.version>4.2.6.RELEASE</spring.version>
<httpcomponents.version>4.4.1</httpcomponents.version>
<checksum-maven-plugin.version>1.2</checksum-maven-plugin.version>
<skipTests>false</skipTests>
@@ -42,7 +43,7 @@
<url>https://git-wip-us.apache.org/repos/asf?p=metamodel.git</url>
<connection>scm:git:http://git-wip-us.apache.org/repos/asf/metamodel.git</connection>
<developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/metamodel.git</developerConnection>
- <tag>5.x</tag>
+ <tag>HEAD</tag>
</scm>
<groupId>org.apache.metamodel</groupId>
<artifactId>MetaModel</artifactId>
@@ -105,20 +106,54 @@
</organization>
<developers>
<developer>
- <id>kasper</id>
+ <id>kaspersor</id>
<name>Kasper Sørensen</name>
- <email>kasper.sorensen@humaninference.com</email>
- <url>http://kasper.eobjects.org</url>
- <organization>Human Inference</organization>
- <organizationUrl>http://www.humaninference.com</organizationUrl>
+ <email>i.am.kasper.sorensen@gmail.com</email>
+ <url>https://github.com/kaspersorensen</url>
+ </developer>
+ <developer>
+ <name>Dennis Du Krøger</name>
+ <url>https://github.com/losd</url>
+ </developer>
+ <developer>
+ <name>Ankit Kumar</name>
+ <url>https://github.com/ankit2711</url>
+ </developer>
+ <developer>
+ <name>Alberto Rodriguez</name>
+ <url>https://github.com/albertostratio</url>
+ </developer>
+ <developer>
+ <name>Tomasz Guzialek</name>
+ <url>https://github.com/tomaszguzialek</url>
+ </developer>
+ <developer>
+ <name>Henry Saputra</name>
+ <url>https://github.com/hsaputra</url>
</developer>
</developers>
<contributors>
<contributor>
+ <name>Arjan Seijkens</name>
+ <url>https://github.com/arjansh</url>
+ </contributor>
+ <contributor>
+ <name>Jakub Horčička</name>
+ <url>https://github.com/jhorcicka</url>
+ </contributor>
+ <contributor>
<name>Francisco Javier Cano</name>
<organization>Stratio</organization>
</contributor>
<contributor>
+ <name>Harel Efraim</name>
+ <url>https://github.com/harel-e</url>
+ </contributor>
+ <contributor>
+ <name>Joerg Unbehauen</name>
+ <url>https://github.com/tomatophantastico</url>
+ </contributor>
+ <contributor>
<name>Saurabh Gupta</name>
<organization>Xebia India</organization>
</contributor>
@@ -372,7 +407,7 @@
<excludeSubProjects>false</excludeSubProjects>
<excludes>
<exclude>KEYS</exclude>
- <exclude>*.md</exclude>
+ <exclude>**/*.md</exclude>
<exclude>example-metamodel-integrationtest-configuration.properties</exclude>
<exclude>travis-metamodel-integrationtest-configuration.properties</exclude>
<exclude>**/src/assembly/metamodel-packaged-assembly-descriptor.xml</exclude>
@@ -386,6 +421,7 @@
<exclude>**/.project</exclude>
<exclude>**/.classpath</exclude>
<exclude>**/.settings/**</exclude>
+ <exclude>**/.vscode/**</exclude>
<exclude>**/.travis.yml</exclude>
<exclude>**/target/**</exclude>
<exclude>**/*.iml/**</exclude>
@@ -393,6 +429,7 @@
<exclude>**/*.ipr/**</exclude>
<exclude>**/.idea/**</exclude>
<exclude>**/tattletale-filters.properties</exclude>
+ <exclude>**/swagger-ui/**</exclude>
<exclude>DEPENDENCIES</exclude>
<exclude>DISCLAIMER</exclude>
<exclude>neo4j-community-*/**</exclude>
@@ -515,6 +552,11 @@
<version>${jackson.version}</version>
</dependency>
<dependency>
+ <groupId>com.fasterxml.jackson.dataformat</groupId>
+ <artifactId>jackson-dataformat-yaml</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+ <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
@@ -539,6 +581,34 @@
<artifactId>hsqldb</artifactId>
<version>1.8.0.10</version>
</dependency>
+
+ <!-- Spring -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>${spring.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-webmvc</artifactId>
+ <version>${spring.version}</version>
+ </dependency>
<!-- Hadoop -->
<dependency>
diff --git a/spring/pom.xml b/spring/pom.xml
index 6792582..b6d09b4 100644
--- a/spring/pom.xml
+++ b/spring/pom.xml
@@ -27,10 +27,6 @@
<artifactId>MetaModel-spring</artifactId>
<name>MetaModel module for Spring enabled configuration</name>
- <properties>
- <spring.version>3.0.7.RELEASE</spring.version>
- </properties>
-
<dependencies>
<dependency>
<groupId>org.apache.metamodel</groupId>
@@ -46,14 +42,7 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
- <version>${spring.version}</version>
<scope>provided</scope>
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
</dependency>
<!-- test -->
@@ -70,7 +59,6 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
- <version>${spring.version}</version>
<scope>test</scope>
</dependency>
</dependencies>