The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Decl::Semantics::Database - implements a database handle.

VERSION

Version 0.01

SYNOPSIS

62% of all Perl code deals with databases. (I just made that up.) This is because DBI is a work of beauty. But seriously, every time I go to use DBI I have to cut and paste from existing code, because I just can't remember all the handles. This module is a first stab at presenting databases the way I see them in my mind.

So. There are two ways to hit databases, essentially. The first is the query: given a database out there somewhere, I want to extract data from it. The data is going to be delivered in an iterator, and in 90% of cases I'm just going to loop over the rows returned and do something really simple with it.

I abstract that out like this (and forgive the Windows/Microsoftiness of it; that's just what I'm doing today):

   database (msaccess) "mydatabase.mdb"
      query need_invoicing "SELECT [jobs to invoice].customer as customer, Sum([jobs to invoice].value) AS total_value FROM [jobs to invoice] GROUP BY [jobs to invoice].customer ORDER BY [jobs to invoice].customer"
   
   do {
      ^foreach need_invoicing {
         print "$customer\t$total_value\n";
      }
   }
   

Alternatively, if you don't like the long line there (neither do I), I could have specified the query as:

   database (msaccess) "mydatabase.mdb"
      query need_invoicing
         select "[jobs to invoice].customer as customer, Sum([jobs to invoice].value) AS total_value"
         from   "jobs to invoice"
         group  "customer"
         order  "total_value desc"

This sets up all the handles for me and even builds the loop code, and I don't have the chance to screw it up. Mission accomplished.

More generally, I can set up a query that can take (optional) parameters, and at some point I can also do discovery of the existing database upon connection. And of course I can also set up non-query queries like insert, update, and delete SQL, add tables, and so on, but I'm really not worried about that right at the moment; I just want to be able to grab data from a database.

The second major case for database interaction is object storage. The way I see this is equally simple: I add an object, and get a key. Given the key, I can then retrieve, update, or delete the object at a later date. Objects are going to end up being nodes (duh), and yes, you read this correctly that this model will cover NoSQL databases just fine.

DRIVERS

There is just no way around a driver system for databases. We're lucky to have DBI and its driver system for most work, but sometimes there will be a database that we'll want to do a little more with (MS Access being a case in point).

If this is the case, that driver can be a separate module Decl::Semantics::Database::<driver>. This uses the Perl module system to provide as much flexibility in system configuration as possible without being too nasty.

Right now, I'm going to special-case some stuff for Access and CSV because I need those and don't want to mess with the directory structure today.

SPECIAL SUBTAGS

The only meaningful child right now is "query", which will macro-insert a data tag (i.e. an iterator) as a sibling of the database. When the database node is built, it thus creates a data source for each query defined that can be referred to in code downstream of the database.

I can imagine other subtags later, perhaps "table" for database management, and certainly something for the NoSQL-like model, whatever that turns out to look like. But those will come when the need arises.

FUNCTIONS DEFINED

defines(), tags_defined()

build_payload

We connect to the database for our payload. The payload itself will be our dbi handle (the one normally called $dbh).

DATABASE-SPECIFIC FUNCTIONS

dbh

An alias to the payload (the database handle) if you want to use conventional DBI techniques:

   my $dbh = ^('database')->dbh;
   $dbh->tables or whatever
   

dbtype

Returns the type of database.

table_info

Returns information about the given table. How the table is specified depends on the database type - if the database driver has multiple sets of tables, the "main" one will be used. If you need the actual DBI table_info functionality, get a handle with dbh first.

AUTHOR

Michael Roberts, <michael at vivtek.com>

BUGS

Please report any bugs or feature requests to bug-decl at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Decl. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

LICENSE AND COPYRIGHT

Copyright 2010 Michael Roberts.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.