- Get link
- X
- Other Apps
CouchDB is a NoSQL document store. This database is highly concurrent, can run stand alone and makes use of a REST API with JSON.
CouchDB needs only a HTTP client for CRUD (Create, Read, Update and Delete) operations. This makes working with CouchDB simple in most languages.
Lets setup our program and create an HTTP client in Pascal. We will need the ability to create and parse JSON. Default security policy is local connections on port 5984 or 'http://localhost:5984' the default server address.
Session endpoint : POST : http://localhost:5984/_session
Set CouchDB credentials in Environment Variables
JSON request body (Credentials)
New database endpoint : PUT : http://localhost:5984/fpctest
Named design document endpoint : PUT : http://localhost:5984/fpctest/_design/fpc
JSON request body (Design Document)
Insert document endpoint : POST : http://localhost:5984/fpctest
JSON request body (Article)
Query document endpoint : GET : http://localhost:5984/fpctest/_design/fpc/_view/article
Delete revision endpoint : DELETE : http://localhost:5984/fpctest/{docID}?rev={docRev}
Delete database endpoint : DELETE : http://localhost:5984/fpctest
CouchDB needs only a HTTP client for CRUD (Create, Read, Update and Delete) operations. This makes working with CouchDB simple in most languages.
Lets setup our program and create an HTTP client in Pascal. We will need the ability to create and parse JSON. Default security policy is local connections on port 5984 or 'http://localhost:5984' the default server address.
program CouchDB;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
Cthreads, Cmem,
{$ENDIF}
Classes, SysUtils, FPHTTPClient, OpenSSLSockets, FPJSON, JSONParser;
const
CouchDBAddress = 'http://localhost:5984/';
DatabaseName = 'fpctest';
DesignDocName = 'fpc';
ViewName = 'article';
var
SessionDoc, ViewDesignDoc, ArticleDoc, Rows, Items, Article, Rev: TJSONObject;
Values: TJSONArray;
DBResponse, JavaScriptMapFunction, Session, DocID: String;
Parser: TJSONParser;
I: Integer;
begin
with TFPHTTPClient.Create(nil) do
try
{ Session }
{ Create database }
{ Insert named design document }
{ Insert document }
{ Query document }
{ Delete document }
{ Delete database }
finally
{ Free }
Free;
end;
end.
{ Session }
Session endpoint : POST : http://localhost:5984/_session
Set CouchDB credentials in Environment Variables
#!/usr/bin/env bash
export CDBAdmin=""
export CDBPassword=""
JSON request body (Credentials)
{
"name" : "",
"password" : ""
}
SessionDoc := TJSONObject.Create;
SessionDoc.Add('name', GetEnvironmentVariable('CDBAdmin'));
SessionDoc.Add('password', GetEnvironmentVariable('CDBPassword'));
AddHeader('Content-Type', 'application/json; charset=UTF-8');
RequestBody := TStringStream.Create(SessionDoc.AsJSON);
Post(CouchDBAddress + '_session');
RequestBody.Free;
Session := Cookies.Values['AuthSession'];
{ Create database }
New database endpoint : PUT : http://localhost:5984/fpctest
Put(CouchDBAddress + DatabaseName);
{ Insert named design document }
Named design document endpoint : PUT : http://localhost:5984/fpctest/_design/fpc
JSON request body (Design Document)
{
"_id" : "_design/fpc",
"indexes" : {},
"lists" : {},
"views" : {
"article" : {
"map" : "function (doc) { if(doc.kind == \"article\") { emit(doc.kind, { \"headline\": doc.headline, \"body\": doc.body, \"published\": doc.published, \"author\": doc.author })}}"
}
},
"shows" : {},
"language" : "javascript"
}
JavaScriptMapFunction := 'function (doc) { '+
'if(doc.kind == "article") { '+
'emit(doc.kind, { '+
'"headline": doc.headline, '+
'"body": doc.body, '+
'"published": doc.published, '+
'"author": doc.author '+
'})'+
'}'+
'}';
ViewDesignDoc := TJSONObject.Create;
ViewDesignDoc.Add('_id', '_design/'+DesignDocName);
ViewDesignDoc.Add('indexes', TJSONObject.Create);
ViewDesignDoc.Add('lists', TJSONObject.Create);
ViewDesignDoc.Add('views', TJSONObject.Create(
[ViewName, TJSONObject.Create(
['map', JavaScriptMapFunction])]));
ViewDesignDoc.Add('shows', TJSONObject.Create);
ViewDesignDoc.Add('language', 'javascript');
RequestHeaders.Clear;
AddHeader('X-CouchDB-WWW-Authenticate', 'Cookie');
AddHeader('Cookie', 'AuthSession=' + Session);
AddHeader('Content-Type', 'application/json; charset=UTF-8');
RequestBody := TStringStream.Create(ViewDesignDoc.AsJSON);
Put(CouchDBAddress + DatabaseName + '/_design/'+DesignDocName);
RequestBody.Free;
{ Insert document }
Insert document endpoint : POST : http://localhost:5984/fpctest
JSON request body (Article)
{
"kind" : "article",
"headline" : "A Test Headline",
"body" : "This would be an article body.",
"published" : "4/20/2020",
"author" : "John Horst"
}
ArticleDoc := TJSONObject.Create;
ArticleDoc.Add('kind', 'article');
ArticleDoc.Add('headline', 'A Test Headline');
ArticleDoc.Add('body', 'This would be an article body.');
ArticleDoc.Add('published', 'article');
ArticleDoc.Add('author', 'John Horst');
RequestHeaders.Clear;
AddHeader('X-CouchDB-WWW-Authenticate', 'Cookie');
AddHeader('Cookie', 'AuthSession=' + Session);
AddHeader('Content-Type', 'application/json; charset=UTF-8');
RequestBody := TStringStream.Create(ArticleDoc.AsJSON);
Post(CouchDBAddress + DatabaseName);
RequestBody.Free;
{ Query document }
Query document endpoint : GET : http://localhost:5984/fpctest/_design/fpc/_view/article
DBResponse := Get(CouchDBAddress + DatabaseName + '/_design/'+ DesignDocName + '/_view/' + ViewName);
Parser := TJSONParser.Create(DBResponse);
Rows := Parser.Parse as TJSONObject;
Values := Rows.Arrays['rows'];
for I := 0 to Values.Count -1 do
begin
Items := Values.Objects[i];
Article := Items.Objects['value'];
WriteLn(Article.Strings['headline']);
WriteLn(Article.Strings['body']);
WriteLn(Article.Strings['published'] + ' by ' + Article.Strings['author']);
end;
RequestBody.Free;
{ Delete document }
Fetch document revision endpoint : GET : http://localhost:5984/fpctest/{docID}Delete revision endpoint : DELETE : http://localhost:5984/fpctest/{docID}?rev={docRev}
DBResponse := Get(CouchDBAddress + DatabaseName + '/' + DocID);
Parser := TJSONParser.Create(DBResponse);
Rev := Parser.Parse as TJSONObject;
RequestBody.Free;
Delete(CouchDBAddress + DatabaseName + '/' + DocID + '?rev=' + Rev.FindPath('_rev').AsString);
{ Delete database }
Delete database endpoint : DELETE : http://localhost:5984/fpctest
Delete(CouchDBAddress + DatabaseName);
Comments
Excellent work !!!😘
ReplyDeleteYou're beautiful ya know. I'm motivated on lockdown to publish and job hunt mamas. I have a ring to buy and you better wear it.
Delete