1#!/usr/bin/perl -w 2 3use strict; 4 5use Test::More tests => 1 + (12 * 4); 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(mysql pg informix sqlite)) 22{ 23 SKIP: 24 { 25 skip("$db_type tests", 12) 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_(?:artist|album)s$'); 40 41 #foreach my $class (@classes) 42 #{ 43 # print $class->meta->perl_class_definition, "\n" if($class->can('meta')); 44 #} 45 46 my $artist_class = $class_prefix . '::RoseDbObjectArtist'; 47 my $album_class = $class_prefix . '::RoseDbObjectAlbum'; 48 49 # DBD::Informix chokes badly when prepare_cached() is used. 50 Rose::DB::Object::Metadata->dbi_prepare_cached($db_type eq 'informix' ? 0 : 1); 51 52 my $albums_method = 'rose_db_object_albums'; 53 54 foreach my $cascade (0, 1) 55 { 56 my @cascade = $cascade ? (cascade => 1) : (); 57 58 my $album = $album_class->new(id => 1, title => 'album1'); 59 $album->save(); 60 61 my $artist = $artist_class->new(id => 1, name => 'Rage'); 62 $artist->$albums_method($album->id); 63 $artist->save(@cascade); 64 65 ok($artist, "$cascade saved artist with albums - $db_type"); 66 67 $artist->$albums_method($album->id); 68 $artist->save(@cascade); 69 70 ok($artist, "$cascade re-saved artist albums = $db_type"); 71 72 $artist = $artist_class->new(id => $artist->id)->load; 73 is(scalar @{$artist->$albums_method() ||[]}, 1, "$cascade Check artist albums count - $db_type"); 74 is($artist->$albums_method()->[0]->id, $album->id, "$cascade Check artist album ids - $db_type"); 75 76 my @albums = $artist->$albums_method(); 77 $artist->$albums_method(@albums); 78 $artist->save; 79 $artist->$albums_method(@albums); 80 $artist->save; 81 82 $artist = $artist_class->new(id => $artist->id)->load; 83 is(scalar @{$artist->$albums_method() ||[]}, 1, "$cascade Check artist albums count 2 - $db_type"); 84 is($artist->$albums_method()->[0]->id, $album->id, "$cascade Check artist album ids 2 - $db_type"); 85 86 $artist->delete(cascade => 1); 87 } 88} 89 90BEGIN 91{ 92 our %Have; 93 94 # 95 # PostgreSQL 96 # 97 98 my $dbh; 99 100 eval 101 { 102 $dbh = Rose::DB->new('pg_admin')->retain_dbh() 103 or die Rose::DB->error; 104 }; 105 106 if(!$@ && $dbh) 107 { 108 $Have{'pg'} = 1; 109 $Have{'pg_with_schema'} = 1; 110 111 # Drop existing tables and create schema, ignoring errors 112 { 113 local $dbh->{'RaiseError'} = 0; 114 local $dbh->{'PrintError'} = 0; 115 $dbh->do('DROP TABLE rose_db_object_albums'); 116 $dbh->do('DROP TABLE rose_db_object_artists'); 117 } 118 119 $dbh->do(<<"EOF"); 120CREATE TABLE rose_db_object_artists 121( 122 id INT PRIMARY KEY NOT NULL, 123 name VARCHAR(255) NOT NULL, 124 125 UNIQUE(name) 126) 127EOF 128 129 $dbh->do(<<"EOF"); 130CREATE TABLE rose_db_object_albums 131( 132 id INT PRIMARY KEY NOT NULL, 133 artist_id INTEGER REFERENCES rose_db_object_artists (id), 134 title VARCHAR(255) NOT NULL 135) 136EOF 137 138 $dbh->disconnect; 139 } 140 141 # 142 # MySQL 143 # 144 145 eval 146 { 147 die "No InnoDB support" unless(mysql_supports_innodb()); 148 149 my $db = Rose::DB->new('mysql_admin'); 150 $dbh = $db->retain_dbh or die Rose::DB->error; 151 152 # Drop existing tables, ignoring errors 153 { 154 local $dbh->{'RaiseError'} = 0; 155 local $dbh->{'PrintError'} = 0; 156 $dbh->do('DROP TABLE rose_db_object_albums'); 157 $dbh->do('DROP TABLE rose_db_object_artists'); 158 } 159 }; 160 161 if(!$@ && $dbh) 162 { 163 $Have{'mysql'} = 1; 164 165 $dbh->do(<<"EOF"); 166CREATE TABLE rose_db_object_artists 167( 168 id INT PRIMARY KEY NOT NULL, 169 name VARCHAR(255) NOT NULL, 170 171 UNIQUE(name) 172) 173ENGINE=InnoDB 174EOF 175 176 $dbh->do(<<"EOF"); 177CREATE TABLE rose_db_object_albums 178( 179 id INT PRIMARY KEY NOT NULL, 180 artist_id INTEGER REFERENCES rose_db_object_artists (id), 181 title VARCHAR(255) NOT NULL, 182 183 INDEX(artist_id), 184 FOREIGN KEY (artist_id) REFERENCES rose_db_object_artists (id) 185) 186ENGINE=InnoDB 187EOF 188 189 $dbh->disconnect; 190 } 191 192 # 193 # Informix 194 # 195 196 eval 197 { 198 $dbh = Rose::DB->new('informix_admin')->retain_dbh() 199 or die Rose::DB->error; 200 }; 201 202 if(!$@ && $dbh) 203 { 204 $Have{'informix'} = 1; 205 206 # Drop existing tables and create schema, ignoring errors 207 { 208 local $dbh->{'RaiseError'} = 0; 209 local $dbh->{'PrintError'} = 0; 210 $dbh->do('DROP TABLE rose_db_object_albums'); 211 $dbh->do('DROP TABLE rose_db_object_artists'); 212 } 213 214 $dbh->do(<<"EOF"); 215CREATE TABLE rose_db_object_artists 216( 217 id INT PRIMARY KEY, 218 name VARCHAR(255) NOT NULL, 219 220 UNIQUE(name) 221) 222EOF 223 224 $dbh->do(<<"EOF"); 225CREATE TABLE rose_db_object_albums 226( 227 id INT PRIMARY KEY, 228 artist_id INT REFERENCES rose_db_object_artists (id), 229 title VARCHAR(255) NOT NULL 230) 231EOF 232 233 $dbh->disconnect; 234 } 235 236 # 237 # SQLite 238 # 239 240 eval 241 { 242 $dbh = Rose::DB->new('sqlite_admin')->retain_dbh() 243 or die Rose::DB->error; 244 }; 245 246 if(!$@ && $dbh) 247 { 248 $Have{'sqlite'} = 1; 249 250 # Drop existing tables and create schema, ignoring errors 251 { 252 local $dbh->{'RaiseError'} = 0; 253 local $dbh->{'PrintError'} = 0; 254 $dbh->do('DROP TABLE rose_db_object_albums'); 255 $dbh->do('DROP TABLE rose_db_object_artists'); 256 } 257 258 $dbh->do(<<"EOF"); 259CREATE TABLE rose_db_object_artists 260( 261 id INT PRIMARY KEY NOT NULL, 262 name VARCHAR(255) NOT NULL, 263 264 UNIQUE(name) 265) 266EOF 267 268 $dbh->do(<<"EOF"); 269CREATE TABLE rose_db_object_albums 270( 271 id INT PRIMARY KEY NOT NULL, 272 artist_id INTEGER REFERENCES rose_db_object_artists (id), 273 title VARCHAR(255) NOT NULL 274) 275EOF 276 277 $dbh->disconnect; 278 } 279} 280 281END 282{ 283 # Delete test table 284 285 if($Have{'pg'}) 286 { 287 # PostgreSQL 288 my $dbh = Rose::DB->new('pg_admin')->retain_dbh() 289 or die Rose::DB->error; 290 291 $dbh->do('DROP TABLE rose_db_object_albums'); 292 $dbh->do('DROP TABLE rose_db_object_artists'); 293 $dbh->disconnect; 294 } 295 296 if($Have{'mysql'}) 297 { 298 # MySQL 299 my $dbh = Rose::DB->new('mysql_admin')->retain_dbh() 300 or die Rose::DB->error; 301 302 $dbh->do('DROP TABLE rose_db_object_albums'); 303 $dbh->do('DROP TABLE rose_db_object_artists'); 304 $dbh->disconnect; 305 } 306 307 if($Have{'informix'}) 308 { 309 # Informix 310 my $dbh = Rose::DB->new('informix_admin')->retain_dbh() 311 or die Rose::DB->error; 312 313 $dbh->do('DROP TABLE rose_db_object_albums CASCADE'); 314 $dbh->do('DROP TABLE rose_db_object_artists CASCADE'); 315 $dbh->disconnect; 316 } 317 318 if($Have{'sqlite'}) 319 { 320 # Informix 321 my $dbh = Rose::DB->new('sqlite_admin')->retain_dbh() 322 or die Rose::DB->error; 323 324 $dbh->do('DROP TABLE rose_db_object_albums'); 325 $dbh->do('DROP TABLE rose_db_object_artists'); 326 $dbh->disconnect; 327 } 328} 329