=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'
  );

  # 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 seamless database schema up- and downgrades.

=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.

=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.

=head2 Schema support

The schema support of this implementation should be considered experimental.
For a PostgreSQL database you may set the managed schema (the schema of your
single-schema application) using the C<search_path> connect option:

  my $m = DBIx::Migration->new(
    dbi:Pg:dbname=test;host=localhost;port=5432;user=postgres;options=--search_path=myschema
  );

The migration object stores the current migration version in the tracking
table. Its default unqualified name is C<dbix_migration>. The table belongs by
default to the C<public> tracking schema.

=head1 METHODS

=over

=item $self->BUILD( $args )

Validate object.

=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->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->password

Get database password.

=item $self->tracking_schema

Get schema that the tracking table belongs to.

=item $self->tracking_table

Get tracking table. If the tracking schema is defined the tracking table name
is fully qualified.

=item $self->username

Get database username.

=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 endDelimiter|https://docs.liquibase.com/change-types/enddelimiter-sql.html>

=item * L<Liquibase tracking schema|https://docs.liquibase.com/parameters/liquibase-schema-name.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
