Strict Development

While working on my new open source project, CouchQL, I’m being very strict with my development process and following both issue driven development, and test driven development.

Issue driven development requires that every commit refers to an issue that has been logged in the bug tracking software. This means that every change must be described, accepted and then logged. This works better if your repository is connected to your bug tracking software such that any commit message with a issue number is automatically logged. In subversion this can be achieved with a post commit hook, such as this script for trac.

The connection between your commit messages and bug tracking software means that when changes are merged between branches new messages will be added to the issue, informing everyone what version of the software the issue has been fixed in. As well as just adding comments to issues it is also possible to mark bugs as fixed with commit messages such as “Fixes issue #43.” which should speed up your work flow. While Google Code does add hyperlinks between commit messages and issues, it doesn’t add automatically add comments, which is a pain.

Enforcing a development practice like this requires you to think about the changes you are making to your software, and focuses your mind one a particular goal. Bug tracking software will have the ability to assign priorities to changes as well to group them into milestones. This helps you to build up a feature list for each version of the software, and to know when you’ve achieved your goals and it’s time to release!

Read More...

CouchQL 0.1 released

I’ve just uploaded the first release of CouchQL. It can be installed from PyPI by typing “easy_install couchql” or you can download a tarball from Google Code.

It’s a very early release, but please play with it, break it and email me your results!

Read More...

CouchQL development progressing

As I mentioned in a previous post I have been working of a library to ease the creation of map/reduce views in CouchDB.

The code is being hosted on google code and can be checked out and used now. The development is currently at a very early stage, but the fundamentals are sound.

Code such that given below will work. In this example it will return all the documents with a member ‘x’ whoes value is greater than one.

Read More...

Building Better Web Services With Django (Part 2)

In the first part I talked about using the Content-Type and Accept HTTP headers to allow a single website to be use both by humans and programs.n In the previous part I gave a decorator which can be used to make working with JSON very easy. For our use though this isn’t great because a view decorated in this way only accepts JSON as the POST body and only returns JSON, regardless of the HTTP headers.

The decorator given below relies on a django snippet to decode the Accept header for us so don’t forget to added it to your middleware.

def content_type(func, common=None, json_in=None, json_out=None, form_in=None):
    def wrapper(req, *args, **kwargs):
        # run the common function, if we have one
        if common is not None:
            args, kwargs = common(req, *args, *kwargs), {}
            if isinstance(args, HttpResponse): return args
        content_type = req.META.get("content_type", "")
        if content_type == "application/json":
            args, kwargs = json_in(req, json.loads(req.raw_post_data), *args, *kwargs), {}
        elif content_type == "application/x-www-form-urlencoded":
            args, kwargs = json_in(req, req.POST, *args, *kwargs), {}
        else:
            return HttpResponse(status=415, "Unsupported Media Type")

        if isinstance(args, HttpResponse): return args

        for (media_type, q_value) in req.accepted_types:
            if media_type == "text/html":
                return func(req, args, kwargs)
            else:
                r = json_out(req, args, kwargs)
                if isinstance(r, HttpResponse):
                    return r
                else:
                    return HttpResponse(json.dumps(r), mimetype="application/json")
         return func(req, args, kwargs)
    return wrapper
Read More...

Introducing CouchQL

CouchDB is a very exciting development in the world of databases and I’m greatly enjoying building a website which uses it. One problem is that most of the of views that I have created are extremely simple and could easily be represented using SQL. Although I wrote some code to help make life easier, creating a view such as that below is never going to be as simple as including SELECT * FROM table WHERE (status="open" OR status="accepted") AND latest AND key="xyz" directly in your code.

function (doc) {
    if((doc["status"] == "open" || doc["status"] == "accepted") && doc["latest"]) {
        emit(doc["key"], null);
    }
}

The SQL above and the Javascript view function are directly equivalent, which is why I’ve started working on an extension to the Python CouchDB library, which I’ve decided to call CouchQL.

Read More...