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