You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metamodel.apache.org by ka...@apache.org on 2016/05/16 03:53:42 UTC

[07/42] metamodel git commit: METAMODEL-183: Fixed

METAMODEL-183: Fixed

Fixes #86

Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo
Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/365fae3a
Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/365fae3a
Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/365fae3a

Branch: refs/heads/5.x
Commit: 365fae3a336bfd7f32ef4b34a8e3b0d50848bc09
Parents: 8e2df82
Author: Xiaomeng Zhao <xi...@gmail.com>
Authored: Sat Jan 23 17:38:58 2016 +0100
Committer: Kasper S�rensen <i....@gmail.com>
Committed: Sat Jan 23 17:38:58 2016 +0100

----------------------------------------------------------------------
 full/pom.xml                                    |   7 +-
 .../apache/metamodel/DataContextFactory.java    |  13 +-
 mongodb/common/pom.xml                          |  67 ++
 .../metamodel/mongodb/common/MongoDBUtils.java  |  93 +++
 .../mongodb/common/MongoDbTableDef.java         |  46 ++
 mongodb/mongo2/pom.xml                          |  70 ++
 .../mongo2/DefaultWriteConcernAdvisor.java      |  32 +
 .../mongodb/mongo2/MongoDbDataContext.java      | 528 +++++++++++++++
 .../mongodb/mongo2/MongoDbDataSet.java          |  84 +++
 .../mongodb/mongo2/MongoDbDeleteBuilder.java    |  56 ++
 .../mongodb/mongo2/MongoDbDropTableBuilder.java |  43 ++
 .../mongodb/mongo2/MongoDbInsertionBuilder.java |  64 ++
 .../mongo2/MongoDbTableCreationBuilder.java     |  57 ++
 .../mongodb/mongo2/MongoDbUpdateCallback.java   | 115 ++++
 .../mongo2/SimpleWriteConcernAdvisor.java       |  50 ++
 .../mongodb/mongo2/WriteConcernAdvisor.java     |  35 +
 .../metamodel/mongodb/mongo2/package-info.java  |  23 +
 .../mongodb/mongo2/MongoDbDataContextTest.java  | 635 ++++++++++++++++++
 .../mongodb/mongo2/MongoDbDataCopyer.java       | 124 ++++
 .../mongodb/mongo2/MongoDbTestCase.java         | 111 ++++
 mongodb/mongo3/pom.xml                          |  70 ++
 .../mongo3/DefaultWriteConcernAdvisor.java      |  32 +
 .../mongodb/mongo3/MongoDbDataContext.java      | 556 ++++++++++++++++
 .../mongodb/mongo3/MongoDbDataSet.java          |  84 +++
 .../mongodb/mongo3/MongoDbDeleteBuilder.java    |  53 ++
 .../mongodb/mongo3/MongoDbDropTableBuilder.java |  43 ++
 .../mongodb/mongo3/MongoDbInsertionBuilder.java |  63 ++
 .../mongo3/MongoDbTableCreationBuilder.java     |  57 ++
 .../mongodb/mongo3/MongoDbUpdateCallback.java   | 119 ++++
 .../mongo3/SimpleWriteConcernAdvisor.java       |  51 ++
 .../mongodb/mongo3/WriteConcernAdvisor.java     |  36 ++
 .../metamodel/mongodb/mongo3/package-info.java  |  23 +
 .../mongodb/mongo3/MongoDbDataContextTest.java  | 613 ++++++++++++++++++
 .../mongodb/mongo3/MongoDbDataCopyer.java       | 127 ++++
 .../mongodb/mongo3/MongoDbTestCase.java         | 111 ++++
 mongodb/pom.xml                                 |  43 +-
 .../mongodb/DefaultWriteConcernAdvisor.java     |  32 -
 .../apache/metamodel/mongodb/MongoDBUtils.java  |  77 ---
 .../metamodel/mongodb/MongoDbDataContext.java   | 526 ---------------
 .../metamodel/mongodb/MongoDbDataSet.java       |  83 ---
 .../metamodel/mongodb/MongoDbDeleteBuilder.java |  56 --
 .../mongodb/MongoDbDropTableBuilder.java        |  43 --
 .../mongodb/MongoDbInsertionBuilder.java        |  64 --
 .../mongodb/MongoDbTableCreationBuilder.java    |  57 --
 .../metamodel/mongodb/MongoDbTableDef.java      |  46 --
 .../mongodb/MongoDbUpdateCallback.java          | 115 ----
 .../mongodb/SimpleWriteConcernAdvisor.java      |  50 --
 .../metamodel/mongodb/WriteConcernAdvisor.java  |  35 -
 .../apache/metamodel/mongodb/package-info.java  |  23 -
 .../mongodb/MongoDbDataContextTest.java         | 636 -------------------
 .../metamodel/mongodb/MongoDbDataCopyer.java    | 124 ----
 .../metamodel/mongodb/MongoDbTestCase.java      | 111 ----
 .../MongoDbDataContextFactoryBeanDelegate.java  |   2 +-
 53 files changed, 4292 insertions(+), 2122 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/full/pom.xml
----------------------------------------------------------------------
diff --git a/full/pom.xml b/full/pom.xml
index 4738093..3602e45 100644
--- a/full/pom.xml
+++ b/full/pom.xml
@@ -181,8 +181,13 @@ under the License.
 			<version>${project.version}</version>
 		</dependency>
 		<dependency>
+            <groupId>org.apache.metamodel</groupId>
+            <artifactId>MetaModel-mongodb-mongo3</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+		<dependency>
 			<groupId>org.apache.metamodel</groupId>
-			<artifactId>MetaModel-mongodb</artifactId>
+			<artifactId>MetaModel-mongodb-mongo2</artifactId>
 			<version>${project.version}</version>
 		</dependency>
 		<dependency>

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/full/src/main/java/org/apache/metamodel/DataContextFactory.java
----------------------------------------------------------------------
diff --git a/full/src/main/java/org/apache/metamodel/DataContextFactory.java b/full/src/main/java/org/apache/metamodel/DataContextFactory.java
index 37776e9..2b3dae2 100644
--- a/full/src/main/java/org/apache/metamodel/DataContextFactory.java
+++ b/full/src/main/java/org/apache/metamodel/DataContextFactory.java
@@ -39,7 +39,7 @@ import org.apache.metamodel.fixedwidth.FixedWidthConfiguration;
 import org.apache.metamodel.fixedwidth.FixedWidthDataContext;
 import org.apache.metamodel.jdbc.JdbcDataContext;
 import org.apache.metamodel.json.JsonDataContext;
-import org.apache.metamodel.mongodb.MongoDbDataContext;
+import org.apache.metamodel.mongodb.mongo3.MongoDbDataContext;
 import org.apache.metamodel.openoffice.OpenOfficeDataContext;
 import org.apache.metamodel.salesforce.SalesforceDataContext;
 import org.apache.metamodel.schema.TableType;
@@ -53,10 +53,10 @@ import org.xml.sax.InputSource;
 
 import com.datastax.driver.core.Cluster;
 import com.google.common.base.Strings;
-import com.mongodb.DB;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoCredential;
 import com.mongodb.ServerAddress;
+import com.mongodb.client.MongoDatabase;
 
 import io.searchbox.client.JestClient;
 
@@ -547,14 +547,15 @@ public class DataContextFactory {
             } else {
                 serverAddress = new ServerAddress(hostname, port);
             }
-
-            final DB mongoDb;
+            MongoClient mongoClient = null;
+            final MongoDatabase mongoDb;
             if (Strings.isNullOrEmpty(username)) {
-                mongoDb = new MongoClient(serverAddress).getDB(databaseName);
+                mongoClient = new MongoClient(serverAddress);
             } else {
                 final MongoCredential credential = MongoCredential.createCredential(username, databaseName, password);
-                mongoDb = new MongoClient(serverAddress, Arrays.asList(credential)).getDB(databaseName);
+                mongoClient = new MongoClient(serverAddress, Arrays.asList(credential));
             }
+            mongoDb = mongoClient.getDatabase(databaseName);
 
             if (tableDefs == null || tableDefs.length == 0) {
                 return new MongoDbDataContext(mongoDb);

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/common/pom.xml
----------------------------------------------------------------------
diff --git a/mongodb/common/pom.xml b/mongodb/common/pom.xml
new file mode 100644
index 0000000..2ef9d14
--- /dev/null
+++ b/mongodb/common/pom.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<artifactId>MetaModel-mongodb</artifactId>
+		<groupId>org.apache.metamodel</groupId>
+		<version>4.5.1-SNAPSHOT</version>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>MetaModel-mongodb-common</artifactId>
+	<name>MetaModel module for MongoDB commons</name>
+	
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.metamodel</groupId>
+			<artifactId>MetaModel-core</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.mongodb</groupId>
+			<artifactId>mongo-java-driver</artifactId>
+			<version>3.1.0</version>
+			<scope>provided</scope>
+		</dependency>
+
+		<!-- Test dependencies -->
+		<dependency>
+			<groupId>org.apache.metamodel</groupId>
+			<artifactId>MetaModel-jdbc</artifactId>
+			<version>${project.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derby</artifactId>
+			<version>10.8.1.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-nop</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/common/src/main/java/org/apache/metamodel/mongodb/common/MongoDBUtils.java
----------------------------------------------------------------------
diff --git a/mongodb/common/src/main/java/org/apache/metamodel/mongodb/common/MongoDBUtils.java b/mongodb/common/src/main/java/org/apache/metamodel/mongodb/common/MongoDBUtils.java
new file mode 100644
index 0000000..f7a5729
--- /dev/null
+++ b/mongodb/common/src/main/java/org/apache/metamodel/mongodb/common/MongoDBUtils.java
@@ -0,0 +1,93 @@
+/**
+ * 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.mongodb.common;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.metamodel.data.DataSetHeader;
+import org.apache.metamodel.data.DefaultRow;
+import org.apache.metamodel.data.Row;
+import org.apache.metamodel.query.SelectItem;
+import org.apache.metamodel.schema.Column;
+import org.apache.metamodel.util.CollectionUtils;
+
+import com.mongodb.DBObject;
+
+/**
+ * A utility class for MongoDB module.
+ */
+public class MongoDBUtils {
+
+    /**
+     * Converts a MongoDB data object {@link DBObject} into MetaModel
+     * {@link Row}.
+     * 
+     * @param dbObject
+     *            a MongoDB object storing data.
+     * @param header
+     *            a header describing the columns of the data stored.
+     * @return the MetaModel {@link Row} result object.
+     */
+    public static Row toRow(DBObject dbObject, DataSetHeader header) {
+        if (dbObject == null) {
+            return null;
+        }
+
+        final Map<?,?> map = dbObject.toMap();
+        return toRow(map, header);
+    }
+    
+    /**
+     * Converts a map into MetaModel. This map stores data of a MongoDB document.
+     * 
+     * @param dbObject
+     *            a map object storing data of a MongoDB document.
+     * @param header
+     *            a header describing the columns of the data stored.
+     * @return the MetaModel {@link Row} result object.
+     */
+    public static Row toRow(Map<?,?> map, DataSetHeader header) {
+        if (map == null) {
+            return null;
+        }
+
+        final int size = header.size();
+        final Object[] values = new Object[size];
+        for (int i = 0; i < values.length; i++) {
+            final SelectItem selectItem = header.getSelectItem(i);
+            final String key = selectItem.getColumn().getName();
+            final Object value = CollectionUtils.find(map, key);
+            values[i] = toValue(selectItem.getColumn(), value);
+        }
+        return new DefaultRow(header, values);
+    }
+
+    private static Object toValue(Column column, Object value) {
+        if (value instanceof List) {
+            return value;
+        }
+        if (value instanceof DBObject) {
+            DBObject basicDBObject = (DBObject) value;
+            return basicDBObject.toMap();
+        }
+        return value;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/common/src/main/java/org/apache/metamodel/mongodb/common/MongoDbTableDef.java
----------------------------------------------------------------------
diff --git a/mongodb/common/src/main/java/org/apache/metamodel/mongodb/common/MongoDbTableDef.java b/mongodb/common/src/main/java/org/apache/metamodel/mongodb/common/MongoDbTableDef.java
new file mode 100644
index 0000000..9bb6174
--- /dev/null
+++ b/mongodb/common/src/main/java/org/apache/metamodel/mongodb/common/MongoDbTableDef.java
@@ -0,0 +1,46 @@
+/**
+ * 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.mongodb.common;
+
+import java.io.Serializable;
+
+import org.apache.metamodel.schema.ColumnType;
+import org.apache.metamodel.util.SimpleTableDef;
+
+/**
+ * Defines a table layout for {@link MongoDbDataContext} tables. This class can
+ * be used as an instruction set for the {@link MongoDbDataContext} to specify
+ * which collections, which columns (and their types) should be included in the
+ * schema structure of a Mongo DB database.
+ * 
+ * @deprecated use {@link SimpleTableDef} instead.
+ */
+@Deprecated
+public final class MongoDbTableDef extends SimpleTableDef implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    public MongoDbTableDef(String name, String[] columnNames, ColumnType[] columnTypes) {
+        super(name, columnNames, columnTypes);
+    }
+
+    public MongoDbTableDef(String name, String[] columnNames) {
+        super(name, columnNames);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/pom.xml
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/pom.xml b/mongodb/mongo2/pom.xml
new file mode 100644
index 0000000..24b1bca
--- /dev/null
+++ b/mongodb/mongo2/pom.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<artifactId>MetaModel-mongodb</artifactId>
+		<groupId>org.apache.metamodel</groupId>
+		<version>4.5.1-SNAPSHOT</version>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+	<artifactId>MetaModel-mongodb-mongo2</artifactId>
+	<name>MetaModel module for MongoDB databases under version 3</name>
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.metamodel</groupId>
+			<artifactId>MetaModel-core</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
+            <groupId>org.apache.metamodel</groupId>
+            <artifactId>MetaModel-mongodb-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+		<dependency>
+			<groupId>org.mongodb</groupId>
+			<artifactId>mongo-java-driver</artifactId>
+			<version>2.14.0</version>
+		</dependency>
+
+		<!-- Test dependencies -->
+		<dependency>
+			<groupId>org.apache.metamodel</groupId>
+			<artifactId>MetaModel-jdbc</artifactId>
+			<version>${project.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derby</artifactId>
+			<version>10.8.1.2</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-nop</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/DefaultWriteConcernAdvisor.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/DefaultWriteConcernAdvisor.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/DefaultWriteConcernAdvisor.java
new file mode 100644
index 0000000..4f87a34
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/DefaultWriteConcernAdvisor.java
@@ -0,0 +1,32 @@
+/**
+ * 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.mongodb.mongo2;
+
+import com.mongodb.WriteConcern;
+
+/**
+ * Default {@link WriteConcernAdvisor}. Always returns
+ * {@link WriteConcern#NORMAL}.
+ */
+public class DefaultWriteConcernAdvisor extends SimpleWriteConcernAdvisor {
+
+    public DefaultWriteConcernAdvisor() {
+        super(WriteConcern.NORMAL);
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDataContext.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDataContext.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDataContext.java
new file mode 100644
index 0000000..cfeb836
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDataContext.java
@@ -0,0 +1,528 @@
+/**
+ * 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.mongodb.mongo2;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.regex.Pattern;
+
+import org.apache.metamodel.DataContext;
+import org.apache.metamodel.MetaModelException;
+import org.apache.metamodel.QueryPostprocessDataContext;
+import org.apache.metamodel.UpdateScript;
+import org.apache.metamodel.UpdateableDataContext;
+import org.apache.metamodel.data.DataSet;
+import org.apache.metamodel.data.DataSetHeader;
+import org.apache.metamodel.data.InMemoryDataSet;
+import org.apache.metamodel.data.Row;
+import org.apache.metamodel.data.SimpleDataSetHeader;
+import org.apache.metamodel.mongodb.common.MongoDBUtils;
+import org.apache.metamodel.mongodb.common.MongoDbTableDef;
+import org.apache.metamodel.query.FilterItem;
+import org.apache.metamodel.query.FromItem;
+import org.apache.metamodel.query.OperatorType;
+import org.apache.metamodel.query.Query;
+import org.apache.metamodel.query.SelectItem;
+import org.apache.metamodel.schema.Column;
+import org.apache.metamodel.schema.ColumnType;
+import org.apache.metamodel.schema.ColumnTypeImpl;
+import org.apache.metamodel.schema.MutableColumn;
+import org.apache.metamodel.schema.MutableSchema;
+import org.apache.metamodel.schema.MutableTable;
+import org.apache.metamodel.schema.Schema;
+import org.apache.metamodel.schema.Table;
+import org.apache.metamodel.util.SimpleTableDef;
+import org.bson.types.ObjectId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mongodb.BasicDBList;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.DBObject;
+import com.mongodb.WriteConcern;
+
+/**
+ * DataContext implementation for MongoDB.
+ *
+ * Since MongoDB has no schema, a virtual schema will be used in this
+ * DataContext. This implementation supports either automatic discovery of a
+ * schema or manual specification of a schema, through the
+ * {@link MongoDbTableDef} class.
+ */
+public class MongoDbDataContext extends QueryPostprocessDataContext implements UpdateableDataContext {
+
+    private static final Logger logger = LoggerFactory.getLogger(MongoDbDataSet.class);
+
+    private final DB _mongoDb;
+    private final SimpleTableDef[] _tableDefs;
+    private WriteConcernAdvisor _writeConcernAdvisor;
+    private Schema _schema;
+
+    /**
+     * Constructor available for backwards compatibility
+     *
+     * @deprecated use {@link #MongoDbDataContext(DB, SimpleTableDef...)}
+     *             instead
+     */
+    @Deprecated
+    public MongoDbDataContext(DB mongoDb, MongoDbTableDef... tableDefs) {
+        this(mongoDb, (SimpleTableDef[]) tableDefs);
+    }
+
+    /**
+     * Constructs a {@link MongoDbDataContext}. This constructor accepts a
+     * custom array of {@link MongoDbTableDef}s which allows the user to define
+     * his own view on the collections in the database.
+     *
+     * @param mongoDb
+     *            the mongo db connection
+     * @param tableDefs
+     *            an array of {@link MongoDbTableDef}s, which define the table
+     *            and column model of the mongo db collections. (consider using
+     *            {@link #detectSchema(DB)} or {@link #detectTable(DB, String)}
+     *            ).
+     */
+    public MongoDbDataContext(DB mongoDb, SimpleTableDef... tableDefs) {
+        _mongoDb = mongoDb;
+        _tableDefs = tableDefs;
+        _schema = null;
+    }
+
+    /**
+     * Constructs a {@link MongoDbDataContext} and automatically detects the
+     * schema structure/view on all collections (see {@link #detectSchema(DB)}).
+     *
+     * @param mongoDb
+     *            the mongo db connection
+     */
+    public MongoDbDataContext(DB mongoDb) {
+        this(mongoDb, detectSchema(mongoDb));
+    }
+
+    /**
+     * Performs an analysis of the available collections in a Mongo {@link DB}
+     * instance and tries to detect the table's structure based on the first
+     * 1000 documents in each collection.
+     *
+     * @param db
+     *            the mongo db to inspect
+     * @return a mutable schema instance, useful for further fine tuning by the
+     *         user.
+     * @see #detectTable(DB, String)
+     */
+    public static SimpleTableDef[] detectSchema(DB db) {
+        Set<String> collectionNames = db.getCollectionNames();
+        SimpleTableDef[] result = new SimpleTableDef[collectionNames.size()];
+        int i = 0;
+        for (String collectionName : collectionNames) {
+            SimpleTableDef table = detectTable(db, collectionName);
+            result[i] = table;
+            i++;
+        }
+        return result;
+    }
+
+    /**
+     * Performs an analysis of an available collection in a Mongo {@link DB}
+     * instance and tries to detect the table structure based on the first 1000
+     * documents in the collection.
+     *
+     * @param db
+     *            the mongo DB
+     * @param collectionName
+     *            the name of the collection
+     * @return a table definition for mongo db.
+     */
+    public static SimpleTableDef detectTable(DB db, String collectionName) {
+        final DBCollection collection = db.getCollection(collectionName);
+        final DBCursor cursor = collection.find().limit(1000);
+
+        final SortedMap<String, Set<Class<?>>> columnsAndTypes = new TreeMap<String, Set<Class<?>>>();
+        while (cursor.hasNext()) {
+            DBObject object = cursor.next();
+            Set<String> keysInObject = object.keySet();
+            for (String key : keysInObject) {
+                Set<Class<?>> types = columnsAndTypes.get(key);
+                if (types == null) {
+                    types = new HashSet<Class<?>>();
+                    columnsAndTypes.put(key, types);
+                }
+                Object value = object.get(key);
+                if (value != null) {
+                    types.add(value.getClass());
+                }
+            }
+        }
+        cursor.close();
+
+        final String[] columnNames = new String[columnsAndTypes.size()];
+        final ColumnType[] columnTypes = new ColumnType[columnsAndTypes.size()];
+
+        int i = 0;
+        for (Entry<String, Set<Class<?>>> columnAndTypes : columnsAndTypes.entrySet()) {
+            final String columnName = columnAndTypes.getKey();
+            final Set<Class<?>> columnTypeSet = columnAndTypes.getValue();
+            final Class<?> columnType;
+            if (columnTypeSet.size() == 1) {
+                columnType = columnTypeSet.iterator().next();
+            } else {
+                columnType = Object.class;
+            }
+            columnNames[i] = columnName;
+            if (columnType == ObjectId.class) {
+                columnTypes[i] = ColumnType.ROWID;
+            } else {
+                columnTypes[i] = ColumnTypeImpl.convertColumnType(columnType);
+            }
+            i++;
+        }
+
+        return new SimpleTableDef(collectionName, columnNames, columnTypes);
+    }
+
+    @Override
+    protected Schema getMainSchema() throws MetaModelException {
+        if (_schema == null) {
+            MutableSchema schema = new MutableSchema(getMainSchemaName());
+            for (SimpleTableDef tableDef : _tableDefs) {
+
+                MutableTable table = tableDef.toTable().setSchema(schema);
+                Column[] rowIdColumns = table.getColumnsOfType(ColumnType.ROWID);
+                for (Column column : rowIdColumns) {
+                    if (column instanceof MutableColumn) {
+                        ((MutableColumn) column).setPrimaryKey(true);
+                    }
+                }
+
+                schema.addTable(table);
+            }
+
+            _schema = schema;
+        }
+        return _schema;
+    }
+
+    @Override
+    protected String getMainSchemaName() throws MetaModelException {
+        return _mongoDb.getName();
+    }
+
+    @Override
+    protected Number executeCountQuery(Table table, List<FilterItem> whereItems, boolean functionApproximationAllowed) {
+        final DBCollection collection = _mongoDb.getCollection(table.getName());
+
+        final DBObject query = createMongoDbQuery(table, whereItems);
+
+        logger.info("Executing MongoDB 'count' query: {}", query);
+        final long count = collection.count(query);
+
+        return count;
+    }
+
+    @Override
+    protected Row executePrimaryKeyLookupQuery(Table table, List<SelectItem> selectItems, Column primaryKeyColumn,
+            Object keyValue) {
+        final DBCollection collection = _mongoDb.getCollection(table.getName());
+
+        List<FilterItem> whereItems = new ArrayList<FilterItem>();
+        SelectItem selectItem = new SelectItem(primaryKeyColumn);
+        FilterItem primaryKeyWhereItem = new FilterItem(selectItem, OperatorType.EQUALS_TO, keyValue);
+        whereItems.add(primaryKeyWhereItem);
+        final DBObject query = createMongoDbQuery(table, whereItems);
+        final DBObject resultDBObject = collection.findOne(query);
+
+        DataSetHeader header = new SimpleDataSetHeader(selectItems);
+
+        Row row = MongoDBUtils.toRow(resultDBObject, header);
+
+        return row;
+    }
+
+    @Override
+    public DataSet executeQuery(Query query) {
+        // Check for queries containing only simple selects and where clauses,
+        // or if it is a COUNT(*) query.
+
+        // if from clause only contains a main schema table
+        List<FromItem> fromItems = query.getFromClause().getItems();
+        if (fromItems.size() == 1 && fromItems.get(0).getTable() != null
+                && fromItems.get(0).getTable().getSchema() == _schema) {
+            final Table table = fromItems.get(0).getTable();
+
+            // if GROUP BY, HAVING and ORDER BY clauses are not specified
+            if (query.getGroupByClause().isEmpty() && query.getHavingClause().isEmpty()
+                    && query.getOrderByClause().isEmpty()) {
+
+                final List<FilterItem> whereItems = query.getWhereClause().getItems();
+
+                // if all of the select items are "pure" column selection
+                boolean allSelectItemsAreColumns = true;
+                List<SelectItem> selectItems = query.getSelectClause().getItems();
+
+                // if it is a
+                // "SELECT [columns] FROM [table] WHERE [conditions]"
+                // query.
+                for (SelectItem selectItem : selectItems) {
+                    if (selectItem.getFunction() != null || selectItem.getColumn() == null) {
+                        allSelectItemsAreColumns = false;
+                        break;
+                    }
+                }
+
+                if (allSelectItemsAreColumns) {
+                    logger.debug("Query can be expressed in full MongoDB, no post processing needed.");
+
+                    // prepare for a non-post-processed query
+                    Column[] columns = new Column[selectItems.size()];
+                    for (int i = 0; i < columns.length; i++) {
+                        columns[i] = selectItems.get(i).getColumn();
+                    }
+
+                    // checking if the query is a primary key lookup query
+                    if (whereItems.size() == 1) {
+                        final FilterItem whereItem = whereItems.get(0);
+                        final SelectItem selectItem = whereItem.getSelectItem();
+                        if (!whereItem.isCompoundFilter() && selectItem != null && selectItem.getColumn() != null) {
+                            final Column column = selectItem.getColumn();
+                            if (column.isPrimaryKey() && OperatorType.EQUALS_TO.equals(whereItem.getOperator())) {
+                                logger.debug("Query is a primary key lookup query. Trying executePrimaryKeyLookupQuery(...)");
+                                final Object operand = whereItem.getOperand();
+                                final Row row = executePrimaryKeyLookupQuery(table, selectItems, column, operand);
+                                if (row == null) {
+                                    logger.debug("DataContext did not return any primary key lookup query results. Proceeding "
+                                            + "with manual lookup.");
+                                } else {
+                                    final DataSetHeader header = new SimpleDataSetHeader(selectItems);
+                                    return new InMemoryDataSet(header, row);
+                                }
+                            }
+                        }
+                    }
+
+                    int firstRow = (query.getFirstRow() == null ? 1 : query.getFirstRow());
+                    int maxRows = (query.getMaxRows() == null ? -1 : query.getMaxRows());
+
+                    final DataSet dataSet = materializeMainSchemaTableInternal(table, columns, whereItems, firstRow,
+                            maxRows, false);
+                    return dataSet;
+                }
+            }
+        }
+
+        logger.debug("Query will be simplified for MongoDB and post processed.");
+        return super.executeQuery(query);
+    }
+
+    private DataSet materializeMainSchemaTableInternal(Table table, Column[] columns, List<FilterItem> whereItems,
+            int firstRow, int maxRows, boolean queryPostProcessed) {
+        final DBCollection collection = _mongoDb.getCollection(table.getName());
+
+        final DBObject query = createMongoDbQuery(table, whereItems);
+
+        logger.info("Executing MongoDB 'find' query: {}", query);
+        DBCursor cursor = collection.find(query);
+
+        if (maxRows > 0) {
+            cursor = cursor.limit(maxRows);
+        }
+        if (firstRow > 1) {
+            final int skip = firstRow - 1;
+            cursor = cursor.skip(skip);
+        }
+
+        return new MongoDbDataSet(cursor, columns, queryPostProcessed);
+    }
+
+    protected BasicDBObject createMongoDbQuery(Table table, List<FilterItem> whereItems) {
+        assert _schema == table.getSchema();
+
+        final BasicDBObject query = new BasicDBObject();
+        if (whereItems != null && !whereItems.isEmpty()) {
+            for (FilterItem item : whereItems) {
+                convertToCursorObject(query, item);
+            }
+        }
+
+        return query;
+    }
+
+    private void convertToCursorObject(BasicDBObject query, FilterItem item) {
+        if (item.isCompoundFilter()) {
+
+            BasicDBList orList = new BasicDBList();
+
+            final FilterItem[] childItems = item.getChildItems();
+            for (FilterItem childItem : childItems) {
+                BasicDBObject childObject = new BasicDBObject();
+                convertToCursorObject(childObject, childItem);
+                orList.add(childObject);
+            }
+
+            query.put("$or", orList);
+
+        } else {
+
+            final Column column = item.getSelectItem().getColumn();
+            final String columnName = column.getName();
+            final String operatorName = getOperatorName(item);
+
+            Object operand = item.getOperand();
+            if (ObjectId.isValid(String.valueOf(operand))) {
+                operand = new ObjectId(String.valueOf(operand));
+            }
+
+            final BasicDBObject existingFilterObject = (BasicDBObject) query.get(columnName);
+            if (existingFilterObject == null) {
+                if (operatorName == null) {
+                    if (OperatorType.LIKE.equals(item.getOperator())) {
+                        query.put(columnName, turnOperandIntoRegExp(operand));
+                    } else {
+                        query.put(columnName, operand);
+                    }
+                } else {
+                    query.put(columnName, new BasicDBObject(operatorName, operand));
+                }
+            } else {
+                if (operatorName == null) {
+                    throw new IllegalStateException("Cannot retrieve records for a column with two EQUALS_TO operators");
+                } else {
+                    existingFilterObject.append(operatorName, operand);
+                }
+            }
+        }
+    }
+
+    private String getOperatorName(FilterItem item) {
+        final OperatorType operator = item.getOperator();
+
+        if (OperatorType.EQUALS_TO.equals(operator)) {
+            return null;
+        }
+        if (OperatorType.LIKE.equals(operator)) {
+            return null;
+        }
+        if (OperatorType.LESS_THAN.equals(operator)) {
+            return "$lt";
+        }
+        if (OperatorType.LESS_THAN_OR_EQUAL.equals(operator)) {
+            return "$lte";
+        }
+        if (OperatorType.GREATER_THAN.equals(operator)) {
+            return "$gt";
+        }
+        if (OperatorType.GREATER_THAN_OR_EQUAL.equals(operator)) {
+            return "$gte";
+        }
+        if (OperatorType.DIFFERENT_FROM.equals(operator)) {
+            return "$ne";
+        }
+        if (OperatorType.IN.equals(operator)) {
+            return "$in";
+        }
+
+        throw new IllegalStateException("Unsupported operator type: " + operator);
+    }
+
+    private Pattern turnOperandIntoRegExp(Object operand) {
+        StringBuilder operandAsRegExp = new StringBuilder(replaceWildCardLikeChars(operand.toString()));
+        operandAsRegExp.insert(0, "^").append("$");
+        return Pattern.compile(operandAsRegExp.toString(), Pattern.CASE_INSENSITIVE);
+    }
+
+    private String replaceWildCardLikeChars(String operand) {
+        return operand.replaceAll("%", ".*");
+    }
+
+    @Override
+    protected DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) {
+        return materializeMainSchemaTableInternal(table, columns, null, 1, maxRows, true);
+    }
+
+    @Override
+    protected DataSet materializeMainSchemaTable(Table table, Column[] columns, int firstRow, int maxRows) {
+        return materializeMainSchemaTableInternal(table, columns, null, firstRow, maxRows, true);
+    }
+
+    /**
+     * Executes an update with a specific {@link WriteConcernAdvisor}.
+     */
+    public void executeUpdate(UpdateScript update, WriteConcernAdvisor writeConcernAdvisor) {
+        MongoDbUpdateCallback callback = new MongoDbUpdateCallback(this, writeConcernAdvisor);
+        try {
+            update.run(callback);
+        } finally {
+            callback.close();
+        }
+    }
+
+    /**
+     * Executes an update with a specific {@link WriteConcern}.
+     */
+    public void executeUpdate(UpdateScript update, WriteConcern writeConcern) {
+        executeUpdate(update, new SimpleWriteConcernAdvisor(writeConcern));
+    }
+
+    @Override
+    public void executeUpdate(UpdateScript update) {
+        executeUpdate(update, getWriteConcernAdvisor());
+    }
+
+    /**
+     * Gets the {@link WriteConcernAdvisor} to use on
+     * {@link #executeUpdate(UpdateScript)} calls.
+     */
+    public WriteConcernAdvisor getWriteConcernAdvisor() {
+        if (_writeConcernAdvisor == null) {
+            return new DefaultWriteConcernAdvisor();
+        }
+        return _writeConcernAdvisor;
+    }
+
+    /**
+     * Sets a global {@link WriteConcern} advisor to use on
+     * {@link #executeUpdate(UpdateScript)}.
+     */
+    public void setWriteConcernAdvisor(WriteConcernAdvisor writeConcernAdvisor) {
+        _writeConcernAdvisor = writeConcernAdvisor;
+    }
+
+    /**
+     * Gets the {@link DB} instance that this {@link DataContext} is backed by.
+     */
+    public DB getMongoDb() {
+        return _mongoDb;
+    }
+
+    protected void addTable(MutableTable table) {
+        if (_schema instanceof MutableSchema) {
+            MutableSchema mutableSchema = (MutableSchema) _schema;
+            mutableSchema.addTable(table);
+        } else {
+            throw new UnsupportedOperationException("Schema is not mutable");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDataSet.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDataSet.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDataSet.java
new file mode 100644
index 0000000..8c2a107
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDataSet.java
@@ -0,0 +1,84 @@
+/**
+ * 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.mongodb.mongo2;
+
+import org.apache.metamodel.data.AbstractDataSet;
+import org.apache.metamodel.data.Row;
+import org.apache.metamodel.mongodb.common.MongoDBUtils;
+import org.apache.metamodel.schema.Column;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mongodb.DBCursor;
+import com.mongodb.DBObject;
+
+final class MongoDbDataSet extends AbstractDataSet {
+
+    private static final Logger logger = LoggerFactory.getLogger(MongoDbDataSet.class);
+
+    private final DBCursor _cursor;
+    private final boolean _queryPostProcessed;
+
+    private boolean _closed;
+    private volatile DBObject _dbObject;
+
+    public MongoDbDataSet(DBCursor cursor, Column[] columns, boolean queryPostProcessed) {
+        super(columns);
+        _cursor = cursor;
+        _queryPostProcessed = queryPostProcessed;
+        _closed = false;
+    }
+
+    public boolean isQueryPostProcessed() {
+        return _queryPostProcessed;
+    }
+
+    @Override
+    public void close() {
+        super.close();
+        _cursor.close();
+        _closed = true;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+        if (!_closed) {
+            logger.warn("finalize() invoked, but DataSet is not closed. Invoking close() on {}", this);
+            close();
+        }
+    }
+
+    @Override
+    public boolean next() {
+        if (_cursor.hasNext()) {
+            _dbObject = _cursor.next();
+            return true;
+        } else {
+            _dbObject = null;
+            return false;
+        }
+    }
+
+    @Override
+    public Row getRow() {
+        return MongoDBUtils.toRow(_dbObject, getHeader());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDeleteBuilder.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDeleteBuilder.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDeleteBuilder.java
new file mode 100644
index 0000000..2ee1977
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDeleteBuilder.java
@@ -0,0 +1,56 @@
+/**
+ * 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.mongodb.mongo2;
+
+import org.apache.metamodel.MetaModelException;
+import org.apache.metamodel.delete.AbstractRowDeletionBuilder;
+import org.apache.metamodel.schema.Table;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.WriteConcern;
+import com.mongodb.WriteResult;
+
+final class MongoDbDeleteBuilder extends AbstractRowDeletionBuilder {
+
+    private static final Logger logger = LoggerFactory.getLogger(MongoDbDeleteBuilder.class);
+
+    private final MongoDbUpdateCallback _updateCallback;
+
+    public MongoDbDeleteBuilder(MongoDbUpdateCallback updateCallback, Table table) {
+        super(table);
+        _updateCallback = updateCallback;
+    }
+
+    @Override
+    public void execute() throws MetaModelException {
+        final DBCollection collection = _updateCallback.getCollection(getTable().getName());
+
+        final MongoDbDataContext dataContext = _updateCallback.getDataContext();
+        final BasicDBObject query = dataContext.createMongoDbQuery(getTable(), getWhereItems());
+        
+        WriteConcern writeConcern = _updateCallback.getWriteConcernAdvisor().adviceDeleteQuery(collection, query);
+        
+        final WriteResult writeResult = collection.remove(query, writeConcern);
+        logger.info("Remove returned result: {}", writeResult);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDropTableBuilder.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDropTableBuilder.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDropTableBuilder.java
new file mode 100644
index 0000000..a9f8d0c
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbDropTableBuilder.java
@@ -0,0 +1,43 @@
+/**
+ * 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.mongodb.mongo2;
+
+import org.apache.metamodel.MetaModelException;
+import org.apache.metamodel.drop.AbstractTableDropBuilder;
+import org.apache.metamodel.schema.MutableSchema;
+import org.apache.metamodel.schema.Table;
+
+final class MongoDbDropTableBuilder extends AbstractTableDropBuilder {
+
+    private final MongoDbUpdateCallback _updateCallback;
+
+    public MongoDbDropTableBuilder(MongoDbUpdateCallback updateCallback, Table table) {
+        super(table);
+        _updateCallback = updateCallback;
+    }
+
+    @Override
+    public void execute() throws MetaModelException {
+        Table table = getTable();
+        _updateCallback.removeCollection(table.getName());
+        MutableSchema schema = (MutableSchema) table.getSchema();
+        schema.removeTable(table);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbInsertionBuilder.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbInsertionBuilder.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbInsertionBuilder.java
new file mode 100644
index 0000000..d9cd583
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbInsertionBuilder.java
@@ -0,0 +1,64 @@
+/**
+ * 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.mongodb.mongo2;
+
+import org.apache.metamodel.MetaModelException;
+import org.apache.metamodel.insert.AbstractRowInsertionBuilder;
+import org.apache.metamodel.insert.RowInsertionBuilder;
+import org.apache.metamodel.schema.Column;
+import org.apache.metamodel.schema.Table;
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.WriteConcern;
+import com.mongodb.WriteResult;
+
+final class MongoDbInsertionBuilder extends AbstractRowInsertionBuilder<MongoDbUpdateCallback> implements RowInsertionBuilder {
+
+    private static final Logger logger = LoggerFactory.getLogger(MongoDbInsertionBuilder.class);
+
+    public MongoDbInsertionBuilder(MongoDbUpdateCallback updateCallback, Table table) {
+        super(updateCallback, table);
+    }
+
+    @Override
+    public void execute() throws MetaModelException {
+        final Column[] columns = getColumns();
+        final Object[] values = getValues();
+
+        final BasicDBObject doc = new BasicDBObject();
+
+        for (int i = 0; i < values.length; i++) {
+            Object value = values[i];
+            if (value != null) {
+                doc.put(columns[i].getName(), value);
+            }
+        }
+
+        final MongoDbUpdateCallback updateCallback = getUpdateCallback();
+        final DBCollection collection = updateCallback.getCollection(getTable().getName());
+
+        final WriteConcern writeConcern = updateCallback.getWriteConcernAdvisor().adviceInsert(collection, doc);
+
+        final WriteResult writeResult = collection.insert(doc, writeConcern);
+        logger.info("Insert returned result: {}", writeResult);
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbTableCreationBuilder.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbTableCreationBuilder.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbTableCreationBuilder.java
new file mode 100644
index 0000000..c93acf1
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbTableCreationBuilder.java
@@ -0,0 +1,57 @@
+/**
+ * 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.mongodb.mongo2;
+
+import org.apache.metamodel.MetaModelException;
+import org.apache.metamodel.create.AbstractTableCreationBuilder;
+import org.apache.metamodel.create.TableCreationBuilder;
+import org.apache.metamodel.schema.ColumnType;
+import org.apache.metamodel.schema.ImmutableColumn;
+import org.apache.metamodel.schema.MutableTable;
+import org.apache.metamodel.schema.Schema;
+import org.apache.metamodel.schema.Table;
+
+final class MongoDbTableCreationBuilder extends
+		AbstractTableCreationBuilder<MongoDbUpdateCallback> implements
+		TableCreationBuilder {
+
+	public MongoDbTableCreationBuilder(MongoDbUpdateCallback updateCallback,
+			Schema schema, String name) {
+		super(updateCallback, schema, name);
+	}
+
+	@Override
+	public Table execute() throws MetaModelException {
+		final MongoDbDataContext dataContext = getUpdateCallback()
+				.getDataContext();
+		final Schema schema = dataContext.getDefaultSchema();
+		final MutableTable table = getTable();
+		if (table.getColumnByName("_id") == null) {
+			// all mongo db collections have an _id field as the first field.
+			ImmutableColumn idColumn = new ImmutableColumn("_id",
+					ColumnType.ROWID, table, table.getColumnCount(), null,
+					null, null, null, true, null, true);
+			table.addColumn(idColumn);
+		}
+		table.setSchema(schema);
+		getUpdateCallback().createCollection(table.getName());
+		dataContext.addTable(table);
+		return table;
+	}
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbUpdateCallback.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbUpdateCallback.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbUpdateCallback.java
new file mode 100644
index 0000000..046f20c
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/MongoDbUpdateCallback.java
@@ -0,0 +1,115 @@
+/**
+ * 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.mongodb.mongo2;
+
+import java.io.Closeable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.metamodel.AbstractUpdateCallback;
+import org.apache.metamodel.UpdateCallback;
+import org.apache.metamodel.create.TableCreationBuilder;
+import org.apache.metamodel.delete.RowDeletionBuilder;
+import org.apache.metamodel.drop.TableDropBuilder;
+import org.apache.metamodel.insert.RowInsertionBuilder;
+import org.apache.metamodel.schema.Schema;
+import org.apache.metamodel.schema.Table;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+
+final class MongoDbUpdateCallback extends AbstractUpdateCallback implements UpdateCallback, Closeable {
+
+    private final MongoDbDataContext _dataContext;
+    private final Map<String, DBCollection> _collections;
+    private final WriteConcernAdvisor _writeConcernAdvisor;
+
+    public MongoDbUpdateCallback(MongoDbDataContext dataContext, WriteConcernAdvisor writeConcernAdvisor) {
+        super(dataContext);
+        _dataContext = dataContext;
+        _writeConcernAdvisor = writeConcernAdvisor;
+        _collections = new HashMap<String, DBCollection>();
+    }
+
+    @Override
+    public MongoDbDataContext getDataContext() {
+        return _dataContext;
+    }
+    
+    public WriteConcernAdvisor getWriteConcernAdvisor() {
+        return _writeConcernAdvisor;
+    }
+
+    @Override
+    public TableCreationBuilder createTable(Schema schema, String name) throws IllegalArgumentException,
+            IllegalStateException {
+        return new MongoDbTableCreationBuilder(this, schema, name);
+    }
+
+    @Override
+    public RowInsertionBuilder insertInto(Table table) throws IllegalArgumentException, IllegalStateException {
+        return new MongoDbInsertionBuilder(this, table);
+    }
+
+    protected void createCollection(String name) {
+        DBCollection collection = _dataContext.getMongoDb().createCollection(name, new BasicDBObject());
+        _collections.put(name, collection);
+    }
+
+    protected void removeCollection(String name) {
+        DBCollection collection = getCollection(name);
+        _collections.remove(name);
+        collection.drop();
+    }
+
+    protected DBCollection getCollection(String name) {
+        DBCollection collection = _collections.get(name);
+        if (collection == null) {
+            collection = _dataContext.getMongoDb().getCollection(name);
+            _collections.put(name, collection);
+        }
+        return collection;
+    }
+
+    @Override
+    public void close() {
+        _collections.clear();
+    }
+
+    @Override
+    public boolean isDropTableSupported() {
+        return true;
+    }
+
+    @Override
+    public TableDropBuilder dropTable(Table table) throws UnsupportedOperationException {
+        return new MongoDbDropTableBuilder(this, table);
+    }
+
+    @Override
+    public boolean isDeleteSupported() {
+        return true;
+    }
+
+    @Override
+    public RowDeletionBuilder deleteFrom(Table table) throws IllegalArgumentException, IllegalStateException,
+            UnsupportedOperationException {
+        return new MongoDbDeleteBuilder(this, table);
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/SimpleWriteConcernAdvisor.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/SimpleWriteConcernAdvisor.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/SimpleWriteConcernAdvisor.java
new file mode 100644
index 0000000..2854615
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/SimpleWriteConcernAdvisor.java
@@ -0,0 +1,50 @@
+/**
+ * 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.mongodb.mongo2;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.WriteConcern;
+
+/**
+ * A simple {@link WriteConcernAdvisor} that always returns the same write
+ * concern.
+ */
+public class SimpleWriteConcernAdvisor implements WriteConcernAdvisor {
+
+    private final WriteConcern _writeConcern;
+
+    public SimpleWriteConcernAdvisor(WriteConcern writeConcern) {
+        if (writeConcern == null) {
+            throw new IllegalArgumentException("WriteConcern cannot be null");
+        }
+        _writeConcern = writeConcern;
+    }
+
+    @Override
+    public WriteConcern adviceDeleteQuery(DBCollection collection, BasicDBObject query) {
+        return _writeConcern;
+    }
+
+    @Override
+    public WriteConcern adviceInsert(DBCollection collection, BasicDBObject document) {
+        return _writeConcern;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/WriteConcernAdvisor.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/WriteConcernAdvisor.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/WriteConcernAdvisor.java
new file mode 100644
index 0000000..a9a89e9
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/WriteConcernAdvisor.java
@@ -0,0 +1,35 @@
+/**
+ * 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.mongodb.mongo2;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.WriteConcern;
+
+/**
+ * Interface for component that advices MetaModel on which {@link WriteConcern}
+ * to apply to given operations
+ */
+public interface WriteConcernAdvisor {
+
+    public WriteConcern adviceDeleteQuery(DBCollection collection, BasicDBObject query);
+
+    public WriteConcern adviceInsert(DBCollection collection, BasicDBObject document);
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/365fae3a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/package-info.java
----------------------------------------------------------------------
diff --git a/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/package-info.java b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/package-info.java
new file mode 100644
index 0000000..b6ffb14
--- /dev/null
+++ b/mongodb/mongo2/src/main/java/org/apache/metamodel/mongodb/mongo2/package-info.java
@@ -0,0 +1,23 @@
+/**
+ * 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.
+ */
+/**
+ * Module package for MongoDB support
+ */
+package org.apache.metamodel.mongodb.mongo2;
+