Commit | Line | Data |
265c2b91 |
1 | package App::IdiotBox::Store::SQLite; |
2 | |
3 | use strict; |
4 | use warnings FATAL => 'all'; |
5 | use DBIx::Data::Store; |
6 | use DBIx::Data::Store::CRUD; |
7 | use App::IdiotBox::DataSet; |
8 | use Scalar::Util qw(weaken); |
9 | |
10 | my (%BIND, %SQL); |
11 | |
12 | %BIND = ( |
13 | recent_announcements => { |
14 | class => { |
15 | inflate => sub { |
16 | my ($self, $obj) = @_; |
17 | bless($obj, 'App::IdiotBox::Announcement'); |
18 | bless($obj->{bucket}, 'App::IdiotBox::Bucket'); |
19 | $obj; |
20 | }, |
21 | deflate => sub { |
22 | my ($self, $obj) = @_; |
23 | my %raw = %$obj; |
265c2b91 |
24 | \%raw; |
25 | } |
26 | }, |
27 | set_over => [ 'id' ], |
28 | }, |
29 | buckets => { |
30 | class => { |
31 | inflate => sub { |
32 | my ($self, $obj) = @_; |
33 | bless($obj, 'App::IdiotBox::Bucket'); |
34 | weaken (my $weak = $obj); |
35 | $obj->{videos} = _bind_set('bucket_videos', |
36 | { |
37 | raw_store => $self->_store->raw_store, |
ebba317f |
38 | implicit_arguments => { 'bucket.slug' => $obj->{slug} }, |
265c2b91 |
39 | }, |
40 | { |
41 | class => { |
42 | inflate => sub { |
43 | my ($self, $obj) = @_; |
44 | bless($obj, 'App::IdiotBox::Video'); |
45 | weaken($obj->{bucket} = $weak); |
46 | $obj; |
47 | }, |
48 | deflate => sub { |
49 | my ($self, $obj) = @_; |
50 | my %raw = %$obj; |
51 | delete $raw{bucket}; |
52 | \%raw; |
53 | }, |
54 | } |
55 | } |
56 | ); |
57 | $obj; |
58 | }, |
59 | deflate => sub { |
60 | my ($self, $obj) = @_; |
61 | my %raw = %$obj; |
62 | delete $raw{videos}; |
63 | \%raw; |
64 | } |
65 | }, |
66 | set_over => [ 'slug' ], |
67 | }, |
68 | bucket_videos => { |
69 | set_over => [ 'slug' ] |
70 | }, |
71 | ); |
72 | |
73 | %SQL = ( |
74 | recent_announcements => { |
75 | select_column_order => [ qw( |
76 | id made_at video_count bucket.slug bucket.name bucket.video_count |
77 | ) ], |
78 | select_sql => q{ |
79 | SELECT |
80 | announcement.id, announcement.made_at, COUNT(DISTINCT my_videos.slug), |
81 | bucket.slug, bucket.name, COUNT(DISTINCT all_videos.slug) |
82 | FROM |
83 | announcements announcement |
84 | JOIN buckets bucket |
85 | ON bucket.slug = announcement.bucket_slug |
86 | JOIN videos my_videos |
87 | ON my_videos.announcement_id = announcement.id |
88 | JOIN videos all_videos |
89 | ON all_videos.bucket_slug = announcement.bucket_slug |
90 | JOIN announcements all_announcements |
91 | ON all_announcements.bucket_slug = announcement.bucket_slug |
92 | GROUP BY |
93 | announcement.made_at, bucket.slug, bucket.name |
94 | HAVING |
95 | announcement.made_at = MAX(all_announcements.made_at) |
96 | ORDER BY |
97 | announcement.made_at DESC |
98 | }, |
ebba317f |
99 | insert_command_constructor => sub { |
100 | require DBIx::Data::Store::Command::Insert::LastInsertId; |
101 | my $self = shift; |
102 | DBIx::Data::Store::Command::Insert::LastInsertId->new( |
103 | id_column => 'id', |
104 | raw_store => $self->raw_store, |
105 | insert_call_command => $self->raw_store->new_call_command(@_) |
106 | ); |
107 | }, |
108 | insert_sql => q{ |
109 | INSERT INTO announcements |
110 | (bucket_slug, made_at) |
111 | VALUES |
112 | (?, ?) |
113 | }, |
114 | insert_argument_order => [ qw(bucket.slug made_at) ], |
265c2b91 |
115 | }, |
116 | buckets => { |
117 | select_column_order => [ qw(slug name) ], |
118 | select_single_sql => q{ |
119 | SELECT slug, name |
120 | FROM buckets |
121 | WHERE slug = ? |
122 | }, |
ebba317f |
123 | select_sql => q{ |
124 | SELECT slug, name |
125 | FROM buckets |
126 | }, |
265c2b91 |
127 | select_single_argument_order => [ 'slug' ], |
128 | }, |
129 | bucket_videos => { |
130 | select_column_order => [ qw(slug name author details) ], |
131 | select_sql => q{ |
132 | SELECT slug, name, author, details |
133 | FROM videos |
134 | WHERE bucket_slug = ? |
ebba317f |
135 | ORDER BY name |
265c2b91 |
136 | }, |
ebba317f |
137 | select_argument_order => [ 'bucket.slug' ], |
265c2b91 |
138 | select_single_sql => q{ |
139 | SELECT slug, name, author, details |
140 | FROM videos |
141 | WHERE bucket_slug = ? AND slug = ? |
142 | }, |
ebba317f |
143 | select_single_argument_order => [ qw(bucket.slug slug) ], |
144 | insert_sql => q{ |
145 | INSERT INTO videos |
146 | (announcement_id, bucket_slug, slug, name, author, details) |
147 | VALUES |
148 | (?, ?, ?, ?, ?, '') |
149 | }, |
150 | insert_argument_order => [ |
151 | qw(announcement.id bucket.slug slug name author) |
152 | ], |
265c2b91 |
153 | }, |
154 | ); |
155 | |
156 | sub bind { |
157 | my ($class, $idiotbox) = @_; |
158 | bless({ idiotbox => $idiotbox }, $class)->_bind; |
159 | } |
160 | |
265c2b91 |
161 | sub _new_db_store { |
71a02d85 |
162 | DBIx::Data::Store->connect("dbi:SQLite:$_[1]"); |
265c2b91 |
163 | } |
164 | |
165 | sub _bind { |
166 | my $self = shift; |
167 | my $idiotbox = $self->{idiotbox}; |
168 | |
71a02d85 |
169 | my $db_store = $self->_new_db_store($idiotbox->config->{db_file}); |
265c2b91 |
170 | |
171 | foreach my $to_bind (qw(recent_announcements buckets)) { |
172 | $idiotbox->{$to_bind} = _bind_set($to_bind, { raw_store => $db_store }); |
173 | } |
174 | $idiotbox; |
175 | } |
176 | |
177 | sub _bind_set { |
178 | my ($type, $store_args, $set_args) = @_; |
179 | my $store = DBIx::Data::Store::CRUD->new({ |
180 | %{$SQL{$type}}, |
181 | %{$store_args}, |
182 | }); |
183 | return App::IdiotBox::DataSet->new({ |
184 | %{$BIND{$type}}, |
185 | store => $store, |
186 | %{$set_args||{}}, |
187 | }); |
188 | } |
189 | |
190 | 1; |