Collection.prototype.find = function() {
  var args = Array.prototype.slice.call(arguments);
  var oncursor = common.future();
  var oncollection = this._oncollection;

  // we provide sugar for doing find(query, callback) -> find(query).toArray(callback);
  if (typeof args[args.length - 1] === 'function') {
    var callback = args.pop();

    oncursor.get(common.fork(callback, function(cur) {
      cur.toArray(callback);
    }));
  }

  common.step([

  function(next) {
      oncollection.get(next);
  },
  function(col, next) {
      args.push(next);
      col.find.apply(col, args);
  },
  function(cur) {
      oncursor.put(null, cur);
  }
 ], oncursor.put);

  return new Cursor(oncursor);
};
Ejemplo n.º 2
0
	that.collection = function(name) {
		var oncollection = common.future();

		common.step([
			function(next) {
				ondb.get(next);
			},
			function(db, next) {
				db.collection(name, next);
			},
			function(col) {
				oncollection.put(null, col);
			}
		], oncollection.put);

		return new Collection(oncollection);
	};
Ejemplo n.º 3
0
var Request = common.emitter(function(method, options) {
	this.readable = true;
	this.writable = true;

	this._lib = options.protocol === 'https:' ? https : http;

	this._options = {
		method:method,
		host:options.hostname,
		port:options.port
	};
	
	this._allowed = [];
	this._follow = true;
	this._head = false;
	this._piping = false;
	this._checkStatus = true;
	this._headers = {};
	this._path = options.pathname || '/';
	this._query = options.search || '';
	this._req = null;
	this._onresponse = common.future();
});
exports.connect = function(url, collections) {
  url = parse(url);

  var that = {};
  var ondb = common.future();

  common.step([

  function(next) {
      var client = new mongo.Db(url.db, new mongo.Server(url.host, url.port, {
        auto_reconnect: true
      }));

      that.bson = {
        Long: client.bson_serializer.Long,
        ObjectID: client.bson_serializer.ObjectID,
        Timestamp: client.bson_serializer.Timestamp,
        DBRef: client.bson_serializer.DBRef,
        Binary: client.bson_serializer.Binary,
        Code: client.bson_serializer.Code
      };

      client.open(next);
  },
  function(db, next) {
      this.db = db;

      if (url.username) {
        db.authenticate(url.username, url.password, next);
      } else {
        next(null, true);
      }
  },
  function(success) {
      if (!success) {
        ondb.put(new Error('invalid username or password'));
        return;
      }
      ondb.put(null, this.db);
  }
 ], ondb.put);

  that.ObjectId = createObjectId;
  that.collection = function(name) {
    var oncollection = common.future();

    common.step([

   function(next) {
        ondb.get(next);
   },
   function(db, next) {
        db.collection(name, next);
   },
   function(col) {
        oncollection.put(null, col);
   }
  ], oncollection.put);

    return new Collection(oncollection);
  };

  Object.keys(mongo.Db.prototype)
    .forEach(function(name) {
      if (!that[name] && typeof mongo.Db.prototype[name] === 'function') {
        that[name] = function() {
          var args = arguments;
          var callback = args[args.length - 1] || noop;

          ondb.get(common.fork(callback, function(db) {
            db[name].apply(db, args);
          }));
        };
      }
    });

  if (collections) {
    collections.forEach(function(col) {
      that[col] = that.collection(col);
    });
  }
  if (typeof Proxy !== 'undefined') {
    return Proxy.create({
      get: function(proxy, name) {
        if (!that[name]) {
          that[name] = that.collection(name);
        }
        return that[name];
      }
    });
  }

  return that;
};
Ejemplo n.º 5
0
var listen = function(options) {
	var that = common.createEmitter();
	var app = root();
	var id = process.pid.toString(16)+Math.random().toString(16).substr(2);
	var heartbeat;

	var onmonitor = common.future();
	var monitor = function(message) {
		onmonitor.get(function(err, daemon) {
			if (!daemon || !daemon.writable) return;
			daemon.write(JSON.stringify(message)+'\n');
		});
	};

	startMonitor(onmonitor.put);

	var cache = {};
	var own = new Repository(id);
	var repos = {me:own};
	var proxy = function(repo) {
		repo.on('push', function(key, values) {
			cache = {};
			values.forEach(function(val) {
				that.emit('push', key, val);
			});
		});
		repo.on('pop', function(key, values) {
			values.forEach(function(val) {
				that.emit('pop', key, val);
			});
		});
	};
	var repository = function(uri) {
		var repo = repos[uri];

		if (repo) return repo;

		monitor({up:uri});
		repo = repos[uri] = new Repository(uri);
		repo.on('destroy', function() {
			cache = {};
			delete repos[uri];
			monitor({down:uri});
		});

		proxy(repo);
		return repo;
	};
	var gc = function() {
		remote(function(repo) {
			request({
				uri: repo.uri+'/ping',
				json: true,
				timeout: PING_TIMEOUT
			}, onresponse(repo));
		});

		clearTimeout(heartbeat);
		heartbeat = setTimeout(gc, HEARTBEAT);
	};
	var onresponse = function(repo) {
		return function(err, res, body) {
			if (!err && res.statusCode === 200 && body.ack) return;
			repo.destroy();
		};
	};
	var remote = function(fn) {
		Object.keys(repos).forEach(function(uri) {
			if (uri === 'me') return;
			fn(repos[uri]);
		});
	};

	proxy(own);
	own.on('push', function(key, values) {
		cache = {};
		remote(function(repo) {
			request.post({
				uri: repo.uri+'/data/'+key,
				headers: {'x-repository': repo.uri},
				json: true,
				body: values
			}, onresponse(repo));
		});
	});

	app.use(root.json);

	app.get('/'+id, function(req, res) {
		res.json(own);
	});
	app.get('/'+id+'/ping', function(req, res) {
		res.json({ack:true});
	});
	app.post('/'+id+'/gc', function(req, res) {
		gc();
		res.json({ack:true});
	});
	app.post('/'+id+'/data/:key', function(req, res) {
		var repo = repository(req.headers['x-repository'] || own.uri);

		repo.push(req.params.key, req.json);
		res.json({ack:true});
	});

	app.listen(function(addr, server) {
		own.uri = 'http://'+ME+':'+server.address().port+'/'+id;
		gc();

		announce(own.uri, options, function(uri) {
			request({
				uri: uri,
				json: true
			}, function(err, res, body) {
				if (err || res.statusCode !== 200) return;

				repository(uri).pushAll(body);
				gc();
			});
		});
	});

	that.address = ME;
	that.push = function(key, val) {
		own.push(key, val);
	};
	that.get = function(key) {
		if (cache[key]) return cache[key];

		var list = cache[key] = [];

		Object.keys(repos).forEach(function(uri) {
			Array.prototype.push.apply(list, repos[uri].get(key));
		});

		return list;
	};
	that.all = function() {
		if (cache._all) return cache._all;

		var all = cache._all = {};

		Object.keys(repos).forEach(function(uri) {
			var repo = repos[uri];

			repo.keys().forEach(function(key) {
				Array.prototype.push.apply(all[key] = all[key] || [], repo.get(key));
			});
		});

		return all;
	};

	return that;
};
Ejemplo n.º 6
0
var connect = function(url, collections) {
	var that = {};
	var options = parseOptions(url);
	var ondb = common.future();

	options.collections = options.collections || collections || [];

	common.step([
		function(next) {
			var replSet = options.replSet && new mongo.ReplSetServers(options.replSet.members.map(function(member) {
				return new mongo.Server(member.host, member.port, {auto_reconnect:true});
			}), {
				read_secondary:options.replSet.slaveOk,
				rs_name:options.replSet.name
			});

			var client = new mongo.Db(options.db, replSet || new mongo.Server(options.host, options.port, {auto_reconnect:true}), {safe:false});

			that.client = client;
			that.bson = {
				Long:      client.bson_serializer.Long,
				ObjectID:  client.bson_serializer.ObjectID,
				Timestamp: client.bson_serializer.Timestamp,
				DBRef:     client.bson_serializer.DBRef,
				Binary:    client.bson_serializer.Binary,
				Code:      client.bson_serializer.Code
			};

			client.open(next);
		},
		function(db, next) {
			this.db = db;

			if (url.username) {
				db.authenticate(url.username, url.password, next);
			} else {
				next(null, true);
			}
		},
		function(success) {
			if (!success) {
				ondb.put(new Error('invalid username or password'));
				return;
			}
			ondb.put(null, this.db);
		}
	], ondb.put);

	that.ObjectId = createObjectId;
	that.collection = function(name) {
		var oncollection = common.future();

		common.step([
			function(next) {
				ondb.get(next);
			},
			function(db, next) {
				db.collection(name, next);
			},
			function(col) {
				oncollection.put(null, col);
			}
		], oncollection.put);

		return new Collection(oncollection);
	};

	Object.keys(mongo.Db.prototype).forEach(function(name) {
		if (shouldExtend(that, mongo.Db.prototype, name)) {
			that[name] = function() {
				var args = arguments;
				var callback = args[args.length-1] || noop;

				ondb.get(common.fork(callback, function(db) {
					db[name].apply(db, args);
				}));
			};
		}
	});

	if (collections) {
		collections.forEach(function(col) {
			that[col] = that.collection(col);
		});
	}
	if (typeof Proxy !== 'undefined') {
		return Proxy.create({
			get: function(proxy, name) {
				if (!that[name]) {
					that[name] = that.collection(name);
				}
				return that[name];
			}
		});
	}

	return that;
};
Ejemplo n.º 7
0
exports.connect = function(url, collections) {
	url = parse(url);
	
	var that = {};
	var ondb = common.future();

	common.step([
		function(next) {
			var client = new mongo.Db(url.db, new mongo.Server(url.host, url.port), {native_parser:true});
			
			that.bson = {
				Long:      client.bson_serializer.Long,
				ObjectID:  client.bson_serializer.ObjectID,
				Timestamp: client.bson_serializer.Timestamp,
				DBRef:     client.bson_serializer.DBRef,
				Binary:    client.bson_serializer.Binary,
				Code:      client.bson_serializer.Code
			};

			client.open(next);
		},
		function(db, next) {
			this.db = db;
			
			if (url.username) {
				db.authenticate(url.username, url.password, next);				
			} else {
				next(null, true);
			}
		},
		function(success) {
			if (!success) {
				ondb.put(new Error('invalid username or password'));
				return;
			}
			ondb.put(null, this.db);
		}
	], ondb.put);
	
	that.close = function(callback) {
		callback = callback || noop;
		
		ondb.get(common.fork(callback, function(db) {
			db.close(callback);
		}));
	};	
	that.collection = function(name) {
		var oncollection = common.future();
		
		common.step([
			function(next) {
				ondb.get(next);
			},
			function(db, next) {
				db.collection(name, next);
			},
			function(col) {
				oncollection.put(null, col);
			}
		], oncollection.put);
		
		return new Collection(oncollection);
	};
	
	if (collections) {
		collections.forEach(function(col) {
			that[col] = that.collection(col);
		});		
	}
	if (typeof Proxy !== 'undefined') {
		return Proxy.create({
			get: function(proxy, name) {
				if (!that[name]) {
					that[name] = that.collection(name);
				}
				return that[name];
			}
		});
	}
	
	return that;
};
Ejemplo n.º 8
0
var Peer = common.emitter(function(hub, socket) {
	var self = this;
	var types = {};

	this.address = null;
	this.onconnect = common.future();

	if (typeof socket === 'string') {
		this.address = socket;
		this.onconnect.put(this.address);
		socket = sockets.connect(socket);
		socket.send({type:'connect', from:hub.address, nodes:hub.nodes()});
	}

	this.callbacks = {};
	this.multiplexes = {};
	this.writable = this.readable = true;
	this.socket = socket;
	this.hub = hub;

	types.connect = function(message) {
		socket.send({type:'nodes', nodes:hub.nodes()});
		self.address = message.from;
		self.emit('connect', message.from);

		if (message.nodes.length) {
			self.emit('nodes', message.nodes);
		}

		self.onconnect.put(self.address);
	};
	types.nodes = function(message) {
		self.emit('nodes', message.nodes);
	};
	types.multiplex = function(message, callback) {
		var multiplexed = !!self.multiplexes[message.channel];

		if (multiplexed) {
			self.emit('multiplex', message.channel);
		}

		callback(null, multiplexed);
	};
	types.response = function(message) {
		(self.callbacks[message.id] || noop)(message.error && new Error(message.error), message.data);
	};
	types.message = function(message, callback) {
		self.emit('message', message, callback);
	};

	socket.on('close', function() {
		self.writable = self.readable = false;

		self.emit('close');

		if (self.address) {
			self.emit('disconnect', self.address);		
		}
		for (var i in self.callbacks) {
			self.callbacks[i](new Error('node failure'));
		}
	});
	socket.on('message', function(message) {
		(types[message.type] || types.message)(message, !message.id ? noop : function(err, data) {
			socket.send({id:message.id, type:'response', error:(err && err.message), data:data});
		});
	});
});
Ejemplo n.º 9
0
    exports.create = function(proxy) {
	var that = {};
	
	var onframe = common.future();
	var iframe = document.createElement('iframe');
	
	iframe.style.position   = 'absolute';
	iframe.style.left       = '-1000px';
	iframe.style.top        = '-1000px';
	iframe.style.visibility = 'hidden';
	
	iframe.src = proxy;
	
	var onbody = function() {
	    document.body.appendChild(iframe);
	};
	
	if (document.body) {
	    onbody();
	} else {
	    onevent('load', onbody);
	}
	
	var onmessage = function(event) {
	    onframe.put(iframe.contentWindow);
	    
	    onmessage = function(event) {
		var data;
		try {
		    data = JSON.parse(event.data);
		} catch (ex) {
		    data = {};
		}
		
		var callback = callbacks[data.id];
		
		if (!callback) {
		    return;
		}
		delete callbacks[data.id];
		
		callback(data.err && new Error(data.err), data.value);
	    };
	};
	var callbacks = {};
	
	onevent('message', function(event) {
		if (proxy.indexOf(event.origin) !== 0) {
		    return;
		}
		onmessage(event);
	    });

	/*
	  Sends message to the iFrame. 
	  Callback is invoked, when the iFrame responds. 
	*/
	var send = function(message, callback) {
	    var id = common.gensym();

	    callbacks[id] = callback;
	    message.id = id;

	    onframe.get(function(frame) {
		    frame.postMessage(JSON.stringify(message), proxy);
		});
	};

	/*
	  Send a cross-origin xhr request. 
	  Arguments: 
	    service : The request is sent to the url: domain/service, 
	              where domain is the domain on which the proxy is served. 
            settings : Same as in jQuery-1.6.2's $.ajax() method. 

	 */
	that.ajax = function() {
	    var callbacks = { };
	    return function(service, settings) {

		var id = common.gensym();
		callbacks[id] = { success : settings.success,
				  error : settings.error,
				  complete : settings.complete };
		
		send({ service : service, settings : settings}, function(err, result) {
			var callback = callbacks[id];
			delete callbacks[id];
			if(err && typeof(callback.error) === "function") {
			    callback.error(result.xhr, result.status, result.xhr.status); 
			}
			else if(typeof(callback.success) === "function") {
			    callback.success(result.xhr.responseText);
			}
			if(typeof(callback.complete) === "function") {
			    callback.complete(result.xhr, result.status);
			}
		    });
	    }
	}();
	    
	that.destroy = function() {
	    onframe.get(function() {
		    iframe.parentNode.removeChild(iframe);
		});
	};

	return that;
    };