= exegesis by Matthew Lyon * http://github.com/mattly/exegesis == Description: A CouchDB ODM (Object/Document Mapper) in Ruby. == Features: Encourages per-"Account" databases. Actually, does not even currently provide a way to do a "singleton" or global database, however this is planned. Since a given class (say, "Article") cannot know what database it is supposed to get/search from you cannot do classical class-based finders such as "Article.find('value')". While it might be possible to pass in a database to use for some class-wide view, Exegesis takes the opinion that this is bad design for couchdb for the reasons that views may return multiple document types other than the desired class, and that views should be scoped to objects that mixin the database accessors. CouchDB is table-less, and Exegesis's design reflects this. In CouchDB, Documents are retrieved by their unique id, or can be queried from a view function in a design document. Exegesis provides tools to aid this. Additionally, since view functions can be used for map/reduce computations against your documents, Exegesis helps you get non-document data out of your views. == Examples: class Account include Exegesis::Database # declares the existence of a design document named 'articles' # view functions will be loaded from 'views/articles/:viewname/*.js design :articles do docs :by_author docs :at_path docs :tagged_with hash :tags_count, :view => :tagged_with end end @account.articles.by_author('user-mattly') # performs GET '/_design/articles/_view/by_author?key="user-mattly"&include_docs=true&reduce=false' @account.articles.at_path('blog/2009'..'blog/2009/04/04') # transforms the range into startkey/endkey # performs GET '/_design/articles/_view/at_path?startkey="blog/2009"&endkey="blog/2009/04/04" # &include_docs=true&reduce=false' @account.articles.tags_count('couchdb') # performs GET '/_design/articles/_view/tagged_with?key="couchdb"&group=true' class Article include Exegesis::Document # defines readers, writers for given attributes expose :path, :title, :body, :tags expose :published_at, :writer => false, :as => Time timestamps! # will load the document at the id referenced by doc['author']; does not yet set writer. expose :author, :as => :reference end == Requirements: * RestClient For running the tests: * Test::Unit (you got it) * Context (http://github.com/jeremymcanally/context, can install from github gems) * Matchy (http://github.com/jeremymcanally/matchy, github gem version out of date; clone, build & install for now) * Zebra (http://github.com/giraffesoft/zerba, depends on jeremymcanally-matchy, which is out of date; clone, build & install for now) The test suite creates and destroys a database for each test that requires access to the database. This is slow, and the test suite may take some time to run. However, I would rather the test suite be slow and accurate than quick and full of mocking.