1#!/usr/bin/perl -w 2 3use strict; 4 5use Test::More tests => 1 + (2 * 13); 6 7BEGIN 8{ 9 require 't/test-lib.pl'; 10 use_ok('Rose::DB::Object::Loader'); 11} 12 13our %Have; 14 15# 16# Tests 17# 18 19#$Rose::DB::Object::Manager::Debug = 1; 20 21foreach my $db_type (qw(pg mysql)) 22{ 23 SKIP: 24 { 25 skip("$db_type tests", 13) unless($Have{$db_type}); 26 } 27 28 next unless($Have{$db_type}); 29 30 Rose::DB->default_type($db_type); 31 32 my $class_prefix = ucfirst($db_type); 33 34 my $loader = 35 Rose::DB::Object::Loader->new( 36 db => Rose::DB->new, 37 class_prefix => $class_prefix); 38 39 my @classes = $loader->make_classes(include_tables => '^rose_db_object_test$'); 40 41 my $object_class = $class_prefix . '::RoseDbObjectTest'; 42 my $manager_class = $object_class . '::Manager'; 43 44 my $data = "\000\001\002\003\004\005" x 10; 45 46 # Standard save 47 48 my $o = $object_class->new(num => 123, data => $data); 49 $o->save; 50 51 $o = $object_class->new(id => $o->id)->load; 52 is($o->data, $data, "save 1 - $db_type"); 53 54 $o->save; 55 56 $o = $object_class->new(id => $o->id)->load; 57 is($o->data, $data, "save 2 - $db_type"); 58 59 # Changes only 60 61 my $short_data = "\000\001\002\003\004\005"; 62 63 $o->data($short_data); 64 $o->save(changes_only => 1); 65 66 $o = $object_class->new(id => $o->id)->load; 67 is($o->data, $short_data, "update changes only - $db_type"); 68 69 $o = $object_class->new(data => $short_data); 70 $o->save(changes_only => 1); 71 72 $o = $object_class->new(id => $o->id)->load; 73 is($o->data, $short_data, "insert changes only - $db_type"); 74 75 # On duplicate key update 76 77 if($o->db->supports_on_duplicate_key_update) 78 { 79 # Force the bind_param code to be triggered (should be harmless) 80 local $object_class->meta->{'dbi_requires_bind_param'}{$o->db->{'id'}} = 1; 81 82 my $data = "\000\001\002"; 83 84 $o->data($data); 85 $o->insert(on_duplicate_key_update => 1); 86 87 $o = $object_class->new(id => $o->id)->load; 88 is($o->data, $data, "on duplicate key update - $db_type"); 89 } 90 else 91 { 92 ok(1, "on duplicate key update not supported - $db_type"); 93 } 94 95 # 96 # Allow inline column values 97 # 98 99 $object_class->meta->allow_inline_column_values(1); 100 $manager_class->delete_rose_db_object_test(all => 1); 101 102 $data = "\000\001\002\003\004\005" x 10; 103 104 # Standard save 105 106 $o = $object_class->new(num => 123, data => $data); 107 108 $o->save; 109 110 $o = $object_class->new(id => $o->id)->load; 111 is($o->data, $data, "inline - save 1 - $db_type"); 112 113 $o->save; 114 115 $o = $object_class->new(id => $o->id)->load; 116 is($o->data, $data, "inline - save 2 - $db_type"); 117 118 # Changes only 119 120 $short_data = "\000\001\002\003\004\005"; 121 122 $o->data($short_data); 123 $o->save(changes_only => 1); 124 125 $o = $object_class->new(id => $o->id)->load; 126 is($o->data, $short_data, "inline - update changes only - $db_type"); 127 128 $o = $object_class->new(data => $short_data); 129 $o->save(changes_only => 1); 130 131 $o = $object_class->new(id => $o->id)->load; 132 is($o->data, $short_data, "inline - insert changes only - $db_type"); 133 134 # On duplicate key update 135 136 if($o->db->supports_on_duplicate_key_update) 137 { 138 # Force the bind_param code to be triggered (should be harmless) 139 local $object_class->meta->{'dbi_requires_bind_param'}{$o->db->{'id'}} = 1; 140 141 my $data = "\000\001\002"; 142 143 $o->data($data); 144 $o->insert(on_duplicate_key_update => 1); 145 146 $o = $object_class->new(id => $o->id)->load; 147 is($o->data, $data, "inline - on duplicate key update - $db_type"); 148 } 149 else 150 { 151 ok(1, "inline - on duplicate key update not supported - $db_type"); 152 } 153 154 # 155 # Manager 156 # 157 158 my $os = 159 $manager_class->get_rose_db_object_test( 160 query => [ data => $o->data, id => $o->id ]); 161 162 ok($os && @$os == 1 && $os->[0]->id == $o->id, "manager 1 - $db_type"); 163 164 $os = 165 $manager_class->get_rose_db_object_test( 166 query => 167 [ 168 data => [ "\000\001", $o->data ], 169 or => 170 [ 171 data => [ "\000\002", $o->data ], 172 id => { ne => [ 123, 456 ] }, 173 ], 174 id => $o->id ]); 175 176 ok($os && @$os == 1 && $os->[0]->id == $o->id, "manager 2 - $db_type"); 177 178 #local $Rose::DB::Object::Manager::Debug = 1; 179 $os = 180 $manager_class->get_rose_db_object_test( 181 query => 182 [ 183 data => [ "\000\001", $o->data ], 184 num => undef, 185 or => 186 [ 187 data => [ "\000\002", $o->data ], 188 id => { ne => [ 123, 456 ] }, 189 or => 190 [ 191 data => [ "\001\003", $o->data ], 192 data => { ne => "\000" }, 193 id => { ne => undef }, 194 num => undef, 195 '!data' => "\002\003", 196 data => $o->data, 197 ] 198 ], 199 id => $o->id ]); 200 201 ok($os && @$os == 1 && $os->[0]->id == $o->id, "manager 3 - $db_type"); 202} 203 204BEGIN 205{ 206 our %Have; 207 208 # 209 # PostgreSQL 210 # 211 212 my $dbh; 213 214 eval 215 { 216 $dbh = Rose::DB->new('pg_admin')->retain_dbh() 217 or die Rose::DB->error; 218 }; 219 220 if(!$@ && $dbh) 221 { 222 $Have{'pg'} = 1; 223 $Have{'pg_with_schema'} = 1; 224 225 # Drop existing tables and create schema, ignoring errors 226 { 227 local $dbh->{'RaiseError'} = 0; 228 local $dbh->{'PrintError'} = 0; 229 $dbh->do('DROP TABLE rose_db_object_test'); 230 } 231 232 $dbh->do(<<"EOF"); 233CREATE TABLE rose_db_object_test 234( 235 id SERIAL PRIMARY KEY, 236 num INT, 237 data BYTEA 238) 239EOF 240 241 $dbh->disconnect; 242 } 243 244 # 245 # MySQL 246 # 247 248 eval 249 { 250 my $db = Rose::DB->new('mysql_admin'); 251 $dbh = $db->retain_dbh or die Rose::DB->error; 252 253 # Drop existing tables, ignoring errors 254 { 255 local $dbh->{'RaiseError'} = 0; 256 local $dbh->{'PrintError'} = 0; 257 $dbh->do('DROP TABLE rose_db_object_test'); 258 } 259 }; 260 261 if(!$@ && $dbh) 262 { 263 $Have{'mysql'} = 1; 264 265 $dbh->do(<<"EOF"); 266CREATE TABLE rose_db_object_test 267( 268 id INT AUTO_INCREMENT PRIMARY KEY, 269 num INT, 270 data BLOB 271) 272EOF 273 } 274} 275 276END 277{ 278 # Delete test table 279 280 if($Have{'pg'}) 281 { 282 # PostgreSQL 283 my $dbh = Rose::DB->new('pg_admin')->retain_dbh() 284 or die Rose::DB->error; 285 286 $dbh->do('DROP TABLE rose_db_object_test'); 287 $dbh->disconnect; 288 } 289 290 if($Have{'mysql'}) 291 { 292 # MySQL 293 my $dbh = Rose::DB->new('mysql_admin')->retain_dbh() 294 or die Rose::DB->error; 295 296 $dbh->do('DROP TABLE rose_db_object_test'); 297 $dbh->disconnect; 298 } 299} 300