Permalink
Browse files

Fixed offset to work with new skip lists

  • Loading branch information...
1 parent b5f1fd5 commit 6c29bb9ade1c878da1a236f2a84f009bfbe70918 @nathansobo committed Jan 4, 2011
@@ -4,11 +4,13 @@ _.constructor("Monarch.Model.Relations.Offset", Monarch.Model.Relations.Relation
initialize: function(operand, n) {
this.operand = operand;
this.n = n;
+ this.sortSpecifications = operand.sortSpecifications;
this.initializeEventsSystem();
},
- allTuples: function() {
- return this.operand.allTuples().slice(this.n);
+ tuples: function() {
+ if (this.storedTuples) return this.storedTuples.values();
+ return this.operand.tuples().slice(this.n);
},
wireRepresentation: function() {
@@ -19,44 +21,48 @@ _.constructor("Monarch.Model.Relations.Offset", Monarch.Model.Relations.Relation
};
},
- subscribeToOperands: function() {
- this.operandsSubscriptionBundle.add(this.operand.onRemoteInsert(function(record, index) {
- if (index < this.n) {
- var nthTuple = this.operand.at(this.n);
- if (nthTuple) this.tupleInsertedRemotely(nthTuple, 0);
- } else {
- this.tupleInsertedRemotely(record, index - this.n);
- }
- }, this));
-
- this.operandsSubscriptionBundle.add(this.operand.onRemoteUpdate(function(record, changeset, newIndex, oldIndex) {
- if (oldIndex < this.n) {
- if (newIndex >= this.n) {
- this.tupleRemovedRemotely(this.operand.at(this.n - 1), 0);
- this.tupleInsertedRemotely(record, newIndex - this.n);
- }
- } else {
- if (newIndex < this.n) {
- this.tupleRemovedRemotely(record, oldIndex - this.n);
- this.tupleInsertedRemotely(this.operand.at(this.n), 0);
- } else {
- this.tupleUpdatedRemotely(record, changeset, newIndex - this.n, oldIndex - this.n);
- }
- }
- }, this));
+ isEqual: function(other) {
+ if (!other || other.constructor !== this.constructor) return false;
+ return other.n === this.n && this.operand.isEqual(other.operand);
+ },
+
+ // private
+
+ onOperandInsert: function(tuple, index, newKey, oldKey) {
+ if (index < this.n) {
+ var nthTuple = this.operand.at(this.n);
+ if (nthTuple) this.tupleInsertedRemotely(nthTuple);
+ } else {
+ this.tupleInsertedRemotely(tuple, newKey, oldKey);
+ }
+ },
+
+ onOperandUpdate: function(tuple, changeset, newIndex, oldIndex, newKey, oldKey) {
- this.operandsSubscriptionBundle.add(this.operand.onRemoteRemove(function(record, index) {
- if (index < this.n) {
- var formerNthTuple = this.operand.at(this.n - 1);
- if (formerNthTuple) this.tupleRemovedRemotely(formerNthTuple, 0);
+ if (oldIndex < this.n) {
+ if (newIndex >= this.n) {
+ this.tupleRemovedRemotely(this.at(0));
+ this.tupleInsertedRemotely(tuple, newKey, oldKey);
+ }
+ } else {
+ if (newIndex < this.n) {
+ this.tupleRemovedRemotely(tuple, newKey, oldKey);
+ this.tupleInsertedRemotely(this.operand.at(this.n));
} else {
- this.tupleRemovedRemotely(record, index - this.n);
+ this.tupleUpdatedRemotely(tuple, changeset, newKey, oldKey)
}
- }, this));
- }
-
+ }
+ },
+ onOperandRemove: function(tuple, index, newKey, oldKey) {
+ if (index < this.n) {
+ var formerNthTuple = this.at(0);
+ if (formerNthTuple) this.tupleRemovedRemotely(formerNthTuple);
+ } else {
+ this.tupleRemovedRemotely(tuple, newKey, oldKey);
+ }
+ }
});
})(Monarch);
@@ -40,6 +40,11 @@ _.constructor("Monarch.Model.Relations.Ordering", Monarch.Model.Relations.Relati
return this.operand.column(name);
},
+ isEqual: function(other) {
+ if (other.constructor !== this.constructor) return false;
+ return _.isEqual(this.sortSpecifications, other.sortSpecifications) && this.operand.isEqual(other.operand);
+ },
+
// private
onOperandInsert: function(tuple) {
@@ -100,6 +100,10 @@ _.constructor("Monarch.Model.Relations.Relation", {
return new Monarch.Model.Relations.Union(this, rightOperand);
},
+ offset: function(n) {
+ return new Monarch.Model.Relations.Offset(this, n);
+ },
+
dirtyTuples: function() {
return _.filter(this.tuples(), function(record) {
return record.dirty();
@@ -153,7 +157,11 @@ _.constructor("Monarch.Model.Relations.Relation", {
},
at: function(i) {
- return this.tuples()[i];
+ if (this.storedTuples) {
+ return this.storedTuples.at(i);
+ } else {
+ return this.tuples()[i];
+ }
},
onInsert: function(callback, context) {
@@ -7,6 +7,11 @@ _.constructor("Monarch.Model.SortSpecification", {
this.qualifiedColumnName = column.qualifiedName;
this.direction = direction;
this.directionCoefficient = (direction == "desc") ? -1 : 1;
+ },
+
+ isEqual: function(other) {
+ if (this.constructor !== other.constructor) return false;
+ return this.column.isEqual(other.column) && this.direction === other.direction;
}
});
@@ -12,14 +12,14 @@ Screw.Unit(function(c) { with(c) {
});
- describe("#allTuples()", function() {
- it("returns all tuples from the #operand with an index beyond the #offset", function() {
+ describe("#tuples()", function() {
+ it("returns all tuples from the operand that have an index beyond n", function() {
BlogPost.createFromRemote({id: 1});
BlogPost.createFromRemote({id: 2});
var post3 = BlogPost.createFromRemote({id: 3});
var post4 = BlogPost.createFromRemote({id: 4});
- expect(offset.allTuples()).to(equal, [post3, post4]);
+ expect(offset.tuples()).to(equal, [post3, post4]);
});
});
@@ -33,22 +33,13 @@ Screw.Unit(function(c) { with(c) {
});
});
- describe("#hasSubscribers()", function() {
- it("returns true if a callback has been registered", function() {
- var subscription = offset.onRemoteInsert(function(){});
- expect(offset.hasSubscribers()).to(beTrue);
- subscription.destroy();
- expect(offset.hasSubscribers()).to(beFalse);
-
- subscription = offset.onRemoteUpdate(function(){});
- expect(offset.hasSubscribers()).to(beTrue);
- subscription.destroy();
- expect(offset.hasSubscribers()).to(beFalse);
-
- subscription = offset.onRemoteRemove(function(){});
- expect(offset.hasSubscribers()).to(beTrue);
- subscription.destroy();
- expect(offset.hasSubscribers()).to(beFalse);
+ describe("#isEqual", function() {
+ it("returns true for only for semantically equivalent relations", function() {
+ expect(offset.isEqual(operand.offset(2))).to(beTrue);
+ expect(offset.isEqual(operand.offset(3))).to(beFalse);
+ expect(offset.isEqual(operand)).to(beFalse);
+ expect(offset.isEqual(1)).to(beFalse);
+ expect(offset.isEqual(null)).to(beFalse);
});
});
@@ -63,24 +54,32 @@ Screw.Unit(function(c) { with(c) {
insertCallback = mockFunction("insert callback", function(record) {
expect(offset.contains(record)).to(beTrue);
});
- offset.onRemoteInsert(insertCallback);
+ offset.onInsert(insertCallback);
removeCallback = mockFunction("remove callback", function(record) {
expect(offset.contains(record)).to(beFalse);
});
- offset.onRemoteRemove(removeCallback);
+ offset.onRemove(removeCallback);
updateCallback = mockFunction("update callback");
- offset.onRemoteUpdate(updateCallback);
+ offset.onUpdate(updateCallback);
});
+ function clearCallbackMocks() {
+ insertCallback.clear();
+ updateCallback.clear();
+ removeCallback.clear();
+ }
+
describe("when a record is inserted into operand remotely", function() {
- describe("when the record's index is less than n", function() {
+ describe("when the inserted record's index is less than n", function() {
describe("when the operand has n or more records", function() {
it("fires an insert event with the record whose index is now n", function() {
BlogPost.createFromRemote({id: 0});
- expect(insertCallback).to(haveBeenCalled, withArgs(post2, 0));
+
+ var sortKey = BlogPost.table.buildSortKey(post2);
+ expect(insertCallback).to(haveBeenCalled, withArgs(post2, 0, sortKey, sortKey));
});
});
@@ -90,16 +89,19 @@ Screw.Unit(function(c) { with(c) {
post3.remotelyDestroyed();
post4.remotelyDestroyed();
+ clearCallbackMocks();
+
BlogPost.createFromRemote({id: 2});
expect(insertCallback).toNot(haveBeenCalled);
});
});
});
- describe("when the record's index is greater than n", function() {
+ describe("when the inserted record's index is greater than n", function() {
it("fires an insert event with the inserted record", function() {
var record = BlogPost.createFromRemote({id: 5});
- expect(insertCallback).to(haveBeenCalled, withArgs(record, 2));
+ var sortKey = BlogPost.table.buildSortKey(record);
+ expect(insertCallback).to(haveBeenCalled, withArgs(record, 2, sortKey, sortKey));
});
});
});
@@ -109,8 +111,8 @@ Screw.Unit(function(c) { with(c) {
describe("when the updated record's index is >= n after the update", function() {
it("fires an insert event for the updated record and a remove event for the record whose index was n and is now n - 1", function() {
post1.remotelyUpdated({id: 3.5});
- expect(removeCallback).to(haveBeenCalled, withArgs(post3, 0));
- expect(insertCallback).to(haveBeenCalled, withArgs(post1, 0));
+ expect(removeCallback).to(haveBeenCalled, withArgs(post3, 0, {'blog_posts.id': 3}, {'blog_posts.id': 3}));
+ expect(insertCallback).to(haveBeenCalled, withArgs(post1, 0, {'blog_posts.id': 3.5}, {'blog_posts.id': 1}));
});
});
@@ -128,8 +130,8 @@ Screw.Unit(function(c) { with(c) {
describe("when the record's index is < n after the update", function() {
it("fires a remove event for the updated record and an insert event for the record whose index was n - 1 and is now n", function() {
post4.remotelyUpdated({id: 1.5});
- expect(insertCallback).to(haveBeenCalled, withArgs(post2, 0));
- expect(removeCallback).to(haveBeenCalled, withArgs(post4, 1));
+ expect(removeCallback).to(haveBeenCalled, withArgs(post4, 1, {'blog_posts.id': 1.5}, {'blog_posts.id': 4}));
+ expect(insertCallback).to(haveBeenCalled, withArgs(post2, 0, {'blog_posts.id': 2}, {'blog_posts.id': 2}));
});
});
@@ -147,11 +149,12 @@ Screw.Unit(function(c) { with(c) {
});
describe("when a record is removed from the operand", function() {
- describe("when the removed record's index is < n>", function() {
+ describe("when the removed record's index is < n", function() {
describe("when there are more than n records in the operand", function() {
- it("fires a remove event for the former first record in the offset", function() {
+ it("fires a remove event for the former first record in the offset that now has an index of n - 1", function() {
post2.remotelyDestroyed();
- expect(removeCallback).to(haveBeenCalled, withArgs(post3, 0));
+ var sortKey = offset.buildSortKey(post3);
+ expect(removeCallback).to(haveBeenCalled, withArgs(post3, 0, sortKey, sortKey));
});
});
@@ -160,7 +163,7 @@ Screw.Unit(function(c) { with(c) {
post3.remotelyDestroyed();
post4.remotelyDestroyed();
- removeCallback.clear();
+ clearCallbackMocks();
post1.remotelyDestroyed();
expect(removeCallback).toNot(haveBeenCalled);
@@ -171,19 +174,12 @@ Screw.Unit(function(c) { with(c) {
describe("when the removed record's index is >= n", function() {
it("fires a remove event for the removed record", function() {
+ var sortKey = offset.buildSortKey(post4);
post4.remotelyDestroyed();
- expect(removeCallback).to(haveBeenCalled, withArgs(post4, 1));
+ expect(removeCallback).to(haveBeenCalled, withArgs(post4, 1, sortKey, sortKey));
});
});
});
});
-
- describe("subscription propagation", function() {
-
- });
-
- describe("#isEqual", function() {
-
- });
});
}});

0 comments on commit 6c29bb9

Please sign in to comment.