CouchDB Module for Duso

A simple CouchDB client for Duso supporting basic CRUD operations and Mango queries. No authentication yet.

Quick Start

couchdb = require("couchdb")

// Connect to database
db = couchdb.connect("http://localhost:5984", "duso")

// Create a document
db.put({_id = "doc1", name = "Alice", age = 30})

// Read it back
doc = db.get("doc1")
print(doc)

// Query with Mango
results = db.query({age = {$gt = 25}})
print(results)

Prerequisites

API

Top-Level Functions

couchdb.connect(url, db_name)

Create a connection object to a database.

Arguments:

Returns: Connection object with CRUD methods

Example:

db = couchdb.connect("http://localhost:5984", "my_db")

couchdb.create_database(url, db_name)

Create a new database and return a connection to it.

Arguments:

Returns: Connection object

Example:

db = couchdb.create_database("http://localhost:5984", "new_db")

couchdb.list_databases(url)

List all databases on the server.

Arguments:

Returns: Array of database names

Example:

dbs = couchdb.list_databases("http://localhost:5984")
print(dbs)  // ["_replicator", "_users", "my_db", ...]

couchdb.server_info(url)

Get server information.

Arguments:

Returns: Server info object

Example:

info = couchdb.server_info("http://localhost:5984")
print(info.couchdb)  // "Welcome"

Connection Methods

Once you have a connection object, use these methods:

db.get(doc_id)

Retrieve a single document by ID.

Arguments:

Returns: Document object with _id and _rev fields

Throws: Error if document not found

Example:

doc = db.get("user_001")
print(doc.name)

db.put(doc)

Create or update a document.

Arguments:

Returns: Result object with new _rev

Note: CouchDB uses optimistic locking. To update, you must:

  1. Get the document
  2. Modify it
  3. Put it back (it includes _rev from the get)

Example:

// Create new
db.put({_id = "user_001", name = "Alice", age = 30})

// Update existing
doc = db.get("user_001")
doc.age = 31
db.put(doc)  // Includes _rev from get

db.delete(doc_id, rev)

Delete a document.

Arguments:

Returns: Result object

Note: You must get the document first to obtain its _rev:

Example:

doc = db.get("user_001")
db.delete("user_001", doc._rev)

db.query(selector, options)

Query documents using Mango selector language.

Arguments:

Returns: Array of matching documents

Mango Selector Syntax:

// Simple equality
{name = "Alice"}

// Comparison operators (use quoted keys for $ operators)
{age = {"$gt" = 30}}        // greater than
{age = {"$gte" = 30}}       // greater than or equal
{age = {"$lt" = 30}}        // less than
{age = {"$lte" = 30}}       // less than or equal
{age = {"$eq" = 30}}        // equal
{age = {"$ne" = 30}}        // not equal

// Array operators
{tags = {"$in" = ["red", "blue"]}}     // any value in array
{tags = {"$nin" = ["red"]}}            // none of values
{tags = {"$all" = ["red", "blue"]}}    // all values present

// Logical operators
{"$and" = [{name = "Alice"}, {age = {"$gt" = 25}}]}
{"$or" = [{name = "Alice"}, {name = "Bob"}]}
{"$nor" = [{status = "deleted"}]}
{"$not" = {status = "inactive"}}

// Complex queries
{
  "$and" = [
    {age = {"$gte" = 25}},
    {age = {"$lt" = 65}},
    {status = "active"}
  ]
}

Example:

// Find users over 30
results = db.query({age = {"$gt" = 30}})

// With sorting and limit
results = db.query(
  {age = {"$gt" = 30}},
  {sort = [{age = "desc"}], limit = 10}
)

// Only specific fields
results = db.query(
  {status = "active"},
  {fields = ["name", "email"]}
)

db.create_index(fields, index_name)

Create an index to speed up queries.

Arguments:

Returns: Index creation result

Note: For best query performance, create indexes on fields you frequently query.

Example:

// Create index on age field
db.create_index([{age = "asc"}])

// Compound index on multiple fields
db.create_index([{status = "asc"}, {created = "asc"}])

db.bulk(docs)

Insert or update multiple documents at once.

Arguments:

Returns: Array of results (one per document)

Example:

docs = [
  {_id = "doc1", name = "Alice"},
  {_id = "doc2", name = "Bob"},
  {_id = "doc3", name = "Charlie"}
]
results = db.bulk(docs)

db.info()

Get database statistics and information.

Returns: Info object with document count, data size, etc.

Example:

info = db.info()
print(info.doc_count)      // Number of documents
print(info.data_size)      // Size in bytes

db.delete_db()

Delete the entire database.

Warning: This is destructive and irreversible.

Returns: Deletion result

Example:

db.delete_db()

Error Handling

All operations throw errors on failure:

try
  db.put({_id = "doc1", name = "Alice"})
catch (e)
  print("Error: " + e)
end

Common errors:

Examples

See examples/basic.du for a complete working example.

Session Pattern (Multiple Operations)

couchdb = require("couchdb")
db = couchdb.connect("http://localhost:5984", "app_db")

// Create some documents
for i = 1, 5 do
  db.put({
    _id = "user_" + i,
    name = "User " + i,
    created = now()
  })
end

// Query them
users = db.query({}, {limit = 10})
for user in users do
  print(user.name)
end

Updating Workflow

// Get current state
doc = db.get("doc_id")

// Modify
doc.field = "new value"
doc.updated_at = now()

// Save back (includes _rev from get)
result = db.put(doc)

// If conflict, fetch fresh and retry
if result.error == "conflict" then
  doc = db.get("doc_id")  // Get latest
  doc.field = "new value"  // Reapply changes
  db.put(doc)
end

Limitations & Future Work

Testing

Run the example:

duso contrib/couchdb/examples/basic.du

Requires CouchDB running locally on port 5984.