Original tests from Class::DBI::Plugin::DeepAbstractSearch
[dbsrgits/DBIx-Class.git] / t / cdbi-DeepAbstractSearch / 01_search.t
1 use strict;
2 use Test::More;
3
4 BEGIN {
5     eval "use DBD::SQLite";
6     plan $@ ? (skip_all => 'needs DBD::SQLite for testing')
7         : (tests => 19);
8 }
9
10 my $DB  = "t/testdb";
11 unlink $DB if -e $DB;
12
13 my @DSN = ("dbi:SQLite:dbname=$DB", '', '', { AutoCommit => 0 });
14
15 package Music::DBI;
16 use base qw(Class::DBI);
17 use Class::DBI::Plugin::DeepAbstractSearch;
18 __PACKAGE__->set_db(Main => @DSN);
19
20 my $sql = <<'SQL_END';
21
22 ---------------------------------------
23 -- Artists
24 ---------------------------------------
25 CREATE TABLE artists (
26         id INTEGER NOT NULL PRIMARY KEY,
27         name VARCHAR(32)
28 );
29
30 INSERT INTO artists VALUES (1, "Willie Nelson");
31 INSERT INTO artists VALUES (2, "Patsy Cline");
32
33 ---------------------------------------
34 -- Labels
35 ---------------------------------------
36 CREATE TABLE labels (
37         id INTEGER NOT NULL PRIMARY KEY,
38         name VARCHAR(32)
39 );
40
41 INSERT INTO labels VALUES (1, "Columbia");
42 INSERT INTO labels VALUES (2, "Sony");
43 INSERT INTO labels VALUES (3, "Supraphon");
44
45 ---------------------------------------
46 -- CDs
47 ---------------------------------------
48 CREATE TABLE cds (
49         id INTEGER NOT NULL PRIMARY KEY,
50         label INTEGER,
51         artist INTEGER,
52         title VARCHAR(32),
53         year INTEGER
54 );
55 INSERT INTO cds VALUES (1, 1, 1, "Songs", 2005);
56 INSERT INTO cds VALUES (2, 2, 1, "Read Headed Stanger", 2000);
57 INSERT INTO cds VALUES (3, 1, 1, "Wanted! The Outlaws", 2004);
58 INSERT INTO cds VALUES (4, 2, 1, "The Very Best of Willie Nelson", 1999);
59
60 INSERT INTO cds VALUES (5, 1, 2, "12 Greates Hits", 1999);
61 INSERT INTO cds VALUES (6, 2, 2, "Sweet Dreams", 1995);
62 INSERT INTO cds VALUES (7, 3, 2, "The Best of Patsy Cline", 1991);
63
64 ---------------------------------------
65 -- Tracks
66 ---------------------------------------
67 CREATE TABLE tracks (
68         id INTEGER NOT NULL PRIMARY KEY,
69         cd INTEGER,
70         position INTEGER,
71         title VARCHAR(32)
72 );
73 INSERT INTO tracks VALUES (1, 1, 1, "Songs: Track 1");
74 INSERT INTO tracks VALUES (2, 1, 2, "Songs: Track 2");
75 INSERT INTO tracks VALUES (3, 1, 3, "Songs: Track 3");
76 INSERT INTO tracks VALUES (4, 1, 4, "Songs: Track 4");
77
78 INSERT INTO tracks VALUES (5, 2, 1, "Read Headed Stanger: Track 1");
79 INSERT INTO tracks VALUES (6, 2, 2, "Read Headed Stanger: Track 2");
80 INSERT INTO tracks VALUES (7, 2, 3, "Read Headed Stanger: Track 3");
81 INSERT INTO tracks VALUES (8, 2, 4, "Read Headed Stanger: Track 4");
82
83 INSERT INTO tracks VALUES (9, 3, 1, "Wanted! The Outlaws: Track 1");
84 INSERT INTO tracks VALUES (10, 3, 2, "Wanted! The Outlaws: Track 2");
85
86 INSERT INTO tracks VALUES (11, 4, 1, "The Very Best of Willie Nelson: Track 1");
87 INSERT INTO tracks VALUES (12, 4, 2, "The Very Best of Willie Nelson: Track 2");
88 INSERT INTO tracks VALUES (13, 4, 3, "The Very Best of Willie Nelson: Track 3");
89 INSERT INTO tracks VALUES (14, 4, 4, "The Very Best of Willie Nelson: Track 4");
90 INSERT INTO tracks VALUES (15, 4, 5, "The Very Best of Willie Nelson: Track 5");
91 INSERT INTO tracks VALUES (16, 4, 6, "The Very Best of Willie Nelson: Track 6");
92
93 INSERT INTO tracks VALUES (17, 5, 1, "12 Greates Hits: Track 1");
94 INSERT INTO tracks VALUES (18, 5, 2, "12 Greates Hits: Track 2");
95 INSERT INTO tracks VALUES (19, 5, 3, "12 Greates Hits: Track 3");
96 INSERT INTO tracks VALUES (20, 5, 4, "12 Greates Hits: Track 4");
97
98 INSERT INTO tracks VALUES (21, 6, 1, "Sweet Dreams: Track 1");
99 INSERT INTO tracks VALUES (22, 6, 2, "Sweet Dreams: Track 2");
100 INSERT INTO tracks VALUES (23, 6, 3, "Sweet Dreams: Track 3");
101 INSERT INTO tracks VALUES (24, 6, 4, "Sweet Dreams: Track 4");
102
103 INSERT INTO tracks VALUES (25, 7, 1, "The Best of Patsy Cline: Track 1");
104 INSERT INTO tracks VALUES (26, 7, 2, "The Best of Patsy Cline: Track 2");
105
106 SQL_END
107
108 foreach my $statement (split /;/, $sql) {
109         $statement =~ s/^\s*//gs;
110         $statement =~ s/\s*$//gs;
111         next unless $statement;
112         Music::DBI->db_Main->do($statement) or die "$@ $!";
113 }
114
115 Music::DBI->dbi_commit;
116
117 package Music::Artist;
118 use base 'Music::DBI';
119 Music::Artist->table('artists');
120 Music::Artist->columns(All => qw/id name/);
121 Music::Artist->has_many(cds => 'Music::CD');
122
123 package Music::Label;
124 use base 'Music::DBI';
125 Music::Label->table('labels');
126 Music::Label->columns(All => qw/id name/);
127 Music::Label->has_many(cds => 'Music::CD');
128
129 package Music::CD;
130 use base 'Music::DBI';
131 Music::CD->table('cds');
132 Music::CD->columns(All => qw/id label artist title year/);
133 Music::CD->has_many(tracks => 'Music::Track');
134 Music::CD->has_a(artist => 'Music::Artist');
135 Music::CD->has_a(label => 'Music::Label');
136
137 package Music::Track;
138 use base 'Music::DBI';
139 Music::Track->table('tracks');
140 Music::Track->columns(All => qw/id cd position title/);
141 Music::Track->has_a(cd => 'Music::CD');
142
143 package main;
144
145 {
146         my $where = { };
147         my $attr;
148         my @artists = Music::Artist->deep_search_where($where, $attr);
149         is_deeply [ sort @artists ], [ 1, 2 ],          "all without order";
150 }
151
152 {
153         my $where = { };
154         my $attr = { order_by => 'name' };
155         my @artists = Music::Artist->deep_search_where($where, $attr);
156         is_deeply \@artists, [ 2, 1 ],          "all with ORDER BY name";
157 }
158
159 {
160         my $where = { };
161         my $attr = { order_by => 'name DESC' };
162         my @artists = Music::Artist->deep_search_where($where, $attr);
163         is_deeply \@artists, [ 1, 2 ],          "all with ORDER BY name DESC";
164 }
165
166 {
167         my $where = { name => { -like => 'Patsy Cline' }, };
168         my $attr;
169         my @artists = Music::Artist->deep_search_where($where, $attr);
170         is_deeply \@artists, [ 2 ],                     "simple search";
171 }
172
173 {
174         my $where = { 'artist.name' => 'Patsy Cline' };
175         my $attr = { } ;
176         my @cds = Music::CD->deep_search_where($where, $attr);
177         is_deeply [ sort @cds ], [ 5, 6, 7 ],   "Patsy's CDs";
178 }
179
180 {
181         my $where = { 'artist.name' => 'Patsy Cline' };
182         my $attr = { order_by => "title" } ;
183         my @cds = Music::CD->deep_search_where($where, $attr);
184         is_deeply [ @cds ], [ 5, 6, 7 ],                "Patsy's CDs by title";
185
186         my $count = Music::CD->count_deep_search_where($where);
187         is_deeply $count, 3,            "count Patsy's CDs by title";
188 }
189
190 {
191         my $where = { 'cd.title' => { -like => 'S%' }, };
192         my $attr = { order_by => "cd.title, title" } ;
193         my @cds = Music::Track->deep_search_where($where, $attr);
194         is_deeply [ @cds ], [1, 2, 3, 4, 21, 22, 23, 24 ],              "Tracks from CDs whose name starts with 'S'";
195 }
196
197 {
198         my $where = {
199                 'cd.artist.name' => { -like => 'W%' },
200                 'cd.year' => { '>' => 2000 },
201                 'position' => { '<' => 3 }
202                 };
203         my $attr = { order_by => "cd.title DESC, title" } ;
204         my @cds = Music::Track->deep_search_where($where, $attr);
205         is_deeply [ @cds ], [ 9, 10, 1, 2 ],            "First 2 tracks from W's albums after 2000 ";
206
207         my $count = Music::Track->count_deep_search_where($where);
208         is_deeply $count, 4,            "Count First 2 tracks from W's albums after 2000";
209 }
210
211 {
212         my $where = {
213                 'cd.artist.name' => { -like => 'W%' },
214                 'cd.year' => { '>' => 2000 },
215                 'position' => { '<' => 3 }
216                 };
217         my $attr = { order_by => [ 'cd.title DESC' , 'title' ] } ;
218         my @cds = Music::Track->deep_search_where($where, $attr);
219         is_deeply [ @cds ], [ 9, 10, 1, 2 ],            "First 2 tracks from W's albums after 2000, array ref order ";
220
221         my $count = Music::Track->count_deep_search_where($where);
222         is_deeply $count, 4,            "Count First 2 tracks from W's albums after 2000, array ref order";
223 }
224
225 {
226         my $where = { 'cd.title' => [ -and => { -like => '%o%' }, { -like => '%W%' } ] };
227         my $attr = { order_by => [ 'cd.id' ] } ;
228
229         my @tracks = Music::Track->deep_search_where($where, $attr);
230         is_deeply [ @tracks ], [ 3, 3, 4, 4, 4, 4, 4, 4 ],              "Tracks from CD titles containing 'o' AND 'W'";
231 }
232
233 {
234         my $where = { 'cd.year' => [ 1995, 1999 ] };
235         my $attr = { order_by => [ 'cd.id' ] } ;
236
237         my @tracks = Music::Track->deep_search_where($where, $attr);
238         is_deeply [ @tracks ], [ 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6 ],
239                         "Tracks from CDs from 1995, 1999";
240 }
241
242 {
243         my $where = { 'cd.year' => { -in => [ 1995, 1999 ] } };
244         my $attr = { order_by => [ 'cd.id' ] } ;
245
246         my @tracks = Music::Track->deep_search_where($where, $attr);
247         is_deeply [ @tracks ], [ 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6 ],
248                         "Tracks from CDs in 1995, 1999";
249 }
250
251 {
252         my $where = { -and => [ 'cd.year' => [ 1995, 1999 ], position => { '<=', 2 } ] };
253         my $attr = { order_by => [ 'cd.id' ] } ;
254
255         my @tracks = Music::Track->deep_search_where($where, $attr);
256         is_deeply [ @tracks ], [ 4, 4, 5, 5, 6, 6 ],
257                         "First 2 tracks Tracks from CDs from 1995, 1999";
258 }
259
260 {
261         my $where = { -and => [ 'cd.year' => { -in => [ 1995, 1999 ] }, position => { '<=', 2 } ] };
262         my $attr = { order_by => [ 'cd.id' ] } ;
263
264         my @tracks = Music::Track->deep_search_where($where, $attr);
265         is_deeply [ @tracks ], [ 4, 4, 5, 5, 6, 6 ],
266                         "First 2 tracks Tracks from CDs in 1995, 1999";
267 }
268
269 {
270         my $where = { 'label.name' => { -in => [ 'Sony', 'Supraphon', 'Bogus' ] } };
271         my $attr = { order_by => [ 'id' ] } ;
272
273         my @cds = Music::CD->deep_search_where($where, $attr);
274         is_deeply [ @cds ], [ 2, 4, 6, 7 ],
275                         "CDs from Sony or Supraphon";
276 }
277
278 {
279         my $where = { 'label.name' => [ 'Sony', 'Supraphon', 'Bogus' ] };
280         my $attr = { order_by => [ 'id' ] } ;
281
282         my @cds = Music::CD->deep_search_where($where, $attr);
283         is_deeply [ @cds ], [ 2, 4, 6, 7 ],
284                         "CDs from Sony or Supraphon";
285 }
286
287 END { unlink $DB if -e $DB }
288