At work I was asked to write a Class::DBI interface to a database. I've already written one for the database used by my first project, and this new assignment would be rather boring if I had to do it again. I like Class::DBI, but setting it up is ugly grunt work. So I wrote a program to write my abstraction for me. It is currently MySQL specific (but that doesn't bother me right now, except that I'd like it to work with Postgres and SQLite).
It has some neat features. It builds a top level package that contains the entire abstraction for all of the tables in your database. Then it also builds packages for each of the classes (tables) so business logic (custom code) can be put there. That way, when the database changes the abstraction can be updated and the custom code can be left alone. The abstraction figures out what the primary key is, and tries several heuristics if a primary key isn't specified, to come up with a suitable key (or keys). It also tries to figure out has_a relationships between the tables using several heuristics. Any date related fields are setup with has_a relationships to Time::Piece. Documentation is also built detailing each column in each class, as well as usage instructions for the package (the entire abstraction) as a whole.
Perhaps I can clean this up and let other folks play with it. I'll have to see what the folks here at pair think of that, and I doubt it will be a problem.
Some interesting numbers; I wrote 365 lines of code in the program and a medium sized database generated 3550 lines of code, comments, and documentation for me. I can think of at least 35 databases I want to run the generator on. If I did, and I used my first database as an average, I'd get 124250 lines of code I never had to write. I like that.