preload __VERSION resultset
[dbsrgits/DBIx-Class-DeploymentHandler.git] / lib / DBIx / Class / DeploymentHandler.pm
CommitLineData
b974984a 1package DBIx::Class::DeploymentHandler;
2
3use Moose;
4use Method::Signatures::Simple;
12fdd461 5require DBIx::Class::Schema; # loaded for type constraint
6require DBIx::Class::Storage; # loaded for type constraint
7require DBIx::Class::ResultSet; # loaded for type constraint
e1f67607 8use Carp::Clan '^DBIx::Class::DeploymentHandler';
b974984a 9
10has schema => (
61847972 11 isa => 'DBIx::Class::Schema',
12 is => 'ro',
13 required => 1,
ceef4ff5 14 handles => [qw( schema_version )],
b974984a 15);
16
17has upgrade_directory => (
61847972 18 isa => 'Str',
19 is => 'ro',
20 required => 1,
ceef4ff5 21 default => 'upgrades',
b974984a 22);
23
24has backup_directory => (
61847972 25 isa => 'Str',
26 is => 'ro',
b974984a 27);
28
29has storage => (
61847972 30 isa => 'DBIx::Class::Storage',
31 is => 'ro',
32 lazy_build => 1,
b974984a 33);
34
7eec7eb7 35method _build_storage {
61847972 36 my $s = $self->schema->storage;
37 $s->_determine_driver;
38 $s
7eec7eb7 39}
12fdd461 40
b974984a 41has _filedata => (
61847972 42 isa => 'Str',
43 is => 'rw',
b974984a 44);
45
46has do_backup => (
61847972 47 isa => 'Bool',
48 is => 'ro',
49 default => undef,
b974984a 50);
51
52has do_diff_on_init => (
61847972 53 isa => 'Bool',
54 is => 'ro',
55 default => undef,
b974984a 56);
57
12fdd461 58has version_rs => (
61847972 59 isa => 'DBIx::Class::ResultSet',
60 is => 'ro',
61 lazy_build => 1,
62 handles => [qw( is_installed db_version )],
12fdd461 63);
64
30749dbf 65method _build_version_rs {
66 $self->schema->set_us_up_the_bomb;
67 $self->schema->resultset('__VERSION')
68}
12fdd461 69
70method backup { $self->storage->backup($self->backup_directory) }
b974984a 71
ceef4ff5 72method create_ddl_dir { $self->storage->create_ddl_dir( $self->schema, @_ ) }
73
b974984a 74method install($new_version) {
12fdd461 75 carp 'Install not possible as versions table already exists in database'
ceef4ff5 76 if $self->is_installed;
b974984a 77
12fdd461 78 $new_version ||= $self->schema_version;
b974984a 79
80 if ($new_version) {
12fdd461 81 $self->schema->deploy;
82
83 $self->version_rs->create({
61847972 84 version => $new_version,
85 # ddl => $ddl,
86 # upgrade_sql => $upgrade_sql,
12fdd461 87 });
b974984a 88 }
89}
90
12fdd461 91method create_upgrade_path { }
b974984a 92
12fdd461 93method ordered_schema_versions { }
b974984a 94
95method upgrade {
12fdd461 96 my $db_version = $self->db_version;
97 my $schema_version = $self->schema_version;
b974984a 98
b974984a 99 unless ($db_version) {
61847972 100 # croak?
101 carp 'Upgrade not possible as database is unversioned. Please call install first.';
102 return;
b974984a 103 }
104
12fdd461 105 if ( $db_version eq $schema_version ) {
61847972 106 # croak?
107 carp "Upgrade not necessary\n";
108 return;
b974984a 109 }
110
12fdd461 111 my @version_list = $self->ordered_schema_versions ||
112 ( $db_version, $schema_version );
b974984a 113
114 # remove all versions in list above the required version
12fdd461 115 while ( @version_list && ( $version_list[-1] ne $schema_version ) ) {
61847972 116 pop @version_list;
b974984a 117 }
118
119 # remove all versions in list below the current version
12fdd461 120 while ( @version_list && ( $version_list[0] ne $db_version ) ) {
61847972 121 shift @version_list;
b974984a 122 }
123
124 # check we have an appropriate list of versions
12fdd461 125 die if @version_list < 2;
b974984a 126
127 # do sets of upgrade
12fdd461 128 while ( @version_list >= 2 ) {
61847972 129 $self->upgrade_single_step( $version_list[0], $version_list[1] );
130 shift @version_list;
b974984a 131 }
132}
133
134method upgrade_single_step($db_version, $target_version) {
b974984a 135 if ($db_version eq $target_version) {
e1f67607 136 # croak?
b974984a 137 carp "Upgrade not necessary\n";
138 return;
139 }
140
b974984a 141 my $upgrade_file = $self->ddl_filename(
12fdd461 142 $self->storage->sqlt_type,
143 $target_version,
144 $self->upgrade_directory,
145 $db_version,
146 );
b974984a 147
148 $self->create_upgrade_path({ upgrade_file => $upgrade_file });
149
150 unless (-f $upgrade_file) {
e1f67607 151 # croak?
b974984a 152 carp "Upgrade not possible, no upgrade file found ($upgrade_file), please create one\n";
153 return;
154 }
155
156 carp "DB version ($db_version) is lower than the schema version (".$self->schema_version."). Attempting upgrade.\n";
157
e1f67607 158 $self->_filedata($self->_read_sql_file($upgrade_file)); # I don't like this --fREW 2010-02-22
12fdd461 159 $self->backup if $self->do_backup;
160 $self->schema->txn_do(sub { $self->do_upgrade });
b974984a 161
12fdd461 162 $self->version_rs->create({
61847972 163 version => $target_version,
164 # ddl => $ddl,
165 # upgrade_sql => $upgrade_sql,
12fdd461 166 });
b974984a 167}
168
12fdd461 169method do_upgrade { $self->run_upgrade(qr/.*?/) }
b974984a 170
171method run_upgrade($stm) {
12fdd461 172 return unless $self->_filedata;
173 my @statements = grep { $_ =~ $stm } @{$self->_filedata};
b974984a 174
12fdd461 175 for (@statements) {
176 $self->storage->debugobj->query_start($_) if $self->storage->debug;
177 $self->apply_statement($_);
178 $self->storage->debugobj->query_end($_) if $self->storage->debug;
179 }
b974984a 180}
181
182method apply_statement($statement) {
e1f67607 183 # croak?
12fdd461 184 $self->storage->dbh->do($_) or carp "SQL was: $_"
b974984a 185}
186
8cf0010a 187method _read_sql_file($file) {
188 return unless $file;
b974984a 189
190 open my $fh, '<', $file or carp("Can't open upgrade file, $file ($!)");
191 my @data = split /\n/, join '', <$fh>;
192 close $fh;
193
194 @data = grep {
8cf0010a 195 $_ &&
196 !/^--/ &&
197 !/^(BEGIN|BEGIN TRANSACTION|COMMIT)/m
b974984a 198 } split /;/,
8cf0010a 199 join '', @data;
b974984a 200
201 return \@data;
202}
203
b974984a 2041;
61847972 205
206__END__
207
208vim: ts=2,sw=2,expandtab