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 2013/07/19 11:33:01 UTC
[18/61] [partial] Hard rename of all 'org/eobjects' folders to
'org/apache'.
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/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
new file mode 100644
index 0000000..6f3db01
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbDataSet.java
@@ -0,0 +1,123 @@
+/**
+ * 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.eobjects.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.eobjects.metamodel.data.AbstractDataSet;
+import org.eobjects.metamodel.data.DefaultRow;
+import org.eobjects.metamodel.data.Row;
+import org.eobjects.metamodel.query.SelectItem;
+
+/**
+ * DataSet implementation for couch db.
+ */
+final class CouchDbDataSet extends AbstractDataSet {
+
+ private final Iterator<org.ektorp.ViewResult.Row> _iterator;
+ private final StreamingViewResult _streamingViewResult;
+ private DefaultRow _row;
+
+ public CouchDbDataSet(SelectItem[] selectItems, StreamingViewResult streamingViewResult) {
+ super(selectItems);
+ _streamingViewResult = streamingViewResult;
+
+ _iterator = _streamingViewResult.iterator();
+ }
+
+ @Override
+ public boolean next() {
+ if (_iterator == null || !_iterator.hasNext()) {
+ return false;
+ }
+
+ 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);
+
+ 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;
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ _streamingViewResult.close();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbInsertionBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbInsertionBuilder.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbInsertionBuilder.java
new file mode 100644
index 0000000..7fe2ae6
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbInsertionBuilder.java
@@ -0,0 +1,54 @@
+/**
+ * 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.eobjects.metamodel.couchdb;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.ektorp.CouchDbConnector;
+import org.eobjects.metamodel.MetaModelException;
+import org.eobjects.metamodel.insert.AbstractRowInsertionBuilder;
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.Table;
+
+final class CouchDbInsertionBuilder extends AbstractRowInsertionBuilder<CouchDbUpdateCallback> {
+
+ public CouchDbInsertionBuilder(CouchDbUpdateCallback updateCallback, Table table) {
+ super(updateCallback, table);
+ }
+
+ @Override
+ public void execute() throws MetaModelException {
+ Table table = getTable();
+ String name = table.getName();
+
+ Object[] values = getValues();
+ Column[] columns = getColumns();
+ Map<String, Object> map = new HashMap<String, Object>();
+ for (int i = 0; i < columns.length; i++) {
+ Column column = columns[i];
+ if (isSet(column)) {
+ map.put(column.getName(), values[i]);
+ }
+ }
+
+ CouchDbConnector connector = getUpdateCallback().getConnector(name);
+ connector.addToBulkBuffer(map);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbRowDeletionBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbRowDeletionBuilder.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbRowDeletionBuilder.java
new file mode 100644
index 0000000..fe0fc66
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbRowDeletionBuilder.java
@@ -0,0 +1,62 @@
+/**
+ * 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.eobjects.metamodel.couchdb;
+
+import java.util.List;
+
+import org.ektorp.CouchDbConnector;
+import org.eobjects.metamodel.MetaModelException;
+import org.eobjects.metamodel.data.DataSet;
+import org.eobjects.metamodel.data.Row;
+import org.eobjects.metamodel.delete.AbstractRowDeletionBuilder;
+import org.eobjects.metamodel.query.FilterItem;
+import org.eobjects.metamodel.schema.Table;
+
+final class CouchDbRowDeletionBuilder extends AbstractRowDeletionBuilder {
+
+ private final CouchDbUpdateCallback _updateCallback;
+
+ public CouchDbRowDeletionBuilder(CouchDbUpdateCallback updateCallback, Table table) {
+ super(table);
+ _updateCallback = updateCallback;
+ }
+
+ @Override
+ public void execute() throws MetaModelException {
+ Table table = getTable();
+ List<FilterItem> whereItems = getWhereItems();
+
+ CouchDbConnector connector = _updateCallback.getConnector(table.getName());
+ CouchDbDataContext dataContext = _updateCallback.getDataContext();
+
+ DataSet dataSet = dataContext.query().from(table)
+ .select(CouchDbDataContext.FIELD_ID, CouchDbDataContext.FIELD_REV).where(whereItems).execute();
+ try {
+ while (dataSet.next()) {
+ Row row = dataSet.getRow();
+ String id = (String) row.getValue(0);
+ String revision = (String) row.getValue(1);
+ connector.delete(id, revision);
+ }
+ } finally {
+ dataSet.close();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbRowUpdationBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbRowUpdationBuilder.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbRowUpdationBuilder.java
new file mode 100644
index 0000000..15a4298
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbRowUpdationBuilder.java
@@ -0,0 +1,79 @@
+/**
+ * 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.eobjects.metamodel.couchdb;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.ektorp.CouchDbConnector;
+import org.eobjects.metamodel.MetaModelException;
+import org.eobjects.metamodel.data.DataSet;
+import org.eobjects.metamodel.data.Row;
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.Table;
+import org.eobjects.metamodel.update.AbstractRowUpdationBuilder;
+
+final class CouchDbRowUpdationBuilder extends AbstractRowUpdationBuilder {
+
+ private final CouchDbUpdateCallback _updateCallback;
+
+ public CouchDbRowUpdationBuilder(CouchDbUpdateCallback updateCallback, Table table) {
+ super(table);
+ _updateCallback = updateCallback;
+ }
+
+ @Override
+ public void execute() throws MetaModelException {
+ final Table table = getTable();
+ final CouchDbConnector connector = _updateCallback.getConnector(table.getName());
+
+ // create a map which will act as a prototype for updated objects
+ final Map<String, Object> prototype = new HashMap<String, Object>();
+ final Column[] columns = getColumns();
+ final Object[] values = getValues();
+ for (int i = 0; i < columns.length; i++) {
+ final Column column = columns[i];
+ if (isSet(column)) {
+ final String columnName = column.getName();
+ final Object value = values[i];
+ prototype.put(columnName, value);
+ }
+ }
+
+ final CouchDbDataContext dc = _updateCallback.getDataContext();
+ final DataSet dataSet = dc.query().from(table).select(table.getColumns()).where(getWhereItems()).execute();
+ try {
+ while (dataSet.next()) {
+ final Map<String, Object> map = new HashMap<String, Object>(prototype);
+ final Row row = dataSet.getRow();
+ for (Column column : table.getColumns()) {
+ if (!map.containsKey(column.getName())) {
+ map.put(column.getName(), row.getValue(column));
+ }
+ }
+
+ // copy the prototype and set the not-updated values
+ connector.update(map);
+ }
+ } finally {
+ dataSet.close();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbTableCreationBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbTableCreationBuilder.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbTableCreationBuilder.java
new file mode 100644
index 0000000..df00880
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbTableCreationBuilder.java
@@ -0,0 +1,75 @@
+/**
+ * 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.eobjects.metamodel.couchdb;
+
+import org.ektorp.CouchDbInstance;
+import org.eobjects.metamodel.MetaModelException;
+import org.eobjects.metamodel.create.AbstractTableCreationBuilder;
+import org.eobjects.metamodel.schema.ColumnType;
+import org.eobjects.metamodel.schema.MutableColumn;
+import org.eobjects.metamodel.schema.MutableSchema;
+import org.eobjects.metamodel.schema.MutableTable;
+import org.eobjects.metamodel.schema.Schema;
+import org.eobjects.metamodel.schema.Table;
+
+final class CouchDbTableCreationBuilder extends AbstractTableCreationBuilder<CouchDbUpdateCallback> {
+
+ public CouchDbTableCreationBuilder(CouchDbUpdateCallback updateCallback, Schema schema, String name) {
+ super(updateCallback, schema, name);
+ }
+
+ @Override
+ public Table execute() throws MetaModelException {
+ MutableTable table = getTable();
+
+ String name = table.getName();
+
+ CouchDbInstance instance = getUpdateCallback().getDataContext().getCouchDbInstance();
+ instance.createDatabase(name);
+
+ addMandatoryColumns(table);
+
+ MutableSchema schema = (MutableSchema) table.getSchema();
+ schema.addTable(table);
+
+ return table;
+ }
+
+ /**
+ * Verifies, and adds if nescesary, the two mandatory columns: _id and _rev.
+ *
+ * @param table
+ */
+ public static void addMandatoryColumns(MutableTable table) {
+ // add or correct ID column
+ {
+ MutableColumn idColumn = (MutableColumn) table.getColumnByName(CouchDbDataContext.FIELD_ID);
+ if (idColumn == null) {
+ idColumn = new MutableColumn(CouchDbDataContext.FIELD_ID, ColumnType.VARCHAR, table, 0, false);
+ table.addColumn(0, idColumn);
+ }
+ idColumn.setPrimaryKey(true);
+ }
+
+ if (table.getColumnByName(CouchDbDataContext.FIELD_REV) == null) {
+ table.addColumn(1, new MutableColumn(CouchDbDataContext.FIELD_REV, ColumnType.VARCHAR, table, 1, false));
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbTableDropBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbTableDropBuilder.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbTableDropBuilder.java
new file mode 100644
index 0000000..91297aa
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbTableDropBuilder.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.eobjects.metamodel.couchdb;
+
+import org.ektorp.CouchDbInstance;
+import org.eobjects.metamodel.MetaModelException;
+import org.eobjects.metamodel.drop.AbstractTableDropBuilder;
+import org.eobjects.metamodel.schema.MutableSchema;
+import org.eobjects.metamodel.schema.Table;
+
+final class CouchDbTableDropBuilder extends AbstractTableDropBuilder {
+
+ private final CouchDbUpdateCallback _updateCallback;
+
+ public CouchDbTableDropBuilder(CouchDbUpdateCallback updateCallback, Table table) {
+ super(table);
+ _updateCallback = updateCallback;
+ }
+
+ @Override
+ public void execute() throws MetaModelException {
+ CouchDbInstance instance = _updateCallback.getDataContext().getCouchDbInstance();
+ Table table = getTable();
+ MutableSchema schema = (MutableSchema) table.getSchema();
+ schema.removeTable(table);
+
+ instance.deleteDatabase(table.getName());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbUpdateCallback.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbUpdateCallback.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbUpdateCallback.java
new file mode 100644
index 0000000..8207c0d
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/CouchDbUpdateCallback.java
@@ -0,0 +1,143 @@
+/**
+ * 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.eobjects.metamodel.couchdb;
+
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.ektorp.CouchDbConnector;
+import org.ektorp.CouchDbInstance;
+import org.ektorp.DocumentOperationResult;
+import org.eobjects.metamodel.AbstractUpdateCallback;
+import org.eobjects.metamodel.MetaModelException;
+import org.eobjects.metamodel.create.TableCreationBuilder;
+import org.eobjects.metamodel.delete.RowDeletionBuilder;
+import org.eobjects.metamodel.drop.TableDropBuilder;
+import org.eobjects.metamodel.insert.RowInsertionBuilder;
+import org.eobjects.metamodel.schema.Schema;
+import org.eobjects.metamodel.schema.Table;
+import org.eobjects.metamodel.update.RowUpdationBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class CouchDbUpdateCallback extends AbstractUpdateCallback implements Closeable {
+
+ private static final Logger logger = LoggerFactory.getLogger(CouchDbUpdateCallback.class);
+ private final Map<String, CouchDbConnector> _connectors;
+
+ public CouchDbUpdateCallback(CouchDbDataContext couchDbDataContext) {
+ super(couchDbDataContext);
+ _connectors = new HashMap<String, CouchDbConnector>();
+ }
+
+ @Override
+ public CouchDbDataContext getDataContext() {
+ return (CouchDbDataContext) super.getDataContext();
+ }
+
+ @Override
+ public boolean isUpdateSupported() {
+ return true;
+ }
+
+ @Override
+ public RowUpdationBuilder update(Table table) throws IllegalArgumentException, IllegalStateException,
+ UnsupportedOperationException {
+ return new CouchDbRowUpdationBuilder(this, table);
+ }
+
+ @Override
+ public boolean isCreateTableSupported() {
+ return true;
+ }
+
+ @Override
+ public TableCreationBuilder createTable(Schema schema, String name) throws IllegalArgumentException,
+ IllegalStateException {
+ return new CouchDbTableCreationBuilder(this, schema, name);
+ }
+
+ @Override
+ public boolean isDropTableSupported() {
+ return true;
+ }
+
+ @Override
+ public TableDropBuilder dropTable(Table table) throws IllegalArgumentException, IllegalStateException,
+ UnsupportedOperationException {
+ return new CouchDbTableDropBuilder(this, table);
+ }
+
+ @Override
+ public RowInsertionBuilder insertInto(Table table) throws IllegalArgumentException, IllegalStateException,
+ UnsupportedOperationException {
+ return new CouchDbInsertionBuilder(this, table);
+ }
+
+ @Override
+ public boolean isDeleteSupported() {
+ return true;
+ }
+
+ @Override
+ public RowDeletionBuilder deleteFrom(Table table) throws IllegalArgumentException, IllegalStateException,
+ UnsupportedOperationException {
+ return new CouchDbRowDeletionBuilder(this, table);
+ }
+
+ @Override
+ public void close() {
+ Collection<CouchDbConnector> connectorSet = _connectors.values();
+ for (CouchDbConnector connector : connectorSet) {
+ List<String> errornousResultsDescriptions = new ArrayList<String>();
+ List<DocumentOperationResult> results = connector.flushBulkBuffer();
+ for (DocumentOperationResult result : results) {
+ if (result.isErroneous()) {
+ String id = result.getId();
+ String error = result.getError();
+ String reason = result.getReason();
+ String revision = result.getRevision();
+ logger.error("Error occurred while flushing bulk buffer: {}, id: {}, revision: {}, reason: {}",
+ new Object[] { error, id, revision, reason });
+ errornousResultsDescriptions.add(error);
+ }
+ }
+
+ if (!errornousResultsDescriptions.isEmpty()) {
+ throw new MetaModelException(errornousResultsDescriptions.size() + " out of " + results.size()
+ + " operations in bulk was errornous: " + errornousResultsDescriptions);
+ }
+ }
+ }
+
+ public CouchDbConnector getConnector(String name) {
+ CouchDbConnector connector = _connectors.get(name);
+ if (connector == null) {
+ CouchDbInstance instance = getDataContext().getCouchDbInstance();
+ connector = instance.createConnector(name, false);
+ _connectors.put(name, connector);
+ }
+ return connector;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/apache/metamodel/couchdb/package-info.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/apache/metamodel/couchdb/package-info.java b/couchdb/src/main/java/org/apache/metamodel/couchdb/package-info.java
new file mode 100644
index 0000000..340fd98
--- /dev/null
+++ b/couchdb/src/main/java/org/apache/metamodel/couchdb/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 CouchDB support
+ */
+package org.eobjects.metamodel.couchdb;
+
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbDataContext.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbDataContext.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbDataContext.java
deleted file mode 100644
index ac626e6..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbDataContext.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/**
- * 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.eobjects.metamodel.couchdb;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.codehaus.jackson.JsonNode;
-import org.ektorp.CouchDbConnector;
-import org.ektorp.CouchDbInstance;
-import org.ektorp.StreamingViewResult;
-import org.ektorp.ViewQuery;
-import org.ektorp.ViewResult.Row;
-import org.ektorp.http.HttpClient;
-import org.ektorp.http.StdHttpClient;
-import org.ektorp.impl.StdCouchDbInstance;
-import org.eobjects.metamodel.MetaModelException;
-import org.eobjects.metamodel.MetaModelHelper;
-import org.eobjects.metamodel.QueryPostprocessDataContext;
-import org.eobjects.metamodel.UpdateScript;
-import org.eobjects.metamodel.UpdateableDataContext;
-import org.eobjects.metamodel.data.DataSet;
-import org.eobjects.metamodel.query.FilterItem;
-import org.eobjects.metamodel.query.SelectItem;
-import org.eobjects.metamodel.schema.Column;
-import org.eobjects.metamodel.schema.ColumnType;
-import org.eobjects.metamodel.schema.MutableSchema;
-import org.eobjects.metamodel.schema.MutableTable;
-import org.eobjects.metamodel.schema.Schema;
-import org.eobjects.metamodel.schema.Table;
-import org.eobjects.metamodel.util.SimpleTableDef;
-
-/**
- * DataContext implementation for CouchDB
- */
-public class CouchDbDataContext extends QueryPostprocessDataContext implements UpdateableDataContext {
-
- public static final int DEFAULT_PORT = 5984;
-
- public static final String FIELD_ID = "_id";
- public static final String FIELD_REV = "_rev";
-
- private static final String SCHEMA_NAME = "CouchDB";
-
- private final CouchDbInstance _couchDbInstance;
- private final SimpleTableDef[] _tableDefs;
-
- public CouchDbDataContext(StdHttpClient.Builder httpClientBuilder, SimpleTableDef... tableDefs) {
- this(httpClientBuilder.build(), tableDefs);
- }
-
- public CouchDbDataContext(StdHttpClient.Builder httpClientBuilder) {
- this(httpClientBuilder.build());
- }
-
- public CouchDbDataContext(HttpClient httpClient, SimpleTableDef... tableDefs) {
- this(new StdCouchDbInstance(httpClient), tableDefs);
- }
-
- public CouchDbDataContext(HttpClient httpClient) {
- this(new StdCouchDbInstance(httpClient));
- }
-
- public CouchDbDataContext(CouchDbInstance couchDbInstance) {
- this(couchDbInstance, detectSchema(couchDbInstance));
- }
-
- public CouchDbDataContext(CouchDbInstance couchDbInstance, SimpleTableDef... tableDefs) {
- // the instance represents a handle to the whole couchdb cluster
- _couchDbInstance = couchDbInstance;
- _tableDefs = tableDefs;
- }
-
- public static SimpleTableDef[] detectSchema(CouchDbInstance couchDbInstance) {
- final List<SimpleTableDef> tableDefs = new ArrayList<SimpleTableDef>();
- final List<String> databaseNames = couchDbInstance.getAllDatabases();
- for (final String databaseName : databaseNames) {
-
- if (databaseName.startsWith("_")) {
- // don't add system tables
- continue;
- }
-
- CouchDbConnector connector = couchDbInstance.createConnector(databaseName, false);
-
- SimpleTableDef tableDef = detectTable(connector);
- tableDefs.add(tableDef);
- }
- return tableDefs.toArray(new SimpleTableDef[tableDefs.size()]);
- }
-
- public static SimpleTableDef detectTable(CouchDbConnector connector) {
- final SortedMap<String, Set<ColumnType>> columnsAndTypes = new TreeMap<String, Set<ColumnType>>();
-
- final StreamingViewResult streamingView = connector.queryForStreamingView(new ViewQuery().allDocs().includeDocs(true)
- .limit(1000));
- try {
- final Iterator<Row> rowIterator = streamingView.iterator();
- while (rowIterator.hasNext()) {
- Row row = rowIterator.next();
- JsonNode doc = row.getDocAsNode();
-
- final Iterator<Entry<String, JsonNode>> fieldIterator = doc.getFields();
- while (fieldIterator.hasNext()) {
- Entry<String, JsonNode> entry = fieldIterator.next();
- String key = entry.getKey();
-
- Set<ColumnType> types = columnsAndTypes.get(key);
-
- if (types == null) {
- types = EnumSet.noneOf(ColumnType.class);
- columnsAndTypes.put(key, types);
- }
-
- JsonNode value = entry.getValue();
- if (value == null || value.isNull()) {
- // do nothing
- } else if (value.isTextual()) {
- types.add(ColumnType.VARCHAR);
- } else if (value.isArray()) {
- types.add(ColumnType.LIST);
- } else if (value.isObject()) {
- types.add(ColumnType.MAP);
- } else if (value.isBoolean()) {
- types.add(ColumnType.BOOLEAN);
- } else if (value.isInt()) {
- types.add(ColumnType.INTEGER);
- } else if (value.isLong()) {
- types.add(ColumnType.BIGINT);
- } else if (value.isDouble()) {
- types.add(ColumnType.DOUBLE);
- }
- }
-
- }
- } finally {
- streamingView.close();
- }
-
- final String[] columnNames = new String[columnsAndTypes.size()];
- final ColumnType[] columnTypes = new ColumnType[columnsAndTypes.size()];
-
- int i = 0;
- for (Entry<String, Set<ColumnType>> columnAndTypes : columnsAndTypes.entrySet()) {
- final String columnName = columnAndTypes.getKey();
- final Set<ColumnType> columnTypeSet = columnAndTypes.getValue();
- final ColumnType columnType;
- if (columnTypeSet.isEmpty()) {
- columnType = ColumnType.OTHER;
- } else if (columnTypeSet.size() == 1) {
- columnType = columnTypeSet.iterator().next();
- } else {
- // TODO: Select best type?
- columnType = ColumnType.OTHER;
- }
- columnNames[i] = columnName;
- columnTypes[i] = columnType;
- i++;
- }
-
- final SimpleTableDef tableDef = new SimpleTableDef(connector.getDatabaseName(), columnNames, columnTypes);
- return tableDef;
- }
-
- public CouchDbInstance getCouchDbInstance() {
- return _couchDbInstance;
- }
-
- @Override
- protected Schema getMainSchema() throws MetaModelException {
- final MutableSchema schema = new MutableSchema(SCHEMA_NAME);
- for (final SimpleTableDef tableDef : _tableDefs) {
- final MutableTable table = tableDef.toTable().setSchema(schema);
- CouchDbTableCreationBuilder.addMandatoryColumns(table);
- schema.addTable(table);
- }
- return schema;
- }
-
- @Override
- protected String getMainSchemaName() throws MetaModelException {
- return SCHEMA_NAME;
- }
-
- @Override
- protected DataSet materializeMainSchemaTable(Table table, Column[] columns, int firstRow, int maxRows) {
- // the connector represents a handle to the the couchdb "database".
- final String databaseName = table.getName();
- final CouchDbConnector connector = _couchDbInstance.createConnector(databaseName, false);
-
- ViewQuery query = new ViewQuery().allDocs().includeDocs(true);
-
- if (maxRows > 0) {
- query = query.limit(maxRows);
- }
- if (firstRow > 1) {
- final int skip = firstRow - 1;
- query = query.skip(skip);
- }
-
- final StreamingViewResult streamingView = connector.queryForStreamingView(query);
-
- final SelectItem[] selectItems = MetaModelHelper.createSelectItems(columns);
- return new CouchDbDataSet(selectItems, streamingView);
- }
-
- @Override
- protected DataSet materializeMainSchemaTable(Table table, Column[] columns, int maxRows) {
- return materializeMainSchemaTable(table, columns, 1, maxRows);
- }
-
- @Override
- protected Number executeCountQuery(Table table, List<FilterItem> whereItems, boolean functionApproximationAllowed) {
- if (whereItems.isEmpty()) {
- String databaseName = table.getName();
- CouchDbConnector connector = _couchDbInstance.createConnector(databaseName, false);
- long docCount = connector.getDbInfo().getDocCount();
- return docCount;
- }
- return null;
- }
-
- @Override
- public void executeUpdate(UpdateScript script) {
- CouchDbUpdateCallback callback = new CouchDbUpdateCallback(this);
- try {
- script.run(callback);
- } finally {
- callback.close();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbDataSet.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbDataSet.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbDataSet.java
deleted file mode 100644
index 6f3db01..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbDataSet.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * 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.eobjects.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.eobjects.metamodel.data.AbstractDataSet;
-import org.eobjects.metamodel.data.DefaultRow;
-import org.eobjects.metamodel.data.Row;
-import org.eobjects.metamodel.query.SelectItem;
-
-/**
- * DataSet implementation for couch db.
- */
-final class CouchDbDataSet extends AbstractDataSet {
-
- private final Iterator<org.ektorp.ViewResult.Row> _iterator;
- private final StreamingViewResult _streamingViewResult;
- private DefaultRow _row;
-
- public CouchDbDataSet(SelectItem[] selectItems, StreamingViewResult streamingViewResult) {
- super(selectItems);
- _streamingViewResult = streamingViewResult;
-
- _iterator = _streamingViewResult.iterator();
- }
-
- @Override
- public boolean next() {
- if (_iterator == null || !_iterator.hasNext()) {
- return false;
- }
-
- 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);
-
- 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;
- }
-
- @Override
- public void close() {
- super.close();
- _streamingViewResult.close();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbInsertionBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbInsertionBuilder.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbInsertionBuilder.java
deleted file mode 100644
index 7b5f298..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbInsertionBuilder.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.eobjects.metamodel.couchdb;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.ektorp.CouchDbConnector;
-import org.eobjects.metamodel.MetaModelException;
-import org.eobjects.metamodel.insert.AbstractRowInsertionBuilder;
-import org.eobjects.metamodel.schema.Column;
-import org.eobjects.metamodel.schema.Table;
-
-final class CouchDbInsertionBuilder extends AbstractRowInsertionBuilder<CouchDbUpdateCallback> {
-
- public CouchDbInsertionBuilder(CouchDbUpdateCallback updateCallback, Table table) {
- super(updateCallback, table);
- }
-
- @Override
- public void execute() throws MetaModelException {
- Table table = getTable();
- String name = table.getName();
-
- Object[] values = getValues();
- Column[] columns = getColumns();
- Map<String, Object> map = new HashMap<String, Object>();
- for (int i = 0; i < columns.length; i++) {
- Column column = columns[i];
- if (isSet(column)) {
- map.put(column.getName(), values[i]);
- }
- }
-
- CouchDbConnector connector = getUpdateCallback().getConnector(name);
- connector.addToBulkBuffer(map);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbRowDeletionBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbRowDeletionBuilder.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbRowDeletionBuilder.java
deleted file mode 100644
index fe0fc66..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbRowDeletionBuilder.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * 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.eobjects.metamodel.couchdb;
-
-import java.util.List;
-
-import org.ektorp.CouchDbConnector;
-import org.eobjects.metamodel.MetaModelException;
-import org.eobjects.metamodel.data.DataSet;
-import org.eobjects.metamodel.data.Row;
-import org.eobjects.metamodel.delete.AbstractRowDeletionBuilder;
-import org.eobjects.metamodel.query.FilterItem;
-import org.eobjects.metamodel.schema.Table;
-
-final class CouchDbRowDeletionBuilder extends AbstractRowDeletionBuilder {
-
- private final CouchDbUpdateCallback _updateCallback;
-
- public CouchDbRowDeletionBuilder(CouchDbUpdateCallback updateCallback, Table table) {
- super(table);
- _updateCallback = updateCallback;
- }
-
- @Override
- public void execute() throws MetaModelException {
- Table table = getTable();
- List<FilterItem> whereItems = getWhereItems();
-
- CouchDbConnector connector = _updateCallback.getConnector(table.getName());
- CouchDbDataContext dataContext = _updateCallback.getDataContext();
-
- DataSet dataSet = dataContext.query().from(table)
- .select(CouchDbDataContext.FIELD_ID, CouchDbDataContext.FIELD_REV).where(whereItems).execute();
- try {
- while (dataSet.next()) {
- Row row = dataSet.getRow();
- String id = (String) row.getValue(0);
- String revision = (String) row.getValue(1);
- connector.delete(id, revision);
- }
- } finally {
- dataSet.close();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbRowUpdationBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbRowUpdationBuilder.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbRowUpdationBuilder.java
deleted file mode 100644
index 15a4298..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbRowUpdationBuilder.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * 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.eobjects.metamodel.couchdb;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.ektorp.CouchDbConnector;
-import org.eobjects.metamodel.MetaModelException;
-import org.eobjects.metamodel.data.DataSet;
-import org.eobjects.metamodel.data.Row;
-import org.eobjects.metamodel.schema.Column;
-import org.eobjects.metamodel.schema.Table;
-import org.eobjects.metamodel.update.AbstractRowUpdationBuilder;
-
-final class CouchDbRowUpdationBuilder extends AbstractRowUpdationBuilder {
-
- private final CouchDbUpdateCallback _updateCallback;
-
- public CouchDbRowUpdationBuilder(CouchDbUpdateCallback updateCallback, Table table) {
- super(table);
- _updateCallback = updateCallback;
- }
-
- @Override
- public void execute() throws MetaModelException {
- final Table table = getTable();
- final CouchDbConnector connector = _updateCallback.getConnector(table.getName());
-
- // create a map which will act as a prototype for updated objects
- final Map<String, Object> prototype = new HashMap<String, Object>();
- final Column[] columns = getColumns();
- final Object[] values = getValues();
- for (int i = 0; i < columns.length; i++) {
- final Column column = columns[i];
- if (isSet(column)) {
- final String columnName = column.getName();
- final Object value = values[i];
- prototype.put(columnName, value);
- }
- }
-
- final CouchDbDataContext dc = _updateCallback.getDataContext();
- final DataSet dataSet = dc.query().from(table).select(table.getColumns()).where(getWhereItems()).execute();
- try {
- while (dataSet.next()) {
- final Map<String, Object> map = new HashMap<String, Object>(prototype);
- final Row row = dataSet.getRow();
- for (Column column : table.getColumns()) {
- if (!map.containsKey(column.getName())) {
- map.put(column.getName(), row.getValue(column));
- }
- }
-
- // copy the prototype and set the not-updated values
- connector.update(map);
- }
- } finally {
- dataSet.close();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbTableCreationBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbTableCreationBuilder.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbTableCreationBuilder.java
deleted file mode 100644
index df00880..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbTableCreationBuilder.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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.eobjects.metamodel.couchdb;
-
-import org.ektorp.CouchDbInstance;
-import org.eobjects.metamodel.MetaModelException;
-import org.eobjects.metamodel.create.AbstractTableCreationBuilder;
-import org.eobjects.metamodel.schema.ColumnType;
-import org.eobjects.metamodel.schema.MutableColumn;
-import org.eobjects.metamodel.schema.MutableSchema;
-import org.eobjects.metamodel.schema.MutableTable;
-import org.eobjects.metamodel.schema.Schema;
-import org.eobjects.metamodel.schema.Table;
-
-final class CouchDbTableCreationBuilder extends AbstractTableCreationBuilder<CouchDbUpdateCallback> {
-
- public CouchDbTableCreationBuilder(CouchDbUpdateCallback updateCallback, Schema schema, String name) {
- super(updateCallback, schema, name);
- }
-
- @Override
- public Table execute() throws MetaModelException {
- MutableTable table = getTable();
-
- String name = table.getName();
-
- CouchDbInstance instance = getUpdateCallback().getDataContext().getCouchDbInstance();
- instance.createDatabase(name);
-
- addMandatoryColumns(table);
-
- MutableSchema schema = (MutableSchema) table.getSchema();
- schema.addTable(table);
-
- return table;
- }
-
- /**
- * Verifies, and adds if nescesary, the two mandatory columns: _id and _rev.
- *
- * @param table
- */
- public static void addMandatoryColumns(MutableTable table) {
- // add or correct ID column
- {
- MutableColumn idColumn = (MutableColumn) table.getColumnByName(CouchDbDataContext.FIELD_ID);
- if (idColumn == null) {
- idColumn = new MutableColumn(CouchDbDataContext.FIELD_ID, ColumnType.VARCHAR, table, 0, false);
- table.addColumn(0, idColumn);
- }
- idColumn.setPrimaryKey(true);
- }
-
- if (table.getColumnByName(CouchDbDataContext.FIELD_REV) == null) {
- table.addColumn(1, new MutableColumn(CouchDbDataContext.FIELD_REV, ColumnType.VARCHAR, table, 1, false));
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbTableDropBuilder.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbTableDropBuilder.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbTableDropBuilder.java
deleted file mode 100644
index 91297aa..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbTableDropBuilder.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * 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.eobjects.metamodel.couchdb;
-
-import org.ektorp.CouchDbInstance;
-import org.eobjects.metamodel.MetaModelException;
-import org.eobjects.metamodel.drop.AbstractTableDropBuilder;
-import org.eobjects.metamodel.schema.MutableSchema;
-import org.eobjects.metamodel.schema.Table;
-
-final class CouchDbTableDropBuilder extends AbstractTableDropBuilder {
-
- private final CouchDbUpdateCallback _updateCallback;
-
- public CouchDbTableDropBuilder(CouchDbUpdateCallback updateCallback, Table table) {
- super(table);
- _updateCallback = updateCallback;
- }
-
- @Override
- public void execute() throws MetaModelException {
- CouchDbInstance instance = _updateCallback.getDataContext().getCouchDbInstance();
- Table table = getTable();
- MutableSchema schema = (MutableSchema) table.getSchema();
- schema.removeTable(table);
-
- instance.deleteDatabase(table.getName());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbUpdateCallback.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbUpdateCallback.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbUpdateCallback.java
deleted file mode 100644
index e96b7bc..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/CouchDbUpdateCallback.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/**
- * 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.eobjects.metamodel.couchdb;
-
-import java.io.Closeable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.ektorp.CouchDbConnector;
-import org.ektorp.CouchDbInstance;
-import org.ektorp.DocumentOperationResult;
-import org.eobjects.metamodel.AbstractUpdateCallback;
-import org.eobjects.metamodel.MetaModelException;
-import org.eobjects.metamodel.create.TableCreationBuilder;
-import org.eobjects.metamodel.delete.RowDeletionBuilder;
-import org.eobjects.metamodel.drop.TableDropBuilder;
-import org.eobjects.metamodel.insert.RowInsertionBuilder;
-import org.eobjects.metamodel.schema.Schema;
-import org.eobjects.metamodel.schema.Table;
-import org.eobjects.metamodel.update.RowUpdationBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-final class CouchDbUpdateCallback extends AbstractUpdateCallback implements Closeable {
-
- private static final Logger logger = LoggerFactory.getLogger(CouchDbUpdateCallback.class);
- private final Map<String, CouchDbConnector> _connectors;
-
- public CouchDbUpdateCallback(CouchDbDataContext couchDbDataContext) {
- super(couchDbDataContext);
- _connectors = new HashMap<String, CouchDbConnector>();
- }
-
- @Override
- public CouchDbDataContext getDataContext() {
- return (CouchDbDataContext) super.getDataContext();
- }
-
- @Override
- public boolean isUpdateSupported() {
- return true;
- }
-
- @Override
- public RowUpdationBuilder update(Table table) throws IllegalArgumentException, IllegalStateException,
- UnsupportedOperationException {
- return new CouchDbRowUpdationBuilder(this, table);
- }
-
- @Override
- public boolean isCreateTableSupported() {
- return true;
- }
-
- @Override
- public TableCreationBuilder createTable(Schema schema, String name) throws IllegalArgumentException,
- IllegalStateException {
- return new CouchDbTableCreationBuilder(this, schema, name);
- }
-
- @Override
- public boolean isDropTableSupported() {
- return true;
- }
-
- @Override
- public TableDropBuilder dropTable(Table table) throws IllegalArgumentException, IllegalStateException,
- UnsupportedOperationException {
- return new CouchDbTableDropBuilder(this, table);
- }
-
- @Override
- public RowInsertionBuilder insertInto(Table table) throws IllegalArgumentException, IllegalStateException,
- UnsupportedOperationException {
- return new CouchDbInsertionBuilder(this, table);
- }
-
- @Override
- public boolean isDeleteSupported() {
- return true;
- }
-
- @Override
- public RowDeletionBuilder deleteFrom(Table table) throws IllegalArgumentException, IllegalStateException,
- UnsupportedOperationException {
- return new CouchDbRowDeletionBuilder(this, table);
- }
-
- @Override
- public void close() {
- Collection<CouchDbConnector> connectorSet = _connectors.values();
- for (CouchDbConnector connector : connectorSet) {
- List<String> errornousResultsDescriptions = new ArrayList<String>();
- List<DocumentOperationResult> results = connector.flushBulkBuffer();
- for (DocumentOperationResult result : results) {
- if (result.isErroneous()) {
- String id = result.getId();
- String error = result.getError();
- String reason = result.getReason();
- String revision = result.getRevision();
- logger.error("Error occurred while flushing bulk buffer: {}, id: {}, revision: {}, reason: {}",
- new Object[] { error, id, revision, reason });
- errornousResultsDescriptions.add(error);
- }
- }
-
- if (!errornousResultsDescriptions.isEmpty()) {
- throw new MetaModelException(errornousResultsDescriptions.size() + " out of " + results.size()
- + " operations in bulk was errornous: " + errornousResultsDescriptions);
- }
- }
- }
-
- public CouchDbConnector getConnector(String name) {
- CouchDbConnector connector = _connectors.get(name);
- if (connector == null) {
- CouchDbInstance instance = getDataContext().getCouchDbInstance();
- connector = instance.createConnector(name, false);
- _connectors.put(name, connector);
- }
- return connector;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/package-info.java
----------------------------------------------------------------------
diff --git a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/package-info.java b/couchdb/src/main/java/org/eobjects/metamodel/couchdb/package-info.java
deleted file mode 100644
index 340fd98..0000000
--- a/couchdb/src/main/java/org/eobjects/metamodel/couchdb/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * 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 CouchDB support
- */
-package org.eobjects.metamodel.couchdb;
-
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/e2e2b37a/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
new file mode 100644
index 0000000..403a64c
--- /dev/null
+++ b/couchdb/src/test/java/org/apache/metamodel/couchdb/CouchDbDataContextTest.java
@@ -0,0 +1,354 @@
+/**
+ * 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.eobjects.metamodel.couchdb;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.ektorp.CouchDbConnector;
+import org.ektorp.DbAccessException;
+import org.ektorp.http.HttpClient;
+import org.ektorp.http.StdHttpClient;
+import org.ektorp.impl.StdCouchDbInstance;
+import org.eobjects.metamodel.UpdateCallback;
+import org.eobjects.metamodel.UpdateScript;
+import org.eobjects.metamodel.data.DataSet;
+import org.eobjects.metamodel.data.Row;
+import org.eobjects.metamodel.drop.DropTable;
+import org.eobjects.metamodel.insert.InsertInto;
+import org.eobjects.metamodel.schema.Column;
+import org.eobjects.metamodel.schema.ColumnType;
+import org.eobjects.metamodel.schema.Schema;
+import org.eobjects.metamodel.schema.Table;
+import org.eobjects.metamodel.util.SimpleTableDef;
+
+public class CouchDbDataContextTest extends TestCase {
+
+ private static final String TEST_DATABASE_NAME = "eobjects_metamodel_test";
+
+ private boolean serverAvailable;
+
+ private HttpClient httpClient;
+ private StdCouchDbInstance couchDbInstance;
+ private CouchDbConnector connector;
+ private SimpleTableDef predefinedTableDef;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ httpClient = new StdHttpClient.Builder().host("localhost").build();
+
+ // set up a simple database
+ couchDbInstance = new StdCouchDbInstance(httpClient);
+
+ try {
+ if (couchDbInstance.getAllDatabases().contains(TEST_DATABASE_NAME)) {
+ throw new IllegalStateException("Couch DB instance already has a database called " + TEST_DATABASE_NAME);
+ }
+ connector = couchDbInstance.createConnector(TEST_DATABASE_NAME, true);
+ System.out.println("Running CouchDB integration tests");
+ serverAvailable = true;
+ } catch (DbAccessException e) {
+ System.out.println("!!! WARNING: Skipping CouchDB tests because local server is not available");
+ e.printStackTrace();
+ serverAvailable = false;
+ }
+
+ final String[] columnNames = new String[] { "name", "gender", "age" };
+ final ColumnType[] columnTypes = new ColumnType[] { ColumnType.VARCHAR, ColumnType.CHAR, ColumnType.INTEGER };
+ predefinedTableDef = new SimpleTableDef(TEST_DATABASE_NAME, columnNames, columnTypes);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ connector = null;
+
+ if (serverAvailable) {
+ couchDbInstance.deleteDatabase(TEST_DATABASE_NAME);
+ }
+
+ httpClient.shutdown();
+ }
+
+ public void testWorkingWithMapsAndLists() throws Exception {
+ if (!serverAvailable) {
+ return;
+ }
+
+ connector = couchDbInstance.createConnector("test_table_map_and_list", true);
+
+ final CouchDbDataContext dc = new CouchDbDataContext(couchDbInstance, new SimpleTableDef("test_table_map_and_list",
+ new String[] { "id", "foo", "bar" }, new ColumnType[] { ColumnType.INTEGER, ColumnType.MAP, ColumnType.LIST }));
+ Table table = null;
+ try {
+ table = dc.getTableByQualifiedLabel("test_table_map_and_list");
+ Map<String, Object> exampleMap = new LinkedHashMap<String, Object>();
+ exampleMap.put("hello", Arrays.asList("world", "welt", "verden"));
+ exampleMap.put("foo", "bar");
+
+ List<Map<String, Object>> exampleList = new ArrayList<Map<String, Object>>();
+ exampleList.add(new LinkedHashMap<String, Object>());
+ Map<String, Object> exampleMap2 = new LinkedHashMap<String, Object>();
+ exampleMap2.put("meta", "model");
+ exampleMap2.put("couch", "db");
+ exampleList.add(exampleMap2);
+
+ dc.executeUpdate(new InsertInto(table).value("id", 1).value("foo", exampleMap).value("bar", exampleList));
+
+ DataSet ds = dc.query().from(table).select("id","foo","bar").execute();
+ assertTrue(ds.next());
+ Row row = ds.getRow();
+ assertFalse(ds.next());
+ ds.close();
+
+ assertEquals(
+ "Row[values=[1, {hello=[world, welt, verden], foo=bar}, [{}, {meta=model, couch=db}]]]",
+ row.toString());
+ assertTrue(row.getValue(0) instanceof Integer);
+ assertTrue(row.getValue(1) instanceof Map);
+ assertTrue(row.getValue(2) instanceof List);
+
+ } finally {
+ dc.executeUpdate(new DropTable(table));
+ }
+
+ }
+
+ public void testCreateUpdateDeleteScenario() throws Exception {
+ if (!serverAvailable) {
+ return;
+ }
+
+ final CouchDbDataContext dc = new CouchDbDataContext(couchDbInstance);
+
+ // first delete the manually created database!
+ dc.executeUpdate(new UpdateScript() {
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.dropTable(TEST_DATABASE_NAME).execute();
+ }
+ });
+
+ assertNull(dc.getDefaultSchema().getTableByName(TEST_DATABASE_NAME));
+
+ dc.executeUpdate(new UpdateScript() {
+ @Override
+ public void run(UpdateCallback callback) {
+ Table table = callback.createTable(dc.getDefaultSchema(), TEST_DATABASE_NAME).withColumn("foo")
+ .ofType(ColumnType.VARCHAR).withColumn("greeting").ofType(ColumnType.VARCHAR).execute();
+ assertEquals("[_id, _rev, foo, greeting]", Arrays.toString(table.getColumnNames()));
+ }
+ });
+
+ dc.executeUpdate(new UpdateScript() {
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.insertInto(TEST_DATABASE_NAME).value("foo", "bar").value("greeting", "hello").execute();
+ callback.insertInto(TEST_DATABASE_NAME).value("foo", "baz").value("greeting", "hi").execute();
+ }
+ });
+
+ DataSet ds = dc.query().from(TEST_DATABASE_NAME).select("_id", "foo", "greeting").execute();
+ assertTrue(ds.next());
+ assertNotNull(ds.getRow().getValue(0));
+ assertEquals("bar", ds.getRow().getValue(1));
+ assertEquals("hello", ds.getRow().getValue(2));
+ assertTrue(ds.next());
+ assertNotNull(ds.getRow().getValue(0));
+ assertEquals("baz", ds.getRow().getValue(1));
+ assertEquals("hi", ds.getRow().getValue(2));
+ assertFalse(ds.next());
+ ds.close();
+
+ dc.executeUpdate(new UpdateScript() {
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.update(TEST_DATABASE_NAME).value("greeting", "howdy").where("foo").isEquals("baz").execute();
+
+ callback.update(TEST_DATABASE_NAME).value("foo", "foo").where("foo").isEquals("bar").execute();
+ }
+ });
+
+ ds = dc.query().from(TEST_DATABASE_NAME).select("_id", "foo", "greeting").execute();
+ assertTrue(ds.next());
+ assertNotNull(ds.getRow().getValue(0));
+ assertEquals("foo", ds.getRow().getValue(1));
+ assertEquals("hello", ds.getRow().getValue(2));
+ assertTrue(ds.next());
+ assertNotNull(ds.getRow().getValue(0));
+ assertEquals("baz", ds.getRow().getValue(1));
+ assertEquals("howdy", ds.getRow().getValue(2));
+ assertFalse(ds.next());
+ ds.close();
+ }
+
+ public void testBasicQuery() throws Exception {
+ if (!serverAvailable) {
+ return;
+ }
+
+ // insert a few records
+ {
+ HashMap<String, Object> map;
+
+ map = new HashMap<String, Object>();
+ map.put("name", "John Doe");
+ map.put("age", 30);
+ connector.create(map);
+
+ map = new HashMap<String, Object>();
+ map.put("name", "Jane Doe");
+ map.put("gender", 'F');
+ connector.create(map);
+ }
+
+ // create datacontext using detected schema
+ SimpleTableDef tableDef = CouchDbDataContext.detectTable(connector);
+ CouchDbDataContext dc = new CouchDbDataContext(couchDbInstance, tableDef);
+
+ // verify schema and execute query
+ Schema schema = dc.getMainSchema();
+ assertEquals("[eobjects_metamodel_test]", Arrays.toString(schema.getTableNames()));
+
+ assertEquals("[_id, _rev, age, gender, name]",
+ Arrays.toString(schema.getTableByName(TEST_DATABASE_NAME).getColumnNames()));
+ Column idColumn = schema.getTableByName(TEST_DATABASE_NAME).getColumnByName("_id");
+ assertEquals("Column[name=_id,columnNumber=0,type=VARCHAR,nullable=true,nativeType=null,columnSize=null]",
+ idColumn.toString());
+ assertTrue(idColumn.isPrimaryKey());
+
+ assertEquals("Column[name=_rev,columnNumber=1,type=VARCHAR,nullable=true,nativeType=null,columnSize=null]", schema
+ .getTableByName(TEST_DATABASE_NAME).getColumnByName("_rev").toString());
+
+ DataSet ds;
+
+ ds = dc.query().from(TEST_DATABASE_NAME).select("name").and("age").execute();
+ assertTrue(ds.next());
+ assertEquals("Row[values=[John Doe, 30]]", ds.getRow().toString());
+ assertTrue(ds.next());
+ assertEquals("Row[values=[Jane Doe, null]]", ds.getRow().toString());
+ assertFalse(ds.next());
+ ds.close();
+
+ ds = dc.query().from(TEST_DATABASE_NAME).select("name").and("gender").where("age").isNull().execute();
+ assertTrue(ds.next());
+ assertEquals("Row[values=[Jane Doe, F]]", ds.getRow().toString());
+ assertFalse(ds.next());
+ ds.close();
+ }
+
+ public void testFirstRowAndLastRow() throws Exception {
+ if (!serverAvailable) {
+ return;
+ }
+
+ // insert a few records
+ {
+ HashMap<String, Object> map;
+
+ map = new HashMap<String, Object>();
+ map.put("name", "John Doe");
+ map.put("age", 30);
+ connector.create(map);
+
+ map = new HashMap<String, Object>();
+ map.put("name", "Jane Doe");
+ map.put("gender", 'F');
+ connector.create(map);
+ }
+
+ // create datacontext using detected schema
+ SimpleTableDef tableDef = CouchDbDataContext.detectTable(connector);
+ CouchDbDataContext dc = new CouchDbDataContext(couchDbInstance, tableDef);
+
+ DataSet ds1 = dc.query().from(TEST_DATABASE_NAME).select("name").and("age").firstRow(2).execute();
+ DataSet ds2 = dc.query().from(TEST_DATABASE_NAME).select("name").and("age").maxRows(1).execute();
+
+ assertTrue("Class: " + ds1.getClass().getName(), ds1 instanceof CouchDbDataSet);
+ assertTrue("Class: " + ds2.getClass().getName(), ds2 instanceof CouchDbDataSet);
+
+ assertTrue(ds1.next());
+ assertTrue(ds2.next());
+
+ final Row row1 = ds1.getRow();
+ final Row row2 = ds2.getRow();
+
+ assertFalse(ds1.next());
+ assertFalse(ds2.next());
+
+ assertEquals("Row[values=[Jane Doe, null]]", row1.toString());
+ assertEquals("Row[values=[John Doe, 30]]", row2.toString());
+
+ ds1.close();
+ ds2.close();
+ }
+
+ public void testInsert() throws Exception {
+ if (!serverAvailable) {
+ return;
+ }
+
+ // create datacontext using predefined table def
+ CouchDbDataContext dc = new CouchDbDataContext(httpClient, predefinedTableDef);
+ Table table = dc.getTableByQualifiedLabel(TEST_DATABASE_NAME);
+ assertNotNull(table);
+
+ assertEquals("[_id, _rev, name, gender, age]", Arrays.toString(table.getColumnNames()));
+
+ DataSet ds;
+
+ // assert not rows in DB
+ ds = dc.query().from(TEST_DATABASE_NAME).selectCount().execute();
+ assertTrue(ds.next());
+ assertEquals(0, ((Number) ds.getRow().getValue(0)).intValue());
+ assertFalse(ds.next());
+ ds.close();
+
+ dc.executeUpdate(new UpdateScript() {
+ @Override
+ public void run(UpdateCallback callback) {
+ callback.insertInto(TEST_DATABASE_NAME).value("name", "foo").value("gender", 'M').execute();
+ callback.insertInto(TEST_DATABASE_NAME).value("name", "bar").value("age", 32).execute();
+ }
+ });
+
+ // now count should be 2
+ ds = dc.query().from(TEST_DATABASE_NAME).selectCount().execute();
+ assertTrue(ds.next());
+ assertEquals(2, ((Number) ds.getRow().getValue(0)).intValue());
+ assertFalse(ds.next());
+ ds.close();
+
+ ds = dc.query().from(TEST_DATABASE_NAME).select("name", "gender", "age").execute();
+ assertTrue(ds.next());
+ assertEquals("Row[values=[foo, M, null]]", ds.getRow().toString());
+ assertTrue(ds.next());
+ assertEquals("Row[values=[bar, null, 32]]", ds.getRow().toString());
+ assertFalse(ds.next());
+ ds.close();
+ }
+}