Commit | Line | Data |
b974984a |
1 | package DBIx::Class::DeploymentHandler; |
2 | |
a65184c8 |
3 | # ABSTRACT: Extensible DBIx::Class deployment |
4 | |
b974984a |
5 | use Moose; |
b974984a |
6 | |
c4f4d4a2 |
7 | extends 'DBIx::Class::DeploymentHandler::Dad'; |
41219a5d |
8 | # a single with would be better, but we can't do that |
9 | # see: http://rt.cpan.org/Public/Bug/Display.html?id=46347 |
4f73e4ac |
10 | with 'DBIx::Class::DeploymentHandler::WithApplicatorDumple' => { |
36009fc8 |
11 | interface_role => 'DBIx::Class::DeploymentHandler::HandlesDeploy', |
12 | class_name => 'DBIx::Class::DeploymentHandler::DeployMethod::SQL::Translator', |
13 | delegate_name => 'deploy_method', |
5020d6a2 |
14 | attributes_to_assume => [qw(schema schema_version)], |
704577c7 |
15 | attributes_to_copy => [qw( |
16 | ignore_ddl databases script_directory sql_translator_args force_overwrite |
17 | )], |
36009fc8 |
18 | }, |
19 | 'DBIx::Class::DeploymentHandler::WithApplicatorDumple' => { |
20 | interface_role => 'DBIx::Class::DeploymentHandler::HandlesVersioning', |
21 | class_name => 'DBIx::Class::DeploymentHandler::VersionHandler::Monotonic', |
22 | delegate_name => 'version_handler', |
23 | attributes_to_assume => [qw( database_version schema_version to_version )], |
24 | }, |
25 | 'DBIx::Class::DeploymentHandler::WithApplicatorDumple' => { |
26 | interface_role => 'DBIx::Class::DeploymentHandler::HandlesVersionStorage', |
27 | class_name => 'DBIx::Class::DeploymentHandler::VersionStorage::Standard', |
28 | delegate_name => 'version_storage', |
29 | attributes_to_assume => ['schema'], |
30 | }; |
41219a5d |
31 | with 'DBIx::Class::DeploymentHandler::WithReasonableDefaults'; |
2e68a8e1 |
32 | |
c8a2f7bd |
33 | sub prepare_version_storage_install { |
34 | my $self = shift; |
35 | |
d9917093 |
36 | $self->prepare_resultsource_install({ |
37 | result_source => $self->version_storage->version_rs->result_source |
38 | }); |
c8a2f7bd |
39 | } |
40 | |
41 | sub install_version_storage { |
42 | my $self = shift; |
43 | |
ba99ba44 |
44 | my $version = (shift||{})->{version} || $self->schema_version; |
45 | |
d9917093 |
46 | $self->install_resultsource({ |
ba99ba44 |
47 | result_source => $self->version_storage->version_rs->result_source, |
48 | version => $version, |
d9917093 |
49 | }); |
c8a2f7bd |
50 | } |
51 | |
d794b8ce |
52 | sub prepare_install { |
36821446 |
53 | $_[0]->prepare_deploy; |
54 | $_[0]->prepare_version_storage_install; |
d794b8ce |
55 | } |
56 | |
53de57ed |
57 | # the following is just a hack so that ->version_storage |
58 | # won't be lazy |
59 | sub BUILD { $_[0]->version_storage } |
2e68a8e1 |
60 | __PACKAGE__->meta->make_immutable; |
61 | |
88fecddb |
62 | sub dev_version_instaled { shift->database_version eq 'DEV' } |
63 | |
64 | use SQL::Translator; |
65 | sub install_dev_version { |
66 | my ($self, $extra) = @_; |
67 | |
68 | die 'roll back existing dev version before installing a new dev version' |
69 | if $self->dev_version_installed; |
70 | |
71 | my $from_schema = do { |
72 | my $t = SQL::Translator->new({ |
73 | debug => 0, |
74 | trace => 0, |
75 | parser => 'SQL::Translator::Parser::YAML', |
76 | }); |
77 | $t->translate($self->deploy_method->_ddl_protoschema_produce_filename( |
78 | $self->database_version, $self->script_directory |
79 | ) or die $t->error; |
80 | $t->schema; |
81 | }; |
82 | |
83 | my $to_schema = do { |
84 | my $t = SQL::Translator->new({ |
85 | parser => 'SQL::Translator::Parser::DBIx::Class', |
86 | parser_args => { |
87 | package => $self->schema, |
88 | }, |
89 | }); |
90 | $t->translate or die $t->error; |
91 | $t->schema; |
92 | }; |
93 | |
94 | my $db = $self->deploy_method->storage->sqlt_type; |
95 | |
96 | my @up = [SQL::Translator::Diff::schema_diff( |
97 | $source_schema, $db, |
98 | $dest_schema, $db, |
99 | $sqltargs |
100 | )]; |
101 | |
102 | my @down = [SQL::Translator::Diff::schema_diff( |
103 | $dest_schema, $db, |
104 | $source_schema, $db, |
105 | $sqltargs |
106 | )]; |
107 | |
108 | $self->deploy_method->_run_sql_array(\@up); |
109 | |
110 | $self->version_storage->version_rs->create({ |
111 | version => 'DEV', |
112 | upgrade_sql => \@up, |
113 | downgrade_sql => \@down, |
114 | extra => $extra, |
115 | }); |
116 | } |
117 | |
118 | sub remove_dev_version { |
119 | my ($self, $extra) = @_; |
120 | |
121 | die 'no dev version installed to remove' |
122 | unless $self->dev_version_installed; |
123 | |
124 | my ($dev_data, $to_version) = $self->version_storage |
125 | ->version_rs |
126 | ->search(undef, { |
127 | order_by => { -desc => 'id' }, |
128 | rows => 2, |
129 | })->all; |
130 | |
131 | $self->deploy_method->_run_sql_array(\@sql_to_run); |
132 | |
133 | $self->version_storage->version_rs->create({ |
134 | version => $to_version->version, |
135 | upgrade_sql => \@sql_to_run, |
136 | downgrade_sql => [], # not meant to be "reverted" |
137 | extra => $extra |
138 | }) |
139 | } |
140 | |
b974984a |
141 | 1; |
61847972 |
142 | |
d1ae780e |
143 | #vim: ts=2 sw=2 expandtab |
144 | |
145 | __END__ |
146 | |
a65184c8 |
147 | =head1 SYNOPSIS |
e9c19a98 |
148 | |
149 | use aliased 'DBIx::Class::DeploymentHandler' => 'DH'; |
150 | my $s = My::Schema->connect(...); |
151 | |
152 | my $dh = DH->new({ |
02a7b8ac |
153 | schema => $s, |
154 | databases => 'SQLite', |
155 | sql_translator_args => { add_drop_table => 0 }, |
e9c19a98 |
156 | }); |
157 | |
f7e215c9 |
158 | $dh->prepare_install; |
e9c19a98 |
159 | |
160 | $dh->install; |
161 | |
162 | or for upgrades: |
163 | |
164 | use aliased 'DBIx::Class::DeploymentHandler' => 'DH'; |
165 | my $s = My::Schema->connect(...); |
166 | |
167 | my $dh = DH->new({ |
02a7b8ac |
168 | schema => $s, |
169 | databases => 'SQLite', |
170 | sql_translator_args => { add_drop_table => 0 }, |
e9c19a98 |
171 | }); |
172 | |
c1326825 |
173 | $dh->prepare_upgrade({ |
174 | from_version => 1, |
175 | to_version => 2, |
176 | }); |
e9c19a98 |
177 | |
178 | $dh->upgrade; |
179 | |
180 | =head1 DESCRIPTION |
181 | |
8b810386 |
182 | C<DBIx::Class::DeploymentHandler> is, as its name suggests, a tool for |
e9c19a98 |
183 | deploying and upgrading databases with L<DBIx::Class>. It is designed to be |
184 | much more flexible than L<DBIx::Class::Schema::Versioned>, hence the use of |
185 | L<Moose> and lots of roles. |
186 | |
187 | C<DBIx::Class::DeploymentHandler> itself is just a recommended set of roles |
327868c9 |
188 | that we think will not only work well for everyone, but will also yield the |
8b810386 |
189 | best overall mileage. Each role it uses has its own nuances and |
e9c19a98 |
190 | documentation, so I won't describe all of them here, but here are a few of the |
191 | major benefits over how L<DBIx::Class::Schema::Versioned> worked (and |
192 | L<DBIx::Class::DeploymentHandler::Deprecated> tries to maintain compatibility |
193 | with): |
194 | |
195 | =over |
196 | |
e9c19a98 |
197 | =item * |
198 | |
199 | Downgrades in addition to upgrades. |
200 | |
201 | =item * |
202 | |
203 | Multiple sql files files per upgrade/downgrade/install. |
204 | |
205 | =item * |
206 | |
207 | Perl scripts allowed for upgrade/downgrade/install. |
208 | |
209 | =item * |
210 | |
211 | Just one set of files needed for upgrade, unlike before where one might need |
212 | to generate C<factorial(scalar @versions)>, which is just silly. |
213 | |
214 | =item * |
215 | |
216 | And much, much more! |
217 | |
218 | =back |
219 | |
220 | That's really just a taste of some of the differences. Check out each role for |
221 | all the details. |
222 | |
223 | =head1 WHERE IS ALL THE DOC?! |
224 | |
225 | C<DBIx::Class::DeploymentHandler> extends |
226 | L<DBIx::Class::DeploymentHandler::Dad>, so that's probably the first place to |
227 | look when you are trying to figure out how everything works. |
228 | |
961d42b1 |
229 | Next would be to look at all the pieces that fill in the blanks that |
e9c19a98 |
230 | L<DBIx::Class::DeploymentHandler::Dad> expects to be filled. They would be |
61627cf0 |
231 | L<DBIx::Class::DeploymentHandler::DeployMethod::SQL::Translator>, |
232 | L<DBIx::Class::DeploymentHandler::VersionHandler::Monotonic>, |
233 | L<DBIx::Class::DeploymentHandler::VersionStorage::Standard>, and |
e9c19a98 |
234 | L<DBIx::Class::DeploymentHandler::WithReasonableDefaults>. |
235 | |
236 | =method prepare_version_storage_install |
237 | |
238 | $dh->prepare_version_storage_install |
239 | |
240 | Creates the needed C<.sql> file to install the version storage and not the rest |
241 | of the tables |
242 | |
f7e215c9 |
243 | =method prepare_install |
244 | |
245 | $dh->prepare_install |
246 | |
247 | First prepare all the tables to be installed and the prepare just the version |
248 | storage |
249 | |
e9c19a98 |
250 | =method install_version_storage |
251 | |
252 | $dh->install_version_storage |
253 | |
254 | Install the version storage and not the rest of the tables |
255 | |
d1ae780e |
256 | =head1 THIS SUCKS |
257 | |
12d6fbad |
258 | You started your project and weren't using C<DBIx::Class::DeploymentHandler>? |
259 | Lucky for you I had you in mind when I wrote this doc. |
d1ae780e |
260 | |
8b810386 |
261 | First, |
262 | L<define the version|DBIx::Class::DeploymentHandler::Intro/Sample_database> |
263 | in your main schema file (maybe using C<$VERSION>). |
264 | |
265 | Then you'll want to just install the version_storage: |
d1ae780e |
266 | |
267 | my $s = My::Schema->connect(...); |
8b810386 |
268 | my $dh = DBIx::Class::DeploymentHandler->new({ schema => $s }); |
d1ae780e |
269 | |
270 | $dh->prepare_version_storage_install; |
271 | $dh->install_version_storage; |
34ac0a51 |
272 | |
12d6fbad |
273 | Then set your database version: |
274 | |
275 | $dh->add_database_version({ version => $s->version }); |
276 | |
ee37360d |
277 | Now you should be able to use C<DBIx::Class::DeploymentHandler> like normal! |
698944cb |
278 | |
a66bf899 |
279 | =head1 LOGGING |
280 | |
281 | This is a complex tool, and because of that sometimes you'll want to see |
8465e767 |
282 | what exactly is happening. The best way to do that is to use the built in |
283 | logging functionality. It the standard six log levels; C<fatal>, C<error>, |
284 | C<warn>, C<info>, C<debug>, and C<trace>. Most of those are pretty self |
285 | explanatory. Generally a safe level to see what all is going on is debug, |
286 | which will give you everything except for the exact SQL being run. |
287 | |
288 | To enable the various logging levels all you need to do is set an environment |
289 | variables: C<DBICDH_FATAL>, C<DBICDH_ERROR>, C<DBICDH_WARN>, C<DBICDH_INFO>, |
8b810386 |
290 | C<DBICDH_DEBUG>, and C<DBICDH_TRACE>. Each level can be set on its own, |
8465e767 |
291 | but the default is the first three on and the last three off, and the levels |
292 | cascade, so if you turn on trace the rest will turn on automatically. |
a66bf899 |
293 | |
698944cb |
294 | =head1 DONATIONS |
295 | |
296 | If you'd like to thank me for the work I've done on this module, don't give me |
297 | a donation. I spend a lot of free time creating free software, but I do it |
298 | because I love it. |
299 | |
300 | Instead, consider donating to someone who might actually need it. Obviously |
301 | you should do research when donating to a charity, so don't just take my word |
26983cf2 |
302 | on this. I like Children's Survival Fund: |
303 | L<http://www.childrenssurvivalfund.org>, but there are a host of other |
304 | charities that can do much more good than I will with your money. |