Implements the PouchDB API for dealing with CouchDB instances over WS
320050
function SocketPouch(opts, callback) {
  var api = this;

  if (typeof opts === 'string') {
    var slashIdx = utils.lastIndexOf(opts, '/');
    opts = {
      url: opts.substring(0, slashIdx),
      name: opts.substring(slashIdx + 1)
    };
  } else {
    opts = utils.clone(opts);
  }

  log('constructor called', opts);

  if (!opts.url || !opts.name) {
    var optsErrMessage = 'Error: you must provide a web socket ' +
      'url and database name.';
    console.error(optsErrMessage);
    return callback(new Error(optsErrMessage));
  }

  // api.name was added in pouchdb 6.0.0
  api._socketName = api.name || opts.originalName;

  var cacheKey = '$' + api._socketName;

  function useExistingSocket() {
    // Re-use the cached one instead of creating multiple sockets.
    // This is important, because if a user creates many PouchDBs
    // without closing/destroying each one, then we could end up
    // with too many open sockets, which causes problems like
    // https://github.com/Automattic/engine.io/issues/320
    var instance = instances[cacheKey];
    api._socket = instance._socket;
    api._callbacks = instance._callbacks;
    api._changesListeners = instance._changesListeners;
    api._blobs = instance._blobs;
    api._binaryMessages = instance._binaryMessages;
    api._name = instance._name;

    if (instance._socketId) {
      api._socketId = instance._socketId;
      process.nextTick(function () {
        callback(null, api);
      });
    } else {
      api._socket.once('open', function () {
        api._socketId = api._socket.id;
        process.nextTick(function () {
          callback(null, api);
        });
      });
    }
  }

  function createNewSocket() {
    // to force XHR during debugging
    // opts.socketOptions = {transports: ['polling']};
    var socket = api._socket = new Socket(opts.url, opts.socketOptions || {});
    socket.binaryType = 'blob';
    api._callbacks = {};
    api._changesListeners = {};
    api._blobs = {};
    api._binaryMessages = {};
    api._name = api._socketName;
    instances[cacheKey] = api;

    socket.once('open', function () {
      api._socketId = socket.id;
      log('socket opened', api._socketId, api._name);
      var serverOpts = {
        name: api._name,
        auto_compaction: !!opts.auto_compaction
      };
      if ('revs_limit' in opts) {
        serverOpts.revs_limit = opts.revs_limit;
      }
      sendMessage('createDatabase', [serverOpts], function (err) {
        if (err) {
          return callback(err);
        }
        callback(null, api);
      });
    });

    api._socket.once('error', function (err) {
      callback(err);
    });

    function handleUncaughtError(content) {
      try {
        api.emit('error', content);
      } catch (err) {
        // TODO: it's weird that adapters should have to handle this themselves
        console.error(
          'The user\'s map/reduce function threw an uncaught error.\n' +
          'You can debug this error by doing:\n' +
          'myDatabase.on(\'error\', function (err) { debugger; });\n' +
          'Please double-check your map/reduce function.');
        console.error(content);
      }
    }

    function receiveMessage(res) {
      var split = utils.parseMessage(res, 3);
      var messageId = split[0];
      var messageType = split[1];
      var content = JSON.parse(split[2]);

      if (messageType === '4') { // unhandled error
        handleUncaughtError(content);
        return;
      }

      var cb = api._callbacks[messageId];

      if (!cb) {
        log('duplicate message (ignoring)', messageId, messageType, content);
        return;
      }

      log('receive message', api._socketId, messageId, messageType, content);

      if (messageType === '0') { // error
        delete api._callbacks[messageId];
        cb(content);
      } else if (messageType === '1') { // success
        delete api._callbacks[messageId];
        cb(null, content);
      } else if (messageType === '2') { // update, i.e. changes
        if (api._changesListeners[messageId].asBinary) {
          readAttachmentsAsBlobOrBuffer(content);
        }
        api._changesListeners[messageId].listener(content);
      } else { // binary success
        delete api._callbacks[messageId];
        receiveBinaryMessage(content, cb);
      }
    }

    function receiveBinaryMessage(content, cb) {
      log('receiveBinaryMessage', content.uuid);
      api._binaryMessages[content.uuid] = {
        contentType: content.type,
        cb: cb
      };
      checkBinaryReady(uuid);
    }

    function receiveBlob(blob) {
      if (isBrowser) {
        blobUtil.blobToBinaryString(blob.slice(0, 36)).then(function (uuid) {
          api._blobs[uuid] = blob.slice(36);
          log('receiveBlob', uuid);
          checkBinaryReady(uuid);
        }).catch(console.log.bind(console));
      } else {
        var uuid = blob.slice(0, 36).toString('utf8');
        log('receiveBlob', uuid);
        api._blobs[uuid] = blob.slice(36);
        checkBinaryReady(uuid);
      }
    }

    // binary messages come in two parts; wait until we've received both
    function checkBinaryReady(uuid) {
      if (!(uuid in api._blobs && uuid in api._binaryMessages)) {
        return;
      }
      log('receive full binary message', uuid);
      var blob = api._blobs[uuid];
      var msg = api._binaryMessages[uuid];

      delete api._blobs[uuid];
      delete api._binaryMessages[uuid];

      var blobToDeliver;
      if (isBrowser) {
        blobToDeliver = blobUtil.createBlob([blob], {type: msg.contentType});
      } else {
        blobToDeliver = blob;
        blob.type = msg.contentType; // non-standard, but we do it for the tests
      }

      msg.cb(null, blobToDeliver);
    }

    api._socket.on('message', function (res) {
      if (typeof res !== 'string') {
        return receiveBlob(res);
      }
      receiveMessage(res);
    });
  }

  if (instances[cacheKey]) {
    useExistingSocket();
  } else { // new DB
    createNewSocket();
  }

  function sendMessage(type, args, callback) {
    if (api._destroyed) {
      return callback(new Error('this db was destroyed'));
    } else if (api._closed) {
      return callback(new Error('this db was closed'));
    }
    var messageId = uuid();
    log('send message', api._socketId, messageId, type, args);
    api._callbacks[messageId] = callback;
    var stringArgs = stringifyArgs(args);
    api._socket.send(type + ':' + messageId + ':' + stringArgs, function () {
      log('message sent', api._socketId, messageId);
    });
  }

  function sendBinaryMessage(type, args, blobIndex, blob, callback) {
    var messageId = uuid();
    api._callbacks[messageId] = callback;
    var header = {
      args: args,
      blobIndex: blobIndex,
      messageId: messageId,
      messageType: type
    };

    log('send binary message', api._socketId, messageId, header);
    var headerString = JSON.stringify(header);
    var headerLen = padInt(headerString.length, 16);
    var blobToSend;
    if (isBrowser) {
      blobToSend = blobUtil.createBlob([
        headerLen,
        headerString,
        blob
      ]);
    } else { // node.js
      blobToSend = buffer.concat([
        new buffer(headerLen, 'utf8'),
        new buffer(headerString, 'utf8'),
        new buffer(blob, 'binary')
      ]);
    }
    api._socket.send(blobToSend, function () {
      log('binary message sent', api._socketId, messageId);
    });
  }

  api.type = function () {
    return 'socket';
  };

  api._id = adapterFun('id', function (callback) {
    sendMessage('id', [], callback);
  });

  api.compact = adapterFun('compact', function (opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = {};
    }
    sendMessage('compact', [opts], callback);
  });

  api._info = function (callback) {
    sendMessage('info', [], callback);
  };

  api.get = adapterFun('get', function (id, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = {};
    }
    sendMessage('get', [id, opts], function (err, res) {
      if (err) {
        return callback(err);
      }
      if (opts.attachments && opts.binary) {
        if (Array.isArray(res)) {
          res.forEach(readAttachmentsAsBlobOrBuffer);
        } else {
          readAttachmentsAsBlobOrBuffer({doc: res});
        }
      }
      callback(null, res);
    });
  });

  // hacky code necessary due to implicit breaking change in
  // https://github.com/pouchdb/pouchdb/commits/0ddeae6b
  api._get = function (id, opts, callback) {
    api.get(id, opts, function (err, doc) {
      if (err) {
        return callback(err);
      }
      callback(null, {doc: doc});
    });
  };

  api.remove =
    adapterFun('remove', function (docOrId, optsOrRev, opts, callback) {
      var doc;
      if (typeof optsOrRev === 'string') {
        // id, rev, opts, callback style
        doc = {
          _id: docOrId,
          _rev: optsOrRev
        };
        if (typeof opts === 'function') {
          callback = opts;
          opts = {};
        }
      } else {
        // doc, opts, callback style
        doc = docOrId;
        if (typeof optsOrRev === 'function') {
          callback = optsOrRev;
          opts = {};
        } else {
          callback = opts;
          opts = optsOrRev;
        }
      }
      var rev = (doc._rev || opts.rev);

      sendMessage('remove', [doc._id, rev], callback);
  });

  api.getAttachment =
    adapterFun('getAttachment', function (docId, attachmentId, opts,
                                                callback) {
      if (typeof opts === 'function') {
        callback = opts;
        opts = {};
      }
      sendMessage('getAttachment', [docId, attachmentId, opts], callback);
  });

  api.removeAttachment =
    adapterFun('removeAttachment', function (docId, attachmentId, rev,
                                                   callback) {

      sendMessage('removeAttachment', [docId, attachmentId, rev], callback);
    });

  // Add the attachment given by blob and its contentType property
  // to the document with the given id, the revision given by rev, and
  // add it to the database given by host.
  api.putAttachment =
    adapterFun('putAttachment', function (docId, attachmentId, rev, blob,
                                                type, callback) {
      if (typeof type === 'function') {
        callback = type;
        type = blob;
        blob = rev;
        rev = null;
      }
      if (typeof type === 'undefined') {
        type = blob;
        blob = rev;
        rev = null;
      }

      if (typeof blob === 'string') {
        var binary;
        try {
          binary = utils.atob(blob);
        } catch (err) {
          // it's not base64-encoded, so throw error
          return callback(errors.error(errors.BAD_ARG,
            'Attachments need to be base64 encoded'));
        }
        if (isBrowser) {
          blob = utils.createBlob([utils.binaryStringToArrayBuffer(binary)], {type: type});
        } else {
          blob = binary ? new buffer(binary, 'binary') : '';
        }
      }

      var args = [docId, attachmentId, rev, null, type];
      sendBinaryMessage('putAttachment', args, 3, blob, callback);
    });

  api.put = adapterFun('put', utils.getArguments(function (args) {
    var temp, temptype, opts;
    var doc = args.shift();
    var id = '_id' in doc;
    var callback = args.pop();
    if (typeof doc !== 'object' || Array.isArray(doc)) {
      return callback(errors.error(errors.NOT_AN_OBJECT));
    }

    doc = utils.clone(doc);

    preprocessAttachments(doc).then(function () {
      while (true) {
        temp = args.shift();
        temptype = typeof temp;
        if (temptype === "string" && !id) {
          doc._id = temp;
          id = true;
        } else if (temptype === "string" && id && !('_rev' in doc)) {
          doc._rev = temp;
        } else if (temptype === "object") {
          opts = utils.clone(temp);
        }
        if (!args.length) {
          break;
        }
      }
      opts = opts || {};

      sendMessage('put', [doc, opts], callback);
    }).catch(callback);

  }));

  api.post = adapterFun('post', function (doc, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = {};
    }
    opts = utils.clone(opts);

    sendMessage('post', [doc, opts], callback);
  });

  api._bulkDocs = function (req, opts, callback) {
    var docs = req.docs || req;

    Promise.all(docs.map(function (doc) {
      var atts = doc._attachments;
      if (!atts) {
        return;
      }
      return Promise.all(Object.keys(atts).map(function (key) {
        var att = doc._attachments[key];
        if (!isBinaryObject(att.data)) {
          return;
        }
        return new Promise(function (resolve) {
          readAsBinaryString(att.data, resolve);
        }).then(function (binString) {
          att.data = base64.btoa(binString);
        });
      }));
    })).then(function () {
      sendMessage('bulkDocs', [req, opts], callback);
    }).catch(callback);
  };

  api._allDocs = function (opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = {};
    }
    sendMessage('allDocs', [opts], function (err, res) {
      if (err) {
        return callback(err);
      }
      if (opts.attachments && opts.binary) {
        res.rows.forEach(readAttachmentsAsBlobOrBuffer);
      }
      callback(null, res);
    });
  };

  api._changes = function (opts) {
    opts = utils.clone(opts);

    if (opts.continuous) {
      var messageId = uuid();
      api._changesListeners[messageId] = {
        listener: opts.onChange,
        asBinary: opts.attachments && opts.binary
      };
      api._callbacks[messageId] = opts.complete;
      api._socket.send('liveChanges' + ':' + messageId + ':' + JSON.stringify([opts]));
      return {
        cancel: function () {
          api._socket.send('cancelChanges' + ':' + messageId + ':' + JSON.stringify([]));
        }
      };
    }

    sendMessage('changes', [opts], function (err, res) {
      if (err) {
        opts.complete(err);
        return callback(err);
      }
      res.results.forEach(function (change) {
        if (opts.attachments && opts.binary) {
          readAttachmentsAsBlobOrBuffer(change);
        }
        opts.onChange(change);
      });
      if (opts.returnDocs === false || opts.return_docs === false) {
        res.results = [];
      }
      opts.complete(null, res);
    });
  };

  // Given a set of document/revision IDs (given by req), tets the subset of
  // those that do NOT correspond to revisions stored in the database.
  // See http://wiki.apache.org/couchdb/HttpPostRevsDiff
  api.revsDiff = adapterFun('revsDiff', function (req, opts, callback) {
    // If no options were given, set the callback to be the second parameter
    if (typeof opts === 'function') {
      callback = opts;
      opts = {};
    }

    sendMessage('revsDiff', [req, opts], callback);
  });

  api._query = adapterFun('query', function (fun, opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = {};
    }
    var funEncoded = fun;
    if (typeof fun === 'function') {
      funEncoded = {map: fun};
    }
    sendMessage('query', [funEncoded, opts], function (err, res) {
      if (err) {
        return callback(err);
      }
      if (opts.attachments && opts.binary) {
        res.rows.forEach(readAttachmentsAsBlobOrBuffer);
      }
      callback(null, res);
    });
  });

  api._viewCleanup = adapterFun('viewCleanup', function (callback) {
    sendMessage('viewCleanup', [], callback);
  });

  api._close = function (callback) {
    api._closed = true;
    var cacheKey = '$' + api._socketName;
    if (!instances[cacheKey]) { // already closed/destroyed
      return callback();
    }
    delete instances[cacheKey];
    close(api, callback);
  };

  api.destroy = adapterFun('destroy', function (opts, callback) {
    if (typeof opts === 'function') {
      callback = opts;
      opts = {};
    }
    var cacheKey = '$' + api._socketName;

    if (!instances[cacheKey]) { // already closed/destroyed
      return callback(null, {ok: true});
    }
    delete instances[cacheKey];
    sendMessage('destroy', [], function (err, res) {
      if (err) {
        api.emit('error', err);
        return callback(err);
      }
      api._destroyed = true;
      close(api, function (err) {
        if (err) {
          api.emit('error', err);
          return callback(err);
        }
        api.emit('destroyed');
        callback(null, res);
      });
    });
  });
}
174440
function(db) {

		/** Fetch external documents
		 * @param data {} 
		 * @param config {} 
		 * @param plv8 {} 
		 * @param ERROR {} 
		 * @param WARNING {} 
		 */
		function get_documents(data, config, plv8, ERROR, WARNING) {

			function get_document(id, fields) {
				fields = (fields || [{'query':'*'}]);

				var map = {};

				var obj = plv8.execute("SELECT "+fields.map(function(f, i) {
					var k;
					if(f.key) {
						k = 'p__' + i;
						map[k] = f;
						return f.query + ' AS ' + k;
					} else {
						return f.query;
					}
				}).join(', ')+" FROM documents WHERE id = $1 LIMIT 1", [id])[0];

				if(!obj) {
					return obj;
				}

				Object.keys(obj).forEach(function(key) {
					if(!map.hasOwnProperty(key)) {
						return;
					}

					var spec = map[key];
					if(!is_object(spec)) {
						return error('mapped resource missing');
					}
					if(!is_string(spec.key)) {
						return error('key missing');
					}
					var value = obj[key];
					delete obj[key];

					if(is_string(spec.datakey)) {
						if(!obj[spec.datakey]) {
							obj[spec.datakey] = {};
						}
						obj[spec.datakey][spec.key] = value;
					} else {
						obj[spec.key] = value;
					}
				});

				return obj;
			}

			function error(msg) {
				plv8.elog(ERROR, msg);
			}

			function warn(msg) {
				plv8.elog(WARNING, msg);
			}

			function is_object(a) {
				return a && (typeof a === 'object');
			}

			function is_array(a) {
				return a && (a instanceof Array);
			}

			function is_string(a) {
				return a && (typeof a === 'string');
			}

			function is_uuid(obj) {
				return /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/.test(obj);
			}

			/** Returns property from object
			 * @returns The value of property named `current` of object `last`, otherwise undefined.
			 */
			function get_property_step(last, current) {
				return is_object(last) ? last[current] : undefined;
			}

			/** Get value of property from provided object using a path.
			 * @param obj {object} The object from where to find the value.
			 * @param path {string} The path to the value in object.
			 * @returns {mixed} The value from the object at the end of path or `undefined` if any part is missing.
			 */
			function get_property(obj, path) {
				if(!is_object(obj)) { return error('get_property(obj, ...) not object: '+ obj); }
				if(!is_string(path)) { return error('get_property(..., path) not string: '+ path); }
				return path.split('.').reduce(get_property_step, obj);
			}

			/** Get PostgreSQL style property expression */
			function get_pg_prop(name) {

				if(name[0] === '$') {
					return name.substr(1);
				}

				var parts = name.split('.');

				if(parts.length === 1) {
					return "content->>'" + name + "'";
				}

				if(parts.length === 2) {
					return "content->'" + parts.join("'->>'") + "'";
				}

				return "content->'" + parts.slice(0, parts.length-1).join("'->'") + "'->>'" + parts[parts.length-1] + "'";
			}

			/** Execute query for document expressions
			 * @param parent {object} The parent document object
			 * @param prop {string} The name of the property where results are saved in the parent
			 * @param type_name {string} The name of the type of related documents
			 * @param type_prop {string} The property name in the related document for the UUID of parent
			 * @param fields {array} The fields in the related document that should be returned
			 */
			function expression_query(parent, prop, type_name, type_prop, fields) {

				fields = (fields || [{'query':'*'}]);

				var map = {};

				var query = "SELECT "+fields.map(function(f, i) {
					var k;
					if(f.key) {
						k = 'p__' + i;
						map[k] = f;
						return f.query + ' AS ' + k;
					} else {
						return f.query;
					}
				}).join(', ')+" FROM documents WHERE type = $1 AND "+get_pg_prop(type_prop)+" = $2";

				var rows = plv8.execute(query, [type_name, parent.id]);

				if(!is_array(rows)) {
					return rows;
				}

				var errors = [];

				rows = rows.map(function(obj) {
					Object.keys(obj).forEach(function(key) {
						if(!map.hasOwnProperty(key)) {
							return;
						}
						var spec = map[key];
						if(!is_object(spec)) {
							errors.push( error('mapped resource missing') );
							return;
						}
						if(!is_string(spec.key)) {
							errors.push( error('key missing') );
							return;
						}
						var value = obj[key];
						delete obj[key];

						if(is_string(spec.datakey)) {
							if(!obj[spec.datakey]) {
								obj[spec.datakey] = {};
							}
							obj[spec.datakey][spec.key] = value;
						} else {
							obj[spec.key] = value;
						}
					});
					return obj;
				});

				if(errors.length >= 1) {
					return errors.shift();
				}

				return rows;
			}

			/** Get document(s) by expression */
			function fetch_objects_by_expression(data, prop, fields, expression) {
				if(!is_object(data)) { return error('fetch_objects_by_expression(data, ..., ...) not object: '+ data); }
				if(!is_string(prop)) { return error('fetch_objects_by_expression(..., prop, ...) not string: '+ prop); }
				if(!is_string(expression)) { return warn('Expression was not string: {' + expression + '}, typeof ' + (typeof expression)); }

				prop = prop.trim();
				expression = expression.trim();

				var type_name, type_prop;
				var type_start = expression.indexOf('#');
				if(type_start >= 0) {
					type_name = expression.substr(0, type_start).trim();
					type_prop = expression.substr(type_start+1).trim();
				} else {
					type_name = expression;
				}

				if(!type_prop) {
					return error('No property name in expression: {'+ expression+'}');
				}

				var rows = expression_query(data, prop, type_name, type_prop, fields);
				if(!is_array(rows)) {
					return rows;
				}

				var warnings = [];

				if(!data.documents) {
					data.documents = {};
				}

				if(!data.documents.expressions) {
					data.documents.expressions = {};
				}

				if(!is_array(data.documents.expressions[prop])) {
					if(data.documents.expressions.hasOwnProperty(prop)) {
						data.documents.expressions[prop] = [data.documents.expressions[prop]];
					} else {
						data.documents.expressions[prop] = [];
					}
				}

				var id_list = data.documents.expressions[prop];

				rows.forEach(function(row) {
					var uuid = row.id;
					if(is_uuid(uuid)) {
						id_list.push(uuid);
						if(data.documents[uuid] === undefined) {
							data.documents[uuid] = row;
						//} else {
						//	warnings.push( warn('Document already fetched: ' + uuid) );
						}
					} else {
						warnings.push( warn('Document did not have UUID property: ' + JSON.stringify(row, null, 2) ) );
					}
				});

				if(warnings.length >= 1) {
					return warnings.shift();
				}
			}

			/** Get document by UUID */
			function fetch_object_by_uuid(data, prop, fields, uuid) {
				if(!is_object(data)) { return error('fetch_object_by_uuid(data, ..., ...) not object: '+ data); }
				if(!is_string(prop)) { return error('fetch_object_by_uuid(..., prop, ...) not string: '+ prop); }
				if(!is_uuid(uuid)) { return warn('Property ' + prop + ' was not uuid: ' + uuid); }
				if(data.documents[uuid] === undefined) {
					data.documents[uuid] = get_document(uuid, fields);
				} else {
					return warn('Document already fetched: ' + uuid);
				}
			}

			/* */
			function fetch_object(data, config) {
				var prop, fields;

				if(is_object(config)) {
					prop = config.prop;
					fields = config.fields;
				} else if(is_string(config)) {
					prop = config;
				}

				if(!is_string(prop)) {
					return error('property is not valid: ' + prop);
				}

				fields = fields ? fields : [{'query':'*'}];

				if(!is_array(fields)) {
					return error('fields are not valid: ' + fields);
				}

				var exp_start = prop.indexOf('{');
				var exp_end = prop.length-1;
				if( (exp_start >= 0) && (prop[exp_end] === '}') ) {
					return fetch_objects_by_expression(data, prop.substr(0, exp_start), fields, prop.substr(exp_start+1, exp_end-(exp_start+1)) );
				}

				var uuid = get_property(data, prop);

				if(is_array(uuid)) {
					// FIXME: This could be implemented with one query
					return uuid.forEach(fetch_object_by_uuid.bind(undefined, data, prop, fields));
				}

				return fetch_object_by_uuid(data, prop, fields, uuid);
			}

			// Check for bad input
			if(!is_object(data)) { return error("get_documents(data, ...) not object"); }
			if(!is_array(config)) { return error("get_documents(..., config) not array"); }

			// Populate documents from `config`
			data.documents = {};
			config.forEach( fetch_object.bind(undefined, data) );
			return data.documents;
		}

		return db.query('CREATE OR REPLACE FUNCTION get_documents(data json, config json) RETURNS json LANGUAGE plv8 VOLATILE AS ' + NoPg._escapeFunction(get_documents, ["data", "config", "plv8", "ERROR", "WARNING"]));
	}
602685
@InterfaceAudience.Private
    protected static Map<String, Object> installAttachmentBodies(Map<String, Object> attachments,
                                                                 Database database)
            throws CouchbaseLiteException {
        Map<String, Object> updatedAttachments = new HashMap<String, Object>();
        for (String name : attachments.keySet()) {
            Object value = attachments.get(name);
            if (value instanceof Attachment) {
                Attachment attachment = (Attachment) value;
                Map<String, Object> metadataMutable = new HashMap<String, Object>();
                metadataMutable.putAll(attachment.getMetadata());
                InputStream body = attachment.getBodyIfNew();
                if (body != null) {
                    // Copy attachment body into the database's blob store:
                    BlobStoreWriter writer;
                    try {
                        writer = blobStoreWriterForBody(body, database);
                    } catch (Exception e) {
                        throw new CouchbaseLiteException(e.getMessage(), Status.ATTACHMENT_ERROR);
                    }
                    metadataMutable.put("length", writer.getLength());
                    metadataMutable.put("digest", writer.mD5DigestString());
                    metadataMutable.put("follows", true);
                    database.rememberAttachmentWriter(writer);
                }
                updatedAttachments.put(name, metadataMutable);
            } else if (value instanceof AttachmentInternal) {
                throw new IllegalArgumentException("AttachmentInternal objects not expected here.  Could indicate a bug");
            } else if (value != null) {
                updatedAttachments.put(name, value);
            }
        }
        return updatedAttachments;
    }
1027385
function condor_classads_stream(cmd, opts, cb) {
    var deferred = Q.defer();
    var p = spawn(cmd, opts, {env: get_condor_env()});//, {cwd: __dirname});
    var buffer = "";
    var items = [];
    
    var parser = new xml2js.Parser();
    function getblock() {
        //look for start / end delimiter
        var s = buffer.indexOf("\n<c>\n");
        var e = buffer.indexOf("\n</c>\n");
        if(s != -1 && e != -1) {
            //var block = buffer.splice(spos, epos);
            xml = buffer.substring(s, e+5);
            buffer = buffer.substring(e+5);
            //XML.parse(xml, function(err, attrs) {
            parser.parseString(xml, function(err, attrs) {
                //console.dir(xml);
                if(err) {
                    console.log("failed to parse job xml (skipping)");
                    console.error(err);
                    console.log(xml);
                } else {
                    var event = {};
                    if(!attrs.c || !attrs.c.a) {
                        event._no_attributes = true;
                        //event.dump = attrs;
                    } else {
                        if(!attrs.c.a.forEach) {
                            attrs.c.a = [attrs.c.a];
                        }
                        attrs.c.a.forEach(function(attr) {
                            var name = attr.$.n;
                            event[name] = parse_attrvalue(attr);
                        });
                    }
                    if(cb) {
                        cb(null, event);
                    }
                    items.push(event);
                }
            });
            return true;
        } else {
            return false;
        }
    }
    p.stdout.on('data', function (data) {
        buffer += data.toString();
        while(getblock());
    });

    var stderr = "";
    p.stderr.on('data', function (data) {
        stderr += data;
    });
    p.on('error', function(err) {
        console.error(err);
        deferred.reject(err);
        cb(err);
    });
    p.on('close', function (code, signal) {
        while(getblock());
        if (signal) {
            deferred.reject(cmd+ " was killed by signal "+ signal);
            if(cb) {
                cb({code: code, signal: signal, stdout: buffer, stderr: stderr});
            }
        } else if (code !== 0) {
            deferred.reject(cmd+ " failed with exit code "+ code+ "\nSTDERR:"+ stderr + "\nbuffer:"+ buffer);
            if(cb) {
                cb({code: code, signal: signal, stdout: buffer, stderr: stderr});
            }
        } else {
            deferred.resolve(items);
        }
    });
    return deferred.promise;
}
670778
def payload_from_doc(req, doc, opts = {})
      if doc.is_a?(IO) || doc.is_a?(StringIO) || doc.is_a?(Tempfile) # attachments
        req[:header]['Content-Type'] = mime_for(req[:uri].path)
        doc
      elsif opts[:raw] || doc.nil?
        doc
      else
        MultiJson.encode(doc.respond_to?(:as_couch_json) ? doc.as_couch_json : doc)
      end
    end
614739
def _build_credentials_tuple(mech, source, user, passwd, extra, database):
    
    if mech != 'MONGODB-X509' and user is None:
        raise ConfigurationError("%s requires a username." % (mech,))
    if mech == 'GSSAPI':
        if source is not None and source != '$external':
            raise ValueError(
                "authentication source must be $external or None for GSSAPI")
        properties = extra.get('authmechanismproperties', {})
        service_name = properties.get('SERVICE_NAME', 'mongodb')
        canonicalize = properties.get('CANONICALIZE_HOST_NAME', False)
        service_realm = properties.get('SERVICE_REALM')
        props = GSSAPIProperties(service_name=service_name,
                                 canonicalize_host_name=canonicalize,
                                 service_realm=service_realm)
        # Source is always $external.
        return MongoCredential(mech, '$external', user, passwd, props, None)
    elif mech == 'MONGODB-X509':
        if passwd is not None:
            raise ConfigurationError(
                "Passwords are not supported by MONGODB-X509")
        if source is not None and source != '$external':
            raise ValueError(
                "authentication source must be "
                "$external or None for MONGODB-X509")
        # user can be None.
        return MongoCredential(mech, '$external', user, None, None, None)
    elif mech == 'PLAIN':
        source_database = source or database or '$external'
        return MongoCredential(mech, source_database, user, passwd, None, None)
    else:
        source_database = source or database or 'admin'
        if passwd is None:
            raise ConfigurationError("A password is required.")
        return MongoCredential(
            mech, source_database, user, passwd, None, _Cache())
388799
@Override
    protected Client instantiateClient(String persistenceUnit)
    {
        return new CouchDBClient(this, httpClient, httpHost, reader, persistenceUnit, externalProperties,
                clientMetadata, kunderaMetadata);
    }
895670
function couchdbAuth ({uri, key, secret} = {}) {
  return {
    /**
     * Check whether we've already ran authentication.
     * @returns {boolean} `true` if already authenticated, otherwise `false`
     */
    isAuthenticated () {
      return !!this._cookie
    },

    /**
     * Authenticate and return true if authentication was successful.
     * @returns {Promise} Promise of authentication success or failure (true/false)
     */
    async authenticate () {
      return authenticate.call(this, {uri, key, secret})
    },

    /**
     * Return an object with the information needed for authenticated requests
     * with this strategy.
     * @returns {Object} Auth object
     */
    getAuthObject () {
      return getAuthObject.call(this)
    },

    /**
     * Return a headers object with the headers needed for authenticated requests
     * with this strategy.
     * @returns {Object} Headers object
     */
    getAuthHeaders () {
      return getAuthHeaders.call(this)
    }
  }
}
1012156
function MongoDB(config) {
  
    var self = this;
    
    this.events = new EventEmitter();

    config = protos.extend({
      host: 'localhost',
      port: 27017,
      database: 'default',
      storage: null,
      username: '',
      password: '',
      safe: true
    }, config || {});
    
    if (typeof config.port != 'number') config.port = parseInt(config.port, 10);
    
    this.className = this.constructor.name;
    
    app.debug(util.format('Initializing MongoDB for %s:%s', config.host, config.port));
    
    /**
    
      config: {
        host: 'localhost',
        port: 27017,
        database: 'db_name',
        storage: 'redis'
      }

     */

    this.config = config;

    var reportError = function(err) {
      app.log(util.format("MongoDB [%s:%s] %s", config.host, config.port, err));
      self.client = null;
    }
    
    // Set db
    self.db = new Db(config.database, new Server(config.host, config.port, {}), {safe: config.safe});
    
    // Add async task
    app.addReadyTask();
    
    // Get client
    self.db.open(function(err, client) {
      
      if (err) {
        reportError(err);
      } else {
        
        // Set client
        self.client = client;
        
        // Set storage
        if (typeof config.storage == 'string') {
          self.storage = app.getResource('storages/' + config.storage);
        } else if (config.storage instanceof protos.lib.storage) {
          self.storage = config.storage;
        }
        
        // Authenticate
        if (config.username && config.password) {
          
          self.db.authenticate(config.username, config.password, function(err, success) {
            
            if (err) {
              
              var msg = util.format('MongoDB: unable to authenticate %s@%s', config.username, config.host);
              app.log(new Error(msg));
              throw err;
              
            } else {
              
              // Emit initialization event
              self.events.emit('init', self.db, self.client);
              
            }
            
          });
          
        } else {
          // Emit initialization event
          self.events.emit('init', self.db, self.client);
        }
        
      }
    });
    
    // Flush async task
    this.events.once('init', function() {
      app.flushReadyTask();
    });

    // Only set important properties enumerable
    protos.util.onlySetEnumerable(this, ['className', 'db']);
}
300272
def get(self, url, instance, service_check_tags, run_check=False):
        ""
        self.log.debug('Fetching CouchDB stats at url: %s' % url)

        auth = None
        if 'user' in instance and 'password' in instance:
            auth = (instance['user'], instance['password'])

        # Override Accept request header so that failures are not redirected to the Futon web-ui
        request_headers = headers(self.agentConfig)
        request_headers['Accept'] = 'text/json'

        try:
            r = requests.get(
                url, auth=auth, headers=request_headers, timeout=int(instance.get('timeout', self.TIMEOUT))
            )
            r.raise_for_status()
            if run_check:
                self.service_check(
                    self.SERVICE_CHECK_NAME,
                    AgentCheck.OK,
                    tags=service_check_tags,
                    message='Connection to %s was successful' % url,
                )
        except requests.exceptions.Timeout as e:
            self.service_check(
                self.SERVICE_CHECK_NAME,
                AgentCheck.CRITICAL,
                tags=service_check_tags,
                message="Request timeout: {0}, {1}".format(url, e),
            )
            raise
        except requests.exceptions.HTTPError as e:
            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL, tags=service_check_tags, message=str(e))
            raise
        except Exception as e:
            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL, tags=service_check_tags, message=str(e))
            raise
        return r.json()
165925
function procPacket(method, path, data, headers, callback) {
  var cookieStr = '';
  var i;
  var req;

  headers = headers || {};

  if(!headers['Content-Type']) {
    headers['Content-Type'] = 'application/json';
  }

  if(data && typeof data !== 'string') {
    data = JSON.stringify(data);
  }

  //deal with global cookies
  for(i in globalCookies) {
    if(globalCookies.hasOwnProperty(i)) {
      cookieStr += i + '=' + globalCookies[i] + ';';
    }
  }

  //only when we built a cookieStr above
  if(cookieStr) {
    //debug help
    if(xmlHTTP && console && typeof console.log === 'function') {
      console.log('Sending Cookie header, but do not expect any cookies in the result - CouchDB uses httpOnly cookies.');
    }

    headers.Cookie = ((headers.Cookie) ? headers.Cookie : '') + cookieStr;
  }

  if(pathPrefix) {
    path = pathPrefix + path;
  }

  //authentication
  if(currAuth.type === exports.AUTH_BASIC && (currAuth.user || currAuth.pass)) {
    headers.Authorization = 'Basic ' + toBase64(currAuth.user + ':' + currAuth.pass);
  }
  else if(currAuth.type === exports.AUTH_COOKIE) {
    if(http && typeof publicThat.getCookie('AuthSession') !== 'string') {
      throw new Error('Trying to use cookie auth, but we never got an AuthSession cookie from the server.');
    }

    headers['X-CouchDB-WWW-Authenticate'] = 'Cookie';
  }

  if(http) {
    // Node.JS http module
    headers['User-Agent'] = 'Sag-JS/0.4'; //can't set this in browsers

    req = http.request(
      {
        method: method,
        host: host,
        port: port,
        path: path,
        headers: headers
      },
      function(res) {
        var resBody = '';

        res.setEncoding('utf8');

        res.on('data', function(chunk) {
          resBody += chunk;
        });

        res.on('end', function() {
          onResponse(res.statusCode, res.headers, resBody, callback);
        });
      }
    );

    req.on('error', function(e) {
      console.log('problem with request: ' + e);
    });

    if(data) {
      req.write(data);
    }

    req.end();
  }
  else if(xmlHTTP) {
    // Browser xhr magik
    xmlHTTP.onreadystatechange = function() {
      var headers = {};
      var rawHeaders;
      var i;

      if(this.readyState === 4 && this.status > 0) {
        rawHeaders = this.getAllResponseHeaders().split('\n');

        for(i in rawHeaders) {
          if(rawHeaders.hasOwnProperty(i)) {
            rawHeaders[i] = rawHeaders[i].split(': ');

            if(rawHeaders[i][1]) {
              headers[rawHeaders[i][0].toLowerCase()] = rawHeaders[i][1].trim();
            }
          }
        }

        onResponse(
          this.status,
          headers,
          (method !== 'HEAD') ? this.response : null,
          callback
        );
      }
    };

    xmlHTTP.open(method, (useSSL ? 'https://' : 'http://') + host + ':' + port + path);

    for(i in headers) {
      if(headers.hasOwnProperty(i)) {
        xmlHTTP.setRequestHeader(i, headers[i]);
      }
    }

    xmlHTTP.send(data || null);
  }
  else {
    throw new Error('coder fail');
  }
}
405109
def folder2db(folder_name, debug, energy_limit, skip_folders,
              goto_reaction):
    """"""

    folder_name = folder_name.rstrip('/')
    skip = []
    for s in skip_folders.split(', '):
        for sk in s.split(','):
            skip.append(sk)
    pub_id = _folder2db.main(folder_name, debug, energy_limit,
                             skip, goto_reaction)
    if pub_id:
        print('')
        print('')
        print('Ready to release the data?')
        print(
            "  Send it to the Catalysis-Hub server with 'cathub db2server {folder_name}/{pub_id}.db'.".format(**locals()))
        print("  Then log in at www.catalysis-hub.org/upload/ to verify and release. ")
833245
function getDocsToPersist(docId, view, docIdsToChangesAndEmits) {
    var metaDocId = '_local/doc_' + docId;
    var defaultMetaDoc = {_id: metaDocId, keys: []};
    var docData = docIdsToChangesAndEmits.get(docId);
    var indexableKeysToKeyValues = docData[0];
    var changes = docData[1];

    function getMetaDoc() {
      if (isGenOne(changes)) {
        // generation 1, so we can safely assume initial state
        // for performance reasons (avoids unnecessary GETs)
        return Promise.resolve(defaultMetaDoc);
      }
      return view.db.get(metaDocId).catch(defaultsTo(defaultMetaDoc));
    }

    function getKeyValueDocs(metaDoc) {
      if (!metaDoc.keys.length) {
        // no keys, no need for a lookup
        return Promise.resolve({rows: []});
      }
      return view.db.allDocs({
        keys: metaDoc.keys,
        include_docs: true
      });
    }

    function processKeyValueDocs(metaDoc, kvDocsRes) {
      var kvDocs = [];
      var oldKeys = new pouchdbCollections.Set();

      for (var i = 0, len = kvDocsRes.rows.length; i < len; i++) {
        var row = kvDocsRes.rows[i];
        var doc = row.doc;
        if (!doc) { // deleted
          continue;
        }
        kvDocs.push(doc);
        oldKeys.add(doc._id);
        doc._deleted = !indexableKeysToKeyValues.has(doc._id);
        if (!doc._deleted) {
          var keyValue = indexableKeysToKeyValues.get(doc._id);
          if ('value' in keyValue) {
            doc.value = keyValue.value;
          }
        }
      }
      var newKeys = pouchdbMapreduceUtils.mapToKeysArray(indexableKeysToKeyValues);
      newKeys.forEach(function (key) {
        if (!oldKeys.has(key)) {
          // new doc
          var kvDoc = {
            _id: key
          };
          var keyValue = indexableKeysToKeyValues.get(key);
          if ('value' in keyValue) {
            kvDoc.value = keyValue.value;
          }
          kvDocs.push(kvDoc);
        }
      });
      metaDoc.keys = pouchdbMapreduceUtils.uniq(newKeys.concat(metaDoc.keys));
      kvDocs.push(metaDoc);

      return kvDocs;
    }

    return getMetaDoc().then(function (metaDoc) {
      return getKeyValueDocs(metaDoc).then(function (kvDocsRes) {
        return processKeyValueDocs(metaDoc, kvDocsRes);
      });
    });
  }
631198
function runLinks(links) {
											let prom = async v => { try {
													let S = v.replace(/SocketLink/,''),
														O = JSON.parse(S), 
														Q = O.point,
														R = {
															params: O.params||{},
															query: 	O.query	||{},
															body: 	O.body	||{},
															files: 	O.files	||[] },
														P = {
															true:  ()=>Q.slice(-1)[0].toTitleCase(),
															false: ()=>'/' }[Q.length>1](),
														A = Q[0].toTitleCase(),
														E = REST.Points[A][P],
														err,itms,opts;
													// --------------------------------
													[err,itms,opts] = await E(R);
													itms = await doLinks(itms,opts);
													return FromJS(Assign({},itms));
												} catch (e) { return e; } };
											return Promise.all(links.toArray().map(prom));
										}
466128
function handlePostedJoint(ws, objJoint, onDone){
	
	if (!objJoint || !objJoint.unit || !objJoint.unit.unit)
		return onDone('no unit');
	
	var unit = objJoint.unit.unit;
	delete objJoint.unit.main_chain_index;
	
	handleJoint(ws, objJoint, false, {
		ifUnitInWork: function(){
			onDone("already handling this unit");
		},
		ifUnitError: function(error){
			onDone(error);
		},
		ifJointError: function(error){
			onDone(error);
		},
		ifNeedHashTree: function(){
			onDone("need hash tree");
		},
		ifNeedParentUnits: function(arrMissingUnits){
			onDone("unknown parents");
		},
		ifOk: function(){
			onDone();
			
			// forward to other peers
			if (!bCatchingUp && !conf.bLight)
				forwardJoint(ws, objJoint);

			delete assocUnitsInWork[unit];
		},
		ifOkUnsigned: function(){
			delete assocUnitsInWork[unit];
			onDone("you can't send unsigned units");
		},
		ifKnown: function(){
			if (objJoint.unsigned)
				return onDone("you can't send unsigned units");
			onDone("known");
			writeEvent('known_good', ws.host);
		},
		ifKnownBad: function(){
			onDone("known bad");
			writeEvent('known_bad', ws.host);
		},
		ifKnownUnverified: function(){ // impossible unless the peer also sends this joint by 'joint' justsaying
			onDone("known unverified");
			delete assocUnitsInWork[unit];
		}
	});
}
1335036
function exec() {

  // NOTE: pardon this cli target to Couchpenter methods mapping,
  // needed to preserve backward compatibility w/ v0.1.x
  const FUNCTIONS = {
    setup: 'setUp',
    'setup-db': 'setUpDatabases',
    'setup-doc': 'setUpDocuments',
    'setup-doc-overwrite': 'setUpDocumentsOverwrite',
    teardown: 'tearDown',
    'teardown-db': 'tearDownDatabases',
    'teardown-doc': 'tearDownDocuments',
    reset: 'reset',
    'reset-db': 'resetDatabases',
    'reset-doc': 'resetDocuments',
    clean: 'clean',
    'clean-db': 'cleanDatabases',
    'warm-view': 'warmViews',
    'live-deploy-view': 'liveDeployView'
  };

  var actions = {
    commands: {
      init: { action: _init }
    }
  };

  _.keys(FUNCTIONS).forEach(function (task) {
    actions.commands[task] = { action: _task(FUNCTIONS[task]) };
  });

  cli.command(__dirname, actions);
}
737824
def _create_event(self, alert_type, msg_title, msg, server, tags=None):
        
        msg_title = 'Couchbase {}: {}'.format(server, msg_title)
        msg = 'Couchbase instance {} {}'.format(server, msg)

        return {
            'timestamp': int(time.time()),
            'event_type': 'couchbase_rebalance',
            'msg_text': msg,
            'msg_title': msg_title,
            'alert_type': alert_type,
            'source_type_name': self.SOURCE_TYPE_NAME,
            'aggregation_key': server,
            'tags': tags,
        }