Showing posts with label CouchDB. Show all posts
Showing posts with label CouchDB. Show all posts

Wednesday, January 29, 2014

How to count total attachments in a CouchDB database


You can watch the screencast here: How to count total attachments in a CouchDB database

And here's the source code for easy copy/paste:

Thursday, April 18, 2013

How to invoke update handler with Cradle?

Invoking an update handler via a Cradle nodejs client should be a simple task but I felt like I spent 10 minutes too many, piecing together documentation on it, since its not explicitly documented in the README.md file.

Based on the comments in the pull request where this functionality was added, here's a sample:

Wednesday, April 17, 2013

Wiring Vend POS with CouchDB - Part 2

Tuesday, March 19, 2013

Wiring Vend POS with CouchDB

Motivation:

  • Vend is a pretty awesome point-of-sale (POS) that resides in the cloud and has an even awesome~er developer API.
  • You can easily create and query views in CouchDB (common hosts: Cloudant and IrisCouch).

Steps:

  1. Get all the products from your Vend store and upload them to CouchDB.
    • Some standalone code be written to pull all the products and upload them. So many ways to do this, depending on what has the best utilities to cobble together something in a hurry: curl or Java or javascript (run via Node.JS) etc.
      • I'm partial to Node.JS because all of Vend's data is in JSON-format and there are some excellent libraries like Cradle which make it simpler to talk with CouchDB.
    • For the upload to CouchDB, it should be possible to leverage the bulk document API and finish it off in one shot.
  2. Going forward, keep everything up to date in real-time by utilizing Vend's webhooks to call into CouchDB's update handlers.
    • Create a design document in CouchDB with update handlers that can parse the payload delivered by a Vend webhook like a product update.
      • When writing an update handler for receiving a product update, I mimicked the Stripe Kanso project.
        • I didn't really write the upload script yet. I simply tried to point Vend's product webhook at the URL for my update handler and I was able to get a document populated in CouchDB.

        • For an actual product update (not just a new one), I haven't quite figured out the code, it fails right now. Just need to spend more time reading up on update handlers, I suppose.
          • Because the Vend API sends the update via a payload that is form urlencoded, I was left wondering where to look for the data and how to grab it inside CouchDB's update handler .. but those questions were easily tackled when I found documentation on handling form-style-submission of data with CouchDB.
          • I did send an email to the CouchDB mailing-list to ask for some advice on actual updates:
            1) I have a 3rd-party-webhook API calling into my update handler and there's nothing I can do to make it pass the document ID in the URL.
            2) That means the CouchDB server cannot provide the update function with the most recent version of that document.
            3) But the request does provide a payload from which I can pull out the document ID ... but by this time I'm inside the update handler function.
            4) So my question is: If CouchDB did not provide a doc, is there still a way for me to:
            a) either, fetch the latest version of the doc myself?
            b) or, override the existing document with another document formed with my request payload ... without running into a revision conflict?

            I know that I can probably route the request through a proxy that parses the payload, sets the document ID onto the request URL and sends it own its way ... but I'd rather leave that as a last resort.

            Thoughts?
          • One more challenge to keep in mind is authentication. If anyone figures out the URL endpoint for the CouchDB and the respective update handler, they could make false additions and updates.
            • It would be worth looking into any username/password BASIC authn provided by CouchDB to secure the update handler endpoint.
            • A quick fix would be to provide a unique token (?token=ABCDEF123) as part of the endpoint URL you specify for the webhook (product.update: https://couchdb.com/myDB/_design/doc/_update/productHandler?token=ABCDEF123) and since the query params are also encrypted in a request, your token would travel over a secure channel and then be validated on the CouchDB side to see if it matches what you expected.

Wednesday, February 22, 2012

CouchCocoa - An iOS client for working with CouchDB

CouchCocoa is a framework / library for iPhone use that abstracts out the work needed to talk to CouchDB instances running on the web or on the device itself. If you want to jump right into the setup for a simple project, then simply follow these steps:
  1. Add CouchCocoa as a submodule to your project:
    • cd ~/dev/myProject/
    • git submodule add git://github.com/couchbaselabs/CouchCocoa.git
  2. Get all the dependencies of this submodule itself:
    • cd ~/dev/myProject/CouchCocoa/
    • git submodule update --init --recursive
  3. Drag & drop CouchCocoa's .xcodeproj file under your own project in Xcode
  4. Add the following as your target's dependencies so that they will get built:
    • iOS Framework (CouchCocoa)
    • iOS Library (CouchCocoa)
  5. Add the following in "Link Binary With Libraries" for your target:
    • libCouchCocoa.a
  6. Add the following in "Header Search Paths" for your target:
    • "$(SRCROOT)/CouchCocoa/Model"
    • "$(SRCROOT)/CouchCocoa/REST"
    • "$(SRCROOT)/CouchCocoa/Couch"
    • "$(SRCROOT)/CouchCocoa/UI/iOS"
  7. In Xcode, select CouchCocoa.xcodeproj in the Project Navigator and edit the Target > Build Settings and set the Skip Install setting to Yes.
  8. If at a later point of time you realize that you want to work with TouchDB as well then you *may* need to update your CouchCocoa submodule and bring it up to speed:
    • cd ~/dev/myProject/CouchCocoa/
    • git checkout touchdb
    • git pull origin touchdb
If you have any problems, post your questions on the google group for mobile couchbase.

Aside from the process there are some "big picture" points to consider:
  • CouchCocoa can talk directly to CouchDB (or CouchBase - a more performant variant). For example, if you use the hosting services provided by IrisCouch, you can configure CouchCocoa to work directly with that Couch server.
  • CouchCocoa can work with an embedded version of CouchDB on mobile devices.
    • TouchDB is one such implementation which is lightweight and exists for iOS and Android mobile devices.
      • For iOS however, I do find it a bit confusing when I think about how to structure my project, there are two ways to do it:
        • Build and soft-link the TouchDB framework. And use CouchCocoa as a submodule as outlined earlier in the blog.
          • If you choose to use TouchDB-iOS as a submodule as well then don't forget that TouchDB's itself also needs a soft-link to CouchCocoa.framework:
            cd ~/dev/superProject
            ln -s ./DerivedData/superProject/Build/Products/Debug-ios-universal/CouchCocoa.framework ./TouchDB-iOS/Demo-iOS/Frameworks/CouchCocoa.framework
        • Syncpoint-iOS which bundles TouchDB and CouchCocoa together but lags behind the individual projects in terms of stability and features. To experiment with it, you can follow a this discussion thread where it was introduced to the community.
      • Another huge pain-point is the fact that for all of GitHub's glory it doesn't let me search for content in wiki pages so when it comes time to try out the infamous Grocery-Sync example, I'm left wondering where to look! This relative path should shed some light I hope: TouchDB-iOS/Demo-iOS/DemoAppDelegate.m
    • Couchbase Mobile is another implementation. Recently it has seen some serious progress in terms of tutorials (one & two) and example-code covering its usage.

Wednesday, November 2, 2011

How to build a webapp with CouchApp and CouchDB

This is a chronicle of the additional work I had to do as I followed Ed Parcell's Tutorial: Using jQuery and CouchDB to build a simple AJAX web application. It is supposed to serve as a supplement.

Ed's post covers the use of CouchApp as far as generating templates to work on is concerned. As a supplement, my post will leverage the Evently framework (already a part of the generated CouchApp 0.8.1) to do the same exact thing.
  1. When asked to edit index.html for the first time in Ed's post, here is how the content will differ if you want to do things the Evently way:
    <!DOCTYPE html>
      <html>
    
      <head>
        <title>Address Book</title>
        <link rel="stylesheet" href="style/main.css" type="text/css">
      </head>
    
      <body>
        <h1>Address Book</h1>
        <div id="add"><button type="button" id="add">Add</button></div>
        <div id="addressbook"></div>
      </body>
    
      <script src="vendor/couchapp/loader.js"></script>
    
      <script type="text/javascript" charset="utf-8">
        $.couch.app(function(app) {
          $("#addressbook").evently("addressbook", app);
        });
      </script>
    </html>
    
  2. Lets take a moment to acknowledge all the differences:
    1. Links to json2.js, jquery.js or jquery.couch.js are not present in the head section. This is now taken care of by loader.js (view source +/-), which loads all of the required javascript files.
    2. An additional script section:
      $.couch.app(function(app) {
            $("#addressbook").evently("addressbook", app);
          });
      
      is used to wire-up the addressbook div element with an evently widget (also named addressbook but the names don't really have to match, its not a requirement) which we will be writing later in this tutorial.
  3. The Evently approach also mandates a rewrite of Ed's refreshAddressbook function such that the html and javascript are placed in separate files and tied together via the use of the Mustache template engine. So instead of injecting any more javascript into your index.html, follow these steps:
    1. Navigate to the addressbook directory, which was generated by couchapp for you when you ran, in the past:
      couchapp generate app addressbook
      cd addressbook
      
    2. Create an evently widget named addressbook by simply creating the appropriate directory structure:
      mkdir -p evently/addressbook/
      
    3. Create _query.js file to hold the view which should be loaded from CouchDB when the addressbook div element is hooked-up with the addressbook widget (refer to line # 19 in index.html source provided earlier):
      function () {
        $.log('Inside evently/addressbook/_init/query.js');
      
        return {
          "view" : "phonenumbers",
        };
      }
    4. Create data.js file to process the data returned by CouchDB which will be available for the Mustache template engine's use:
      function(data) {
        $.log('Inside evently/addressbook/_init/data.js');
        $.log(data.rows);
        return {
          "addressbook" : data.rows
        };
      }
    5. Create mustache.html file to substitute the data and render the html directly into the addressbook div element:
      {{#addressbook}}
      <div class="address">
        <span class="name">{{key}}</span>
        <span class="phonenumber">{{value}}</span>
        <a href="#edit" class="edit">edit</a>
        <a href="#delete" class="delete">delete</a>
      </div>
      {{/addressbook}}
      
    6. Uplaod the app:
      couchapp push
    7. Before we go any further let's test what we've written so far. You'll notice that I've thrown in logs and alerts into the javascript above. If all is well then we should see an alert pop up with the data being retrieved from the server. Also if you have debugging tools like Firebug or Web Inspector at your disposal, then you should be able to see the data printed out in the console.
      1. Safari and Firefox on my mac work well and I hope that you too see a popup stating [object Object] and your console output looks something like:
        Entering view callback in evently/addressbook/_init.js
        jquery...util.js (line 3)
        Object { total_rows=2, offset=0, rows=[2]}
        jquery...util.js (line 3)
        Exiting view callback in evently/addressbook/_init.js
        
      2. B U T ... if you head over to your iPhone's safari browser and try the same thing, you may be in for a huge disappointment! Nothing will happen. And if you enable the Debug Console, you'll see javascript errors stating that jQuery does not exist!
        • If you run into this then based on the wisdom gleaned from this post on stackoverflow, here's what you need to do:
          1. Get all the supporting JS files listed under the _utils URL to be directly present in your own addressbook couchapp:
            cd vendor/couchapp/_attachments/
            wget http://fermyon.iriscouch.com/_utils/script/jquery.couch.js
            wget http://fermyon.iriscouch.com/_utils/script/sha1.js
            wget http://fermyon.iriscouch.com/_utils/script/json2.js
            wget http://fermyon.iriscouch.com/_utils/script/jquery.js
            
          2. Update loader.js to serve the files out of your own addressbook couchapp:
            vi vendor/couchapp/_attachments/loader.js
            
            ...
            couchapp_load([
              "vendor/couchapp/sha1.js",
              "vendor/couchapp/json2.js",
              "vendor/couchapp/jquery.js",
              "vendor/couchapp/jquery.couch.js",
              "vendor/couchapp/jquery.couch.app.js",
              "vendor/couchapp/jquery.couch.app.util.js",
              "vendor/couchapp/jquery.mustache.js",
              "vendor/couchapp/jquery.evently.js"
            ]);
            
        • If things are still breaking then there is one other analysis & workaround for this dilemma presented here in a blog post by Lee Boonstra.
        • If you are still having issues then use the Safari on your Mac's iOS Simulator to browse the couchapp because it gives more detailed information in its Debug Console than the actual browser on the iPhone. If you are still seeing something like the following image:
          Then you still haven't fixed the problem as described in the steps above so go back and make sure you follow all the instructions to get it resolved.
    8. Now lets finish off editing _init.js:
      put code here...
      
  4. mustache stuff

Sunday, October 9, 2011

Scalability Madness

CouchDB CouchDB-Lucene CouchIO / CouchOne / CouchBase Solr Elastic Search MongoDB BigCouch
Full-Text SearchNoYes?YesYesMay Be with Photovoltaic?
Distribute-ableYes??YesYes??
Distribute-ed???NoYes??
Schema-lessYes???Yes??
Tools for Importing Data???Yes???
Comments?Does it go Toe to Toe against all the features of Lucene exposed by Solr? best for HTML5 dev? it is distributable but not distributed. SolrCloud has very few features Compass got punted to invent Elastic Search.??