Skip to content
Browse files

Moved the files around a bit and added package.json, so hopefully we …

…can use seedJS
  • Loading branch information...
1 parent e37150e commit 53ad161197e7f0b201cacd3ca0d7d814ede1c8f5 @jasonwyatt jasonwyatt committed with Apr 21, 2010
Showing with 608 additions and 206 deletions.
  1. +146 −0 lib/base64.js
  2. +253 −0 lib/index.js
  3. +205 −206 module/node-couch.js
  4. +4 −0 package.json
View
146 lib/base64.js
@@ -0,0 +1,146 @@
+/**
+ * Refactored variant in order to properly encapsulate private/protected
+ * methods within a functional scope and make things look a lot cleaner
+ * and lintier for greater good.
+ *
+ * @voodootikigod
+ */
+
+
+/**
+ *
+ * Base64 encode / decode
+ * Adapted from: http://www.webtoolkit.info/
+ *
+ **/
+
+var Base64 = (function() {
+
+ // private property
+ var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+
+ // private method for UTF-8 encoding
+ var _utf8_encode = function (string) {
+ string = string.replace(/\r\n/g,"\n");
+ var utftext = "";
+ for (var n = 0; n < string.length; n++) {
+ var c = string.charCodeAt(n);
+ if (c < 128) {
+ utftext += String.fromCharCode(c);
+ }
+ else if((c > 127) && (c < 2048)) {
+ utftext += String.fromCharCode((c >> 6) | 192);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ else {
+ utftext += String.fromCharCode((c >> 12) | 224);
+ utftext += String.fromCharCode(((c >> 6) & 63) | 128);
+ utftext += String.fromCharCode((c & 63) | 128);
+ }
+ }
+ return utftext;
+ };
+
+ // private method for UTF-8 decoding
+ var _utf8_decode = function (utftext) {
+ var string = "";
+ var i = 0;
+ var c = c1 = c2 = 0;
+ while ( i < utftext.length ) {
+ c = utftext.charCodeAt(i);
+ if (c < 128) {
+ string += String.fromCharCode(c);
+ i++;
+ }
+ else if((c > 191) && (c < 224)) {
+ c2 = utftext.charCodeAt(i+1);
+ string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
+ i += 2;
+ }
+ else {
+ c2 = utftext.charCodeAt(i+1);
+ c3 = utftext.charCodeAt(i+2);
+ string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+ i += 3;
+ }
+ }
+ return string;
+ };
+
+
+ return {
+ encode : function (input) {
+ var output = "";
+ var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
+ var i = 0;
+
+ input = _utf8_encode(input);
+
+ while (i < input.length) {
+
+ chr1 = input.charCodeAt(i++);
+ chr2 = input.charCodeAt(i++);
+ chr3 = input.charCodeAt(i++);
+
+ enc1 = chr1 >> 2;
+ enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+ enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+ enc4 = chr3 & 63;
+
+ if (isNaN(chr2)) {
+ enc3 = enc4 = 64;
+ } else if (isNaN(chr3)) {
+ enc4 = 64;
+ }
+
+ output = output +
+ _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
+ _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
+
+ }
+
+ return output;
+ },
+
+ // public method for decoding
+ decode : function (input) {
+ var output = "";
+ var chr1, chr2, chr3;
+ var enc1, enc2, enc3, enc4;
+ var i = 0;
+
+ input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
+
+ while (i < input.length) {
+
+ enc1 = this._keyStr.indexOf(input.charAt(i++));
+ enc2 = this._keyStr.indexOf(input.charAt(i++));
+ enc3 = this._keyStr.indexOf(input.charAt(i++));
+ enc4 = this._keyStr.indexOf(input.charAt(i++));
+
+ chr1 = (enc1 << 2) | (enc2 >> 4);
+ chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+ chr3 = ((enc3 & 3) << 6) | enc4;
+
+ output = output + String.fromCharCode(chr1);
+
+ if (enc3 != 64) {
+ output = output + String.fromCharCode(chr2);
+ }
+ if (enc4 != 64) {
+ output = output + String.fromCharCode(chr3);
+ }
+
+ }
+
+ output = exports.base64._utf8_decode(output);
+
+ return output;
+
+ }
+ }
+})()
+
+exports.encode = Base64.encode;
+exports.decode = Base64.decode;
+
View
253 lib/index.js
@@ -0,0 +1,253 @@
+/*
+Copyright (c) 2009 Hagen Overdick
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+var sys = require('sys'),
+ http = require('http'),
+ url = require('url'),
+ base64 = require('./base64');
+
+var clients = {};
+
+function cache_client(host) {
+ var client = clients[host];
+ if (client) {
+ return client;
+ } else {
+ var uri = url.parse(host);
+ return clients[host] = http.createClient(uri.port, uri.hostname);
+ }
+}
+
+function _interact(verb, path, successStatus, options, host) {
+ verb = verb.toUpperCase();
+ options = options || {};
+ var request;
+
+ var client = cache_client(host);
+ var requestPath = path + encodeOptions(options);
+ if (CouchDB.debug) {
+ sys.puts("COUCHING " + requestPath + " -> " + verb);
+ }
+
+ var uri = url.parse(host);
+ var headers = {};
+ headers["Host"] = uri.hostname;
+ if (uri.auth) {
+ headers["Authorization"] = "Basic "+base64.encode(uri.auth);
+ }
+
+ if (options.keys) {
+ options.body = {keys: options.keys};
+ }
+
+ if (options.body) {
+ if (verb === "get") {
+ verb = "post";
+ }
+ var requestBody = toJSON(options.body);
+
+ headers["Content-Length"] = requestBody.length;
+ headers["Content-Type"] = "application/json";
+
+ request = client.request(verb, requestPath, headers);
+ request.write(requestBody, "utf8");
+ } else {
+ request = client.request(verb, requestPath, headers);
+ }
+
+ request.addListener('response', function(response) {
+ var responseBody = ""
+
+ response.setBodyEncoding("utf8");
+
+ response.addListener("data", function(chunk) {
+ responseBody += chunk
+ });
+
+ response.addListener("end", function() {
+ if (CouchDB.debug) {
+ sys.puts("COMPLETED " + requestPath + " -> " + verb);
+ sys.puts(responseBody)
+ }
+ responseBody = JSON.parse(responseBody);
+
+ if (response.statusCode === successStatus) {
+ if (options.success) {
+ options.success(responseBody);
+ }
+ } else if (options.error) {
+ options.error(responseBody);
+ }
+ });
+ });
+
+ request.end();
+
+}
+
+function encodeOptions(options) {
+ var result = [];
+ if (typeof(options) === "object" && options !== null) {
+ for (var name in options) {
+ if (options.hasOwnProperty(name)) {
+ if (name === "request" || name === "error" || name === "success" || name === "body" || name === "keys") {
+ continue;
+ }
+
+ var value = options[name];
+
+ if (name == "key" || name == "startkey" || name == "endkey") {
+ value = toJSON(value);
+ }
+
+ result.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
+ }
+ }
+ }
+ return result.length ? ("?" + result.join("&")) : "";
+}
+
+function toJSON(obj) {
+ return obj !== null ? JSON.stringify(obj) : null;
+}
+
+var CouchDB = {
+ // Possible basic auth eg: "http://admin:password@127.0.0.1:5984"
+ defaultHost : "http://localhost:5984",
+ debug : true,
+
+ activeTasks: function(options) {
+ _interact("get", "/_active_tasks", 200, options, CouchDB.defaultHost);
+ },
+
+ allDbs : function(options) {
+ _interact("get", "/_all_dbs", 200, options, CouchDB.defaultHost);
+ },
+
+ generateUUIDs : function(options) {
+ options = options || {};
+ if (!options.count) {
+ options.count = 100;
+ }
+ var callback = options.success;
+ options.success = function(result) {
+ callback(result.uuids);
+ };
+ _interact("get", "/_uuids", 200, options, CouchDB.defaultHost);
+ },
+
+ db : function(name, host) {
+ return {
+ name : name,
+ uri : "/" + encodeURIComponent(name) + "/",
+ host : host || CouchDB.defaultHost,
+
+ interact : function(verb, path, successStatus, options, suppressPrefix) {
+ if (!suppressPrefix) {
+ path = this.uri + path;
+ }
+ _interact(verb, path, successStatus, options, this.host);
+ },
+
+ compact : function(options) {
+ this.interact("post", "_compact", 202, options);
+ },
+
+ create : function(options) {
+ this.interact("put", "", 201, options);
+ },
+
+ drop : function(options) {
+ this.interact("del", "", 200, options);
+ },
+
+ info : function(options) {
+ this.interact("get", "", 200, options);
+ },
+
+ allDocs : function(options) {
+ this.interact("get", "_all_docs", 200, options);
+ },
+
+ openDoc : function(docId, options) {
+ var path;
+ if (typeof docId === "string") {
+ path = docId;
+ } else {
+ path = "_all_docs";
+ options.body = {
+ keys : docId
+ };
+ }
+ this.interact("get", path, 200, options); // interact will override get to post when needed
+ },
+
+ saveDoc : function(doc, options) {
+ options = options || {};
+ doc = doc || {};
+ var success = options.success;
+ options.success = function(result) {
+ if (!result.ok) {
+ options.error(result);
+ } else {
+ doc._id = result.id;
+ doc._rev = result.rev;
+ }
+ if (success) { success(doc); }
+ };
+
+ options.body = doc;
+
+ if (doc._id === undefined) {
+ this.interact("post", "", 201, options);
+ } else {
+ this.interact("put", doc._id, 201, options);
+ }
+ },
+
+ removeDoc : function(doc, options) {
+ options = options || {};
+ options.rev = doc._rev;
+
+ var success = options.success;
+ options.success = function(result) {
+ if (!result.ok) {
+ options.error(result);
+ }
+ delete doc._rev;
+ if (success) {
+ success(doc);
+ }
+ };
+
+ this.interact("del", doc._id, 200, options);
+ },
+
+ view : function(name, options) {
+ name = name.split('/');
+ this.interact("get", "_design/" + name[0] + "/_view/" + name[1], 200, options);
+ }
+ }
+ }
+};
+
+exports.CouchDB = CouchDB;
View
411 module/node-couch.js
@@ -28,103 +28,102 @@ var sys = require('sys'),
var clients = {};
function cache_client(host) {
- var client = clients[host];
- if (client) {
- return client;
- } else {
+ var client = clients[host];
+ if (client) {
+ return client;
+ } else {
var uri = url.parse(host);
- return clients[host] = http.createClient(uri.port, uri.hostname);
- }
+ return clients[host] = http.createClient(uri.port, uri.hostname);
+ }
}
function _interact(verb, path, successStatus, options, host) {
- verb = verb.toUpperCase();
- options = options || {};
- var request;
-
- var client = cache_client(host);
- var requestPath = path + encodeOptions(options);
- if (CouchDB.debug) {
- sys.puts("COUCHING " + requestPath + " -> " + verb);
- }
-
-
- var uri = url.parse(host);
- var headers = {};
- headers["Host"] = uri.hostname;
- if (uri.auth) {
- headers["Authorization"] = "Basic "+base64.encode(uri.auth);
- }
-
- if (options.keys) {
- options.body = {keys: options.keys};
- }
-
- if (options.body) {
- if (verb === "get") {
- verb = "post";
- }
- var requestBody = toJSON(options.body);
-
- headers["Content-Length"] = requestBody.length;
- headers["Content-Type"] = "application/json";
-
- request = client.request(verb, requestPath, headers);
- request.write(requestBody, "utf8");
- } else {
- request = client.request(verb, requestPath, headers);
- }
-
- request.addListener('response', function(response) {
- var responseBody = ""
-
- response.setBodyEncoding("utf8");
-
- response.addListener("data", function(chunk) {
- responseBody += chunk
- });
-
- response.addListener("end", function() {
- if (CouchDB.debug) {
- sys.puts("COMPLETED " + requestPath + " -> " + verb);
- sys.puts(responseBody)
- }
- responseBody = JSON.parse(responseBody);
-
- if (response.statusCode === successStatus) {
- if (options.success) {
- options.success(responseBody);
- }
- } else if (options.error) {
- options.error(responseBody);
- }
- });
- });
-
- request.close()
-
+ verb = verb.toUpperCase();
+ options = options || {};
+ var request;
+
+ var client = cache_client(host);
+ var requestPath = path + encodeOptions(options);
+ if (CouchDB.debug) {
+ sys.puts("COUCHING " + requestPath + " -> " + verb);
+ }
+
+ var uri = url.parse(host);
+ var headers = {};
+ headers["Host"] = uri.hostname;
+ if (uri.auth) {
+ headers["Authorization"] = "Basic "+base64.encode(uri.auth);
+ }
+
+ if (options.keys) {
+ options.body = {keys: options.keys};
+ }
+
+ if (options.body) {
+ if (verb === "get") {
+ verb = "post";
+ }
+ var requestBody = toJSON(options.body);
+
+ headers["Content-Length"] = requestBody.length;
+ headers["Content-Type"] = "application/json";
+
+ request = client.request(verb, requestPath, headers);
+ request.write(requestBody, "utf8");
+ } else {
+ request = client.request(verb, requestPath, headers);
+ }
+
+ request.addListener('response', function(response) {
+ var responseBody = ""
+
+ response.setBodyEncoding("utf8");
+
+ response.addListener("data", function(chunk) {
+ responseBody += chunk
+ });
+
+ response.addListener("end", function() {
+ if (CouchDB.debug) {
+ sys.puts("COMPLETED " + requestPath + " -> " + verb);
+ sys.puts(responseBody)
+ }
+ responseBody = JSON.parse(responseBody);
+
+ if (response.statusCode === successStatus) {
+ if (options.success) {
+ options.success(responseBody);
+ }
+ } else if (options.error) {
+ options.error(responseBody);
+ }
+ });
+ });
+
+ request.end();
+
}
function encodeOptions(options) {
- var result = [];
- if (typeof(options) === "object" && options !== null) {
- for (var name in options) {
- if (options.hasOwnProperty(name)) {
- if (name === "request" || name === "error" || name === "success" || name === "body" || name === "keys") {
- continue;
- }
-
- var value = options[name];
-
- if (name == "key" || name == "startkey" || name == "endkey") {
- value = toJSON(value);
- }
-
- result.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
- }
- }
- }
- return result.length ? ("?" + result.join("&")) : "";
+ var result = [];
+ if (typeof(options) === "object" && options !== null) {
+ for (var name in options) {
+ if (options.hasOwnProperty(name)) {
+ if (name === "request" || name === "error" || name === "success" || name === "body" || name === "keys") {
+ continue;
+ }
+
+ var value = options[name];
+
+ if (name == "key" || name == "startkey" || name == "endkey") {
+ value = toJSON(value);
+ }
+
+ result.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
+ }
+ }
+ }
+ return result.length ? ("?" + result.join("&")) : "";
}
function toJSON(obj) {
@@ -133,122 +132,122 @@ function toJSON(obj) {
var CouchDB = {
// Possible basic auth eg: "http://admin:password@127.0.0.1:5984"
- defaultHost : "http://localhost:5984",
- debug : true,
-
- activeTasks: function(options) {
- _interact("get", "/_active_tasks", 200, options, CouchDB.defaultHost);
- },
-
- allDbs : function(options) {
- _interact("get", "/_all_dbs", 200, options, CouchDB.defaultHost);
- },
-
- generateUUIDs : function(options) {
- options = options || {};
- if (!options.count) {
- options.count = 100;
- }
- var callback = options.success;
- options.success = function(result) {
- callback(result.uuids);
- };
- _interact("get", "/_uuids", 200, options, CouchDB.defaultHost);
- },
-
- db : function(name, host) {
- return {
- name : name,
- uri : "/" + encodeURIComponent(name) + "/",
- host : host || CouchDB.defaultHost,
-
- interact : function(verb, path, successStatus, options, suppressPrefix) {
- if (!suppressPrefix) {
- path = this.uri + path;
- }
- _interact(verb, path, successStatus, options, this.host);
- },
-
- compact : function(options) {
- this.interact("post", "_compact", 202, options);
- },
-
- create : function(options) {
- this.interact("put", "", 201, options);
- },
-
- drop : function(options) {
- this.interact("del", "", 200, options);
- },
-
- info : function(options) {
- this.interact("get", "", 200, options);
- },
-
- allDocs : function(options) {
- this.interact("get", "_all_docs", 200, options);
- },
-
- openDoc : function(docId, options) {
- var path;
- if (typeof docId === "string") {
- path = docId;
- } else {
- path = "_all_docs";
- options.body = {
- keys : docId
- };
- }
- this.interact("get", path, 200, options); // interact will override get to post when needed
- },
-
- saveDoc : function(doc, options) {
- options = options || {};
- doc = doc || {};
- var success = options.success;
- options.success = function(result) {
- if (!result.ok) {
- options.error(result);
- } else {
- doc._id = result.id;
- doc._rev = result.rev;
- }
- if (success) { success(doc); }
- };
-
- options.body = doc;
-
- if (doc._id === undefined) {
- this.interact("post", "", 201, options);
- } else {
- this.interact("put", doc._id, 201, options);
- }
- },
-
- removeDoc : function(doc, options) {
- options = options || {};
- options.rev = doc._rev;
-
- var success = options.success;
- options.success = function(result) {
- if (!result.ok) {
- options.error(result);
- }
- delete doc._rev;
- if (success) {
- success(doc);
- }
- };
-
- this.interact("del", doc._id, 200, options);
- },
-
- view : function(name, options) {
- name = name.split('/');
- this.interact("get", "_design/" + name[0] + "/_view/" + name[1], 200, options);
- }
- }
- }
+ defaultHost : "http://localhost:5984",
+ debug : true,
+
+ activeTasks: function(options) {
+ _interact("get", "/_active_tasks", 200, options, CouchDB.defaultHost);
+ },
+
+ allDbs : function(options) {
+ _interact("get", "/_all_dbs", 200, options, CouchDB.defaultHost);
+ },
+
+ generateUUIDs : function(options) {
+ options = options || {};
+ if (!options.count) {
+ options.count = 100;
+ }
+ var callback = options.success;
+ options.success = function(result) {
+ callback(result.uuids);
+ };
+ _interact("get", "/_uuids", 200, options, CouchDB.defaultHost);
+ },
+
+ db : function(name, host) {
+ return {
+ name : name,
+ uri : "/" + encodeURIComponent(name) + "/",
+ host : host || CouchDB.defaultHost,
+
+ interact : function(verb, path, successStatus, options, suppressPrefix) {
+ if (!suppressPrefix) {
+ path = this.uri + path;
+ }
+ _interact(verb, path, successStatus, options, this.host);
+ },
+
+ compact : function(options) {
+ this.interact("post", "_compact", 202, options);
+ },
+
+ create : function(options) {
+ this.interact("put", "", 201, options);
+ },
+
+ drop : function(options) {
+ this.interact("del", "", 200, options);
+ },
+
+ info : function(options) {
+ this.interact("get", "", 200, options);
+ },
+
+ allDocs : function(options) {
+ this.interact("get", "_all_docs", 200, options);
+ },
+
+ openDoc : function(docId, options) {
+ var path;
+ if (typeof docId === "string") {
+ path = docId;
+ } else {
+ path = "_all_docs";
+ options.body = {
+ keys : docId
+ };
+ }
+ this.interact("get", path, 200, options); // interact will override get to post when needed
+ },
+
+ saveDoc : function(doc, options) {
+ options = options || {};
+ doc = doc || {};
+ var success = options.success;
+ options.success = function(result) {
+ if (!result.ok) {
+ options.error(result);
+ } else {
+ doc._id = result.id;
+ doc._rev = result.rev;
+ }
+ if (success) { success(doc); }
+ };
+
+ options.body = doc;
+
+ if (doc._id === undefined) {
+ this.interact("post", "", 201, options);
+ } else {
+ this.interact("put", doc._id, 201, options);
+ }
+ },
+
+ removeDoc : function(doc, options) {
+ options = options || {};
+ options.rev = doc._rev;
+
+ var success = options.success;
+ options.success = function(result) {
+ if (!result.ok) {
+ options.error(result);
+ }
+ delete doc._rev;
+ if (success) {
+ success(doc);
+ }
+ };
+
+ this.interact("del", doc._id, 200, options);
+ },
+
+ view : function(name, options) {
+ name = name.split('/');
+ this.interact("get", "_design/" + name[0] + "/_view/" + name[1], 200, options);
+ }
+ }
+ }
};
exports.CouchDB = CouchDB;
View
4 package.json
@@ -0,0 +1,4 @@
+{
+ "name": "node-couch",
+ "version": "0.1.0"
+}

0 comments on commit 53ad161

Please sign in to comment.
Something went wrong with that request. Please try again.