=pod

=head1 NAME

DBIx::Migration - Seamless database schema up- and downgrades

=head1 SYNOPSIS

  use DBIx::Migration ();

  my $m = DBIx::Migration->new(
    dsn            => 'dbi:SQLite:~/Projects/myapp/db/myapp.db',
    tracking_table => 'myapp_migration'
  );

  # Get current migration version from database
  my $version = $m->version;

  # Set directory before applying migrations
  $m->dir( '~/Projects/myapp/db/migrations' );

  # Migrate database to version 1
  $m->migrate( 1 );

  # Migrate database to the latest version
  $m->migrate;

  -- ~/Projects/myapp/db/migrations/schema_1_up.sql
  CREATE TABLE foo (
    id INTEGER PRIMARY KEY,
    bar TEXT
  );

  -- ~/Projects/myapp/db/migrations/schema_1_down.sql
  DROP TABLE foo;

  -- ~/Projects/myapp/db/migrations/schema_2_up.sql
  CREATE TABLE bar (
    id INTEGER PRIMARY KEY,
    baz TEXT
  );

  -- ~/Projects/myapp/db/migrations/schema_2_down.sql
  DROP TABLE bar;

=head1 DESCRIPTION

This class provides the basis for seamless database schema up- and downgrades.
It isn't abstract that means it can be used by its own. Subclasses like for
example L<DBIx::Migration::Pg> offer driver specific improvements.

=head2 Migrations

The implementation of this class is based on migrations. A migration is a
C<.sql> script.  Although not mandatory the script name begins with a prefix
like for example C<schema_>. It follows a version number that is a positive
integer. After an C<_> (underscore) character the script name ends with the
migration type that is either C<up> or C<down>. Migrations are stored in a
directory and are applied in order to a database. Usually the version number of
the first migration is 1. The version numbers of the other migrations have to
be ascending without gaps.

The migration object stores the current migration version in a tracking table.
Its default unqualified name is C<dbix_migration>.

=head2 Processing

During processing the content of each migration is read with the C<binmode> of
C<:raw> into a scalar. The content is split into sections using the default SQL
delimiter C<;> (semicolon). Each section is executed independently. All related
sections are encapsulated in a database transaction.  If a migration embeds
stored logic containing one or more semicolons (a PostgreSQL trigger function
for example), the C<migrate()> method incorrectly splits the migration into
sections, causing an error. You can set a different delimiter to overcome this
problem. Add the C<dbix_migration_delimiter> annotation as an SQL comment to
the migration

  -- dbix_migration_delimiter: /
  ...

The annotation has to be specified in the first line. The delimiter has to be
a single printable ASCII character, excluding the space character. In the
previous example it is the C</> (slash) character.

=head1 LIFECYCLE METHODS

=over

=item $self->BUILD( $args )

Validate object.

=back

=head1 ACCESSORS

=over

=item $self->dir( $dir )

Get/set-once directory that contains migrations.

=item $self->dsn

Get data source name.

=item $self->dbh

Get database handle.

=item $self->password

Get database password.

=item $self->tracking_table

Get tracking table.

=item $self->username

Get database username.

=back

=head1 METHODS

=over 

=item $self->apply_managed_schema

Drivers that support schemas like PostgreSQL should override this method to set
a managed schema before processing migrations.

=item $self->driver, $class->driver( $dsn )

Extracts and returns the driver name from the data source name.

=item $self->migrate( $version )

Migrate database to version. Returns true in case of success; otherwise false.
If called without the version argument the latest migration version will be
used.

=item $self->quoted_tracking_table

Quotes and returns the tracking table using L<DBI/quote_identifier>. This
method is overrideable in subclasses.

=item $self->version

Get migration version from database. Will be C<undef> if no migration has taken
place yet. The version is stored in the tracking table.

=back

=head1 LOGGING

The logging of this class is based on a static L<Log::Any> logger. Its category
is the class name itself. The easiest way to enable logging is to set the
C<LOG_ANY_DEFAULT_ADAPTER> environment variable:

  LOG_ANY_DEFAULT_ADAPTER=Stderr

=head1 SEE ALSO

=over

=item * L<Liquibase end delimiter|https://docs.liquibase.com/change-types/enddelimiter-sql.html>

=back

=head1 AUTHOR

Sebastian Riedel, <kraihx@gmail.com>

=head1 CONTRIBUTORS

Dan Sully, <dan+github@sully.org>

Marcus Ramberg, <marcus@nordaaker.com>

Steven Jenkin, <sjenkin@venda.com>

Sven Willenbuecher, <sven.willenbuecher@gmx.de>

=head1 COPYRIGHT

Copyright 2004-2005 Sebastian Riedel. All rights reserved.

This program is free software, you can redistribute it and/or modify it under
the same terms as Perl itself.

=cut
