From: Peter Rabbitson Date: Tue, 17 Jan 2012 11:02:22 +0000 (+0100) Subject: Tab/WS crusade X-Git-Tag: v0.11011~49 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=aee4b66eb2152b7066ced4def46e0223eb1649b1;p=dbsrgits%2FSQL-Translator.git Tab/WS crusade --- diff --git a/Changes b/Changes index 8b29b8d..ab0a4c8 100644 --- a/Changes +++ b/Changes @@ -20,6 +20,7 @@ * MySQL parser correctly differentiates between signed and unsigned integer column display sizes * Replace Class::Accessor::Fast dependency with already-included Moo +* Entire codebase is now free of tabs and trailing whitespace # ---------------------------------------------------------- # 0.11010 2011-10-05 diff --git a/Makefile.PL b/Makefile.PL index a777e44..90a3d41 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -63,8 +63,6 @@ for my $type (qw/requires recommends test_requires/) { } } -tests_recursive (); - install_script (qw| script/sqlt-diagram script/sqlt-diff @@ -76,7 +74,28 @@ install_script (qw| install_share(); -auto_provides(); +tests_recursive (); + + +# temporary(?) until I get around to fix M::I wrt xt/ +# needs Module::Install::AuthorTests +eval { + # this should not be necessary since the autoloader is supposed + # to work, but there were reports of it failing + require Module::Install::AuthorTests; + recursive_author_tests (qw/xt/); + 1; +} || do { + if ($Module::Install::AUTHOR) { + my $err = $@; + + # better error message in case of missing dep + eval { require Module::Install::AuthorTests } + || die "\nYou need Module::Install::AuthorTests installed to run this Makefile.PL in author mode:\n\n$@\n"; + + die $err; + } +}; auto_install(); diff --git a/lib/SQL/Translator/Manual.pod b/lib/SQL/Translator/Manual.pod index 78df6e0..3726278 100644 --- a/lib/SQL/Translator/Manual.pod +++ b/lib/SQL/Translator/Manual.pod @@ -19,7 +19,7 @@ groupings: =item * Parsers -The parsers are responsible for reading the input files and describing +The parsers are responsible for reading the input files and describing them to the Schema object middleware. =item * Producers @@ -37,7 +37,7 @@ Indices, Constraints, etc. It's not necessary to understand how to write or manipulate any of these for most common tasks, but you should aware of the concepts -as they will be referenced later in this document. +as they will be referenced later in this document. =head1 SQLFAIRY SCRIPTS @@ -51,7 +51,7 @@ do: =item * sqlt This is the main interface for text-to-text translations, e.g., -converting a MySQL schema to Oracle. +converting a MySQL schema to Oracle. =item * sqlt-diagram @@ -61,7 +61,7 @@ myriad options. =item * sqlt-diff This script will examine two schemas and report the SQL commands -(ALTER, CREATE) needed to turn the first schema into the second. +(ALTER, CREATE) needed to turn the first schema into the second. =item * sqlt-dumper @@ -135,11 +135,11 @@ would be fairly easy to add an XML parser for something like the TorqueDB (http://db.apache.org/torque/) project. The actual parsing of XML should be trivial given the number of XML parsers available, so all that would be left would be to map the specific concepts in the source file to the Schema objects -in SQLFairy. +in SQLFairy. To convert a schema in SQLFairy's XML dialect to Oracle, do the following: - $ sqlt -f XML-SQLFairy -t Oracle foo.xml > foo-oracle.sql + $ sqlt -f XML-SQLFairy -t Oracle foo.xml > foo-oracle.sql =head1 SERIALIZING SCHEMAS @@ -157,7 +157,7 @@ This can be accomplished like so: $ ... SQLFairy has three serialization producers, none of which is superior -to the other in their description of a schema. +to the other in their description of a schema. =over 4 @@ -213,7 +213,7 @@ the "sqlt-graph" script for more information. =back -=head1 AUTOMATED CODE-GENERATION +=head1 AUTOMATED CODE-GENERATION Given that so many applications interact with SQL databases, it's no wonder that people have automated code to deal with this interaction. @@ -321,14 +321,14 @@ somewhat quirky: $ sqlt-diff foo-v1.sql=MySQL foo-v2.sql=Oracle > diff.sql As demonstrated, the schemas need not even be from the same vendor, -though this is likely to produce some spurious results as +though this is likely to produce some spurious results as datatypes are not currently viewed equivalent unless they match exactly, even if they would be converted to the same. For example, MySQL's "integer" data type would be converted to Oracle's "number," but the differ isn't quite smart enough yet to figure this out. Also, as the SQL to ALTER a field definition varies from database vendor to vendor, these statements are made using just the keyword "CHANGE" and -will likely need to be corrected for the target database. +will likely need to be corrected for the target database. =head1 A UNIFIED GRAPHICAL INTERFACE @@ -355,28 +355,28 @@ 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 strict; 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; @@ -389,7 +389,7 @@ learn the methods you can call. Here is a very simple example: Executing this script produces the following: - $ ./my-producer.pl + $ ./my-producer.pl Table = foo Table = bar @@ -404,25 +404,25 @@ 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 ) diff --git a/lib/SQL/Translator/Parser/DB2.pm b/lib/SQL/Translator/Parser/DB2.pm index 0961f53..534bf25 100644 --- a/lib/SQL/Translator/Parser/DB2.pm +++ b/lib/SQL/Translator/Parser/DB2.pm @@ -33,7 +33,7 @@ startrule : statement(s) eofile { eofile : /^\Z/ -statement : +statement : comment | create | @@ -129,21 +129,21 @@ FULL: /full/i OUTER: /outer/i WHERE: /where/i - + trigger_name: SCHEMA '.' NAME { $return = { schema => $item[1], name => $item[3] } } | NAME - { $return = { name => $item[1] } } + { $return = { name => $item[1] } } table_name: SCHEMA '.' NAME { $return = { schema => $item[1], name => $item[3] } } | NAME - { $return = { name => $item[1] } } + { $return = { name => $item[1] } } view_name: SCHEMA '.' NAME { $return = { schema => $item[1], name => $item[3] } } | NAME - { $return = { name => $item[1] } } + { $return = { name => $item[1] } } column_name: NAME @@ -160,7 +160,7 @@ SCHEMA: /\w{1,128}/ NAME: /\w+/ NAME: /\w{1,18}/ - + options: /WITH/i ( /CASCADED/i | /LOCAL/i ) /CHECK\s+OPTION/i # root_view_definition: /MODE\s+DB2SQL/i '(' oid_column ( /,/ with_options )(?) ')' @@ -175,13 +175,13 @@ options: /WITH/i ( /CASCADED/i | /LOCAL/i ) /CHECK\s+OPTION/i common_table_expression: table_name column_list /AS/i get_bracketed { - $return = { name => $item{table_name}{name}, + $return = { name => $item{table_name}{name}, query => $item[4] }; } -get_bracketed: -{ +get_bracketed: +{ extract_bracketed($text, '('); } @@ -189,7 +189,7 @@ common_table_expression: table_name column_list /AS/i '(' fullselect ')' # fullselect: ( subselect | '(' fullselect ')' | values_clause ) ( ( /UNION/i | /UNION/i /ALL/i | /EXCEPT/i | /EXCEPT/i /ALL/i | /INTERSECT/i | /INTERSECT/i /ALL/i ) ( subselect | '(' fullselect ')' | values_clause ) )(s) -# values_clause: /VALUES/i values_row(s /,/) +# values_clause: /VALUES/i values_row(s /,/) # values_row: ( expression | /NULL/i ) | '(' ( expression | /NULL/i )(s /,/) ')' @@ -201,37 +201,37 @@ common_table_expression: table_name column_list /AS/i '(' fullselect ')' # from_clause: /FROM/i table_reference(s /,/) -# table_reference: -# ( -# ( nickname -# | table_name -# | view_name -# ) +# table_reference: +# ( +# ( nickname +# | table_name +# | view_name +# ) # | ( /ONLY/i -# | /OUTER/i -# ) '(' -# ( table_name -# | view_name -# ) ')' -# ) correlation_clause(?) -# | TABLE '(' function_name '(' expression(s? /,/) ')' ')' correlation_clause -# | TABLE(?) '(' fullselect ')' correlation_clause -# | joined_table - +# | /OUTER/i +# ) '(' +# ( table_name +# | view_name +# ) ')' +# ) correlation_clause(?) +# | TABLE '(' function_name '(' expression(s? /,/) ')' ')' correlation_clause +# | TABLE(?) '(' fullselect ')' correlation_clause +# | joined_table + # correlation_clause: /AS/i(?) correlation_name column_list(?) -# joined_table: -# table_reference ( INNER -# | outer +# joined_table: +# table_reference ( INNER +# | outer # )(?) JOIN table_reference ON join_condition # | '(' joined_table ')' - + # outer: ( LEFT | RIGHT | FULL ) OUTER(?) where_clause: WHERE search_condition -# group_by_clause: /GROUP\s+BY/i ( grouping_expression +# group_by_clause: /GROUP\s+BY/i ( grouping_expression # | grouping_sets # | super_groups # )(s /,/) @@ -245,27 +245,27 @@ where_clause: WHERE search_condition # # Name of one of the selected columns! # simple_column_name: NAME -# simple_integer: /\d+/ +# simple_integer: /\d+/ # { $item[1] <= $numberofcolumns && $item[1] > 1 } # sort_key_expression: expression # { expression from select columns list, grouping_expression, column function.. } -# grouping_sets: /GROUPING\s+SETS/i '(' ( -# ( grouping_expression -# | super_groups -# ) -# | '(' ( grouping_expression -# | super_groups -# )(s /,/) ')' -# )(s /,/) ')' +# grouping_sets: /GROUPING\s+SETS/i '(' ( +# ( grouping_expression +# | super_groups +# ) +# | '(' ( grouping_expression +# | super_groups +# )(s /,/) ')' +# )(s /,/) ')' -# super_groups: /ROLLUP/i '(' grouping_expression_list ')' +# super_groups: /ROLLUP/i '(' grouping_expression_list ')' # | /CUBE/i '(' grouping_expression_list ')' # | grand_total -# grouping_expression_list: ( grouping_expression -# | '(' grouping_expression(s /,/) ')' +# grouping_expression_list: ( grouping_expression +# | '(' grouping_expression(s /,/) ')' # )(s /,/) # grand_total: '(' ')' @@ -283,7 +283,7 @@ before: /NO CASCADE BEFORE/i after: /AFTER/i -type: /UPDATE/i /OF/i column_name(s /,/) +type: /UPDATE/i /OF/i column_name(s /,/) { $return = { event => 'update_on', fields => $item[3] } } @@ -294,10 +294,10 @@ type: ( /INSERT/i | /DELETE/i | /UPDATE/i ) reference_b: /REFERENCING/i old_new_corr(0..2) { $return = join(' ', $item[1], join(' ', @{$item[2]}) ) } -reference_a: /REFERENCING/i old_new_corr(0..2) old_new_table(0..2) +reference_a: /REFERENCING/i old_new_corr(0..2) old_new_table(0..2) { $return = join(' ', $item[1], join(' ', @{$item[2]}), join(' ', @{$item[3]}) ) } -old_new_corr: /OLD/i /(AS)?/i correlation_name +old_new_corr: /OLD/i /(AS)?/i correlation_name { $return = join(' ', @item[1..3] ) } | /NEW/i /(AS)?/i correlation_name { $return = join(' ', @item[1..3] ) } @@ -310,17 +310,17 @@ old_new_table: /OLD_TABLE/i /(AS)?/i identifier # Just parsing simple search conditions for now. search_condition: /[^)]+/ -expression: ( - ( '+' - | '-' - )(?) +expression: ( + ( '+' + | '-' + )(?) ( function | '(' expression ')' | constant | column_name | host_variable | special_register - | '(' scalar_fullselect ')' + | '(' scalar_fullselect ')' | labeled_duration | case_expression | cast_specification @@ -328,15 +328,15 @@ expression: ( | OLAP_function | method_invocation | subtype_treatment - | sequence_reference + | sequence_reference ) )(s /operator/) -operator: ( /CONCAT/i | '||' ) | '/' | '*' | '+' | '-' +operator: ( /CONCAT/i | '||' ) | '/' | '*' | '+' | '-' -function: ( /SYSIBM\.|/i sysibm_function +function: ( /SYSIBM\.|/i sysibm_function | /SYSFUN\.|/i sysfun_function - | userdefined_function + | userdefined_function ) '(' func_args(s /,/) ')' constant: int_const | float_const | dec_const | char_const | hex_const | grastr_const @@ -493,83 +493,83 @@ scalar_fullselect: '(' fullselect ')' labeled_duration: ld_type ld_duration -ld_type: function - | '(' expression ')' - | constant - | column_name +ld_type: function + | '(' expression ')' + | constant + | column_name | host_variable -ld_duration: /YEARS?/i - | /MONTHS?/i - | /DAYS?/i - | /HOURS?/i +ld_duration: /YEARS?/i + | /MONTHS?/i + | /DAYS?/i + | /HOURS?/i | /MINUTES?/i | /SECONDS?/i | /MICROSECONDS?/i -case_expression: /CASE/i ( searched_when_clause - | simple_when_clause - ) - ( /ELSE\s+NULL/i - | /ELSE/i result_expression +case_expression: /CASE/i ( searched_when_clause + | simple_when_clause + ) + ( /ELSE\s+NULL/i + | /ELSE/i result_expression )(?) /END/i -searched_when_clause: ( /WHEN/i search_condition /THEN/i - ( result_expression +searched_when_clause: ( /WHEN/i search_condition /THEN/i + ( result_expression | /NULL/i ) )(s) -simple_when_clause: expression ( /WHEN/i search_condition /THEN/i - ( result_expression +simple_when_clause: expression ( /WHEN/i search_condition /THEN/i + ( result_expression | /NULL/i ) )(s) -result_expression: expression +result_expression: expression -cast_specification: /CAST/i '(' ( expression +cast_specification: /CAST/i '(' ( expression | /NULL/i | parameter_marker - ) /AS/i data_type - ( /SCOPE/ ( typed_table_name + ) /AS/i data_type + ( /SCOPE/ ( typed_table_name | typed_view_name ) )(?) ')' -dereference_operation: scoped_reference_expression '->' name1 +dereference_operation: scoped_reference_expression '->' name1 ( '(' expression(s) ')' )(?) # ( '(' expression(s /,/) ')' )(?) -scoped_reference_expression: expression -{ # scoped, reference +scoped_reference_expression: expression +{ # scoped, reference } name1: NAME -OLAP_function: ranking_function +OLAP_function: ranking_function | numbering_function | aggregation_function -ranking_function: ( /RANK/ '()' - | /DENSE_RANK|DENSERANK/i '()' +ranking_function: ( /RANK/ '()' + | /DENSE_RANK|DENSERANK/i '()' ) /OVER/i '(' window_partition_clause(?) window_order_clause ')' -numbering_function: /ROW_NUMBER|ROWNUMBER/i '()' /OVER/i '(' window_partition_clause(?) - ( window_order_clause window_aggregation_group_clause(?) - )(?) - ( /RANGE\s+BETWEEN\s+UNBOUNDED\s+PRECEDING\s+AND\s+UNBBOUNDED\s+FOLLOWING/i +numbering_function: /ROW_NUMBER|ROWNUMBER/i '()' /OVER/i '(' window_partition_clause(?) + ( window_order_clause window_aggregation_group_clause(?) + )(?) + ( /RANGE\s+BETWEEN\s+UNBOUNDED\s+PRECEDING\s+AND\s+UNBBOUNDED\s+FOLLOWING/i | window_aggregation_group_clause )(?) ')' window_partition_clause: /PARTITION\s+BY/i partitioning_expression(s /,/) -window_order_clause: /ORDER\s+BY/i - ( sort_key_expression - ( asc_option - | desc_option +window_order_clause: /ORDER\s+BY/i + ( sort_key_expression + ( asc_option + | desc_option )(?) )(s /,/) @@ -579,42 +579,42 @@ desc_option: /DESC/i ( /NULLS\s+FIRST/i | /NULLS\s+LAST/i )(?) window_aggregation_group_clause: ( /ROWS/i | /RANGE/i - ) + ) ( group_start | group_between | group_end ) -group_start: /UNBOUNDED\s+PRECEDING/i +group_start: /UNBOUNDED\s+PRECEDING/i | unsigned_constant /PRECEDING/i | /CURRENT\s+ROW/i group_between: /BETWEEN/i group_bound1 /AND/i group_bound2 -group_bound1: /UNBOUNDED\s+PRECEDING/i +group_bound1: /UNBOUNDED\s+PRECEDING/i | unsigned_constant /PRECEDING/i | unsigned_constant /FOLLOWING/i | /CURRENT\s+ROW/i -group_bound2: /UNBOUNDED\s+PRECEDING/i +group_bound2: /UNBOUNDED\s+PRECEDING/i | unsigned_constant /PRECEDING/i | unsigned_constant /FOLLOWING/i | /CURRENT\s+ROW/i -group_end: /UNBOUNDED\s+PRECEDING/i - | unsigned_constant /FOLLOWING/i +group_end: /UNBOUNDED\s+PRECEDING/i + | unsigned_constant /FOLLOWING/i method_invocation: subject_expression '..' method_name - ( '(' expression(s) ')' -# ( '(' expression(s /,/) ')' + ( '(' expression(s) ')' +# ( '(' expression(s /,/) ')' )(?) subject_expression: expression -{ # with static result type that is a used-defined struct type +{ # with static result type that is a used-defined struct type } method_name: NAME -{ # must be a method of subject_expression +{ # must be a method of subject_expression } subtype_treatment: /TREAT/i '(' expression /AS/i data_type ')' @@ -633,7 +633,7 @@ search_condition: /NOT|/i ( predicate ( /SELECTIVITY/i numeric_constant )(?) | ' cond: ( /AND/i | /OR/i ) /NOT|/i ( predicate ( /SELECTIVITY/i numeric_constant )(?) | '(' search_condition ')' ) -predicate: basic_p | quantified_p | between_p | exists_p | in_p | like_p | null_p | type_p +predicate: basic_p | quantified_p | between_p | exists_p | in_p | like_p | null_p | type_p basic_p: expression /(=|<>|<|>|<=|=>|\^=|\^<|\^>|\!=)/ expression diff --git a/lib/SQL/Translator/Parser/SQLServer.pm b/lib/SQL/Translator/Parser/SQLServer.pm index 8540041..bfe427d 100644 --- a/lib/SQL/Translator/Parser/SQLServer.pm +++ b/lib/SQL/Translator/Parser/SQLServer.pm @@ -175,7 +175,7 @@ create_table : /create/i /table/i ident '(' create_def(s /,/) ')' lock(?) on_sys disable_constraints : if_exists(?) /alter/i /table/i ident /nocheck/i /constraint/i /all/i END_STATEMENT -# this is for the normal case +# this is for the normal case create_constraint : /create/i constraint END_STATEMENT { @table_comments = (); diff --git a/lib/SQL/Translator/Producer/Oracle.pm b/lib/SQL/Translator/Producer/Oracle.pm index ba0b9de..46a24a5 100644 --- a/lib/SQL/Translator/Producer/Oracle.pm +++ b/lib/SQL/Translator/Producer/Oracle.pm @@ -709,7 +709,7 @@ sub create_field { "CREATE OR REPLACE TRIGGER $trig_name\n". "BEFORE INSERT OR UPDATE ON $table_name_q\n". "FOR EACH ROW WHEN (new.$field_name_q IS NULL)\n". - "BEGIN \n". + "BEGIN\n". " SELECT sysdate INTO :new.$field_name_q FROM dual;\n". "END;\n"; diff --git a/script/sqlt b/script/sqlt index 720a926..9c19bce 100755 --- a/script/sqlt +++ b/script/sqlt @@ -51,7 +51,7 @@ To translate a schema: General Parser Options: --skip Comma-separated list of tables to skip (only implemented in some parsers) - --ignore_opts Comma-separated list of table options to ignore + --ignore_opts Comma-separated list of table options to ignore DBI Parser Options: @@ -247,12 +247,12 @@ GetOptions( ) or pod2usage(2); if ($use_same_auth) { - $producer_dsn = $dsn; - $producer_db_user = $db_user; - $producer_db_password = $db_password; + $producer_dsn = $dsn; + $producer_db_user = $db_user; + $producer_db_password = $db_password; } -if ( +if ( ( !defined $from && defined $dsn ) || $from =~ /^DBI.*/ @@ -277,7 +277,7 @@ if ( $show_version ) { exit(0); } -my $translator = SQL::Translator->new( +my $translator = SQL::Translator->new( debug => $debug || 0, trace => $trace || 0, no_comments => $no_comments || 0, @@ -318,7 +318,7 @@ my $translator = SQL::Translator->new( newlines => $newlines, postgres_version => $postgres_version, mysql_version => $mysql_version, - package_name => $package_name, + package_name => $package_name, }, ); @@ -345,7 +345,7 @@ $translator->parser($from); $translator->producer($to); for my $file (@files) { - my @args = + my @args = ($file eq '-') ? (data => \*STDIN) : ($file eq '!') ? (data => '') : (file => $file); diff --git a/script/sqlt-diagram b/script/sqlt-diagram index ca58dc6..767eb6e 100755 --- a/script/sqlt-diagram +++ b/script/sqlt-diagram @@ -18,7 +18,7 @@ # 02111-1307 USA # ------------------------------------------------------------------- -=head1 NAME +=head1 NAME sqlt-diagram - Automatically create a diagram from a database schema @@ -37,13 +37,13 @@ sqlt-diagram - Automatically create a diagram from a database schema default "medium") --gutter Gutter size between tables --color Add colors - --show-fk-only Only show fields that act as primary + --show-fk-only Only show fields that act as primary or foreign keys --natural-join Perform natural joins --natural-join-pk Perform natural joins from primary keys only -s|--skip Fields to skip in natural joins - --skip-tables Comma-separated list of table names to exclude + --skip-tables Comma-separated list of table names to exclude --skip-tables-like Comma-separated list of regexen to exclude tables --debug Print debugging information @@ -82,10 +82,10 @@ $VERSION = '1.59'; # # Get arguments. # -my ( - $out_file, $image_type, $db_driver, $title, $num_columns, +my ( + $out_file, $image_type, $db_driver, $title, $num_columns, $no_lines, $font_size, $add_color, $debug, $show_fk_only, - $gutter, $natural_join, $join_pk_only, $skip_fields, + $gutter, $natural_join, $join_pk_only, $skip_fields, $skip_tables, $skip_tables_like, $help ); @@ -114,7 +114,7 @@ pod2usage(1) if $help; pod2usage( -message => "No db driver specified" ) unless $db_driver; pod2usage( -message => 'No input file' ) unless @files; -my $translator = SQL::Translator->new( +my $translator = SQL::Translator->new( from => $db_driver, to => 'Diagram', debug => $debug || 0, diff --git a/script/sqlt-diff b/script/sqlt-diff index 3a5a6a5..f2ee1fb 100755 --- a/script/sqlt-diff +++ b/script/sqlt-diff @@ -57,8 +57,8 @@ Options: =head1 DESCRIPTION sqlt-diff is a utility for creating a file of SQL commands necessary to -transform the first schema provided to the second. While not yet -exhaustive in its ability to mutate the entire schema, it will report the +transform the first schema provided to the second. While not yet +exhaustive in its ability to mutate the entire schema, it will report the following =over @@ -71,24 +71,24 @@ indices). =item * Missing/altered fields -Any fields missing or altered between the two schemas will be reported +Any fields missing or altered between the two schemas will be reported as: - ALTER TABLE - [DROP ] + ALTER TABLE + [DROP ] [CHANGE ()] ; =item * Missing/altered indices Any indices missing or of a different type or on different fields will be indicated. Indices that should be dropped will be reported as such: - + DROP INDEX ON ; -An index of a different type or on different fields will be reported as a +An index of a different type or on different fields will be reported as a new index as such: - CREATE [] INDEX [] ON + CREATE [] INDEX [] ON ( [,] ) ; =back @@ -113,9 +113,9 @@ use SQL::Translator::Schema::Constants; use vars qw( $VERSION ); $VERSION = '1.59'; -my ( @input, $list, $help, $debug, $trace, $caseopt, $ignore_index_names, - $ignore_constraint_names, $output_db, $mysql_parser_version, - $ignore_view_sql, $ignore_proc_sql, $no_batch_alters ); +my ( @input, $list, $help, $debug, $trace, $caseopt, $ignore_index_names, + $ignore_constraint_names, $output_db, $mysql_parser_version, + $ignore_view_sql, $ignore_proc_sql, $no_batch_alters ); for my $arg ( @ARGV ) { if ( $arg =~ m/^-?-l(ist)?$/ ) { $list = 1; @@ -124,31 +124,31 @@ for my $arg ( @ARGV ) { $help = 1; } elsif ( $arg =~ m/^-?-d(ebug)?$/ ) { - $debug = 1; + $debug = 1; } elsif ( $arg =~ m/^-?-t(race)?$/ ) { - $trace = 1; + $trace = 1; } elsif ( $arg =~ m/^-?-c(ase-insensitive)?$/ ) { - $caseopt = 1; + $caseopt = 1; } elsif ( $arg =~ m/^--ignore-index-names$/ ) { - $ignore_index_names = 1; + $ignore_index_names = 1; } elsif ( $arg =~ m/^--ignore-constraint-names$/ ) { - $ignore_constraint_names = 1; + $ignore_constraint_names = 1; } elsif ( $arg =~ m/^--mysql-parser-version=(.+)$/ ) { - $mysql_parser_version = $1; + $mysql_parser_version = $1; } elsif ( $arg =~ m/^--output-db=(.+)$/ ) { - $output_db = $1; + $output_db = $1; } elsif ( $arg =~ m/^--ignore-view-sql$/ ) { - $ignore_view_sql = 1; + $ignore_view_sql = 1; } elsif ( $arg =~ m/^--ignore-proc-sql$/ ) { - $ignore_proc_sql = 1; + $ignore_proc_sql = 1; } elsif ( $arg =~ m/^([^=]+)=(.+)$/ ) { push @input, { file => $1, parser => $2 }; @@ -162,7 +162,7 @@ for my $arg ( @ARGV ) { } print STDERR <<'EOM'; -This code is experimental, currently the new code only supports MySQL or +This code is experimental, currently the new code only supports MySQL or SQLite diffing. To add support for other databases, please patch the relevant SQL::Translator::Producer:: module. If you need compatibility with the old sqlt-diff, please use sqlt-diff-old, and look into helping us make this one @@ -204,7 +204,7 @@ my ( $source_schema, $source_db, $target_schema, $target_db ) = map { ($schema, $parser); } @input; -my $result = SQL::Translator::Diff::schema_diff($source_schema, $source_db, +my $result = SQL::Translator::Diff::schema_diff($source_schema, $source_db, $target_schema, $target_db, { caseopt => $caseopt, ignore_index_names => $ignore_index_names, diff --git a/script/sqlt-diff-old b/script/sqlt-diff-old index 96a3c92..3036943 100755 --- a/script/sqlt-diff-old +++ b/script/sqlt-diff-old @@ -44,8 +44,8 @@ Options: =head1 DESCRIPTION sqlt-diff is a utility for creating a file of SQL commands necessary to -transform the first schema provided to the second. While not yet -exhaustive in its ability to mutate the entire schema, it will report the +transform the first schema provided to the second. While not yet +exhaustive in its ability to mutate the entire schema, it will report the following =over @@ -58,24 +58,24 @@ indices). =item * Missing/altered fields -Any fields missing or altered between the two schemas will be reported +Any fields missing or altered between the two schemas will be reported as: - ALTER TABLE - [DROP ] + ALTER TABLE + [DROP ] [CHANGE ()] ; =item * Missing/altered indices Any indices missing or of a different type or on different fields will be indicated. Indices that should be dropped will be reported as such: - + DROP INDEX ON ; -An index of a different type or on different fields will be reported as a +An index of a different type or on different fields will be reported as a new index as such: - CREATE [] INDEX [] ON + CREATE [] INDEX [] ON ( [,] ) ; =back @@ -107,7 +107,7 @@ for my $arg ( @ARGV ) { $help = 1; } elsif ( $arg =~ m/^-?-d(ebug)?$/ ) { - $debug = 1; + $debug = 1; } elsif ( $arg =~ m/^([^=]+)=(.+)$/ ) { push @input, { file => $1, parser => $2 }; @@ -181,65 +181,65 @@ for my $t1 ( $source_schema->get_tables ) { warn "TABLE '$s1_name.$t1_name'\n" if $debug; unless ( $t2 ) { - warn "Couldn't find table '$s1_name.$t1_name' in '$s2_name'\n" + warn "Couldn't find table '$s1_name.$t1_name' in '$s2_name'\n" if $debug; if ( $target_db =~ /(SQLServer|Oracle)/ ) { - for my $constraint ( $t1->get_constraints ) { - next if $constraint->type ne FOREIGN_KEY; - push @diffs_at_end, "ALTER TABLE $t1_name ADD ". - constraint_to_string($constraint, $source_schema).";"; - $t1->drop_constraint($constraint); - } + for my $constraint ( $t1->get_constraints ) { + next if $constraint->type ne FOREIGN_KEY; + push @diffs_at_end, "ALTER TABLE $t1_name ADD ". + constraint_to_string($constraint, $source_schema).";"; + $t1->drop_constraint($constraint); + } } push @new_tables, $t1; next; } - + # Go through our options - my $options_different = 0; - my %checkedOptions; + my $options_different = 0; + my %checkedOptions; OPTION: - for my $t1_option_ref ( $t1->options ) { - my($key1, $value1) = %{$t1_option_ref}; - for my $t2_option_ref ( $t2->options ) { - my($key2, $value2) = %{$t2_option_ref}; - if ( $key1 eq $key2 ) { - if ( defined $value1 != defined $value2 ) { - $options_different = 1; - last OPTION; - } - if ( defined $value1 && $value1 ne $value2 ) { - $options_different = 1; - last OPTION; - } - $checkedOptions{$key1} = 1; - next OPTION; - } - } - $options_different = 1; - last OPTION; - } + for my $t1_option_ref ( $t1->options ) { + my($key1, $value1) = %{$t1_option_ref}; + for my $t2_option_ref ( $t2->options ) { + my($key2, $value2) = %{$t2_option_ref}; + if ( $key1 eq $key2 ) { + if ( defined $value1 != defined $value2 ) { + $options_different = 1; + last OPTION; + } + if ( defined $value1 && $value1 ne $value2 ) { + $options_different = 1; + last OPTION; + } + $checkedOptions{$key1} = 1; + next OPTION; + } + } + $options_different = 1; + last OPTION; + } # Go through the other table's options unless ( $options_different ) { - for my $t2_option_ref ( $t2->options ) { - my($key, $value) = %{$t2_option_ref}; - next if $checkedOptions{$key}; - $options_different = 1; - last; - } + for my $t2_option_ref ( $t2->options ) { + my($key, $value) = %{$t2_option_ref}; + next if $checkedOptions{$key}; + $options_different = 1; + last; + } } # If there's a difference, just re-set all the options my @diffs_table_options; if ( $options_different ) { - my @options = (); - foreach my $option_ref ( $t1->options ) { - my($key, $value) = %{$option_ref}; - push(@options, defined $value ? "$key=$value" : $key); - } - my $options = join(' ', @options); - @diffs_table_options = ("ALTER TABLE $t1_name $options;"); + my @options = (); + foreach my $option_ref ( $t1->options ) { + my($key, $value) = %{$option_ref}; + push(@options, defined $value ? "$key=$value" : $key); + } + my $options = join(' ', @options); + @diffs_table_options = ("ALTER TABLE $t1_name $options;"); } - + my $t2_name = $t2->name; my(@diffs_table_adds, @diffs_table_changes); for my $t1_field ( $t1->get_fields ) { @@ -256,48 +256,48 @@ OPTION: my $f2_full_name = "$s2_name.$t2_name.$f1_name"; unless ( $t2_field ) { - warn "Couldn't find field '$f2_full_name' in '$t2_name'\n" + warn "Couldn't find field '$f2_full_name' in '$t2_name'\n" if $debug; my $temp_default_value = 0; if ( $target_db =~ /SQLServer/ && !$f1_nullable && !defined $f1_default ) { - # SQL Server doesn't allow adding non-nullable, non-default columns - # so we add it with a default value, then remove the default value - $temp_default_value = 1; - my(@numeric_types) = qw(decimal numeric float real int bigint smallint tinyint); - $f1_default = grep($_ eq $f1_type, @numeric_types) ? 0 : ''; + # SQL Server doesn't allow adding non-nullable, non-default columns + # so we add it with a default value, then remove the default value + $temp_default_value = 1; + my(@numeric_types) = qw(decimal numeric float real int bigint smallint tinyint); + $f1_default = grep($_ eq $f1_type, @numeric_types) ? 0 : ''; } push @diffs_table_adds, sprintf( "ALTER TABLE %s ADD %s%s %s%s%s%s%s%s;", $t1_name, $target_db =~ /Oracle/ ? '(' : '', $f1_name, $f1_type, ($f1_size && $f1_type !~ /(blob|text)$/) ? "($f1_size)" : '', !defined $f1_default ? '' - : uc $f1_default eq 'NULL' ? ' DEFAULT NULL' - : uc $f1_default eq 'CURRENT_TIMESTAMP' ? ' DEFAULT CURRENT_TIMESTAMP' - : " DEFAULT '$f1_default'", + : uc $f1_default eq 'NULL' ? ' DEFAULT NULL' + : uc $f1_default eq 'CURRENT_TIMESTAMP' ? ' DEFAULT CURRENT_TIMESTAMP' + : " DEFAULT '$f1_default'", $f1_nullable ? '' : ' NOT NULL', $f1_auto_inc ? ' AUTO_INCREMENT' : '', $target_db =~ /Oracle/ ? ')' : '', ); if ( $temp_default_value ) { - undef $f1_default; - push @diffs_table_adds, sprintf( <default_value; my $f2_auto_inc = $t2_field->is_auto_increment; if ( !$t1_field->equals($t2_field, $case_insensitive) ) { - # SQLServer timestamp fields can't be altered, so we drop and add instead - if ( $target_db =~ /SQLServer/ && $f2_type eq "timestamp" ) { - push @diffs_table_changes, "ALTER TABLE $t1_name DROP COLUMN $f1_name;"; - push @diffs_table_changes, sprintf( "ALTER TABLE %s ADD %s%s %s%s%s%s%s%s;", - $t1_name, $target_db =~ /Oracle/ ? '(' : '', - $f1_name, $f1_type, - ($f1_size && $f1_type !~ /(blob|text)$/) ? "($f1_size)" : '', - !defined $f1_default ? '' - : uc $f1_default eq 'NULL' ? ' DEFAULT NULL' - : uc $f1_default eq 'CURRENT_TIMESTAMP' ? ' DEFAULT CURRENT_TIMESTAMP' - : " DEFAULT '$f1_default'", - $f1_nullable ? '' : ' NOT NULL', - $f1_auto_inc ? ' AUTO_INCREMENT' : '', - $target_db =~ /Oracle/ ? ')' : '', - ); - next; - } - - my $changeText = $target_db =~ /SQLServer/ ? 'ALTER COLUMN' : - $target_db =~ /Oracle/ ? 'MODIFY (' : 'CHANGE'; - my $nullText = $f1_nullable ? '' : ' NOT NULL'; - $nullText = '' if $target_db =~ /Oracle/ && $f1_nullable == $f2_nullable; + # SQLServer timestamp fields can't be altered, so we drop and add instead + if ( $target_db =~ /SQLServer/ && $f2_type eq "timestamp" ) { + push @diffs_table_changes, "ALTER TABLE $t1_name DROP COLUMN $f1_name;"; + push @diffs_table_changes, sprintf( "ALTER TABLE %s ADD %s%s %s%s%s%s%s%s;", + $t1_name, $target_db =~ /Oracle/ ? '(' : '', + $f1_name, $f1_type, + ($f1_size && $f1_type !~ /(blob|text)$/) ? "($f1_size)" : '', + !defined $f1_default ? '' + : uc $f1_default eq 'NULL' ? ' DEFAULT NULL' + : uc $f1_default eq 'CURRENT_TIMESTAMP' ? ' DEFAULT CURRENT_TIMESTAMP' + : " DEFAULT '$f1_default'", + $f1_nullable ? '' : ' NOT NULL', + $f1_auto_inc ? ' AUTO_INCREMENT' : '', + $target_db =~ /Oracle/ ? ')' : '', + ); + next; + } + + my $changeText = $target_db =~ /SQLServer/ ? 'ALTER COLUMN' : + $target_db =~ /Oracle/ ? 'MODIFY (' : 'CHANGE'; + my $nullText = $f1_nullable ? '' : ' NOT NULL'; + $nullText = '' if $target_db =~ /Oracle/ && $f1_nullable == $f2_nullable; push @diffs_table_changes, sprintf( "ALTER TABLE %s %s %s%s %s%s%s%s%s%s;", $t1_name, $changeText, $f1_name, $target_db =~ /MySQL/ ? " $f1_name" : '', $f1_type, ($f1_size && $f1_type !~ /(blob|text)$/) ? "($f1_size)" : '', $nullText, !defined $f1_default || $target_db =~ /SQLServer/ ? '' - : uc $f1_default eq 'NULL' ? ' DEFAULT NULL' - : uc $f1_default eq 'CURRENT_TIMESTAMP' ? ' DEFAULT CURRENT_TIMESTAMP' - : " DEFAULT '$f1_default'", + : uc $f1_default eq 'NULL' ? ' DEFAULT NULL' + : uc $f1_default eq 'CURRENT_TIMESTAMP' ? ' DEFAULT CURRENT_TIMESTAMP' + : " DEFAULT '$f1_default'", $f1_auto_inc ? ' AUTO_INCREMENT' : '', $target_db =~ /Oracle/ ? ')' : '', ); if ( defined $f1_default && $target_db =~ /SQLServer/ ) { - # Adding a column with a default value for SQL Server means adding a - # constraint and setting existing NULLs to the default value - push @diffs_table_changes, sprintf( "ALTER TABLE %s ADD CONSTRAINT DF_%s_%s %s FOR %s;", - $t1_name, $t1_name, $f1_name, uc $f1_default eq 'NULL' ? 'DEFAULT NULL' - : uc $f1_default eq 'CURRENT_TIMESTAMP' ? 'DEFAULT CURRENT_TIMESTAMP' - : "DEFAULT '$f1_default'", $f1_name, + # Adding a column with a default value for SQL Server means adding a + # constraint and setting existing NULLs to the default value + push @diffs_table_changes, sprintf( "ALTER TABLE %s ADD CONSTRAINT DF_%s_%s %s FOR %s;", + $t1_name, $t1_name, $f1_name, uc $f1_default eq 'NULL' ? 'DEFAULT NULL' + : uc $f1_default eq 'CURRENT_TIMESTAMP' ? 'DEFAULT CURRENT_TIMESTAMP' + : "DEFAULT '$f1_default'", $f1_name, ); - push @diffs_table_changes, sprintf( "UPDATE %s SET %s = %s WHERE %s IS NULL;", - $t1_name, $f1_name, uc $f1_default eq 'NULL' ? 'NULL' - : uc $f1_default eq 'CURRENT_TIMESTAMP' ? 'CURRENT_TIMESTAMP' - : "'$f1_default'", $f1_name, + push @diffs_table_changes, sprintf( "UPDATE %s SET %s = %s WHERE %s IS NULL;", + $t1_name, $f1_name, uc $f1_default eq 'NULL' ? 'NULL' + : uc $f1_default eq 'CURRENT_TIMESTAMP' ? 'CURRENT_TIMESTAMP' + : "'$f1_default'", $f1_name, ); } } } - - my(%checked_indices, @diffs_index_creates, @diffs_index_drops); + + my(%checked_indices, @diffs_index_creates, @diffs_index_drops); INDEX: - for my $i1 ( $t1->get_indices ) { - for my $i2 ( $t2->get_indices ) { - if ( $i1->equals($i2, $case_insensitive) ) { - $checked_indices{$i2} = 1; - next INDEX; - } - } - push @diffs_index_creates, sprintf( + for my $i1 ( $t1->get_indices ) { + for my $i2 ( $t2->get_indices ) { + if ( $i1->equals($i2, $case_insensitive) ) { + $checked_indices{$i2} = 1; + next INDEX; + } + } + push @diffs_index_creates, sprintf( "CREATE %sINDEX%s ON %s (%s);", $i1->type eq NORMAL ? '' : $i1->type." ", $i1->name ? " ".$i1->name : '', $t1_name, join(",", $i1->fields), ); - } + } INDEX2: - for my $i2 ( $t2->get_indices ) { - next if $checked_indices{$i2}; - for my $i1 ( $t1->get_indices ) { - next INDEX2 if $i2->equals($i1, $case_insensitive); - } - $target_db =~ /SQLServer/ - ? push @diffs_index_drops, "DROP INDEX $t1_name.".$i2->name.";" - : push @diffs_index_drops, "DROP INDEX ".$i2->name." on $t1_name;"; - } - - my(%checked_constraints, @diffs_constraint_drops); + for my $i2 ( $t2->get_indices ) { + next if $checked_indices{$i2}; + for my $i1 ( $t1->get_indices ) { + next INDEX2 if $i2->equals($i1, $case_insensitive); + } + $target_db =~ /SQLServer/ + ? push @diffs_index_drops, "DROP INDEX $t1_name.".$i2->name.";" + : push @diffs_index_drops, "DROP INDEX ".$i2->name." on $t1_name;"; + } + + my(%checked_constraints, @diffs_constraint_drops); CONSTRAINT: - for my $c1 ( $t1->get_constraints ) { - next if $source_db =~ /Oracle/ && $c1->type eq UNIQUE && $c1->name =~ /^SYS_/i; - for my $c2 ( $t2->get_constraints ) { - if ( $c1->equals($c2, $case_insensitive) ) { - $checked_constraints{$c2} = 1; - next CONSTRAINT; - } - } - push @diffs_at_end, "ALTER TABLE $t1_name ADD ". - constraint_to_string($c1, $source_schema).";"; - } + for my $c1 ( $t1->get_constraints ) { + next if $source_db =~ /Oracle/ && $c1->type eq UNIQUE && $c1->name =~ /^SYS_/i; + for my $c2 ( $t2->get_constraints ) { + if ( $c1->equals($c2, $case_insensitive) ) { + $checked_constraints{$c2} = 1; + next CONSTRAINT; + } + } + push @diffs_at_end, "ALTER TABLE $t1_name ADD ". + constraint_to_string($c1, $source_schema).";"; + } CONSTRAINT2: - for my $c2 ( $t2->get_constraints ) { - next if $checked_constraints{$c2}; - for my $c1 ( $t1->get_constraints ) { - next CONSTRAINT2 if $c2->equals($c1, $case_insensitive); - } - if ( $c2->type eq UNIQUE ) { - push @diffs_constraint_drops, "ALTER TABLE $t1_name DROP INDEX ". - $c2->name.";"; - } elsif ( $target_db =~ /SQLServer/ ) { - push @diffs_constraint_drops, "ALTER TABLE $t1_name DROP ".$c2->name.";"; - } else { - push @diffs_constraint_drops, "ALTER TABLE $t1_name DROP ".$c2->type. - ($c2->type eq FOREIGN_KEY ? " ".$c2->name : '').";"; - } - } - - push @diffs, @diffs_index_drops, @diffs_constraint_drops, - @diffs_table_options, @diffs_table_adds, - @diffs_table_changes, @diffs_index_creates; + for my $c2 ( $t2->get_constraints ) { + next if $checked_constraints{$c2}; + for my $c1 ( $t1->get_constraints ) { + next CONSTRAINT2 if $c2->equals($c1, $case_insensitive); + } + if ( $c2->type eq UNIQUE ) { + push @diffs_constraint_drops, "ALTER TABLE $t1_name DROP INDEX ". + $c2->name.";"; + } elsif ( $target_db =~ /SQLServer/ ) { + push @diffs_constraint_drops, "ALTER TABLE $t1_name DROP ".$c2->name.";"; + } else { + push @diffs_constraint_drops, "ALTER TABLE $t1_name DROP ".$c2->type. + ($c2->type eq FOREIGN_KEY ? " ".$c2->name : '').";"; + } + } + + push @diffs, @diffs_index_drops, @diffs_constraint_drops, + @diffs_table_options, @diffs_table_adds, + @diffs_table_changes, @diffs_index_creates; } for my $t2 ( $target_schema->get_tables ) { @@ -427,12 +427,12 @@ for my $t2 ( $target_schema->get_tables ) { my $t1 = $source_schema->get_table( $t2_name, $target_db =~ /SQLServer/ ); unless ( $t1 ) { - if ( $target_db =~ /SQLServer/ ) { - for my $constraint ( $t2->get_constraints ) { - next if $constraint->type eq PRIMARY_KEY; - push @diffs, "ALTER TABLE $t2_name DROP ".$constraint->name.";"; - } - } + if ( $target_db =~ /SQLServer/ ) { + for my $constraint ( $t2->get_constraints ) { + next if $constraint->type eq PRIMARY_KEY; + push @diffs, "ALTER TABLE $t2_name DROP ".$constraint->name.";"; + } + } push @diffs_at_end, "DROP TABLE $t2_name;"; next; } @@ -441,7 +441,7 @@ for my $t2 ( $target_schema->get_tables ) { my $f2_name = $t2_field->name; my $t1_field = $t1->get_field( $f2_name ); unless ( $t1_field ) { - my $modifier = $target_db =~ /SQLServer/ ? "COLUMN " : ''; + my $modifier = $target_db =~ /SQLServer/ ? "COLUMN " : ''; push @diffs, "ALTER TABLE $t2_name DROP $modifier$f2_name;"; } } @@ -462,7 +462,7 @@ if ( @diffs ) { } if ( @diffs ) { - print join( "\n", + print join( "\n", "-- Convert schema '$s2_name' to '$s1_name':\n", @diffs, "\n" ); exit(1); @@ -472,74 +472,74 @@ else { } sub constraint_to_string { - my $c = shift; - my $schema = shift or die "No schema given"; - my @fields = $c->field_names or return ''; - - if ( $c->type eq PRIMARY_KEY ) { - if ( $target_db =~ /Oracle/ ) { - return (defined $c->name ? 'CONSTRAINT '.$c->name.' ' : '') . - 'PRIMARY KEY (' . join(', ', @fields). ')'; - } else { - return 'PRIMARY KEY (' . join(', ', @fields). ')'; - } - } - elsif ( $c->type eq UNIQUE ) { - if ( $target_db =~ /Oracle/ ) { - return (defined $c->name ? 'CONSTRAINT '.$c->name.' ' : '') . - 'UNIQUE (' . join(', ', @fields). ')'; - } else { - return 'UNIQUE '. - (defined $c->name ? $c->name.' ' : ''). - '(' . join(', ', @fields). ')'; - } - } - elsif ( $c->type eq FOREIGN_KEY ) { - my $def = join(' ', - map { $_ || () } 'CONSTRAINT', $c->name, 'FOREIGN KEY' - ); - - $def .= ' (' . join( ', ', @fields ) . ')'; - - $def .= ' REFERENCES ' . $c->reference_table; - - my @rfields = map { $_ || () } $c->reference_fields; - unless ( @rfields ) { - my $rtable_name = $c->reference_table; - if ( my $ref_table = $schema->get_table( $rtable_name ) ) { - push @rfields, $ref_table->primary_key; - } - else { - warn "Can't find reference table '$rtable_name' " . - "in schema\n"; - } - } - - if ( @rfields ) { - $def .= ' (' . join( ', ', @rfields ) . ')'; - } - else { - warn "FK constraint on " . 'some table' . '.' . - join('', @fields) . " has no reference fields\n"; - } - - if ( $c->match_type ) { - $def .= ' MATCH ' . - ( $c->match_type =~ /full/i ) ? 'FULL' : 'PARTIAL'; - } - - if ( $c->on_delete ) { - $def .= ' ON DELETE '.join( ' ', $c->on_delete ); - } - - if ( $c->on_update ) { - $def .= ' ON UPDATE '.join( ' ', $c->on_update ); - } - - return $def; - } + my $c = shift; + my $schema = shift or die "No schema given"; + my @fields = $c->field_names or return ''; + + if ( $c->type eq PRIMARY_KEY ) { + if ( $target_db =~ /Oracle/ ) { + return (defined $c->name ? 'CONSTRAINT '.$c->name.' ' : '') . + 'PRIMARY KEY (' . join(', ', @fields). ')'; + } else { + return 'PRIMARY KEY (' . join(', ', @fields). ')'; + } + } + elsif ( $c->type eq UNIQUE ) { + if ( $target_db =~ /Oracle/ ) { + return (defined $c->name ? 'CONSTRAINT '.$c->name.' ' : '') . + 'UNIQUE (' . join(', ', @fields). ')'; + } else { + return 'UNIQUE '. + (defined $c->name ? $c->name.' ' : ''). + '(' . join(', ', @fields). ')'; + } + } + elsif ( $c->type eq FOREIGN_KEY ) { + my $def = join(' ', + map { $_ || () } 'CONSTRAINT', $c->name, 'FOREIGN KEY' + ); + + $def .= ' (' . join( ', ', @fields ) . ')'; + + $def .= ' REFERENCES ' . $c->reference_table; + + my @rfields = map { $_ || () } $c->reference_fields; + unless ( @rfields ) { + my $rtable_name = $c->reference_table; + if ( my $ref_table = $schema->get_table( $rtable_name ) ) { + push @rfields, $ref_table->primary_key; + } + else { + warn "Can't find reference table '$rtable_name' " . + "in schema\n"; + } + } + + if ( @rfields ) { + $def .= ' (' . join( ', ', @rfields ) . ')'; + } + else { + warn "FK constraint on " . 'some table' . '.' . + join('', @fields) . " has no reference fields\n"; + } + + if ( $c->match_type ) { + $def .= ' MATCH ' . + ( $c->match_type =~ /full/i ) ? 'FULL' : 'PARTIAL'; + } + + if ( $c->on_delete ) { + $def .= ' ON DELETE '.join( ' ', $c->on_delete ); + } + + if ( $c->on_update ) { + $def .= ' ON UPDATE '.join( ' ', $c->on_update ); + } + + return $def; + } } - + # ------------------------------------------------------------------- # Bring out number weight & measure in a year of dearth. # William Blake diff --git a/script/sqlt-graph b/script/sqlt-graph index b92129c..6238026 100755 --- a/script/sqlt-graph +++ b/script/sqlt-graph @@ -18,7 +18,7 @@ # 02111-1307 USA # ------------------------------------------------------------------- -=head1 NAME +=head1 NAME sqlt-graph - Automatically create a graph from a database schema @@ -30,9 +30,9 @@ sqlt-graph - Automatically create a graph from a database schema -l|--layout Layout schema for GraphViz ("dot," "neato," "twopi"; default "dot") - -n|--node-shape Shape of the nodes ("record," "plaintext," - "ellipse," "circle," "egg," "triangle," "box," - "diamond," "trapezium," "parallelogram," "house," + -n|--node-shape Shape of the nodes ("record," "plaintext," + "ellipse," "circle," "egg," "triangle," "box," + "diamond," "trapezium," "parallelogram," "house," "hexagon," "octagon," default "record") -o|--output Output file name (default STDOUT) -t|--output-type Output file type ("canon", "text," "ps," "hpgl," @@ -44,13 +44,13 @@ sqlt-graph - Automatically create a graph from a database schema --no-fields Don't show field names --height Image height (in inches, default "11", set to "0" to undefine) - --width Image width (in inches, default "8.5", + --width Image width (in inches, default "8.5", set to "0" to undefine) --fontsize custom font size for node and edge labels - --fontname name of custom font (or full path to font file) for + --fontname name of custom font (or full path to font file) for node, edge, and graph labels --nodeattr attribute name and value (in key=val syntax) for - nodes; this option may be repeated to specify + nodes; this option may be repeated to specify multiple node attributes --edgeattr same as --nodeattr, but for edge attributes --graphattr same as --nodeattr, but for graph attributes @@ -60,7 +60,7 @@ sqlt-graph - Automatically create a graph from a database schema --show-sizes Show column sizes for VARCHAR and CHAR fields --show-constraints Show list of constraints for each field -s|--skip Fields to skip in natural joins - --skip-tables Comma-separated list of table names to exclude + --skip-tables Comma-separated list of table names to exclude --skip-tables-like Comma-separated list of regexen to exclude tables --debug Print debugging information @@ -88,8 +88,8 @@ If the schema defines foreign keys, then the graph produced will be directed showing the direction of the relationship. If the foreign keys are intuited via natural joins, the graph will be undirected. -Clustering of tables allows you to group and box tables according to -function or domain or whatever criteria you choose. The syntax for +Clustering of tables allows you to group and box tables according to +function or domain or whatever criteria you choose. The syntax for clustering tables is: cluster1=table1,table2;cluster2=table3,table4 @@ -112,8 +112,8 @@ $VERSION = '1.59'; # # Get arguments. # -my ( - $layout, $node_shape, $out_file, $output_type, $db_driver, $add_color, +my ( + $layout, $node_shape, $out_file, $output_type, $db_driver, $add_color, $natural_join, $join_pk_only, $skip_fields, $show_datatypes, $show_sizes, $show_constraints, $debug, $help, $height, $width, $no_fields, $fontsize, $fontname, $skip_tables, $skip_tables_like, @@ -158,7 +158,7 @@ pod2usage(1) if $help; pod2usage( -message => "No db driver specified" ) unless $db_driver; pod2usage( -message => 'No input file' ) unless @files; -my $translator = SQL::Translator->new( +my $translator = SQL::Translator->new( from => $db_driver, to => 'GraphViz', debug => $debug || 0, diff --git a/script/sqlt.cgi b/script/sqlt.cgi index 658e5ab..edef31d 100755 --- a/script/sqlt.cgi +++ b/script/sqlt.cgi @@ -25,7 +25,7 @@ sqlt.cgi - CGI front-end for SQL::Translator =head1 DESCRIPTION Place this script in your "cgi-bin" directory and point your browser -to it. This script is meant to be a simple graphical interface to +to it. This script is meant to be a simple graphical interface to all the parsers and producers of SQL::Translator. =cut @@ -58,18 +58,18 @@ eval { my $output_type = $producer eq 'Diagram' ? $q->param('diagram_output_type') : $producer eq 'GraphViz' - ? $q->param('graphviz_output_type') + ? $q->param('graphviz_output_type') : '' ; - my $t = SQL::Translator->new( + my $t = SQL::Translator->new( from => $q->param('parser'), producer_args => { add_drop_table => $q->param('add_drop_table'), output_type => $output_type, title => $q->param('title') || 'Schema', - natural_join => $q->param('natural_join') eq 'no' ? 0 : 1, - join_pk_only => $q->param('natural_join') eq 'pk_only' + natural_join => $q->param('natural_join') eq 'no' ? 0 : 1, + join_pk_only => $q->param('natural_join') eq 'pk_only' ? 1 : 0, add_color => $q->param('add_color'), skip_fields => $q->param('skip_fields'), @@ -136,41 +136,41 @@ sub show_form { my $q = shift; my $title = 'SQL::Translator'; - print $q->header, + print $q->header, $q->start_html( -title => $title ), $q->h1( qq[$title] ), $q->start_form(-enctype => 'multipart/form-data'), $q->table( { -border => 1 }, - $q->Tr( + $q->Tr( $q->td( [ 'Upload your schema file:', $q->filefield( -name => 'schema_file'), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Or paste your schema here:', - $q->textarea( - -name => 'schema', - -rows => 5, + $q->textarea( + -name => 'schema', + -rows => 5, -columns => 60, ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Parser:', $q->radio_group( -name => 'parser', - -values => [ qw( MySQL PostgreSQL Oracle - Sybase Excel XML-SQLFairy xSV + -values => [ qw( MySQL PostgreSQL Oracle + Sybase Excel XML-SQLFairy xSV ) ], -default => 'MySQL', -rows => 3, ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Producer:', $q->radio_group( @@ -184,103 +184,103 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( { -colspan => 2, -align => 'center' }, - $q->submit( - -name => 'submit', + $q->submit( + -name => 'submit', -value => 'Submit', ) ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, - 'General Options:' + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + 'General Options:' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Validate Schema:', $q->radio_group( -name => 'validate', -values => [ 1, 0 ], - -labels => { - 1 => 'Yes', - 0 => 'No' + -labels => { + 1 => 'Yes', + 0 => 'No' }, -default => 0, -rows => 2, ), ] ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, - 'DB Producer Options:' + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + 'DB Producer Options:' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Add "DROP TABLE" statements:', $q->radio_group( -name => 'add_drop_table', -values => [ 1, 0 ], - -labels => { - 1 => 'Yes', - 0 => 'No' + -labels => { + 1 => 'Yes', + 0 => 'No' }, -default => 0, -rows => 2, ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Include comments:', $q->radio_group( -name => 'comments', -values => [ 1, 0 ], - -labels => { - 1 => 'Yes', - 0 => 'No' + -labels => { + 1 => 'Yes', + 0 => 'No' }, -default => 1, -rows => 2, ), ] ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, - 'HTML/POD/Diagram Producer Options:' + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + 'HTML/POD/Diagram Producer Options:' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Title:', $q->textfield('title'), ] ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, - 'TTSchema Producer Options:' + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + 'TTSchema Producer Options:' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Template:', $q->filefield( -name => 'template'), ] ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, 'Graphical Producer Options' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Perform Natural Joins:', $q->radio_group( @@ -296,7 +296,7 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Skip These Fields in Natural Joins:', $q->textarea( @@ -306,7 +306,7 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Show Only Foreign Keys:', $q->radio_group( @@ -321,22 +321,22 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Add Color:', $q->radio_group( -name => 'add_color', -values => [ 1, 0 ], - -labels => { - 1 => 'Yes', - 0 => 'No' + -labels => { + 1 => 'Yes', + 0 => 'No' }, -default => 1, -rows => 2, ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Show Field Names:', $q->radio_group( @@ -351,13 +351,13 @@ sub show_form { ), ] ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, 'Diagram Producer Options' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Output Type:', $q->radio_group( @@ -368,7 +368,7 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Font Size:', $q->radio_group( @@ -379,19 +379,19 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Number of Columns:', $q->textfield('no_columns'), ] ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, 'GraphViz Producer Options' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Output Type:', $q->radio_group( @@ -405,7 +405,7 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Layout:', $q->radio_group( @@ -416,87 +416,87 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Node Shape:', $q->radio_group( -name => 'node_shape', - -values => [ qw( record plaintext ellipse - circle egg triangle box diamond trapezium - parallelogram house hexagon octagon + -values => [ qw( record plaintext ellipse + circle egg triangle box diamond trapezium + parallelogram house hexagon octagon ) ], -default => 'record', -rows => 4, ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Height:', $q->textfield( -name => 'height' ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Width:', $q->textfield( -name => 'width' ), ] ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, - 'XML Producer Options:' + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + 'XML Producer Options:' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Use attributes for values:', $q->radio_group( -name => 'attrib-values', -values => [ 1, 0 ], - -labels => { - 1 => 'Yes', - 0 => 'No' + -labels => { + 1 => 'Yes', + 0 => 'No' }, -default => 0, -rows => 2, ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Emit Empty Tags:', $q->radio_group( -name => 'emit-empty-tags', -values => [ 1, 0 ], - -labels => { - 1 => 'Yes', - 0 => 'No' + -labels => { + 1 => 'Yes', + 0 => 'No' }, -default => 0, -rows => 2, ), ] ), ), - $q->Tr( - $q->th( - { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, + $q->Tr( + $q->th( + { align => 'left', bgcolor => 'lightgrey', colspan => 2 }, 'xSV Parser Options' ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Field Separator:', $q->textfield( -name => 'fs' ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Record Separator:', $q->textfield( -name => 'rs' ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Trim Whitespace Around Fields:', $q->radio_group( @@ -511,7 +511,7 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( [ 'Scan Fields for Data Type:', $q->radio_group( @@ -526,11 +526,11 @@ sub show_form { ), ] ), ), - $q->Tr( + $q->Tr( $q->td( { -colspan => 2, -align => 'center' }, - $q->submit( - -name => 'submit', + $q->submit( + -name => 'submit', -value => 'Submit', ) ), diff --git a/t/02mysql-parser.t b/t/02mysql-parser.t index 4dd921c..2b4bfa1 100644 --- a/t/02mysql-parser.t +++ b/t/02mysql-parser.t @@ -69,10 +69,10 @@ BEGIN { { my $tr = SQL::Translator->new; - my $data = parse($tr, + my $data = parse($tr, q[ CREATE TABLE `check` ( - check_id int(7) unsigned zerofill NOT NULL default '0000000' + check_id int(7) unsigned zerofill NOT NULL default '0000000' auto_increment primary key, successful date NOT NULL default '0000-00-00', unsuccessful date default '0000-00-00', @@ -92,7 +92,7 @@ BEGIN { ) TYPE=MyISAM PACK_KEYS=1; ] ); - + my $schema = $tr->schema; is( $schema->is_valid, 1, 'Schema is valid' ); my @tables = $schema->get_tables; @@ -240,7 +240,7 @@ BEGIN { { my $tr = SQL::Translator->new; - my $data = parse($tr, + my $data = parse($tr, q[ CREATE TABLE orders ( order_id integer NOT NULL auto_increment, @@ -307,13 +307,13 @@ BEGIN { is( $f2->default_value, undef, 'Default value is undefined' ); my $f3 = shift @fields; - is( $f3->name, 'billing_address_id', + is( $f3->name, 'billing_address_id', 'Third field name is "billing_address_id"' ); is( $f3->data_type, 'int', 'Type is "int"' ); is( $f3->size, 11, 'Size is "11"' ); my $f4 = shift @fields; - is( $f4->name, 'shipping_address_id', + is( $f4->name, 'shipping_address_id', 'Fourth field name is "shipping_address_id"' ); is( $f4->data_type, 'int', 'Type is "int"' ); is( $f4->size, 11, 'Size is "11"' ); @@ -363,17 +363,17 @@ BEGIN { my $i2 = shift @indices; is( $i2->type, NORMAL, 'Second index is normal' ); - is( join(',', $i2->fields), 'billing_address_id', + is( join(',', $i2->fields), 'billing_address_id', 'Index is on "billing_address_id"' ); my $i3 = shift @indices; is( $i3->type, NORMAL, 'Third index is normal' ); - is( join(',', $i3->fields), 'shipping_address_id', + is( join(',', $i3->fields), 'shipping_address_id', 'Index is on "shipping_address_id"' ); my $i4 = shift @indices; is( $i4->type, NORMAL, 'Third index is normal' ); - is( join(',', $i4->fields), 'member_id,store_id', + is( join(',', $i4->fields), 'member_id,store_id', 'Index is on "member_id,store_id"' ); my @constraints = $t1->get_constraints; @@ -391,25 +391,25 @@ BEGIN { my $c3 = shift @constraints; is( $c3->type, FOREIGN_KEY, 'Constraint is a FK' ); - is( join(',', $c3->fields), 'billing_address_id', + is( join(',', $c3->fields), 'billing_address_id', 'Constraint is on "billing_address_id"' ); is( $c3->reference_table, 'address', 'To table "address"' ); - is( join(',', $c3->reference_fields), 'address_id', + is( join(',', $c3->reference_fields), 'address_id', 'To field "address_id"' ); my $c4 = shift @constraints; is( $c4->type, FOREIGN_KEY, 'Constraint is a FK' ); - is( join(',', $c4->fields), 'shipping_address_id', + is( join(',', $c4->fields), 'shipping_address_id', 'Constraint is on "shipping_address_id"' ); is( $c4->reference_table, 'address', 'To table "address"' ); - is( join(',', $c4->reference_fields), 'address_id', + is( join(',', $c4->reference_fields), 'address_id', 'To field "address_id"' ); my $c5 = shift @constraints; is( $c5->type, FOREIGN_KEY, 'Constraint is a FK' ); is( join(',', $c5->fields), 'store_id', 'Constraint is on "store_id"' ); is( $c5->reference_table, 'store', 'To table "store"' ); - is( join(',', map { $_ || '' } $c5->reference_fields), '', + is( join(',', map { $_ || '' } $c5->reference_fields), '', 'No reference fields defined' ); my $t2 = shift @tables; @@ -427,7 +427,7 @@ BEGIN { # { my $tr = SQL::Translator->new; - my $data = parse($tr, + my $data = parse($tr, q[ USE database_name; @@ -500,98 +500,98 @@ BEGIN { # { my $tr = SQL::Translator->new(parser_args => {mysql_parser_version => 50003}); - my $data = parse($tr, + my $data = parse($tr, q[ - DELIMITER ;; + DELIMITER ;; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;; - /*!50003 CREATE */ /*!50017 DEFINER=`cmdomain`@`localhost` */ - /*!50003 TRIGGER `acl_entry_insert` BEFORE INSERT ON `acl_entry` - FOR EACH ROW SET NEW.dateCreated = CONVERT_TZ(SYSDATE(),'SYSTEM','+0:00'), - NEW.dateModified = CONVERT_TZ(SYSDATE(),'SYSTEM','+0:00') */;; + /*!50003 CREATE */ /*!50017 DEFINER=`cmdomain`@`localhost` */ + /*!50003 TRIGGER `acl_entry_insert` BEFORE INSERT ON `acl_entry` + FOR EACH ROW SET NEW.dateCreated = CONVERT_TZ(SYSDATE(),'SYSTEM','+0:00'), + NEW.dateModified = CONVERT_TZ(SYSDATE(),'SYSTEM','+0:00') */;; - DELIMITER ; + DELIMITER ; CREATE TABLE one ( `op` varchar(255) character set latin1 collate latin1_bin default NULL, `last_modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, ) TYPE=INNODB DEFAULT CHARSET=latin1; - /*!50001 CREATE ALGORITHM=UNDEFINED */ - /*!50013 DEFINER=`cmdomain`@`localhost` SQL SECURITY DEFINER */ - /*! VIEW `vs_asset` AS - select `a`.`asset_id` AS `asset_id`,`a`.`fq_name` AS `fq_name`, - `cfgmgmt_mig`.`ap_extract_folder`(`a`.`fq_name`) AS `folder_name`, - `cfgmgmt_mig`.`ap_extract_asset`(`a`.`fq_name`) AS `asset_name`, - `a`.`annotation` AS `annotation`,`a`.`asset_type` AS `asset_type`, - `a`.`foreign_asset_id` AS `foreign_asset_id`, - `a`.`foreign_asset_id2` AS `foreign_asset_id2`,`a`.`dateCreated` AS `date_created`, - `a`.`dateModified` AS `date_modified`,`a`.`container_id` AS `container_id`, - `a`.`creator_id` AS `creator_id`,`a`.`modifier_id` AS `modifier_id`, - `m`.`user_id` AS `user_access` - from (`asset` `a` join `M_ACCESS_CONTROL` `m` on((`a`.`acl_id` = `m`.`acl_id`))) */; - DELIMITER ;; - /*!50001 CREATE */ - /*! VIEW `vs_asset2` AS - select `a`.`asset_id` AS `asset_id`,`a`.`fq_name` AS `fq_name`, - `cfgmgmt_mig`.`ap_extract_folder`(`a`.`fq_name`) AS `folder_name`, - `cfgmgmt_mig`.`ap_extract_asset`(`a`.`fq_name`) AS `asset_name`, - `a`.`annotation` AS `annotation`,`a`.`asset_type` AS `asset_type`, - `a`.`foreign_asset_id` AS `foreign_asset_id`, - `a`.`foreign_asset_id2` AS `foreign_asset_id2`,`a`.`dateCreated` AS `date_created`, - `a`.`dateModified` AS `date_modified`,`a`.`container_id` AS `container_id`, - `a`.`creator_id` AS `creator_id`,`a`.`modifier_id` AS `modifier_id`, - `m`.`user_id` AS `user_access` - from (`asset` `a` join `M_ACCESS_CONTROL` `m` on((`a`.`acl_id` = `m`.`acl_id`))) */; - DELIMITER ;; - /*!50001 CREATE OR REPLACE */ - /*! VIEW `vs_asset3` AS - select `a`.`asset_id` AS `asset_id`,`a`.`fq_name` AS `fq_name`, - `cfgmgmt_mig`.`ap_extract_folder`(`a`.`fq_name`) AS `folder_name`, - `cfgmgmt_mig`.`ap_extract_asset`(`a`.`fq_name`) AS `asset_name`, - `a`.`annotation` AS `annotation`,`a`.`asset_type` AS `asset_type`, - `a`.`foreign_asset_id` AS `foreign_asset_id`, - `a`.`foreign_asset_id2` AS `foreign_asset_id2`,`a`.`dateCreated` AS `date_created`, - `a`.`dateModified` AS `date_modified`,`a`.`container_id` AS `container_id`, - `a`.`creator_id` AS `creator_id`,`a`.`modifier_id` AS `modifier_id`, - `m`.`user_id` AS `user_access` - from (`asset` `a` join `M_ACCESS_CONTROL` `m` on((`a`.`acl_id` = `m`.`acl_id`))) */; - DELIMITER ;; - /*!50003 CREATE*/ /*!50020 DEFINER=`cmdomain`@`localhost`*/ /*!50003 FUNCTION `ap_from_millitime_nullable`( millis_since_1970 BIGINT ) RETURNS timestamp - DETERMINISTIC - BEGIN - DECLARE rval TIMESTAMP; - IF ( millis_since_1970 = 0 ) - THEN - SET rval = NULL; - ELSE - SET rval = FROM_UNIXTIME( millis_since_1970 / 1000 ); - END IF; - RETURN rval; - END */;; - /*!50003 CREATE*/ /*!50020 DEFINER=`cmdomain`@`localhost`*/ /*!50003 PROCEDURE `sp_update_security_acl`(IN t_acl_id INTEGER) - BEGIN - DECLARE hasMoreRows BOOL DEFAULT TRUE; - DECLARE t_group_id INT; - DECLARE t_user_id INT ; - DECLARE t_user_name VARCHAR (512) ; - DECLARE t_message VARCHAR (512) ; - - DROP TABLE IF EXISTS group_acl; - DROP TABLE IF EXISTS user_group; - DELETE FROM M_ACCESS_CONTROL WHERE acl_id = t_acl_id; - - CREATE TEMPORARY TABLE group_acl SELECT DISTINCT p.id group_id, d.acl_id acl_id - FROM asset d, acl_entry e, alterpoint_principal p - WHERE d.acl_id = e.acl - AND p.id = e.principal AND d.acl_id = t_acl_id; - - CREATE TEMPORARY TABLE user_group SELECT a.id user_id, a.name user_name, c.id group_id - FROM alterpoint_principal a, groups_for_user b, alterpoint_principal c - WHERE a.id = b.user_ref AND b.elt = c.id; - - INSERT INTO M_ACCESS_CONTROL SELECT DISTINCT group_acl.group_id, group_acl.acl_id, user_group.user_id, user_group.user_name - FROM group_acl, user_group - WHERE group_acl.group_id = user_group.group_id ; - END */;; + /*!50001 CREATE ALGORITHM=UNDEFINED */ + /*!50013 DEFINER=`cmdomain`@`localhost` SQL SECURITY DEFINER */ + /*! VIEW `vs_asset` AS + select `a`.`asset_id` AS `asset_id`,`a`.`fq_name` AS `fq_name`, + `cfgmgmt_mig`.`ap_extract_folder`(`a`.`fq_name`) AS `folder_name`, + `cfgmgmt_mig`.`ap_extract_asset`(`a`.`fq_name`) AS `asset_name`, + `a`.`annotation` AS `annotation`,`a`.`asset_type` AS `asset_type`, + `a`.`foreign_asset_id` AS `foreign_asset_id`, + `a`.`foreign_asset_id2` AS `foreign_asset_id2`,`a`.`dateCreated` AS `date_created`, + `a`.`dateModified` AS `date_modified`,`a`.`container_id` AS `container_id`, + `a`.`creator_id` AS `creator_id`,`a`.`modifier_id` AS `modifier_id`, + `m`.`user_id` AS `user_access` + from (`asset` `a` join `M_ACCESS_CONTROL` `m` on((`a`.`acl_id` = `m`.`acl_id`))) */; + DELIMITER ;; + /*!50001 CREATE */ + /*! VIEW `vs_asset2` AS + select `a`.`asset_id` AS `asset_id`,`a`.`fq_name` AS `fq_name`, + `cfgmgmt_mig`.`ap_extract_folder`(`a`.`fq_name`) AS `folder_name`, + `cfgmgmt_mig`.`ap_extract_asset`(`a`.`fq_name`) AS `asset_name`, + `a`.`annotation` AS `annotation`,`a`.`asset_type` AS `asset_type`, + `a`.`foreign_asset_id` AS `foreign_asset_id`, + `a`.`foreign_asset_id2` AS `foreign_asset_id2`,`a`.`dateCreated` AS `date_created`, + `a`.`dateModified` AS `date_modified`,`a`.`container_id` AS `container_id`, + `a`.`creator_id` AS `creator_id`,`a`.`modifier_id` AS `modifier_id`, + `m`.`user_id` AS `user_access` + from (`asset` `a` join `M_ACCESS_CONTROL` `m` on((`a`.`acl_id` = `m`.`acl_id`))) */; + DELIMITER ;; + /*!50001 CREATE OR REPLACE */ + /*! VIEW `vs_asset3` AS + select `a`.`asset_id` AS `asset_id`,`a`.`fq_name` AS `fq_name`, + `cfgmgmt_mig`.`ap_extract_folder`(`a`.`fq_name`) AS `folder_name`, + `cfgmgmt_mig`.`ap_extract_asset`(`a`.`fq_name`) AS `asset_name`, + `a`.`annotation` AS `annotation`,`a`.`asset_type` AS `asset_type`, + `a`.`foreign_asset_id` AS `foreign_asset_id`, + `a`.`foreign_asset_id2` AS `foreign_asset_id2`,`a`.`dateCreated` AS `date_created`, + `a`.`dateModified` AS `date_modified`,`a`.`container_id` AS `container_id`, + `a`.`creator_id` AS `creator_id`,`a`.`modifier_id` AS `modifier_id`, + `m`.`user_id` AS `user_access` + from (`asset` `a` join `M_ACCESS_CONTROL` `m` on((`a`.`acl_id` = `m`.`acl_id`))) */; + DELIMITER ;; + /*!50003 CREATE*/ /*!50020 DEFINER=`cmdomain`@`localhost`*/ /*!50003 FUNCTION `ap_from_millitime_nullable`( millis_since_1970 BIGINT ) RETURNS timestamp + DETERMINISTIC + BEGIN + DECLARE rval TIMESTAMP; + IF ( millis_since_1970 = 0 ) + THEN + SET rval = NULL; + ELSE + SET rval = FROM_UNIXTIME( millis_since_1970 / 1000 ); + END IF; + RETURN rval; + END */;; + /*!50003 CREATE*/ /*!50020 DEFINER=`cmdomain`@`localhost`*/ /*!50003 PROCEDURE `sp_update_security_acl`(IN t_acl_id INTEGER) + BEGIN + DECLARE hasMoreRows BOOL DEFAULT TRUE; + DECLARE t_group_id INT; + DECLARE t_user_id INT ; + DECLARE t_user_name VARCHAR (512) ; + DECLARE t_message VARCHAR (512) ; + + DROP TABLE IF EXISTS group_acl; + DROP TABLE IF EXISTS user_group; + DELETE FROM M_ACCESS_CONTROL WHERE acl_id = t_acl_id; + + CREATE TEMPORARY TABLE group_acl SELECT DISTINCT p.id group_id, d.acl_id acl_id + FROM asset d, acl_entry e, alterpoint_principal p + WHERE d.acl_id = e.acl + AND p.id = e.principal AND d.acl_id = t_acl_id; + + CREATE TEMPORARY TABLE user_group SELECT a.id user_id, a.name user_name, c.id group_id + FROM alterpoint_principal a, groups_for_user b, alterpoint_principal c + WHERE a.id = b.user_ref AND b.elt = c.id; + + INSERT INTO M_ACCESS_CONTROL SELECT DISTINCT group_acl.group_id, group_acl.acl_id, user_group.user_id, user_group.user_name + FROM group_acl, user_group + WHERE group_acl.group_id = user_group.group_id ; + END */;; ] ) or die $tr->error; @@ -606,18 +606,18 @@ BEGIN { is(scalar @fields, 2, 'Right number of fields (2) on table one'); my $tableTypeFound = 0; my $charsetFound = 0; - for my $t1_option_ref ( $table1->options ) { - my($key, $value) = %{$t1_option_ref}; - if ( $key eq 'TYPE' ) { - is($value, 'INNODB', 'Table has right table type option' ); - $tableTypeFound = 1; - } elsif ( $key eq 'CHARACTER SET' ) { - is($value, 'latin1', 'Table has right character set option' ); - $charsetFound = 1; - } - } - fail('Table did not have a type option') unless $tableTypeFound; - fail('Table did not have a character set option') unless $charsetFound; + for my $t1_option_ref ( $table1->options ) { + my($key, $value) = %{$t1_option_ref}; + if ( $key eq 'TYPE' ) { + is($value, 'INNODB', 'Table has right table type option' ); + $tableTypeFound = 1; + } elsif ( $key eq 'CHARACTER SET' ) { + is($value, 'latin1', 'Table has right character set option' ); + $charsetFound = 1; + } + } + fail('Table did not have a type option') unless $tableTypeFound; + fail('Table did not have a character set option') unless $charsetFound; my $t1f1 = shift @fields; is( $t1f1->data_type, 'varchar', 'Field is a varchar' ); @@ -632,7 +632,7 @@ BEGIN { is_deeply( $t1f2->default_value, \'CURRENT_TIMESTAMP', - 'Field has right default value' + 'Field has right default value' ); is( $t1f2->extra('on update'), 'CURRENT_TIMESTAMP', 'Field has right on update qualifier' ); @@ -651,19 +651,19 @@ BEGIN { is( scalar @procs, 2, 'Right number of procedures (2)' ); my $proc1 = shift @procs; is( $proc1->name, 'ap_from_millitime_nullable', 'Found "ap_from_millitime_nullable" procedure' ); - like($proc1->sql, qr/CREATE FUNCTION ap_from_millitime_nullable/, "Detected procedure ap_from_millitime_nullable"); + like($proc1->sql, qr/CREATE FUNCTION ap_from_millitime_nullable/, "Detected procedure ap_from_millitime_nullable"); my $proc2 = shift @procs; is( $proc2->name, 'sp_update_security_acl', 'Found "sp_update_security_acl" procedure' ); - like($proc2->sql, qr/CREATE PROCEDURE sp_update_security_acl/, "Detected procedure sp_update_security_acl"); + like($proc2->sql, qr/CREATE PROCEDURE sp_update_security_acl/, "Detected procedure sp_update_security_acl"); } # Tests for collate table option { my $tr = SQL::Translator->new(parser_args => {mysql_parser_version => 50003}); - my $data = parse($tr, + my $data = parse($tr, q[ CREATE TABLE test ( id int ) DEFAULT CHARACTER SET latin1 COLLATE latin1_bin; - ] ); + ] ); my $schema = $tr->schema; is( $schema->is_valid, 1, 'Schema is valid' ); @@ -862,7 +862,7 @@ ok ($@, 'Exception thrown on invalid version string'); is( $f2->is_primary_key, 0, 'Field is not PK' ); # this is more of a sanity test because the original sqlt regex for default looked for an escaped quote represented as \' - # however in mysql 5.x (and probably other previous versions) still actually outputs that as '' + # however in mysql 5.x (and probably other previous versions) still actually outputs that as '' is( $f3->name, 'user', 'Second field name is "user"' ); is( $f3->data_type, 'varchar', 'Type is "varchar"' ); is( $f3->size, 20, 'Size is "20"' ); diff --git a/t/05bgep-re.t b/t/05bgep-re.t index 1c55bc4..db38576 100644 --- a/t/05bgep-re.t +++ b/t/05bgep-re.t @@ -18,7 +18,7 @@ local $SIG{__WARN__} = sub { }; BEGIN { - maybe_plan(2, + maybe_plan(2, 'SQL::Translator::Parser::MySQL', 'SQL::Translator::Producer::XML::SQLFairy'); } @@ -42,7 +42,7 @@ SKIP: { require XML::Parser; }; if ($@) { - skip "Can't load XML::Parser" => 1; + skip "Can't load XML::Parser" => 1; } # Can't get XML::Parser::parsestring to do Useful Things diff --git a/t/08postgres-to-mysql.t b/t/08postgres-to-mysql.t index 8146c24..6db064a 100644 --- a/t/08postgres-to-mysql.t +++ b/t/08postgres-to-mysql.t @@ -8,14 +8,14 @@ use Data::Dumper; use Test::SQL::Translator qw(maybe_plan); BEGIN { - maybe_plan(1, + maybe_plan(1, 'SQL::Translator::Parser::MySQL', 'SQL::Translator::Producer::PostgreSQL'); } my $create = q| --- The cvterm module design is based on the ontology +-- The cvterm module design is based on the ontology -- ================================================ -- TABLE: cv @@ -48,7 +48,7 @@ create table cvterm ( ); create index cvterm_idx1 on cvterm (cv_id); -- the primary dbxref for this term. Other dbxrefs may be cvterm_dbxref --- The unique key on termname, termtype_id ensures that all terms are +-- The unique key on termname, termtype_id ensures that all terms are -- unique within a given cv @@ -63,7 +63,7 @@ COMMENT ON COLUMN cvterm.termdefinition IS 'A human-readable text definition'; COMMENT ON COLUMN cvterm.dbxref_id IS 'A human-readable text definition'; -COMMENT ON INDEX cvterm_c1 IS +COMMENT ON INDEX cvterm_c1 IS 'the OBO identifier is globally unique'; @@ -125,7 +125,7 @@ create table cvtermsynonym ( unique(cvterm_id, termsynonym) ); --- The table "cvterm_synonym" doesn't exist, so +-- The table "cvterm_synonym" doesn't exist, so -- creating an index on it screws things up! -- create index cvterm_synonym_idx1 on cvterm_synonym (cvterm_id); @@ -156,9 +156,9 @@ create table cvterm_geom ( cvterm_id int not null, foreign key (cvterm_id) references cvterm (cvterm_id), cvterm_geom geometry, - constraint "enforce_dims_cvterm_geom" CHECK ((st_ndims(cvterm_geom) = 2)), - constraint "enforce_srid_cvterm_geom" CHECK ((st_srid(cvterm_geom) = -1)), - constraint "enforce_geotype_cvterm_geom" CHECK ((geometrytype(cvterm_geom) = 'POINT'::text OR cvterm_geom IS NULL)), + constraint "enforce_dims_cvterm_geom" CHECK ((st_ndims(cvterm_geom) = 2)), + constraint "enforce_srid_cvterm_geom" CHECK ((st_srid(cvterm_geom) = -1)), + constraint "enforce_geotype_cvterm_geom" CHECK ((geometrytype(cvterm_geom) = 'POINT'::text OR cvterm_geom IS NULL)), unique(cvterm_id) ); diff --git a/t/09sqlt-diagram.t b/t/09sqlt-diagram.t index 157206f..e5bdd2a 100644 --- a/t/09sqlt-diagram.t +++ b/t/09sqlt-diagram.t @@ -24,9 +24,9 @@ my $test_data = catfile($Bin, @data); my $tmp = mktemp('sqlXXXXX'); -ok(-e $sqlt_diagram); +ok(-e $sqlt_diagram); my @cmd = ($^X, $sqlt_diagram, "-d", "MySQL", "-o", $tmp, $test_data); eval { system(@cmd); }; ok(!$@ && ($? == 0)); -ok(-e $tmp); +ok(-e $tmp); eval { unlink $tmp; }; diff --git a/t/10excel.t b/t/10excel.t index 2074792..5c2e148 100644 --- a/t/10excel.t +++ b/t/10excel.t @@ -10,7 +10,7 @@ BEGIN { maybe_plan(31, 'SQL::Translator::Parser::Excel'); SQL::Translator::Parser::Excel->import('parse'); } - + my $tr = SQL::Translator->new(parser => "Excel"); my $t = $tr->translate(filename => "t/data/Excel/t.xls"); my $schema = $tr->schema; @@ -45,7 +45,7 @@ is( $f3->is_primary_key, 0, 'Field is not PK' ); my $f4 = shift @fields; TODO: { eval { require Spreadsheet::ParseExcel }; - todo_skip "Bug in Spreadsheet::ParseExcel, http://rt.cpan.org/Public/Bug/Display.html?id=39892", 4 + todo_skip "Bug in Spreadsheet::ParseExcel, http://rt.cpan.org/Public/Bug/Display.html?id=39892", 4 if ( $Spreadsheet::ParseExcel::VERSION > 0.32 and $Spreadsheet::ParseExcel::VERSION < 0.41 ); is( $f4->name, 'math', 'Fourth field name is "math"' ); @@ -67,7 +67,7 @@ is( $f6->size, 10, 'Size is "10"' ); is( $f6->is_primary_key, 0, 'Field is not PK' ); my $f7 = shift @fields; -is( $f7->name, 'silly_field_with_random_characters', +is( $f7->name, 'silly_field_with_random_characters', 'Seventh field name is "silly_field_with_random_characters"' ); is( lc $f7->data_type, 'char', 'Data type is "CHAR"' ); is( $f7->size, 11, 'Size is "11"' ); diff --git a/t/13schema.t b/t/13schema.t index f0f873e..c85c3b6 100644 --- a/t/13schema.t +++ b/t/13schema.t @@ -14,7 +14,7 @@ require_ok( 'SQL::Translator::Schema' ); # # Schema # - my $schema = SQL::Translator::Schema->new( + my $schema = SQL::Translator::Schema->new( name => 'foo', database => 'MySQL', ); @@ -24,7 +24,7 @@ require_ok( 'SQL::Translator::Schema' ); is( $schema->name('bar'), 'bar', 'Schema name changed to "bar"' ); is( $schema->database, 'MySQL', 'Schema database is "MySQL"' ); - is( $schema->database('PostgreSQL'), 'PostgreSQL', + is( $schema->database('PostgreSQL'), 'PostgreSQL', 'Schema database changed to "PostgreSQL"' ); is( $schema->is_valid, undef, 'Schema not valid...' ); @@ -36,7 +36,7 @@ require_ok( 'SQL::Translator::Schema' ); my $foo_table = $schema->add_table(name => 'foo') or warn $schema->error; isa_ok( $foo_table, 'SQL::Translator::Schema::Table', 'Table "foo"' ); - my $bar_table = SQL::Translator::Schema::Table->new( name => 'bar' ) or + my $bar_table = SQL::Translator::Schema::Table->new( name => 'bar' ) or warn SQL::Translator::Schema::Table->error; $bar_table = $schema->add_table( $bar_table ); isa_ok( $bar_table, 'SQL::Translator::Schema::Table', 'Table "bar"' ); @@ -45,14 +45,14 @@ require_ok( 'SQL::Translator::Schema' ); $schema = $bar_table->schema( $schema ); isa_ok( $schema, 'SQL::Translator::Schema', 'Schema' ); - is( $bar_table->name('foo'), undef, + is( $bar_table->name('foo'), undef, q[Can't change name of table "bar" to "foo"...]); - like( $bar_table->error, qr/can't use table name/i, + like( $bar_table->error, qr/can't use table name/i, q[...because "foo" exists] ); my $redundant_table = $schema->add_table(name => 'foo'); is( $redundant_table, undef, qq[Can't create another "foo" table...] ); - like( $schema->error, qr/can't use table name/i, + like( $schema->error, qr/can't use table name/i, '... because "foo" exists' ); $redundant_table = $schema->add_table(name => ''); @@ -93,21 +93,21 @@ require_ok( 'SQL::Translator::Schema' ); # # New table with args # - my $person_table = $schema->add_table( - name => 'person', + my $person_table = $schema->add_table( + name => 'person', comments => 'foo', ); is( $person_table->name, 'person', 'Table name is "person"' ); is( $person_table->is_valid, undef, 'Table is not yet valid' ); is( $person_table->comments, 'foo', 'Comments = "foo"' ); - is( join(',', $person_table->comments('bar')), 'foo,bar', + is( join(',', $person_table->comments('bar')), 'foo,bar', 'Table comments = "foo,bar"' ); is( $person_table->comments, "foo\nbar", 'Table comments = "foo,bar"' ); # # Field default new # - my $f1 = $person_table->add_field(name => 'foo') or + my $f1 = $person_table->add_field(name => 'foo') or warn $person_table->error; isa_ok( $f1, 'SQL::Translator::Schema::Field', 'Field' ); is( $f1->name, 'foo', 'Field name is "foo"' ); @@ -134,7 +134,7 @@ require_ok( 'SQL::Translator::Schema' ); is( $f2->is_nullable('0'), 0, 'Field cannot be NULL' ); is( $f2->default_value(''), '', 'Field default is empty string' ); is( $f2->comments, 'foo', 'Field comment = "foo"' ); - is( join(',', $f2->comments('bar')), 'foo,bar', + is( join(',', $f2->comments('bar')), 'foo,bar', 'Field comment = "foo,bar"' ); is( $f2->comments, "foo\nbar", 'Field comment = "foo,bar"' ); @@ -146,7 +146,7 @@ require_ok( 'SQL::Translator::Schema' ); my $redundant_field = $person_table->add_field(name => 'f2'); is( $redundant_field, undef, qq[Didn't create another "f2" field...] ); - like( $person_table->error, qr/can't use field/i, + like( $person_table->error, qr/can't use field/i, '... because it exists' ); $redundant_field = $person_table->add_field(name => ''); @@ -217,7 +217,7 @@ require_ok( 'SQL::Translator::Schema' ); my @indices = $person_table->get_indices; is( scalar @indices, 0, 'No indices' ); like( $person_table->error, qr/no indices/i, 'Error for no indices' ); - my $index1 = $person_table->add_index( name => "foo" ) + my $index1 = $person_table->add_index( name => "foo" ) or warn $person_table->error; isa_ok( $index1, 'SQL::Translator::Schema::Index', 'Index' ); is( $index1->name, 'foo', 'Index name is "foo"' ); @@ -225,20 +225,20 @@ require_ok( 'SQL::Translator::Schema' ); is( $index1->is_valid, undef, 'Index name is not valid...' ); like( $index1->error, qr/no fields/i, '...because it has no fields' ); - is( join(':', $index1->fields('foo,bar')), 'foo:bar', + is( join(':', $index1->fields('foo,bar')), 'foo:bar', 'Index accepts fields'); is( $index1->is_valid, undef, 'Index name is not valid...' ); - like( $index1->error, qr/does not exist in table/i, + like( $index1->error, qr/does not exist in table/i, '...because it used fields not in the table' ); - is( join(':', $index1->fields(qw[foo age])), 'foo:age', + is( join(':', $index1->fields(qw[foo age])), 'foo:age', 'Index accepts fields'); is( $index1->is_valid, 1, 'Index name is now valid' ); is( $index1->type, NORMAL, 'Index type is "normal"' ); - my $index2 = SQL::Translator::Schema::Index->new( name => "bar" ) + my $index2 = SQL::Translator::Schema::Index->new( name => "bar" ) or warn SQL::Translator::Schema::Index->error; $index2 = $person_table->add_index( $index2 ); isa_ok( $index2, 'SQL::Translator::Schema::Index', 'Index' ); @@ -268,9 +268,9 @@ require_ok( 'SQL::Translator::Schema' ); # my @constraints = $person_table->get_constraints; is( scalar @constraints, 0, 'No constraints' ); - like( $person_table->error, qr/no constraints/i, + like( $person_table->error, qr/no constraints/i, 'Error for no constraints' ); - my $constraint1 = $person_table->add_constraint( name => 'foo' ) + my $constraint1 = $person_table->add_constraint( name => 'foo' ) or warn $person_table->error; isa_ok( $constraint1, 'SQL::Translator::Schema::Constraint', 'Constraint' ); is( $constraint1->name, 'foo', 'Constraint name is "foo"' ); @@ -304,11 +304,11 @@ require_ok( 'SQL::Translator::Schema' ); is( $fields, 'age,name', 'Constraint field_names = "age,name"' ); is( $constraint1->match_type, '', 'Constraint match type is empty' ); - is( $constraint1->match_type('foo'), undef, + is( $constraint1->match_type('foo'), undef, 'Constraint match type rejects bad arg...' ); like( $constraint1->error, qr/invalid match type/i, '...because it is invalid'); - is( $constraint1->match_type('FULL'), 'full', + is( $constraint1->match_type('FULL'), 'full', 'Constraint match type = "full"' ); my $constraint2 = SQL::Translator::Schema::Constraint->new( name => 'bar' ); @@ -322,7 +322,7 @@ require_ok( 'SQL::Translator::Schema' ); ) or die $person_table->error; isa_ok( $constraint3, 'SQL::Translator::Schema::Constraint', 'Constraint' ); is( $constraint3->type, CHECK_C, 'Constraint type is "CHECK"' ); - is( $constraint3->expression, 'foo bar', + is( $constraint3->expression, 'foo bar', 'Constraint expression is "foo bar"' ); my $constraints = $person_table->get_constraints; @@ -382,14 +382,14 @@ require_ok( 'SQL::Translator::Schema' ); like( $schema->error, qr/no table/i, 'Error on no arg to get_table' ); $bad_table = $schema->get_table('baz'); - like( $schema->error, qr/does not exist/i, + like( $schema->error, qr/does not exist/i, 'Error on bad arg to get_table' ); my $bad_view = $schema->get_view; like( $schema->error, qr/no view/i, 'Error on no arg to get_view' ); $bad_view = $schema->get_view('bar'); - like( $schema->error, qr/does not exist/i, + like( $schema->error, qr/does not exist/i, 'Error on bad arg to get_view' ); my $good_table = $schema->get_table('foo'); @@ -413,8 +413,8 @@ require_ok( 'SQL::Translator::Schema' ); # # Test ability to introspect some values # -{ - my $s = SQL::Translator::Schema->new( +{ + my $s = SQL::Translator::Schema->new( name => 'foo', database => 'PostgreSQL', ); @@ -450,7 +450,7 @@ require_ok( 'SQL::Translator::Schema' ); is( join('', $c->fields('foo')), 'foo', 'Fields now = "foo"' ); is( $c->is_valid, undef, 'Constraint on "person" not valid...'); - like( $c->error, qr/non-existent field/i, + like( $c->error, qr/non-existent field/i, q[...because field "foo" doesn't exist] ); my $fk = $t->add_field( name => 'pet_id' ); @@ -461,18 +461,18 @@ require_ok( 'SQL::Translator::Schema' ); $t->add_field( name => 'f2' ); is( join(',', $c->fields('f1,f2')), 'f1,f2', 'Fields now = "f1,f2"' ); is( $c->is_valid, undef, 'Constraint on "person" not valid...'); - like( $c->error, qr/only one field/i, + like( $c->error, qr/only one field/i, q[...because too many fields for FK] ); $c->fields('f1'); is( $c->is_valid, undef, 'Constraint on "person" not valid...'); - like( $c->error, qr/no reference table/i, + like( $c->error, qr/no reference table/i, q[...because there's no reference table] ); is( $c->reference_table('foo'), 'foo', 'Reference table now = "foo"' ); is( $c->is_valid, undef, 'Constraint on "person" not valid...'); - like( $c->error, qr/no table named/i, + like( $c->error, qr/no table named/i, q[...because reference table "foo" doesn't exist] ); my $t2 = $s->add_table( name => 'pet' ); @@ -484,7 +484,7 @@ require_ok( 'SQL::Translator::Schema' ); like( $c->error, qr/no reference fields/i, q[...because there're no reference fields]); - is( join('', $c->reference_fields('pet_id')), 'pet_id', + is( join('', $c->reference_fields('pet_id')), 'pet_id', 'Reference fields = "pet_id"' ); is( $c->is_valid, undef, 'Constraint on "person" not valid...'); @@ -493,7 +493,7 @@ require_ok( 'SQL::Translator::Schema' ); my $pet_id = $t2->add_field( name => 'pet_id' ); is( $pet_id->name, 'pet_id', 'Added field "pet_id"' ); - + is( $c->is_valid, 1, 'Constraint now valid' ); } @@ -506,7 +506,7 @@ require_ok( 'SQL::Translator::Schema' ); is( $t->primary_key, undef, 'No primary key' ); - is( $t->primary_key('person_id'), undef, + is( $t->primary_key('person_id'), undef, q[Can't make PK on "person_id"...] ); like( $t->error, qr/invalid field/i, "...because it doesn't exist" ); @@ -519,7 +519,7 @@ require_ok( 'SQL::Translator::Schema' ); $t->add_field( name => 'name' ); $c = $t->primary_key('name'); - is( join(',', $c->fields), 'person_id,name', + is( join(',', $c->fields), 'person_id,name', 'Constraint now on "person_id" and "name"' ); is( scalar @{ $t->get_constraints }, 1, 'Found 1 constraint' ); @@ -599,9 +599,9 @@ require_ok( 'SQL::Translator::Schema' ); isa_ok( $t->schema, 'SQL::Translator::Schema', 'Schema' ); is( $t->schema->name, 'TrigTest', qq[Schema name is "'TrigTest'"] ); is( $t->name, $name, qq[Name is "$name"] ); - is( $t->perform_action_when, $perform_action_when, + is( $t->perform_action_when, $perform_action_when, qq[Perform action when is "$perform_action_when"] ); - is( join(',', $t->database_events), $database_events, + is( join(',', $t->database_events), $database_events, qq[Database event is "$database_events"] ); isa_ok( $t->table, 'SQL::Translator::Schema::Table', qq[table is a Table"] ); is( $t->action, $action, qq[Action is "$action"] ); @@ -615,7 +615,7 @@ require_ok( 'SQL::Translator::Schema' ); - my $s2 = SQL::Translator::Schema->new(name => 'TrigTest2'); + my $s2 = SQL::Translator::Schema->new(name => 'TrigTest2'); $s2->add_table(name=>'foo') or die "Couldn't create table: ", $s2->error; my $t2 = $s2->add_trigger( name => 'foo_trigger', @@ -624,35 +624,35 @@ require_ok( 'SQL::Translator::Schema' ); on_table => 'foo', action => 'update modified=timestamp();', ) or die $s2->error; - isa_ok( $t2, 'SQL::Translator::Schema::Trigger', 'Trigger' ); + isa_ok( $t2, 'SQL::Translator::Schema::Trigger', 'Trigger' ); isa_ok( $t2->schema, 'SQL::Translator::Schema', 'Schema' ); is( $t2->schema->name, 'TrigTest2', qq[Schema name is "'TrigTest2'"] ); is( $t2->name, 'foo_trigger', qq[Name is "foo_trigger"] ); - is_deeply( + is_deeply( [$t2->database_events], [qw/insert update/], "Database events are [qw/insert update/] " ); - isa_ok($t2->database_events,'ARRAY','Database events'); - - # - # Trigger equal tests - # - isnt( + isa_ok($t2->database_events,'ARRAY','Database events'); + + # + # Trigger equal tests + # + isnt( $t1->equals($t2), 1, 'Compare two Triggers with database_event and database_events' ); - $t1->database_events($database_events); - $t2->database_events($database_events); - is($t1->equals($t2),1,'Compare two Triggers with database_event'); + $t1->database_events($database_events); + $t2->database_events($database_events); + is($t1->equals($t2),1,'Compare two Triggers with database_event'); + + $t2->database_events(''); + $t1->database_events([qw/update insert/]); + $t2->database_events([qw/insert update/]); + is($t1->equals($t2),1,'Compare two Triggers with database_events'); - $t2->database_events(''); - $t1->database_events([qw/update insert/]); - $t2->database_events([qw/insert update/]); - is($t1->equals($t2),1,'Compare two Triggers with database_events'); - # # $schema-> drop_trigger # @@ -667,7 +667,7 @@ require_ok( 'SQL::Translator::Schema' ); $s->add_trigger($t); } - + # # Procedure # diff --git a/t/14postgres-parser.t b/t/14postgres-parser.t index 6448196..fd60cb0 100644 --- a/t/14postgres-parser.t +++ b/t/14postgres-parser.t @@ -79,7 +79,7 @@ my $sql = q{ alter table t_test1 alter column f_char drop default; - -- The following are allowed by the grammar + -- The following are allowed by the grammar -- but won\'t do anything... - ky alter table t_text1 alter column f_char set not null; diff --git a/t/15oracle-parser.t b/t/15oracle-parser.t index e5f8f37..8cae44a 100644 --- a/t/15oracle-parser.t +++ b/t/15oracle-parser.t @@ -14,22 +14,22 @@ my $t = SQL::Translator->new( trace => 0 ); my $sql = q[ CREATE TABLE qtl_trait_category ( - qtl_trait_category_id NUMBER(11) NOT NULL + qtl_trait_category_id NUMBER(11) NOT NULL CONSTRAINT pk_qtl_trait_category PRIMARY KEY, trait_category VARCHAR2(100) NOT NULL, - CONSTRAINT AVCON_4287_PARAM_000 CHECK + CONSTRAINT AVCON_4287_PARAM_000 CHECK (trait_category IN ('S', 'A', 'E')) ENABLE, UNIQUE ( trait_category ) ); - COMMENT ON TABLE qtl_trait_category IS + COMMENT ON TABLE qtl_trait_category IS 'hey, hey, hey, hey'; - comment on column qtl_trait_category.qtl_trait_category_id + comment on column qtl_trait_category.qtl_trait_category_id is 'the primary key!'; -- foo bar comment CREATE TABLE qtl_trait ( - qtl_trait_id NUMBER(11) NOT NULL + qtl_trait_id NUMBER(11) NOT NULL CONSTRAINT pk_qtl_trait PRIMARY KEY, trait_symbol VARCHAR2(100 BYTE) NOT NULL, trait_name VARCHAR2(200 CHAR) NOT NULL, @@ -43,7 +43,7 @@ my $sql = q[ CREATE TABLE qtl ( /* qtl_id comment */ - qtl_id NUMBER(11) NOT NULL + qtl_id NUMBER(11) NOT NULL CONSTRAINT pk_qtl PRIMARY KEY, qtl_accession_id VARCHAR2(20) NOT NULL /* accession comment */, published_symbol VARCHAR2(100), @@ -61,7 +61,7 @@ my $sql = q[ CREATE TABLE qtl_trait_synonym ( - qtl_trait_synonym_id NUMBER(11) NOT NULL + qtl_trait_synonym_id NUMBER(11) NOT NULL CONSTRAINT pk_qtl_trait_synonym PRIMARY KEY, trait_synonym VARCHAR2(200) NOT NULL, qtl_trait_id NUMBER(11) NOT NULL, @@ -70,43 +70,41 @@ my $sql = q[ ); -- View and procedure testing - CREATE OR REPLACE PROCEDURE CMDOMAIN_LATEST.P_24_HOUR_EVENT_SUMMARY - IS - ldate varchar2(10); - user_added INT; - user_deleted INT; - workingsets_created INT; - change_executed INT; - change_detected INT; - reports_run INT; - backup_complete INT; - backup_failed INT; - devices_in_inventory INT; - - - BEGIN - - select CAST(TO_CHAR(sysdate,'MM/DD/YYYY') AS varchar2(10)) INTO ldate from dual; - END; + CREATE OR REPLACE PROCEDURE CMDOMAIN_LATEST.P_24_HOUR_EVENT_SUMMARY + IS + ldate varchar2(10); + user_added INT; + user_deleted INT; + workingsets_created INT; + change_executed INT; + change_detected INT; + reports_run INT; + backup_complete INT; + backup_failed INT; + devices_in_inventory INT; + + BEGIN + select CAST(TO_CHAR(sysdate,'MM/DD/YYYY') AS varchar2(10)) INTO ldate from dual; + END; / - - CREATE OR REPLACE FORCE VIEW CMDOMAIN_MIG.VS_ASSET (ASSET_ID, FQ_NAME, FOLDER_NAME, ASSET_NAME, ANNOTATION, ASSET_TYPE, FOREIGN_ASSET_ID, FOREIGN_ASSET_ID2, DATE_CREATED, DATE_MODIFIED, CONTAINER_ID, CREATOR_ID, MODIFIER_ID, USER_ACCESS) AS - SELECT - a.asset_id, a.fq_name, - ap_extract_folder(a.fq_name) AS folder_name, - ap_extract_asset(a.fq_name) AS asset_name, - a.annotation, - a.asset_type, - a.foreign_asset_id, - a.foreign_asset_id2, - a.dateCreated AS date_created, - a.dateModified AS date_modified, - a.container_id, - a.creator_id, - a.modifier_id, - m.user_id AS user_access - from asset a - JOIN M_ACCESS_CONTROL m on a.acl_id = m.acl_id; + + CREATE OR REPLACE FORCE VIEW CMDOMAIN_MIG.VS_ASSET (ASSET_ID, FQ_NAME, FOLDER_NAME, ASSET_NAME, ANNOTATION, ASSET_TYPE, FOREIGN_ASSET_ID, FOREIGN_ASSET_ID2, DATE_CREATED, DATE_MODIFIED, CONTAINER_ID, CREATOR_ID, MODIFIER_ID, USER_ACCESS) AS + SELECT + a.asset_id, a.fq_name, + ap_extract_folder(a.fq_name) AS folder_name, + ap_extract_asset(a.fq_name) AS asset_name, + a.annotation, + a.asset_type, + a.foreign_asset_id, + a.foreign_asset_id2, + a.dateCreated AS date_created, + a.dateModified AS date_modified, + a.container_id, + a.creator_id, + a.modifier_id, + m.user_id AS user_access + from asset a + JOIN M_ACCESS_CONTROL m on a.acl_id = m.acl_id; ]; @@ -130,7 +128,7 @@ my @t1_fields = $t1->get_fields; is( scalar @t1_fields, 2, '2 fields in table' ); my $f1 = shift @t1_fields; -is( $f1->name, 'qtl_trait_category_id', +is( $f1->name, 'qtl_trait_category_id', 'First field is "qtl_trait_category_id"' ); is( $f1->data_type, 'number', 'Field is a number' ); is( $f1->size, 11, 'Size is "11"' ); @@ -156,21 +154,21 @@ my @t1_constraints = $t1->get_constraints; is( scalar @t1_constraints, 3, '3 constraints on table' ); my $c1 = $t1_constraints[0]; -is( $c1->name, 'pk_qtl_trait_category', +is( $c1->name, 'pk_qtl_trait_category', 'Constraint name is "pk_qtl_trait_category"' ); is( $c1->type, PRIMARY_KEY, 'First constraint is PK' ); -is( join(',', $c1->fields), 'qtl_trait_category_id', +is( join(',', $c1->fields), 'qtl_trait_category_id', 'Constraint is on field "qtl_trait_category_id"' ); my $c2 = $t1_constraints[1]; is( $c2->type, CHECK_C, 'Second constraint is a check' ); -is( $c2->expression, +is( $c2->expression, "( trait_category IN ('S', 'A', 'E') ) ENABLE", 'Constraint is on field "trait_category"' ); my $c3 = $t1_constraints[2]; is( $c3->type, UNIQUE, 'Third constraint is unique' ); -is( join(',', $c3->fields), 'trait_category', +is( join(',', $c3->fields), 'trait_category', 'Constraint is on field "trait_category"' ); # @@ -206,7 +204,7 @@ is( $t2_f3->is_nullable, 0, 'Field cannot be null' ); is( $t2_f3->is_foreign_key, 0, 'Field is not a FK' ); my $t2_f4 = shift @t2_fields; -is( $t2_f4->name, 'qtl_trait_category_id', +is( $t2_f4->name, 'qtl_trait_category_id', 'Fourth field is "qtl_trait_category_id"' ); is( $t2_f4->data_type, 'number', 'Field is a number' ); is( $t2_f4->size, 11, 'Size is "11"' ); @@ -214,9 +212,9 @@ is( $t2_f4->is_nullable, 0, 'Field cannot be null' ); is( $t2_f4->is_foreign_key, 1, 'Field is a FK' ); my $f4_fk = $t2_f4->foreign_key_reference; isa_ok( $f4_fk, 'SQL::Translator::Schema::Constraint', 'FK' ); -is( $f4_fk->reference_table, 'qtl_trait_category', +is( $f4_fk->reference_table, 'qtl_trait_category', 'FK references table "qtl_trait_category"' ); -is( join(',', $f4_fk->reference_fields), 'qtl_trait_category_id', +is( join(',', $f4_fk->reference_fields), 'qtl_trait_category_id', 'FK references field "qtl_trait_category_id"' ); my @t2_constraints = $t2->get_constraints; @@ -240,11 +238,11 @@ is( join(',', $t2_c3->fields), 'trait_name', 'Fields = "trait_name"' ); my $t2_c4 = shift @t2_constraints; is( $t2_c4->type, FOREIGN_KEY, 'Fourth constraint is FK' ); is( $t2_c4->name, '', 'No name' ); -is( join(',', $t2_c4->fields), 'qtl_trait_category_id', +is( join(',', $t2_c4->fields), 'qtl_trait_category_id', 'Fields = "qtl_trait_category_id"' ); -is( $t2_c4->reference_table, 'qtl_trait_category', +is( $t2_c4->reference_table, 'qtl_trait_category', 'Reference table = "qtl_trait_category"' ); -is( join(',', $t2_c4->reference_fields), 'qtl_trait_category_id', +is( join(',', $t2_c4->reference_fields), 'qtl_trait_category_id', 'Reference fields = "qtl_trait_category_id"' ); @@ -270,7 +268,7 @@ my $t3_f1 = shift @t3_fields; is( $t3_f1->comments, 'qtl_id comment', 'Comment "qtl_id comment" exists' ); my $t3_f2 = shift @t3_fields; -is( $t3_f2->comments, 'accession comment', +is( $t3_f2->comments, 'accession comment', 'Comment "accession comment" exists' ); my @t3_indices = $t3->get_indices; @@ -295,13 +293,13 @@ is( scalar @t4_constraints, 3, '3 constraints on table' ); my $t4_c3 = $t4_constraints[2]; is( $t4_c3->type, FOREIGN_KEY, 'Third constraint is FK' ); is( $t4_c3->name, '', 'No name' ); -is( join(',', $t4_c3->fields), 'qtl_trait_id', +is( join(',', $t4_c3->fields), 'qtl_trait_id', 'Fields = "qtl_trait_id"' ); -is( $t4_c3->reference_table, 'qtl_trait', +is( $t4_c3->reference_table, 'qtl_trait', 'Reference table = "qtl_trait"' ); -is( join(',', $t4_c3->reference_fields), 'qtl_trait_id', +is( join(',', $t4_c3->reference_fields), 'qtl_trait_id', 'Reference fields = "qtl_trait_id"' ); -is( $t4_c3->on_delete, 'SET NULL', +is( $t4_c3->on_delete, 'SET NULL', 'on_delete = "SET NULL"' ); my @views = $schema->get_views; @@ -310,7 +308,7 @@ my $view1 = shift @views; is( $view1->name, 'VS_ASSET', 'Found "VS_ASSET" view' ); like($view1->sql, qr/VS_ASSET/, "Detected view VS_ASSET"); unlike($view1->sql, qr/CMDOMAIN_MIG/, "Did not detect CMDOMAIN_MIG"); - + my @procs = $schema->get_procedures; is( scalar @procs, 1, 'Right number of procedures (1)' ); my $proc1 = shift @procs; diff --git a/t/16xml-parser.t b/t/16xml-parser.t index 2fe15f3..b8fad41 100644 --- a/t/16xml-parser.t +++ b/t/16xml-parser.t @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl -w # vim:filetype=perl # Before `make install' is performed this script should be runnable with diff --git a/t/17sqlfxml-producer.t b/t/17sqlfxml-producer.t index 5b9fa76..d9d0868 100644 --- a/t/17sqlfxml-producer.t +++ b/t/17sqlfxml-producer.t @@ -157,7 +157,7 @@ EOXML ok("$xml" ne "" ,"Produced something!"); print "XML attrib_values=>1:\n$xml" if DEBUG; # Strip sqlf header with its variable date so we diff safely - $xml =~ s/^([^\n]*\n){7}//m; + $xml =~ s/^([^\n]*\n){7}//m; eq_or_diff $xml, $ans ,"XML looks right"; } # end View @@ -220,7 +220,7 @@ EOXML ok("$xml" ne "" ,"Produced something!"); print "XML attrib_values=>1:\n$xml" if DEBUG; # Strip sqlf header with its variable date so we diff safely - $xml =~ s/^([^\n]*\n){7}//m; + $xml =~ s/^([^\n]*\n){7}//m; eq_or_diff $xml, $ans ,"XML looks right"; } # end Trigger @@ -276,7 +276,7 @@ EOXML ok("$xml" ne "" ,"Produced something!"); print "XML attrib_values=>1:\n$xml" if DEBUG; # Strip sqlf header with its variable date so we diff safely - $xml =~ s/^([^\n]*\n){7}//m; + $xml =~ s/^([^\n]*\n){7}//m; eq_or_diff $xml, $ans ,"XML looks right"; } # end Procedure diff --git a/t/18ttschema-producer.t b/t/18ttschema-producer.t index 909a015..3118da8 100644 --- a/t/18ttschema-producer.t +++ b/t/18ttschema-producer.t @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl -w # vim:filetype=perl # Before `make install' is performed this script should be runnable with @@ -46,8 +46,11 @@ use SQL::Translator::Producer::TTSchema; my $out; lives_ok { $out = $obj->translate; } "Translate ran"; ok $out ne "" ,"Produced something!"; - local $/ = undef; # slurp - eq_or_diff $out, ,"Output looks right"; + eq_or_diff + $out, + do { local (@ARGV, $/) = "$Bin/data/template/testresult_basic.txt"; <> }, + "Output looks right" + ; } # Test passing of Template config @@ -82,254 +85,3 @@ use SQL::Translator::Producer::TTSchema; Table: Another} ,"Output looks right"; } - - -__DATA__ -Schema: -Database: - -Foo: bar -Hello: world - -Table: Basic -========================================================================== - -Fields - id - data_type: int - size: 10 - is_nullable: 0 - default_value: - is_primary_key: 1 - is_unique: 0 - is_auto_increment: 1 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 1 - table: Basic - - title - data_type: varchar - size: 100 - is_nullable: 0 - default_value: hello - is_primary_key: 0 - is_unique: 1 - is_auto_increment: 0 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 2 - table: Basic - - description - data_type: text - size: 0 - is_nullable: 1 - default_value: - is_primary_key: 0 - is_unique: 0 - is_auto_increment: 0 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 3 - table: Basic - - email - data_type: varchar - size: 500 - is_nullable: 1 - default_value: - is_primary_key: 0 - is_unique: 1 - is_auto_increment: 0 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 4 - table: Basic - - explicitnulldef - data_type: varchar - size: 0 - is_nullable: 1 - default_value: - is_primary_key: 0 - is_unique: 0 - is_auto_increment: 0 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 5 - table: Basic - - explicitemptystring - data_type: varchar - size: 0 - is_nullable: 1 - default_value: - is_primary_key: 0 - is_unique: 0 - is_auto_increment: 0 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 6 - table: Basic - - emptytagdef - data_type: varchar - size: 0 - is_nullable: 1 - default_value: - is_primary_key: 0 - is_unique: 0 - is_auto_increment: 0 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 7 - table: Basic - - another_id - data_type: int - size: 10 - is_nullable: 1 - default_value: 2 - is_primary_key: 0 - is_unique: 0 - is_auto_increment: 0 - is_foreign_key: 1 - foreign_key_reference: Another - is_valid: 1 - order: 8 - table: Basic - - timest - data_type: timestamp - size: 0 - is_nullable: 1 - default_value: - is_primary_key: 0 - is_unique: 0 - is_auto_increment: 0 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 9 - table: Basic - - -Indices - titleindex - table: Basic - fields: title - type: NORMAL - options: - is_valid: 1 - - -Constraints - ? - type: PRIMARY KEY - fields: id - expression: - match_type: - reference_fields: - reference_table: - deferrable: 1 - on_delete: - on_update: - options: - is_valid: 1 - - emailuniqueindex - type: UNIQUE - fields: email - expression: - match_type: - reference_fields: - reference_table: - deferrable: 1 - on_delete: - on_update: - options: - is_valid: 1 - - very_long_index_name_on_title_field_which_should_be_truncated_for_various_rdbms - type: UNIQUE - fields: title - expression: - match_type: - reference_fields: - reference_table: - deferrable: 1 - on_delete: - on_update: - options: - is_valid: 1 - - ? - type: FOREIGN KEY - fields: another_id - expression: - match_type: - reference_fields: id - reference_table: Another - deferrable: 1 - on_delete: - on_update: - options: - is_valid: 1 - -Table: Another -========================================================================== - -Fields - id - data_type: int - size: 10 - is_nullable: 0 - default_value: - is_primary_key: 1 - is_unique: 0 - is_auto_increment: 1 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 1 - table: Another - - num - data_type: numeric - size: 10,2 - is_nullable: 1 - default_value: - is_primary_key: 0 - is_unique: 0 - is_auto_increment: 0 - is_foreign_key: 0 - foreign_key_reference: - is_valid: 1 - order: 2 - table: Another - - -Indices - -Constraints - ? - type: PRIMARY KEY - fields: id - expression: - match_type: - reference_fields: - reference_table: - deferrable: 1 - on_delete: - on_update: - options: - is_valid: 1 - diff --git a/t/19sybase-parser.t b/t/19sybase-parser.t index 3a6e573..fc9d239 100644 --- a/t/19sybase-parser.t +++ b/t/19sybase-parser.t @@ -106,6 +106,6 @@ is( scalar @tables, 9, 'Nine tables' ); is( scalar @constraints, 1, 'One constraint' ); is( $constraints[0]->type, UNIQUE, 'Constraint is UNIQUE' ); - is( join(',', $constraints[0]->fields), + is( join(',', $constraints[0]->fields), 'mdinfo,mdaver_end,srvver_end', 'On "mdinfo,mdaver_end,srvver_end"' ); } diff --git a/t/26sybase.t b/t/26sybase.t index 45169ed..b9f0a5d 100644 --- a/t/26sybase.t +++ b/t/26sybase.t @@ -5,7 +5,7 @@ use Test::SQL::Translator qw(maybe_plan); BEGIN { maybe_plan(3, 'SQL::Translator::Parser::DBI::Sybase', - ); + ); } use_ok('SQL::Translator::Parser::DBI::Sybase'); diff --git a/t/27sqlite-parser.t b/t/27sqlite-parser.t index 198d8c3..0d2abf0 100644 --- a/t/27sqlite-parser.t +++ b/t/27sqlite-parser.t @@ -47,7 +47,7 @@ my $file = "$Bin/data/sqlite/create.sql"; my $c1 = pop @constraints; is( $c1->type, 'FOREIGN KEY', 'FK constraint' ); is( $c1->reference_table, 'person', 'References person table' ); - is( join(',', $c1->reference_fields), 'person_id', + is( join(',', $c1->reference_fields), 'person_id', 'References person_id field' ); my @views = $schema->get_views; @@ -80,7 +80,7 @@ $file = "$Bin/data/sqlite/named.sql"; is( $c1->type, 'FOREIGN KEY', 'FK constraint' ); is( $c1->reference_table, 'person', 'References person table' ); is( $c1->name, 'fk_person_id', 'Constraint name fk_person_id' ); - is( join(',', $c1->reference_fields), 'person_id', + is( join(',', $c1->reference_fields), 'person_id', 'References person_id field' ); } diff --git a/t/29html.t b/t/29html.t index a4cc607..3796b4b 100644 --- a/t/29html.t +++ b/t/29html.t @@ -21,7 +21,7 @@ BEGIN { my ($p, $tables, $classes); $p = HTML::Parser->new(api_version => 3); -$p->strict_names(1); +$p->strict_names(1); my $create = q| CREATE TABLE foo ( @@ -35,7 +35,7 @@ my $parsed = $tr->translate(data => $create) or die $tr->error; my $status; eval { - $status = $p->parse($parsed); + $status = $p->parse($parsed); }; if ($@) { daig $@; @@ -94,6 +94,6 @@ BEGIN { $classes++; } }, 'tagname,attr', - ], + ], ); } diff --git a/t/30sqlt-diff.t b/t/30sqlt-diff.t index 90abd7d..957f89f 100644 --- a/t/30sqlt-diff.t +++ b/t/30sqlt-diff.t @@ -24,15 +24,15 @@ BEGIN { ); } -ok(-e $sqlt_diff, 'Found sqlt-diff script'); +ok(-e $sqlt_diff, 'Found sqlt-diff script'); my @cmd = ($^X, $sqlt_diff, "$create1=SQLite", "$create2=SQLite"); my $out = `@cmd`; like($out, qr/-- Target database SQLite is untested/, "Detected 'untested' comment"); like($out, qr/ALTER TABLE person CHANGE iq/, "Detected altered 'iq' field"); -like($out, qr/ALTER TABLE person ADD is_rock_star/, +like($out, qr/ALTER TABLE person ADD is_rock_star/, "Detected missing rock star field"); - + @cmd = ($^X, $sqlt_diff, "$create1=SQLite", "$create1=SQLite"); $out = `@cmd`; @@ -58,17 +58,17 @@ like($out, qr/ALTER TABLE person CHANGE person_id/, "Detected altered 'person_id like($out, qr/ALTER TABLE person CHANGE iq/, "Detected altered 'iq' field"); like($out, qr/ALTER TABLE person CHANGE name/, "Detected altered 'name' field"); like($out, qr/ALTER TABLE person CHANGE age/, "Detected altered 'age' field"); -like($out, qr/ALTER TABLE person ADD is_rock_star/, +like($out, qr/ALTER TABLE person ADD is_rock_star/, "Detected missing rock star field"); -like($out, qr/ALTER TABLE person ADD UNIQUE UC_person_id/, +like($out, qr/ALTER TABLE person ADD UNIQUE UC_person_id/, "Detected missing unique constraint"); -like($out, qr/CREATE UNIQUE INDEX unique_name/, +like($out, qr/CREATE UNIQUE INDEX unique_name/, "Detected unique index with different name"); -like($out, qr/ALTER TABLE person ENGINE=InnoDB;/, +like($out, qr/ALTER TABLE person ENGINE=InnoDB;/, "Detected altered table option"); -like($out, qr/ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E/, +like($out, qr/ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E/, "Detected drop foreign key"); -like($out, qr/ALTER TABLE employee ADD CONSTRAINT FK5302D47D93FE702E_diff/, +like($out, qr/ALTER TABLE employee ADD CONSTRAINT FK5302D47D93FE702E_diff/, "Detected add constraint"); unlike($out, qr/ALTER TABLE employee ADD PRIMARY KEY/, "Primary key looks different when it shouldn't"); @@ -93,7 +93,7 @@ my $oracle_create2 = (-d "t") $out = `@cmd`; unlike($out, qr/-- Target database Oracle is untested/, "Did not detect 'untested' comment"); -like($out, qr/ALTER TABLE TABLE1 DROP FOREIGN KEY/, +like($out, qr/ALTER TABLE TABLE1 DROP FOREIGN KEY/, "Detected drop foreign key"); -like($out, qr/ALTER TABLE TABLE1 ADD CONSTRAINT/, +like($out, qr/ALTER TABLE TABLE1 ADD CONSTRAINT/, "Detected add constraint"); diff --git a/t/30sqlt-new-diff-mysql.t b/t/30sqlt-new-diff-mysql.t index 9ed3108..3bd1653 100644 --- a/t/30sqlt-new-diff-mysql.t +++ b/t/30sqlt-new-diff-mysql.t @@ -25,7 +25,7 @@ my ( $source_schema, $target_schema, $parsed_sql_schema ) = map { or die $tr->error; my $out = $t->translate( catfile($Bin, qw/data diff/, $_ ) ) or die $tr->error; - + my $schema = $t->schema; unless ( $schema->name ) { $schema->name( $_ ); @@ -34,13 +34,13 @@ my ( $source_schema, $target_schema, $parsed_sql_schema ) = map { } (qw( create1.yml create2.yml )); # Test for differences -my @out = SQL::Translator::Diff::schema_diff( - $source_schema, 'MySQL', +my @out = SQL::Translator::Diff::schema_diff( + $source_schema, 'MySQL', $target_schema, 'MySQL', - { - no_batch_alters => 1, - producer_args => { quote_table_names => 0 } - } + { + no_batch_alters => 1, + producer_args => { quote_table_names => 0 } + } ); ok( @out, 'Got a list' ); @@ -167,13 +167,13 @@ eq_or_diff($out, <<'## END OF DIFF', "No differences found"); # Lets remove the renamed table so we dont have to change the SQL or other tests $target_schema->drop_table('new_name'); - + my $schema = $t->schema; unless ( $schema->name ) { $schema->name( 'create.sql' ); } - # Now lets change the type of one of the 'integer' columns so that it + # Now lets change the type of one of the 'integer' columns so that it # matches what the mysql parser sees for ' interger'. my $field = $target_schema->get_table('employee')->get_field('employee_id'); $field->data_type('integer'); @@ -268,7 +268,7 @@ COMMIT; } { - # Test other things about renaming tables to - namely that renames + # Test other things about renaming tables to - namely that renames # constraints are still formated right. my $s1 = SQL::Translator::Schema->new; @@ -315,7 +315,7 @@ COMMIT; ## END OF DIFF # Test quoting works too. - $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL', + $out = SQL::Translator::Diff::schema_diff($s1, 'MySQL', $s2, 'MySQL', { producer_args => { quote_table_names => '`' } } ); eq_or_diff($out, <<'## END OF DIFF', "Quoting can be turned on"); diff --git a/t/30sqlt-new-diff-pgsql.t b/t/30sqlt-new-diff-pgsql.t index 6e635cf..48cb32b 100644 --- a/t/30sqlt-new-diff-pgsql.t +++ b/t/30sqlt-new-diff-pgsql.t @@ -25,7 +25,7 @@ my ( $source_schema, $target_schema, $parsed_sql_schema ) = map { or die $tr->error; my $out = $t->translate( catfile($Bin, qw/data diff pgsql/, $_ ) ) or die $tr->error; - + my $schema = $t->schema; unless ( $schema->name ) { $schema->name( $_ ); diff --git a/t/30sqlt-new-diff-sqlite.t b/t/30sqlt-new-diff-sqlite.t index bfcbd68..4503d6e 100644 --- a/t/30sqlt-new-diff-sqlite.t +++ b/t/30sqlt-new-diff-sqlite.t @@ -23,7 +23,7 @@ my ( $source_schema, $target_schema ) = map { or die $tr->error; my $out = $t->translate( catfile($Bin, qw/data diff/, $_ ) ) or die $tr->error; - + my $schema = $t->schema; unless ( $schema->name ) { $schema->name( $_ ); @@ -32,11 +32,11 @@ my ( $source_schema, $target_schema ) = map { } (qw/create1.yml create2.yml/); # Test for differences -my $out = SQL::Translator::Diff::schema_diff( $source_schema, 'SQLite', $target_schema, 'SQLite', - { no_batch_alters => 1, +my $out = SQL::Translator::Diff::schema_diff( $source_schema, 'SQLite', $target_schema, 'SQLite', + { no_batch_alters => 1, ignore_missing_methods => 1, output_db => 'SQLite', - } + } ); eq_or_diff($out, <<'## END OF DIFF', "Diff as expected"); diff --git a/t/30sqlt-new-diff.t b/t/30sqlt-new-diff.t index 5f9b01f..b2e55d7 100644 --- a/t/30sqlt-new-diff.t +++ b/t/30sqlt-new-diff.t @@ -22,7 +22,7 @@ my ( $source_schema, $target_schema ) = map { or die $tr->error; my $out = $t->translate( catfile($Bin, qw/data diff /, $_ ) ) or die $tr->error; - + my $schema = $t->schema; unless ( $schema->name ) { $schema->name( $_ ); @@ -41,7 +41,7 @@ my $diff = SQL::Translator::Diff->new({ my $diff_hash = make_diff_hash(); eq_or_diff($diff_hash->{employee}, - { + { constraints_to_create => [ 'FK5302D47D93FE702E_diff' ], constraints_to_drop => [ 'FK5302D47D93FE702E' ], fields_to_drop => [ 'job_title' ] @@ -52,7 +52,7 @@ eq_or_diff($diff_hash->{person}, { constraints_to_create => [ 'UC_person_id', 'UC_age_name' ], constraints_to_drop => [ 'UC_age_name' ], - fields_to_alter => [ + fields_to_alter => [ 'person_id person_id', 'name name', 'age age', @@ -91,7 +91,7 @@ $diff = SQL::Translator::Diff->new({ $diff_hash = make_diff_hash(); eq_or_diff($diff_hash->{employee}, - { + { fields_to_drop => [ 'job_title' ] }, "Correct differences correct on employee table"); @@ -100,7 +100,7 @@ eq_or_diff($diff_hash->{person}, { constraints_to_create => [ 'UC_person_id', 'UC_age_name' ], constraints_to_drop => [ 'UC_age_name' ], - fields_to_alter => [ + fields_to_alter => [ 'person_id person_id', 'name name', 'age age', @@ -139,14 +139,14 @@ sub make_diff_hash { my %table_diffs = ( map { - + my $opt = $table_diff->{$_}; @$opt ? ( $_ => [ map { (ref $_||'') eq 'ARRAY' ? "@$_" : (ref $_) ? $_->name : "$_"; - } @$opt - ] ) + } @$opt + ] ) : () } keys %$table_diff ); diff --git a/t/31dumper.t b/t/31dumper.t index 4dd0c3e..abf54ce 100644 --- a/t/31dumper.t +++ b/t/31dumper.t @@ -14,7 +14,7 @@ use Symbol qw(gensym); BEGIN { maybe_plan( - 5, + 5, 'DBI', 'SQL::Translator::Parser::SQLite', 'SQL::Translator::Producer::Dumper' diff --git a/t/33tt-table-producer.t b/t/33tt-table-producer.t index 7d75023..db87f83 100644 --- a/t/33tt-table-producer.t +++ b/t/33tt-table-producer.t @@ -1,4 +1,4 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl -w # vim:filetype=perl # Before `make install' is performed this script should be runnable with @@ -55,7 +55,11 @@ warn $obj->error unless $out; # Normal output looks ok local $/ = undef; # slurp -eq_or_diff $out, ,"Output looks right"; +eq_or_diff + $out, + do { local (@ARGV, $/) = "$Bin/data/template/testresult_table.txt"; <> }, + "Output looks right" +; # File output my @files = glob("$tdir/*.txt"); @@ -66,7 +70,7 @@ is( $files[1], "$tdir/pet.txt" , "Wrote pet.txt" ); open(FILE, "$tdir/person.txt") || die "Couldn't open $tdir/person.txt : $!"; eq_or_diff , qq{Table: person Primary Key: person_id - Foreign Keys: + Foreign Keys:\x20 Data Fields: name, age, weight, iq, description } @@ -76,25 +80,12 @@ close(FILE); open(FILE, "$tdir/pet.txt") || die "Couldn't open $tdir/pet.txt : $!"; eq_or_diff , qq{Table: pet Primary Key: pet_id, person_id - Foreign Keys: + Foreign Keys:\x20 Data Fields: name, age } , "pet.txt looks right"; close(FILE); - print $out if DEBUG; #print "Debug:", Dumper($obj) if DEBUG; - -__DATA__ -Table: person - Primary Key: person_id - Foreign Keys: - Data Fields: name, age, weight, iq, description - -Table: pet - Primary Key: pet_id, person_id - Foreign Keys: - Data Fields: name, age - diff --git a/t/38-filter-names.t b/t/38-filter-names.t index 47428b4..4edd793 100644 --- a/t/38-filter-names.t +++ b/t/38-filter-names.t @@ -74,7 +74,7 @@ $obj = SQL::Translator->new( data => $in_yaml, filters => [ # Filter from SQL::Translator::Filter::* - [ 'Names', { + [ 'Names', { tables => 'lc', fields => 'ucfirst', } ], @@ -86,7 +86,7 @@ my $out; lives_ok { $out = $obj->translate; } "Translate ran"; is $obj->error, '' ,"No errors"; ok $out ne "" ,"Produced something!"; -# Somewhat hackishly modify the yaml with a regex to avoid +# Somewhat hackishly modify the yaml with a regex to avoid # failing randomly on every change of version. $out =~ s/version: .*/version: SUPPRESSED/; eq_or_diff $out, $ans_yaml ,"Output looks right"; diff --git a/t/38-mysql-producer.t b/t/38-mysql-producer.t index 2305f4f..6d1c681 100644 --- a/t/38-mysql-producer.t +++ b/t/38-mysql-producer.t @@ -37,8 +37,8 @@ schema: thing: name: thing extra: - mysql_charset: latin1 - mysql_collate: latin1_danish_ci + mysql_charset: latin1 + mysql_collate: latin1_danish_ci order: 1 fields: id: @@ -339,14 +339,14 @@ my $number_sizes = { }; for my $size (keys %$number_sizes) { my $expected = $number_sizes->{$size}; - my $number_field = SQL::Translator::Schema::Field->new( + my $number_field = SQL::Translator::Schema::Field->new( name => "numberfield_$expected", table => $table, data_type => 'number', size => $size, is_nullable => 1, is_foreign_key => 0, - is_unique => 0 + is_unique => 0 ); is( @@ -358,7 +358,7 @@ for my $size (keys %$number_sizes) { my $varchars; for my $size (qw/255 256 65535 65536/) { - $varchars->{$size} = SQL::Translator::Schema::Field->new( + $varchars->{$size} = SQL::Translator::Schema::Field->new( name => "vch_$size", table => $table, data_type => 'varchar', @@ -370,68 +370,68 @@ for my $size (qw/255 256 65535 65536/) { is ( SQL::Translator::Producer::MySQL::create_field($varchars->{255}, { mysql_version => 5.000003 }), - 'vch_255 varchar(255)', + 'vch_255 varchar(255)', 'VARCHAR(255) is not substituted with TEXT for Mysql >= 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{255}, { mysql_version => 5.0 }), - 'vch_255 varchar(255)', + 'vch_255 varchar(255)', 'VARCHAR(255) is not substituted with TEXT for Mysql < 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{255}), - 'vch_255 varchar(255)', + 'vch_255 varchar(255)', 'VARCHAR(255) is not substituted with TEXT when no version specified', ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{256}, { mysql_version => 5.000003 }), - 'vch_256 varchar(256)', + 'vch_256 varchar(256)', 'VARCHAR(256) is not substituted with TEXT for Mysql >= 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{256}, { mysql_version => 5.0 }), - 'vch_256 text', + 'vch_256 text', 'VARCHAR(256) is substituted with TEXT for Mysql < 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{256}), - 'vch_256 text', + 'vch_256 text', 'VARCHAR(256) is substituted with TEXT when no version specified', ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65535}, { mysql_version => 5.000003 }), - 'vch_65535 varchar(65535)', + 'vch_65535 varchar(65535)', 'VARCHAR(65535) is not substituted with TEXT for Mysql >= 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65535}, { mysql_version => 5.0 }), - 'vch_65535 text', + 'vch_65535 text', 'VARCHAR(65535) is substituted with TEXT for Mysql < 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65535}), - 'vch_65535 text', + 'vch_65535 text', 'VARCHAR(65535) is substituted with TEXT when no version specified', ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65536}, { mysql_version => 5.000003 }), - 'vch_65536 text', + 'vch_65536 text', 'VARCHAR(65536) is substituted with TEXT for Mysql >= 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65536}, { mysql_version => 5.0 }), - 'vch_65536 text', + 'vch_65536 text', 'VARCHAR(65536) is substituted with TEXT for Mysql < 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65536}), - 'vch_65536 text', + 'vch_65536 text', 'VARCHAR(65536) is substituted with TEXT when no version specified', ); @@ -560,7 +560,7 @@ EOV quote_field_names => $qf, }; - + my $alter_field = SQL::Translator::Producer::MySQL::alter_field($field1, $field2, $options); is($alter_field, 'ALTER TABLE `mydb`.`mytable` CHANGE COLUMN `myfield` `myfield` VARCHAR(25) NOT NULL', 'Alter field works'); @@ -586,14 +586,14 @@ is($field3_sql, "`myfield` enum('0','1') NOT NULL", 'When no version specified, }; for my $size (keys %$number_sizes) { my $expected = $number_sizes->{$size}; - my $number_field = SQL::Translator::Schema::Field->new( + my $number_field = SQL::Translator::Schema::Field->new( name => "numberfield_$expected", table => $table, data_type => 'number', size => $size, is_nullable => 1, is_foreign_key => 0, - is_unique => 0 + is_unique => 0 ); is( @@ -605,7 +605,7 @@ is($field3_sql, "`myfield` enum('0','1') NOT NULL", 'When no version specified, my $varchars; for my $size (qw/255 256 65535 65536/) { - $varchars->{$size} = SQL::Translator::Schema::Field->new( + $varchars->{$size} = SQL::Translator::Schema::Field->new( name => "vch_$size", table => $table, data_type => 'varchar', @@ -617,68 +617,68 @@ is($field3_sql, "`myfield` enum('0','1') NOT NULL", 'When no version specified, is ( SQL::Translator::Producer::MySQL::create_field($varchars->{255}, { mysql_version => 5.000003, %$options }), - '`vch_255` varchar(255)', + '`vch_255` varchar(255)', 'VARCHAR(255) is not substituted with TEXT for Mysql >= 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{255}, { mysql_version => 5.0, %$options }), - '`vch_255` varchar(255)', + '`vch_255` varchar(255)', 'VARCHAR(255) is not substituted with TEXT for Mysql < 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{255}, $options), - '`vch_255` varchar(255)', + '`vch_255` varchar(255)', 'VARCHAR(255) is not substituted with TEXT when no version specified', ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{256}, { mysql_version => 5.000003, %$options }), - '`vch_256` varchar(256)', + '`vch_256` varchar(256)', 'VARCHAR(256) is not substituted with TEXT for Mysql >= 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{256}, { mysql_version => 5.0, %$options }), - '`vch_256` text', + '`vch_256` text', 'VARCHAR(256) is substituted with TEXT for Mysql < 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{256}, $options), - '`vch_256` text', + '`vch_256` text', 'VARCHAR(256) is substituted with TEXT when no version specified', ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65535}, { mysql_version => 5.000003, %$options }), - '`vch_65535` varchar(65535)', + '`vch_65535` varchar(65535)', 'VARCHAR(65535) is not substituted with TEXT for Mysql >= 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65535}, { mysql_version => 5.0, %$options }), - '`vch_65535` text', + '`vch_65535` text', 'VARCHAR(65535) is substituted with TEXT for Mysql < 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65535}, $options), - '`vch_65535` text', + '`vch_65535` text', 'VARCHAR(65535) is substituted with TEXT when no version specified', ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65536}, { mysql_version => 5.000003, %$options }), - '`vch_65536` text', + '`vch_65536` text', 'VARCHAR(65536) is substituted with TEXT for Mysql >= 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65536}, { mysql_version => 5.0, %$options }), - '`vch_65536` text', + '`vch_65536` text', 'VARCHAR(65536) is substituted with TEXT for Mysql < 5.0.3' ); is ( SQL::Translator::Producer::MySQL::create_field($varchars->{65536}, $options), - '`vch_65536` text', + '`vch_65536` text', 'VARCHAR(65536) is substituted with TEXT when no version specified', ); diff --git a/t/40oracle-parser-dbi.t b/t/40oracle-parser-dbi.t index d1056c9..c915bdf 100644 --- a/t/40oracle-parser-dbi.t +++ b/t/40oracle-parser-dbi.t @@ -5,7 +5,7 @@ use Test::SQL::Translator qw(maybe_plan); BEGIN { maybe_plan(1, 'SQL::Translator::Parser::DBI::Oracle', - ); + ); } use_ok('SQL::Translator::Parser::DBI::Oracle'); diff --git a/t/47postgres-producer.t b/t/47postgres-producer.t index 447930f..7b4cf27 100644 --- a/t/47postgres-producer.t +++ b/t/47postgres-producer.t @@ -199,14 +199,14 @@ my $field3_datetime_with_TZ = SQL::Translator::Schema::Field->new( size => 7, ); -my $field3_datetime_with_TZ_sql = +my $field3_datetime_with_TZ_sql = SQL::Translator::Producer::PostgreSQL::create_field( $field3_datetime_with_TZ ); is( - $field3_datetime_with_TZ_sql, - 'datetime_with_TZ timestamp(6) with time zone', + $field3_datetime_with_TZ_sql, + 'datetime_with_TZ timestamp(6) with time zone', 'Create time field with time zone and size, works' ); @@ -217,14 +217,14 @@ my $field3_time_without_TZ = SQL::Translator::Schema::Field->new( size => 2, ); -my $field3_time_without_TZ_sql +my $field3_time_without_TZ_sql = SQL::Translator::Producer::PostgreSQL::create_field( $field3_time_without_TZ ); is( - $field3_time_without_TZ_sql, - 'time_without_TZ time(2) without time zone', + $field3_time_without_TZ_sql, + 'time_without_TZ time(2) without time zone', 'Create time field without time zone but with size, works' ); @@ -558,7 +558,7 @@ my $drop_view_8_1_expected = "DROP VIEW view_foo; CREATE VIEW view_foo ( id, name ) AS SELECT id, name FROM thing "; - + is($drop_view_8_1_produced, $drop_view_8_1_expected, "My DROP VIEW statement for 8.1 is correct"); my $drop_view_opts2 = { add_drop_view => 1, no_comments => 1, postgres_version => 9.001 }; @@ -568,5 +568,5 @@ my $drop_view_9_1_expected = "DROP VIEW IF EXISTS view_foo; CREATE VIEW view_foo ( id, name ) AS SELECT id, name FROM thing "; - + is($drop_view_9_1_produced, $drop_view_9_1_expected, "My DROP VIEW statement for 9.1 is correct"); diff --git a/t/48xml-to-sqlite.t b/t/48xml-to-sqlite.t index 9502348..9d0baa4 100644 --- a/t/48xml-to-sqlite.t +++ b/t/48xml-to-sqlite.t @@ -92,7 +92,7 @@ my @sql = $sqlt->translate( filename => $xmlfile, ) or die $sqlt->error; -eq_or_diff(\@sql, +eq_or_diff(\@sql, [ 'BEGIN TRANSACTION', q, diff --git a/t/50-sqlserver-parser.t b/t/50-sqlserver-parser.t index 156091a..298e5f6 100644 --- a/t/50-sqlserver-parser.t +++ b/t/50-sqlserver-parser.t @@ -108,7 +108,7 @@ is( scalar @tables, 8, 'Eight tables' ); is( scalar @constraints, 1, 'One constraint' ); is( $constraints[0]->type, UNIQUE, 'Constraint is UNIQUE' ); - is( join(',', $constraints[0]->fields), + is( join(',', $constraints[0]->fields), 'mdinfo,mdaver_end,srvver_end', 'On "mdinfo,mdaver_end,srvver_end"' ); } diff --git a/t/51-xml-to-oracle.t b/t/51-xml-to-oracle.t index c72ea4c..2486246 100644 --- a/t/51-xml-to-oracle.t +++ b/t/51-xml-to-oracle.t @@ -40,7 +40,7 @@ my $sql_string = $sqlt->translate( filename => $xmlfile, ) or die $sqlt->error; -my $want = [ +my $want = [ 'DROP TABLE Basic CASCADE CONSTRAINTS', 'DROP SEQUENCE sq_Basic_id', 'CREATE SEQUENCE sq_Basic_id', @@ -84,7 +84,7 @@ END; 'CREATE OR REPLACE TRIGGER ts_Basic_timest BEFORE INSERT OR UPDATE ON Basic FOR EACH ROW WHEN (new.timest IS NULL) -BEGIN +BEGIN SELECT sysdate INTO :new.timest FROM dual; END; ', @@ -160,7 +160,7 @@ END; CREATE OR REPLACE TRIGGER ts_Basic_timest01 BEFORE INSERT OR UPDATE ON Basic FOR EACH ROW WHEN (new.timest IS NULL) -BEGIN +BEGIN SELECT sysdate INTO :new.timest FROM dual; END; / diff --git a/t/51-xml-to-oracle_quoted.t b/t/51-xml-to-oracle_quoted.t index be7f7b4..6f3a102 100644 --- a/t/51-xml-to-oracle_quoted.t +++ b/t/51-xml-to-oracle_quoted.t @@ -40,7 +40,7 @@ my $sql_string = $sqlt->translate( filename => $xmlfile, ) or die $sqlt->error; -my $want = [ +my $want = [ 'DROP TABLE "Basic" CASCADE CONSTRAINTS', 'DROP SEQUENCE "sq_Basic_id"', 'CREATE SEQUENCE "sq_Basic_id"', @@ -84,7 +84,7 @@ END; 'CREATE OR REPLACE TRIGGER "ts_Basic_timest" BEFORE INSERT OR UPDATE ON "Basic" FOR EACH ROW WHEN (new."timest" IS NULL) -BEGIN +BEGIN SELECT sysdate INTO :new."timest" FROM dual; END; ', @@ -160,7 +160,7 @@ END; CREATE OR REPLACE TRIGGER "ts_Basic_timest01" BEFORE INSERT OR UPDATE ON "Basic" FOR EACH ROW WHEN (new."timest" IS NULL) -BEGIN +BEGIN SELECT sysdate INTO :new."timest" FROM dual; END; / diff --git a/t/61translator_agnostic.t b/t/61translator_agnostic.t index e706717..88cd06d 100644 --- a/t/61translator_agnostic.t +++ b/t/61translator_agnostic.t @@ -41,7 +41,7 @@ TODO: { like ( $sql, - qr/^\s*CREATE TABLE/m, #assume there is at least one create table statement + qr/^\s*CREATE TABLE/m, #assume there is at least one create table statement "Received some meaningful output from the producer", ); } diff --git a/t/63-spacial-pgsql.t b/t/63-spacial-pgsql.t index 9eddc0c..652893f 100644 --- a/t/63-spacial-pgsql.t +++ b/t/63-spacial-pgsql.t @@ -32,10 +32,10 @@ my $field1 = SQL::Translator::Schema::Field->new( name => 'myfield', table => $table, data_type => 'geometry', extra => { - dimensions => 2, - geometry_type => 'POINT', - srid => -1 - }, + dimensions => 2, + geometry_type => 'POINT', + srid => -1 + }, default_value => undef, is_auto_increment => 0, is_nullable => 1, @@ -107,9 +107,9 @@ my $field4 = SQL::Translator::Schema::Field->new( name => 'field4', table => $table, data_type => 'geography', extra => { - geography_type => 'POINT', - srid => -1 - }, + geography_type => 'POINT', + srid => -1 + }, default_value => undef, is_auto_increment => 0, is_nullable => 1, diff --git a/t/66-postgres-dbi-parser.t b/t/66-postgres-dbi-parser.t index f3d88c9..1054e83 100644 --- a/t/66-postgres-dbi-parser.t +++ b/t/66-postgres-dbi-parser.t @@ -64,7 +64,7 @@ my $sql = q[ price numeric ); - -- drop a column, to not have a linear id + -- drop a column, to not have a linear id -- When the table t_test1 is created, f_last get id 5 but -- after this drop, there is only 4 columns. alter table sqlt_test1 drop column f_to_drop; diff --git a/t/data/template/basic.tt b/t/data/template/basic.tt index f4e4689..46663fe 100644 --- a/t/data/template/basic.tt +++ b/t/data/template/basic.tt @@ -34,7 +34,7 @@ Indices options: [% index.options %] is_valid: [% index.is_valid %] [% END %] - + Constraints [%- FOREACH constraint = table.get_constraints %] [% constraint.name OR "?" %] diff --git a/t/data/template/testresult_basic.txt b/t/data/template/testresult_basic.txt new file mode 100644 index 0000000..8a7d2e9 --- /dev/null +++ b/t/data/template/testresult_basic.txt @@ -0,0 +1,248 @@ +Schema: +Database: + +Foo: bar +Hello: world + +Table: Basic +========================================================================== + +Fields + id + data_type: int + size: 10 + is_nullable: 0 + default_value: + is_primary_key: 1 + is_unique: 0 + is_auto_increment: 1 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 1 + table: Basic + + title + data_type: varchar + size: 100 + is_nullable: 0 + default_value: hello + is_primary_key: 0 + is_unique: 1 + is_auto_increment: 0 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 2 + table: Basic + + description + data_type: text + size: 0 + is_nullable: 1 + default_value: + is_primary_key: 0 + is_unique: 0 + is_auto_increment: 0 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 3 + table: Basic + + email + data_type: varchar + size: 500 + is_nullable: 1 + default_value: + is_primary_key: 0 + is_unique: 1 + is_auto_increment: 0 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 4 + table: Basic + + explicitnulldef + data_type: varchar + size: 0 + is_nullable: 1 + default_value: + is_primary_key: 0 + is_unique: 0 + is_auto_increment: 0 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 5 + table: Basic + + explicitemptystring + data_type: varchar + size: 0 + is_nullable: 1 + default_value: + is_primary_key: 0 + is_unique: 0 + is_auto_increment: 0 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 6 + table: Basic + + emptytagdef + data_type: varchar + size: 0 + is_nullable: 1 + default_value: + is_primary_key: 0 + is_unique: 0 + is_auto_increment: 0 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 7 + table: Basic + + another_id + data_type: int + size: 10 + is_nullable: 1 + default_value: 2 + is_primary_key: 0 + is_unique: 0 + is_auto_increment: 0 + is_foreign_key: 1 + foreign_key_reference: Another + is_valid: 1 + order: 8 + table: Basic + + timest + data_type: timestamp + size: 0 + is_nullable: 1 + default_value: + is_primary_key: 0 + is_unique: 0 + is_auto_increment: 0 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 9 + table: Basic + + +Indices + titleindex + table: Basic + fields: title + type: NORMAL + options: + is_valid: 1 + + +Constraints + ? + type: PRIMARY KEY + fields: id + expression: + match_type: + reference_fields: + reference_table: + deferrable: 1 + on_delete: + on_update: + options: + is_valid: 1 + + emailuniqueindex + type: UNIQUE + fields: email + expression: + match_type: + reference_fields: + reference_table: + deferrable: 1 + on_delete: + on_update: + options: + is_valid: 1 + + very_long_index_name_on_title_field_which_should_be_truncated_for_various_rdbms + type: UNIQUE + fields: title + expression: + match_type: + reference_fields: + reference_table: + deferrable: 1 + on_delete: + on_update: + options: + is_valid: 1 + + ? + type: FOREIGN KEY + fields: another_id + expression: + match_type: + reference_fields: id + reference_table: Another + deferrable: 1 + on_delete: + on_update: + options: + is_valid: 1 + +Table: Another +========================================================================== + +Fields + id + data_type: int + size: 10 + is_nullable: 0 + default_value: + is_primary_key: 1 + is_unique: 0 + is_auto_increment: 1 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 1 + table: Another + + num + data_type: numeric + size: 10,2 + is_nullable: 1 + default_value: + is_primary_key: 0 + is_unique: 0 + is_auto_increment: 0 + is_foreign_key: 0 + foreign_key_reference: + is_valid: 1 + order: 2 + table: Another + + +Indices + +Constraints + ? + type: PRIMARY KEY + fields: id + expression: + match_type: + reference_fields: + reference_table: + deferrable: 1 + on_delete: + on_update: + options: + is_valid: 1 + diff --git a/t/data/template/testresult_table.txt b/t/data/template/testresult_table.txt new file mode 100644 index 0000000..520b098 --- /dev/null +++ b/t/data/template/testresult_table.txt @@ -0,0 +1,10 @@ +Table: person + Primary Key: person_id + Foreign Keys: + Data Fields: name, age, weight, iq, description + +Table: pet + Primary Key: pet_id, person_id + Foreign Keys: + Data Fields: name, age + diff --git a/t/mysql-sqlite-translate.t b/t/mysql-sqlite-translate.t index 55043a4..8d96ff6 100644 --- a/t/mysql-sqlite-translate.t +++ b/t/mysql-sqlite-translate.t @@ -7,13 +7,13 @@ use_ok( "SQL::Translator::Parser::MySQL" ); use_ok( "SQL::Translator::Producer::SQLite" ); # This test reproduces a bug in SQL::Translator::Producer::SQLite. -# +# # When tables are created their names are not added to %global_names, and # may be duplicated. # # SQL::Translator::Producer::SQLite version 1.59. # compliments of SymKat - + my $output = SQL::Translator @@ -35,7 +35,7 @@ sub find_table_names { sub has_dupes { my ( @list ) = @_; my %hist; - + for my $elem ( @list ) { return 0 if exists $hist{$elem}; $hist{$elem} = 1; diff --git a/xt/eol.t b/xt/eol.t new file mode 100644 index 0000000..349e099 --- /dev/null +++ b/xt/eol.t @@ -0,0 +1,14 @@ +use warnings; +use strict; + +use Test::More; +eval "use Test::EOL 1.1"; +plan skip_all => 'Test::EOL 1.1 required' if $@; + +Test::EOL::all_perl_files_ok({ trailing_whitespace => 1}, + qw|lib t xt script share/DiaUml|, +); + +# FIXME - Test::EOL declares 'no_plan' which conflicts with done_testing +# https://github.com/schwern/test-more/issues/14 +#done_testing; diff --git a/xt/notabs.t b/xt/notabs.t new file mode 100644 index 0000000..9de9721 --- /dev/null +++ b/xt/notabs.t @@ -0,0 +1,15 @@ +use warnings; +use strict; + +use Test::More; + +eval "use Test::NoTabs 1.1"; +plan skip_all => 'Test::NoTabs 1.1 required' if $@; + +Test::NoTabs::all_perl_files_ok( + qw|lib t xt script share/DiaUml|, +); + +# FIXME - Test::NoTabs declares 'no_plan' which conflicts with done_testing +# https://github.com/schwern/test-more/issues/14 +#done_testing; diff --git a/t/01pod.t b/xt/pod.t similarity index 100% rename from t/01pod.t rename to xt/pod.t