App-Sqitch
view release on metacpan or search on metacpan
lib/sqitchtutorial-firebird.pod view on Meta::CPAN
of our projects:
> sqitch config --user user.name 'Marge N. OâVera'
> sqitch config --user user.email 'marge@example.com'
Have a look at F<~/.sqitch/sqitch.conf> and you'll see something like
this:
> cat ~/.sqitch/sqitch.conf
[engine "firebird"]
client = /opt/local/bin/isql
[user]
name = Marge N. OâVera
email = marge@example.com
Which means that Sqitch should be able to find C<isql> for any project, and
that it will always properly identify us when planning and committing changes.
Back to the repository. Have a look at the plan file, F<sqitch.plan>:
> cat sqitch.plan
%syntax-version=1.0.0
%project=flipr
%uri=https://github.com/sqitchers/sqitch-firebird-intro/
Note that it has picked up on the name and URI of the app we're building.
Sqitch uses this data to manage cross-project dependencies. The
C<%syntax-version> pragma is always set by Sqitch, so that it always knows how
to parse the plan, even if the format changes in the future.
Let's commit these changes and start creating the database changes.
> git add .
> git commit -am 'Initialize Sqitch configuration.'
[main 2177ce4] Initialize Sqitch configuration.
2 files changed, 19 insertions(+), 0 deletions(-)
create mode 100644 sqitch.conf
create mode 100644 sqitch.plan
Let's create our flipr test database using C<isql>:
> sudo -u firebird mkdir /tmp/flipr_test
> echo "CREATE DATABASE 'localhost:/tmp/flipr_test/flipr.fdb'; exit;" \
| isql-fb -q -u SYSDBA -p masterkey
=head1 Our First Change
Let's create a table. Our app will need users, of course, so we'll create a
table for them. Run this command:
> 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:
-- Deploy flipr:users to firebird
CREATE TABLE users (
nickname VARCHAR(50) PRIMARY KEY,
password VARCHAR(512) NOT NULL,
fullname VARCHAR(512) NOT NULL,
twitter VARCHAR(512) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL
);
COMMIT;
The C<revert> script's job is to precisely revert the change to the deploy
script, so we edit this to F<revert/users.sql> to look like this:
-- Revert flipr:users from firebird
DROP TABLE users;
COMMIT;
Now we can try deploying this change. We tell Sqitch where to send the change
via a L<database URI|https://github.com/libwww-perl/uri-db/>. Here we've
specified a database file, F</tmp/flipr_test/flipr.fdb>:
> sqitch deploy db:firebird://sysdba:masterkey@localhost//tmp/flipr_test/flipr.fdb
Adding registry tables to db:firebird://sysdba:@localhost//tmp/flipr_test/sqitch.fdb
Deploying changes to db:firebird://sysdba:@localhost//tmp/flipr_test/flipr.fdb
+ users .. ok
First Sqitch created the registry database and tables used to track database
changes. The registry is separate from the database to which the C<users>
change was deployed; by default, its name is C<sqitch.$suffix>, where
C<$suffix> is the same as the suffix on the target database, if any. It lives
in the same directory as the target database, which means that one registry
database is used for all the databases with the same suffix in a single
directory. In this case, we should end up with two databases:
=over
=item * F</tmp/flipr_test/sqitch.fdb>
The Sqitch registry database.
=item * F</tmp/flipr_test/flipr.fdb>
The database Sqitch manages.
=back
lib/sqitchtutorial-firebird.pod view on Meta::CPAN
> git reset --hard HEAD
HEAD is now at d5e7e86 Merge branch 'lists'
That throws out our botched merge. Now let's go back to our branch and rebase
it on C<main>:
> git checkout hashtags
Switched to branch 'hashtags'
> 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
CONFLICT (content): Merge conflict in sqitch.plan
Failed to merge in the changes.
Patch failed at 0001 Add hashtags table.
The copy of the patch that failed is found in:
.git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Oy, that's kind of a pain. It seems like no matter what we do, we'll need to
resolve conflicts in that file. Except in Git. Fortunately for us, we can tell
Git to resolve conflicts in F<sqitch.plan> differently. Because we only ever
append lines to the file, we can have it use the "union" merge driver, which,
according to L<its
docs|https://git-scm.com/docs/gitattributes#_built-in_merge_drivers>:
=over
Run 3-way file level merge for text files, but take lines from both versions,
instead of leaving conflict markers. This tends to leave the added lines in
the resulting file in random order and the user should verify the result. Do
not use this if you do not understand the implications.
=back
This has the effect of appending lines from all the merging files, which is
exactly what we need. So let's give it a try. First, back out the botched
rebase:
> git rebase --abort
Now add the union merge driver to F<.gitattributes> for F<sqitch.plan>
and rebase again:
> 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.
lists [flips] 2014-01-05T22:44:41Z Marge N. OâVera <marge@example.com> # Adds table for storing lists.
hashtags [flips] 2014-01-05T22:54:27Z Marge N. OâVera <marge@example.com> # Adds table for storing hashtags.
Note that it has appended the changes from the merged "lists" branch, and then
merged the changes from our "hashtags" branch. Test it to make sure it works
as expected:
> sqitch rebase -y
Reverting all changes from flipr_test
- hashtags ................ ok
- userflips @v1.0.0-dev1 .. ok
- flips ................... ok
- users ................... ok
Deploying changes to flipr_test
+ users ................... ok
+ flips ................... ok
+ userflips @v1.0.0-dev1 .. ok
+ lists ................... ok
+ hashtags ................ ok
Note the use of L<C<rebase>|sqitch-rebase>, which combines a
L<C<revert>|sqitch-revert> and a L<C<deploy>|sqitch-deploy> into a single
command. Handy, right? It correctly reverted our changes, and then deployed
them all again in the proper order. So let's commit F<.gitattributes>; seems
worthwhile to keep that change:
> git add .
> git commit -m 'Add `.gitattributes` with union merge for `sqitch.plan`.'
[hashtags 52ed9a2] Add `.gitattributes` with union merge for `sqitch.plan`.
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 .gitattributes
=head2 Merges Mastered
And now, finally, we can merge into C<main>:
> git checkout main
Switched to branch 'main'
> git merge --no-ff hashtags -m "Merge branch 'hashtags'"
Merge made by recursive.
.gitattributes | 1 +
deploy/hashtags.sql | 10 ++++++++++
revert/hashtags.sql | 5 +++++
sqitch.plan | 1 +
verify/hashtags.sql | 5 +++++
5 files changed, 22 insertions(+), 0 deletions(-)
create mode 100644 .gitattributes
create mode 100644 deploy/hashtags.sql
create mode 100644 revert/hashtags.sql
( run in 1.501 second using v1.01-cache-2.11-cpan-39bf76dae61 )