A simple CouchDB client for Duso supporting basic CRUD operations and Mango queries. No authentication yet.
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)
http://localhost:5984brew services start couchdb or docker run -d -p 5984:5984 couchdbcouchdb.connect(url, db_name)Create a connection object to a database.
Arguments:
url (string, optional): CouchDB server URL. Defaults to "http://localhost:5984"db_name (string, required): Database nameReturns: 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:
url (string, optional): CouchDB server URLdb_name (string, required): Name for new databaseReturns: Connection object
Example:
db = couchdb.create_database("http://localhost:5984", "new_db")
couchdb.list_databases(url)List all databases on the server.
Arguments:
url (string, optional): CouchDB server URLReturns: 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:
url (string, optional): CouchDB server URLReturns: Server info object
Example:
info = couchdb.server_info("http://localhost:5984")
print(info.couchdb) // "Welcome"
Once you have a connection object, use these methods:
db.get(doc_id)Retrieve a single document by ID.
Arguments:
doc_id (string): Document IDReturns: 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:
doc (object): Document with required _id field. Include _rev if updating existing document.Returns: Result object with new _rev
Note: CouchDB uses optimistic locking. To update, you must:
_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:
doc_id (string): Document IDrev (string): Current revision (from _rev field)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:
selector (object): Mango query selectoroptions (object, optional):
sort (array): Sort fields. Example: [{field = "asc"}]limit (number): Max documents to returnskip (number): Number of documents to skipfields (array): Only return these fieldsReturns: 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:
fields (array): Array of field objects to index. Example: [{age = "asc"}]index_name (string, optional): Index name. Defaults to "auto"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:
docs (array): Array of document objects (each must have _id)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()
All operations throw errors on failure:
try
db.put({_id = "doc1", name = "Alice"})
catch (e)
print("Error: " + e)
end
Common errors:
404 not_found: Document or database doesn't exist409 conflict: Document revision mismatch (use fresh _rev)400 bad_request: Invalid query or bad selector syntaxSee examples/basic.du for a complete working example.
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
// 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
Run the example:
duso contrib/couchdb/examples/basic.du
Requires CouchDB running locally on port 5984.