<commit_before>// (c) 2011 <NAME>
//
// Based on <NAME> backbone.couchdb.js connector
// backbone.couchdb.js is licensed under the MIT license.

// I added the connector to the Backbone object.
Backbone.couchConnector = {
	// Name of the Database.
	databaseName : "",
	// Name of the design document that contains the views.
  ddocName : "",
  // Name of the view.
  viewName : "byCollection",
  // Enable updates via the couchdb _changes feed
  enableChanges : false,

  // If `baseUrl` is set, the default uri of jquery.couch.js will be overridden.
  // This is useful if you want to access a couch on another server e.g. `http://127.0.0.1:5984`
  // Important: Be aware of the Cross-Origin Policy.
  baseUrl : null,
  // A simple lookup table for collections that should be synched.
  _watchList : [],
  getCollectionFromModel : function(model){
    // I would like to use the Backbone `getUrl()` helper here but it's not in my scope.
    if (!(model && model.url))
      throw new Error("No url property/function!");
    var collectionName = _.isFunction(model.url) ? model.url() : model.url;
    collectionName = collectionName.replace("/","");
    var split = collectionName.split("/");
    // jquery.couch.js adds the id itself, so we delete the id if it is in the url.
    // "collection/:id" -> "collection"
    if(split.length > 1){
      collectionName = split[0];
    }
    return collectionName;
  },
  // Creates a couchDB object from the given model object.
  makeDb : function(model){
    var db = $.couch.db(this.databaseName);
    if(this.baseUrl){
      db.uri = this.baseUrl + "/" + this.databaseName + "/";
    }
    return db;
  },


  designDocChange : function(callback) {
    var db = this.makeDb(this.databaseName),
      currentDoc = "_design/" + this.ddocName;
    db.info({
      success : function(data){
        var since = (data.update_seq || 0)
        // Connect to the changes feed.
        var changesFeed = db.changes(since,{include_docs:true});
        changesFeed.onChange(function(changes) {
          if (_.select(changes.results, function(doc) { return doc.id === currentDoc}).length > 0) {
            callback(currentDoc);
          }
        });
      }
    })
  },

  // Fetches all docs from the given collection.
  // Therefore all docs from the view `ddocName`/`viewName` will be requested.
  // A simple view could look like this:
  //
  //    function(doc) {
  //        if(doc.collection)
  //            emit(doc.collection, doc);
  //    }
  //
  // doc.collection represents the url property of the collection and is automatically added to the model.
  readCollection : function(coll, _success, _error){
    var db = this.makeDb(coll);
    var collection = this.getCollectionFromModel(coll);
    var query = this.ddocName + "/" + this.viewName;

    var descending = coll.descending || false;
    // Query equals ddocName/viewName
    db.view(query,{
      // Only return docs that have this collection's name as key.
      descending: descending,
      keys : [collection],
      success:function(result){
        if(result.rows.length > 0){
          var arr = [];
          var model = {};
          var curr = {};
          // Prepare the result set for Backbone -> Only return the docs and no meta data.
          for (var i=0; i < result.rows.length; i++) {
            curr = result.rows[i];
            model = curr.value;
            if(!model.id)
              model.id = curr.id;
            arr.push(model);
          }
          _success(arr);
        }else{
          _success(null);
        }
      },
      error: _error
    });
    // Add the collection to the `_watchlist`.
    if(!this._watchList[collection]){
      this._watchList[collection] = coll;
    }

  },
  // Reads the state of one specific model from the server.
  readModel : function(model, _success, _error){
    var db = this.makeDb(model);
    db.openDoc(model.id,{
      success : function(doc){
        _success(doc);
      },
      error : _error
    });
  },
  // Creates a document.
  create : function(model, _success, _error){
    var db = this.makeDb(model);
    var data = model.toJSON();
    if(!data.collection){
      data.collection = this.getCollectionFromModel(model);
    }
    // Backbone finds out that an element has been
    // synched by checking for the existance of an `id` property in the model.
    // By returning the an object with an `id` we mark the model as synched.
    if(!data.id && data._id){
      data.id = data._id;
    }
    // jquery.couch.js automatically finds out whether the document is new
    // or already exists by checking for the _id property.
    db.saveDoc(data,{
      success : function(resp){
        // When the document has been successfully created/altered, return
        // the created/changed values.
        _success({
          "id" : resp.id,
          "_id" : resp.id,
          "_rev" : resp.rev
        });
      },
      error : function(nr){
        // document already exists, we don't care ;)
        if(nr == 409){
          _error();
        }else{
          _error();
        }
      }
    });
  },
  // jquery.couch.js provides the same method for updating and creating a document,
  // so we can use the `create` method here.
  update : function(model, _success, _error){
    this.create(model, _success, _error);
  },
  // Deletes the document via the removeDoc method.
  del : function(model, _success, _error){
    var db = this.makeDb(model);
    var data = model.toJSON();
    db.removeDoc(data,{
      success: function(){
        _success();
      },
      error: function(nr,req,e){
        if(e == "deleted"){
          console.log("The Doc could not be deleted because it was already deleted from the server.");
          _success();
        }else{
          _error();
        }

      }
    });
  },
  // The _changes feed is one of the coolest things about CouchDB in my opinion.
  // It enables you to get real time updates of changes in your database.
  // If `enableChanges` is true the connector automatically listens to changes in the database
  // and updates the changed models. -> Remotely triggered events in your models and collections. YES!
  _changes : function(model){
    var db = this.makeDb(model);
    var connector = this;
    // First grab the `update_seq` from the database info, so that we only receive newest changes.
    db.info({
      success : function(data){
        var since = (data.update_seq || 0)
        // Connect to the changes feed.
        connector.changesFeed = db.changes(since,{include_docs:true});
        connector.changesFeed.onChange(function(changes){
          var doc,coll,model,ID;
          // Iterate over the changed docs and validate them.
          for (var i=0; i < changes.results.length; i++) {
            doc = changes.results[i].doc;
            if(doc.collection){
              coll = connector._watchList[doc.collection];
              if(coll){
                ID = (doc.id || doc._id);
                model = coll.get(ID);
                if(model){
                  // Check if the model on this client has changed by comparing `rev`.
                  if(doc._rev != model.get("_rev")){<commit_msg>move ddoc change detection to main _changes - to eliminate second opened longpoll connection, additionaly added continue to skip current ddoc from conditions checking.<commit_after>// (c) 2011 <NAME>
//
// Based on Jan Monschke backbone.couchdb.js connector
// backbone.couchdb.js is licensed under the MIT license.

// I added the connector to the Backbone object.
Backbone.couchConnector = {
	// Name of the Database.
	databaseName : "",
	// Name of the design document that contains the views.
  ddocName : "",
  // Name of the view.
  viewName : "byCollection",
  // Enable updates via the couchdb _changes feed
  enableChanges : false,

  // If `baseUrl` is set, the default uri of jquery.couch.js will be overridden.
  // This is useful if you want to access a couch on another server e.g. `http://127.0.0.1:5984`
  // Important: Be aware of the Cross-Origin Policy.
  baseUrl : null,
  // A simple lookup table for collections that should be synched.
  _watchList : [],
  getCollectionFromModel : function(model){
    // I would like to use the Backbone `getUrl()` helper here but it's not in my scope.
    if (!(model && model.url))
      throw new Error("No url property/function!");
    var collectionName = _.isFunction(model.url) ? model.url() : model.url;
    collectionName = collectionName.replace("/","");
    var split = collectionName.split("/");
    // jquery.couch.js adds the id itself, so we delete the id if it is in the url.
    // "collection/:id" -> "collection"
    if(split.length > 1){
      collectionName = split[0];
    }
    return collectionName;
  },
  // Creates a couchDB object from the given model object.
  makeDb : function(model){
    var db = $.couch.db(this.databaseName);
    if(this.baseUrl){
      db.uri = this.baseUrl + "/" + this.databaseName + "/";
    }
    return db;
  },


  designDocChange : function(callback) {
    this.ddocChangeHandler = callback;
  },

  // Fetches all docs from the given collection.
  // Therefore all docs from the view `ddocName`/`viewName` will be requested.
  // A simple view could look like this:
  //
  //    function(doc) {
  //        if(doc.collection)
  //            emit(doc.collection, doc);
  //    }
  //
  // doc.collection represents the url property of the collection and is automatically added to the model.
  readCollection : function(coll, _success, _error){
    var db = this.makeDb(coll);
    var collection = this.getCollectionFromModel(coll);
    var query = this.ddocName + "/" + this.viewName;

    var descending = coll.descending || false;
    // Query equals ddocName/viewName
    db.view(query,{
      // Only return docs that have this collection's name as key.
      descending: descending,
      keys : [collection],
      success:function(result){
        if(result.rows.length > 0){
          var arr = [];
          var model = {};
          var curr = {};
          // Prepare the result set for Backbone -> Only return the docs and no meta data.
          for (var i=0; i < result.rows.length; i++) {
            curr = result.rows[i];
            model = curr.value;
            if(!model.id)
              model.id = curr.id;
            arr.push(model);
          }
          _success(arr);
        }else{
          _success(null);
        }
      },
      error: _error
    });
    // Add the collection to the `_watchlist`.
    if(!this._watchList[collection]){
      this._watchList[collection] = coll;
    }

  },
  // Reads the state of one specific model from the server.
  readModel : function(model, _success, _error){
    var db = this.makeDb(model);
    db.openDoc(model.id,{
      success : function(doc){
        _success(doc);
      },
      error : _error
    });
  },
  // Creates a document.
  create : function(model, _success, _error){
    var db = this.makeDb(model);
    var data = model.toJSON();
    if(!data.collection){
      data.collection = this.getCollectionFromModel(model);
    }
    // Backbone finds out that an element has been
    // synched by checking for the existance of an `id` property in the model.
    // By returning the an object with an `id` we mark the model as synched.
    if(!data.id && data._id){
      data.id = data._id;
    }
    // jquery.couch.js automatically finds out whether the document is new
    // or already exists by checking for the _id property.
    db.saveDoc(data,{
      success : function(resp){
        // When the document has been successfully created/altered, return
        // the created/changed values.
        _success({
          "id" : resp.id,
          "_id" : resp.id,
          "_rev" : resp.rev
        });
      },
      error : function(nr){
        // document already exists, we don't care ;)
        if(nr == 409){
          _error();
        }else{
          _error();
        }
      }
    });
  },
  // jquery.couch.js provides the same method for updating and creating a document,
  // so we can use the `create` method here.
  update : function(model, _success, _error){
    this.create(model, _success, _error);
  },
  // Deletes the document via the removeDoc method.
  del : function(model, _success, _error){
    var db = this.makeDb(model);
    var data = model.toJSON();
    db.removeDoc(data,{
      success: function(){
        _success();
      },
      error: function(nr,req,e){
        if(e == "deleted"){
          console.log("The Doc could not be deleted because it was already deleted from the server.");
          _success();
        }else{
          _error();
        }

      }
    });
  },
  // The _changes feed is one of the coolest things about CouchDB in my opinion.
  // It enables you to get real time updates of changes in your database.
  // If `enableChanges` is true the connector automatically listens to changes in the database
  // and updates the changed models. -> Remotely triggered events in your models and collections. YES!
  _changes : function(model){
    var db = this.makeDb(model),
      connector = this,
      currentDoc = "_design/" + this.ddocName;
    // First grab the `update_seq` from the database info, so that we only receive newest changes.
    db.info({
      success : function(data){
        var since = (data.update_seq || 0);
        // Connect to the changes feed.
        connector.changesFeed = db.changes(since,{include_docs:true});
        connector.changesFeed.onChange(function(changes){
          var doc,coll,model,ID;
          // Iterate over the changed docs and validate them.
          for (var i=0; i < changes.results.length; i++) {

            doc = changes.results[i].doc;
            if (typeof connector.ddocChangeHandler === "function" && (doc._id === currentDoc || doc.id === currentDoc)) {
              connector.ddocChangeHandler(currentDoc);
              continue;
            }

            if(doc.collection){
              coll = connector._watchList[doc.collection];
              if(coll){
                ID = (doc.id || doc._id);
                model = coll.get(ID);
                if(model){
                  // Check if the model on this client has changed by comparing `rev`.
                  if(doc._rev != model.get("_rev")){
{'fraction_non_alphanumeric': 0.11810639336261591, 'fraction_numerical': 0.003346580213344489, 'mean_word_length': 2.2147019273868223, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1051461', 'n_tokens_mistral': 4178, 'n_tokens_neox': 4060, 'n_words': 1358}