Code Generation in Perl
nferraz
created: 2004-06-16 16:30:30
Some time ago, I published an article about an open source Customer Relationship Management (CRM) application I was working on.

What I didn't tell you at the time, is that I was also working on a code generation tool which would allow me to generate a database-driven web application, just like this, in minutes.

The first version, called auto_coder, took an SQL script and generated all the required Perl scripts, modules and templates. The problem was that SQL isn't extensible: there's only so much information you can infer from a SQL script.

The solution was to use an extensible markup language -- XML for short :) -- to describe the database and all the required information.

This lead to a new version of my code generator, which I called "AppML" ("Application Markup Language").

Here's a small application described in AppML:


  
    
    
    
    
    
    
  

That's it!

Given the XML file, a Perl script will generate the complete Perl code, Class::DBI modules, templates (using Template Toolkit), documentation and diagrams automatically.

Of course, you can include as much details as needed. For instance, a project can have multiple tables and relationships:



  
    
  

I'm releasing AppML under the GNU General Public License, and the complete source code is available for download.

Any feedback will be appreciated!

Best wishes,

Nelson

--
Nelson Ferraz
GNU BIS

Re: Code Generation in Perl
created: 2004-06-16 17:01:40

In applm.pl, you say

$SIG{__WARN__} = sub { warn @_ unless $_[0] =~ /Use of uninitialized value/ };
Why not just this?
no warnings 'uninitialized';
Your program needs pod badly, there is no documentation.

After Compline,
Zaxo

Re^2: Code Generation in Perl
created: 2004-06-17 13:43:01
Yup, I must improve documentation and code style. I just wanted to release the code as soon as possible! ("Release soon, release often", they say)

Expect a revision in a few minutes.

Re: Code Generation in Perl
created: 2004-06-16 18:51:55

I like that idea, but I've never liked having to write XML by hand. What's the benefit over an API more like:

my $project = APPML::Project->new(
   name  => "sample",
   title => "Sample Application"
);

my $table = $project->add_table(
   name       => "contact",
   caption    => "contact",
   descriptor => "name"
);

my $vc40notnull = AppML::FieldType->new(
    type    => "varchar",
    size    => "40",
    notnull => "1",
);

$table->add_fields(
[
    name    => "name", 
    caption => "name",
    type    => $vc40notnull,
],
[
    # more fields here...
]
);

$project->create();

That's the sort of interface I'd create. Maybe it's appropriate to make that write out the XML for you, but I'd personally skip the step of writing out XML, reading it in, and translating it into internal data structures.

Re^2: Code Generation in Perl
created: 2004-06-17 13:16:08
The short answer is: I didn't want to be tied to Perl; AppML can generate code in any programming language. (Although Perl is the first one.)

Here's AppML output:

nferraz@debian:~/appml$ ./appml.pl xml/sample.xml

meta/db/create.tmpl -> sample/db/create.sql
meta/db/view.tmpl -> sample/db/view.sql
meta/db/stats.tmpl -> sample/db/stats.sql
meta/db/drop.tmpl -> sample/db/drop.sql

meta/pl/base.tmpl -> sample/lib/sample.pm
meta/pl/base_cdbi.tmpl -> sample/lib/sample/cdbi.pm
meta/pl/cdbi.tmpl -> sample/lib/sample/cdbi/contact.pm

meta/templates/header.tmpl -> sample/templates/inc/header.tt2
meta/templates/menu.tmpl -> sample/templates/inc/menu.tt2
meta/templates/stats.tmpl -> sample/templates/inc/stats.tt2
meta/templates/footer.tmpl -> sample/templates/inc/footer.tt2
meta/templates/frm.tmpl -> sample/templates/contact/frm_contact.tt2
meta/templates/detail.tmpl -> sample/templates/contact/detail_contact.tt2
meta/templates/list.tmpl -> sample/templates/contact/list_contact.tt2
meta/templates/tbl.tmpl -> sample/templates/contact/tbl_contact.tt2

meta/doc/install.tmpl -> sample/doc/INSTALL
meta/doc/plan.tmpl -> sample/doc/sample.html
meta/doc/dot.tmpl -> sample/doc/sample.dot

meta/data/strings.tmpl -> sample/data/sample.txt
As you can see, the source metafiles are divided in directories:
  • meta/db
  • meta/pl
  • meta/templates
  • meta/doc
  • meta/data
These metafiles are nothing more than text templates, used to generate code; if I wanted to generate Java code, I would probably create a new directory to store Java metafiles.
Re: Code Generation in Perl
created: 2004-06-16 20:40:07
I think that is pretty bitchin'.

All technical implementation critique's aside, it is at the very least extremely straight forward and useable for quick and dirty application.

Good job, and thanks for posting it.
Re^2: Code Generation in Perl
created: 2004-06-17 15:23:48
Thanks! I've successfully deployed some web applications using auto_coder and AppML. I'm sure it needs some tweaking, but I hope it will be useful to more people.
Re: Code Generation in Perl
created: 2004-06-17 23:19:32
Have you looked at Alzabo at all?
Re^2: Code Generation in Perl
created: 2004-06-18 09:19:33
If I understand it correctly, Alzabo is an "object-oriented wrapper"; applications created with Alzabo require Alzabo to be executed.

AppML is a code generator; you describe what you want, and AppML will generate thousands of lines of Perl, SQL, and templates, to meet your project description.

You can tweak the generated code, or, preferably, you can tweak the generator -- so the improvements will be applied to the next projects as well.

Futhermore, AppML can generate code in other languages, and can use other open source platforms and frameworks like Alzabo or Maypole.

Re: Code Generation in Perl
created: 2004-06-19 06:23:55

If you needed a little more info that the SQL already contained you could have added it in there, eg. in the form of some specialy formated comments. That way your users do not have to learn a whole new "language", just a few additional attributes. And if someone does have the SQL ready, he/she doesn't have to rewrite it into XML to be able to use your generator.

I would prefer

create table occupation /*#descriptor="description"*/ (
  description varchar(40) not null /*#caption="occupation"*/,
  comments text
)
to

    
  
anytime. But that's maybe because I would prefer anything to XML.

Jenda
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
   -- Rick Osborne

Re^2: Code Generation in Perl
created: 2004-06-19 09:19:49
Interestingly, that's exactly what I did in the first versions of auto_coder.

One of the problems with this approach is that we don't have an easy way to define broader project properties -- we're too focused on the database design.

Moreover, we must write different scripts for different databases; with XML we can write a single source and generate different scripts.

Another advantage of XML is the avaibility of modules like XML::Simple, which translates a XML source into a Perl data structure like this:

$VAR1 = {
          'table' => [
                     {
                       'descriptor' => 'name',
                       'caption' => 'contact',
                       'name' => 'contact',
                       'field' => [
                                  {
                                    'notnull' => '1',
                                    'caption' => 'first name',
                                    'name' => 'name',
                                    'type' => 'varchar',
                                    'size' => '40'
                                  },
                                  {
                                    'visible' => '1',
                                    'caption' => 'organization',
                                    'name' => 'organization',
                                    'type' => 'varchar',
                                    'size' => '40'
                                  },
                                  # ...and so on.

In other words, extending SQL with comments *was* my first approach, but it had its shortcomings.

perlmonks.org content © perlmonks.org and autarch, chromatic, Jenda, nferraz, perlfan, Zaxo

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03