package SQL::Translator::Parser::XML::SQLFairy;
# -------------------------------------------------------------------
-# $Id: SQLFairy.pm,v 1.8 2004-07-09 00:50:06 grommit Exp $
+# $Id: SQLFairy.pm,v 1.9 2004-08-19 14:08:59 grommit Exp $
# -------------------------------------------------------------------
# Copyright (C) 2003 Mark Addison <mark.addison@itn.co.uk>,
#
use strict;
use vars qw[ $DEBUG $VERSION @EXPORT_OK ];
-$VERSION = sprintf "%d.%02d", q$Revision: 1.8 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.9 $ =~ /(\d+)\.(\d+)/;
$DEBUG = 0 unless defined $DEBUG;
use Data::Dumper;
#
# 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)
#
# 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/
#
# 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/
#
# 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/
package SQL::Translator::Producer::XML::SQLFairy;
# -------------------------------------------------------------------
-# $Id: SQLFairy.pm,v 1.16 2004-08-18 20:27:58 grommit Exp $
+# $Id: SQLFairy.pm,v 1.17 2004-08-19 14:09:00 grommit Exp $
# -------------------------------------------------------------------
# Copyright (C) 2003 Ken Y. Clark <kclark@cpan.org>,
# darren chamberlain <darren@cpan.org>,
use strict;
use vars qw[ $VERSION @EXPORT_OK ];
-$VERSION = sprintf "%d.%02d", q$Revision: 1.16 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.17 $ =~ /(\d+)\.(\d+)/;
use Exporter;
use base qw(Exporter);
#
# Table
#
+ $xml->startTag( [ $Namespace => "tables" ] );
for my $table ( $schema->get_tables ) {
debug "Table:",$table->name;
xml_obj($xml, $table,
- tag => "table", methods => [qw/name order/], end_tag => 0 );
+ tag => "table",
+ methods => [qw/name order/],
+ end_tag => 0
+ );
#
# Fields
#
- $xml->startTag( [ $Namespace => 'fields' ] );
- for my $field ( $table->get_fields ) {
- debug " Field:",$field->name;
- xml_obj($xml, $field,
- tag =>"field",
- end_tag => 1,
- methods =>[qw/name data_type size is_nullable default_value
- is_auto_increment is_primary_key is_foreign_key extra comments order
- /],
- );
- }
- $xml->endTag( [ $Namespace => 'fields' ] );
+ xml_obj_children( $xml, $table,
+ tag => 'field',
+ methods =>[qw/
+ name data_type size is_nullable default_value is_auto_increment
+ is_primary_key is_foreign_key extra comments order
+ /],
+ );
#
# Indices
#
- $xml->startTag( [ $Namespace => 'indices' ] );
- for my $index ( $table->get_indices ) {
- debug "Index:",$index->name;
- xml_obj($xml, $index,
- tag => "index",
- end_tag => 1,
- methods =>[qw/ name type fields options/],
- );
- }
- $xml->endTag( [ $Namespace => 'indices' ] );
+ xml_obj_children( $xml, $table,
+ tag => 'index',
+ collection_tag => "indices",
+ methods => [qw/name type fields options/],
+ );
#
# Constraints
#
- $xml->startTag( [ $Namespace => 'constraints' ] );
- for my $index ( $table->get_constraints ) {
- debug "Constraint:",$index->name;
- xml_obj($xml, $index,
- tag => "constraint",
- end_tag => 1,
- methods =>[qw/
- name type fields reference_table reference_fields
- on_delete on_update match_type expression options deferrable
- /],
- );
- }
- $xml->endTag( [ $Namespace => 'constraints' ] );
+ xml_obj_children( $xml, $table,
+ tag => 'constraint',
+ methods => [qw/
+ name type fields reference_table reference_fields
+ on_delete on_update match_type expression options deferrable
+ /],
+ );
$xml->endTag( [ $Namespace => 'table' ] );
}
+ $xml->endTag( [ $Namespace => 'tables' ] );
#
# Views
#
- for my $foo ( $schema->get_views ) {
- xml_obj($xml, $foo, tag => "view",
- methods => [qw/name sql fields order/], end_tag => 1 );
- }
+ xml_obj_children( $xml, $schema,
+ tag => 'view',
+ methods => [qw/name sql fields order/],
+ );
#
# Tiggers
#
- for my $foo ( $schema->get_triggers ) {
- xml_obj($xml, $foo, tag => "trigger",
+ xml_obj_children( $xml, $schema,
+ tag => 'trigger',
methods => [qw/name database_event action on_table perform_action_when
- fields order/], end_tag => 1 );
- }
+ fields order/],
+ );
#
# Procedures
#
- for my $foo ( $schema->get_procedures ) {
- xml_obj($xml, $foo, tag => "procedure",
- methods => [qw/name sql parameters owner comments order/], end_tag=>1 );
- }
+ xml_obj_children( $xml, $schema,
+ tag => 'procedure',
+ methods => [qw/name sql parameters owner comments order/],
+ );
$xml->endTag([ $Namespace => 'schema' ]);
$xml->end;
return $io;
}
-# -------------------------------------------------------------------
+
+#
+# Takes and XML::Write object, Schema::* parent object, the tag name,
+# the collection name and a list of methods (of the children) to write as XML.
+# The collection name defaults to the name with an s on the end and is used to
+# work out the method to get the children with. eg a name of 'foo' gives a
+# collection of foos and gets the members using ->get_foos.
+#
+sub xml_obj_children {
+ my ($xml,$parent) = (shift,shift);
+ my %args = @_;
+ my ($name,$collection_name,$methods)
+ = @args{qw/tag collection_tag methods/};
+ $collection_name ||= "${name}s";
+ my $meth = "get_$collection_name";
+
+ my @kids = $parent->$meth;
+ #@kids || return;
+ $xml->startTag( [ $Namespace => $collection_name ] );
+ for my $obj ( @kids ) {
+ xml_obj($xml, $obj,
+ tag => "$name",
+ end_tag => 1,
+ methods => $methods,
+ );
+ }
+ $xml->endTag( [ $Namespace => $collection_name ] );
+}
+
#
# Takes an XML::Writer, Schema::* object and list of method names
# and writes the obect out as XML. All methods values are written as attributes
-# except for comments, sql and action which get written as child data elements.
+# except for the methods listed in @MAP_AS_ELEMENTS which get written as child
+# data elements.
#
# The attributes/tags are written in the same order as the method names are
# passed.
#=============================================================================
BEGIN {
- maybe_plan(15,
+ maybe_plan(14,
'XML::Writer',
'Test::Differences',
'SQL::Translator::Producer::XML::SQLFairy');
$ans = <<EOXML;
<schema name="" database="" xmlns="http://sqlfairy.sourceforge.net/sqlfairy.xml">
- <table name="Basic" order="1">
- <fields>
- <field name="id" data_type="integer" size="10" is_nullable="0" is_auto_increment="1" is_primary_key="1" is_foreign_key="0" order="1">
- <extra />
- <comments>comment on id field</comments>
- </field>
- <field name="title" data_type="varchar" size="100" is_nullable="0" default_value="hello" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="2">
- <extra />
- <comments></comments>
- </field>
- <field name="description" data_type="text" size="65535" is_nullable="1" default_value="" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="3">
- <extra />
- <comments></comments>
- </field>
- <field name="email" data_type="varchar" size="255" is_nullable="1" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="4">
- <extra />
- <comments></comments>
- </field>
- </fields>
- <indices>
- <index name="titleindex" type="NORMAL" fields="title" options="" />
- </indices>
- <constraints>
- <constraint name="" type="PRIMARY KEY" fields="id" reference_table="" reference_fields="" on_delete="" on_update="" match_type="" expression="" options="" deferrable="1" />
- <constraint name="" type="UNIQUE" fields="email" reference_table="" reference_fields="" on_delete="" on_update="" match_type="" expression="" options="" deferrable="1" />
- </constraints>
- </table>
+ <tables>
+ <table name="Basic" order="1">
+ <fields>
+ <field name="id" data_type="integer" size="10" is_nullable="0" is_auto_increment="1" is_primary_key="1" is_foreign_key="0" order="1">
+ <extra />
+ <comments>comment on id field</comments>
+ </field>
+ <field name="title" data_type="varchar" size="100" is_nullable="0" default_value="hello" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="2">
+ <extra />
+ <comments></comments>
+ </field>
+ <field name="description" data_type="text" size="65535" is_nullable="1" default_value="" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="3">
+ <extra />
+ <comments></comments>
+ </field>
+ <field name="email" data_type="varchar" size="255" is_nullable="1" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="4">
+ <extra />
+ <comments></comments>
+ </field>
+ </fields>
+ <indices>
+ <index name="titleindex" type="NORMAL" fields="title" options="" />
+ </indices>
+ <constraints>
+ <constraint name="" type="PRIMARY KEY" fields="id" reference_table="" reference_fields="" on_delete="" on_update="" match_type="" expression="" options="" deferrable="1" />
+ <constraint name="" type="UNIQUE" fields="email" reference_table="" reference_fields="" on_delete="" on_update="" match_type="" expression="" options="" deferrable="1" />
+ </constraints>
+ </table>
+ </tables>
+ <views></views>
+ <triggers></triggers>
+ <procedures></procedures>
</schema>
EOXML
from => "MySQL",
to => "XML-SQLFairy",
);
-lives_ok {$xml = $obj->translate($file);} "Translate (attrib_values=>1) ran";
+$xml = $obj->translate($file) or die $obj->error;
ok("$xml" ne "" ,"Produced something!");
print "XML:\n$xml" if DEBUG;
# Strip sqlf header with its variable date so we diff safely
$ans = <<EOXML;
<schema name="" database="" xmlns="http://sqlfairy.sourceforge.net/sqlfairy.xml">
- <view name="foo_view" fields="name,age" order="1">
- <sql>select name, age from person</sql>
- </view>
+ <tables></tables>
+ <views>
+ <view name="foo_view" fields="name,age" order="1">
+ <sql>select name, age from person</sql>
+ </view>
+ </views>
+ <triggers></triggers>
+ <procedures></procedures>
</schema>
EOXML
$ans = <<EOXML;
<schema name="" database="" xmlns="http://sqlfairy.sourceforge.net/sqlfairy.xml">
- <trigger name="foo_trigger" database_event="insert" on_table="foo" perform_action_when="after" order="1">
- <action>update modified=timestamp();</action>
- </trigger>
+ <tables></tables>
+ <views></views>
+ <triggers>
+ <trigger name="foo_trigger" database_event="insert" on_table="foo" perform_action_when="after" order="1">
+ <action>update modified=timestamp();</action>
+ </trigger>
+ </triggers>
+ <procedures></procedures>
</schema>
EOXML
$ans = <<EOXML;
<schema name="" database="" xmlns="http://sqlfairy.sourceforge.net/sqlfairy.xml">
- <procedure name="foo_proc" parameters="foo,bar" owner="Nomar" order="1">
- <sql>select foo from bar</sql>
- <comments>Go Sox!</comments>
- </procedure>
+ <tables></tables>
+ <views></views>
+ <triggers></triggers>
+ <procedures>
+ <procedure name="foo_proc" parameters="foo,bar" owner="Nomar" order="1">
+ <sql>select foo from bar</sql>
+ <comments>Go Sox!</comments>
+ </procedure>
+ </procedures>
</schema>
EOXML
$ans = <<EOXML;
<schema name="" database="" xmlns="http://sqlfairy.sourceforge.net/sqlfairy.xml">
- <table name="Basic" order="2">
- <fields>
- <field name="foo" data_type="integer" size="10" is_nullable="1" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="5">
- <extra ZEROFILL="1" />
- <comments></comments>
- </field>
- </fields>
- <indices></indices>
- <constraints></constraints>
- </table>
+ <tables>
+ <table name="Basic" order="2">
+ <fields>
+ <field name="foo" data_type="integer" size="10" is_nullable="1" is_auto_increment="0" is_primary_key="0" is_foreign_key="0" order="5">
+ <extra ZEROFILL="1" />
+ <comments></comments>
+ </field>
+ </fields>
+ <indices></indices>
+ <constraints></constraints>
+ </table>
+ </tables>
+ <views></views>
+ <triggers></triggers>
+ <procedures></procedures>
</schema>
EOXML
-->
<schema xmlns="http://sqlfairy.sourceforge.net/sqlfairy.xml">
- <table order="1" name="Basic">
- <fields>
- <field
- name="id"
- is_primary_key="1" is_foreign_key="0"
- size="10" data_type="int" is_auto_increment="1" order="1"
- is_nullable="0">
- <extra ZEROFILL="1" />
- </field>
- <field
- name="title"
- is_primary_key="0" is_foreign_key="0"
- size="100" is_auto_increment="0" data_type="varchar"
- order="2" default_value="hello" is_nullable="0" />
- <field
- name="description"
- size="0" data_type="text" order="3" default_value="" />
- <field name="email" size="255" data_type="varchar" order="4">
- <extra foo="bar" hello="world" bar="baz" />
- </field>
- <field name="explicitnulldef" size="0" data_type="varchar" order="5" />
- <field name="explicitemptystring" size="0"
- data_type="varchar" order="6" default_value="" />
- <field name="emptytagdef" size="0"
- data_type="varchar" order="7" default_value="" >
- <comments>Hello emptytagdef</comments>
- </field>
- </fields>
+ <tables>
+ <table order="1" name="Basic">
+ <fields>
+ <field
+ name="id"
+ is_primary_key="1" is_foreign_key="0"
+ size="10" data_type="int" is_auto_increment="1" order="1"
+ is_nullable="0">
+ <extra ZEROFILL="1" />
+ </field>
+ <field
+ name="title"
+ is_primary_key="0" is_foreign_key="0"
+ size="100" is_auto_increment="0" data_type="varchar"
+ order="2" default_value="hello" is_nullable="0" />
+ <field
+ name="description"
+ size="0" data_type="text" order="3" default_value="" />
+ <field name="email" size="255" data_type="varchar" order="4">
+ <extra foo="bar" hello="world" bar="baz" />
+ </field>
+ <field name="explicitnulldef" size="0" data_type="varchar" order="5" />
+ <field name="explicitemptystring" size="0"
+ data_type="varchar" order="6" default_value="" />
+ <field name="emptytagdef" size="0"
+ data_type="varchar" order="7" default_value="" >
+ <comments>Hello emptytagdef</comments>
+ </field>
+ </fields>
- <indices>
- <index name="titleindex" fields="title" type="NORMAL" />
- </indices>
+ <indices>
+ <index name="titleindex" fields="title" type="NORMAL" />
+ </indices>
- <constraints>
- <constraint name="" type="PRIMARY KEY" fields="id"
- reference_table="" options="" deferrable="1" match_type=""
- expression="" on_update="" on_delete="" />
- <constraint name="emailuniqueindex" type="UNIQUE" fields="email" />
- </constraints>
- </table>
+ <constraints>
+ <constraint name="" type="PRIMARY KEY" fields="id"
+ reference_table="" options="" deferrable="1" match_type=""
+ expression="" on_update="" on_delete="" />
+ <constraint name="emailuniqueindex" type="UNIQUE" fields="email" />
+ </constraints>
+ </table>
+ </tables>
- <view name="email_list" fields="email" order="1">
- <sql>SELECT email FROM Basic WHERE email IS NOT NULL</sql>
- </view>
+ <views>
+ <view name="email_list" fields="email" order="1">
+ <sql>SELECT email FROM Basic WHERE email IS NOT NULL</sql>
+ </view>
+ </views>
- <trigger name="foo_trigger" database_event="insert" on_table="foo"
- perform_action_when="after" order="1">
- <action>update modified=timestamp();</action>
- </trigger>
+ <triggers>
+ <trigger name="foo_trigger" database_event="insert" on_table="foo"
+ perform_action_when="after" order="1">
+ <action>update modified=timestamp();</action>
+ </trigger>
+ </triggers>
- <procedure name="foo_proc" order="1" owner="Nomar" parameters="foo,bar">
- <sql>select foo from bar</sql>
- <comments>Go Sox!</comments>
- </procedure>
+ <procedures>
+ <procedure name="foo_proc" order="1" owner="Nomar" parameters="foo,bar">
+ <sql>select foo from bar</sql>
+ <comments>Go Sox!</comments>
+ </procedure>
+ </procedures>
</schema>