From 7b6d3c277ac17ec52e579555bb7c43ee666798b9 Mon Sep 17 00:00:00 2001 From: pedro Date: Fri, 21 May 2010 18:20:13 +0100 Subject: [PATCH] datanucleus cassandra now supports maps. --- .../cassandra/CassandraFetchFieldManager.java | 55 +++++++++++++- .../CassandraInsertFieldManager.java | 74 ++++++++++++++++++- 2 files changed, 124 insertions(+), 5 deletions(-) diff --git a/src/org/datanucleus/store/cassandra/CassandraFetchFieldManager.java b/src/org/datanucleus/store/cassandra/CassandraFetchFieldManager.java index 9c80157..4a78ea5 100644 --- a/src/org/datanucleus/store/cassandra/CassandraFetchFieldManager.java +++ b/src/org/datanucleus/store/cassandra/CassandraFetchFieldManager.java @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. -**********************************************************************/ + **********************************************************************/ package org.datanucleus.store.cassandra; @@ -22,13 +22,16 @@ import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; - import org.apache.cassandra.thrift.ColumnOrSuperColumn; import org.datanucleus.ClassLoaderResolver; +import org.datanucleus.StateManager; +import org.datanucleus.api.ApiAdapter; import org.datanucleus.exceptions.NucleusException; import org.datanucleus.metadata.AbstractClassMetaData; import org.datanucleus.metadata.AbstractMemberMetaData; @@ -257,11 +260,13 @@ public Object fetchObjectField(int fieldNumber) { || relationType == Relation.ONE_TO_MANY_UNI) { MetaDataManager mmgr = context.getMetaDataManager(); - String elementClassName = fieldMetaData.getCollection() - .getElementClassMetaData(clr, mmgr).getFullClassName(); + if (fieldMetaData.hasCollection()) { + String elementClassName = fieldMetaData.getCollection().getElementType(); + + List mapping = (List) value; Collection collection = new ArrayList(); for (Object id : mapping) { @@ -272,6 +277,48 @@ public Object fetchObjectField(int fieldNumber) { } value = collection; } + + else if (fieldMetaData.hasMap()) { + // Process all keys, values of the Map that are PC + + String key_elementClassName = fieldMetaData.getMap().getKeyType(); + String value_elementClassName = fieldMetaData.getMap().getValueType(); + + Map mapping = new TreeMap(); + + Map map = (Map) value; + ApiAdapter api = context.getApiAdapter(); + + Set keys = map.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) { + Object mapKey = iter.next(); + Object key = null; + + if (mapKey instanceof javax.jdo.identity.SingleFieldIdentity) { + key = context.findObject(mapKey, true, false, + key_elementClassName); + + } else { + key = mapKey; + } + + Object mapValue = map.get(key); + Object key_value = null; + + if (mapValue instanceof javax.jdo.identity.SingleFieldIdentity) { + + key_value = context.findObject(mapValue, true, false, + value_elementClassName); + } else { + key_value = mapValue; + } + + mapping.put(key, key_value); + } + + value = mapping; + } } return value; diff --git a/src/org/datanucleus/store/cassandra/CassandraInsertFieldManager.java b/src/org/datanucleus/store/cassandra/CassandraInsertFieldManager.java index c256a15..74feda0 100644 --- a/src/org/datanucleus/store/cassandra/CassandraInsertFieldManager.java +++ b/src/org/datanucleus/store/cassandra/CassandraInsertFieldManager.java @@ -22,8 +22,10 @@ import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import org.apache.cassandra.thrift.Column; @@ -33,14 +35,18 @@ import org.apache.cassandra.thrift.SlicePredicate; import org.datanucleus.ClassLoaderResolver; import org.datanucleus.StateManager; +import org.datanucleus.api.ApiAdapter; import org.datanucleus.exceptions.NucleusException; import org.datanucleus.metadata.AbstractClassMetaData; import org.datanucleus.metadata.AbstractMemberMetaData; +import org.datanucleus.metadata.MapMetaData; +import org.datanucleus.metadata.MetaDataManager; import org.datanucleus.metadata.Relation; import org.datanucleus.store.ExecutionContext; import org.datanucleus.store.ObjectProvider; import org.datanucleus.store.fieldmanager.AbstractFieldManager; + //TODO isolate cassandra operations... public class CassandraInsertFieldManager extends AbstractFieldManager { @@ -342,7 +348,8 @@ public void storeObjectField(int fieldNumber, Object value) { List mapping = new ArrayList(); - for (Object c : (Collection) value) { + for (Object c : (Collection) value) { + Object persisted = context.persistObjectInternal(c, objectProvider, -1, StateManager.PC); Object valueId = context.getApiAdapter() @@ -370,9 +377,74 @@ public void storeObjectField(int fieldNumber, Object value) { throw new NucleusException(e.getMessage(), e); } } + else if (value instanceof Map) + { + // Process all keys, values of the Map that are PC + + Map mapping = new TreeMap(); + + Map map = (Map)value; + ApiAdapter api = context.getApiAdapter(); + Set keys = map.keySet(); + Iterator iter = keys.iterator(); + while (iter.hasNext()) + { + Object mapKey = iter.next(); + Object key = null; + + if (api.isPersistable(mapKey)) + { + Object persisted = context.persistObjectInternal(mapKey, + objectProvider, -1, StateManager.PC); + key = context.getApiAdapter().getIdForObject(persisted); + } + else{ + key = mapKey; + } + + Object mapValue = map.get(key); + Object key_value = null; + + if (api.isPersistable(mapValue)) + { + + Object persisted = context.persistObjectInternal(mapValue, + objectProvider, -1, StateManager.PC); + key_value = context.getApiAdapter().getIdForObject(persisted); + } + else{ + key_value = mapValue; + } + + mapping.put(key, key_value); + + } + + try { + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(mapping); + + Mutation mutation = new Mutation(); + ColumnOrSuperColumn columnOrSuperColumn = new ColumnOrSuperColumn(); + Column column = new Column(columnName.getBytes(), bos + .toByteArray(), System.currentTimeMillis()); + columnOrSuperColumn.setColumn(column); + mutation.setColumn_or_supercolumn(columnOrSuperColumn); + mutations.add(mutation); + + oos.close(); + bos.close(); + } catch (IOException e) { + throw new NucleusException(e.getMessage(), e); + } + } return; } + //normal object; + try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos);