CouchApp 有两条基本的命令,分别是push和generate。
- push命令的作用是把文件系统目录保存到 CouchDB 的设计文档中。它的语法是couchapp push [options] [appdir] [appname] [dburl],如命令couchapp push . http://127.0.0.1:5984/databasename的作用是把当前目录的内容保存到数据库databasename中。
- generate命令的作用是创建一个应用,所创建的应用有比较好的目录结构,推荐使用。它的语法是couchapp generate <appname> [appdir],如命令couchapp generate myapp的作用是在当前目录创建名为myapp的应用。
对于本文中介绍的示例应用来说,首先使用couchapp generate dianping来创建,然后使用couchapp push . http://127.0.0.1:5984/dianping来保存到 CouchDB 中,然后就可以通过浏览器访问http://127.0.0.1:5984/dianping/_design/dianping/index.html来查看该应用。在对 CouchApp 生成的目录结构进行删减之后,就得到了该应用的目录结构,如图 2 所示。
图 2. 示例应用的目录结构图
如图 2所示,_attachments目录中包含的是静态的 JavaScript 和 CSS 文件;vendor目录中包含的是 CouchApp 提供的一些 JavaScript 类库;views目录中包含的是永久视图定义;shows目录中包含的是格式化文档的 show 方法;lists目录中包含的是格式化视图运行结果的 list 方法;templates目录中包含的是 show 和 list 方法所需的 HTML 模板。在下面的章节中将会具体介绍这些目录中存放的文件。
使用 CouchDB jQuery 插件
前面提到 CouchDB 提供了返回 JSON 数据的 REST API,在浏览器中使用 JavaScript 就可以很容易的通过 Ajax 请求来操纵 CouchDB 。 CouchDB 自带的管理工具 Futon 使用了一个 jQuery 的插件来操纵 CouchDB 。在一般的 Web 应用中也可以使用该插件,其 JavaScript 文件的路径是 /_utils/script/jquery.couch.js。表 1 中给出了该插件中的常用方法。本文的示例应用使用 jQuery 和该插件来开发。
表 1. jQuery CouchDB 插件的常用方法
方法 | 说明 |
---|---|
$.couch.allDbs(options) | 获取 CouchDB 中所有数据库的信息。 |
$.couch.db(dbname).create(options) | 创建名为dbname的数据库。 |
$.couch.db(dbname).drop(options) | 删除名为dbname的数据库。 |
$.couch.db(dbname).info(options) | 获取名为dbname的数据库的信息。 |
$.couch.db(dbname).allDocs(options) | 获取名为dbname的数据库中的全部文档。 |
$.couch.db(dbname).allDesignDocs(options) | 获取名为dbname的数据库中的全部设计文档。 |
$.couch.db(dbname).openDoc(docId, options) | 获取名为dbname的数据库中 ID 为docId的文档内容。 |
$.couch.db(dbname).saveDoc(doc, options) | 把内容为doc的文档保存到名为dbname的数据库中。 |
$.couch.db(dbname).removeDoc(doc, options) | 从名为dbname的数据库中删除内容为doc的文档。 |
$.couch.db(dbname).query(mapFun, reduceFun, language, options) | 基于 Map 和 Reduce 方法创建临时视图并进行查询。 |
$.couch.db(dbname).view(viewname, options) | 获取名为dbname的数据库中永久视图viewname的运行结果。 |
在表 1 中,所有方法的参数 options 表示调用 CouchDB REST API 的可选参数,其中一般需要包含 success 和 error 两个方法作为请求正确完成和出现错误时的回调方法。
示例应用建模
在对示例应用经过分析之后,确定应用中应该包含两类实体,即图书和用户评论。图书实体的属性有名称、作者、出版日期、出版社、简介、标签等,用户评论的属性有评论者的姓名和评论内容。代码清单 8 中给出了两类实体在 CouchDB 中的文档实例,其中 type 字段是用来区分不同类别的文档,方便用视图来进行查询。
清单 8. 图书和用户评论的 CouchDB 文档实例
// 图书 { "_id": "4c4e301b00351326f5692b5e7be41d43", "_rev": "3-3409240079", "title": " 光月道重生美丽 ", "author": " 自由鸟 ", "press": " 长江文艺出版社 ", "price": "19.8", "tags": [ " 小说 ", " 爱情 ", " 都市小说 " ], "summary": " 人与人之间喜爱、憎恨、吸引、排斥 ... 皆因生活在同一个世界而产生,好像绿绒桌子上 .....", "type": "book", "publish_date": "2009-2-1" } // 用户评论 { "_id": "27026e72f41cbc4ea3e29d402984dcdc", "_rev": "1-2177730796", "book_id": "8ee34f275e6ed7de6e219f5ea1dcaafd", "commenter_name": "alex", "comment": " 这本书写得不错 ", "type": "comment", "created_at": 1243767814421 } |
下面将具体介绍如何在应用中管理文档和使用视图。
管理文档
下面以图书这类文档为例来说明如何对文档进行操作,所涉及的操作包括文档的创建、更新和删除。对文档进行管理需要提供给用户相应的 HTML 页面,而实际的操作是通过CouchDB jQuery 插件调用 CouchDB 的REST API来完成的。
创建与更新文档
创建文档和更新文档的行为是类似的,都需要一个 HTML 表单来接受用户的输入。所不同的是更新文档的时候,需要用文档的当前内容填充表单。在表单提交的时候,需要提取表单中的内容并创建文档的 JSON 对象,接着将该 JSON 对象保存到 CouchDB 中。
因为需要返回的是 HTML 页面,因此需要用到前面提到的设计文档中的 show 方法。所有的 show 方法都是存放在设计文档的 shows 字段里面的,如代码清单 9 所示。
清单 9. 设计文档中的shows字段
{ "_id" : "_design/dianping", "shows" : { "example_show" : "function(doc, req) { ... }", "another_show" : "function(doc, req) { ... }" } |
代码清单 9中定义了两个 show 方法,分别是example_show和another_show。通过 URL/dianping/_design/dianping/_show/example_show/doc_id就可以调用数据库dianping中设计文档dianping中名为example_show的方法,并且传入对应的文档 IDdoc_id。每个 show 方法都可以有两个参数:doc和req,其中 doc表 示的是与请求的文档 ID 对应的文档内容,而req则表示与当前请求相关的内容,是一个 JSON 对象。表 2 中给出了该 JSON 对象的属性和含义。
表 2. show 方法的req参数
属性 | 说明 |
---|---|
body | 对于 GET 请求来说,该属性的值是undefined;对于 POST/PUT 请求来说,该属性的值是请求的内容。 |
cookie | 该属性表示浏览器端的 cookie 。 |
form | 如果请求的内容类型(Content Type)是application/x-www-form-urlencoded的话,该属性包含解码之后的 JSON 对象。 |
info | 该属性包含所请求的 CouchDB 数据库的信息。 |
path | 该属性是一个数组,表示请求的路径。 |
query | 该属性包含对请求的查询字符串解码之后的 JSON 对象。 |
verb | 该属性表示 HTTP 请求的方法,一般是 GET/POST/PUT/DELETE 。 |
这里需要注意的是请求中的文档 ID 与 show 方法的参数doc的关系,具体的情况如下:
- 请求中传入了文档 ID,并且数据库中存在与此 ID 对应的文档:这种情况下,doc的值就是此 ID 对应的文档内容。
- 请求中传入了文档 ID,但是数据库中没有与此 ID 对应的文档:这种情况下,doc的值是null,可以通过req.docId获取此 ID 。一般的行为是创建 ID 为req.docId的文档。
- 请求中没有传入文档 ID:这种情况下,doc和req.docId的值都为null。一般的行为是由 CouchDB 生成一个 ID,并创建文档。
show方法都需要返回一个包含了 HTTP 响应信息的 JSON 对象。该 JSON 对象中可以包含表 3中给出的几个字段。表示 HTTP 响应内容的json、body和base64只需要设置一个即可。
表 3. show 方法返回的 JSON 对象
属性 | 说明 |
---|---|
code | 该属性表示 HTTP 响应的状态代码,默认是 200 。 |
headers | 该属性表示 HTTP 响应的头,是一个 JSON 对象,如{"Content-Type" : "application/xml"}。 |
json | 设置该属性表示把一个 JSON 对象发送给客户端。 |
body | 设置该属性表示把一个任意的字符串发送给客户端。 |
base64 | 设置该属性表示把 base64 编码的二进制数据发送给客户端。 |