Resolve $rsrc instance duality on metadata traversal
[dbsrgits/DBIx-Class.git] / t / 745db2.t
1 BEGIN { do "./t/lib/ANFANG.pm" or die ( $@ || $! ) }
2 use DBIx::Class::Optional::Dependencies -skip_all_without => 'test_rdbms_db2';
3
4 use strict;
5 use warnings;
6
7 use Test::More;
8 use Test::Exception;
9 use Try::Tiny;
10
11 use DBICTest;
12
13 my ($dsn, $user, $pass) = @ENV{map { "DBICTEST_DB2_${_}" } qw/DSN USER PASS/};
14 my $schema = DBICTest::Schema->connect($dsn, $user, $pass);
15
16 my $name_sep = $schema->storage->_dbh_get_info('SQL_QUALIFIER_NAME_SEPARATOR');
17
18 my $dbh = $schema->storage->dbh;
19
20 # test RNO and name_sep detection
21
22 is $schema->storage->sql_maker->name_sep, $name_sep,
23   'name_sep detection';
24
25 my $have_rno = try {
26   $dbh->selectrow_array(
27 "SELECT row_number() OVER (ORDER BY 1) FROM sysibm${name_sep}sysdummy1"
28   );
29   1;
30 };
31
32 is $schema->storage->sql_maker->limit_dialect,
33   ($have_rno ? 'RowNumberOver' : 'FetchFirst'),
34   'limit_dialect detection';
35
36 eval { $dbh->do("DROP TABLE artist") };
37
38 $dbh->do("CREATE TABLE artist (artistid INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), name VARCHAR(255), charfield CHAR(10), rank INTEGER DEFAULT 13);");
39
40 my $ars = $schema->resultset('Artist');
41 is ( $ars->count, 0, 'No rows at first' );
42
43 # test primary key handling
44 my $new = $ars->create({ name => 'foo' });
45 ok($new->artistid, "Auto-PK worked");
46
47 # test explicit key spec
48 $new = $ars->create ({ name => 'bar', artistid => 66 });
49 is($new->artistid, 66, 'Explicit PK worked');
50 $new->discard_changes;
51 is($new->artistid, 66, 'Explicit PK assigned');
52
53 # test populate
54 lives_ok (sub {
55   my @pop;
56   for (1..2) {
57     push @pop, { name => "Artist_$_" };
58   }
59   $ars->populate (\@pop);
60 });
61
62 # test populate with explicit key
63 lives_ok (sub {
64   my @pop;
65   for (1..2) {
66     push @pop, { name => "Artist_expkey_$_", artistid => 100 + $_ };
67   }
68   $ars->populate (\@pop);
69 });
70
71 # count what we did so far
72 is ($ars->count, 6, 'Simple count works');
73
74 # test LIMIT support
75 my $lim = $ars->search( {},
76   {
77     rows => 3,
78     offset => 4,
79     order_by => 'artistid'
80   }
81 );
82 is( $lim->count, 2, 'ROWS+OFFSET count ok' );
83 is( $lim->all, 2, 'Number of ->all objects matches count' );
84
85 # Limit with select-lock
86 {
87   local $TODO = "Seems we can't SELECT ... FOR ... on subqueries";
88   lives_ok {
89     $schema->txn_do (sub {
90       isa_ok (
91         $schema->resultset('Artist')->find({artistid => 1}, {for => 'update', rows => 1}),
92         'DBICTest::Schema::Artist',
93       );
94     });
95   } 'Limited FOR UPDATE select works';
96 }
97
98 # test iterator
99 $lim->reset;
100 is( $lim->next->artistid, 101, "iterator->next ok" );
101 is( $lim->next->artistid, 102, "iterator->next ok" );
102 is( $lim->next, undef, "next past end of resultset ok" );
103
104 # test FetchFirst limit dialect syntax
105 {
106   local $schema->storage->sql_maker->{limit_dialect} = 'FetchFirst';
107
108   my $lim = $ars->search({}, {
109     rows => 3,
110     offset => 2,
111     order_by => 'artistid',
112   });
113
114   is $lim->count, 3, 'fetch first limit count ok';
115
116   is $lim->all, 3, 'fetch first number of ->all objects matches count';
117
118   is $lim->next->artistid, 3, 'iterator->next ok';
119   is $lim->next->artistid, 66, 'iterator->next ok';
120   is $lim->next->artistid, 101, 'iterator->next ok';
121   is $lim->next, undef, 'iterator->next past end of resultset ok';
122 }
123
124 my $test_type_info = {
125     'artistid' => {
126         'data_type' => 'INTEGER',
127         'is_nullable' => 0,
128         'size' => 10
129     },
130     'name' => {
131         'data_type' => 'VARCHAR',
132         'is_nullable' => 1,
133         'size' => 255
134     },
135     'charfield' => {
136         'data_type' => 'CHAR',
137         'is_nullable' => 1,
138         'size' => 10
139     },
140     'rank' => {
141         'data_type' => 'INTEGER',
142         'is_nullable' => 1,
143         'size' => 10
144     },
145 };
146
147
148 my $type_info = $schema->storage->columns_info_for('artist');
149 is_deeply($type_info, $test_type_info, 'columns_info_for - column data types');
150
151 done_testing;
152
153 # clean up our mess
154 END {
155   my $dbh = eval { $schema->storage->_dbh };
156   $dbh->do("DROP TABLE artist") if $dbh;
157   undef $schema;
158 }