From 3ab19c1b31fa1fef8284a271afd282736242dd8f Mon Sep 17 00:00:00 2001 From: Wallace Reis Date: Tue, 29 Jul 2014 14:58:11 -0300 Subject: [PATCH 1/2] Extend Field->equals() for numeric comparison --- Makefile.PL | 1 + lib/SQL/Translator/Schema/Field.pm | 25 ++++++++++++++++++++++++- t/30sqlt-new-diff-mysql.t | 1 + t/30sqlt-new-diff-sqlite.t | 6 ++++-- t/data/diff/create1.yml | 12 ++++++++++++ t/data/diff/create2.yml | 14 +++++++++++++- 6 files changed, 55 insertions(+), 4 deletions(-) diff --git a/Makefile.PL b/Makefile.PL index e63df5da3..4724acf18 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -19,6 +19,7 @@ my $deps = { 'Sub::Quote' => '0', 'Try::Tiny' => '0.04', 'List::MoreUtils' => '0.09', + 'Scalar::Util' => '0', }, recommends => { 'Template' => '2.20', diff --git a/lib/SQL/Translator/Schema/Field.pm b/lib/SQL/Translator/Schema/Field.pm index b9aed4729..47f1b5d02 100644 --- a/lib/SQL/Translator/Schema/Field.pm +++ b/lib/SQL/Translator/Schema/Field.pm @@ -27,6 +27,7 @@ use SQL::Translator::Schema::Constants; use SQL::Translator::Types qw(schema_obj); use SQL::Translator::Utils qw(parse_list_arg ex2err throw carp_ro); use Sub::Quote qw(quote_sub); +use Scalar::Util (); extends 'SQL::Translator::Schema::Object'; @@ -75,6 +76,16 @@ our %type_mapping = ( ); +has _numeric_sql_data_types => ( is => 'lazy' ); + +sub _build__numeric_sql_data_types { + return { + map { $_ => 1 } + (SQL_INTEGER, SQL_TINYINT, SQL_SMALLINT, SQL_BIGINT, SQL_DOUBLE, + SQL_NUMERIC, SQL_DECIMAL, SQL_FLOAT, SQL_REAL) + }; +} + =head2 new Object constructor. @@ -543,7 +554,14 @@ around equals => sub { my $effective_lhs = $lhs_is_ref ? $$lhs : $lhs; my $effective_rhs = $rhs_is_ref ? $$rhs : $rhs; - return 0 if $effective_lhs ne $effective_rhs; + if ( $self->_is_numeric_data_type + && Scalar::Util::looks_like_number($effective_lhs) + && Scalar::Util::looks_like_number($effective_rhs) ) { + return 0 if ($effective_lhs + 0) != ($effective_rhs + 0); + } + else { + return 0 if $effective_lhs ne $effective_rhs; + } } return 0 unless $self->is_nullable eq $other->is_nullable; @@ -559,6 +577,11 @@ around equals => sub { # Must come after all 'has' declarations around new => \&ex2err; +sub _is_numeric_data_type { + my $self = shift; + return $self->_numeric_sql_data_types->{ $self->sql_data_type }; +} + 1; =pod diff --git a/t/30sqlt-new-diff-mysql.t b/t/30sqlt-new-diff-mysql.t index e29583340..6a4ce404f 100644 --- a/t/30sqlt-new-diff-mysql.t +++ b/t/30sqlt-new-diff-mysql.t @@ -199,6 +199,7 @@ ALTER TABLE employee DROP FOREIGN KEY FK5302D47D93FE702E, ALTER TABLE person DROP INDEX UC_age_name, DROP INDEX u_name, ADD COLUMN is_rock_star tinyint(4) NULL DEFAULT 1, + ADD COLUMN value double(8, 2) NULL DEFAULT 0.00, CHANGE COLUMN person_id person_id integer(11) NOT NULL auto_increment, CHANGE COLUMN name name varchar(20) NOT NULL, CHANGE COLUMN age age integer(11) NULL DEFAULT 18, diff --git a/t/30sqlt-new-diff-sqlite.t b/t/30sqlt-new-diff-sqlite.t index ef7fee72e..e5b7865e2 100644 --- a/t/30sqlt-new-diff-sqlite.t +++ b/t/30sqlt-new-diff-sqlite.t @@ -128,10 +128,11 @@ CREATE TEMPORARY TABLE person_temp_alter ( weight double(11,2), iq int(11) DEFAULT 0, is_rock_star tinyint(4) DEFAULT 1, + value double(8,2) DEFAULT 0.00, physical_description text ); -INSERT INTO person_temp_alter( person_id, name, age, weight, iq, is_rock_star, physical_description) SELECT person_id, name, age, weight, iq, is_rock_star, physical_description FROM person; +INSERT INTO person_temp_alter( person_id, name, age, weight, iq, is_rock_star, value, physical_description) SELECT person_id, name, age, weight, iq, is_rock_star, value, physical_description FROM person; DROP TABLE person; @@ -142,6 +143,7 @@ CREATE TABLE person ( weight double(11,2), iq int(11) DEFAULT 0, is_rock_star tinyint(4) DEFAULT 1, + value double(8,2) DEFAULT 0.00, physical_description text ); @@ -151,7 +153,7 @@ CREATE UNIQUE INDEX UC_person_id02 ON person (person_id); CREATE UNIQUE INDEX UC_age_name02 ON person (age, name); -INSERT INTO person SELECT person_id, name, age, weight, iq, is_rock_star, physical_description FROM person_temp_alter; +INSERT INTO person SELECT person_id, name, age, weight, iq, is_rock_star, value, physical_description FROM person_temp_alter; DROP TABLE person_temp_alter; diff --git a/t/data/diff/create1.yml b/t/data/diff/create1.yml index 4cddd5c10..b0f147763 100644 --- a/t/data/diff/create1.yml +++ b/t/data/diff/create1.yml @@ -205,6 +205,18 @@ schema: size: - 11 - 2 + value: + data_type: double + default_value: 0 + extra: {} + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 7 + size: + - 8 + - 2 indices: - fields: - name diff --git a/t/data/diff/create2.yml b/t/data/diff/create2.yml index 693c20a06..d5912d14d 100644 --- a/t/data/diff/create2.yml +++ b/t/data/diff/create2.yml @@ -201,7 +201,7 @@ schema: is_primary_key: 0 is_unique: 0 name: physical_description - order: 7 + order: 8 size: - 65535 weight: @@ -216,6 +216,18 @@ schema: size: - 11 - 2 + value: + data_type: double + default_value: 0.00 + extra: {} + is_nullable: 1 + is_primary_key: 0 + is_unique: 0 + name: value + order: 7 + size: + - 8 + - 2 indices: - fields: - name From 658991afb3d5cac4b807fe53f62eda5b0ef21a40 Mon Sep 17 00:00:00 2001 From: Wallace Reis Date: Tue, 29 Jul 2014 18:39:26 -0300 Subject: [PATCH 2/2] Add more data_types for sql_types mapping --- lib/SQL/Translator/Schema/Field.pm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/SQL/Translator/Schema/Field.pm b/lib/SQL/Translator/Schema/Field.pm index 47f1b5d02..a88263233 100644 --- a/lib/SQL/Translator/Schema/Field.pm +++ b/lib/SQL/Translator/Schema/Field.pm @@ -54,10 +54,14 @@ our %type_mapping = ( bigint => SQL_BIGINT, double => SQL_DOUBLE, + 'double precision' => SQL_DOUBLE, decimal => SQL_DECIMAL, - numeric => SQL_NUMERIC, dec => SQL_DECIMAL, + numeric => SQL_NUMERIC, + + real => SQL_REAL, + float => SQL_FLOAT, bit => SQL_BIT,