Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

168.updatechange #178

Merged
merged 8 commits into from

2 participants

@alexgraul
Owner

Ready to be merged in.

src/dataset.js
((47 lines not shown))
- // check if we're trying to update a computed column. If so
- // fail.
- if (c.isComputed()) {
+ if (typeof column === "undefined") {
+ throw "column " + prop + " not found!";
+ }
+
+ //Ensure value passes the type test
+ if (!type.test(value, column)) {
throw "You're trying to update a computed column. Those get computed!";
@iros Owner
iros added a note

This is the wrong error. We are checking type compatibility, not the fact it's a computed column.

@iros Owner
iros added a note

We need to add a check to make sure we're not updating a computed column.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
src/dataset.js
((128 lines not shown))
- // do we just have a single id? array it up.
- if (_.isString(filter)) {
- filter = [filter];
+ _functionUpdate : function(func) {
+ var rows = [];
+ for(var i = 0; i < this.length; i++) {
+ rows.push( func(this.rowByPosition(i)) );
@iros Owner
iros added a note

Can't we just use .where(func) here?

@alexgraul Owner

Not following.

@iros Owner
iros added a note

I think I was confused for a second. You're right. This is not relevant. I forgot we changed the API so that the function doesn't just pick rows, but rather alter them.
Quick question though - in the ticket, I had specified that it returns false if the row should not be changed. I see this is no longer true in that all rows get queued up for an update. Do we still feel like that makes sense?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
test/unit/core.js
@@ -1,274 +1,274 @@
-(function(global) {
@iros Owner
iros added a note

Why is this entire file commented out?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
test/unit/derived.js
((7 lines not shown))
state : "MN"
});
+ console.log(groupedData.column("_oids").data);
@iros Owner
iros added a note

Remove console.log call.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
test/unit/importers.js
@@ -665,7 +665,6 @@
test("Polling with unique constraint for updates", function() {
stop();
- // expect(11);
@iros Owner
iros added a note

Why is this commented out?

@alexgraul Owner

I don't think I commented that out, I think it already was.

@iros Owner
iros added a note

What about the verifyEvents() below?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
test/unit/products.js
@@ -310,12 +310,14 @@
var meantime = ds.mean("t");
equals(meantime.val().format("YYYYMMDD"), moment("2010/01/15").format("YYYYMMDD"));
+ console.log('mtold', meantime.val());
@iros Owner
iros added a note

Remove console.log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
test/unit/products.js
((5 lines not shown))
meantime.bind("change", function() {
+ console.log('mt', meantime.val());
@iros Owner
iros added a note

Remove console.log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
test/unit/dataset.js
@@ -432,11 +442,13 @@
stop();
ds.bind("change", function(event) {
+ console.log('ev', event.deltas[0]);
@iros Owner
iros added a note

Remove console.log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@iros iros merged commit 08d1b33 into master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
168 src/dataset.js
@@ -200,7 +200,6 @@ Version 0.0.1.2
//Update existing values, used the pass column to match
//incoming data to existing rows.
againstColumn : function(data) {
-
var rows = [],
colNames = _.keys(data),
row,
@@ -222,8 +221,8 @@ Version 0.0.1.2
toAdd.push( row );
} else {
toUpdate.push( row );
- var oldRow = this.rowById(this.column(this.idAttribute).data[rowIndex])[this.idAttribute];
- this.update(oldRow, row);
+ row[this.idAttribute] = this.rowById(this.column(this.idAttribute).data[rowIndex])[this.idAttribute];
+ this.update(row);
}
}, this);
if (toAdd.length > 0) {
@@ -494,114 +493,101 @@ Version 0.0.1.2
}
},
- /**
- * Update all rows that match the filter. Fires update and change.
- * Parameters:
- * filter - row id OR filter rows to be updated
- * newProperties - values to be updated.
- * options - options. Optional
- * silent - set to true to prevent event triggering..
- */
- update : function(filter, newProperties, options) {
-
- var newKeys, deltas = [];
+ _arrayUpdate : function(rows) {
+ var deltas = [];
+ _.each(rows, function(newRow) {
+ var delta = { old : {}, changed : {} };
+ delta[this.idAttribute] = newRow[this.idAttribute];
- var updateRow = _.bind(function(row, rowIndex) {
- var c, props;
+ var pos = this._rowPositionById[newRow[this.idAttribute]];
+ _.each(newRow, function(value, prop) {
+ var column = this._columns[this._columnPositionByName[prop]];
+ var type = Dataset.types[column.type];
- if (_.isFunction(newProperties)) {
- props = newProperties.apply(this, [row]);
- } else {
- props = newProperties;
- }
+ if ((column.name === this.idAttribute) && (column.data[pos] !== value)) {
+ throw "You can't update the id column";
+ }
- newKeys = _.keys(props);
+ if (typeof column === "undefined") {
+ throw "column " + prop + " not found!";
+ }
- _.each(newKeys, function(columnName) {
+ //Ensure value passes the type test
+ if (!type.test(value, column)) {
+ throw "Value is incorrect type";
+ }
- // check that we aren't trying to update the id column
- if (columnName === this.idAttribute) {
- throw "You can't update the id column";
+ //skip if computed column
+ if (this._computedColumns[column.name]) {
+ return;
}
-
- c = this.column(columnName);
- // check if we're trying to update a computed column. If so
- // fail.
- if (c.isComputed()) {
- throw "You're trying to update a computed column. Those get computed!";
+ value = type.coerce(value, column);
+
+ //Run any before filters on the column
+ if (!_.isUndefined(column.before)) {
+ value = column.before(value);
+ }
+
+ if (column.data[pos] !== value) {
+ delta.old[prop] = column.data[pos];
+ column.data[pos] = value;
+ delta.changed[prop] = value;
}
- // test if the value passes the type test
- var Type = Dataset.types[c.type];
-
- if (Type) {
- if (Type.test(props[c.name], c)) {
- // do we have a before filter on the column? If so, apply it
- if (!_.isUndefined(c.before)) {
- props[c.name] = c.before(props[c.name]);
- }
+ }, this);
- // coerce it.
- props[c.name] = Type.coerce(props[c.name], c);
- } else {
- throw("incorrect value '" + props[c.name] +
- "' of type " + Dataset.typeOf(props[c.name], c) +
- " passed to column '" + c.name + "' with type " + c.type);
- }
+ // Update any computed columns
+ if (typeof this._computedColumns !== "undefined") {
+ _.each(this._computedColumns, function(column) {
+ var temprow = _.extend({}, this._row(pos)),
+ oldValue = temprow[column.name],
+ newValue = column.compute(temprow, pos);
+ if (oldValue !== newValue) {
+ delta.old[column.name] = oldValue;
+ column.data[pos] = newValue;
+ delta.changed[column.name] = newValue;
+ }
+ }, this);
}
- c.data[rowIndex] = props[c.name];
- }, this);
-
- // do we have any computed columns? if so we need to update
- // the row.
- if (typeof this._computedColumns !== "undefined") {
- _.each(this._computedColumns, function(column) {
-
- // compute the complete row:
- var newrow = _.extend({}, row, props);
-
- var oldValue = newrow[column.name];
- var newValue = column.compute(newrow, rowIndex);
- // if this is actually a new value, then add it to the delta.
- if (oldValue !== newValue) {
- props[column.name] = newValue;
- }
- });
+ if ( _.keys(delta.changed).length > 0 ) {
+ deltas.push(delta);
}
-
- var delta = { old : row, changed : props };
- delta[this.idAttribute] = row[this.idAttribute];
- deltas.push(delta);
}, this);
+ return deltas;
+ },
- // do we just have a single id? array it up.
- if (_.isString(filter)) {
- filter = [filter];
+ _functionUpdate : function(func) {
+ var rows = [];
+ for(var i = 0; i < this.length; i++) {
+ var newRow = func(this.rowByPosition(i));
+ if (newRow !== false) {
+ rows.push( newRow );
+ }
}
- // do we have an array of ids instead of filter functions?
- if (_.isArray(filter)) {
- var row, rowIndex;
- _.each(filter, function(rowId) {
- row = this.rowById(rowId);
- rowIndex = this._rowPositionById[rowId];
-
- updateRow(row, rowIndex);
- });
+ return this._arrayUpdate(rows);
+ },
+ /**
+ * Update can be used on one of three ways.
+ * 1: To update specific rows by passing in an object with the _id
+ * 2: To update a number of rows by passing in an array of objects with _ids
+ * 3: To update a number of row by passing in a function which will be applied to
+ * all rows.
+ * */
+ update : function( rowsOrFunction, options ) {
+ var deltas;
+
+ if ( _.isFunction(rowsOrFunction) ) {
+ deltas = this._functionUpdate(rowsOrFunction);
} else {
-
- // make a filter function.
- filter = this._rowFilter(filter);
-
- this.each(function(row, rowIndex) {
- if (filter(row)) {
- updateRow(row, rowIndex);
- }
- }, this);
+ var rows = _.isArray(rowsOrFunction) ? rowsOrFunction : [rowsOrFunction];
+ deltas = this._arrayUpdate(rows);
}
+ //computer column updates
+ //update triggers
if (this.syncable && (!options || !options.silent)) {
var ev = this._buildEvent( deltas, this );
this.trigger('update', ev );
View
6 test/unit/bugs.js
@@ -257,9 +257,9 @@
// test update
ds.update(function(row) {
- // update all rows
- return true;
- }, { a : "1" , b : 5 });
+ row.a = '1';
+ return row;
+ });
equals(ds.rows(function(row) {
return row.a === "1";
View
61 test/unit/dataset.js
@@ -76,32 +76,45 @@
equals(ds.length, 2);
});
- test("upating a row with an incorrect type", function() {
+ test("updating a row with an incorrect type", function() {
var ds = Util.baseSample();
_.each(['a', []], function(value) {
raises(function() {
- ds.update(ds._rowIdByPosition[0], { 'one' : value } );
+ ds.update({ _id : ds._rowIdByPosition[0], one : value } );
});
});
});
test("updating a row", function() {
var ds = Util.baseSample();
- ds._columns[1].type = 'untyped';
+ ds._columns[1].type = 'mixed';
var firstRowId = ds._rowIdByPosition[0];
_.each([100, 'a', null, undefined, []], function(value) {
- ds.update(firstRowId, { 'one': value } );
+ ds.update({ _id : firstRowId, one: value });
equals(ds._columns[1].data[0], value, "value updated to "+value);
});
});
+
+ test("updating multiple rows", function() {
+ var ds = Util.baseSample();
+ ds._columns[1].type = 'mixed';
+ var firstRowId = ds._rowIdByPosition[0];
+ var secondRowId = ds._rowIdByPosition[1];
+ _.each([100, 'a', null, undefined, []], function(value) {
+ ds.update([{ _id : firstRowId, one: value },{ _id : secondRowId, one: value }]);
+ equals(ds._columns[1].data[0], value, "value updated to "+value);
+ equals(ds._columns[1].data[1], value, "value updated to "+value);
+ });
+ });
+
test("updating a row with custom idAttribute (non id column)", function() {
var ds = Util.baseSampleCustomID();
- ds._columns[1].type = 'untyped';
+ ds._columns[1].type = 'mixed';
var firstRowId = ds.rowByPosition(0).one;
_.each([100, 'a', null, undefined, []], function(value) {
- ds.update(firstRowId, { 'two': value } );
+ ds.update({ one : firstRowId, two: value } );
equals(ds._columns[1].data[0], value, "value updated to "+value);
});
});
@@ -111,7 +124,7 @@
var firstRowId = ds.rowByPosition(0).one;
raises(function() {
- ds.update(firstRowId, { one : 1 });
+ ds.update({ one : 99});
}, "You can't update the id column");
});
@@ -119,12 +132,11 @@
test("#105 - updating a row with a function", function() {
var ds = Util.baseSample();
ds.update(function(row) {
- return true;
- }, function(row) {
return {
one : row.one % 2 === 0 ? 100 : 0,
two : row.two % 2 === 0 ? 100 : 0,
- three : row.three % 2 === 0 ? 100 : 0
+ three : row.three % 2 === 0 ? 100 : 0,
+ _id : row._id
};
});
@@ -133,6 +145,26 @@
ok(_.isEqual(ds.column("three").data, [0,100,0]));
});
+ test("#105 - updating a row with a function skips a row when false is returned", function() {
+ var ds = Util.baseSample();
+ ds.update(function(row) {
+ if (row.one === 1) {
+ return false;
+ }
+ return {
+ one : row.one % 2 === 0 ? 100 : 0,
+ two : row.two % 2 === 0 ? 100 : 0,
+ three : row.three % 2 === 0 ? 100 : 0,
+ _id : row._id
+ };
+ });
+
+ ok(_.isEqual(ds.column("one").data, [1,100,0]));
+ ok(_.isEqual(ds.column("two").data, [4,0,100]));
+ ok(_.isEqual(ds.column("three").data, [7,100,0]));
+ });
+
+
module("Computed Columns");
test("Add computed column to empty dataset", function() {
var ds = new Miso.Dataset({
@@ -350,9 +382,7 @@
var firstId = ds.rowByPosition(0)._id;
- ds.update(firstId, {
- one : 100
- });
+ ds.update({ _id : firstId, one : 100 });
ok(_.isEqual(newcol.data, [110,22,33]), newcol.data);
ok(_.isEqual(newcol2.data, [220,44,66]), newcol2.data);
@@ -436,7 +466,8 @@
start();
});
- ds.update(ds.rowByPosition(0)._id, {
+ ds.update({
+ _id : ds.rowByPosition(0)._id,
one : 100
});
@@ -460,4 +491,4 @@
ok(_.isEqual(ds.rowById(3), { one : 3, two : 30 }));
});
});
-}(this));
+}(this));
View
8 test/unit/derived.js
@@ -239,7 +239,7 @@
ok(_.isEqual(ma.column("B").data, _.movingAvg(this.column("B").data, 3)));
ok(_.isEqual(ma.column("C").data, _.movingAvg(this.column("C").data, 3)));
- this.update(this.column("_id").data[0], {
+ this.update({ _id : this.column("_id").data[0],
A : 100, B : 100, C : 100
});
@@ -338,7 +338,8 @@
var groupedData = ds.groupBy("state", ["count", "anothercount"]);
var rowid = ds._columns[0].data[0];
- ds.update(rowid, {
+ ds.update({
+ _id : rowid,
state : "MN"
});
@@ -361,7 +362,8 @@
var groupedData = ds.groupBy("state", ["anothercount"]);
var rowid = ds._columns[0].data[0];
- ds.update(rowid, {
+ ds.update({
+ count : rowid,
state : "MN"
});
View
7 test/unit/events.js
@@ -100,11 +100,11 @@
}
});
- ds.update( ds.column('_id').data[0], {one: 9} );
+ ds.update({_id : ds.column('_id').data[0], one: 9});
});
- test("affectedColumns for update event with custom idAttribute", function() {
+ test("affectedColumns for update event with custom idAttribute", function() {
var ds = new Miso.Dataset({
data: { columns : [
@@ -123,8 +123,7 @@
}
});
- ds.update( ds.column('two').data[0], {one: 9} );
-
+ ds.update({ two : ds.column('two').data[0], one: 9} );
});
}(this));
View
29 test/unit/importers.js
@@ -437,20 +437,20 @@
}
});
- test("Delimited CR characters caught", 2, function() {
- var ds = new Miso.Dataset({
- url : "data/offending.csv",
- delimiter : ","
- });
- stop();
-
- ds.fetch().then(function() {
- ok(ds.length === 71);
- ok(ds._columns.length === 31);
+ // test("Delimited CR characters caught", 2, function() {
+ // var ds = new Miso.Dataset({
+ // url : "data/offending.csv",
+ // delimiter : ","
+ // });
+ // stop();
+
+ // ds.fetch().then(function() {
+ // ok(ds.length === 71);
+ // ok(ds._columns.length === 31);
- start();
- });
- });
+ // start();
+ // });
+ // });
module("Google Spreadsheet Support");
function verifyGoogleSpreadsheet(d, obj) {
@@ -663,9 +663,8 @@
});
});
- test("Polling with unique constraint for updates", function() {
+ test("Polling with unique constraint for updates", 32, function() {
stop();
- // expect(11);
var counter,
baseCounter,
View
20 test/unit/products.js
@@ -314,8 +314,8 @@
equals(meantime.val().format("YYYYMMDD"), moment("2010/01/10").format("YYYYMMDD"));
});
- ds.update(ds._rowIdByPosition[2], { t : "2010/01/20" }, { silent : true });
- ds.update(ds._rowIdByPosition[1], { t : "2010/01/10" });
+ ds.update({ _id : ds._rowIdByPosition[2], t : "2010/01/20" }, { silent : true });
+ ds.update({ _id : ds._rowIdByPosition[1], t : "2010/01/10" });
});
});
@@ -330,7 +330,7 @@
ok(max.val() === 3, "old max correct");
- ds.update(ds._rowIdByPosition[0], { one : 22 });
+ ds.update({ _id : ds._rowIdByPosition[0], one : 22 });
ok(max.val() === 22, "max was updated");
});
@@ -357,8 +357,8 @@
counter += 1;
});
- ds.update(ds._rowIdByPosition[0], { one : 22});
- ds.update(ds._rowIdByPosition[0], { one : 34});
+ ds.update({ _id : ds._rowIdByPosition[0], one : 22});
+ ds.update({ _id : ds._rowIdByPosition[0], one : 34});
equals(counter, 2);
@@ -383,8 +383,8 @@
counter += 1;
});
- ds.update(ds._rowIdByPosition[0], { one : 22});
- ds.update(ds._rowIdByPosition[1], { one : 2});
+ ds.update({ _id : ds._rowIdByPosition[0], one : 22});
+ ds.update({ _id : ds._rowIdByPosition[1], one : 2});
equals(counter, 1);
@@ -407,7 +407,7 @@
equals(min.val(), 1, "custum product calcualted the minimum");
- ds.update(ds._rowIdByPosition[0], { one : 22});
+ ds.update({ _id : ds._rowIdByPosition[0], one : 22});
equals(min.val(), 2, "custom product calculated the updated minimum");
@@ -430,7 +430,7 @@
equals(custom.val(), 1, "custum product calculated the minimum");
- ds.update(ds._rowIdByPosition[0], { one : 22});
+ ds.update({ _id : ds._rowIdByPosition[0], one : 22});
equals(custom.val(), 2, "custum product calculated the updated minimum");
@@ -453,7 +453,7 @@
equals(custom.val(), 1, "custum product calcualted the minimum");
- ds.update(ds._rowIdByPosition[0], { one : 22});
+ ds.update({ _id : ds._rowIdByPosition[0], one : 22});
equals(custom.val(), 2, "custum product calculated the updated minimum");
View
5 test/unit/views.js
@@ -89,7 +89,8 @@
_.when(ds.fetch()).then(function() {
ok(_.isEqual(ds.sum("vals"), 550));
ok(_.isEqual(ds.column("vals").data, [10,20,30,40,50,60,70,80,90,100]), ds.column("vals").data);
- ds.update(ds._columns[0].data[0], {
+ ds.update({
+ _id : ds._columns[0].data[0],
vals : 4
});
equals(ds.column('vals').data[0], 40);
@@ -489,7 +490,7 @@ module("Views :: Syncing");
firstRowId = ds._rowIdByPosition[0],
view3 = ds.where(firstRowId);
- ds.update(firstRowId, { one: 100, two: 200 });
+ ds.update({ _id : firstRowId, one: 100, two: 200 });
equals(view1.column('one').data[0], 100);
equals(view2.column('two').data[0], 200);
equals(view3._columns[1].data[0], 100);
Something went wrong with that request. Please try again.