Extend Field->equals() for numeric comparison
Wallace Reis [Tue, 29 Jul 2014 17:58:11 +0000 (14:58 -0300)]
Makefile.PL
lib/SQL/Translator/Schema/Field.pm
t/30sqlt-new-diff-mysql.t
t/30sqlt-new-diff-sqlite.t
t/data/diff/create1.yml
t/data/diff/create2.yml

index e63df5d..4724acf 100644 (file)
@@ -19,6 +19,7 @@ my $deps = {
     'Sub::Quote'               => '0',
     'Try::Tiny'                => '0.04',
     'List::MoreUtils'          => '0.09',
+    'Scalar::Util'             => '0',
   },
   recommends => {
     'Template'                 => '2.20',
index b9aed47..47f1b5d 100644 (file)
@@ -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
index e295833..6a4ce40 100644 (file)
@@ -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,
index ef7fee7..e5b7865 100644 (file)
@@ -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;
 
index 4cddd5c..b0f1477 100644 (file)
@@ -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
index 693c20a..d5912d1 100644 (file)
@@ -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