PageRenderTime 144ms CodeModel.GetById 27ms RepoModel.GetById 3ms app.codeStats 0ms

/js/backbone-couchdb.js

https://bitbucket.org/colinbate/listed
JavaScript | 274 lines | 247 code | 22 blank | 5 comment | 79 complexity | 4be3a6e13c54835abbaad606881607af MD5 | raw file
  1. /*
  2. (c) 2011 Jan Monschke
  3. v1.1
  4. backbone-couchdb.js is licensed under the MIT license.
  5. */
  6. (function() {
  7. var con,
  8. __hasProp = Object.prototype.hasOwnProperty,
  9. __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
  10. __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
  11. Backbone.couch_connector = con = {
  12. config: {
  13. db_name: "backbone_connect",
  14. ddoc_name: "backbone_example",
  15. view_name: "byCollection",
  16. global_changes: false,
  17. base_url: null
  18. },
  19. helpers: {
  20. extract_collection_name: function(model) {
  21. var _name, _splitted;
  22. if (model == null) throw new Error("No model has been passed");
  23. if (!(((model.collection != null) && (model.collection.url != null)) || (model.url != null))) {
  24. return "";
  25. }
  26. if (model.url != null) {
  27. _name = _.isFunction(model.url) ? model.url() : model.url;
  28. } else {
  29. _name = _.isFunction(model.collection.url) ? model.collection.url() : model.collection.url;
  30. }
  31. if (_name[0] === "/") _name = _name.slice(1, _name.length);
  32. _splitted = _name.split("/");
  33. _name = _splitted.length > 0 ? _splitted[0] : _name;
  34. _name = _name.replace("/", "");
  35. return _name;
  36. },
  37. make_db: function() {
  38. var db;
  39. db = $.couch.db(con.config.db_name);
  40. if (con.config.base_url != null) {
  41. db.uri = "" + con.config.base_url + "/" + con.config.db_name + "/";
  42. }
  43. return db;
  44. }
  45. },
  46. read: function(model, opts) {
  47. if (model.models) {
  48. return con.read_collection(model, opts);
  49. } else {
  50. return con.read_model(model, opts);
  51. }
  52. },
  53. read_collection: function(coll, opts) {
  54. var keys, _opts, _view,
  55. _this = this;
  56. _view = this.config.view_name;
  57. keys = [this.helpers.extract_collection_name(coll)];
  58. if (coll.db != null) {
  59. if (coll.db.changes || this.config.global_changes) {
  60. coll.listen_to_changes();
  61. }
  62. if (coll.db.view != null) _view = coll.db.view;
  63. if (coll.db.keys != null) keys = coll.db.keys;
  64. }
  65. _opts = {
  66. keys: keys,
  67. success: function(data) {
  68. var doc, _i, _len, _ref, _temp;
  69. _temp = [];
  70. _ref = data.rows;
  71. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  72. doc = _ref[_i];
  73. (doc.value) ? _temp.push(doc.value) : _temp.push(doc.doc);
  74. }
  75. opts.success(_temp);
  76. return opts.complete();
  77. },
  78. error: function() {
  79. opts.error();
  80. return opts.complete();
  81. }
  82. };
  83. if (opts.limit != null) _opts.limit = opts.limit;
  84. if (opts.skip != null) _opts.skip = opts.skip;
  85. if (opts.include_docs != null) _opts.include_docs = opts.include_docs;
  86. if (opts.startkey != null) _opts.startkey = opts.startkey;
  87. if (opts.endkey != null) _opts.endkey = opts.endkey;
  88. if (opts.startkey_docid != null) _opts.startkey_docid = opts.startkey_docid;
  89. if (opts.endkey_docid != null) _opts.endkey_docid = opts.endkey_docid;
  90. if ((coll.db != null) && (coll.db.view != null) && !(coll.db.keys != null)) {
  91. delete _opts.keys;
  92. }
  93. return this.helpers.make_db().view("" + this.config.ddoc_name + "/" + _view, _opts);
  94. },
  95. read_model: function(model, opts) {
  96. if (!model.id) {
  97. throw new Error("The model has no id property, so it can't get fetched from the database");
  98. }
  99. return this.helpers.make_db().openDoc(model.id, {
  100. success: function(doc) {
  101. opts.success(doc);
  102. return opts.complete();
  103. },
  104. error: function() {
  105. opts.error();
  106. return opts.complete();
  107. }
  108. });
  109. },
  110. create: function(model, opts) {
  111. var coll, vals;
  112. vals = model.toJSON();
  113. coll = this.helpers.extract_collection_name(model);
  114. if (coll.length > 0) vals.collection = coll;
  115. return this.helpers.make_db().saveDoc(vals, {
  116. success: function(doc) {
  117. opts.success({
  118. _id: doc.id,
  119. _rev: doc.rev
  120. });
  121. return opts.complete();
  122. },
  123. error: function() {
  124. opts.error();
  125. return opts.complete();
  126. }
  127. });
  128. },
  129. update: function(model, opts) {
  130. return this.create(model, opts);
  131. },
  132. del: function(model, opts) {
  133. return this.helpers.make_db().removeDoc(model.toJSON(), {
  134. success: function() {
  135. return opts.success();
  136. },
  137. error: function(nr, req, e) {
  138. if (e === "deleted") {
  139. opts.success();
  140. return opts.complete();
  141. } else {
  142. opts.error();
  143. return opts.complete();
  144. }
  145. }
  146. });
  147. }
  148. };
  149. Backbone.sync = function(method, model, opts) {
  150. if (opts.success == null) opts.success = function() {};
  151. if (opts.error == null) opts.error = function() {};
  152. if (opts.complete == null) opts.complete = function() {};
  153. switch (method) {
  154. case "read":
  155. return con.read(model, opts);
  156. case "create":
  157. return con.create(model, opts);
  158. case "update":
  159. return con.update(model, opts);
  160. case "delete":
  161. return con.del(model, opts);
  162. }
  163. };
  164. Backbone.Model = (function(_super) {
  165. __extends(Model, _super);
  166. function Model() {
  167. Model.__super__.constructor.apply(this, arguments);
  168. }
  169. Model.prototype.idAttribute = "_id";
  170. Model.prototype.clone = function() {
  171. var new_model;
  172. new_model = new this.constructor(this);
  173. if (new_model.attributes._id) delete new_model.attributes._id;
  174. if (new_model.attributes._rev) delete new_model.attributes._rev;
  175. return new_model;
  176. };
  177. return Model;
  178. })(Backbone.Model);
  179. Backbone.Collection = (function(_super) {
  180. __extends(Collection, _super);
  181. function Collection() {
  182. this._db_on_change = __bind(this._db_on_change, this);
  183. this._db_prepared_for_changes = __bind(this._db_prepared_for_changes, this);
  184. Collection.__super__.constructor.apply(this, arguments);
  185. }
  186. Collection.prototype.model = Backbone.Model;
  187. Collection.prototype.initialize = function() {
  188. if (!this._db_changes_enabled && ((this.db && this.db.changes) || con.config.global_changes)) {
  189. return this.listen_to_changes();
  190. }
  191. };
  192. Collection.prototype.listen_to_changes = function() {
  193. if (!this._db_changes_enabled) {
  194. this._db_changes_enabled = true;
  195. if (!this._db_inst) this._db_inst = con.helpers.make_db();
  196. return this._db_inst.info({
  197. "success": this._db_prepared_for_changes
  198. });
  199. }
  200. };
  201. Collection.prototype.stop_changes = function() {
  202. this._db_changes_enabled = false;
  203. if (this._db_changes_handler != null) {
  204. this._db_changes_handler.stop();
  205. return this._db_changes_handler = null;
  206. }
  207. };
  208. Collection.prototype._db_prepared_for_changes = function(data) {
  209. var opts,
  210. _this = this;
  211. this._db_update_seq = data.update_seq || 0;
  212. opts = {
  213. include_docs: true,
  214. collection: con.helpers.extract_collection_name(this),
  215. filter: "" + con.config.ddoc_name + "/by_collection"
  216. };
  217. _.extend(opts, this.db);
  218. return _.defer(function() {
  219. _this._db_changes_handler = _this._db_inst.changes(_this._db_update_seq, opts);
  220. return _this._db_changes_handler.onChange(_this._db_on_change);
  221. });
  222. };
  223. Collection.prototype._db_on_change = function(changes) {
  224. var obj, _doc, _i, _len, _ref, _results;
  225. _ref = changes.results;
  226. _results = [];
  227. for (_i = 0, _len = _ref.length; _i < _len; _i++) {
  228. _doc = _ref[_i];
  229. obj = this.get(_doc.id);
  230. if (obj != null) {
  231. if (_doc.deleted) {
  232. _results.push(this.remove(obj));
  233. } else {
  234. if (obj.get("_rev") !== _doc.doc._rev) {
  235. _results.push(obj.set(_doc.doc));
  236. } else {
  237. _results.push(void 0);
  238. }
  239. }
  240. } else {
  241. if (!_doc.deleted) {
  242. _results.push(this.add(_doc.doc));
  243. } else {
  244. _results.push(void 0);
  245. }
  246. }
  247. }
  248. return _results;
  249. };
  250. return Collection;
  251. })(Backbone.Collection);
  252. }).call(this);