07 May 2009
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...
02 May 2009
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...
30 Apr 2009
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...
23 Apr 2009
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...
16 Apr 2009
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...