updateCacheData : function (updateData, dsRequest) { if (!isc.isAn.Array(updateData)) updateData = [updateData]; // NOTE: if allRows is present we are performing a local filter to display a subset of // this set of rows. // (This may be the entire dataSet for the dataSource - in which case we're in local mode, // or just the matching rows for our less restrictive 'allRowsFilter') var filteringOnClient = this.allRows != null, cache = filteringOnClient ? this.allRows : this.localData, updatedRows = 0, removedRows = 0, addedRows = 0; var keyColumns = this.getDataSource().getPrimaryKeyFields(); for (var i = 0; i < updateData.length; i++) { var updateRow = updateData[i], keyValues = isc.applyMask(updateRow, keyColumns); // find the index of the old row var index = this.getDataSource().findByKeys(keyValues, cache), origRecord; // if we didn't find the record in our cache, check for the case where the server // returned a changed (bad) primary key value for an update of an existing record. // In this case warn, and clear out the original version of the record. if (index == -1) { var submittedRecord = dsRequest.data; if (isc.isAn.Array(submittedRecord)) submittedRecord = submittedRecord[0]; // pare down to PKs and find in our data-set submittedRecord = isc.applyMask(submittedRecord, keyColumns); var oldRecordIndex = this.getDataSource().findByKeys(submittedRecord, cache); if (oldRecordIndex != -1) { this.logWarn("Update operation - submitted record with primary key value[s]:" + this.echo(submittedRecord) + " returned with modified primary key:" + this.echo(keyValues) + ". This may indicate bad server logic. " + "Updating cache to reflect new primary key."); // remove the old record from our dataSet. If it matches filter, we'll re-add below removedRows++; cache.removeAt(oldRecordIndex); // this is a weird case - don't attempt to fire row-specific dataChanged delete this._lastUpdateData; } else { // handle modification of the primary key submittedRecord = dsRequest.oldValues; if (submittedRecord) { submittedRecord = isc.applyMask(submittedRecord, keyColumns); var oldRecordIndex = this.getDataSource().findByKeys(submittedRecord, cache); if (oldRecordIndex != -1) { this.logWarn("Update operation - submitted record with old primary key value[s]:" + this.echo(submittedRecord) + " returned with new primary key:" + this.echo(keyValues) + "Updating cache to reflect new primary key."); // remove the old record from our dataSet. If it matches filter, we'll re-add below removedRows++; cache.removeAt(oldRecordIndex); // this is a weird case - don't attempt to fire row-specific dataChanged delete this._lastUpdateData; } } } } else if (updateData.length == 1) { origRecord = cache.get(index); // catch the case where the orig record is present in the allRows cache but doesn't // match filter criteria for local data if (filteringOnClient && !this.getDataSource().recordMatchesFilter(origRecord, this.criteria, this.context)) { origRecord = null; } // if the original record was in the (filtered) cache, we'll pass it to // dataChanged as a parameter this._lastOrigRecord = origRecord; // also hang onto the position now. If the record is updated it won't change without // a sort, and if it's removed we won't be able to pick it up later if (origRecord) this._lastUpdateRow = this.indexOf(origRecord); } var criteria = filteringOnClient ? this.allRowsCriteria : this.criteria, // see if the new row matches the filter criteria matchesFilter = this.getDataSource().recordMatchesFilter(updateRow, criteria, this.context), // don't drop the updated row if neverDropUpdatedRows dontDrop = this.shouldNeverDropUpdatedRows(); if (index == -1 && matchesFilter) { // we got an updated row that matches our filter criteria but is not in the cache. // This could indicate either: // - an "update" operation submitted by a separate grid, form or manual call to // dataSource.updateData(), changing an existing row so that it now matches our // criteria // - an "update" operation was submitted based on a record we have cached, but there's // a server bug where the server return the wrong PK, so we couldn't locate the // row. In this second case we've already removed the original record, so it's // appropriate to re-add the "new" record to the cache. this.logInfo("updated row returned by server doesn't match any cached row, " + " adding as new row. Primary key values: " + this.echo(keyValues) + ", complete row: " + this.echo(updateRow)); addedRows++; cache.add(updateRow); // in this case we are adding a row to the cache // if it's being added to the filtered cache figure out the new rowNum here if (updateData.length == 1) { // actually store a pointer to the new row. If we just added the record to the // allRows cache this can be used to calculate the position within the local cache // when the calling method does a local filter. this._lastUpdateRecord = updateRow; this._lastUpdateRow = cache.length-1; } } else if (index != -1) { // found the original row (matching primary keys) in our cache if (matchesFilter || dontDrop) { // update the row in place if any of the following is true: // - the updated row passes the current filter // - we are configured to never drop updated rows // - we're actually updating the complete client-side cache, not just the list // of rows that match the filter // Note that we use set() instead of just always removing and adding every time // because it maintains the record's index when there's no current sort order updatedRows++; cache.set(index, updateRow); } else { // otherwise, row has been changed so that it does not match filter, // remove the old row //>DEBUG if (this.logIsDebugEnabled()) { this.logDebug("row dropped:\n" + this.echo(updateRow) + "\ndidn't match filter: " + this.echo(criteria)); } //