Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the store to pass adapter options to the adapter #3310

Merged
merged 2 commits into from
Jun 13, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/ember-data/lib/system/adapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ var Adapter = Ember.Object.extend({
@param {DS.Store} store
@param {DS.Model} type
@param {String} sinceToken
@param {DS.SnapshotRecordArray} snapshotRecordArray
@return {Promise} promise
*/
findAll: null,
Expand Down
11 changes: 7 additions & 4 deletions packages/ember-data/lib/system/model/internal-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,11 @@ InternalModel.prototype = {
this.send('deleteRecord');
},

save: function() {
save: function(options) {
var promiseLabel = "DS: Model#save " + this;
var resolver = Ember.RSVP.defer(promiseLabel);

this.store.scheduleSave(this, resolver);
this.store.scheduleSave(this, resolver, options);
return resolver.promise;
},

Expand Down Expand Up @@ -221,8 +221,11 @@ InternalModel.prototype = {
@method createSnapshot
@private
*/
createSnapshot: function() {
return new Snapshot(this);
createSnapshot: function(options) {
var adapterOptions = options && options.adapterOptions;
var snapshot = new Snapshot(this);
snapshot.adapterOptions = adapterOptions;
return snapshot;
},

/**
Expand Down
10 changes: 6 additions & 4 deletions packages/ember-data/lib/system/model/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -519,12 +519,13 @@ var Model = Ember.Object.extend(Ember.Evented, {
```

@method destroyRecord
@param {Object} options
@return {Promise} a promise that will be resolved when the adapter returns
successfully or rejected if the adapter returns with an error.
*/
destroyRecord: function() {
destroyRecord: function(options) {
this.deleteRecord();
return this.save();
return this.save(options);
},

/**
Expand Down Expand Up @@ -677,13 +678,14 @@ var Model = Ember.Object.extend(Ember.Evented, {
});
```
@method save
@param {Object} options
@return {Promise} a promise that will be resolved when the adapter returns
successfully or rejected if the adapter returns with an error.
*/
save: function() {
save: function(options) {
var model = this;
return PromiseObject.create({
promise: this._internalModel.save().then(function() {
promise: this._internalModel.save(options).then(function() {
return model;
})
});
Expand Down
44 changes: 44 additions & 0 deletions packages/ember-data/lib/system/snapshot-record-array.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
@module ember-data
*/

/**
@class SnapshotRecordArray
@namespace DS
@private
@constructor
@param {Array} snapshots An array of snapshots
@param {Object} meta
*/
function SnapshotRecordArray(recordArray, meta, adapterOptions) {
this._snapshots = null;
this._recordArray = recordArray;
this.length = recordArray.get('length');
this.meta = meta;
this.adapterOptions = adapterOptions;
}

/**
@method fromRecordArray
@private
@static
@param {DS.RecordArray} recordArray
@param {Object} adapterOptions
@return SnapshotRecordArray
*/
SnapshotRecordArray.fromRecordArray = function(recordArray, adapterOptions) {
var meta = recordArray.get('meta');
return new SnapshotRecordArray(recordArray, meta, adapterOptions);
};

SnapshotRecordArray.prototype.snapshots = function() {
if (this._snapshots) {
return this._snapshots;
}
var recordArray = this._recordArray;
this._snapshots = recordArray.invoke('createSnapshot');

return this._snapshots;
};

export default SnapshotRecordArray;
63 changes: 35 additions & 28 deletions packages/ember-data/lib/system/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ Store = Service.extend({
}

if (internalModel.isEmpty()) {
fetchedInternalModel = this.scheduleFetch(internalModel);
fetchedInternalModel = this.scheduleFetch(internalModel, options);
//TODO double check about reloading
} else if (internalModel.isLoading()) {
fetchedInternalModel = internalModel._loadingPromise;
Expand Down Expand Up @@ -641,16 +641,17 @@ Store = Service.extend({
@private
@param {InternalModel} internalModel model
@return {Promise} promise
*/
fetchRecord: function(internalModel) {
*/
// TODO rename this to have an underscore
fetchRecord: function(internalModel, options) {
var typeClass = internalModel.type;
var id = internalModel.id;
var adapter = this.adapterFor(typeClass.modelName);

Ember.assert("You tried to find a record but you have no adapter (for " + typeClass + ")", adapter);
Ember.assert("You tried to find a record but your adapter (for " + typeClass + ") does not implement 'find'", typeof adapter.find === 'function');

var promise = _find(adapter, this, typeClass, id, internalModel);
var promise = _find(adapter, this, typeClass, id, internalModel, options);
return promise;
},

Expand All @@ -659,24 +660,25 @@ Store = Service.extend({
return Promise.all(map(internalModels, this.scheduleFetch, this));
},

scheduleFetch: function(internalModel) {
scheduleFetch: function(internalModel, options) {
var typeClass = internalModel.type;

if (internalModel._loadingPromise) { return internalModel._loadingPromise; }

var resolver = Ember.RSVP.defer('Fetching ' + typeClass + 'with id: ' + internalModel.id);
var recordResolverPair = {
var pendingFetchItem = {
record: internalModel,
resolver: resolver
resolver: resolver,
options: options
};
var promise = resolver.promise;

internalModel.loadingData(promise);

if (!this._pendingFetch.get(typeClass)) {
this._pendingFetch.set(typeClass, [recordResolverPair]);
this._pendingFetch.set(typeClass, [pendingFetchItem]);
} else {
this._pendingFetch.get(typeClass).push(recordResolverPair);
this._pendingFetch.get(typeClass).push(pendingFetchItem);
}
Ember.run.scheduleOnce('afterRender', this, this.flushAllPendingFetches);

Expand All @@ -692,19 +694,19 @@ Store = Service.extend({
this._pendingFetch = Map.create();
},

_flushPendingFetchForType: function (recordResolverPairs, typeClass) {
_flushPendingFetchForType: function (pendingFetchItems, typeClass) {
var store = this;
var adapter = store.adapterFor(typeClass.modelName);
var shouldCoalesce = !!adapter.findMany && adapter.coalesceFindRequests;
var records = Ember.A(recordResolverPairs).mapBy('record');
var records = Ember.A(pendingFetchItems).mapBy('record');

function _fetchRecord(recordResolverPair) {
recordResolverPair.resolver.resolve(store.fetchRecord(recordResolverPair.record));
recordResolverPair.resolver.resolve(store.fetchRecord(recordResolverPair.record, recordResolverPair.options)); // TODO adapter options
}

function resolveFoundRecords(records) {
forEach(records, function(record) {
var pair = Ember.A(recordResolverPairs).findBy('record', record);
var pair = Ember.A(pendingFetchItems).findBy('record', record);
if (pair) {
var resolver = pair.resolver;
resolver.resolve(record);
Expand Down Expand Up @@ -734,16 +736,16 @@ Store = Service.extend({

function rejectRecords(records, error) {
forEach(records, function(record) {
var pair = Ember.A(recordResolverPairs).findBy('record', record);
var pair = Ember.A(pendingFetchItems).findBy('record', record);
if (pair) {
var resolver = pair.resolver;
resolver.reject(error);
}
});
}

if (recordResolverPairs.length === 1) {
_fetchRecord(recordResolverPairs[0]);
if (pendingFetchItems.length === 1) {
_fetchRecord(pendingFetchItems[0]);
} else if (shouldCoalesce) {

// TODO: Improve records => snapshots => records => snapshots
Expand All @@ -769,14 +771,14 @@ Store = Service.extend({
then(makeMissingRecordsRejector(requestedRecords)).
then(null, makeRecordsRejector(requestedRecords));
} else if (ids.length === 1) {
var pair = Ember.A(recordResolverPairs).findBy('record', groupOfRecords[0]);
var pair = Ember.A(pendingFetchItems).findBy('record', groupOfRecords[0]);
_fetchRecord(pair);
} else {
Ember.assert("You cannot return an empty array from adapter's method groupRecordsForFindMany", false);
}
});
} else {
forEach(recordResolverPairs, _fetchRecord);
forEach(pendingFetchItems, _fetchRecord);
}
},

Expand Down Expand Up @@ -1043,13 +1045,14 @@ Store = Service.extend({

@method findAll
@param {String} modelName
@param {Object} options
@return {DS.AdapterPopulatedRecordArray}
*/
findAll: function(modelName) {
findAll: function(modelName, options) {
Ember.assert('Passing classes to store methods has been removed. Please pass a dasherized string instead of '+ Ember.inspect(modelName), typeof modelName === 'string');
var typeClass = this.modelFor(modelName);

return this._fetchAll(typeClass, this.peekAll(modelName));
return this._fetchAll(typeClass, this.peekAll(modelName), options);
},

/**
Expand All @@ -1059,7 +1062,7 @@ Store = Service.extend({
@param {DS.RecordArray} array
@return {Promise} promise
*/
_fetchAll: function(typeClass, array) {
_fetchAll: function(typeClass, array, options) {
var adapter = this.adapterFor(typeClass.modelName);
var sinceToken = this.typeMapFor(typeClass).metadata.since;

Expand All @@ -1068,7 +1071,7 @@ Store = Service.extend({
Ember.assert("You tried to load all records but you have no adapter (for " + typeClass + ")", adapter);
Ember.assert("You tried to load all records but your adapter does not implement `findAll`", typeof adapter.findAll === 'function');

return promiseArray(_findAll(adapter, this, typeClass, sinceToken));
return promiseArray(_findAll(adapter, this, typeClass, sinceToken, options));
},

/**
Expand Down Expand Up @@ -1349,12 +1352,16 @@ Store = Service.extend({
@private
@param {InternalModel} internalModel
@param {Resolver} resolver
@param {Object} options
*/
scheduleSave: function(internalModel, resolver) {
var snapshot = internalModel.createSnapshot();
scheduleSave: function(internalModel, resolver, options) {
var snapshot = internalModel.createSnapshot(options);
internalModel.flushChangedAttributes();
internalModel.adapterWillCommit();
this._pendingSave.push([snapshot, resolver]);
this._pendingSave.push({
snapshot: snapshot,
resolver: resolver
});
once(this, 'flushPendingSave');
},

Expand All @@ -1369,9 +1376,9 @@ Store = Service.extend({
var pending = this._pendingSave.slice();
this._pendingSave = [];

forEach(pending, function(tuple) {
var snapshot = tuple[0];
var resolver = tuple[1];
forEach(pending, function(pendingItem) {
var snapshot = pendingItem.snapshot;
var resolver = pendingItem.resolver;
var record = snapshot._internalModel;
var adapter = this.adapterFor(record.type.modelName);
var operation;
Expand Down
12 changes: 8 additions & 4 deletions packages/ember-data/lib/system/store/finders.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import {
serializerForAdapter
} from "ember-data/system/store/serializers";

import SnapshotRecordArray from "ember-data/system/snapshot-record-array";

var Promise = Ember.RSVP.Promise;
var map = Ember.EnumerableUtils.map;

export function _find(adapter, store, typeClass, id, internalModel) {
var snapshot = internalModel.createSnapshot();
export function _find(adapter, store, typeClass, id, internalModel, options) {
var snapshot = internalModel.createSnapshot(options);
var promise = adapter.find(store, typeClass, id, snapshot);
var serializer = serializerForAdapter(store, adapter, internalModel.type.modelName);
var label = "DS: Handle Adapter#find of " + typeClass + " with id: " + id;
Expand Down Expand Up @@ -118,9 +120,11 @@ export function _findBelongsTo(adapter, store, internalModel, link, relationship
}, null, "DS: Extract payload of " + internalModel + " : " + relationship.type);
}

export function _findAll(adapter, store, typeClass, sinceToken) {
var promise = adapter.findAll(store, typeClass, sinceToken);
export function _findAll(adapter, store, typeClass, sinceToken, options) {
var adapterOptions = options && options.adapterOptions;
var modelName = typeClass.modelName;
var snapshotArray = SnapshotRecordArray.fromRecordArray(store.peekAll(modelName), adapterOptions);
var promise = adapter.findAll(store, typeClass, sinceToken, snapshotArray);
var serializer = serializerForAdapter(store, adapter, modelName);
var label = "DS: Handle Adapter#findAll of " + typeClass;

Expand Down
Loading