| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| define([ |
| 'app', |
| 'api', |
| 'cloudant.pagingcollection' |
| ], function (app, FauxtonAPI, PagingCollection) { |
| |
| // defined here because this is contains the base resources used throughout the addon and outside, |
| // so it's the first code that gets run |
| var Documents = FauxtonAPI.addon(); |
| |
| |
| Documents.Doc = FauxtonAPI.Model.extend({ |
| idAttribute: "_id", |
| documentation: function () { |
| return FauxtonAPI.constants.DOC_URLS.GENERAL; |
| }, |
| url: function (context) { |
| if (context === undefined) { |
| context = 'server'; |
| } |
| return FauxtonAPI.urls('document', context, this.getDatabase().safeID(), this.safeID()); |
| }, |
| |
| initialize: function (_attrs, options) { |
| if (this.collection && this.collection.database) { |
| this.database = this.collection.database; |
| } else if (options.database) { |
| this.database = options.database; |
| } |
| }, |
| |
| // HACK: the doc needs to know about the database, but it may be |
| // set directly or indirectly in all docs |
| getDatabase: function () { |
| return this.database ? this.database : this.collection.database; |
| }, |
| |
| validate: function (attrs, options) { |
| if (this.id && this.id !== attrs._id && this.get('_rev') ) { |
| return "Cannot change a documents id."; |
| } |
| }, |
| |
| docType: function () { |
| return app.utils.getDocTypeFromId(this.id); |
| }, |
| |
| isDeletable: function () { |
| return !!this.id; |
| }, |
| |
| isFromView: function () { |
| return !this.id; |
| }, |
| |
| isMangoDoc: function () { |
| if (!this.isDdoc()) return false; |
| if (this.get('language') === 'query') { |
| return true; |
| } |
| |
| if (this.get('doc') && this.get('doc').language === 'query') { |
| return true; |
| } |
| |
| return false; |
| }, |
| |
| isReducedShown : function () { |
| if (this.collection) { |
| return this.collection.params.reduce; |
| } else { |
| return false; |
| } |
| }, |
| |
| isDdoc: function () { |
| return this.docType() === "design doc"; |
| }, |
| |
| hasViews: function () { |
| if (!this.isDdoc()) return false; |
| var doc = this.get('doc'); |
| if (doc) { |
| return doc && doc.views && _.keys(doc.views).length > 0; |
| } |
| |
| var views = this.get('views'); |
| return views && _.keys(views).length > 0; |
| }, |
| |
| getDdocView: function (view) { |
| if (!this.isDdoc() || !this.hasViews()) { |
| return false; |
| } |
| |
| var doc = this.get('doc'); |
| if (doc) { |
| return doc.views[view]; |
| } |
| |
| return this.get('views')[view]; |
| }, |
| |
| setDdocView: function (view, map, reduce) { |
| if (!this.isDdoc()) { |
| return false; |
| } |
| |
| var views = this.get('views'), |
| tempView = views[view] || {}; |
| |
| if (reduce) { |
| tempView.reduce = reduce; |
| } else { |
| delete tempView.reduce; |
| } |
| tempView.map = map; |
| |
| views[view] = tempView; |
| this.set({views: views}); |
| |
| return true; |
| }, |
| |
| removeDdocView: function (viewName) { |
| if (!this.isDdoc()) return false; |
| var views = this.get('views'); |
| |
| delete views[viewName]; |
| this.set({views: views}); |
| }, |
| |
| dDocModel: function () { |
| if (!this.isDdoc()) return false; |
| var doc = this.get('doc'); |
| |
| if (doc) { |
| doc._rev = this.get('_rev'); |
| return new Documents.Doc(doc, {database: this.database}); |
| } |
| |
| return this; |
| }, |
| |
| safeID: function () { |
| return app.utils.getSafeIdForDoc(this.id); |
| }, |
| |
| destroy: function () { |
| var url = this.url() + "?rev=" + this.get('_rev'); |
| return $.ajax({ |
| url: url, |
| dataType: 'json', |
| type: 'DELETE' |
| }); |
| }, |
| |
| parse: function (resp) { |
| if (resp.rev) { |
| resp._rev = resp.rev; |
| delete resp.rev; |
| } |
| if (resp.id) { |
| if (_.isUndefined(this.id)) { |
| resp._id = resp.id; |
| } |
| } |
| |
| if (resp.ok) { |
| delete resp.id; |
| delete resp.ok; |
| } |
| |
| return resp; |
| }, |
| |
| prettyJSON: function () { |
| var data = this.get("doc") ? this.get("doc") : this.attributes; |
| |
| return JSON.stringify(data, null, " "); |
| }, |
| |
| copy: function (copyId) { |
| return $.ajax({ |
| type: 'COPY', |
| url: '/' + this.database.safeID() + '/' + this.safeID(), |
| headers: {Destination: copyId} |
| }); |
| }, |
| |
| isNewDoc: function () { |
| return this.get('_rev') ? false : true; |
| } |
| }); |
| |
| |
| Documents.AllDocs = PagingCollection.extend({ |
| model: Documents.Doc, |
| documentation: function () { |
| return FauxtonAPI.constants.DOC_URLS.GENERAL; |
| }, |
| initialize: function (_models, options) { |
| this.viewMeta = options.viewMeta; |
| this.database = options.database; |
| this.params = _.clone(options.params); |
| |
| this.on("remove", this.decrementTotalRows, this); |
| this.perPageLimit = options.perPageLimit || 20; |
| |
| if (!this.params.limit) { |
| this.params.limit = this.perPageLimit; |
| } |
| }, |
| |
| isEditable: function () { |
| return true; |
| }, |
| |
| urlRef: function (context, params) { |
| var query = ""; |
| |
| if (params) { |
| if (!_.isEmpty(params)) { |
| query = "?" + $.param(params); |
| } else { |
| query = ''; |
| } |
| } else if (this.params) { |
| query = "?" + $.param(this.params); |
| } |
| if (_.isUndefined(context)) { |
| context = 'server'; |
| } |
| return FauxtonAPI.urls('allDocs', context, this.database.safeID(), query); |
| }, |
| |
| url: function () { |
| return this.urlRef.apply(this, arguments); |
| }, |
| |
| simple: function () { |
| var docs = this.map(function (item) { |
| return { |
| _id: item.id, |
| _rev: item.get('_rev'), |
| }; |
| }); |
| |
| return new Documents.AllDocs(docs, { |
| database: this.database, |
| params: this.params |
| }); |
| }, |
| |
| totalRows: function () { |
| return this.viewMeta.total_rows || "unknown"; |
| }, |
| |
| decrementTotalRows: function () { |
| if (this.viewMeta.total_rows) { |
| this.viewMeta.total_rows = this.viewMeta.total_rows - 1; |
| this.trigger('totalRows:decrement'); |
| } |
| }, |
| |
| updateSeq: function () { |
| if (!this.viewMeta) { |
| return false; |
| } |
| return this.viewMeta.update_seq || false; |
| }, |
| |
| parse: function (resp) { |
| var rows = resp.rows; |
| |
| // remove any query errors that may return without doc info |
| // important for when querying keys on all docs |
| var cleanRows = _.filter(rows, function (row) { |
| return row.value; |
| }); |
| |
| resp.rows = _.map(cleanRows, function (row) { |
| var res = { |
| _id: row.id, |
| _rev: row.value.rev, |
| value: row.value, |
| key: row.key |
| }; |
| |
| if (row.doc) { |
| res.doc = row.doc; |
| } |
| |
| return res; |
| }); |
| |
| return PagingCollection.prototype.parse.call(this, resp); |
| }, |
| |
| clone: function () { |
| return new this.constructor(this.models, { |
| database: this.database, |
| params: this.params, |
| paging: this.paging |
| }); |
| } |
| }); |
| |
| return Documents; |
| }); |