Skip to content

Instantly share code, notes, and snippets.

@ynniv
Created February 26, 2010 01:05
Show Gist options
  • Save ynniv/315278 to your computer and use it in GitHub Desktop.
Save ynniv/315278 to your computer and use it in GitHub Desktop.
// ==========================================================================
// Project: WhenAbout.com / Front
// Copyright: ©2010 Touch of Logic LLC, Vincent Fiano <ynniv@touchoflogic.com>
// ==========================================================================
// This is sample code for DataSources and remote queries. It was compiled from
// multiple files, and extraneous code and comments have been removed. It
// probably does not function out of the box. You've been warned.
Front = SC.Application.create(
/** @scope Front.prototype */ {
store: SC.Store.create({
commitRecordsAutomatically: NO
}).from('Evtcal.EvtcalDataSource'),
eventsController: SC.ArrayController.create(
/** @scope Editor.eventsController.prototype */ {
filter: SC.Object.create({
_primaryProperties: ['en_name', 'startDate', 'duration'],
en_name: '',
startDate: SC.DateTime.create(),
duration: 0
})
}),
setupEventsFilterObserver: function () {
Front.eventsController.filter.set('duration', 0);
var props = Front.eventsController.filter.get('_primaryProperties');
props.forEach(function (p) {
Front.eventsController.filter.addObserver(p, Front, Front.eventsFilterObserver);
});
this.eventsFilterObserver();
},
eventsFilterObserver: function (target, key, value, revision) {
// pool filter attribute updates into a single dispatch
this.invokeOnce(this._eventsFilterObserver);
},
_eventsFilterObserver: function () {
console.log('_eventsFilterObserver(%@)'.fmt(SC.A(arguments)));
var filter = Front.eventsController.get('filter');
var startDate = filter.get('startDate');
var endDate = filter.get('endDate');
var filter_en_name = filter.get("en_name");
var query = { "event.en_name" : 're:.*%@.*'.fmt(filter_en_name.split('')
.map(function (c) {
return '[%@%@]'.fmt(c.toUpperCase(), c.toLowerCase());
}).join('')),
startDateTime : { "$lte" : 'd:' + endDate.get('milliseconds') },
endDateTime : { "$gte" : 'd:' + startDate.get('milliseconds') }
};
var results = Front.store.find(
SC.Query.remote(Evtcal.Event, {
query : query,
isSparse : YES,
orderBy : 'startDateTime' }));
this.get('eventsController').set('content', results);
}
}) ;
Front.main = function main() {
Front.setupEventsFilterObserver();
};
Evtcal.EvtcalDataSource = SC.DataSource.extend(
/** @scope Evtcal.EvtcalDataSource.prototype */ {
typeTagOfDataHash: function (hash) {
return hash.guid.match(/^\/([a-z_]+)\//)[1];
},
recordTypeForTag: function (tag) {
switch (tag) {
case 'event' : return Evtcal.Event; break;
case 'venue' : return Evtcal.Venue; break;
}
return undefined;
},
tagForRecordType: function (type) {
switch (type) {
case Evtcal.Event: return 'event'; break;
case Evtcal.Venue: return 'venue'; break;
}
return undefined;
},
fetch: function(store, query) {
if (query.get('isRemote')) {
if (query.get('isSparse')) {
store.loadQueryResults(query, SC.SparseArray.create({
delegate: this, store: store, query: query, rangeWindowSize: 30
}));
return YES;
} else {
var type = this.tagForRecordType(query.get('recordType'));
var url = query.get('url');
if (url == undefined) {
var q = SC.json.encode(query.get('query'));
url = '/api/%@/search.json?q=%@'.fmt(type, q);
}
SC.Request.getUrl(url).json()
.notify(Front.store._getDataSource(), 'didFetchRecords',
{ store: Front.store, query: query }).send();
return YES;
}
}
return NO;
},
sparseArrayDidRequestLength: function (sparseArray) {
return this.sparseArrayDidRequestRange(sparseArray, { start: 0, length: 50 });
},
sparseArrayDidRequestRange: function(sparseArray, range) {
var query = sparseArray.query;
var type = this.tagForRecordType(query.get('recordType'));
var q = SC.json.encode(query.get('query'));
var url = '/api/%@/search.json'.fmt(type);
SC.Request.getUrl('%@?q=%@&start=%@&length=%@&full=1'
.fmt(url, q, range.start, range.length))
.json().notify(Front.store._getDataSource(), 'didFetchRecords',
{ sparseArray: sparseArray, store: Front.store,
query: query, start: range.start, length: range.length }).send();
},
loadJSONRecords: function (store, records) {
var typeGroups = {};
records.forEach(function (r) {
var type = this.typeTagOfDataHash(r);
(typeGroups[type] = typeGroups[type] || []).push(r);
}, this);
for (var tag in typeGroups) {
var type = this.recordTypeForTag(tag);
store.loadRecords(type, typeGroups[tag]);
}
},
didFetchRecords: function(response, params) {
if (SC.ok(response)) {
var result = response.get('body');
var records = SC.A(result.records);
this.loadJSONRecords(params.store, records);
if (params.query) {
if (params.query.get('isRemote')) {
var storeKeys = SC.A(result.resultIds).map(function (id) {
var split = id.match(/^\/([a-z_]+)\/(.*)$/);
var type = split[1], guid = split[2];
return this.recordTypeForTag(type).storeKeyFor(id);
}, this);
if (params.sparseArray) {
var array = params.sparseArray;
array.provideLength(result.resultCount);
array.provideObjectsInRange({
start: result.resultOffset, length: storeKeys.length}, storeKeys);
} else {
params.store.loadQueryResults(params.query, storeKeys);
}
} else {
params.store.dataSourceDidFetchQuery(params.query);
}
}
} else {
if (params.query) params.store.dataSourceDidErrorQuery(params.query, response);
}
},
retrieveRecords: function(store, storeKeys, ids) {
if (storeKeys.length == 1) {
return this.retrieveRecord(store, storeKeys[0]);
} else {
return this._handleEach(store, storeKeys, this.retrieveRecord, ids);
}
},
retrieveRecord: function(store, storeKey) {
if ([Evtcal.Event, Evtcal.Venue].indexOf(
store.recordTypeFor(storeKey)) > -1) {
var url = store.idFor(storeKey);
SC.Request.getUrl("/api" + url + '.json').json().
notify(this, 'didRetrieveRecord', store, storeKey).send();
return YES;
}
return NO ;
},
didRetrieveRecord: function(response, store, storeKey) {
if (SC.ok(response)) {
this.loadJSONRecords(store, response.get('body').records);
} else store.dataSourceDidError(storeKey, response);
},
createRecord: function(store, storeKey) { return NO ; },
updateRecord: function(store, storeKey) { return NO ; },
destroyRecord: function(store, storeKey) { return NO ; }
}) ;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment