X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSQL%2FTranslator%2FParser%2FXML%2FSQLFairy.pm;h=3e2d68a5188b1fe0d82c1b41eb172c2cd5dbf03b;hb=6196ab86ac3e135811917ee5bb43f8afbca2d545;hp=bf30f219fa40964804c82f238ae588b45c0f5297;hpb=8571d1980c9ac71cf8f530cbaba1280c2d90b296;p=dbsrgits%2FSQL-Translator.git diff --git a/lib/SQL/Translator/Parser/XML/SQLFairy.pm b/lib/SQL/Translator/Parser/XML/SQLFairy.pm index bf30f21..3e2d68a 100644 --- a/lib/SQL/Translator/Parser/XML/SQLFairy.pm +++ b/lib/SQL/Translator/Parser/XML/SQLFairy.pm @@ -1,8 +1,6 @@ package SQL::Translator::Parser::XML::SQLFairy; # ------------------------------------------------------------------- -# $Id: SQLFairy.pm,v 1.6 2004-07-08 19:06:24 grommit Exp $ -# ------------------------------------------------------------------- # Copyright (C) 2003 Mark Addison , # # This program is free software; you can redistribute it and/or @@ -27,22 +25,21 @@ SQL::Translator::Parser::XML::SQLFairy - parser for SQL::Translator's XML. =head1 SYNOPSIS use SQL::Translator; - use SQL::Translator::Parser::XML::SQLFairy; - my $translator = SQL::Translator->new( - from => 'XML-SQLFairy', - to => 'MySQL', - filename => 'schema.xml', - show_warnings => 1, - add_drop_table => 1, - ); + my $translator = SQL::Translator->new( show_warnings => 1 ); + + my $out = $obj->translate( + from => 'XML-SQLFairy', + to => 'MySQL', + filename => 'schema.xml', + ) or die $translator->error; - print $obj->translate; + print $out; =head1 DESCRIPTION This parser handles the flavor of XML used natively by the SQLFairy -project (SQL::Translator). The XML must be in the namespace +project (L). The XML must be in the namespace "http://sqlfairy.sourceforge.net/sqlfairy.xml." See L for details of this format. @@ -64,20 +61,36 @@ tags then the order the tags appear in the XML will be used. =head2 default_value -Leave the tag out all together to use the default in Schema::Field. -Use empty tags or 'EMPTY_STRING' for a zero lenth string. 'NULL' for an +Leave the attribute out all together to use the default in L. +Use empty quotes or 'EMPTY_STRING' for a zero lenth string. 'NULL' for an explicit null (currently sets default_value to undef in the Schema::Field obj). - - EMPTY_STRING - - NULL + + + =head2 ARGS Doesn't take any extra parser args at the moment. +=head1 LEGACY FORMAT + +The previous version of the SQLFairy XML allowed the attributes of the the +schema objects to be written as either xml attributes or as data elements, in +any combination. While this allows for lots of flexibility in writing the XML +the result is a great many possible XML formats, not so good for DTD writing, +XPathing etc! So we have moved to a fixed version described in +L. + +This version of the parser will still parse the old formats and emmit warnings +when it sees them being used but they should be considered B. + +To convert your old format files simply pass them through the translator :) + + $ sqlt -f XML-SQLFairy -t XML-SQLFairy schema-old.xml > schema-new.xml + =cut # ------------------------------------------------------------------- @@ -85,10 +98,11 @@ Doesn't take any extra parser args at the moment. use strict; use vars qw[ $DEBUG $VERSION @EXPORT_OK ]; -$VERSION = sprintf "%d.%02d", q$Revision: 1.6 $ =~ /(\d+)\.(\d+)/; +$VERSION = '1.59'; $DEBUG = 0 unless defined $DEBUG; use Data::Dumper; +use Carp::Clan qw/^SQL::Translator/; use Exporter; use base qw(Exporter); @EXPORT_OK = qw(parse); @@ -109,18 +123,20 @@ sub parse { # # Work our way through the tables # - my @nodes = $xp->findnodes('/sqlf:schema/sqlf:table'); + my @nodes = $xp->findnodes( + '/sqlf:schema/sqlf:table|/sqlf:schema/sqlf:tables/sqlf:table' + ); for my $tblnode ( sort { - "".$xp->findvalue('sqlf:order|@order',$a) + ("".$xp->findvalue('sqlf:order|@order',$a) || 0) <=> - "".$xp->findvalue('sqlf:order|@order',$b) + ("".$xp->findvalue('sqlf:order|@order',$b) || 0) } @nodes ) { debug "Adding table:".$xp->findvalue('sqlf:name',$tblnode); my $table = $schema->add_table( - get_tagfields($xp, $tblnode, "sqlf:" => qw/name order/) + get_tagfields($xp, $tblnode, "sqlf:" => qw/name order extra/) ) or die $schema->error; # @@ -135,7 +151,7 @@ sub parse { } @nodes ) { my %fdata = get_tagfields($xp, $_, "sqlf:", - qw/name data_type size default_value is_nullable + qw/name data_type size default_value is_nullable extra is_auto_increment is_primary_key is_foreign_key comments/ ); @@ -159,7 +175,6 @@ sub parse { # TODO: # - We should be able to make the table obj spot this when # we use add_field. - # - Deal with $field->extra # } @@ -170,7 +185,7 @@ sub parse { foreach (@nodes) { my %data = get_tagfields($xp, $_, "sqlf:", qw/name type table fields reference_fields reference_table - match_type on_delete_do on_update_do/ + match_type on_delete on_update extra/ ); $table->add_constraint( %data ) or die $table->error; } @@ -181,19 +196,31 @@ sub parse { @nodes = $xp->findnodes('sqlf:indices/sqlf:index',$tblnode); foreach (@nodes) { my %data = get_tagfields($xp, $_, "sqlf:", - qw/name type fields options/); + qw/name type fields options extra/); $table->add_index( %data ) or die $table->error; } + + # + # Comments + # + @nodes = $xp->findnodes('sqlf:comments/sqlf:comment',$tblnode); + foreach (@nodes) { + my $data = $_->string_value; + $table->comments( $data ); + } + } # tables loop # # Views # - @nodes = $xp->findnodes('/sqlf:schema/sqlf:view'); + @nodes = $xp->findnodes( + '/sqlf:schema/sqlf:view|/sqlf:schema/sqlf:views/sqlf:view' + ); foreach (@nodes) { my %data = get_tagfields($xp, $_, "sqlf:", - qw/name sql fields order/ + qw/name sql fields order extra/ ); $schema->add_view( %data ) or die $schema->error; } @@ -201,21 +228,41 @@ sub parse { # # Triggers # - @nodes = $xp->findnodes('/sqlf:schema/sqlf:trigger'); + @nodes = $xp->findnodes( + '/sqlf:schema/sqlf:trigger|/sqlf:schema/sqlf:triggers/sqlf:trigger' + ); foreach (@nodes) { - my %data = get_tagfields($xp, $_, "sqlf:", - qw/name perform_action_when database_event fields on_table action order/ - ); + my %data = get_tagfields($xp, $_, "sqlf:", qw/ + name perform_action_when database_event database_events fields on_table action order + extra + /); + + # back compat + if (my $evt = $data{database_event} and $translator->{show_warnings}) { + carp 'The database_event tag is deprecated - please use database_events (which can take one or more comma separated event names)'; + $data{database_events} = join (', ', + $data{database_events} || (), + $evt, + ); + } + + # split into arrayref + if (my $evts = $data{database_events}) { + $data{database_events} = [split (/\s*,\s*/, $evts) ]; + } + $schema->add_trigger( %data ) or die $schema->error; } # # Procedures # - @nodes = $xp->findnodes('/sqlf:schema/sqlf:procedure'); + @nodes = $xp->findnodes( + '/sqlf:schema/sqlf:procedure|/sqlf:schema/sqlf:procedures/sqlf:procedure' + ); foreach (@nodes) { my %data = get_tagfields($xp, $_, "sqlf:", - qw/name sql parameters owner comments order/ + qw/name sql parameters owner comments order extra/ ); $schema->add_procedure( %data ) or die $schema->error; } @@ -239,7 +286,7 @@ sub get_tagfields { if ( m/:$/ ) { $ns = $_; next; } # Set def namespace my $thisns = (s/(^.*?:)// ? $1 : $ns); - my $is_attrib = m/^sql|comments|action$/ ? 0 : 1; + my $is_attrib = m/^(sql|comments|action|extra)$/ ? 0 : 1; my $attrib_path = "\@$thisns$_"; my $tag_path = "$thisns$_"; @@ -252,7 +299,17 @@ sub get_tagfields { debug "Got $_=".( defined $data{ $_ } ? $data{ $_ } : 'UNDEF' ); } elsif ( $xp->exists($tag_path,$node) ) { - $data{$_} = "".$xp->findvalue($tag_path,$node); + if ($_ eq "extra") { + my %extra; + my $extra_nodes = $xp->find($tag_path,$node); + foreach ( $extra_nodes->pop->getAttributes ) { + $extra{$_->getName} = $_->getData; + } + $data{$_} = \%extra; + } + else { + $data{$_} = "".$xp->findvalue($tag_path,$node); + } warn "Use of '$_' as a child tag is depricated." ." Use an attribute instead." ." To convert your file to the new version see the Docs.\n" @@ -276,13 +333,18 @@ Ignores the order attribute for Constraints, Views, Indices, Views, Triggers and Procedures, using the tag order instead. (This is the order output by the SQLFairy XML producer). +=head1 SEE ALSO + +L, L, L, +L. + =head1 TODO =over 4 =item * -Support options and extra attributes. +Support options attribute. =item * @@ -290,7 +352,7 @@ Test foreign keys are parsed ok. =item * -Control over defaulting of non-existant tags. +Control over defaulting. =back @@ -298,9 +360,4 @@ Control over defaulting of non-existant tags. Mark D. Addison Emark.addison@itn.co.ukE. -=head1 SEE ALSO - -perl(1), SQL::Translator, SQL::Translator::Producer::XML::SQLFairy, -SQL::Translator::Schema. - =cut