From: Ken Youens-Clark Date: Wed, 31 Mar 2004 21:37:45 +0000 (+0000) Subject: Added examples of plugging in custom parsers and producers. X-Git-Tag: v0.06~100 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=30bda799e8049cf0f36487c321cd168c13b5ade2;p=dbsrgits%2FSQL-Translator.git Added examples of plugging in custom parsers and producers. --- diff --git a/lib/SQL/Translator/Manual.pod b/lib/SQL/Translator/Manual.pod index ae4936e..623e72f 100644 --- a/lib/SQL/Translator/Manual.pod +++ b/lib/SQL/Translator/Manual.pod @@ -200,9 +200,10 @@ diagrams: The first visualization tool in SQLFairy, this producer uses libgd to draw a picture of the schema. The tables are evenly distributed in definition order running in columns (i.e., no graphing algorithms are -used), so the end result may result in many crossed lines showing the -foreign key relationships. Please read the documentation of the -"sqlt-diagram" script for all the options available to this producer. +used), so the many of the lines showing the foreign key relationships +may cross over each other and the table boxes. Please read the +documentation of the "sqlt-diagram" script for all the options +available to this producer. =item * GraphViz @@ -345,6 +346,125 @@ provides a simple interface to all the SQLFairy parsers and producers. Now that you have seen how the parsers and producers interact via the Schema objects, you may wish to create your own versions to plugin. +Producers are probably the easier concept to grok, so let's cover that +first. By far the easiest way to create custom output is to use the +TTSchema producer in conjunction with a Template Toolkit template as +described earlier. However, you can also easily pass a reference to a +subroutine that SQL::Translator can call for the production of the +ouput. This subroutine will be passed a single argument of the +SQL::Translator object which you can use to access the Schema objects. +Please read the POD for SQL::Translator and SQL::Translator::Schema to +learn the methods you can call. Here is a very simple example: + + #!/usr/bin/perl + + use SQL::Translator; + + my $input = q[ + create table foo ( + foo_id int not null default '0' primary key, + foo_name varchar(30) not null default '' + ); + + create table bar ( + bar_id int not null default '0' primary key, + bar_value varchar(100) not null default '' + ); + ]; + + my $t = SQL::Translator->new; + $t->parser('MySQL') or die $t->error; + $t->producer( \&produce ) or die $t->error; + my $output = $t->translate( \$input ) or die $t->error; + print $output; + + sub produce { + my $tr = shift; + my $schema = $tr->schema; + my $output = ''; + for my $t ( $schema->get_tables ) { + $output .= join('', "Table = ", $t->name, "\n"); + } + return $output; + } + +Executing this script produces the following: + + $ ./my-producer.pl + Table = foo + Table = bar + +A custom parser will be passed two arguments: the SQL::Translator +object and the data to be parsed. In this example, the schema will be +represented in a simple text format. Each line is a table definition +where the fields are separated by colons. The first field is the +table name and the following fields are column definitions where the +column name, data type and size are separated by spaces. The +specifics of the example are unimportant -- what is being demonstrated +is that you have to decide how to parse the incoming data and then +map the concepts in the data to the Schema object. + + #!/usr/bin/perl + + use strict; + use SQL::Translator; + + my $input = + "foo:foo_id int 11:foo_name varchar 30\n" . + "bar:bar_id int 11:bar_value varchar 30" + ; + + my $t = SQL::Translator->new; + $t->parser( \&parser ) or die $t->error; + $t->producer('Oracle') or die $t->error; + my $output = $t->translate( \$input ) or die $t->error; + print $output; + + sub parser { + my ( $tr, $data ) = @_; + my $schema = $tr->schema; + + for my $line ( split( /\n/, $data ) ) { + my ( $table_name, @fields ) = split( /:/, $line ); + my $table = $schema->add_table( name => $table_name ) + or die $schema->error; + for ( @fields ) { + my ( $f_name, $type, $size ) = split; + $table->add_field( + name => $f_name, + data_type => $type, + size => $size, + ) or die $table->error; + } + } + + return 1; + } + +And here is the output produced by this script: + + -- + -- Created by SQL::Translator::Producer::Oracle + -- Created on Wed Mar 31 15:43:30 2004 + -- + -- + -- Table: foo + -- + + CREATE TABLE foo ( + foo_id number(11), + foo_name varchar2(30) + ); + + -- + -- Table: bar + -- + + CREATE TABLE bar ( + bar_id number(11), + bar_value varchar2(30) + ); + =head1 AUTHOR Ken Y. Clark Ekclark@cpan.orgE.