import Ember from 'ember';
import DS from 'ember-data';
/**
* @module Adapter
*/
/**
* The DataAdapter allows your store to communicate with the couchdb or any
* proxy api which connects to couchdb.
* To use the adapter in your app, extend DataAdapter
*
* ```js
* import DataAdapter from 'ember-cli-couchdb/adapters/data';
*
* export default DataAdapter.extend({
*
* });
* ```
*
* and customize the namespace to point to the database name or proxy api namespace
* where data to be stored.
*
* @class DataAdapter
* @namespace ember-cli-couchdb
* @extends DS.RESTAdapter
*/
export default DS.RESTAdapter.extend({
primaryKey: '_id',
defaultSerializer: 'data',
updateHandler: null,
acceptedKeys: ['reduce', 'key', 'startkey', 'endkey', 'keys', 'limit', 'skip', 'group_level', 'include_docs', 'descending'],
getViewURL: function (category, view) {
return `_design/${category}/_view/${view}`;
},
buildURL: function(type, id, snapshot, query) {
let category, key, value, view;
let namespace = this.get('namespace') || '';
let host = this.get('host') || `${window.location.protocol}\/\/${window.location.host}`;
host = `${host}/${namespace}`;
if (query && typeof(query) === 'object') {
if(query.data && query.data.updateHandler){
return `${host}/_update/${query.data.updateHandler}/${id}`;
}
else if(!query.category && query.view){
// all docs
query.type = 'POST';
//[todo] - for /_all_docs set the query object correctly
return `${host}/_all_docs`;
}
else {
// _view
category = query.category;
view = query.view;
delete query.category;
delete query.view;
// [todo] - handle query object formating of multiple startkey & endkey pairs
for (key in query) {
value = query[key];
if (key === 'startkey' || key === 'endkey') {
if (typeof value === 'object') {
query[key] = JSON.stringify(value);
}
}
}
// Clean keys in query
let acceptedKeys = this.get('acceptedKeys') || [];
query.data = {};
for (key in query) {
value = query[key];
if(acceptedKeys.indexOf(key) < 0) {
continue;
}
query.data[key] = query[key];
delete query[key];
}
let viewUrl = this.getViewURL(category, view);
// return `${host}/_view/${category}/${view}`;
return `${host}/${viewUrl}`;
}
}
else if (id) {
return `${host}/${id}`;
} else {
return `${host}`;
}
},
findAll: function(store, type) {
return Ember.assert(`Please do not call find() for ${type.typeKey} instead pass keys or startkey & endkey pair`, false);
},
findQuery: function(store, type, query) {
if (this.sortQueryParams) {
query = this.sortQueryParams(query);
}
var url = this.buildURL(type, null,null, query);
type = query.type || 'GET';
delete query.type;
return this.ajax(url, type, query);
},
createRecord: function(store, type, snapshot) {
var data = {};
var serializer = store.serializerFor(type.typeKey);
data = serializer.serialize(snapshot, { includeId: true });
return this.ajax(this.buildURL(type.typeKey, null, snapshot), 'POST', function(json) {
Ember.assert('Must contain ok key in save response', json.ok);
delete json.ok;
Ember.assert('Must contain id key in save response', json.id);
Ember.assert('Must contain rev key in save response', json.rev);
data._rev = json.rev;
delete json.rev;
json = Ember.$.extend(data, json);
return json;
}, {
data: data
});
},
updateRecord: function(store, type, snapshot) {
var data = {};
var id = snapshot.get('id');
var serializer = store.serializerFor(type.typeKey);
data = serializer.serialize(snapshot, { includeId: true });
var query;
if (this.updateHandler) {
query = { data: { updateHandler: this.updateHandler }};
}
return this.ajax(this.buildURL(type.typeKey, id, snapshot, query), 'PUT', function(json) {
Ember.assert('Must contain ok key in save response', json.ok);
delete json.ok;
Ember.assert('Must contain id key in save response', json.id);
Ember.assert('Must contain rev key in save response', json.rev);
data._rev = json.rev;
delete json.rev;
json = JSON.parse(JSON.stringify(Ember.$.extend(data, json)));
return json;
}, {
data: data
});
},
deleteRecord: function(store, type, snapshot) {
var data, id, serializer;
data = {};
serializer = store.serializerFor(type.typeKey);
serializer.serializeIntoHash(data, type, snapshot, {includeId: true});
data._deleted = true;
id = snapshot.get('id');
return this.ajax(this.buildURL(type.typeKey, id, snapshot), 'PUT', function(json) {
Ember.assert('Must contain ok key in save response', json.ok);
delete json.ok;
Ember.assert('Must contain rev key in save response', json.rev);
data._rev = json.rev;
delete json.rev;
json = Ember.$.extend(data, json);
return json;
}, {
data: data
});
},
ajax: function(url, type, normalizeResponse, hash) {
var adapter;
adapter = this;
if (normalizeResponse && !hash) {
hash = normalizeResponse;
normalizeResponse = null;
}
return new Ember.RSVP.Promise(function(resolve, reject) {
hash = adapter.ajaxOptions(url, type, hash);
hash.success = function(json/*, textStatus, jqXHR*/) {
if (normalizeResponse && Ember.typeOf(normalizeResponse) === 'function') {
json = normalizeResponse.call(adapter, json);
}
Ember.run(null, resolve, json);
};
hash.error = function(jqXHR, textStatus, errorThrown) {
Ember.run(null, reject, adapter.ajaxError(jqXHR, jqXHR.responseText, errorThrown));
};
return Ember.$.ajax(hash);
}, `DS: DataAdapter#ajax ${type} to ${url}`);
}
});