PageRenderTime 26ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/src/fauxton/app/modules/documents/resources.js

https://github.com/benoitc/couchdb
JavaScript | 255 lines | 189 code | 46 blank | 20 comment | 24 complexity | de63bb5c1697f6814f5423f0ab50742e MD5 | raw file
  1. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  2. // use this file except in compliance with the License. You may obtain a copy of
  3. // the License at
  4. //
  5. // http://www.apache.org/licenses/LICENSE-2.0
  6. //
  7. // Unless required by applicable law or agreed to in writing, software
  8. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  9. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  10. // License for the specific language governing permissions and limitations under
  11. // the License.
  12. define([
  13. "app",
  14. "api",
  15. // Views
  16. "modules/documents/views"
  17. // Plugins
  18. ],
  19. function(app, FauxtonAPI, Views) {
  20. var Documents = app.module();
  21. Documents.Doc = Backbone.Model.extend({
  22. idAttribute: "_id",
  23. url: function(context) {
  24. if (context === "app") {
  25. return this.getDatabase().url("app") + "/" + this.safeID();
  26. } else {
  27. return app.host + "/" + this.getDatabase().id + "/" + this.id;
  28. }
  29. },
  30. initialize: function() {
  31. if (this.collection && this.collection.database) {
  32. this.database = this.collection.database;
  33. }
  34. },
  35. // HACK: the doc needs to know about the database, but it may be
  36. // set directly or indirectly in all docs
  37. getDatabase: function() {
  38. return this.database ? this.database : this.collection.database;
  39. },
  40. docType: function() {
  41. return this.id.match(/^_design/) ? "design doc" : "doc";
  42. },
  43. isEditable: function() {
  44. return this.docType() != "reduction";
  45. },
  46. isDdoc: function() {
  47. return this.docType() === "design doc";
  48. },
  49. hasViews: function() {
  50. if (!this.isDdoc()) return false;
  51. var doc = this.get('doc');
  52. return doc && doc.views && _.keys(doc.views).length > 0;
  53. },
  54. getDdocView: function(view) {
  55. if (!this.isDdoc() || !this.hasViews()) return false;
  56. var doc = this.get('doc');
  57. return doc.views[view];
  58. },
  59. viewHasReduce: function(viewName) {
  60. var view = this.getDdocView(viewName);
  61. return view && view.reduce;
  62. },
  63. // Need this to work around backbone router thinking _design/foo
  64. // is a separate route. Alternatively, maybe these should be
  65. // treated separately. For instance, we could default into the
  66. // json editor for docs, or into a ddoc specific page.
  67. safeID: function() {
  68. return this.id.replace('/', '%2F');
  69. },
  70. destroy: function() {
  71. var url = this.url() + "?rev=" + this.get('_rev');
  72. return $.ajax({
  73. url: url,
  74. dataType: 'json',
  75. type: 'DELETE'
  76. });
  77. },
  78. parse: function(resp) {
  79. if (resp.rev) {
  80. resp._rev = resp.rev;
  81. delete resp.rev;
  82. }
  83. if (resp.id) {
  84. if (typeof(this.id) === "undefined") {
  85. resp._id = resp.id;
  86. }
  87. delete resp.id;
  88. }
  89. if (resp.ok) {
  90. delete resp.ok;
  91. }
  92. return resp;
  93. },
  94. prettyJSON: function() {
  95. var data = this.get("doc") ? this.get("doc") : this;
  96. return JSON.stringify(data, null, " ");
  97. }
  98. });
  99. Documents.ViewRow = Backbone.Model.extend({
  100. docType: function() {
  101. if (!this.id) return "reduction";
  102. return this.id.match(/^_design/) ? "design doc" : "doc";
  103. },
  104. isEditable: function() {
  105. return this.docType() != "reduction";
  106. },
  107. prettyJSON: function() {
  108. //var data = this.get("doc") ? this.get("doc") : this;
  109. return JSON.stringify(this, null, " ");
  110. }
  111. });
  112. Documents.NewDoc = Documents.Doc.extend({
  113. fetch: function() {
  114. var uuid = new FauxtonAPI.UUID();
  115. var deferred = this.deferred = $.Deferred();
  116. var that = this;
  117. uuid.fetch().done(function() {
  118. that.set("_id", uuid.next());
  119. deferred.resolve();
  120. });
  121. return deferred.promise();
  122. }
  123. });
  124. Documents.AllDocs = Backbone.Collection.extend({
  125. model: Documents.Doc,
  126. initialize: function(_models, options) {
  127. this.database = options.database;
  128. this.params = options.params;
  129. },
  130. url: function() {
  131. var query = "";
  132. if (this.params) {
  133. query = "?" + $.param(this.params);
  134. }
  135. return app.host + "/" + this.database.id + "/_all_docs" + query;
  136. },
  137. totalRows: function() {
  138. return this.viewMeta.total_rows || "unknown";
  139. },
  140. updateSeq: function() {
  141. return this.viewMeta.update_seq || false;
  142. },
  143. parse: function(resp) {
  144. that = this;
  145. this.viewMeta = {
  146. total_rows: resp.total_rows,
  147. offest: resp.offest,
  148. update_seq: resp.update_seq
  149. };
  150. return _.map(resp.rows, function(row) {
  151. return {
  152. _id: row.id,
  153. _rev: row.value.rev,
  154. value: row.value,
  155. key: row.key,
  156. doc: row.doc || undefined
  157. };
  158. });
  159. }
  160. });
  161. Documents.IndexCollection = Backbone.Collection.extend({
  162. model: Documents.ViewRow,
  163. initialize: function(_models, options) {
  164. this.database = options.database;
  165. this.view = options.view;
  166. this.design = options.design;
  167. this.params = _.extend({limit: 10, reduce: false}, options.params);
  168. this.idxType = "_view";
  169. },
  170. url: function() {
  171. var query = "";
  172. if (this.params) {
  173. query = "?" + $.param(this.params);
  174. }
  175. var url = [app.host, this.database.id, "_design", this.design, this.idxType, this.view];
  176. return url.join("/") + query;
  177. },
  178. totalRows: function() {
  179. return this.viewMeta.total_rows || "unknown";
  180. },
  181. updateSeq: function() {
  182. return this.viewMeta.update_seq || false;
  183. },
  184. parse: function(resp) {
  185. that = this;
  186. this.viewMeta = {
  187. total_rows: resp.total_rows,
  188. offest: resp.offest,
  189. update_seq: resp.update_seq
  190. };
  191. return _.map(resp.rows, function(row) {
  192. return {
  193. value: row.value,
  194. key: row.key,
  195. doc: row.doc,
  196. id: row.id
  197. };
  198. });
  199. },
  200. buildAllDocs: function(){
  201. this.fetch();
  202. },
  203. allDocs: function(){
  204. return this.models;
  205. }
  206. });
  207. Documents.Views = Views;
  208. return Documents;
  209. });