package SQL::Translator::Producer::XML::SQLFairy;
# -------------------------------------------------------------------
-# $Id: SQLFairy.pm,v 1.12 2004-07-08 19:05:26 grommit Exp $
+# $Id: SQLFairy.pm,v 1.15 2004-07-08 23:39:38 grommit Exp $
# -------------------------------------------------------------------
# Copyright (C) 2003 Ken Y. Clark <kclark@cpan.org>,
# darren chamberlain <darren@cpan.org>,
Child objects, such as a tables fields, get mapped to child tags wrapped in a
set of container tags using the plural of their contained classes name.
+L<SQL::Translator::Schema::Field>'s extra attribute (a hash of arbitary data) is
+mapped to a tag called extra, with the hash of data as attributes, sorted into
+alphabetical order.
+
e.g.
<schema name="" database=""
<table name="Story" order="1">
<fields>
- <field name="created" data_type="datetime" size="0"
- is_nullable="1" is_auto_increment="0" is_primary_key="0"
- is_foreign_key="0" order="1">
- <comments></comments>
- </field>
<field name="id" data_type="BIGINT" size="20"
is_nullable="0" is_auto_increment="1" is_primary_key="1"
is_foreign_key="0" order="3">
+ <extra ZEROFILL="1" />
+ <comments></comments>
+ </field>
+ <field name="created" data_type="datetime" size="0"
+ is_nullable="1" is_auto_increment="0" is_primary_key="0"
+ is_foreign_key="0" order="1">
+ <extra />
<comments></comments>
</field>
...
=head1 ARGS
-Doesn't take any extra arguments.
+=over 4
+
+=item add_prefix
+
+Set to true to use the default namespace prefix of 'sqlf', instead of using
+the default namespace for
+C<http://sqlfairy.sourceforge.net/sqlfairy.xml namespace>
+
+e.g.
+
+ <!-- add_prefix=0 -->
+ <field name="foo" />
+
+ <!-- add_prefix=1 -->
+ <sqlf:field name="foo" />
+
+=item prefix
+
+Set to the namespace prefix you want to use for the
+C<http://sqlfairy.sourceforge.net/sqlfairy.xml namespace>
+
+e.g.
+
+ <!-- prefix='foo' -->
+ <foo:field name="foo" />
+
+=item newlines
+
+If true (the default) inserts newlines around the XML, otherwise the schema is
+written on one line.
+
+=item indent
+
+When using newlines the number of whitespace characters to use as the indent.
+Default is 2, set to 0 to turn off indenting.
+
+=back
+
+=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. The old producer could produce attribute only or data element
+only versions. While this allowed 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 above.
+
+This version of the producer will now only produce the new style XML.
+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
use strict;
use vars qw[ $VERSION @EXPORT_OK ];
-$VERSION = sprintf "%d.%02d", q$Revision: 1.12 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision: 1.15 $ =~ /(\d+)\.(\d+)/;
use Exporter;
use base qw(Exporter);
my $translator = shift;
my $schema = $translator->schema;
$PArgs = $translator->producer_args;
+ my $newlines = defined $PArgs->{newlines} ? $PArgs->{newlines} : 1;
+ my $indent = defined $PArgs->{indent} ? $PArgs->{indent} : 2;
my $io = IO::Scalar->new;
+
+ my $prefix = "";
+ $prefix = $Name if $PArgs->{add_prefix};
+ $prefix = $PArgs->{prefix} if $PArgs->{prefix};
my $xml = XML::Writer->new(
OUTPUT => $io,
NAMESPACES => 1,
- PREFIX_MAP => { $Namespace => $Name },
- DATA_MODE => 1,
- DATA_INDENT => 2,
+ PREFIX_MAP => { $Namespace => $prefix },
+ DATA_MODE => $newlines,
+ DATA_INDENT => $indent,
);
$xml->xmlDecl('UTF-8');
tag =>"field",
end_tag => 1,
methods =>[qw/name data_type size is_nullable default_value
- is_auto_increment is_primary_key is_foreign_key comments order
+ is_auto_increment is_primary_key is_foreign_key extra comments order
/],
);
}
my @tags;
my @attr;
foreach ( grep { defined $obj->$_ } @meths ) {
- my $what = m/^sql|comments|action$/ ? \@tags : \@attr;
- my $val = $obj->$_;
+ my $what = m/^(sql|comments|action|extra)$/ ? \@tags : \@attr;
+ my $val = $_ eq 'extra'
+ ? { $obj->$_ }
+ : $obj->$_;
$val = ref $val eq 'ARRAY' ? join(',', @$val) : $val;
push @$what, $_ => $val;
};
? $xml->emptyTag( [ $Namespace => $tag ], @attr )
: $xml->startTag( [ $Namespace => $tag ], @attr );
while ( my ($name,$val) = splice @tags,0,2 ) {
- $xml->dataElement( [ $Namespace => $name ], $val );
+ if ( ref $val eq 'HASH' ) {
+ $xml->emptyTag( [ $Namespace => $name ],
+ map { ($_, $val->{$_}) } sort keys %$val );
+ }
+ else {
+ $xml->dataElement( [ $Namespace => $name ], $val );
+ }
}
$xml->endTag( [ $Namespace => $tag ] ) if $child_tags && $end_tag;
}