Handle errors in perl scripts better and remove suport for $0
[dbsrgits/DBIx-Class-DeploymentHandler.git] / lib / DBIx / Class / DeploymentHandler / Manual / Intro.pod
1 package DBIx::Class::DeploymentHandler::Manual::Intro
2
3 # ABSTRACT: Introduction to DBIx::Class::DeploymentHandler
4
5 =pod
6
7 =head1 Why is DBIx::Class::DeploymentHandler worth using?
8
9 The most obvious reasons for using DBIx::Class::DeploymentHandler are
10 that it can run multiple SQL scripts as well as Perl scripts, unlike
11 DBIx::Class::Schema::Versioned, which only allows for a single SQL script.
12 It is also extremely extensible, and is an opportunity for a break from
13 backwards compatibility, so some regrettable decisions are avoided.
14
15 =head1 Sample database
16
17 Follow L<DBIx::Class::Manual::Intro> except for the parts setting up the
18 database.  After you are done, You should have the following files.
19
20  MyDatabase/
21  |-- Main
22  |   |-- Result
23  |   |   |-- Artist.pm
24  |   |   |-- Cd.pm
25  |   |   `-- Track.pm
26  |   `-- ResultSet
27  `-- Main.pm
28
29 Add a line like the following in your MyDatabase::Main file:
30
31  our $VERSION = 1;
32
33 or if you are using a newer Perl you can use the prettier syntax:
34
35  package MyDatabase::Main 1;
36
37 By default DBIx::Class::DeploymentHandler only uses integers for versions,
38 this makes versioning much simpler for figuring out what version is next
39 (or previous.) However, if you are using decimal numbers for versioning,
40 you will need to create a separate DeploymentHandler class, as per
41 L<DBIx::Class::DeploymentHandler::Cookbook::CustomResultSource>, and
42 set the VersionHandler class_name from Monotonic to ExplicitVersions or
43 DatabaseToSchemaVersions, as these handle version numbers as strings instead
44 of integers.
45
46 =head1 install.pl
47
48 Our first script, C<install.pl> reads our schema file and creates the tables
49 in the database.
50
51  #!/usr/bin/env perl
52
53  use strict;
54  use warnings;
55  use aliased 'DBIx::Class::DeploymentHandler' => 'DH';
56  use Getopt::Long;
57  use FindBin;
58  use lib "$FindBin::Bin/../lib";
59  use MyDatabase::Main;
60
61  my $force_overwrite = 0;
62
63  unless ( GetOptions( 'force_overwrite!' => \$force_overwrite ) ) {
64      die "Invalid options";
65  }
66
67  my $schema = MyDatabase::Main->connect('dbi:SQLite:mydb.db');
68
69  my $dh = DH->new(
70      {
71          schema              => $schema,
72          script_directory    => "$FindBin::Bin/../dbicdh",
73          databases           => 'SQLite',
74          sql_translator_args => { add_drop_table => 0 },
75          force_overwrite     => $force_overwrite,
76      }
77  );
78
79  $dh->prepare_install;
80  $dh->install;
81
82 =head2 dbicdh - Our migration scripts
83
84 Running C<install.pl> should create the following:
85
86  dbicdh/
87  |-- SQLite
88  |   `-- deploy
89  |       `-- 1
90  |           `-- 001-auto.sql
91  `-- _source
92      `-- deploy
93          `-- 1
94              `-- 001-auto.yml
95
96 You may wish to turn on L<debug logging|DBIx::Class::DeploymentHandler/"LOGGING"> 
97 before running this script by setting the environment variable C<DBICDH_TRACE> to
98 C<1>.
99
100 =head3 001-auto.sql
101
102 DBIx::Class::DeploymentHandler automatically generates SQL from our schema
103 that is suitable for SQLite
104
105 =head3 001-auto.yml
106
107 This contains all of the raw information about our schema that is then
108 translated into the sql.
109
110 =head3 Population
111
112 To truly take advantage of all DBIx::Class::DeploymentHandler offers, you
113 should probably be using it for population.  To do that all you need to do
114 is create a file called C<dbicdh/_common/deploy/1/create_artists.pl>:
115
116   sub {
117      my $schema = shift;
118      $schema->resultset('Artist')->populate([
119         ['artistid', 'name'],
120         [1,          'Marillion'],
121         [2,          'The Moutain Goats'],
122         [3,          'Ladyhawke'],
123      ]);
124   };
125
126 =head1 Upgrading
127
128 Add a line to MyDatabase/Main/Result/Cd.pm below
129
130  __PACKAGE__->add_columns(qw/ cdid artist title /);
131
132 with
133
134  __PACKAGE__->add_column(isbn => { is_nullable => 1 });
135
136 Aside: It must be nullable or have a default - otherwise the upgrade will
137 fail for logical reasons.  To be clear, if you add a column to a database and
138 it is not nullable and has no default, what will the existing rows contain
139 for that column?
140
141 Now you need to modify the schema version in your MyDatabase::Main file to
142 tell DBIx::Class::DeploymentHandler the new schema version number. You will
143 want to remember the earlier advice about integer version numbers.
144
145  our $VERSION = 2;
146
147 So here is our next script, C<upgrade.pl>:
148
149  #!/usr/bin/env perl
150  use strict;
151  use warnings;
152  use aliased 'DBIx::Class::DeploymentHandler' => 'DH';
153  use FindBin;
154  use lib "$FindBin::Bin/../lib";
155  use MyDatabase::Main;
156  my $schema = MyDatabase::Main->connect('dbi:SQLite:mydb');
157
158  my $dh = DH->new({
159     schema              => $schema,
160     script_directory    => "$FindBin::Bin/../dbicdh",
161     databases           => 'SQLite',
162     sql_translator_args => { add_drop_table => 0 },
163  });
164
165  $dh->prepare_deploy;
166  $dh->prepare_upgrade({ from_version => 1, to_version => 2});
167  $dh->upgrade;
168
169 Our script directory now looks like:
170
171   dbicdh/
172   |-- SQLite
173   |   |-- deploy
174   |   |   |-- 1
175   |   |   |   `-- 001-auto.sql
176   |   |   `-- 2
177   |   |       `-- 001-auto.sql
178   |   `-- upgrade
179   |       `-- 1-2
180   |           `-- 001-auto.sql
181   `-- _source
182       `-- deploy
183           |-- 1
184           |   `-- 001-auto.yml
185           `-- 2
186               `-- 001-auto.yml
187
188 The new C<deploy/001-auto.sql> and C<deploy/001-auto.yml> files are the
189 state of the db as at that version.  The C<upgrade/1-2/001-auto.sql> file
190 is the most interesting one; it is what gets your database from version 1 to 2.
191
192 And again, you can create a Perl file like we did previously with the
193 deploy stage.
194