Skip to content

Commit

Permalink
added synchronous api_factory, updated docs
Browse files Browse the repository at this point in the history
  • Loading branch information
dgreisen committed Nov 9, 2011
1 parent 279da01 commit 97e49f8
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 20 deletions.
29 changes: 21 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

Simply import YACA, and call the factory function. The factory function introspects your CouchDB instance and returns a custom api. This allows you to make intuitive and easy calls to your database, and inspect your database from the commandline. For example, to request all documents from the 'master' view of the '_design/app' design document of your 'primary_db' database you simply make the following call:

api_factory = require('YACA');
api_factory = require('YACA').api_factory;
api_factory(function(error, couchdb_api) {
couchdb_api.primary_db.app.views.master(function(error, response, body) {
console.log(body)
Expand All @@ -25,23 +25,36 @@ argument and a callback. They return an error, the original response, and the pa

## Usage ##
### 1. Generate API ###
First, generate the API by calling:
The database can be introspected at runtime using the asynchronous `api_factory`. When this function is called, the database is introspected, an api is constructed, and a cache of the CouchDB structure is saved. The synchronous `api_factory_sync` can use a cache previously generated by the asynchronous `api_factory` to synchronously generate an api. The synchronous gactory will not introspect the database, only use the cache from a previous introspection. You can optionally call the helper `generate_couch_api` from the command line to generate a cache of your couchdb structure.

api_factory = require('YACA');
#### Asynchronous factory ####
From within node call:

api_factory = require('YACA').api_factory;
api_factory(factory_options, callback)

* `factory_options` - an optional hash. See [factory options](#factory_options) reference for more.
* `callback` - a callback function of the form `callback(error, couchdb_api)`.

You can optionally call `generate_couche_api` from the commandline:
#### Generate cache from command line ####
From the command line:

generate_couch_api [-f PATH] [-d DB_URL] [-a USERNAME:PASSWORD]

* `PATH` - the location of the file into which to write the couchdb api. If not specified, it will be placed in path/to/YACA/lib/couchdb.js, and will be imported when you `require('YACA')`.
* `PATH` - the location of the cached database configuration. YACA caches the database structure so it does not have to introspect the database every time it generates an api. If set to `false`, no cache will be created. Defaults to path/to/YACA/lib/api_cache.json.
* `DB_URL` - the url to your CouchDB instance. It defaults to `http://127.0.0.1:5984`. If privileges are needed to view design documents or the root instance, provide username and password as: `http://username:password@host_name`
* `USERNAME:PASSWORD` - basic auth credentials where `USERNAME` is an admin username and `PASSWORD` is the admin's password, if you wish to be able to access admin-restricted content through the api. *The username and password will be stored in the generated cache.* See [options reference](#options) for more.

The command line function is useful for generating a cache that your production code can then access and create an api without ever having to introspect the database.
The command line function is useful for generating a cache that your production code can then access to create an api without ever having to introspect the database. This command simply calls the asynchronous factory.

#### Synchronous factory ####
Once you have a cache, either from the command line or from a previous call to the asynchronous factory:

api_factory_sync = require('YACA').api_factory_sync;
api_factory_sync(file)

* `file` - the location of the cached database configuration. Defaults to path/to/YACA/lib/api_cache.json.


### 2. Use the API ###
There are four primary API methods, corresponding to the http methods:
Expand Down Expand Up @@ -80,7 +93,7 @@ Assume we have a CouchDB instance with the following structure:

We use the api thus:

couchdb_factory = require('YACA');
couchdb_factory = require('YACA').api_factory;

couchdb_factory( { db_url:'127.0.0.1:5984'
, admin :'administrator:password'
Expand Down Expand Up @@ -123,7 +136,7 @@ When couchdb returns any code greater than 299, the api returns a javascript opt
The couchdb_factory, takes an optional options hash. If no hash is given, the defaults will be used. The defaults usually work just fine. However it is important to use `update` when the database structure has changed.
* `db_url` - the url to your CouchDB instance. It defaults to `http://127.0.0.1:5984`. If privileges are needed to view design documents or the root instance, provide username and password as: `http(s)://username:password@host_name`
* `admin` - basic auth string, `USERNAME:PASSWORD`, where `USERNAME` is an admin username and `PASSWORD` is the admin password, if you wish to be able to access admin-restricted content through the api. *The username and password will be stored in plain text in the cache.* See [options] reference(#options) for more.
* `file` is the location of the cached database configuration. YACA caches thedatabase structure so it does not have to introspect the database every time it generates an api. If set to `false`, no cache will be created. If not specified, the cache will be placed in path/to/YACA/lib/couchdb.js.
* `file` is the location of the cached database configuration. YACA caches the database structure so it does not have to introspect the database every time it generates an api. If set to `false`, no cache will be created. Defaults to path/to/YACA/lib/api_cache.json.
* `update` controls introspection. If `update: true`, then the database will be introspected when an api is created even if a cache exists.

You must create a new API whenever you add or remove a database, or you modify a design document.
Expand Down
30 changes: 20 additions & 10 deletions lib/api_factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var Request = require('request');
var querystring = require('querystring');
var factory = require('./factory');
var factory_factory = factory.factory;
var factory_factory_sync = factory.factory_sync;
var proto_helper = factory.proto_helper;
var constructor_helper = factory.constructor_helper;
var child_constructor = factory.child_constructor;
Expand Down Expand Up @@ -31,16 +32,9 @@ proto_couchdb['_uuids'] = function(count, callback) {
return callback(null, b['uuids']);
}
}
/*
proto_couchdb[' get'] = function(options, callback) {
console.log(this);
return this._request(options, null, callback)
}
*/

// options:
// file: name of cache file false if no cache - defaults to ./couchdb.json
// file: name of cache file false if no cache - defaults to ./api_cache.json
// db_url: url of couchdb - defaults to http://127.0.0.1:5984
// update: update cache on init - defaults to false
// admin: admin credentials
Expand All @@ -55,7 +49,7 @@ proto_couchdb.constructor = function(options, callback){
var cache = {}

if (options.file !== false) {
options.file = options.file || path.join(__dirname, '/couchdb.js')
options.file = options.file || path.join(__dirname, '/api_cache.json')
return fs.readFile(options.file, 'utf8', handle_file);
}
else {
Expand Down Expand Up @@ -226,4 +220,20 @@ proto_couchdb.constructor = function(options, callback){


var couchdb_factory = factory_factory(proto_couchdb)
module.exports = couchdb_factory;


// synchronous version of couchdb_factory
// file: name of cache file false if no cache - defaults to ./api_cache.json

var proto_couchdb_sync = proto_couchdb;
proto_couchdb_sync.constructor = function(file) {
file = file || path.join(__dirname, '/api_cache.json')

var cache = JSON.parse(fs.readFileSync(file, 'utf8'));
constructor_helper.apply(this, [cache]);
child_constructor.apply(this, [cache, db_factory]);
}

var couchdb_factory_sync = factory_factory_sync(proto_couchdb_sync)
exports.api_factory = couchdb_factory;
exports.api_factory_sync = couchdb_factory_sync;
7 changes: 6 additions & 1 deletion lib/db_factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,17 @@ proto_ddoc.constructor = function(cache) {
}
var ddoc_factory = factory_factory(proto_ddoc)

// ** CouchDB root **
// ** database**
var proto_db = proto_helper(['get', 'put', 'post', 'del'], 'get');

proto_db.constructor = function(cache) {
constructor_helper.apply(this, [cache]);
child_constructor.apply(this, [cache, ddoc_factory]);
}

proto_db._new_doc = function(json, callback)


var db_factory = factory_factory(proto_db)


Expand Down
1 change: 0 additions & 1 deletion lib/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ cache =
function constructor_helper(cache) {
var ADMIN_PATH = cache.ADMIN_PATH;
var PATH = cache.PATH;

// private. has_error returns the error/couchdb error, if it exists or null.
var _has_error = function(error, response, body) {
// return connection error
Expand Down

0 comments on commit 97e49f8

Please sign in to comment.