empty insert into a Sybase table with computed columns and either data_type => undef...
Rafael Kitover [Sun, 31 Jan 2010 12:18:33 +0000 (12:18 +0000)]
lib/DBIx/Class/Storage/DBI/Sybase/ASE.pm
t/746sybase.t
t/inflate/datetime_sybase.t
t/lib/DBICTest/Schema/ComputedColumn.pm [new file with mode: 0644]
t/lib/sqlite.sql

index 45d95da..d7bf678 100644 (file)
@@ -353,10 +353,19 @@ sub insert {
 
   # check for empty insert
   # INSERT INTO foo DEFAULT VALUES -- does not work with Sybase
-  # try to insert explicit 'DEFAULT's instead (except for identity)
+  # try to insert explicit 'DEFAULT's instead (except for identity, timestamp
+  # and computed columns)
   if (not %$to_insert) {
     for my $col ($source->columns) {
       next if $col eq $identity_col;
+
+      my $info = $source->column_info($col);
+
+      next if ref $info->{default_value} eq 'SCALAR'
+        || (exists $info->{data_type} && (not defined $info->{data_type}));
+
+      next if $info->{data_type} && $info->{data_type} =~ /^timestamp\z/i;
+
       $to_insert->{$col} = \'DEFAULT';
     }
   }
index 82ad9c2..441a258 100644 (file)
@@ -9,7 +9,7 @@ use DBICTest;
 
 my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_SYBASE_${_}" } qw/DSN USER PASS/};
 
-my $TESTS = 63 + 2;
+my $TESTS = 66 + 2;
 
 if (not ($dsn && $user)) {
   plan skip_all =>
@@ -575,6 +575,35 @@ SQL
     'updated money value to NULL round-trip'
   );
   diag $@ if $@;
+
+# Test computed columns and timestamps
+  $schema->storage->dbh_do (sub {
+      my ($storage, $dbh) = @_;
+      eval { $dbh->do("DROP TABLE computed_column_test") };
+      $dbh->do(<<'SQL');
+CREATE TABLE computed_column_test (
+   id INT IDENTITY PRIMARY KEY,
+   a_computed_column AS getdate(),
+   a_timestamp timestamp,
+   charfield VARCHAR(20) DEFAULT 'foo' 
+)
+SQL
+  });
+
+  require DBICTest::Schema::ComputedColumn;
+  $schema->register_class(
+    ComputedColumn => 'DBICTest::Schema::ComputedColumn'
+  );
+
+  ok (($rs = $schema->resultset('ComputedColumn')),
+    'got rs for ComputedColumn');
+
+  lives_ok { $row = $rs->create({}) }
+    'empty insert for a table with computed columns survived';
+
+  lives_ok {
+    $row->update({ charfield => 'bar' })
+  } 'update of a table with computed columns survived';
 }
 
 is $ping_count, 0, 'no pings';
@@ -583,6 +612,6 @@ is $ping_count, 0, 'no pings';
 END {
   if (my $dbh = eval { $schema->storage->_dbh }) {
     eval { $dbh->do("DROP TABLE $_") }
-      for qw/artist bindtype_test money_test/;
+      for qw/artist bindtype_test money_test computed_column_test/;
   }
 }
index bbd603a..2b1fbed 100644 (file)
@@ -17,9 +17,6 @@ if (not ($dsn && $user)) {
   if ($@) {
     plan skip_all => 'needs DateTime and DateTime::Format::Sybase for testing';
   }
-  else {
-    plan tests => (4 * 2 * 2) + 2; # (tests * dt_types * storage_types) + storage_tests
-  }
 }
 
 my @storage_types = (
@@ -57,9 +54,9 @@ for my $storage_type (@storage_types) {
     $schema->storage->dbh->do(<<"SQL");
 CREATE TABLE track (
    trackid INT IDENTITY PRIMARY KEY,
-   cd INT,
-   position INT,
-   $col $type,
+   cd INT NULL,
+   position INT NULL,
+   $col $type NULL
 )
 SQL
     ok(my $dt = DateTime::Format::Sybase->parse_datetime($sample_dt));
@@ -75,8 +72,33 @@ SQL
     );
     is( $row->$col, $dt, 'DateTime roundtrip' );
   }
+
+  # test a computed datetime column
+  eval { $schema->storage->dbh->do("DROP TABLE track") };
+  $schema->storage->dbh->do(<<"SQL");
+CREATE TABLE track (
+   trackid INT IDENTITY PRIMARY KEY,
+   cd INT NULL,
+   position INT NULL,
+   title VARCHAR(100) NULL,
+   last_updated_on DATETIME NULL,
+   last_updated_at AS getdate(),
+   small_dt SMALLDATETIME NULL
+)
+SQL
+
+  my $now     = DateTime->now;
+  sleep 1;
+  my $new_row = $schema->resultset('Track')->create({});
+  $new_row->discard_changes;
+
+  lives_and {
+    cmp_ok (($new_row->last_updated_at - $now)->seconds, '>=', 1)
+  } 'getdate() computed column works';
 }
 
+done_testing;
+
 # clean up our mess
 END {
   if (my $dbh = eval { $schema->storage->_dbh }) {
diff --git a/t/lib/DBICTest/Schema/ComputedColumn.pm b/t/lib/DBICTest/Schema/ComputedColumn.pm
new file mode 100644 (file)
index 0000000..6832b3e
--- /dev/null
@@ -0,0 +1,34 @@
+package # hide from PAUSE 
+    DBICTest::Schema::ComputedColumn;
+
+# for sybase and mssql computed column tests
+
+use base qw/DBICTest::BaseResult/;
+
+__PACKAGE__->table('computed_column_test');
+
+__PACKAGE__->add_columns(
+  'id' => {
+    data_type => 'integer',
+    is_auto_increment => 1,
+  },
+  'a_computed_column' => {
+    data_type => undef,
+    is_nullable => 0,
+    default_value => \'getdate()',
+  },
+  'a_timestamp' => {
+    data_type => 'timestamp',
+    is_nullable => 0,
+  },
+  'charfield' => {
+    data_type => 'varchar',
+    size => 20,
+    default_value => 'foo',
+    is_nullable => 0,
+  }
+);
+
+__PACKAGE__->set_primary_key('id');
+
+1;
index 880227f..4d7905f 100644 (file)
@@ -1,6 +1,6 @@
 -- 
 -- Created by SQL::Translator::Producer::SQLite
--- Created on Thu Jan 28 11:26:22 2010
+-- Created on Sat Jan 30 19:18:55 2010
 -- 
 ;