/share/www/script/jquery.couch.js
JavaScript | 1079 lines | 635 code | 50 blank | 394 comment | 121 complexity | 9cc59cdfbc7f922ac750e3b183aa3339 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
- // 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.
- /**
- * @namespace
- * $.couch is used to communicate with a CouchDB server, the server methods can
- * be called directly without creating an instance. Typically all methods are
- * passed an <code>options</code> object which defines a success callback which
- * is called with the data returned from the http request to CouchDB, you can
- * find the other settings that can be used in the <code>options</code> object
- * from <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
- * jQuery.ajax settings</a>
- * <pre><code>$.couch.activeTasks({
- * success: function (data) {
- * console.log(data);
- * }
- * });</code></pre>
- * Outputs (for example):
- * <pre><code>[
- * {
- * "pid" : "<0.11599.0>",
- * "status" : "Copied 0 of 18369 changes (0%)",
- * "task" : "recipes",
- * "type" : "Database Compaction"
- * }
- *]</code></pre>
- */
- (function($) {
- $.couch = $.couch || {};
- /** @lends $.couch */
- /**
- * @private
- */
- function encodeDocId(docID) {
- var parts = docID.split("/");
- if (parts[0] == "_design") {
- parts.shift();
- return "_design/" + encodeURIComponent(parts.join('/'));
- }
- return encodeURIComponent(docID);
- }
- /**
- * @private
- */
- var uuidCache = [];
- $.extend($.couch, {
- urlPrefix: '',
- /**
- * You can obtain a list of active tasks by using the /_active_tasks URL.
- * The result is a JSON array of the currently running tasks, with each task
- * being described with a single object.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/uploads/
- * all/documentation/couchbase-api-misc.html#couchbase-api-misc_active-task
- * s_get">docs for /_active_tasks</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/jQuery.ajax
- * /#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- activeTasks: function(options) {
- ajax(
- {url: this.urlPrefix + "/_active_tasks"},
- options,
- "Active task status could not be retrieved"
- );
- },
- /**
- * Returns a list of all the databases in the CouchDB instance
- * @see <a href="http://techzone.couchbase.com/sites/default/files/uploads/
- * all/documentation/couchbase-api-misc.html#couchbase-api-misc_active-task
- * s_get">docs for /_all_dbs</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/jQuery.ajax
- * /#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- allDbs: function(options) {
- ajax(
- {url: this.urlPrefix + "/_all_dbs"},
- options,
- "An error occurred retrieving the list of all databases"
- );
- },
- /**
- * View and edit the CouchDB configuration, called with just the options
- * parameter the entire config is returned, you can be more specific by
- * passing the section and option parameters, if you specify a value that
- * value will be stored in the configuration.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/uploads/
- * all/documentation/couchbase-api-config.html#couchbase-api-config_config
- * -section-key_put">docs for /_config</a>
- * @param {ajaxSettings} options
- * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
- * jQuery ajax settings</a>
- * @param {String} [section] the section of the config
- * @param {String} [option] the particular config option
- * @param {String} [value] value to be set
- */
- config: function(options, section, option, value) {
- var req = {url: this.urlPrefix + "/_config/"};
- if (section) {
- req.url += encodeURIComponent(section) + "/";
- if (option) {
- req.url += encodeURIComponent(option);
- }
- }
- if (value === null) {
- req.type = "DELETE";
- } else if (value !== undefined) {
- req.type = "PUT";
- req.data = toJSON(value);
- req.contentType = "application/json";
- req.processData = false
- }
- ajax(req, options,
- "An error occurred retrieving/updating the server configuration"
- );
- },
-
- /**
- * Returns the session information for the currently logged in user.
- * @param {ajaxSettings} options
- * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
- * jQuery ajax settings</a>
- */
- session: function(options) {
- options = options || {};
- ajax({
- type: "GET", url: this.urlPrefix + "/_session",
- beforeSend: function(xhr) {
- xhr.setRequestHeader('Accept', 'application/json');
- },
- complete: function(req) {
- var resp = $.parseJSON(req.responseText);
- if (req.status == 200) {
- if (options.success) options.success(resp);
- } else if (options.error) {
- options.error(req.status, resp.error, resp.reason);
- } else {
- throw "An error occurred getting session info: " + resp.reason;
- }
- }
- });
- },
- /**
- * @private
- */
- userDb : function(callback) {
- $.couch.session({
- success : function(resp) {
- var userDb = $.couch.db(resp.info.authentication_db);
- callback(userDb);
- }
- });
- },
- /**
- * Create a new user on the CouchDB server, <code>user_doc</code> is an
- * object with a <code>name</code> field and other information you want
- * to store relating to that user, for example
- * <code>{"name": "daleharvey"}</code>
- * @param {Object} user_doc Users details
- * @param {String} password Users password
- * @param {ajaxSettings} options
- * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
- * jQuery ajax settings</a>
- */
- signup: function(user_doc, password, options) {
- options = options || {};
- user_doc.password = password;
- user_doc.roles = user_doc.roles || [];
- user_doc.type = user_doc.type = "user" || [];
- var user_prefix = "org.couchdb.user:";
- user_doc._id = user_doc._id || user_prefix + user_doc.name;
- $.couch.userDb(function(db) {
- db.saveDoc(user_doc, options);
- });
- },
- /**
- * Authenticate against CouchDB, the <code>options</code> parameter is
- *expected to have <code>name</code> and <code>password</code> fields.
- * @param {ajaxSettings} options
- * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
- * jQuery ajax settings</a>
- */
- login: function(options) {
- options = options || {};
- $.ajax({
- type: "POST", url: this.urlPrefix + "/_session", dataType: "json",
- data: {name: options.name, password: options.password},
- beforeSend: function(xhr) {
- xhr.setRequestHeader('Accept', 'application/json');
- },
- complete: function(req) {
- var resp = $.parseJSON(req.responseText);
- if (req.status == 200) {
- if (options.success) options.success(resp);
- } else if (options.error) {
- options.error(req.status, resp.error, resp.reason);
- } else {
- throw 'An error occurred logging in: ' + resp.reason;
- }
- }
- });
- },
- /**
- * Delete your current CouchDB user session
- * @param {ajaxSettings} options
- * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
- * jQuery ajax settings</a>
- */
- logout: function(options) {
- options = options || {};
- $.ajax({
- type: "DELETE", url: this.urlPrefix + "/_session", dataType: "json",
- username : "_", password : "_",
- beforeSend: function(xhr) {
- xhr.setRequestHeader('Accept', 'application/json');
- },
- complete: function(req) {
- var resp = $.parseJSON(req.responseText);
- if (req.status == 200) {
- if (options.success) options.success(resp);
- } else if (options.error) {
- options.error(req.status, resp.error, resp.reason);
- } else {
- throw 'An error occurred logging out: ' + resp.reason;
- }
- }
- });
- },
- /**
- * @namespace
- * $.couch.db is used to communicate with a specific CouchDB database
- * <pre><code>var $db = $.couch.db("mydatabase");
- *$db.allApps({
- * success: function (data) {
- * ... process data ...
- * }
- *});
- * </code></pre>
- */
- db: function(name, db_opts) {
- db_opts = db_opts || {};
- var rawDocs = {};
- function maybeApplyVersion(doc) {
- if (doc._id && doc._rev && rawDocs[doc._id] &&
- rawDocs[doc._id].rev == doc._rev) {
- // todo: can we use commonjs require here?
- if (typeof Base64 == "undefined") {
- throw 'Base64 support not found.';
- } else {
- doc._attachments = doc._attachments || {};
- doc._attachments["rev-"+doc._rev.split("-")[0]] = {
- content_type :"application/json",
- data : Base64.encode(rawDocs[doc._id].raw)
- };
- return true;
- }
- }
- };
- return /** @lends $.couch.db */{
- name: name,
- uri: this.urlPrefix + "/" + encodeURIComponent(name) + "/",
- /**
- * Request compaction of the specified database.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db_
- * db-compact_post">docs for /db/_compact</a>
- * @param {ajaxSettings} options
- * <a href="http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings">
- * jQuery ajax settings</a>
- */
- compact: function(options) {
- $.extend(options, {successStatus: 202});
- ajax({
- type: "POST", url: this.uri + "_compact",
- data: "", processData: false
- },
- options,
- "The database could not be compacted"
- );
- },
- /**
- * Cleans up the cached view output on disk for a given view.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db
- * _db-view-cleanup_post">docs for /db/_compact</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- viewCleanup: function(options) {
- $.extend(options, {successStatus: 202});
- ajax({
- type: "POST", url: this.uri + "_view_cleanup",
- data: "", processData: false
- },
- options,
- "The views could not be cleaned up"
- );
- },
- /**
- * Compacts the view indexes associated with the specified design
- * document. You can use this in place of the full database compaction
- * if you know a specific set of view indexes have been affected by a
- * recent database change.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/upl
- * oads/all/documentation/couchbase-api-db.html#couchbase-api-db_db-
- * compact-design-doc_post">docs for /db/_compact/design-doc</a>
- * @param {String} groupname Name of design-doc to compact
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- compactView: function(groupname, options) {
- $.extend(options, {successStatus: 202});
- ajax({
- type: "POST", url: this.uri + "_compact/" + groupname,
- data: "", processData: false
- },
- options,
- "The view could not be compacted"
- );
- },
- /**
- * Create a new database
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db_
- * db_put">docs for PUT /db/</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- create: function(options) {
- $.extend(options, {successStatus: 201});
- ajax({
- type: "PUT", url: this.uri, contentType: "application/json",
- data: "", processData: false
- },
- options,
- "The database could not be created"
- );
- },
- /**
- * Deletes the specified database, and all the documents and
- * attachments contained within it.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db_
- * db_delete">docs for DELETE /db/</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- drop: function(options) {
- ajax(
- {type: "DELETE", url: this.uri},
- options,
- "The database could not be deleted"
- );
- },
- /**
- * Gets information about the specified database.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db
- * _db_get">docs for GET /db/</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- info: function(options) {
- ajax(
- {url: this.uri},
- options,
- "Database information could not be retrieved"
- );
- },
- /**
- * @namespace
- * $.couch.db.changes provides an API for subscribing to the changes
- * feed
- * <pre><code>var $changes = $.couch.db("mydatabase").changes();
- *$changes.onChange = function (data) {
- * ... process data ...
- * }
- * $changes.stop();
- * </code></pre>
- */
- changes: function(since, options) {
- options = options || {};
- // set up the promise object within a closure for this handler
- var timeout = 100, db = this, active = true,
- listeners = [],
- promise = /** @lends $.couch.db.changes */ {
- /**
- * Add a listener callback
- * @see <a href="http://techzone.couchbase.com/sites/default/
- * files/uploads/all/documentation/couchbase-api-db.html#couch
- * base-api-db_db-changes_get">docs for /db/_changes</a>
- * @param {Function} fun Callback function to run when
- * notified of changes.
- */
- onChange : function(fun) {
- listeners.push(fun);
- },
- /**
- * Stop subscribing to the changes feed
- */
- stop : function() {
- active = false;
- }
- };
- // call each listener when there is a change
- function triggerListeners(resp) {
- $.each(listeners, function() {
- this(resp);
- });
- };
- // when there is a change, call any listeners, then check for
- // another change
- options.success = function(resp) {
- timeout = 100;
- if (active) {
- since = resp.last_seq;
- triggerListeners(resp);
- getChangesSince();
- };
- };
- options.error = function() {
- if (active) {
- setTimeout(getChangesSince, timeout);
- timeout = timeout * 2;
- }
- };
- // actually make the changes request
- function getChangesSince() {
- var opts = $.extend({heartbeat : 10 * 1000}, options, {
- feed : "longpoll",
- since : since
- });
- ajax(
- {url: db.uri + "_changes"+encodeOptions(opts)},
- options,
- "Error connecting to "+db.uri+"/_changes."
- );
- }
- // start the first request
- if (since) {
- getChangesSince();
- } else {
- db.info({
- success : function(info) {
- since = info.update_seq;
- getChangesSince();
- }
- });
- }
- return promise;
- },
- /**
- * Fetch all the docs in this db, you can specify an array of keys to
- * fetch by passing the <code>keys</code> field in the
- * <code>options</code>
- * parameter.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db_
- * db-all-docs_get">docs for /db/all_docs/</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- allDocs: function(options) {
- var type = "GET";
- var data = null;
- if (options["keys"]) {
- type = "POST";
- var keys = options["keys"];
- delete options["keys"];
- data = toJSON({ "keys": keys });
- }
- ajax({
- type: type,
- data: data,
- url: this.uri + "_all_docs" + encodeOptions(options)
- },
- options,
- "An error occurred retrieving a list of all documents"
- );
- },
- /**
- * Fetch all the design docs in this db
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- allDesignDocs: function(options) {
- this.allDocs($.extend(
- {startkey:"_design", endkey:"_design0"}, options));
- },
- /**
- * Fetch all the design docs with an index.html, <code>options</code>
- * parameter expects an <code>eachApp</code> field which is a callback
- * called on each app found.
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- allApps: function(options) {
- options = options || {};
- var self = this;
- if (options.eachApp) {
- this.allDesignDocs({
- success: function(resp) {
- $.each(resp.rows, function() {
- self.openDoc(this.id, {
- success: function(ddoc) {
- var index, appPath, appName = ddoc._id.split('/');
- appName.shift();
- appName = appName.join('/');
- index = ddoc.couchapp && ddoc.couchapp.index;
- if (index) {
- appPath = ['', name, ddoc._id, index].join('/');
- } else if (ddoc._attachments &&
- ddoc._attachments["index.html"]) {
- appPath = ['', name, ddoc._id, "index.html"].join('/');
- }
- if (appPath) options.eachApp(appName, appPath, ddoc);
- }
- });
- });
- }
- });
- } else {
- throw 'Please provide an eachApp function for allApps()';
- }
- },
- /**
- * Returns the specified doc from the specified db.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-dbdoc.html#couchbase-api-
- * dbdoc_db-doc_get">docs for GET /db/doc</a>
- * @param {String} docId id of document to fetch
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- * @param {ajaxSettings} ajaxOptions <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- openDoc: function(docId, options, ajaxOptions) {
- options = options || {};
- if (db_opts.attachPrevRev || options.attachPrevRev) {
- $.extend(options, {
- beforeSuccess : function(req, doc) {
- rawDocs[doc._id] = {
- rev : doc._rev,
- raw : req.responseText
- };
- }
- });
- } else {
- $.extend(options, {
- beforeSuccess : function(req, doc) {
- if (doc["jquery.couch.attachPrevRev"]) {
- rawDocs[doc._id] = {
- rev : doc._rev,
- raw : req.responseText
- };
- }
- }
- });
- }
- ajax({url: this.uri + encodeDocId(docId) + encodeOptions(options)},
- options,
- "The document could not be retrieved",
- ajaxOptions
- );
- },
- /**
- * Create a new document in the specified database, using the supplied
- * JSON document structure. If the JSON structure includes the _id
- * field, then the document will be created with the specified document
- * ID. If the _id field is not specified, a new unique ID will be
- * generated.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-dbdoc.html#couchbase-api-
- * dbdoc_db_post">docs for GET /db/doc</a>
- * @param {String} doc document to save
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- saveDoc: function(doc, options) {
- options = options || {};
- var db = this;
- var beforeSend = fullCommit(options);
- if (doc._id === undefined) {
- var method = "POST";
- var uri = this.uri;
- } else {
- var method = "PUT";
- var uri = this.uri + encodeDocId(doc._id);
- }
- var versioned = maybeApplyVersion(doc);
- $.ajax({
- type: method, url: uri + encodeOptions(options),
- contentType: "application/json",
- dataType: "json", data: toJSON(doc),
- beforeSend : beforeSend,
- complete: function(req) {
- var resp = $.parseJSON(req.responseText);
- if (req.status == 200 || req.status == 201 || req.status == 202) {
- doc._id = resp.id;
- doc._rev = resp.rev;
- if (versioned) {
- db.openDoc(doc._id, {
- attachPrevRev : true,
- success : function(d) {
- doc._attachments = d._attachments;
- if (options.success) options.success(resp);
- }
- });
- } else {
- if (options.success) options.success(resp);
- }
- } else if (options.error) {
- options.error(req.status, resp.error, resp.reason);
- } else {
- throw "The document could not be saved: " + resp.reason;
- }
- }
- });
- },
- /**
- * Save a list of documents
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db_
- * db-bulk-docs_post">docs for /db/_bulk_docs</a>
- * @param {Object[]} docs List of documents to save
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- bulkSave: function(docs, options) {
- var beforeSend = fullCommit(options);
- $.extend(options, {successStatus: 201, beforeSend : beforeSend});
- ajax({
- type: "POST",
- url: this.uri + "_bulk_docs" + encodeOptions(options),
- contentType: "application/json", data: toJSON(docs)
- },
- options,
- "The documents could not be saved"
- );
- },
- /**
- * Deletes the specified document from the database. You must supply
- * the current (latest) revision and <code>id</code> of the document
- * to delete eg <code>removeDoc({_id:"mydoc", _rev: "1-2345"})</code>
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-dbdoc.html#couchbase-api
- * -dbdoc_db-doc_delete">docs for DELETE /db/doc</a>
- * @param {Object} doc Document to delete
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- removeDoc: function(doc, options) {
- ajax({
- type: "DELETE",
- url: this.uri +
- encodeDocId(doc._id) +
- encodeOptions({rev: doc._rev})
- },
- options,
- "The document could not be deleted"
- );
- },
- /**
- * Remove a set of documents
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db_
- * db-bulk-docs_post">docs for /db/_bulk_docs</a>
- * @param {String[]} docs List of document id's to remove
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- bulkRemove: function(docs, options){
- docs.docs = $.each(
- docs.docs, function(i, doc){
- doc._deleted = true;
- }
- );
- $.extend(options, {successStatus: 201});
- ajax({
- type: "POST",
- url: this.uri + "_bulk_docs" + encodeOptions(options),
- data: toJSON(docs)
- },
- options,
- "The documents could not be deleted"
- );
- },
- /**
- * The COPY command (which is non-standard HTTP) copies an existing
- * document to a new or existing document.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-dbdoc.html#couchbase-api-
- * dbdoc_db-doc_copy">docs for COPY /db/doc</a>
- * @param {String[]} docId document id to copy
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- copyDoc: function(docId, options, ajaxOptions) {
- ajaxOptions = $.extend(ajaxOptions, {
- complete: function(req) {
- var resp = $.parseJSON(req.responseText);
- if (req.status == 201) {
- if (options.success) options.success(resp);
- } else if (options.error) {
- options.error(req.status, resp.error, resp.reason);
- } else {
- throw "The document could not be copied: " + resp.reason;
- }
- }
- });
- ajax({
- type: "COPY",
- url: this.uri + encodeDocId(docId)
- },
- options,
- "The document could not be copied",
- ajaxOptions
- );
- },
- /**
- * Creates (and executes) a temporary view based on the view function
- * supplied in the JSON request.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-db.html#couchbase-api-db
- * _db-temp-view_post">docs for /db/_temp_view</a>
- * @param {Function} mapFun Map function
- * @param {Function} reduceFun Reduce function
- * @param {Function} language Language the map / reduce funs are
- * implemented in
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- query: function(mapFun, reduceFun, language, options) {
- language = language || "javascript";
- if (typeof(mapFun) !== "string") {
- mapFun = mapFun.toSource ? mapFun.toSource()
- : "(" + mapFun.toString() + ")";
- }
- var body = {language: language, map: mapFun};
- if (reduceFun != null) {
- if (typeof(reduceFun) !== "string")
- reduceFun = reduceFun.toSource ? reduceFun.toSource()
- : "(" + reduceFun.toString() + ")";
- body.reduce = reduceFun;
- }
- ajax({
- type: "POST",
- url: this.uri + "_temp_view" + encodeOptions(options),
- contentType: "application/json", data: toJSON(body)
- },
- options,
- "An error occurred querying the database"
- );
- },
- /**
- * Fetch a _list view output, you can specify a list of
- * <code>keys</code> in the options object to recieve only those keys.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-design.html#couchbase-api
- * -design_db-design-designdoc-list-listname-viewname_get">
- * docs for /db/_design/design-doc/_list/l1/v1</a>
- * @param {String} list Listname in the form of ddoc/listname
- * @param {String} view View to run list against
- * @param {options} CouchDB <a href="http://wiki.apache.org/couchdb/
- * HTTP_view_API">View Options</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- list: function(list, view, options, ajaxOptions) {
- var list = list.split('/');
- var options = options || {};
- var type = 'GET';
- var data = null;
- if (options['keys']) {
- type = 'POST';
- var keys = options['keys'];
- delete options['keys'];
- data = toJSON({'keys': keys });
- }
- ajax({
- type: type,
- data: data,
- url: this.uri + '_design/' + list[0] +
- '/_list/' + list[1] + '/' + view + encodeOptions(options)
- },
- ajaxOptions, 'An error occured accessing the list'
- );
- },
- /**
- * Executes the specified view-name from the specified design-doc
- * design document, you can specify a list of <code>keys</code>
- * in the options object to recieve only those keys.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-design.html#couchbase-api-
- * design_db-design-designdoc-view-viewname_get">docs for /db/
- * _design/design-doc/_list/l1/v1</a>
- * @param {String} name View to run list against (string should have
- * the design-doc name followed by a slash and the view name)
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- view: function(name, options) {
- var name = name.split('/');
- var options = options || {};
- var type = "GET";
- var data= null;
- if (options["keys"]) {
- type = "POST";
- var keys = options["keys"];
- delete options["keys"];
- data = toJSON({ "keys": keys });
- }
- ajax({
- type: type,
- data: data,
- url: this.uri + "_design/" + name[0] +
- "/_view/" + name[1] + encodeOptions(options)
- },
- options, "An error occurred accessing the view"
- );
- },
- /**
- * Fetch an arbitrary CouchDB database property
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api.html">docs for /db/_prop</a>
- * @param {String} propName Propery name to fetch
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- * @param {ajaxSettings} ajaxOptions <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- getDbProperty: function(propName, options, ajaxOptions) {
- ajax({url: this.uri + propName + encodeOptions(options)},
- options,
- "The property could not be retrieved",
- ajaxOptions
- );
- },
- /**
- * Set an arbitrary CouchDB database property
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api.html">docs for /db/_prop</a>
- * @param {String} propName Propery name to fetch
- * @param {String} propValue Propery value to set
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- * @param {ajaxSettings} ajaxOptions <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- setDbProperty: function(propName, propValue, options, ajaxOptions) {
- ajax({
- type: "PUT",
- url: this.uri + propName + encodeOptions(options),
- data : JSON.stringify(propValue)
- },
- options,
- "The property could not be updated",
- ajaxOptions
- );
- }
- };
- },
- encodeDocId: encodeDocId,
- /**
- * Accessing the root of a CouchDB instance returns meta information about
- * the instance. The response is a JSON structure containing information
- * about the server, including a welcome message and the version of the
- * server.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/uploads/
- * all/documentation/couchbase-api-misc.html#couchbase-api-misc_root_get">
- * docs for GET /</a>
- * @param {ajaxSettings} options <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- */
- info: function(options) {
- ajax(
- {url: this.urlPrefix + "/"},
- options,
- "Server information could not be retrieved"
- );
- },
- /**
- * Request, configure, or stop, a replication operation.
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-misc.html#couchbase-api-
- * misc_replicate_post">docs for POST /_replicate</a>
- * @param {String} source Path or url to source database
- * @param {String} target Path or url to target database
- * @param {ajaxSettings} ajaxOptions <a href="http://api.jquery.com/
- * jQuery.ajax/#jQuery-ajax-settings">jQuery ajax settings</a>
- * @param {Object} repOpts Additional replication options
- */
- replicate: function(source, target, ajaxOptions, repOpts) {
- repOpts = $.extend({source: source, target: target}, repOpts);
- if (repOpts.continuous && !repOpts.cancel) {
- ajaxOptions.successStatus = 202;
- }
- ajax({
- type: "POST", url: this.urlPrefix + "/_replicate",
- data: JSON.stringify(repOpts),
- contentType: "application/json"
- },
- ajaxOptions,
- "Replication failed"
- );
- },
- /**
- * Fetch a new UUID
- * @see <a href="http://techzone.couchbase.com/sites/default/files/
- * uploads/all/documentation/couchbase-api-misc.html#couchbase-api-
- * misc_uuids_get">docs for /_uuids</a>
- * @param {Int} cacheNum Number of uuids to keep cached for future use
- */
- newUUID: function(cacheNum) {
- if (cacheNum === undefined) {
- cacheNum = 1;
- }
- if (!uuidCache.length) {
- ajax({url: this.urlPrefix + "/_uuids", data: {count: cacheNum}, async:
- false}, {
- success: function(resp) {
- uuidCache = resp.uuids;
- }
- },
- "Failed to retrieve UUID batch."
- );
- }
- return uuidCache.shift();
- }
- });
- /**
- * @private
- */
- function ajax(obj, options, errorMessage, ajaxOptions) {
- var timeStart;
- var defaultAjaxOpts = {
- contentType: "application/json",
- headers:{"Accept": "application/json"}
- };
- options = $.extend({successStatus: 200}, options);
- ajaxOptions = $.extend(defaultAjaxOpts, ajaxOptions);
- errorMessage = errorMessage || "Unknown error";
- timeStart = (new Date()).getTime();
- $.ajax($.extend($.extend({
- type: "GET", dataType: "json", cache : !$.browser.msie,
- beforeSend: function(xhr){
- if(ajaxOptions && ajaxOptions.headers){
- for (var header in ajaxOptions.headers){
- xhr.setRequestHeader(header, ajaxOptions.headers[header]);
- }
- }
- },
- complete: function(req) {
- var reqDuration = (new Date()).getTime() - timeStart;
- try {
- var resp = $.parseJSON(req.responseText);
- } catch(e) {
- if (options.error) {
- options.error(req.status, req, e);
- } else {
- throw errorMessage + ': ' + e;
- }
- return;
- }
- if (options.ajaxStart) {
- options.ajaxStart(resp);
- }
- if (req.status == options.successStatus) {
- if (options.beforeSuccess) options.beforeSuccess(req, resp, reqDuration);
- if (options.success) options.success(resp, reqDuration);
- } else if (options.error) {
- options.error(req.status, resp && resp.error ||
- errorMessage, resp && resp.reason || "no response",
- reqDuration);
- } else {
- throw errorMessage + ": " + resp.reason;
- }
- }
- }, obj), ajaxOptions));
- }
- /**
- * @private
- */
- function fullCommit(options) {
- var options = options || {};
- if (typeof options.ensure_full_commit !== "undefined") {
- var commit = options.ensure_full_commit;
- delete options.ensure_full_commit;
- return function(xhr) {
- xhr.setRequestHeader('Accept', 'application/json');
- xhr.setRequestHeader("X-Couch-Full-Commit", commit.toString());
- };
- }
- };
- /**
- * @private
- */
- // Convert a options object to an url query string.
- // ex: {key:'value',key2:'value2'} becomes '?key="value"&key2="value2"'
- function encodeOptions(options) {
- var buf = [];
- if (typeof(options) === "object" && options !== null) {
- for (var name in options) {
- if ($.inArray(name,
- ["error", "success", "beforeSuccess", "ajaxStart"]) >= 0)
- continue;
- var value = options[name];
- if ($.inArray(name, ["key", "startkey", "endkey"]) >= 0) {
- value = toJSON(value);
- }
- buf.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
- }
- }
- return buf.length ? "?" + buf.join("&") : "";
- }
- /**
- * @private
- */
- function toJSON(obj) {
- return obj !== null ? JSON.stringify(obj) : null;
- }
- })(jQuery);