PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/design/console/vendor/backbone.couchdb.js

http://github.com/couchbaselabs/Syncpoint-API
JavaScript | 181 lines | 144 code | 26 blank | 11 comment | 22 complexity | 04e780a5601d76e8312bae10090780a0 MD5 | raw file
Possible License(s): Apache-2.0
  1. /**
  2. * @author: Thomas Rampelberg <thomas@saunter.org>
  3. *
  4. * Copyright(c) 2011 Thomas Rampelberg
  5. */
  6. (function($) {
  7. Backbone.couch = {};
  8. Backbone.couch.options = {
  9. database: 'test',
  10. design: 'backbone'
  11. };
  12. Backbone.couch.utils = {
  13. _format_row: function(row) {
  14. _.extend(row, row.value ? { value: row.value } : {}, row.doc);
  15. // if (!row.id && row._id) row.id = row._id;
  16. // Since we reassigned these, remove them from the object;
  17. // delete row._id;
  18. delete row.doc;
  19. // if (!row.id) row.id = k;
  20. return row;
  21. },
  22. _ignores: [ 'view', 'update', 'filter', 'show', 'list' ],
  23. _remove: function(opts) {
  24. _.each(couch._ignores, function(v) {
  25. delete opts[v];
  26. });
  27. },
  28. model: {
  29. create: function(_db, model, cb) {
  30. var opts = (model.couch && model.couch()) || {};
  31. var method = _.bind(_db.saveDoc, _db);
  32. if ('update' in opts)
  33. method = _.bind(_db.updateDoc, _db, opts.update);
  34. couch._remove(opts);
  35. method(model.toJSON(), _.extend(opts, {
  36. success: function(resp) {
  37. cb.success(_.extend({
  38. _id: resp.id,
  39. _rev: resp.rev
  40. }, resp.doc));
  41. },
  42. error: cb.error
  43. }));
  44. },
  45. update: function(_db, model, cb) {
  46. this.create(_db, model, cb);
  47. },
  48. read: function(_db, model, cb) {
  49. var opts = (model.couch && model.couch()) || {};
  50. var method = _.bind(_db.openDoc, _db);
  51. if ('show' in opts)
  52. method = _.bind(_db.show, _db, opts.show);
  53. method(model.id, {
  54. success: cb.success,
  55. error: cb.error
  56. });
  57. },
  58. 'delete': function(_db, model, cb) {
  59. _db.removeDoc(_.extend({ _id: model.id }, model.toJSON()), {
  60. success: cb.success,
  61. error: cb.error
  62. });
  63. }
  64. },
  65. collection: {
  66. read: function(_db, model, cb) {
  67. var opts = model.couch();
  68. var method = null;
  69. if ('view' in opts)
  70. method = _.bind(_db.view, _db, opts.view);
  71. if ('list' in opts)
  72. method = _.bind(_db.list, _db, opts.list, opts.view.split('/')[1]);
  73. if (!method)
  74. throw new Error("The return of `couch()` must contain the view " +
  75. "and/or the list");
  76. couch._remove(opts);
  77. method(_.extend({
  78. success: function(resp) {
  79. cb.success(_.map(resp.rows, couch._format_row));
  80. },
  81. error: cb.error
  82. }, opts));
  83. }
  84. },
  85. sync: function(method, model, cb) {
  86. // XXX - This is going to be a memory issue unless someone does the
  87. // extend trick.
  88. var _db = this._db || (this.collection && this.collection._db);
  89. if (!_db) _db = this._db = Backbone.couch.db(
  90. Backbone.couch.options.database);
  91. var type = 'model' in model ? 'collection' : 'model';
  92. couch[type][method](_db, model, cb);
  93. }
  94. };
  95. Backbone.couch.db = function(name, db_opts) {
  96. if (!db_opts) db_opts = {};
  97. var old_prefix = $.couch.urlPrefix;
  98. $.couch.urlPrefix = db_opts.host || $.couch.urlPrefix;
  99. var ret = $.couch.db(name, db_opts);
  100. var base_func = function(path, fname, handler) {
  101. var current_uri = this.uri;
  102. var name = handler.split('/');
  103. this.uri = this.uri + '_design/' + name[0] + '/_' + path + '/' + name[1] +
  104. '/';
  105. this[fname].apply(this, _.toArray(arguments).slice(3));
  106. this.uri = current_uri;
  107. };
  108. _.extend(ret, {
  109. show: _.bind(base_func, ret, 'show', 'openDoc'),
  110. updateDoc: _.bind(base_func, ret, 'update', 'saveDoc')
  111. });
  112. $.couch.urlPrefix = old_prefix;
  113. return ret
  114. };
  115. var couch = Backbone.couch.utils;
  116. Backbone.couch.sync = couch.sync;
  117. Backbone.couch.Model = Backbone.Model.extend({
  118. sync: couch.sync,
  119. idAttribute: '_id'
  120. });
  121. Backbone.couch.Collection = Backbone.Collection.extend({
  122. model: Backbone.couch.Model,
  123. sync: couch.sync,
  124. change_feed: false,
  125. initialize: function() {
  126. _.bindAll(this, '_init_changes', '_on_change');
  127. if (this.change_feed)
  128. this._db.info({
  129. success: this._init_changes
  130. });
  131. },
  132. _init_changes: function(state) {
  133. var seq = state.update_seq || 0;
  134. var opts = { include_docs: true };
  135. var col_opts = this.couch();
  136. if ('filter' in col_opts)
  137. _.extend(opts, col_opts.filter);
  138. this._changes = this._db.changes(seq, opts);
  139. this._changes.onChange(this._on_change);
  140. },
  141. _on_change: function(changes) {
  142. var _this = this;
  143. _.each(changes.results, function(res) {
  144. var client_model = _this.get(res.id);
  145. if (client_model) {
  146. if (res.deleted) return _this.remove(client_model);
  147. if (client_model.get('_rev') == res.doc._rev) return
  148. return client_model.set(res.doc);
  149. }
  150. if (res.deleted) return
  151. _this.add(couch._format_row(res));
  152. });
  153. }
  154. });
  155. })(jQuery);