App-Sqitch

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


0.995  2014-07-13T22:24:53Z
     - Fixed test failures due to the introduction of "Negative repeat count
       does nothing" warning in Perl 5.21.1.
     - Fixed more test failures when DBD::Firebird is installed but Firebird
       isql cannot be found.
     - Fixed registry file naming issues on Win32 for the SQLite engine, and
       as well as the tests that failed because of it.
     - Worked around Config::GitLike bug on Windows in the target test.
     - Changed the exit value for an attempt to deploy to an up-to-date
       database from 1 to 0. In other words, it no longer looks like an error
       (Issue #147).

0.994  2014-06-20T02:58:10Z
     - Fixed installation failure due to missing IO::File module on Windows.
     - Fixed file test failure for the Oracle engine on Windows.
     - Fixed bug where namespace-autoclean: 0.16 caused errors such as
       "Invalid object instance: 'yellow'".
     - Fixed Oracle SQL*Plus capture test failure on Windows.

0.993  2014-06-04T20:14:34Z

Changes  view on Meta::CPAN

       system-wide and user-specific configuration directories. They now live
       in subdirectories of the `templates` directory named for each action
       (deploy, revert, and verify), and with file names matching engine names
       (`pg.tmpl`, `sqlite.tmpl`, `oracle.tmpl`, and `mysql.tmpl`). The
       installer will move old files from the system-wide config directory
       (`sqitch --etc-path`) to their new homes, named `pg.tmpl` and
       `sqlite.tmpl`. It assumes no customizations exist for Oracle. If that's
       not true in your case, simply copy the `pg.tmpl` files to
       `oracle.tmpl`.
     - Added the `--template-name` option to the `add` command. By default, it
       looks for templates named for the current engine. The option allows for
       the user of task-specific templates. For example, if you create
       templates named `createtable.tmpl` in the `deploy`, `revert`, and
       `verify` subdirectories of `~/.sqitch/templates`, You can specify
       `--template-name createtable` to use those templates when adding a
       change.
     - Added the `--exists` option to the `show` command.
     - Fixed the `--set` option to the `add` command so that duplicate keys
       have their values passed to the template as an array, as documented.
     - If Template::Toolkit is installed, the `add` command will use it for
       processing templates instead of Template::Tiny. This makes it easy to

Changes  view on Meta::CPAN

0.952  2013-01-12T00:02:54Z
     - Switched from Moose to Mouse whever possible. Speeds load and runtime
       20-30%. Thanks to Michael Schwern for the pull request!

0.951  2013-01-08T00:21:58Z
     - Fixed double "@" displayed for tags in the output of `revert`.
     - Fixed reversion of reworked changes to run the original revert script,
       rather than the reworked script.
     - Added `is_reworked` accessor to App::Sqitch::Plan::Change.
     - Changed the behavior determining the file name to use for reworked
       change scripts. It now looks for a deploy script using the name of any
       tag between the reworked instances of a change and selects the first
       one it finds that exists. This will allow Sqitch to find the proper
       script name even if new tags have been added to the plan (issue #70).

0.950  2013-01-03T23:09:42Z
     - Fixed the "Name" header in `sqitch-rebase` so that it will actually
       show up on the CPAN search sites.
     - Fixed test failure triggered by the passage of time in `t/engine.t`.
     - At the start of a `deploy`, if the most recently deployed change has
       any unlogged tags (that is, tags added since the last `deploy`), they

lib/App/Sqitch.pm  view on Meta::CPAN

    return \%opts;
}

sub _find_cmd {
    my ( $class, $args ) = @_;
    my (@tried, $prev);
    for (my $i = 0; $i <= $#$args; $i++) {
        my $arg = $args->[$i] or next;
        if ($arg =~ /^-/) {
            last if $arg eq '--';
            # Skip the next argument if this looks like a pre-0.9999 option.
            # There shouldn't be many since we now recommend putting options
            # after the command. XXX Remove at some future date.
            $i++ if $arg =~ /^(?:-[duhp])|(?:--(?:db-\w+|client|engine|extension|plan-file|registry|top-dir))$/;
            next;
        }
        push @tried => $arg;
        my $cmd = try { App::Sqitch::Command->class_for($class, $arg) } or next;
        splice @{ $args }, $i, 1;
        return $cmd;
    }

lib/App/Sqitch.pm  view on Meta::CPAN

A L<database URI|URI::db> object, to be used to connect to the target
database.


=item C<registry>

The name of the Sqitch registry in the target database.

=back

If the C<$target> argument looks like a database URI, it will simply returned
in the hash reference. If the C<$target> argument corresponds to a target
configuration key, the target configuration will be returned, with the C<uri>
value a upgraded to a L<URI> object. Otherwise returns C<undef>.

=head3 C<shell>

  $sqitch->shell('echo -n hello');

Shells out a system command and waits for it to finish. Throws an exception on
error. Always uses the shell, so a single string must be passed encapsulating

lib/App/Sqitch/Engine/mysql.pm  view on Meta::CPAN


=item * C<mysql_ssl_cipher>: C<--ssl-cipher>

=back

=head3 C<username>

=head3 C<password>

Overrides the methods provided by the target so that, if the target has
no username or password, Sqitch looks them up in the
L<F</etc/my.cnf> and F<~/.my.cnf> files|https://dev.mysql.com/doc/refman/5.7/en/password-security-user.html>.
These files must limit access only to the current user (C<0600>). Sqitch will
look for a username and password under the C<[client]> and C<[mysql]>
sections, in that order.

=head1 Author

David E. Wheeler <david@justatheory.com>

=head1 License

lib/App/Sqitch/Engine/snowflake.pm  view on Meta::CPAN


App::Sqitch::Engine::snowflake provides the Snowflake storage engine for Sqitch.

=head1 Interface

=head2 Attributes

=head3 C<uri>

Returns the Snowflake database URI name. It starts with the URI for the target
and builds out missing parts. Sqitch looks for the host name in this order:

=over

=item 1

In the host name of the target URI. If that host name does not end in
C<snowflakecomputing.com>, Sqitch appends it. This lets Snowflake URLs just
reference the Snowflake account name or the account name and region in URLs.

=item 2

lib/App/Sqitch/Engine/snowflake.pm  view on Meta::CPAN

username.

=back

Other attributes of the URI are set from the C<account>, C<username> and
C<password> attributes documented below.

=head3 C<account>

Returns the Snowflake account name, or an exception if none can be determined.
Sqitch looks for the account code in this order:

=over

=item 1

In the host name of the target URI.

=item 2

In the C<$SNOWSQL_ACCOUNT> environment variable.

=item 3

In the C<connections.accountname> setting in the
L<SnowSQL configuration file|https://docs.snowflake.com/en/user-guide/snowsql-start.html#configuring-default-connection-settings>.

=back

=head3 username

Returns the snowflake user name. Sqitch looks for the user name in this order:

=over

=item 1

In the C<$SQITCH_USERNAME> environment variable.

=item 2

In the target URI.

lib/App/Sqitch/Engine/snowflake.pm  view on Meta::CPAN

L<SnowSQL config file|https://docs.snowflake.com/en/user-guide/snowsql-config.html#snowsql-config-file>.

=item 5

The system username.

=back

=head3 password

Returns the snowflake password. Sqitch looks for the password in this order:

=over

=item 1

In the C<$SQITCH_PASSWORD> environment variable.

=item 2

In the target URI.

lib/App/Sqitch/Engine/snowflake.pm  view on Meta::CPAN

=item 4

In the C<connections.password> variable from the
L<SnowSQL config file|https://docs.snowflake.com/en/user-guide/snowsql-config.html#snowsql-config-file>.

=back

=head3 C<warehouse>

Returns the warehouse to use for all connections. This value will be available
to all Snowflake change scripts as the C<&warehouse> variable. Sqitch looks
for the warehouse in this order:

=over

=item 1

In the C<warehouse> query parameter of the target URI

=item 2

lib/App/Sqitch/Engine/snowflake.pm  view on Meta::CPAN


=item 4

If none of the above are found, it falls back on the hard-coded value
"sqitch".

=back

=head3 C<role>

Returns the role to use for all connections. Sqitch looks for the role in this
order:

=over

=item 1

In the C<role> query parameter of the target URI

=item 2

lib/App/Sqitch/Role/TargetConfigCommand.pm  view on Meta::CPAN

        my $plan = App::Sqitch::Plan->new(
            sqitch => $self->sqitch,
            file   => $file,
            target => $target,
        );
        my $file_proj = try { $plan->project } or hurl init => __x(
            'Cannot initialize because {file} already exists and is not a valid plan file',
            file => $file,
        );

        # Bail if this plan file looks like it's for a different project.
        hurl init => __x(
            'Cannot initialize because project "{project}" already initialized in {file}',
            project => $plan->project,
            file    => $file,
        ) if $plan->project ne $project;
        return $self;
    }

    $self->mkdirs( $file->dir ) unless -d $file->dir;

lib/sqitch-add.pod  view on Meta::CPAN

Sqitch uses system-wide templates installed in
F<$(prefix)/etc/sqitch/templates>; call C<sqitch --etc-path> to find out
where, exactly (e.g., C<$(sqitch --etc-path)/templates>). Individual templates
may be overridden on a user basis by copying templates to
F<~/.sqitch/templates> and making modifications. They may also be overridden
by using the C<--template-directory> or C<--template-name> options, as well as
the template-specific options.

=head2 Directory Layout

Sqitch looks for templates in the following directories, and in this order:

=over

=item * C<--template-directory> or C<add.template_directory>

=item * F<~/.sqitch/templates/>

=item * F<$(prefix)/etc/sqitch/templates>

=back

lib/sqitch-authentication.pod  view on Meta::CPAN


The Firebird engine uses the C<ISC_USER> environment variable, if set.

=item Exasol

Exasol provides no default to search for a username.

=item Snowflake

The Snowflake engine uses the C<SNOWSQL_USER> environment variable, if set.
Next, it looks in the
L<F<~/.snowsql/config> file|https://docs.snowflake.com/en/user-guide/snowsql-start.html#snowsql-config-file>
and use the default C<connections.username> value. Otherwise, it uses the
system username.

=back

=head1 Passwords

You may have noticed that Sqitch has no C<--password> option. This is
intentional. It's generally not a great idea to specify a password on the

lib/sqitch-config.pod  view on Meta::CPAN

=over

=item C<engine.pg.registry>

For the PostgreSQL engine, the C<registry> value identifies the schema for
Sqitch to use for its own data. No other data should be stored there. Defaults
to C<sqitch>.

=item C<engine.sqlite.registry>

For the SQLite engine, if the C<registry> value looks like an absolute path,
then it will be the database file. Otherwise, it will be in the same directory
as the database specified by the C<uri>. Defaults to C<sqitch>.

=item C<engine.mysql.registry>

For the MySQL engine, the C<registry> value identifies the database for Sqitch
to use for its own data. If you need to manage multiple databases on a single
server, and don't want them all to share the same registry, change this
property to a value specific for your database. Defaults to C<sqitch>.

=item C<engine.oracle.registry>

For Oracle, C<registry> value identifies the schema for Sqitch to use for its
own data. No other data should be stored there. Uses the current schema by
default (usually the same name as the connection user).

=item C<engine.firebird.registry>

For the Firebird engine, if the C<registry> value looks like an absolute path,
then it will be the database file. Otherwise, it will be in the same directory
as the database specified by the C<uri>. Defaults to C<sqitch.$extension>,
where C<$extension> is the same as that in the C<uri>, if any.

=item C<engine.vertica.registry>

For the Vertica engine, the C<registry> value identifies the schema for Sqitch
to use for its own data. No other data should be stored there. Defaults to
C<sqitch>.

lib/sqitch-configuration.pod  view on Meta::CPAN

  > mv deploy revert verify sqitch.plan pg
  > ls  pg  
  deploy/ revert/ sqitch.plan verify/

Now we need to tell Sqitch where things are. To create an engine-specific
configuration, use the L<C<engine>|sqitch-engine> command's C<add> action:

  sqitch engine add pg --top-dir pg

The C<add> action adds the C<pg> engine to the configuration, setting the top
directory to our newly-created C<pg> directory. The configuration looks like
this (with comments removed for clarity):

  [core]
    engine = pg
  [engine "pg"]
    target = db:pg:
    top_dir = pg

Curious about all the other settings for the engine? Let C<sqitch engine show>
show you:

lib/sqitch-configuration.pod  view on Meta::CPAN

in F<pg/reworked/verify>. And you're good to go! From here on in Sqitch always
knows to find the reworked scripts when doing a L<deploy|sqitch-deploy>,
L<revert|sqitch-revert>, or L<bundle|sqitch-bundle>. And meanwhile, they're
tucked out of the way, less likely to break your brain or your IDE.

=head1 Other Options

You can see by the output of the L<C<init>|sqitch-init>,
L<C<engine>|sqitch-engine>, and L<C<target>|sqitch-target> commands that there
are quite a few other properties that can be set on a per-engine or per-target
database. To determine the value of each, Sqitch looks at a combination of
command-line options and configuration variables. Here's a complete list,
including specification of their values and how to set them.

=over

=item C<target>

The target database. May be a L<database URI|https://github.com/libwww-perl/uri-db> or
a named target managed by the L<C<target>|sqitch-target> commands. On each run,
its value will be determined by examining each of the following in turn:

lib/sqitch-engine.pod  view on Meta::CPAN

The name or URI of the database target. Note that if the value is a URI, the
engine in the URI must match the engine being added or altered. The default is
C<db:$engine>. See L<sqitch-target> for details on target configuration.

=item C<registry>

The name of the registry schema or database. The default is C<sqitch>.

=item C<client>

The command-line client to use. If not specified, each engine looks in the OS
Path for an appropriate client.

=item C<top_dir>

The path to the top directory for the engine. This directory generally
contains the plan file and subdirectories for deploy, revert, and verify
scripts, as well as reworked instances of those scripts. The default is F<.>,
the current directory.

=item C<plan_file>

lib/sqitch-target.pod  view on Meta::CPAN

See L<URL encoding|https://en.wikipedia.org/wiki/URL_encoding> for details.
and the L<DB URI Draft|https://github.com/libwww-perl/uri-db> for in-depth
information on database URIs in general.

=item C<registry>

The name of the registry schema or database. The default is C<sqitch>.

=item C<client>

The command-line client to use. If not specified, each engine looks in the OS
Path for an appropriate client.

=item C<top_dir>

The path to the top directory for the target. This directory generally
contains the plan file and subdirectories for deploy, revert, and verify
scripts, as well as reworked instances of those scripts. The default is F<.>,
the current directory.

=item C<plan_file>

lib/sqitchtutorial-exasol.pod  view on Meta::CPAN

  > git rebase main
  First, rewinding head to replay your work on top of it...
  Applying: Add hashtags table.
  Using index info to reconstruct a base tree...
  <stdin>:16: new blank line at EOF.
  +
  warning: 1 line adds whitespace errors.
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

  > cat sqitch.plan
  %syntax-version=1.0.0
  %project=flipr
  %uri=https://github.com/sqitchers/sqitch-exasol-intro/

  appschema 2014-09-04T18:40:34Z Marge N. O’Vera <marge@example.com> # Add schema for all flipr objects.
  users [appschema] 2014-09-04T23:40:15Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
  flips [appschema users] 2014-09-05T00:16:58Z Marge N. O’Vera <marge@example.com> # Adds table for storing flips.
  userflips [appschema users flips] 2014-09-05T00:18:43Z Marge N. O’Vera <marge@example.com> # Creates the userflips view.

lib/sqitchtutorial-firebird.pod  view on Meta::CPAN


  > sqitch add users -n 'Creates table to track our users.'
  Created deploy/users.sql
  Created revert/users.sql
  Created verify/users.sql
  Added "users" to sqitch.plan

The L<C<add>|sqitch-add> command adds a database change to the plan and writes
deploy, revert, and verify scripts that represent the change. Now we edit
these files. The C<deploy> script's job is to create the table. By default,
the F<deploy/users.sql> file looks like this:

  -- Deploy flipr:users to firebird

  -- XXX Add DDLs here.

  COMMIT;

What we want to do is to replace the C<XXX> comment with the C<CREATE TABLE>
statement, like so:

lib/sqitchtutorial-firebird.pod  view on Meta::CPAN


  > echo sqitch.plan merge=union > .gitattributes
  > git rebase main
  First, rewinding head to replay your work on top of it...
  Applying: Add hashtags table.
  Using index info to reconstruct a base tree...
  M sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

  > cat sqitch.plan
  %syntax-version=1.0.0
  %project=flipr
  %uri=https://github.com/sqitchers/sqitch-firebird-intro/

  users 2014-01-05T22:01:30Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
  flips [users] 2014-01-05T22:21:24Z Marge N. O’Vera <marge@example.com> # Adds table for storing flips.
  userflips [users flips] 2014-01-05T22:40:29Z Marge N. O’Vera <marge@example.com> # Creates the userflips view.
  @v1.0.0-dev1 2014-01-05T22:42:36Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1.

lib/sqitchtutorial-mysql.pod  view on Meta::CPAN


  > sqitch add appuser -n 'Creates a an application user.'
  Created deploy/appuser.sql
  Created revert/appuser.sql
  Created verify/appuser.sql
  Added "appuser" to sqitch.plan

The L<C<add>|sqitch-add> command adds a database change to the plan and writes
deploy, revert, and verify scripts that represent the change. Now we edit
these files. The C<deploy> script's job is to create the table. By default,
the F<deploy/appuser.sql> file looks like this:

  -- Deploy flipr:appuser to mysql

  BEGIN;

  -- XXX Add DDLs here.

  COMMIT;

What we want to do is to replace the C<XXX> comment with the C<CREATE USER>

lib/sqitchtutorial-mysql.pod  view on Meta::CPAN

  Using index info to reconstruct a base tree...
  M	sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan
  Applying: Add functions to insert and delete flips.
  Using index info to reconstruct a base tree...
  M	sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

  > cat sqitch.plan
  %syntax-version=1.0.0
  %project=flipr
  %uri=https://github.com/sqitchers/sqitch-mysql-intro/

  appuser 2013-12-31T21:04:04Z Marge N. O’Vera <marge@example.com> # Creates a an application user.
  users [appuser] 2013-12-31T21:32:48Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
  insert_user [users appuser] 2013-12-31T21:37:29Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user.
  change_pass [users appuser] 2013-12-31T21:37:36Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password.

lib/sqitchtutorial-mysql.pod  view on Meta::CPAN

  | foo      | 9695da4dd567a19f9b92065f240c6725 | 2013-12-31 22:15:29.842700 |
  +----------+----------------------------------+----------------------------+

Yes, it works! Sqitch properly finds the original instances of these changes
in the new script files that include tags.

But what about the verify script? How can we verify that the functions have
been modified to use C<ENCRYPT()>? I think the simplest thing to do is to
examine the body of the function as returned by
L<C<INFORMATION_SCHEMA.ROUTINES>|https://dev.mysql.com/doc/refman/5.7/en/information-schema-routines-table.html>
So the C<insert_user> verify script looks like this:

  -- Verify flipr:insert_user on mysql

  BEGIN;

  SELECT sqitch.checkit(COUNT(*), 'Procedure "insert_user" does not exist or is not up-to-date')
    FROM information_schema.routines
   WHERE routine_schema = database()
     AND routine_name = 'insert_user'
     AND routine_definition LIKE '%ENCRYPT(md5(password), md5(FLOOR(RAND() * 0xFFFFFFFF))%';

  ROLLBACK;

And the C<change_pass> verify script looks like this:

  -- Verify flipr:change_pass on mysql

  BEGIN;

  SELECT sqitch.checkit(COUNT(*), 'Procedure "change_pass" does not exist or is not up-to-date')
    FROM information_schema.routines
   WHERE routine_schema = database()
     AND routine_name = 'change_pass'
     AND routine_definition LIKE '%ENCRYPT(md5(oldpass), password)%';

lib/sqitchtutorial-oracle.pod  view on Meta::CPAN

  Using index info to reconstruct a base tree...
  M	sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan
  Applying: Add functions to insert and delete flips.
  Using index info to reconstruct a base tree...
  M	sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

  > cat sqitch.plan 
  %syntax-version=1.0.0
  %project=flipr
  %uri=https://github.com/sqitchers/sqitch-oracle-intro/

  appschema 2013-12-31T22:34:42Z Marge N. O’Vera <marge@example.com> # App user and schema for all flipr objects.
  users [appschema] 2014-01-01T00:31:20Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
  insert_user [users appschema] 2014-01-01T00:35:21Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user.
  change_pass [users appschema] 2014-01-01T00:35:28Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password.

lib/sqitchtutorial-oracle.pod  view on Meta::CPAN

  bar
  a4d80eac9ab26a4a2da04125bc2c096a

Yes, it works! Sqitch properly finds the original instances of these changes
in the new script files that include tags.

But what about the verify script? How can we verify that the functions have
been modified to use C<crypt()>? I think the simplest thing to do is to
examine the body of the function by querying the
L<C<all_source>|https://docs.oracle.com/cd/B19306_01/server.102/b14237/statviews_2063.htm>
view. So the C<insert_user> verify script looks like this:

  -- Verify flipr:insert_user on oracle

  DESCRIBE flipr.insert_user;

  SELECT 1/COUNT(*)
    FROM all_source
   WHERE type = 'PROCEDURE'
     AND name = 'INSERT_USER'
     AND text LIKE '%flipr.crypt(password, DBMS_RANDOM.STRING(''p'', 10))%';

And the C<change_pass> verify script looks like this:

  -- Verify flipr:change_pass on oracle

  DESCRIBE flipr.change_pass;

  SELECT 1/COUNT(*)
    FROM all_source
   WHERE type = 'PROCEDURE'
     AND name = 'CHANGE_PASS'
     AND text LIKE '%password = flipr.crypt(newpass, DBMS_RANDOM.STRING(''p'', 10))%';

lib/sqitchtutorial-snowflake.pod  view on Meta::CPAN


  > echo sqitch.plan merge=union > .gitattributes
  > git rebase main
  First, rewinding head to replay your work on top of it...
  Applying: Add hashtags table.
  Using index info to reconstruct a base tree...
  M	sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

  > cat sqitch.plan
  %syntax-version=1.0.0
  %project=flipr
  %uri=https://github.com/sqitchers/sqitch-snowflake-intro/

  appschema 2018-07-27T14:27:24Z Marge N. O’Vera <marge@example.com> # Add schema for all flipr objects.
  users [appschema] 2018-07-27T15:03:56Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
  flips [appschema users] 2018-07-27T15:23:41Z Marge N. O’Vera <marge@example.com> # Adds table for storing flips.
  userflips [appschema users flips] 2018-07-27T15:23:50Z Marge N. O’Vera <marge@example.com> # Creates the userflips view.

lib/sqitchtutorial-sqlite.pod  view on Meta::CPAN


  > sqitch add users -n 'Creates table to track our users.'
  Created deploy/users.sql
  Created revert/users.sql
  Created verify/users.sql
  Added "users" to sqitch.plan

The L<C<add>|sqitch-add> command adds a database change to the plan and writes
deploy, revert, and verify scripts that represent the change. Now we edit
these files. The C<deploy> script's job is to create the table. By default,
the F<deploy/users.sql> file looks like this:

  -- Deploy flipr:users to sqlite

  BEGIN;

  -- XXX Add DDLs here.

  COMMIT;

What we want to do is to replace the C<XXX> comment with the C<CREATE TABLE>

lib/sqitchtutorial-sqlite.pod  view on Meta::CPAN


  > echo sqitch.plan merge=union > .gitattributes
  > git rebase main
  First, rewinding head to replay your work on top of it...
  Applying: Add hashtags table.
  Using index info to reconstruct a base tree...
  M	sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

  > cat sqitch.plan
  %syntax-version=1.0.0
  %project=flipr
  %uri=https://github.com/sqitchers/sqitch-sqlite-intro/

  users 2013-12-31T18:06:04Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
  flips [users] 2013-12-31T19:01:40Z Marge N. O’Vera <marge@example.com> # Adds table for storing flips.
  userflips [users flips] 2013-12-31T19:11:11Z Marge N. O’Vera <marge@example.com> # Creates the userflips view.
  @v1.0.0-dev1 2013-12-31T19:13:02Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1.

lib/sqitchtutorial-vertica.pod  view on Meta::CPAN

  > git rebase main
  First, rewinding head to replay your work on top of it...
  Applying: Add hashtags table.
  Using index info to reconstruct a base tree...
  <stdin>:16: new blank line at EOF.
  +
  warning: 1 line adds whitespace errors.
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

  > cat sqitch.plan
  %syntax-version=1.0.0
  %project=flipr
  %uri=https://github.com/sqitchers/sqitch-vertica-intro/

  appschema 2014-09-04T18:40:34Z Marge N. O’Vera <marge@example.com> # Add schema for all flipr objects.
  users [appschema] 2014-09-04T23:40:15Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
  flips [appschema users] 2014-09-05T00:16:58Z Marge N. O’Vera <marge@example.com> # Adds table for storing flips.
  userflips [appschema users flips] 2014-09-05T00:18:43Z Marge N. O’Vera <marge@example.com> # Creates the userflips view.

lib/sqitchtutorial.pod  view on Meta::CPAN

  Using index info to reconstruct a base tree...
  M	sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan
  Applying: Add functions to insert and delete flips.
  Using index info to reconstruct a base tree...
  M	sqitch.plan
  Falling back to patching base and 3-way merge...
  Auto-merging sqitch.plan

Ah, that looks a bit better. Let's have a look at the plan:

  > cat sqitch.plan
  %syntax-version=1.0.0
  %project=flipr
  %uri=https://github.com/sqitchers/sqitch-intro/

  appschema 2013-12-30T23:19:45Z Marge N. O’Vera <marge@example.com> # Add schema for all flipr objects.
  users [appschema] 2013-12-30T23:49:00Z Marge N. O’Vera <marge@example.com> # Creates table to track our users.
  insert_user [users appschema] 2013-12-30T23:57:36Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user.
  change_pass [users appschema] 2013-12-30T23:57:45Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password.

lib/sqitchtutorial.pod  view on Meta::CPAN

  ----------+----------------------------------+-------------------------------
   foo      | 9695da4dd567a19f9b92065f240c6725 | 2013-12-31 01:03:57.263583+00
   bar      | 9695da4dd567a19f9b92065f240c6725 | 2013-12-31 01:03:57.263583+00

Yes, it works! Sqitch properly finds the original instances of these changes
in the new script files that include tags.

But what about the verify script? How can we verify that the functions have
been modified to use C<crypt()>? I think the simplest thing to do is to
examine the body of the function, using
L<C<pg_get_functiondef()>|https://www.postgresql.org/docs/9.2/static/functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE>. So the C<insert_user> verify script looks like this:

  -- Verify flipr:insert_user on pg

  BEGIN;

  SELECT has_function_privilege('flipr.insert_user(text, text)', 'execute');

  SELECT 1/COUNT(*)
    FROM pg_catalog.pg_proc
   WHERE proname = 'insert_user'
     AND pg_get_functiondef(oid) LIKE $$%crypt($2, gen_salt('md5'))%$$;

  ROLLBACK;

And the C<change_pass> verify script looks like this:

  -- Verify flipr:change_pass on pg

  BEGIN;

  SELECT has_function_privilege('flipr.change_pass(text, text, text)', 'execute');

  SELECT 1/COUNT(*)
    FROM pg_catalog.pg_proc
   WHERE proname = 'change_pass'

t/plan.t  view on Meta::CPAN

        file => $file,
        lineno => 4,
        error => __x(
            '"{name}" is a reserved name',
            name => '@' . $reserved,
        ),
    ), qq{And the \@$reserved error message should be correct};
    is sorted, 0, "Should have sorted \@$reserved changes nonce";
}

# Try a plan with a change name that looks like a sha1 hash.
my $sha1 = '6c2f28d125aff1deea615f8de774599acf39a7a1';
$file = file qw(t plans sha1.plan);
$fh = IO::File->new(\"$prags$sha1 $tsnp", '<:utf8_strict');
throws_ok { $plan->_parse($file, $fh) } 'App::Sqitch::X',
    'Should die on plan with SHA1 change name';
is $@->ident, 'parse', 'The SHA1 error ident should be "parse"';
is $@->message, __x(
    'Syntax error in {file} at line {lineno}: {error}',
    file => $file,
    lineno => 4,

t/plan.t  view on Meta::CPAN

# Should choke on an unknown tag, too.
throws_ok { $plan->add(name => 'whu', requires => ['@nonesuch' ] ) } 'App::Sqitch::X',
    'Should get failure for failed tag dependency';
is $@->ident, 'plan', 'Tag dependency error ident should be "plan"';
is $@->message, __x(
    'Cannot add change "{change}": requires unknown change "{req}"',
    change => 'whu',
    req    => '@nonesuch',
), 'The tag dependency error should be correct';

# Should choke on a change that looks like a SHA1.
throws_ok { $plan->add(name => $sha1) } 'App::Sqitch::X',
    'Should get error for a SHA1 change';
is $@->ident, 'plan', 'SHA1 tag error ident should be "plan"';
is $@->message, __x(
    '"{name}" is invalid because it could be confused with a SHA1 ID',
    name => $sha1,,
), 'And the reserved name error should be output';

##############################################################################
# Try reworking a change.

t/target.t  view on Meta::CPAN

    @get_params = ();
    isa_ok $target = $CLASS->new(sqitch => $sqitch), $CLASS, 'Default target';
    is $target->name, 'db:mysql:', 'Name should be "db:mysql:"';
    is $target->uri, URI::db->new('db:mysql:'), 'URI should be "db:mysql"';
    is_deeply \@get_params, [
        [key => 'core.target'],
        [key => 'core.engine'],
        [key => 'engine.mysql.target'],
    ], 'Should have tried to get core.target, core.engine and then the target';

    # Try with no engine option but a name that looks like a URI.
    @get_params = ();
    delete $sqitch->options->{engine};
    isa_ok $target = $CLASS->new(
        sqitch => $sqitch,
        name   => 'db:pg:',
    ), $CLASS, 'Target with URI in name';
    is $target->name, 'db:pg:', 'Name should be "db:pg:"';
    is $target->uri, URI::db->new('db:pg:'), 'URI should be "db:pg"';
    is_deeply \@get_params, [], 'Should have fetched no config';



( run in 0.396 second using v1.01-cache-2.11-cpan-64827b87656 )