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 2014/06/02 17:26:57 UTC

git commit: METAMODEL-46: Added Tomasz Guzialeks patch to fix this issue.

Repository: incubator-metamodel
Updated Branches:
  refs/heads/master f1ca2be89 -> 0344dfc06


METAMODEL-46: Added Tomasz Guzialeks patch to fix this issue.

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

Branch: refs/heads/master
Commit: 0344dfc06a71401c4ced2ed0b88eeec4958a2e28
Parents: f1ca2be
Author: Kasper Sørensen <i....@gmail.com>
Authored: Mon Jun 2 17:26:53 2014 +0200
Committer: Kasper Sørensen <i....@gmail.com>
Committed: Mon Jun 2 17:26:53 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 .../metamodel/couchdb/CouchDbDataContext.java   |  13 +++
 .../metamodel/couchdb/CouchDbDataSet.java       |  60 +---------
 .../apache/metamodel/couchdb/CouchDbUtils.java  | 113 +++++++++++++++++++
 .../couchdb/CouchDbDataContextTest.java         |   8 ++
 5 files changed, 140 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/0344dfc0/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index e9e8606..11b2f89 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,6 +9,7 @@ Apache MetaModel 4.1.0-incubating
  * [METAMODEL-47] - Fixed issue in Excel of loading schema if query is fired based on metadata from a previous DataContext instance.
  * [METAMODEL-35] - Improved query rewriting for DB2 when paged queries contain ORDER BY clause.
  * [METAMODEL-44] - Added an optional method for QueryPostprocessDataContext implementations to do a row-lookup by primary key value.
+ * [METAMODEL-46] - Improved row-lookup by primary key (ID) in CouchDB
  * [METAMODEL-43] - Made CSV datastores skip empty lines in file instead of treating them of rows with null values.
  * [METAMODEL-39] - Added pooling of active/used Connections and PreparedStatements in JDBC compiled queries.
  * [METAMODEL-58] - Fixed a bug related to using CreateTable class and primary keys not getting created.

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/0344dfc0/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataContext.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataContext.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataContext.java
index 7e85001..e0ef5f9 100644
--- a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataContext.java
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataContext.java
@@ -33,6 +33,7 @@ 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.SimpleDataSetHeader;
 import org.apache.metamodel.query.FilterItem;
 import org.apache.metamodel.query.SelectItem;
 import org.apache.metamodel.schema.Column;
@@ -246,6 +247,18 @@ public class CouchDbDataContext extends QueryPostprocessDataContext implements U
     }
 
     @Override
+    protected org.apache.metamodel.data.Row executePrimaryKeyLookupQuery(Table table, List<SelectItem> selectItems,
+            Column primaryKeyColumn, Object keyValue) {
+        final String databaseName = table.getName();
+        final CouchDbConnector connector = _couchDbInstance.createConnector(databaseName, false);
+
+        final String keyString = (String) keyValue;
+        final JsonNode node = connector.find(JsonNode.class, keyString);
+
+        return CouchDbUtils.jsonNodeToMetaModelRow(node, new SimpleDataSetHeader(selectItems));
+    }
+
+    @Override
     protected Number executeCountQuery(Table table, List<FilterItem> whereItems, boolean functionApproximationAllowed) {
         if (whereItems.isEmpty()) {
             String databaseName = table.getName();

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/0344dfc0/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataSet.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataSet.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataSet.java
index a390975..5d2a538 100644
--- a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataSet.java
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataSet.java
@@ -19,16 +19,14 @@
 package org.apache.metamodel.couchdb;
 
 import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
 
-import org.codehaus.jackson.JsonNode;
-import org.codehaus.jackson.map.ObjectMapper;
-import org.ektorp.StreamingViewResult;
 import org.apache.metamodel.data.AbstractDataSet;
+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.codehaus.jackson.JsonNode;
+import org.ektorp.StreamingViewResult;
 
 /**
  * DataSet implementation for couch db.
@@ -54,61 +52,13 @@ final class CouchDbDataSet extends AbstractDataSet {
 
         final org.ektorp.ViewResult.Row row = _iterator.next();
         final JsonNode node = row.getDocAsNode();
-        final int size = getHeader().size();
-        final Object[] values = new Object[size];
-        for (int i = 0; i < size; i++) {
-            final String key = getHeader().getSelectItem(i).getColumn().getName();
-            final JsonNode valueNode = node.get(key);
-            final Object value;
-            if (valueNode == null || valueNode.isNull()) {
-                value = null;
-            } else if (valueNode.isTextual()) {
-                value = valueNode.asText();
-            } else if (valueNode.isArray()) {
-                value = toList(valueNode);
-            } else if (valueNode.isObject()) {
-                value = toMap(valueNode);
-            } else if (valueNode.isBoolean()) {
-                value = valueNode.asBoolean();
-            } else if (valueNode.isInt()) {
-                value = valueNode.asInt();
-            } else if (valueNode.isLong()) {
-                value = valueNode.asLong();
-            } else if (valueNode.isDouble()) {
-                value = valueNode.asDouble();
-            } else {
-                value = valueNode;
-            }
-            values[i] = value;
-        }
 
-        _row = new DefaultRow(getHeader(), values);
+        final DataSetHeader header = getHeader();
+        _row = (DefaultRow) CouchDbUtils.jsonNodeToMetaModelRow(node, header);
 
         return true;
     }
 
-    private Map<String, Object> toMap(JsonNode valueNode) {
-        if (valueNode == null) {
-            return null;
-        }
-        try {
-            return new ObjectMapper().reader(Map.class).readValue(valueNode);
-        } catch (Exception e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
-    private Object toList(JsonNode valueNode) {
-        if (valueNode == null) {
-            return null;
-        }
-        try {
-            return new ObjectMapper().reader(List.class).readValue(valueNode);
-        } catch (Exception e) {
-            throw new IllegalStateException(e);
-        }
-    }
-
     @Override
     public Row getRow() {
         return _row;

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/0344dfc0/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbUtils.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbUtils.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbUtils.java
new file mode 100644
index 0000000..1708b28
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbUtils.java
@@ -0,0 +1,113 @@
+/**
+ * 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.couchdb;
+
+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.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+
+/**
+ * Convenience and utility methods for MetaModel's CouchDB adaptor
+ */
+final class CouchDbUtils {
+    /**
+     * Converts {@link JsonNode} to MetaModel {@link Row}.
+     * 
+     * @param node
+     *            {@link JsonNode} to convert.
+     * @param selectItems
+     *            Column names for the values in the row.
+     * @return MetaModel {@link Row} populated with values from {@link JsonNode}
+     *         .
+     */
+    public static Row jsonNodeToMetaModelRow(JsonNode node, DataSetHeader header) {
+        final int size = header.size();
+        final Object[] values = new Object[size];
+        for (int i = 0; i < size; i++) {
+            final String key = header.getSelectItem(i).getColumn().getName();
+            final JsonNode valueNode = node.get(key);
+            final Object value;
+            if (valueNode == null || valueNode.isNull()) {
+                value = null;
+            } else if (valueNode.isTextual()) {
+                value = valueNode.asText();
+            } else if (valueNode.isArray()) {
+                value = jsonNodeToList(valueNode);
+            } else if (valueNode.isObject()) {
+                value = jsonNodeToMap(valueNode);
+            } else if (valueNode.isBoolean()) {
+                value = valueNode.asBoolean();
+            } else if (valueNode.isInt()) {
+                value = valueNode.asInt();
+            } else if (valueNode.isLong()) {
+                value = valueNode.asLong();
+            } else if (valueNode.isDouble()) {
+                value = valueNode.asDouble();
+            } else {
+                value = valueNode;
+            }
+            values[i] = value;
+        }
+
+        DefaultRow finalRow = new DefaultRow(header, values);
+
+        return finalRow;
+    }
+
+    /**
+     * Converts {@link JsonNode} to a {@link Map}.
+     * 
+     * @param valueNode
+     *            The {@link JsonNode} to convert.
+     * @return The {@link Map} with values from {@link JsonNode}.
+     */
+    public static Map<String, Object> jsonNodeToMap(JsonNode valueNode) {
+        if (valueNode == null) {
+            return null;
+        }
+        try {
+            return new ObjectMapper().reader(Map.class).readValue(valueNode);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    /**
+     * Converts {@link JsonNode} to a {@link List}.
+     * 
+     * @param valueNode
+     *            The {@link JsonNode} to convert.
+     * @return The {@link List} with values from {@link JsonNode}.
+     */
+    public static Object jsonNodeToList(JsonNode valueNode) {
+        if (valueNode == null) {
+            return null;
+        }
+        try {
+            return new ObjectMapper().reader(List.class).readValue(valueNode);
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/0344dfc0/couchdb/src/test/java/org/apache/metamodel/couchdb/CouchDbDataContextTest.java
----------------------------------------------------------------------
diff --git a/couchdb/src/test/java/org/apache/metamodel/couchdb/CouchDbDataContextTest.java b/couchdb/src/test/java/org/apache/metamodel/couchdb/CouchDbDataContextTest.java
index 5f8c7b7..48d9497 100644
--- a/couchdb/src/test/java/org/apache/metamodel/couchdb/CouchDbDataContextTest.java
+++ b/couchdb/src/test/java/org/apache/metamodel/couchdb/CouchDbDataContextTest.java
@@ -252,6 +252,14 @@ public class CouchDbDataContextTest extends CouchDbTestCase {
         assertEquals("Row[values=[Jane Doe, F]]", ds.getRow().toString());
         assertFalse(ds.next());
         ds.close();
+
+        // test primary key lookup query
+        ds = dc.query().from(getDatabaseName()).select("name").and("gender").where("_id")
+                .eq("jane_doe_some_unique_test_id").execute();
+        assertTrue(ds.next());
+        assertEquals("Row[values=[Jane Doe, F]]", ds.getRow().toString());
+        assertFalse(ds.next());
+        ds.close();
     }
 
     public void testFirstRowAndLastRow() throws Exception {