beginnings of IndexableBy
[dbsrgits/DBIx-Data-Store-old.git] / t / 01basic_collection.t
1 use Test::More;
2 use DBIx::Data::Store;
3 use DBIx::Data::Store::CRUD;
4 use DBIx::Data::Collection::Set;
5 use DBI;
6 use Scalar::Util qw(refaddr);
7
8 use Devel::Dwarn;
9
10 use strict;
11 use warnings FATAL => 'all';
12
13 my $dsn = 'dbi:SQLite:tmp.db';
14
15 sub sort_set {
16   sort { $a->{name} cmp $b->{name} } @_
17 }
18
19 sub setup_db {
20   unlink('tmp.db');
21   my $dbh = DBI->connect($dsn);
22   $dbh->do(q{
23     CREATE TABLE person (
24       id INTEGER NOT NULL PRIMARY KEY,
25       name VARCHAR(255) NOT NULL
26     )
27   });
28   my $pop = $dbh->prepare(q{INSERT INTO person (name) VALUES (?)});
29   my @names = qw(Joe Jim Bob Pterry);
30   $pop->execute($_) for @names;
31   return sort_set do {
32     my $id = 0; map +{ id => ++$id, name => $_ }, @names
33   };
34 }
35
36 my $db_store = DBIx::Data::Store->connect($dsn);
37
38 sub make_store {
39   my ($crud) = @_;
40   DBIx::Data::Store::CRUD->new(
41     raw_store => $db_store,
42     select_sql => q{SELECT id, name FROM person},
43     select_column_order => [ qw(id name) ],
44     %$crud
45   );
46 }
47
48 sub make_set {
49   my ($set, $crud, $class) = @_;
50   ($class || 'DBIx::Data::Collection::Set')->new(
51     set_over => [ 'id' ],
52     store => make_store($crud),
53     %$set
54   );
55 }
56
57 sub run_tests {
58
59   my @expect = setup_db;
60
61   my $set = make_set;
62
63   is_deeply([ sort_set $set->flatten ], \@expect, 'Basic data out ok (flatten)');
64
65   {
66     my $stream = $set->as_stream;
67
68     my @got; while (my ($next) = $stream->next) { push @got, $next }
69
70     is_deeply([ sort_set @got ], \@expect, 'Basic data out ok (stream)');
71   }
72
73   $set = make_set { class => 'Spoon' };
74
75   is_deeply(
76     [ sort_set $set->flatten ],
77     [ map { bless({ %$_ }, 'Spoon') } @expect ],
78     'Basic data with class out ok'
79   );
80
81   $set = make_set {}, {
82     insert_sql => q{INSERT INTO person (name) VALUES (?) },
83     insert_argument_order => [ 'name' ],
84     insert_command_constructor => sub {
85       require DBIx::Data::Store::Command::Insert::LastInsertId;
86       my $self = shift;
87       DBIx::Data::Store::Command::Insert::LastInsertId->new(
88         id_column => 'id',
89         raw_store => $self->raw_store,
90         insert_call_command => $self->raw_store->new_call_command(@_)
91       );
92     },
93     delete_sql => q{DELETE FROM person WHERE id = ?},
94     delete_argument_order => [ 'id' ],
95   };
96
97   my $doug = $set->add({ name => 'Doug' });
98
99   ok($doug->{id}, 'id filled out in new row');
100
101   my ($set_doug) = grep $_->{name} eq 'Doug', $set->flatten;
102
103   ok($set_doug, 'new row exists in flatten');
104
105   cmp_ok(refaddr($doug), '==', refaddr($set_doug), 'Same hashref returned');
106
107   $set->remove($doug);
108
109   is_deeply([ sort_set $set->flatten ], \@expect, 'new row gone after remove');
110
111   $set = make_set;
112
113   is_deeply([ sort_set $set->flatten ], \@expect, 'new row still gone on reload');
114
115   $set = make_set {}, {
116     update_sql => q{UPDATE person SET name = ? WHERE id = ?},
117     update_argument_order => [ qw(name id) ]
118   };
119
120   my ($pterry) = grep $_->{name} eq 'Pterry', $set->flatten;
121
122   $pterry->{name} = 'Sir Pterry'; # http://xrl.us/bgse8s
123
124   $set->_update_in_store($pterry);
125
126   $set = make_set;
127
128   my ($fresh_pterry) = grep $_->{name} =~ /Pterry/, $set->flatten;
129
130   is($fresh_pterry->{name}, 'Sir Pterry', 'Update persisted correctly');
131
132   $set = make_set {}, {
133     select_single_sql => q{SELECT id, name FROM person WHERE id = ?},
134     select_single_argument_order => [ qw(id) ],
135   };
136
137   my $pterry_id = (grep $_->{name} eq 'Pterry', @expect)[0]->{id};
138
139   $pterry = $set->get({ id => $pterry_id });
140
141   is($pterry->{name}, 'Sir Pterry', 'Pterry retrieved by id');
142
143   ok(!defined($set->get({ id => -1 })), 'undef on missing id');
144
145   $pterry->{name} = 'Pterry';
146
147   is_deeply([ sort_set $set->flatten ], \@expect, 'Basic data after fetch by id');
148
149   done_testing;
150 }
151
152 run_tests unless caller;
153
154 1;