Skip to content

Commit

Permalink
managed nested embedded collection dirty support
Browse files Browse the repository at this point in the history
  • Loading branch information
tglman committed Aug 11, 2015
1 parent 31fe5c1 commit fce6786
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 59 deletions.
@@ -1,22 +1,22 @@
/*
*
* * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
* *
* * Licensed 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.
* *
* * For more information: http://www.orientechnologies.com
*
*/
*
* * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
* *
* * Licensed 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.
* *
* * For more information: http://www.orientechnologies.com
*
*/
package com.orientechnologies.orient.core.db.record;

import java.io.Serializable;
Expand All @@ -30,6 +30,7 @@

import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.record.ORecordInternal;
import com.orientechnologies.orient.core.record.impl.ODirtyManager;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.record.impl.ODocumentInternal;

Expand Down Expand Up @@ -115,8 +116,10 @@ public T set(int index, T element) {
}

private void addOwnerToEmbeddedDoc(T e) {
if (embeddedCollection && e instanceof ODocument && !((ODocument) e).getIdentity().isValid())
if (embeddedCollection && e instanceof ODocument && !((ODocument) e).getIdentity().isValid()) {
ODocumentInternal.addOwner((ODocument) e, this);
ORecordInternal.track(sourceRecord, (ODocument) e);
}
}

@Override
Expand All @@ -140,16 +143,16 @@ public boolean remove(Object o) {
return false;
}

@Override
public boolean removeAll(Collection<?> c) {
boolean removed = false;
for (Object o : c)
removed = removed | remove(o);
@Override
public boolean removeAll(Collection<?> c) {
boolean removed = false;
for (Object o : c)
removed = removed | remove(o);

return removed;
}
return removed;
}

@Override
@Override
public void clear() {
final List<T> origValues;
if (changeListeners.isEmpty())
Expand Down
@@ -1,22 +1,22 @@
/*
*
* * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
* *
* * Licensed 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.
* *
* * For more information: http://www.orientechnologies.com
*
*/
*
* * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
* *
* * Licensed 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.
* *
* * For more information: http://www.orientechnologies.com
*
*/
package com.orientechnologies.orient.core.db.record;

import java.io.Serializable;
Expand Down Expand Up @@ -157,7 +157,7 @@ public void setDirtyNoChanged() {
sourceRecord.setDirtyNoChanged();
}

public STATUS getInternalStatus() {
public STATUS getInternalStatus() {
return status;
}

Expand Down Expand Up @@ -216,8 +216,10 @@ protected void fireCollectionChangedEvent(final OMultiValueChangeEvent<T, T> eve
}

private void addOwnerToEmbeddedDoc(T e) {
if (embeddedCollection && e instanceof ODocument && !((ODocument) e).getIdentity().isValid())
if (embeddedCollection && e instanceof ODocument && !((ODocument) e).getIdentity().isValid()) {
ODocumentInternal.addOwner((ODocument) e, this);
ORecordInternal.track(sourceRecord, (ODocument) e);
}
}

private Object writeReplace() {
Expand Down
Expand Up @@ -148,4 +148,9 @@ public List<OIdentifiable> getPointed(ORecord rec) {
return null;
return references.get(rec);
}

public void removeNew(ODocument oDocument) {
if (this.newRecord != null)
this.newRecord.remove(oDocument);
}
}
Expand Up @@ -2261,8 +2261,11 @@ protected byte getRecordType() {
* Internal.
*/
protected void addOwner(final ORecordElement iOwner) {
if (_owners == null)
if (_owners == null) {
_owners = new ArrayList<WeakReference<ORecordElement>>();
if (_dirtyManager != null && this.getIdentity().isNew())
_dirtyManager.removeNew(this);
}

boolean found = false;
for (WeakReference<ORecordElement> _owner : _owners) {
Expand Down Expand Up @@ -2303,12 +2306,17 @@ protected void convertAllMultiValuesToTrackedVersions() {

for (Map.Entry<String, ODocumentEntry> fieldEntry : _fields.entrySet()) {
final Object fieldValue = fieldEntry.getValue().value;
if (!(fieldValue instanceof Collection<?>) && !(fieldValue instanceof Map<?, ?>))
if (!(fieldValue instanceof Collection<?>) && !(fieldValue instanceof Map<?, ?>) && !(fieldValue instanceof ODocument))
continue;
if (addCollectionChangeListener(fieldEntry.getValue())) {
continue;
}

if (fieldValue instanceof ODocument && fieldValue != this) {
((ODocument) fieldValue).convertAllMultiValuesToTrackedVersions();
continue;
}

OType fieldType = fieldEntry.getValue().type;
if (fieldType == null) {
OClass _clazz = getImmutableSchemaClass();
Expand Down Expand Up @@ -2354,6 +2362,12 @@ protected void convertAllMultiValuesToTrackedVersions() {
addCollectionChangeListener(fieldEntry.getValue());
fieldEntry.getValue().value = newValue;
}
if (fieldType.equals(OType.EMBEDDEDLIST) || fieldType.equals(OType.EMBEDDEDSET)) {
for (Object cur : (Collection<Object>) newValue) {
if (cur instanceof ODocument)
((ODocument) cur).convertAllMultiValuesToTrackedVersions();
}
}
}

}
Expand Down
Expand Up @@ -25,15 +25,15 @@ public ODirtyManagerTest() {
}

@Test
public void testBasicDirtyTracking() {
public void testBasic() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
ODirtyManager manager = ORecordInternal.getDirtyManager(doc);
assertEquals(1, manager.getNewRecord().size());
}

@Test
public void testEmbeddedDirtyTracking() {
public void testEmbeddedDocument() {
ODocument doc = new ODocument();
ODocument doc1 = new ODocument();
doc.field("test", doc1, OType.EMBEDDED);
Expand All @@ -46,7 +46,7 @@ public void testEmbeddedDirtyTracking() {
}

@Test
public void testRefDirtyTracking() {
public void testLink() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
ODocument doc2 = new ODocument();
Expand All @@ -58,7 +58,7 @@ public void testRefDirtyTracking() {
}

@Test
public void testRefDirtyTrackingOther() {
public void testLinkOther() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
ODocument doc1 = new ODocument();
Expand All @@ -70,7 +70,7 @@ public void testRefDirtyTrackingOther() {
}

@Test
public void testCollextionRefDirtyTracking() {
public void testLinkCollection() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
List<ODocument> lst = new ArrayList<ODocument>();
Expand All @@ -92,7 +92,7 @@ public void testCollextionRefDirtyTracking() {
}

@Test
public void testCollectionRefDirtyTrackingOther() {
public void testLinkCollectionOther() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
List<ODocument> lst = new ArrayList<ODocument>();
Expand All @@ -111,7 +111,7 @@ public void testCollectionRefDirtyTrackingOther() {
}

@Test
public void testMapRefDirtyTrackingOther() {
public void testLinkMapOther() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
Map<String, ODocument> map = new HashMap<String, ODocument>();
Expand All @@ -126,38 +126,44 @@ public void testMapRefDirtyTrackingOther() {
}

@Test
public void testEmbeddedMapDirtyTrackingOther() {
public void testEmbeddedMap() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
Map<String, Object> map = new HashMap<String, Object>();

ODocument doc1 = new ODocument();
map.put("bla", "bla");
map.put("some", doc1);

doc.field("list", map, OType.EMBEDDEDMAP);

ODocumentInternal.convertAllMultiValuesToTrackedVersions(doc);
ODirtyManager manager = ORecordInternal.getDirtyManager(doc);
assertEquals(1, manager.getNewRecord().size());
}

@Test
public void testEmbeddedCollectionDirtyTrackingOther() {
public void testEmbeddedCollection() {
ODocument doc = new ODocument();
doc.field("test", "ddd");

List<ODocument> lst = new ArrayList<ODocument>();
ODocument doc1 = new ODocument();
lst.add(doc1);
doc.field("list", lst, OType.EMBEDDEDLIST);

Set<ODocument> set = new HashSet<ODocument>();
ODocument doc2 = new ODocument();
set.add(doc2);
doc.field("set", set, OType.EMBEDDEDSET);

ODocumentInternal.convertAllMultiValuesToTrackedVersions(doc);
ODirtyManager manager = ORecordInternal.getDirtyManager(doc);
assertEquals(1, manager.getNewRecord().size());
}

@Test
public void testRidBagRefTrackingOther() {
public void testRidBagOther() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
ORidBag bag = new ORidBag();
Expand All @@ -169,4 +175,49 @@ public void testRidBagRefTrackingOther() {
assertEquals(2, manager.getNewRecord().size());
}

@Test
public void testEmbendedWithEmbeddedCollection() {
ODocument doc = new ODocument();
doc.field("test", "ddd");

ODocument emb = new ODocument();
doc.field("emb", emb, OType.EMBEDDED);

ODocument embedInList = new ODocument();
List<ODocument> lst = new ArrayList<ODocument>();
lst.add(embedInList);
emb.field("lst", lst, OType.EMBEDDEDLIST);
ODocument link = new ODocument();
embedInList.field("set", link);
ODocumentInternal.convertAllMultiValuesToTrackedVersions(doc);
ODirtyManager manager = ORecordInternal.getDirtyManager(doc);

assertEquals(2, manager.getNewRecord().size());
assertEquals(1, manager.getPointed(doc).size());
assertTrue(manager.getPointed(doc).contains(link));
}

@Test
public void testDoubleLevelEmbeddedCollection() {
ODocument doc = new ODocument();
doc.field("test", "ddd");
List<ODocument> lst = new ArrayList<ODocument>();
ODocument embeddedInList = new ODocument();
ODocument link = new ODocument();
embeddedInList.field("link", link);
lst.add(embeddedInList);
Set<ODocument> set = new HashSet<ODocument>();
ODocument embeddedInSet = new ODocument();
embeddedInSet.field("list", lst, OType.EMBEDDEDLIST);
set.add(embeddedInSet);
doc.field("set", set, OType.EMBEDDEDSET);
ODocumentInternal.convertAllMultiValuesToTrackedVersions(doc);
ODirtyManager manager = ORecordInternal.getDirtyManager(doc);
ODirtyManager managerNested = ORecordInternal.getDirtyManager(embeddedInSet);
assertTrue(manager.isSame(managerNested));
assertEquals(2, manager.getNewRecord().size());
assertEquals(1, manager.getPointed(doc).size());
assertTrue(manager.getPointed(doc).contains(link));
}

}

0 comments on commit fce6786

Please sign in to comment.