SlideShare uma empresa Scribd logo
1 de 297
Sane SQL Change
  Management with Sqitch
                                                       David E. Wheeler
                                                      http:/
                                                           /sqitch.org/


                                                       PDXPUG
                                                 September 20, 2012




Text: Attribution-Noncommercial-Share Alike 3.0 United States:
http://creativecommons.org/licenses/by-nc-sa/3.0/us/
Images licensed independently and © Their respective owners.
Whats Wrong with
  Migrations?
Whats Wrong with
    Migrations?
Incomplete mini-language
Whats Wrong with
     Migrations?
Incomplete mini-language

No logical replication integration
Whats Wrong with
     Migrations?
Incomplete mini-language

No logical replication integration

Numbered scripts hard to track
Whats Wrong with
     Migrations?
Incomplete mini-language

No logical replication integration

Numbered scripts hard to track

No VCS awareness
What about SQL
      Migrations?
Incomplete mini-language

No logical replication integration

Numbered scripts hard to track

No VCS awareness
What about SQL
      Migrations?
———————————————
Incomplete mini-language

No logical replication integration

Numbered scripts hard to track

No VCS awareness
What about SQL
      Migrations?
———————————————
Incomplete mini-language

———————————————————
No logical replication integration

Numbered scripts hard to track

No VCS awareness
What about SQL
      Migrations?
———————————————
Incomplete mini-language

———————————————————
No logical replication integration

Numbered scripts hard to track

No VCS awareness

Managing procedures is a PITA
Imagine this Change

>
Imagine this Change

>git diff
diff --git a/deploy/recur.sql b/deploy/recur.sql
index 622d52e..56e419e 100644
--- a/deploy/recur.sql
+++ b/deploy/recur.sql
@@ -22,7 +22,10 @@
             recurrence <> 'none'
           OR (
                recurrence = 'none'
-            AND starts_at BETWEEN range_start AND range_end
+             AND (
+                  starts_at BETWEEN range_start AND range_end
+                 OR ends_at BETWEEN range_start AND range_end
+             )
           )
        )
    LOOP
Imagine this Change

>git diff
diff --git a/deploy/recur.sql b/deploy/recur.sql
index 622d52e..56e419e 100644
--- a/deploy/recur.sql
+++ b/deploy/recur.sql
@@ -22,7 +22,10 @@
             recurrence <> 'none'
           OR (
                recurrence = 'none'
-            AND starts_at BETWEEN range_start AND range_end
+             AND (
+                  starts_at BETWEEN range_start AND range_end
+                 OR ends_at BETWEEN range_start AND range_end
+             )
           )


                  Simple, right?
        )
    LOOP
Not So Much
Not So Much
Paste entire function to new “up” script
Not So Much
Paste entire function to new “up” script

Edit the new file
Not So Much
Paste entire function to new “up” script

Edit the new file

Copy the function to the new “down” script
Not So Much
Paste entire function to new “up” script

Edit the new file

Copy the function to the new “down” script

Three copies of the function!
Not So Much
Paste entire function to new “up” script

Edit the new file

Copy the function to the new “down” script

Three copies of the function!

No real source code management
Not So Much
Paste entire function to new “up” script

Edit the new file

Copy the function to the new “down” script

Three copies of the function!

No real source code management

This sucks
What about Liquibase?




filename
What about Liquibase?
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
 xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.6"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.6
      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.6.xsd">
 <changeSet id="1" author="me">
  <createTable tableName="first_table">
   <column name="id" type="int">
     <constraints primaryKey="true" nullable="false"/>
   </column>
   <column name="name" type="varchar(50)">
     <constraints nullable="false"/>
   </column>
  </createTable>
  <createTable tableName="new_table">
   <column name="id" type="int">
     <constraints primaryKey="true" nullable="false"/>
   </column>
  </createTable>
 </changeSet>
</databaseChangeLog>
  filename
What about Liquibase?
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
 xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.6"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.6
      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.6.xsd">
 <changeSet id="1" author="me">
  <createTable tableName="first_table">
   <column name="id" type="int">
     <constraints primaryKey="true" nullable="false"/>
   </column>
   <column name="name" type="varchar(50)">



                                        Whaaaa?
     <constraints nullable="false"/>
   </column>
  </createTable>
  <createTable tableName="new_table">
   <column name="id" type="int">
     <constraints primaryKey="true" nullable="false"/>
   </column>
  </createTable>
 </changeSet>
</databaseChangeLog>
  filename
What about Liquibase?
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
 xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.6"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.6
      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.6.xsd">
 <changeSet id="1" author="me">
  <createTable tableName="first_table">
   <column name="id" type="int">
     <constraints primaryKey="true" nullable="false"/>
   </column>
   <column name="name" type="varchar(50)">



                                        Whaaaa?
     <constraints nullable="false"/>
   </column>
  </createTable>
  <createTable tableName="new_table">
   <column name="id" type="int">
     <constraints primaryKey="true" nullable="false"/>



                                          GTFO!
   </column>
  </createTable>
 </changeSet>
</databaseChangeLog>
  filename
depesz’s Versioning?
depesz’s Versioning?
https:/
      /github.com/depesz/versioning
depesz’s Versioning?
https:/
      /github.com/depesz/versioning

Nice dependency specification
depesz’s Versioning?
https:/
      /github.com/depesz/versioning

Nice dependency specification

Tight PostgreSQL integration
depesz’s Versioning?
https:/
      /github.com/depesz/versioning

Nice dependency specification

Tight PostgreSQL integration

No VCS integration
depesz’s Versioning?
https:/
      /github.com/depesz/versioning

Nice dependency specification

Tight PostgreSQL integration

No VCS integration

No tools
depesz’s Versioning?
https:/
      /github.com/depesz/versioning

Nice dependency specification

Tight PostgreSQL integration

No VCS integration

No tools

Managing procedures still a PITA
Introducing
   Sqitch
Sq—what?


sql ch anges
Sq—what?


sq ch
Sq—what?


sqitch
Sq—what?


sqitch


There is no “u”
Sqitch Philosophy
Sqitch Philosophy
No opinions
Sqitch Philosophy
No opinions

Native scripting
Sqitch Philosophy
No opinions

Native scripting

Dependency resolution
Sqitch Philosophy
No opinions

Native scripting

Dependency resolution

No numbering
Sqitch Philosophy
No opinions

Native scripting

Dependency resolution

No numbering

Distribution bundling
Sqitch Philosophy
No opinions

Native scripting

Dependency resolution

No numbering

Distribution bundling

VCS integration
Sqitch Philosophy
Sqitch Philosophy
Reduced duplication
Sqitch Philosophy
Reduced duplication

Built-in configuration
Sqitch Philosophy
Reduced duplication

Built-in configuration

Deployment planning
Sqitch Philosophy
Reduced duplication

Built-in configuration

Deployment planning

Git-style interface
Sqitch Philosophy
Reduced duplication

Built-in configuration

Deployment planning

Git-style interface

Deployment tagging
Sqitch Terminology
Sqitch Terminology

change
Sqitch Terminology

change

tag
Sqitch Terminology

change

tag

state
Sqitch Terminology

change

tag

state

plan
Sqitch Terminology

change       add

tag

state

plan
Sqitch Terminology

change       add

tag          deploy

state

plan
Sqitch Terminology

change       add

tag          deploy

state        revert

plan
Sqitch Terminology

change       add

tag          deploy

state        revert

plan         committer
How it Works
>
How it Works
>mkdir flipr
> cd flipr
> git init .
Initialized empty Git repository in /flipr/.git/
> touch README.md
> git add .
> git commit -am 'Fist post!'

>
How it Works
>mkdir flipr
> cd flipr
> git init .
Initialized empty Git repository in /flipr/.git/
> touch README.md
> git add .
> git commit -am 'Fist post!'

>sqitch --engine pg init flipr --uri https://github
Created sqitch.conf
Created sqitch.plan
Created deploy/
Created revert/
Created test/
>
How it Works
>mkdir flipr
> cd flipr
> git init .
Initialized empty Git repository in /flipr/.git/
> touch README.md
> git add .
> git commit -am 'Fist post!'

>sqitch --engine pg init flipr --uri https://github
Created sqitch.conf
Created sqitch.plan
Created deploy/
Created revert/
Created test/
>
How it Works
>mkdir flipr
> cd flipr
> git init .
Initialized empty Git repository in /flipr/.git/
> touch README.md
> git add .
> git commit -am 'Fist post!'

>sqitch --engine pg init flipr --uri https://github
Created sqitch.conf
Created sqitch.plan
Created deploy/
Created revert/
Created test/
>emacs sqitch.conf
sqitch.conf
[core]

   engine = pg
   # plan_file = sqitch.plan
   # top_dir = .
   # deploy_dir = deploy
   # revert_dir = revert
   # test_dir = test
   # extension = sql
# [core "pg"]
   # db_name =
   # client = /usr/local/pgsql/bin/psql
   # sqitch_schema = sqitch
   # password =
   # port =
   # host =
   # username =
  sqitch.conf
sqitch.conf
[core]

   engine = pg
                        --engine pg
   # plan_file = sqitch.plan
   # top_dir = .
   # deploy_dir = deploy
   # revert_dir = revert
   # test_dir = test
   # extension = sql
# [core "pg"]
   # db_name =
   # client = /usr/local/pgsql/bin/psql
   # sqitch_schema = sqitch
   # password =
   # port =
   # host =
   # username =
  sqitch.conf
Add User Config
>
Add User Config
>sqitch config --user core.pg.client /usr/local/pgsql/bin/psql
>
Add User Config
>sqitch config --user core.pg.client /usr/local/pgsql/bin/psql
>
Add User Config
>sqitch config --user core.pg.client /usr/local/pgsql/bin/psql
>sqitch config --user user.name 'Marge N. O’Vera'
>
Add User Config
>sqitch config --user core.pg.client /usr/local/pgsql/bin/psql
>sqitch config --user user.name 'Marge N. O’Vera'
>sqitch config --user user.email 'marge@example.com'
>
Add User Config
>sqitch config --user core.pg.client /usr/local/pgsql/bin/psql
>sqitch config --user user.name 'Marge N. O’Vera'
>sqitch config --user user.email 'marge@example.com'
>emacs ~/.sqitch/sqitch.conf
~/
          .sqitch/sqitch.conf
[core "pg"]

    client = /usr/local/pgsql/bin/psql
[user]
  
 name = Marge N. O’Vera
   
 email = marge@example.com




  ~/.sqitch/sqitc
~/
          .sqitch/sqitch.conf
[core "pg"]

    client = /usr/local/pgsql/bin/psql
[user]
  
 name = Marge N. O’Vera
   
 email = marge@example.com




                     Good for
                     all projects
  ~/.sqitch/sqitc
What’s the Plan Man?
>
What’s the Plan Man?
>emacs sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b1
%project=flipr
%uri=https://github.com/theory/sqitch-intro/




  sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b1
%project=flipr
%uri=https://github.com/theory/sqitch-intro/




                    Identified
  sqitch.plan
Make It So
>
Make It So
> git add .
> git commit -am 'Initialize Sqitch configuration.'
[master bd7e3f0] Initialize Sqitch configuration.
 2 files changed, 20 insertions(+)
 create mode 100644 sqitch.conf
 create mode 100644 sqitch.plan
>
First Deployment
>
First Deployment
> sqitch add appschema -n 'Adds flipr app schema.'
Created deploy/appschema.sql
Created revert/appschema.sql
Created test/appschema.sql
Added "appschema" to sqitch.plan
>
First Deployment
> sqitch add appschema -n 'Adds flipr app schema.'
Created deploy/appschema.sql
Created revert/appschema.sql
Created test/appschema.sql
Added "appschema" to sqitch.plan
>
First Deployment
> sqitch add appschema -n 'Adds flipr app schema.'
Created deploy/appschema.sql
Created revert/appschema.sql
Created test/appschema.sql
Added "appschema" to sqitch.plan
>
First Deployment
> sqitch add appschema -n 'Adds flipr app schema.'
Created deploy/appschema.sql
Created revert/appschema.sql
Created test/appschema.sql
Added "appschema" to sqitch.plan
>emacs deploy/appschema.sql
deploy/appschema.sql
-- Deploy appschema

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  deploy/
  appschem
deploy/appschema.sql
-- Deploy appschema

BEGIN;

CREATE SCHEMA flipr;

COMMIT;




  deploy/
  appschem
First Deployment
> sqitch add appschema -n 'Adds flipr app schema.'
Created deploy/appschema.sql
Created revert/appschema.sql
Created test/appschema.sql
Added "appschema" to sqitch.plan
> emacs deploy/appschema.sql
>
First Deployment
> sqitch add appschema -n 'Adds flipr app schema.'
Created deploy/appschema.sql
Created revert/appschema.sql
Created test/appschema.sql
Added "appschema" to sqitch.plan
> emacs deploy/appschema.sql
>emacs revert/appschema.sql
revert/appschema.sql
-- Revert appschema

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  revert/appschem
revert/appschema.sql
-- Revert appschema

BEGIN;

DROP SCHEMA flipr;

COMMIT;




  revert/appschem
Make it So!
>
Make it So!
>createdb flipr_test
> sqitch --db-name flipr_test deploy
Adding metadata tables to flipr_test
Deploying to flipr_test
 + appschema
>
Make it So!
>createdb flipr_test
> sqitch --db-name flipr_test deploy
Adding metadata tables to flipr_test
Deploying to flipr_test
 + appschema
>
Make it So!
>createdb flipr_test
> sqitch --db-name flipr_test deploy
Adding metadata tables to flipr_test
Deploying to flipr_test
 + appschema
>
Make it So!
>createdb flipr_test
> sqitch --db-name flipr_test deploy
Adding metadata tables to flipr_test
Deploying to flipr_test
 + appschema
>
Make it So!
>createdb flipr_test
> sqitch --db-name flipr_test deploy
Adding metadata tables to flipr_test
Deploying to flipr_test
 + appschema
> psql -d flipr_test -c 'dn flipr'
List of schemas
 Name | Owner
-------+-------
 flipr | marge
>
How’s it Look?
>
How’s it Look?
> sqitch -d flipr_test status
# On database flipr_test
# Project: flipr
# Change:
9b24259744da156552479197872adba6a01a1ace
# Name:     appschema
# Deployed: 2012-08-16 18:52:40 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
How’s it Look?
> sqitch -d flipr_test status
# On database flipr_test
# Project: flipr
# Change:
9b24259744da156552479197872adba6a01a1ace
# Name:     appschema
# Deployed: 2012-08-16 18:52:40 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
How’s it Look?
> sqitch -d flipr_test status
# On database flipr_test
# Project: flipr
# Change:
9b24259744da156552479197872adba6a01a1ace
# Name:     appschema
# Deployed: 2012-08-16 18:52:40 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
How’s it Look?
> sqitch -d flipr_test status
# On database flipr_test
# Project: flipr
# Change:
9b24259744da156552479197872adba6a01a1ace
# Name:     appschema
# Deployed: 2012-08-16 18:52:40 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
How’s it Look?
> sqitch -d flipr_test status
# On database flipr_test
# Project: flipr
# Change:
9b24259744da156552479197872adba6a01a1ace
# Name:     appschema
# Deployed: 2012-08-16 18:52:40 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
How’s it Look?
> sqitch -d flipr_test status
# On database flipr_test
# Project: flipr
# Change:
9b24259744da156552479197872adba6a01a1ace
# Name:     appschema
# Deployed: 2012-08-16 18:52:40 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
Go Back
>
Go Back
> sqitch --db-name flipr_test revert
Reverting all changes from flipr_test
 - appschema
>
Go Back
> sqitch --db-name flipr_test revert
Reverting all changes from flipr_test
 - appschema
>
Go Back
> sqitch --db-name flipr_test revert
Reverting all changes from flipr_test
 - appschema
>
Go Back
> sqitch --db-name flipr_test revert
Reverting all changes from flipr_test
 - appschema
>psql -d flipr_test -c 'dn flipr'
         List of roles
List of schemas
 Name | Owner
------+-------
What’s The Status?
>
What’s The Status?
> sqitch -d flipr_test status
# On database flipr_test
No changes deployed
>
What’s The Status?
> sqitch -d flipr_test status
# On database flipr_test
No changes deployed
>
History
>
History
> sqitch -d flipr_test log
On database flipr_test
Revert 9b24259744da156552479197872adba6a01a1ace
Name:     appschema
Committer: Marge N. O’Vera <marge@example.com>
Date:    2012-08-16 18:54:55 -0700

  App schema for all flipr objects.

Deploy 9b24259744da156552479197872adba6a01a1ace
Name:    appschema
Committer: Marge N. O’Vera <marge@example.com>
Date:   2012-08-16 18:52:40 -0700

  App schema for all flipr objects.
History
> sqitch -d flipr_test log
On database flipr_test
Revert 9b24259744da156552479197872adba6a01a1ace
Name:     appschema
Committer: Marge N. O’Vera <marge@example.com>
Date:    2012-08-16 18:54:55 -0700

  App schema for all flipr objects.

Deploy 9b24259744da156552479197872adba6a01a1ace
Name:    appschema
Committer: Marge N. O’Vera <marge@example.com>
Date:   2012-08-16 18:52:40 -0700

  App schema for all flipr objects.
History
> sqitch -d flipr_test log
On database flipr_test
Revert 9b24259744da156552479197872adba6a01a1ace
Name:     appschema
Committer: Marge N. O’Vera <marge@example.com>
Date:    2012-08-16 18:54:55 -0700

  App schema for all flipr objects.

Deploy 9b24259744da156552479197872adba6a01a1ace
Name:    appschema
Committer: Marge N. O’Vera <marge@example.com>
Date:   2012-08-16 18:52:40 -0700

  App schema for all flipr objects.
Commit It!
>
Commit It!
> git add .
> git commit -m 'Add flipr schema.'
[master 0fcb493] Add flipr schema.
 4 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 deploy/appschema.sql
 create mode 100644 revert/appschema.sql
 create mode 100644 test/appschema.sql
>
Commit It!
> git add .
> git commit -m 'Add flipr schema.'
[master 0fcb493] Add flipr schema.
 4 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 deploy/appschema.sql
 create mode 100644 revert/appschema.sql
 create mode 100644 test/appschema.sql
>sqitch --db-name flipr_test deploy
Deploying changes to flipr_test
  + appschema
>
Commit It!
> git add .
> git commit -m 'Add flipr schema.'
[master 0fcb493] Add flipr schema.
 4 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 deploy/appschema.sql
 create mode 100644 revert/appschema.sql
 create mode 100644 test/appschema.sql
>sqitch --db-name flipr_test deploy
Deploying changes to flipr_test
  + appschema
>
Commit It!
> git add .
> git commit -m 'Add flipr schema.'
[master 0fcb493] Add flipr schema.
 4 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 deploy/appschema.sql
 create mode 100644 revert/appschema.sql
 create mode 100644 test/appschema.sql
>sqitch --db-name flipr_test deploy
Deploying changes to flipr_test
  + appschema
>psql -d flipr_test -c 'dn flipr'
List of schemas
 Name | Owner
-------+-------
 flipr | marge
Status Update
>
Status Update
> sqitch -d flipr_test status
# On database flipr_test
# Project: flipr
# Change: 9b24259744da156552479197872adba6a01a1ace
# Name:     appschema
# Deployed: 2012-08-16 18:57:03 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
Save My Fingers
>
Save My Fingers
>sqitch config core.pg.db_name flipr_test
>
Save My Fingers
>sqitch config core.pg.db_name flipr_test
>sqitch status
# On database flipr_test
# Project: flipr             No --db-name
# Change: 9b24259744da156552479197872adba6a01a1ace
# Name:     appschema
# Deployed: 2012-08-16 18:57:03 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
Dependencies!
>
Dependencies!
> sqitch add users --requires appschema 
 -n 'Creates table to track our users.'
Created deploy/users.sql
Created revert/users.sql
Created test/users.sql
Added "users [appschema]" to sqitch.plan
>
Dependencies!
> sqitch add users --requires appschema 
 -n 'Creates table to track our users.'
Created deploy/users.sql
Created revert/users.sql
Created test/users.sql
Added "users [appschema]" to sqitch.plan
>
Dependencies!
> sqitch add users --requires appschema 
 -n 'Creates table to track our users.'
Created deploy/users.sql
Created revert/users.sql
Created test/users.sql
Added "users [appschema]" to sqitch.plan
>emacs deploy/users.sql
deploy/users.sql
-- Deploy users
-- requires: appschema

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  deploy/users.sq
deploy/users.sql
-- Deploy users
-- requires: appschema

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  deploy/users.sq
deploy/users.sql
-- Deploy users
-- requires: appschema

BEGIN;

CREATE TABLE flipr.users (
   nickname TEXT      PRIMARY KEY,
   password TEXT     NOT NULL,
   timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

COMMIT;




  deploy/users.sq
Dependencies!
> sqitch add users --requires appschema 
 -n 'Creates table to track our users.'
Created deploy/users.sql
Created revert/users.sql
Created test/users.sql
Added "users [appschema]" to sqitch.plan
> emacs deploy/users.sql
>
Dependencies!
> sqitch add users --requires appschema 
 -n 'Creates table to track our users.'
Created deploy/users.sql
Created revert/users.sql
Created test/users.sql
Added "users [appschema]" to sqitch.plan
> emacs deploy/users.sql
>emacs revert/users.sql
revert/users.sql
-- Revert users

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  revert/users.sq
revert/users.sql
-- Revert users

BEGIN;

DROP TABLE flipr.users;

COMMIT;




  revert/users.sq
Make Users
>
Make Users
>sqitch deploy
Deploying changes to flipr_test
 + users
>
Make Users
>sqitch deploy
Deploying changes to flipr_test
 + users
>
Make Users
>sqitch deploy
Deploying changes to flipr_test
  + users
>psql -d flipr_test -c 'd flipr.users'
              Table "flipr.users"
  Column |     Type |        Modifiers
-----------+-------------+------------------------
 nickname | text       | not null
 password | text       | not null
 timestamp | timestamptz | not null default now()
Indexes:
   "users_pkey" PRIMARY KEY, btree (nickname)
>
Status Update

>
Status Update

> sqitch status
# On database flipr_test
# Project: flipr
# Change: 0521530ed75365d16163e3b46d292c2a29e13dfa
# Name:     users
# Deployed: 2012-08-16 19:01:06 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
Status Update

> sqitch status
# On database flipr_test
# Project: flipr
# Change: 0521530ed75365d16163e3b46d292c2a29e13dfa
# Name:     users
# Deployed: 2012-08-16 19:01:06 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
Status Update

> sqitch status
# On database flipr_test
# Project: flipr
# Change: 0521530ed75365d16163e3b46d292c2a29e13dfa
# Name:     users
# Deployed: 2012-08-16 19:01:06 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>sqitch revert --to @LAST^
Reverting changes to appschema from flipr_test
  - users
>
Status Update

> sqitch status
# On database flipr_test
# Project: flipr
# Change: 0521530ed75365d16163e3b46d292c2a29e13dfa
# Name:     users
# Deployed: 2012-08-16 19:01:06 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>sqitch revert --to @LAST^
Reverting changes to appschema from flipr_test
  - users
>
Symbolic Tags
Symbolic Tags
@LAST   Last deployed change
Symbolic Tags
@LAST    Last deployed change

@FIRST   First deployed change
Symbolic Tags
@LAST    Last deployed change

@FIRST   First deployed change

@HEAD    Last change in the plan
Symbolic Tags
@LAST    Last deployed change

@FIRST   First deployed change

@HEAD    Last change in the plan

@ROOT    First change in the plan
Symbolic Tags
@LAST    Last deployed change

@FIRST   First deployed change

@HEAD    Last change in the plan

@ROOT    First change in the plan

^        Previous change
Symbolic Tags
@LAST    Last deployed change

@FIRST   First deployed change

@HEAD    Last change in the plan

@ROOT    First change in the plan

^        Previous change

~        Following change
Lose Users
>
Lose Users
> psql -d flipr_test -c 'd flipr.users'
Did not find any relation named "flipr.users".
>
Lose Users
> psql -d flipr_test -c 'd flipr.users'
Did not find any relation named "flipr.users".
>git add .
> git commit -am 'Add users table.'
[master dfa6952] Add users table.
 5 files changed, 30 insertions(+)
 create mode 100644 deploy/users.sql
 create mode 100644 revert/users.sql
 create mode 100644 test/users.sql
>
Lose Users
> psql -d flipr_test -c 'd flipr.users'
Did not find any relation named "flipr.users".
>git add .
> git commit -am 'Add users table.'
[master dfa6952] Add users table.
 5 files changed, 30 insertions(+)
 create mode 100644 deploy/users.sql
 create mode 100644 revert/users.sql
 create mode 100644 test/users.sql
>sqitch deploy
Deploying changes to flipr_test
  + users
>
Up to Date
>
Up to Date
> sqitch status
# On database flipr_test
# Project: flipr
# Change: 0521530ed75365d16163e3b46d292c2a29e13dfa
# Name:     users
# Deployed: 2012-08-16 19:03:48 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
Up to Date
> sqitch status
# On database flipr_test
# Project: flipr
# Change: 0521530ed75365d16163e3b46d292c2a29e13dfa
# Name:     users
# Deployed: 2012-08-16 19:03:48 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
Up to Date
> sqitch status
# On database flipr_test
# Project: flipr
# Change: 0521530ed75365d16163e3b46d292c2a29e13dfa
# Name:     users
# Deployed: 2012-08-16 19:03:48 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
A Twofer
>
A Twofer
> sqitch add insert_user -r users -r appschema 
 -n 'Creates a function to insert a user.'
Created deploy/insert_user.sql
Created revert/insert_user.sql
Created test/insert_user.sql
Added "insert_user [users appschema]" to sqitch.plan

>
A Twofer
> sqitch add insert_user -r users -r appschema 
 -n 'Creates a function to insert a user.'
Created deploy/insert_user.sql
Created revert/insert_user.sql
Created test/insert_user.sql
Added "insert_user [users appschema]" to sqitch.plan

>
A Twofer
> sqitch add insert_user -r users -r appschema 
 -n 'Creates a function to insert a user.'
Created deploy/insert_user.sql
Created revert/insert_user.sql
Created test/insert_user.sql
Added "insert_user [users appschema]" to sqitch.plan

>sqitch add change_pass -r users -r appschema 
 -n 'Creates a function to change a user password.'
Created deploy/change_pass.sql
Created revert/change_pass.sql
Created test/change_pass.sql
Added "change_pass [users appschema]" to sqitch.plan

>
A Twofer
> sqitch add insert_user -r users -r appschema 
 -n 'Creates a function to insert a user.'
Created deploy/insert_user.sql
Created revert/insert_user.sql
Created test/insert_user.sql
Added "insert_user [users appschema]" to sqitch.plan

>sqitch add change_pass -r users -r appschema 
 -n 'Creates a function to change a user password.'
Created deploy/change_pass.sql
Created revert/change_pass.sql
Created test/change_pass.sql
Added "change_pass [users appschema]" to sqitch.plan

>
A Twofer
> sqitch add insert_user -r users -r appschema 
 -n 'Creates a function to insert a user.'
Created deploy/insert_user.sql
Created revert/insert_user.sql
Created test/insert_user.sql
Added "insert_user [users appschema]" to sqitch.plan

>sqitch add change_pass -r users -r appschema 
 -n 'Creates a function to change a user password.'
Created deploy/change_pass.sql
Created revert/change_pass.sql
Created test/change_pass.sql
Added "change_pass [users appschema]" to sqitch.plan

>emacs sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com>
# App schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera
<marge@example.com> # Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.




  sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com>
# App schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera
<marge@example.com> # Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.




  sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com>
# App schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera
<marge@example.com> # Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.




  sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com>
# App schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera
<marge@example.com> # Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.




  sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com>
# App schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera
<marge@example.com> # Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.




  sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com>
# App schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera
<marge@example.com> # Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.




  sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com>
# App schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera
<marge@example.com> # Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.




  sqitch.plan
sqitch.plan
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com>
# App schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera
<marge@example.com> # Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.




  sqitch.plan
A Twofer
>
A Twofer
>emacs sqitch.plan
> emacs deploy/insert_user.sql
deploy/insert_user.sql
-- Deploy insert_user
-- requires: appuser
-- requires: users

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  deploy/insert_u
deploy/insert_user.sql
-- Deploy insert_user
-- requires: appuser
-- requires: users

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  deploy/insert_u
deploy/insert_user.sql
-- Deploy insert_user
-- requires: appuser
-- requires: users

BEGIN;

CREATE OR REPLACE FUNCTION flipr.insert_user(
   nickname TEXT,
   password TEXT
) RETURNS VOID LANGUAGE SQL SECURITY DEFINER AS $$
   INSERT INTO users VALUES($1, md5($2));
$$;

COMMIT;


  deploy/insert_u
A Twofer
>emacs sqitch.plan
> emacs deploy/insert_user.sql
>
A Twofer
>emacs sqitch.plan
> emacs deploy/insert_user.sql
>emacs deploy/change_pass.sql
deploy/change_pass.sql
-- Deploy change_pass
-- :requires: appuser
-- :requires: users

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  deploy/change_u
deploy/change_pass.sql
-- Deploy change_pass
-- :requires: appuser
-- :requires: users

BEGIN;
CREATE OR REPLACE FUNCTION flipr.change_pass(
    nick TEXT, oldpass TEXT, newpass TEXT
) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER AS $$
BEGIN
   UPDATE users SET password = md5($3)
    WHERE nickname = $1 AND password = md5($2);
   RETURN FOUND;
END;
$$;

COMMIT;
 deploy/change_u
Deploy Functions
>
Deploy Functions
> sqitch deploy
Deploying changes to flipr_test
 + insert_user
 + change_pass
>
Deploy Functions
> sqitch deploy
Deploying changes to flipr_test
  + insert_user
  + change_pass
> psql -d flipr_test -c 'df flipr.*'
                          List of function
 Schema | Name         | Result data type |
--------+-------------+------------------+----------
 flipr | change_pass | boolean            | nick text
 flipr | insert_user | void           | nickname
>
Deploy Functions
> sqitch deploy
Deploying changes to flipr_test
  + insert_user
  + change_pass
> psql -d flipr_test -c 'df flipr.*'
                          List of function
 Schema | Name         | Result data type |
--------+-------------+------------------+----------
 flipr | change_pass | boolean            | nick text
 flipr | insert_user | void           | nickname
>
Status Update
>
Status Update
> sqitch status
# On database flipr_test
# Project: flipr
# Change: 99408db589f6031b6e851bce17aec7f870ed11e6
# Name:     change_pass
# Deployed: 2012-08-16 19:10:58 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
>
Revert
>
Revert
> sqitch revert --to @LAST^^
Reverting changes to users from flipr_test
 - change_pass
 - insert_user
>
Revert
> sqitch revert --to @LAST^^
Reverting changes to users from flipr_test
 - change_pass
 - insert_user
>
Revert
> sqitch revert --to @LAST^^
Reverting changes to users from flipr_test
  - change_pass
  - insert_user
>psql -d flipr_test -c 'df flipr.*'
                List of functions
 Schema | Name | Result data type | Argument data ty
--------+------+------------------+-----------------
>
Commit It
Commit It
git add && git commit
Commit It
git add && git commit

sqitch deploy
Commit It
git add && git commit

sqitch deploy

And now…
Commit It
git add && git commit

sqitch deploy

And now…

  Tag
Commit It
git add && git commit

sqitch deploy

And now…

  Tag

  Bundle
Commit It
git add && git commit

sqitch deploy

And now…

  Tag

  Bundle

  Ship!
Tag It!
>
Tag It!
> sqitch tag v1.0.0-dev1 -n 'Tag v1.0.0-dev1.'
Tagged "change_pass" with @v1.0.0-dev1
>
Tag It!
> sqitch tag v1.0.0-dev1 -n 'Tag v1.0.0-dev1.'
Tagged "change_pass" with @v1.0.0-dev1
>
Tag It!
> sqitch tag v1.0.0-dev1 -n 'Tag v1.0.0-dev1.'
Tagged "change_pass" with @v1.0.0-dev1
>git commit -am 'Tag the database with v1.0.0-dev1.'
[master 067ef73] Tag the database with v1.0.0-dev1.
 1 file changed, 1 insertion(+)
>
Tag It!
> sqitch tag v1.0.0-dev1 -n 'Tag v1.0.0-dev1.'
Tagged "change_pass" with @v1.0.0-dev1
>git commit -am 'Tag the database with v1.0.0-dev1.'
[master 067ef73] Tag the database with v1.0.0-dev1.
 1 file changed, 1 insertion(+)
>git tag v1.0.0-dev1 -am 'Tag v1.0.0-dev1'
>
Bundle It!
>
Bundle It!
> sqitch bundle
Bundling into bundle/
Writing config
Writing plan
Writing scripts
 + appschema
 + users
 + insert_user
 + change_pass @v1.0.0-dev1
>
Bundle It!
> sqitch bundle
Bundling into bundle/
Writing config
Writing plan
Writing scripts
 + appschema
 + users
 + insert_user
 + change_pass @v1.0.0-dev1
>
Test and Ship It!
>
Test and Ship It!
>cd bundle
>
Test and Ship It!
>cd bundle
>createdb flipr_stage
>
Test and Ship It!
>cd bundle
>createdb flipr_stage
>sqitch --db-name flipr_stage deploy
Adding metadata tables to flipr_stage
Deploying changes to flipr_stage
 + appschema
 + users
 + insert_user
 + change_pass @v1.0.0-dev1
>
Test and Ship It!
>cd bundle
>createdb flipr_stage
>sqitch --db-name flipr_stage deploy
Adding metadata tables to flipr_stage
Deploying changes to flipr_stage
 + appschema
 + users
 + insert_user
 + change_pass @v1.0.0-dev1
> cd ..
> mv bundle flipr-1.0.0-dev1
> tar -czf flipr-1.0.0-dev1.tar.gz flipr-1.0.0-dev1
>
Reworking Changes
Ruh-Roh
>
Ruh-Roh
>psql -d flipr_test -c "
   SELECT insert_user('foo', 'secr3t'),
       insert_user('bar', 'secr3t');
   SELECT nickname, password FROM users;
"
 nickname |          password
----------+----------------------------------
 foo    | 9695da4dd567a19f9b92065f240c6725
 bar    | 9695da4dd567a19f9b92065f240c6725
Ruh-Roh
>psql -d flipr_test -c "
   SELECT insert_user('foo', 'secr3t'),
       insert_user('bar', 'secr3t');
   SELECT nickname, password FROM users;
"
 nickname |          password
----------+----------------------------------
 foo    | 9695da4dd567a19f9b92065f240c6725
 bar    | 9695da4dd567a19f9b92065f240c6725




                       Not good.
Add pgcrypto
>
Add pgcrypto
>sqitch add pgcrypto -n 'Loads pgcrypto extension.'
Adding deploy/pgcrypto.sql
Adding revert/pgcrypto.sql
Adding test/pgcrypto.sql
Added "pgcrypto" to sqitch.plan
>
Add pgcrypto
>sqitch add pgcrypto -n 'Loads pgcrypto extension.'
Adding deploy/pgcrypto.sql
Adding revert/pgcrypto.sql
Adding test/pgcrypto.sql
Added "pgcrypto" to sqitch.plan
>emacs deploy/pgcrpyto.sql
deploy/pgcrypto.sql
-- Deploy pgcrypto

BEGIN;

-- XXX Add DDLs here.

COMMIT;




  deploy/pgcrypto
deploy/pgcrypto.sql
-- Deploy pgcrypto

BEGIN;

CREATE EXTENSION pgcrypto;

COMMIT;




  deploy/pgcrypto
How to Modify?
How to Modify?
Copy insert_user.sql to new deploy file
How to Modify?
Copy insert_user.sql to new deploy file

Change that new file
How to Modify?
Copy insert_user.sql to new deploy file

Change that new file

Copy insert_user.sql to new revert file
How to Modify?
Copy insert_user.sql to new deploy file

Change that new file

Copy insert_user.sql to new revert file

Test it
How to Modify?
Copy insert_user.sql to new deploy file

Change that new file

Copy insert_user.sql to new revert file

Test it

Do the same for change_pass.sql
How to Modify?
Copy insert_user.sql to new deploy file

Change that new file

Copy insert_user.sql to new revert file

Test it

Do the same for change_pass.sql

The problem with that…
>
> git diff HEAD^
diff --git a/deploy/insert_user_crypt.sql b/deploy/insert_user_crypto.sql
new file mode 100644
index 0000000..fa8d0c6
--- /dev/null
+++ b/deploy/insert_user_crypt.sql
@@ -0,0 +1,8 @@
+-- requires: users, appuser, pgcrypto
+
+CREATE OR REPLACE FUNCTION insert_user(
+ nickname TEXT,
+ password TEXT
+) RETURNS VOID LANGUAGE SQL AS $$
+ INSERT INTO users values($1, crypt($2, gen_salt('md5')));
+$$;
diff --git a/revert/insert_user_crypt.sql b/revert/insert_user_crypto.sql
new file mode 100644
index 0000000..a7f4e31
--- /dev/null
+++ b/revert/insert_user_crypt.sql
@@ -0,0 +1,8 @@
+-- requires: users, appuser
+
+CREATE OR REPLACE FUNCTION insert_user(
+ nickname TEXT,
+ password TEXT
+) RETURNS VOID LANGUAGE SQL AS $$
+ INSERT INTO users values($1, md5($2));
+$$;
> git diff HEAD^
diff --git a/deploy/insert_user_crypt.sql b/deploy/insert_user_crypto.sql
new file mode 100644
index 0000000..fa8d0c6
--- /dev/null
+++ b/deploy/insert_user_crypt.sql
@@ -0,0 +1,8 @@
+-- requires: users, appuser, pgcrypto
+
+CREATE OR REPLACE FUNCTION insert_user(
+ nickname TEXT,
+ password TEXT
+) RETURNS VOID LANGUAGE SQL AS $$
+ INSERT INTO users values($1, crypt($2, gen_salt('md5')));
+$$;
diff --git a/revert/insert_user_crypt.sql b/revert/insert_user_crypto.sql
new file mode 100644
index 0000000..a7f4e31
--- /dev/null
+++ b/revert/insert_user_crypt.sql
@@ -0,0 +1,8 @@
+-- requires: users, appuser
+
+CREATE OR REPLACE FUNCTION insert_user(
+ nickname TEXT,
+ password TEXT
+) RETURNS VOID LANGUAGE SQL AS $$
+ INSERT INTO users values($1, md5($2));
+$$;                                                              Oy.
Let Sqitch do the work.
Rework It
>
Rework It
>sqitch rework insert_user -r pgcrypto 
 -n 'Changes insert_user to use pgcrypto.'
Added "insert_user [insert_user@v1.0.0-dev1 pgcrypto]" to sqitch.plan.
Modify these files as appropriate:
 * deploy/insert_user.sql
 * revert/insert_user.sql
 * test/insert_user.sql
>
Rework It
>sqitch rework insert_user -r pgcrypto 
 -n 'Changes insert_user to use pgcrypto.'
Added "insert_user [insert_user@v1.0.0-dev1 pgcrypto]" to sqitch.plan.
Modify these files as appropriate:
 * deploy/insert_user.sql
 * revert/insert_user.sql
 * test/insert_user.sql
>
Rework It
>sqitch rework insert_user -r pgcrypto 
 -n 'Changes insert_user to use pgcrypto.'
Added "insert_user [insert_user@v1.0.0-dev1 pgcrypto]" to sqitch.plan.
Modify these files as appropriate:
 * deploy/insert_user.sql
 * revert/insert_user.sql
 * test/insert_user.sql
>
Rework It
>sqitch rework insert_user -r pgcrypto 
 -n 'Changes insert_user to use pgcrypto.'
Added "insert_user [insert_user@v1.0.0-dev1 pgcrypto]" to sqitch.plan.
Modify these files as appropriate:
 * deploy/insert_user.sql
 * revert/insert_user.sql
 * test/insert_user.sql
>




                         Same files?
Same Files?
>
Same Files?
>git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 13 and 14 different commits each, respectively.
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working direct
#
#
 modified: revert/insert_user.sql
#
 modified: sqitch.plan
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#
 deploy/insert_user@v1.0.0-dev1.sql
#
 revert/insert_user@v1.0.0-dev1.sql
#
 test/insert_user@v1.0.0-dev1.sql
no changes added to commit (use "git add" and/or "git commit -a")
Same Files?
>git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 13 and 14 different commits each, respectively.
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working direct
#
#
 modified: revert/insert_user.sql
#
 modified: sqitch.plan
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#
 deploy/insert_user@v1.0.0-dev1.sql
#
 revert/insert_user@v1.0.0-dev1.sql
#
 test/insert_user@v1.0.0-dev1.sql
no changes added to commit (use "git add" and/or "git commit -a")
Same Files?
>git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 13 and 14 different commits each, respectively.
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working direct
#
#
 modified: revert/insert_user.sql
#
 modified: sqitch.plan
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#
 deploy/insert_user@v1.0.0-dev1.sql
#
 revert/insert_user@v1.0.0-dev1.sql                      As of
#
 test/insert_user@v1.0.0-dev1.sql
                                                        @v1.0.0-dev1
no changes added to commit (use "git add" and/or "git commit -a")
Same Files?
>git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 13 and 14 different commits each, respectively.
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working direct
#
#
 modified: revert/insert_user.sql
#
 modified: sqitch.plan
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#
 deploy/insert_user@v1.0.0-dev1.sql
#
 revert/insert_user@v1.0.0-dev1.sql
#
 test/insert_user@v1.0.0-dev1.sql
no changes added to commit (use "git add" and/or "git commit -a")
Same Files?
>git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 13 and 14 different commits each, respectively.
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working direct
#
#
 modified: revert/insert_user.sql
#
 modified: sqitch.plan                                 Previous deploy
#
# Untracked files:                                       becomes revert
# (use "git add <file>..." to include in what will be committed)
#
#
 deploy/insert_user@v1.0.0-dev1.sql
#
 revert/insert_user@v1.0.0-dev1.sql
#
 test/insert_user@v1.0.0-dev1.sql
no changes added to commit (use "git add" and/or "git commit -a")
What’s the Diff?
>
What’s the Diff?
>diff -u deploy/insert_user.sql
@@ -1,6 +1,7 @@
 -- Deploy insert_user
 -- requires: users
 -- requires: appschema
+-- requires: pgcrypto

BEGIN;

@@ -8,7 +9,7 @@ CREATE OR REPLACE FUNCTION flipr.insert_user(
    nickname TEXT,
    password TEXT
 ) RETURNS VOID LANGUAGE SQL SECURITY DEFINER AS $$
- INSERT INTO flipr.users VALUES($1, md5($2));
+ INSERT INTO flipr.users values($1, crypt($2, gen_salt('md5')));
 $$;

COMMIT;
Rework change_pass
>
Rework change_pass
>sqitch rework change_pass -r pgcrypto 
 -n 'Change change_pass to use pgcrypto.'
Added "change_pass [change_pass@v1.0.0-dev1 pgcrypto]" to sqitch.plan.
Modify these files as appropriate:
 * deploy/change_pass.sql
 * revert/change_pass.sql
 * test/change_pass.sql
>
Rework change_pass
>sqitch rework change_pass -r pgcrypto 
 -n 'Change change_pass to use pgcrypto.'
Added "change_pass [change_pass@v1.0.0-dev1 pgcrypto]" to sqitch.plan.
Modify these files as appropriate:
 * deploy/change_pass.sql
 * revert/change_pass.sql
 * test/change_pass.sql
>
Rework change_pass
>sqitch rework change_pass -r pgcrypto 
 -n 'Change change_pass to use pgcrypto.'
Added "change_pass [change_pass@v1.0.0-dev1 pgcrypto]" to sqitch.plan.
Modify these files as appropriate:
 * deploy/change_pass.sql
 * revert/change_pass.sql
 * test/change_pass.sql
>
Rework change_pass
>sqitch rework change_pass -r pgcrypto 
 -n 'Change change_pass to use pgcrypto.'
Added "change_pass [change_pass@v1.0.0-dev1 pgcrypto]" to sqitch.plan.
Modify these files as appropriate:
 * deploy/change_pass.sql
 * revert/change_pass.sql
 * test/change_pass.sql
>




                        Same files?
What’s the Diff?
>
What’s the Diff?
>diff -u deploy/change_pass.sql
@@ -1,6 +1,7 @@
 -- Deploy change_pass
 -- requires: users
 -- requires: appschema
+-- requires: pgcrypto

BEGIN;

@@ -11,9 +12,9 @@ CREATE OR REPLACE FUNCTION flipr.change_pass(
 ) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER AS $$
 BEGIN
    UPDATE flipr.users
-     SET password = md5($3)
+     SET password = crypt($3, gen_salt('md5'))
     WHERE nickname = $1
-     AND password = md5($2);
+     AND password = crypt($2, password);
    RETURN FOUND;
 END;
 $$;
Send it Up!
>
Send it Up!
> sqitch deploy
Deploying changes to flipr_test
 + insert_user
 + change_pass
>
Send it Up!
> sqitch deploy
Deploying changes to flipr_test
  + insert_user
  + change_pass
>psql -d flipr_test -c "
   DELETE FROM users;
   SELECT insert_user('foo', 'secr3t'),
        insert_user('bar', 'secr3t');
   SELECT nickname, password FROM users;
"
 nickname |           password
----------+------------------------------------
 foo     | $1$l6OEKyF3$kv5ae7505ROub75d9QKTh/
 bar     | $1$J4NJDgaJ$578i9Lt6b8ohJwi6WhNNO1
>
Send it Up!
> sqitch deploy
Deploying changes to flipr_test
  + insert_user
  + change_pass
>psql -d flipr_test -c "
                                   o/
   DELETE FROM users;
   SELECT insert_user('foo', 'secr3t'),
        insert_user('bar', 'secr3t');
   SELECT nickname, password FROM users;
"
 nickname |           password
----------+------------------------------------
 foo     | $1$l6OEKyF3$kv5ae7505ROub75d9QKTh/
 bar     | $1$J4NJDgaJ$578i9Lt6b8ohJwi6WhNNO1
>
Can We Go Back?
>
Can We Go Back?
> sqitch revert --to @LAST^^
Reverting changes to pgcrypto from flipr_test
 - change_pass
 - insert_user
>
Can We Go Back?
> sqitch revert --to @LAST^^
Reverting changes to pgcrypto from flipr_test
  - change_pass
  - insert_user
>psql -d flipr_test -c "
   DELETE FROM users;
   SELECT insert_user('foo', 'secr3t'),
        insert_user('bar', 'secr3t');
   SELECT nickname, password FROM users;
"
 nickname |           password
----------+----------------------------------
 foo     | 9695da4dd567a19f9b92065f240c6725
 bar     | 9695da4dd567a19f9b92065f240c6725
>
What About Bundling?
>
What About Bundling?
> sqitch tag v1.0.0-b1 -n 'Tag v1.0.0-b1.'
> git tag v1.0.0-b1 -am 'Tag v1.0.0-b1'
> sqitch bundle
Bundling into bundle
Writing config
Writing plan
Writing scripts
 + appschema
 + users
 + insert_user
 + change_pass @v1.0.0-dev1
 + pgcrypto
 + insert_user
 + change_pass @v1.0.0-b1
>
What About Bundling?
> sqitch tag v1.0.0-b1 -n 'Tag v1.0.0-b1.'
> git tag v1.0.0-b1 -am 'Tag v1.0.0-b1'
> sqitch bundle
Bundling into bundle
Writing config
Writing plan
Writing scripts
 + appschema
 + users
 + insert_user
 + change_pass @v1.0.0-dev1
 + pgcrypto
 + insert_user
 + change_pass @v1.0.0-b1
>
What About Bundling?
> sqitch tag v1.0.0-b1 -n 'Tag v1.0.0-b1.'
> git tag v1.0.0-b1 -am 'Tag v1.0.0-b1'
> sqitch bundle
Bundling into bundle
Writing config
Writing plan
Writing scripts
 + appschema
 + users
 + insert_user
 + change_pass @v1.0.0-dev1
 + pgcrypto
 + insert_user
 + change_pass @v1.0.0-b1
>
What About Bundling?
> sqitch tag v1.0.0-b1 -n 'Tag v1.0.0-b1.'
> git tag v1.0.0-b1 -am 'Tag v1.0.0-b1'
> sqitch bundle
Bundling into bundle
Writing config
Writing plan
Writing scripts
 + appschema
 + users
 + insert_user
 + change_pass @v1.0.0-dev1
 + pgcrypto
 + insert_user
 + change_pass @v1.0.0-b1
>emacs bundle/sqitch.plan
What’s the Plan?
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App
schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com>
# Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.
@v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
v1.0.0-dev1.

pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads
the pgcrypto extension.
insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N.
O’Vera <marge@example.com> # Change insert_user to use pgcrypto.
change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N.
O’Vera <marge@example.com> # Change change_pass to use pgcrypto.
@v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
  bundle/sqitch.p
What’s the Plan?
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App
schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com>
# Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.
@v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
v1.0.0-dev1.

pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads
the pgcrypto extension.
insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N.
O’Vera <marge@example.com> # Change insert_user to use pgcrypto.
change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N.
O’Vera <marge@example.com> # Change change_pass to use pgcrypto.
@v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
  bundle/sqitch.p
What’s the Plan?
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App
schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com>
# Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.
@v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
v1.0.0-dev1.

pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads
the pgcrypto extension.
insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N.
O’Vera <marge@example.com> # Change insert_user to use pgcrypto.
change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N.
O’Vera <marge@example.com> # Change change_pass to use pgcrypto.
@v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
  bundle/sqitch.p
What’s the Plan?
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App
schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com>
# Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.
@v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
v1.0.0-dev1.

pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads
the pgcrypto extension.
insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N.
O’Vera <marge@example.com> # Change insert_user to use pgcrypto.
change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N.
O’Vera <marge@example.com> # Change change_pass to use pgcrypto.
@v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
  bundle/sqitch.p
What’s the Plan?
%syntax-version=1.0.0-b2
%project=flipr
%uri=https://github.com/theory/sqitch-intro/

appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App
schema for all flipr objects.
users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com>
# Creates table to track our users.
insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera
<marge@example.com> # Creates a function to insert a user.
change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera
<marge@example.com> # Creates a function to change a user password.
@v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
v1.0.0-dev1.

pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads
the pgcrypto extension.
insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N.
O’Vera <marge@example.com> # Change insert_user to use pgcrypto.
change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N.
O’Vera <marge@example.com> # Change change_pass to use pgcrypto.
@v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag
  bundle/sqitch.p
Make it So
>
Make it So
>cd bundle
>
Make it So
>cd bundle
>sqitch --db-name flipr_stage deploy
Deploying changes to flipr_stage
 + pgcrypto
 + insert_user
 + change_pass @v1.0.0-b1
>
Make it So
>cd bundle
>sqitch --db-name flipr_stage deploy
Deploying changes to flipr_stage
  + pgcrypto
  + insert_user
  + change_pass @v1.0.0-b1
>sqitch --db-name flipr_stage status
# On database flipr_stage
# Project: flipr
# Change: d0eb9c5ff822877696e834d686a4d9ee8a5cd2a9
# Name:     change_pass
# Tag:     @v1.0.0-b1
# Deployed: 2012-08-17 13:42:09 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
Make it So
>cd bundle
>sqitch --db-name flipr_stage deploy
Deploying changes to flipr_stage
  + pgcrypto
  + insert_user
  + change_pass @v1.0.0-b1
>sqitch --db-name flipr_stage status
# On database flipr_stage
# Project: flipr
# Change: d0eb9c5ff822877696e834d686a4d9ee8a5cd2a9
# Name:     change_pass
# Tag:     @v1.0.0-b1
# Deployed: 2012-08-17 13:42:09 -0700
# By:     Marge N. O’Vera <marge@example.com>
#
Nothing to deploy (up-to-date)
Ship It!
Other Commands
Other Commands
help - Get it
Other Commands
help - Get it

log - Like git log
Other Commands
help - Get it

log - Like git log

check - Validate plan & database
Other Commands
help - Get it

log - Like git log

check - Validate plan & database

test - Test deployment success
Current Status
Current Status
Adding locale support
Current Status
Adding locale support

Porting to SQLite
Current Status
Adding locale support

Porting to SQLite

Adding VCS/SCM integration
Current Status
Adding locale support

Porting to SQLite

Adding VCS/SCM integration

  Sync tags
Current Status
Adding locale support

Porting to SQLite

Adding VCS/SCM integration

  Sync tags

  Fetch reworked files from history
Fork It
Fork It
http:/
     /sqitch.org/
Fork It
http:/
     /sqitch.org/

https:/
      /github.com/theory/sqitch/
Fork It
http:/
     /sqitch.org/

https:/
      /github.com/theory/sqitch/

Opinions wanted
Fork It
http:/
     /sqitch.org/

https:/
      /github.com/theory/sqitch/

Opinions wanted

Coders wanted
Fork It
http:/
     /sqitch.org/

https:/
      /github.com/theory/sqitch/

Opinions wanted

Coders wanted

Doc writers and web designers wanted!
Fork It
http:/
     /sqitch.org/

https:/
      /github.com/theory/sqitch/

Opinions wanted

Coders wanted

Doc writers and web designers wanted!

Make it great!
Thank you.
Sane SQL Change
  Management with Sqitch
                                                       David E. Wheeler
                                                      http:/
                                                           /sqitch.org/


                                                       PDXPUG
                                                 September 20, 2012




Text: Attribution-Noncommercial-Share Alike 3.0 United States:
http://creativecommons.org/licenses/by-nc-sa/3.0/us/
Images licensed independently and © Their respective owners.

Mais conteúdo relacionado

Mais procurados

Gearman work queue in php
Gearman work queue in phpGearman work queue in php
Gearman work queue in phpBo-Yi Wu
 
Max Voloshin - "Organization of frontend development for products with micros...
Max Voloshin - "Organization of frontend development for products with micros...Max Voloshin - "Organization of frontend development for products with micros...
Max Voloshin - "Organization of frontend development for products with micros...IT Event
 
The Bash Dashboard (Or: How to Use Bash for Data Analysis)
The Bash Dashboard (Or: How to Use Bash for Data Analysis)The Bash Dashboard (Or: How to Use Bash for Data Analysis)
The Bash Dashboard (Or: How to Use Bash for Data Analysis)Bram Adams
 
What’s New in Rails 5.0?
What’s New in Rails 5.0?What’s New in Rails 5.0?
What’s New in Rails 5.0?Unboxed
 
KYSUC - Keep Your Schema Under Control
KYSUC - Keep Your Schema Under ControlKYSUC - Keep Your Schema Under Control
KYSUC - Keep Your Schema Under ControlCoimbra JUG
 
Nina Zakharenko - Introduction to Git - Start SLC 2015
Nina Zakharenko - Introduction to Git - Start SLC 2015Nina Zakharenko - Introduction to Git - Start SLC 2015
Nina Zakharenko - Introduction to Git - Start SLC 2015Nina Zakharenko
 
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008Baruch Sadogursky
 
One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.Javier López
 
Continous Delivering a PHP application
Continous Delivering a PHP applicationContinous Delivering a PHP application
Continous Delivering a PHP applicationJavier López
 
Мониторинг облачной CI-системы на примере Jenkins / Александр Акбашев (HERE T...
Мониторинг облачной CI-системы на примере Jenkins / Александр Акбашев (HERE T...Мониторинг облачной CI-системы на примере Jenkins / Александр Акбашев (HERE T...
Мониторинг облачной CI-системы на примере Jenkins / Александр Акбашев (HERE T...Ontico
 
Hosting Your Own OTA Update Service
Hosting Your Own OTA Update ServiceHosting Your Own OTA Update Service
Hosting Your Own OTA Update ServiceQuinlan Jung
 
Deep dark-side of git: How git works internally
Deep dark-side of git: How git works internallyDeep dark-side of git: How git works internally
Deep dark-side of git: How git works internallySeongJae Park
 
Javascript - The Stack and Beyond
Javascript - The Stack and BeyondJavascript - The Stack and Beyond
Javascript - The Stack and BeyondAll Things Open
 
VCS for Teamwork - GIT Workshop
VCS for Teamwork - GIT WorkshopVCS for Teamwork - GIT Workshop
VCS for Teamwork - GIT WorkshopAnis Ahmad
 
That's (g)it! par Sébastien Dawans CETIC
That's (g)it! par Sébastien Dawans CETICThat's (g)it! par Sébastien Dawans CETIC
That's (g)it! par Sébastien Dawans CETICLa FeWeb
 
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...Ortus Solutions, Corp
 
ITB2019 CommandBox vs Node.js - Nolan Erck
ITB2019  CommandBox vs Node.js - Nolan ErckITB2019  CommandBox vs Node.js - Nolan Erck
ITB2019 CommandBox vs Node.js - Nolan ErckOrtus Solutions, Corp
 
Tracing Software Build Processes to Uncover License Compliance Inconsistencies
Tracing Software Build Processes to Uncover License Compliance InconsistenciesTracing Software Build Processes to Uncover License Compliance Inconsistencies
Tracing Software Build Processes to Uncover License Compliance InconsistenciesShane McIntosh
 
Recovering From Git Mistakes - Nina Zakharenko
Recovering From Git Mistakes - Nina ZakharenkoRecovering From Git Mistakes - Nina Zakharenko
Recovering From Git Mistakes - Nina ZakharenkoNina Zakharenko
 

Mais procurados (20)

Gearman work queue in php
Gearman work queue in phpGearman work queue in php
Gearman work queue in php
 
Max Voloshin - "Organization of frontend development for products with micros...
Max Voloshin - "Organization of frontend development for products with micros...Max Voloshin - "Organization of frontend development for products with micros...
Max Voloshin - "Organization of frontend development for products with micros...
 
The Bash Dashboard (Or: How to Use Bash for Data Analysis)
The Bash Dashboard (Or: How to Use Bash for Data Analysis)The Bash Dashboard (Or: How to Use Bash for Data Analysis)
The Bash Dashboard (Or: How to Use Bash for Data Analysis)
 
What’s New in Rails 5.0?
What’s New in Rails 5.0?What’s New in Rails 5.0?
What’s New in Rails 5.0?
 
KYSUC - Keep Your Schema Under Control
KYSUC - Keep Your Schema Under ControlKYSUC - Keep Your Schema Under Control
KYSUC - Keep Your Schema Under Control
 
Nina Zakharenko - Introduction to Git - Start SLC 2015
Nina Zakharenko - Introduction to Git - Start SLC 2015Nina Zakharenko - Introduction to Git - Start SLC 2015
Nina Zakharenko - Introduction to Git - Start SLC 2015
 
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
Wicket Presentation @ AlphaCSP Java Web Frameworks Playoff 2008
 
One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.One commit, one release. Continuously delivering a Symfony project.
One commit, one release. Continuously delivering a Symfony project.
 
Continous Delivering a PHP application
Continous Delivering a PHP applicationContinous Delivering a PHP application
Continous Delivering a PHP application
 
Мониторинг облачной CI-системы на примере Jenkins / Александр Акбашев (HERE T...
Мониторинг облачной CI-системы на примере Jenkins / Александр Акбашев (HERE T...Мониторинг облачной CI-системы на примере Jenkins / Александр Акбашев (HERE T...
Мониторинг облачной CI-системы на примере Jenkins / Александр Акбашев (HERE T...
 
Hosting Your Own OTA Update Service
Hosting Your Own OTA Update ServiceHosting Your Own OTA Update Service
Hosting Your Own OTA Update Service
 
Deep dark-side of git: How git works internally
Deep dark-side of git: How git works internallyDeep dark-side of git: How git works internally
Deep dark-side of git: How git works internally
 
Namshi in 2014: let's rock!
Namshi in 2014: let's rock!Namshi in 2014: let's rock!
Namshi in 2014: let's rock!
 
Javascript - The Stack and Beyond
Javascript - The Stack and BeyondJavascript - The Stack and Beyond
Javascript - The Stack and Beyond
 
VCS for Teamwork - GIT Workshop
VCS for Teamwork - GIT WorkshopVCS for Teamwork - GIT Workshop
VCS for Teamwork - GIT Workshop
 
That's (g)it! par Sébastien Dawans CETIC
That's (g)it! par Sébastien Dawans CETICThat's (g)it! par Sébastien Dawans CETIC
That's (g)it! par Sébastien Dawans CETIC
 
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
ITB2019 ColdBox APIs + VueJS - powering Mobile, Desktop and Web Apps with 1 V...
 
ITB2019 CommandBox vs Node.js - Nolan Erck
ITB2019  CommandBox vs Node.js - Nolan ErckITB2019  CommandBox vs Node.js - Nolan Erck
ITB2019 CommandBox vs Node.js - Nolan Erck
 
Tracing Software Build Processes to Uncover License Compliance Inconsistencies
Tracing Software Build Processes to Uncover License Compliance InconsistenciesTracing Software Build Processes to Uncover License Compliance Inconsistencies
Tracing Software Build Processes to Uncover License Compliance Inconsistencies
 
Recovering From Git Mistakes - Nina Zakharenko
Recovering From Git Mistakes - Nina ZakharenkoRecovering From Git Mistakes - Nina Zakharenko
Recovering From Git Mistakes - Nina Zakharenko
 

Destaque

Hooked Model
Hooked ModelHooked Model
Hooked ModelNir Eyal
 
Devops and Immutable infrastructure - Cloud Expo 2015 NYC
Devops and Immutable infrastructure  - Cloud Expo 2015 NYCDevops and Immutable infrastructure  - Cloud Expo 2015 NYC
Devops and Immutable infrastructure - Cloud Expo 2015 NYCJohn Willis
 
Enterprise Habit-Forming Products
Enterprise Habit-Forming ProductsEnterprise Habit-Forming Products
Enterprise Habit-Forming ProductsNir Eyal
 
Why People Check Their Tech at the Wrong Times (and the Simple Trick to Stop It)
Why People Check Their Tech at the Wrong Times (and the Simple Trick to Stop It)Why People Check Their Tech at the Wrong Times (and the Simple Trick to Stop It)
Why People Check Their Tech at the Wrong Times (and the Simple Trick to Stop It)Nir Eyal
 
Hooked Workshop
Hooked WorkshopHooked Workshop
Hooked WorkshopNir Eyal
 

Destaque (7)

Hooked Model
Hooked ModelHooked Model
Hooked Model
 
Devops and Immutable infrastructure - Cloud Expo 2015 NYC
Devops and Immutable infrastructure  - Cloud Expo 2015 NYCDevops and Immutable infrastructure  - Cloud Expo 2015 NYC
Devops and Immutable infrastructure - Cloud Expo 2015 NYC
 
Enterprise Habit-Forming Products
Enterprise Habit-Forming ProductsEnterprise Habit-Forming Products
Enterprise Habit-Forming Products
 
Why People Check Their Tech at the Wrong Times (and the Simple Trick to Stop It)
Why People Check Their Tech at the Wrong Times (and the Simple Trick to Stop It)Why People Check Their Tech at the Wrong Times (and the Simple Trick to Stop It)
Why People Check Their Tech at the Wrong Times (and the Simple Trick to Stop It)
 
Bessemer's 10 Laws of Cloud Computing
Bessemer's 10 Laws of Cloud ComputingBessemer's 10 Laws of Cloud Computing
Bessemer's 10 Laws of Cloud Computing
 
Hooked: How to Build Habit-Forming Products
Hooked: How to Build Habit-Forming ProductsHooked: How to Build Habit-Forming Products
Hooked: How to Build Habit-Forming Products
 
Hooked Workshop
Hooked WorkshopHooked Workshop
Hooked Workshop
 

Semelhante a Sane SQL Change Management with Sqitch

Simple SQL Change Management with Sqitch
Simple SQL Change Management with SqitchSimple SQL Change Management with Sqitch
Simple SQL Change Management with SqitchDavid Wheeler
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainKen Collins
 
Deploying TYPO3 Neos websites using Surf
Deploying TYPO3 Neos websites using SurfDeploying TYPO3 Neos websites using Surf
Deploying TYPO3 Neos websites using SurfKarsten Dambekalns
 
PgConf US 2015 - ALTER DATABASE ADD more SANITY
PgConf US 2015  - ALTER DATABASE ADD more SANITYPgConf US 2015  - ALTER DATABASE ADD more SANITY
PgConf US 2015 - ALTER DATABASE ADD more SANITYOleksii Kliukin
 
Handling Database Deployments
Handling Database DeploymentsHandling Database Deployments
Handling Database DeploymentsMike Willbanks
 
Database automated build and test - SQL In The City Cambridge
Database automated build and test - SQL In The City CambridgeDatabase automated build and test - SQL In The City Cambridge
Database automated build and test - SQL In The City CambridgeRed Gate Software
 
OpenWhisk Under the Hood -- London Oct 16 2016
OpenWhisk Under the Hood -- London Oct 16 2016OpenWhisk Under the Hood -- London Oct 16 2016
OpenWhisk Under the Hood -- London Oct 16 2016Stephen Fink
 
Agile Database Modeling with Grails - Preview of GORM 1.4 - SF Grails Meetup ...
Agile Database Modeling with Grails - Preview of GORM 1.4 - SF Grails Meetup ...Agile Database Modeling with Grails - Preview of GORM 1.4 - SF Grails Meetup ...
Agile Database Modeling with Grails - Preview of GORM 1.4 - SF Grails Meetup ...Philip Stehlik
 
Continuous Deployment: The Dirty Details
Continuous Deployment: The Dirty DetailsContinuous Deployment: The Dirty Details
Continuous Deployment: The Dirty DetailsMike Brittain
 
SQL Server 2008 Integration Services
SQL Server 2008 Integration ServicesSQL Server 2008 Integration Services
SQL Server 2008 Integration ServicesEduardo Castro
 
vJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemvJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemAndres Almiray
 
Web Development Foundation & Team Collaboration
Web Development Foundation & Team CollaborationWeb Development Foundation & Team Collaboration
Web Development Foundation & Team CollaborationSupanat Potiwarakorn
 
Embracing Distributed Version Control
Embracing Distributed Version ControlEmbracing Distributed Version Control
Embracing Distributed Version ControlNowell Strite
 
sbt 0.10 for beginners?
sbt 0.10 for beginners?sbt 0.10 for beginners?
sbt 0.10 for beginners?k4200
 
Liquibase for java developers
Liquibase for java developersLiquibase for java developers
Liquibase for java developersIllia Seleznov
 
Version Control ThinkVitamin
Version Control ThinkVitaminVersion Control ThinkVitamin
Version Control ThinkVitaminAlex Hillman
 
Learn you some Ansible for great good!
Learn you some Ansible for great good!Learn you some Ansible for great good!
Learn you some Ansible for great good!David Lapsley
 
Evolutionary Database Design
Evolutionary Database DesignEvolutionary Database Design
Evolutionary Database DesignAndrei Solntsev
 

Semelhante a Sane SQL Change Management with Sqitch (20)

Simple SQL Change Management with Sqitch
Simple SQL Change Management with SqitchSimple SQL Change Management with Sqitch
Simple SQL Change Management with Sqitch
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own Domain
 
Deploying TYPO3 Neos websites using Surf
Deploying TYPO3 Neos websites using SurfDeploying TYPO3 Neos websites using Surf
Deploying TYPO3 Neos websites using Surf
 
Revoke-Obfuscation
Revoke-ObfuscationRevoke-Obfuscation
Revoke-Obfuscation
 
PgConf US 2015 - ALTER DATABASE ADD more SANITY
PgConf US 2015  - ALTER DATABASE ADD more SANITYPgConf US 2015  - ALTER DATABASE ADD more SANITY
PgConf US 2015 - ALTER DATABASE ADD more SANITY
 
Handling Database Deployments
Handling Database DeploymentsHandling Database Deployments
Handling Database Deployments
 
Database automated build and test - SQL In The City Cambridge
Database automated build and test - SQL In The City CambridgeDatabase automated build and test - SQL In The City Cambridge
Database automated build and test - SQL In The City Cambridge
 
Liquibase
LiquibaseLiquibase
Liquibase
 
OpenWhisk Under the Hood -- London Oct 16 2016
OpenWhisk Under the Hood -- London Oct 16 2016OpenWhisk Under the Hood -- London Oct 16 2016
OpenWhisk Under the Hood -- London Oct 16 2016
 
Agile Database Modeling with Grails - Preview of GORM 1.4 - SF Grails Meetup ...
Agile Database Modeling with Grails - Preview of GORM 1.4 - SF Grails Meetup ...Agile Database Modeling with Grails - Preview of GORM 1.4 - SF Grails Meetup ...
Agile Database Modeling with Grails - Preview of GORM 1.4 - SF Grails Meetup ...
 
Continuous Deployment: The Dirty Details
Continuous Deployment: The Dirty DetailsContinuous Deployment: The Dirty Details
Continuous Deployment: The Dirty Details
 
SQL Server 2008 Integration Services
SQL Server 2008 Integration ServicesSQL Server 2008 Integration Services
SQL Server 2008 Integration Services
 
vJUG - The JavaFX Ecosystem
vJUG - The JavaFX EcosystemvJUG - The JavaFX Ecosystem
vJUG - The JavaFX Ecosystem
 
Web Development Foundation & Team Collaboration
Web Development Foundation & Team CollaborationWeb Development Foundation & Team Collaboration
Web Development Foundation & Team Collaboration
 
Embracing Distributed Version Control
Embracing Distributed Version ControlEmbracing Distributed Version Control
Embracing Distributed Version Control
 
sbt 0.10 for beginners?
sbt 0.10 for beginners?sbt 0.10 for beginners?
sbt 0.10 for beginners?
 
Liquibase for java developers
Liquibase for java developersLiquibase for java developers
Liquibase for java developers
 
Version Control ThinkVitamin
Version Control ThinkVitaminVersion Control ThinkVitamin
Version Control ThinkVitamin
 
Learn you some Ansible for great good!
Learn you some Ansible for great good!Learn you some Ansible for great good!
Learn you some Ansible for great good!
 
Evolutionary Database Design
Evolutionary Database DesignEvolutionary Database Design
Evolutionary Database Design
 

Mais de David Wheeler

Building and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CBuilding and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CDavid Wheeler
 
Releasing PostgreSQL Extension on PGXN
Releasing PostgreSQL Extension on PGXNReleasing PostgreSQL Extension on PGXN
Releasing PostgreSQL Extension on PGXNDavid Wheeler
 
Building and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CBuilding and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CDavid Wheeler
 
Test Driven Database Development
Test Driven Database DevelopmentTest Driven Database Development
Test Driven Database DevelopmentDavid Wheeler
 
PgTAP Best Practices
PgTAP Best PracticesPgTAP Best Practices
PgTAP Best PracticesDavid Wheeler
 
Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your DatabaseDavid Wheeler
 

Mais de David Wheeler (6)

Building and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CBuilding and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning C
 
Releasing PostgreSQL Extension on PGXN
Releasing PostgreSQL Extension on PGXNReleasing PostgreSQL Extension on PGXN
Releasing PostgreSQL Extension on PGXN
 
Building and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning CBuilding and Distributing PostgreSQL Extensions Without Learning C
Building and Distributing PostgreSQL Extensions Without Learning C
 
Test Driven Database Development
Test Driven Database DevelopmentTest Driven Database Development
Test Driven Database Development
 
PgTAP Best Practices
PgTAP Best PracticesPgTAP Best Practices
PgTAP Best Practices
 
Unit Test Your Database
Unit Test Your DatabaseUnit Test Your Database
Unit Test Your Database
 

Último

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 

Último (20)

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 

Sane SQL Change Management with Sqitch

  • 1. Sane SQL Change Management with Sqitch David E. Wheeler http:/ /sqitch.org/ PDXPUG September 20, 2012 Text: Attribution-Noncommercial-Share Alike 3.0 United States: http://creativecommons.org/licenses/by-nc-sa/3.0/us/ Images licensed independently and © Their respective owners.
  • 2. Whats Wrong with Migrations?
  • 3. Whats Wrong with Migrations? Incomplete mini-language
  • 4. Whats Wrong with Migrations? Incomplete mini-language No logical replication integration
  • 5. Whats Wrong with Migrations? Incomplete mini-language No logical replication integration Numbered scripts hard to track
  • 6. Whats Wrong with Migrations? Incomplete mini-language No logical replication integration Numbered scripts hard to track No VCS awareness
  • 7. What about SQL Migrations? Incomplete mini-language No logical replication integration Numbered scripts hard to track No VCS awareness
  • 8. What about SQL Migrations? ——————————————— Incomplete mini-language No logical replication integration Numbered scripts hard to track No VCS awareness
  • 9. What about SQL Migrations? ——————————————— Incomplete mini-language ——————————————————— No logical replication integration Numbered scripts hard to track No VCS awareness
  • 10. What about SQL Migrations? ——————————————— Incomplete mini-language ——————————————————— No logical replication integration Numbered scripts hard to track No VCS awareness Managing procedures is a PITA
  • 12. Imagine this Change >git diff diff --git a/deploy/recur.sql b/deploy/recur.sql index 622d52e..56e419e 100644 --- a/deploy/recur.sql +++ b/deploy/recur.sql @@ -22,7 +22,10 @@ recurrence <> 'none' OR ( recurrence = 'none' - AND starts_at BETWEEN range_start AND range_end + AND ( + starts_at BETWEEN range_start AND range_end + OR ends_at BETWEEN range_start AND range_end + ) ) ) LOOP
  • 13. Imagine this Change >git diff diff --git a/deploy/recur.sql b/deploy/recur.sql index 622d52e..56e419e 100644 --- a/deploy/recur.sql +++ b/deploy/recur.sql @@ -22,7 +22,10 @@ recurrence <> 'none' OR ( recurrence = 'none' - AND starts_at BETWEEN range_start AND range_end + AND ( + starts_at BETWEEN range_start AND range_end + OR ends_at BETWEEN range_start AND range_end + ) ) Simple, right? ) LOOP
  • 15. Not So Much Paste entire function to new “up” script
  • 16. Not So Much Paste entire function to new “up” script Edit the new file
  • 17. Not So Much Paste entire function to new “up” script Edit the new file Copy the function to the new “down” script
  • 18. Not So Much Paste entire function to new “up” script Edit the new file Copy the function to the new “down” script Three copies of the function!
  • 19. Not So Much Paste entire function to new “up” script Edit the new file Copy the function to the new “down” script Three copies of the function! No real source code management
  • 20. Not So Much Paste entire function to new “up” script Edit the new file Copy the function to the new “down” script Three copies of the function! No real source code management This sucks
  • 22. What about Liquibase? <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.6" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.6 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.6.xsd"> <changeSet id="1" author="me"> <createTable tableName="first_table"> <column name="id" type="int"> <constraints primaryKey="true" nullable="false"/> </column> <column name="name" type="varchar(50)"> <constraints nullable="false"/> </column> </createTable> <createTable tableName="new_table"> <column name="id" type="int"> <constraints primaryKey="true" nullable="false"/> </column> </createTable> </changeSet> </databaseChangeLog> filename
  • 23. What about Liquibase? <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.6" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.6 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.6.xsd"> <changeSet id="1" author="me"> <createTable tableName="first_table"> <column name="id" type="int"> <constraints primaryKey="true" nullable="false"/> </column> <column name="name" type="varchar(50)"> Whaaaa? <constraints nullable="false"/> </column> </createTable> <createTable tableName="new_table"> <column name="id" type="int"> <constraints primaryKey="true" nullable="false"/> </column> </createTable> </changeSet> </databaseChangeLog> filename
  • 24. What about Liquibase? <?xml version="1.0" encoding="UTF-8"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.6" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.6 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.6.xsd"> <changeSet id="1" author="me"> <createTable tableName="first_table"> <column name="id" type="int"> <constraints primaryKey="true" nullable="false"/> </column> <column name="name" type="varchar(50)"> Whaaaa? <constraints nullable="false"/> </column> </createTable> <createTable tableName="new_table"> <column name="id" type="int"> <constraints primaryKey="true" nullable="false"/> GTFO! </column> </createTable> </changeSet> </databaseChangeLog> filename
  • 26. depesz’s Versioning? https:/ /github.com/depesz/versioning
  • 27. depesz’s Versioning? https:/ /github.com/depesz/versioning Nice dependency specification
  • 28. depesz’s Versioning? https:/ /github.com/depesz/versioning Nice dependency specification Tight PostgreSQL integration
  • 29. depesz’s Versioning? https:/ /github.com/depesz/versioning Nice dependency specification Tight PostgreSQL integration No VCS integration
  • 30. depesz’s Versioning? https:/ /github.com/depesz/versioning Nice dependency specification Tight PostgreSQL integration No VCS integration No tools
  • 31. depesz’s Versioning? https:/ /github.com/depesz/versioning Nice dependency specification Tight PostgreSQL integration No VCS integration No tools Managing procedures still a PITA
  • 32.
  • 33. Introducing Sqitch
  • 41. Sqitch Philosophy No opinions Native scripting Dependency resolution
  • 42. Sqitch Philosophy No opinions Native scripting Dependency resolution No numbering
  • 43. Sqitch Philosophy No opinions Native scripting Dependency resolution No numbering Distribution bundling
  • 44. Sqitch Philosophy No opinions Native scripting Dependency resolution No numbering Distribution bundling VCS integration
  • 48. Sqitch Philosophy Reduced duplication Built-in configuration Deployment planning
  • 49. Sqitch Philosophy Reduced duplication Built-in configuration Deployment planning Git-style interface
  • 50. Sqitch Philosophy Reduced duplication Built-in configuration Deployment planning Git-style interface Deployment tagging
  • 56. Sqitch Terminology change add tag state plan
  • 57. Sqitch Terminology change add tag deploy state plan
  • 58. Sqitch Terminology change add tag deploy state revert plan
  • 59. Sqitch Terminology change add tag deploy state revert plan committer
  • 61. How it Works >mkdir flipr > cd flipr > git init . Initialized empty Git repository in /flipr/.git/ > touch README.md > git add . > git commit -am 'Fist post!' >
  • 62. How it Works >mkdir flipr > cd flipr > git init . Initialized empty Git repository in /flipr/.git/ > touch README.md > git add . > git commit -am 'Fist post!' >sqitch --engine pg init flipr --uri https://github Created sqitch.conf Created sqitch.plan Created deploy/ Created revert/ Created test/ >
  • 63. How it Works >mkdir flipr > cd flipr > git init . Initialized empty Git repository in /flipr/.git/ > touch README.md > git add . > git commit -am 'Fist post!' >sqitch --engine pg init flipr --uri https://github Created sqitch.conf Created sqitch.plan Created deploy/ Created revert/ Created test/ >
  • 64. How it Works >mkdir flipr > cd flipr > git init . Initialized empty Git repository in /flipr/.git/ > touch README.md > git add . > git commit -am 'Fist post!' >sqitch --engine pg init flipr --uri https://github Created sqitch.conf Created sqitch.plan Created deploy/ Created revert/ Created test/ >emacs sqitch.conf
  • 65. sqitch.conf [core] engine = pg # plan_file = sqitch.plan # top_dir = . # deploy_dir = deploy # revert_dir = revert # test_dir = test # extension = sql # [core "pg"] # db_name = # client = /usr/local/pgsql/bin/psql # sqitch_schema = sqitch # password = # port = # host = # username = sqitch.conf
  • 66. sqitch.conf [core] engine = pg --engine pg # plan_file = sqitch.plan # top_dir = . # deploy_dir = deploy # revert_dir = revert # test_dir = test # extension = sql # [core "pg"] # db_name = # client = /usr/local/pgsql/bin/psql # sqitch_schema = sqitch # password = # port = # host = # username = sqitch.conf
  • 68. Add User Config >sqitch config --user core.pg.client /usr/local/pgsql/bin/psql >
  • 69. Add User Config >sqitch config --user core.pg.client /usr/local/pgsql/bin/psql >
  • 70. Add User Config >sqitch config --user core.pg.client /usr/local/pgsql/bin/psql >sqitch config --user user.name 'Marge N. O’Vera' >
  • 71. Add User Config >sqitch config --user core.pg.client /usr/local/pgsql/bin/psql >sqitch config --user user.name 'Marge N. O’Vera' >sqitch config --user user.email 'marge@example.com' >
  • 72. Add User Config >sqitch config --user core.pg.client /usr/local/pgsql/bin/psql >sqitch config --user user.name 'Marge N. O’Vera' >sqitch config --user user.email 'marge@example.com' >emacs ~/.sqitch/sqitch.conf
  • 73. ~/ .sqitch/sqitch.conf [core "pg"] client = /usr/local/pgsql/bin/psql [user] name = Marge N. O’Vera email = marge@example.com ~/.sqitch/sqitc
  • 74. ~/ .sqitch/sqitch.conf [core "pg"] client = /usr/local/pgsql/bin/psql [user] name = Marge N. O’Vera email = marge@example.com Good for all projects ~/.sqitch/sqitc
  • 76. What’s the Plan Man? >emacs sqitch.plan
  • 80. Make It So > git add . > git commit -am 'Initialize Sqitch configuration.' [master bd7e3f0] Initialize Sqitch configuration. 2 files changed, 20 insertions(+) create mode 100644 sqitch.conf create mode 100644 sqitch.plan >
  • 82. First Deployment > sqitch add appschema -n 'Adds flipr app schema.' Created deploy/appschema.sql Created revert/appschema.sql Created test/appschema.sql Added "appschema" to sqitch.plan >
  • 83. First Deployment > sqitch add appschema -n 'Adds flipr app schema.' Created deploy/appschema.sql Created revert/appschema.sql Created test/appschema.sql Added "appschema" to sqitch.plan >
  • 84. First Deployment > sqitch add appschema -n 'Adds flipr app schema.' Created deploy/appschema.sql Created revert/appschema.sql Created test/appschema.sql Added "appschema" to sqitch.plan >
  • 85. First Deployment > sqitch add appschema -n 'Adds flipr app schema.' Created deploy/appschema.sql Created revert/appschema.sql Created test/appschema.sql Added "appschema" to sqitch.plan >emacs deploy/appschema.sql
  • 86. deploy/appschema.sql -- Deploy appschema BEGIN; -- XXX Add DDLs here. COMMIT; deploy/ appschem
  • 87. deploy/appschema.sql -- Deploy appschema BEGIN; CREATE SCHEMA flipr; COMMIT; deploy/ appschem
  • 88. First Deployment > sqitch add appschema -n 'Adds flipr app schema.' Created deploy/appschema.sql Created revert/appschema.sql Created test/appschema.sql Added "appschema" to sqitch.plan > emacs deploy/appschema.sql >
  • 89. First Deployment > sqitch add appschema -n 'Adds flipr app schema.' Created deploy/appschema.sql Created revert/appschema.sql Created test/appschema.sql Added "appschema" to sqitch.plan > emacs deploy/appschema.sql >emacs revert/appschema.sql
  • 90. revert/appschema.sql -- Revert appschema BEGIN; -- XXX Add DDLs here. COMMIT; revert/appschem
  • 91. revert/appschema.sql -- Revert appschema BEGIN; DROP SCHEMA flipr; COMMIT; revert/appschem
  • 93. Make it So! >createdb flipr_test > sqitch --db-name flipr_test deploy Adding metadata tables to flipr_test Deploying to flipr_test + appschema >
  • 94. Make it So! >createdb flipr_test > sqitch --db-name flipr_test deploy Adding metadata tables to flipr_test Deploying to flipr_test + appschema >
  • 95. Make it So! >createdb flipr_test > sqitch --db-name flipr_test deploy Adding metadata tables to flipr_test Deploying to flipr_test + appschema >
  • 96. Make it So! >createdb flipr_test > sqitch --db-name flipr_test deploy Adding metadata tables to flipr_test Deploying to flipr_test + appschema >
  • 97. Make it So! >createdb flipr_test > sqitch --db-name flipr_test deploy Adding metadata tables to flipr_test Deploying to flipr_test + appschema > psql -d flipr_test -c 'dn flipr' List of schemas Name | Owner -------+------- flipr | marge >
  • 99. How’s it Look? > sqitch -d flipr_test status # On database flipr_test # Project: flipr # Change: 9b24259744da156552479197872adba6a01a1ace # Name: appschema # Deployed: 2012-08-16 18:52:40 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 100. How’s it Look? > sqitch -d flipr_test status # On database flipr_test # Project: flipr # Change: 9b24259744da156552479197872adba6a01a1ace # Name: appschema # Deployed: 2012-08-16 18:52:40 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 101. How’s it Look? > sqitch -d flipr_test status # On database flipr_test # Project: flipr # Change: 9b24259744da156552479197872adba6a01a1ace # Name: appschema # Deployed: 2012-08-16 18:52:40 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 102. How’s it Look? > sqitch -d flipr_test status # On database flipr_test # Project: flipr # Change: 9b24259744da156552479197872adba6a01a1ace # Name: appschema # Deployed: 2012-08-16 18:52:40 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 103. How’s it Look? > sqitch -d flipr_test status # On database flipr_test # Project: flipr # Change: 9b24259744da156552479197872adba6a01a1ace # Name: appschema # Deployed: 2012-08-16 18:52:40 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 104. How’s it Look? > sqitch -d flipr_test status # On database flipr_test # Project: flipr # Change: 9b24259744da156552479197872adba6a01a1ace # Name: appschema # Deployed: 2012-08-16 18:52:40 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 106. Go Back > sqitch --db-name flipr_test revert Reverting all changes from flipr_test - appschema >
  • 107. Go Back > sqitch --db-name flipr_test revert Reverting all changes from flipr_test - appschema >
  • 108. Go Back > sqitch --db-name flipr_test revert Reverting all changes from flipr_test - appschema >
  • 109. Go Back > sqitch --db-name flipr_test revert Reverting all changes from flipr_test - appschema >psql -d flipr_test -c 'dn flipr' List of roles List of schemas Name | Owner ------+-------
  • 111. What’s The Status? > sqitch -d flipr_test status # On database flipr_test No changes deployed >
  • 112. What’s The Status? > sqitch -d flipr_test status # On database flipr_test No changes deployed >
  • 114. History > sqitch -d flipr_test log On database flipr_test Revert 9b24259744da156552479197872adba6a01a1ace Name: appschema Committer: Marge N. O’Vera <marge@example.com> Date: 2012-08-16 18:54:55 -0700 App schema for all flipr objects. Deploy 9b24259744da156552479197872adba6a01a1ace Name: appschema Committer: Marge N. O’Vera <marge@example.com> Date: 2012-08-16 18:52:40 -0700 App schema for all flipr objects.
  • 115. History > sqitch -d flipr_test log On database flipr_test Revert 9b24259744da156552479197872adba6a01a1ace Name: appschema Committer: Marge N. O’Vera <marge@example.com> Date: 2012-08-16 18:54:55 -0700 App schema for all flipr objects. Deploy 9b24259744da156552479197872adba6a01a1ace Name: appschema Committer: Marge N. O’Vera <marge@example.com> Date: 2012-08-16 18:52:40 -0700 App schema for all flipr objects.
  • 116. History > sqitch -d flipr_test log On database flipr_test Revert 9b24259744da156552479197872adba6a01a1ace Name: appschema Committer: Marge N. O’Vera <marge@example.com> Date: 2012-08-16 18:54:55 -0700 App schema for all flipr objects. Deploy 9b24259744da156552479197872adba6a01a1ace Name: appschema Committer: Marge N. O’Vera <marge@example.com> Date: 2012-08-16 18:52:40 -0700 App schema for all flipr objects.
  • 118. Commit It! > git add . > git commit -m 'Add flipr schema.' [master 0fcb493] Add flipr schema. 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 deploy/appschema.sql create mode 100644 revert/appschema.sql create mode 100644 test/appschema.sql >
  • 119. Commit It! > git add . > git commit -m 'Add flipr schema.' [master 0fcb493] Add flipr schema. 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 deploy/appschema.sql create mode 100644 revert/appschema.sql create mode 100644 test/appschema.sql >sqitch --db-name flipr_test deploy Deploying changes to flipr_test + appschema >
  • 120. Commit It! > git add . > git commit -m 'Add flipr schema.' [master 0fcb493] Add flipr schema. 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 deploy/appschema.sql create mode 100644 revert/appschema.sql create mode 100644 test/appschema.sql >sqitch --db-name flipr_test deploy Deploying changes to flipr_test + appschema >
  • 121. Commit It! > git add . > git commit -m 'Add flipr schema.' [master 0fcb493] Add flipr schema. 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 deploy/appschema.sql create mode 100644 revert/appschema.sql create mode 100644 test/appschema.sql >sqitch --db-name flipr_test deploy Deploying changes to flipr_test + appschema >psql -d flipr_test -c 'dn flipr' List of schemas Name | Owner -------+------- flipr | marge
  • 123. Status Update > sqitch -d flipr_test status # On database flipr_test # Project: flipr # Change: 9b24259744da156552479197872adba6a01a1ace # Name: appschema # Deployed: 2012-08-16 18:57:03 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 125. Save My Fingers >sqitch config core.pg.db_name flipr_test >
  • 126. Save My Fingers >sqitch config core.pg.db_name flipr_test >sqitch status # On database flipr_test # Project: flipr No --db-name # Change: 9b24259744da156552479197872adba6a01a1ace # Name: appschema # Deployed: 2012-08-16 18:57:03 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 128. Dependencies! > sqitch add users --requires appschema -n 'Creates table to track our users.' Created deploy/users.sql Created revert/users.sql Created test/users.sql Added "users [appschema]" to sqitch.plan >
  • 129. Dependencies! > sqitch add users --requires appschema -n 'Creates table to track our users.' Created deploy/users.sql Created revert/users.sql Created test/users.sql Added "users [appschema]" to sqitch.plan >
  • 130. Dependencies! > sqitch add users --requires appschema -n 'Creates table to track our users.' Created deploy/users.sql Created revert/users.sql Created test/users.sql Added "users [appschema]" to sqitch.plan >emacs deploy/users.sql
  • 131. deploy/users.sql -- Deploy users -- requires: appschema BEGIN; -- XXX Add DDLs here. COMMIT; deploy/users.sq
  • 132. deploy/users.sql -- Deploy users -- requires: appschema BEGIN; -- XXX Add DDLs here. COMMIT; deploy/users.sq
  • 133. deploy/users.sql -- Deploy users -- requires: appschema BEGIN; CREATE TABLE flipr.users ( nickname TEXT PRIMARY KEY, password TEXT NOT NULL, timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW() ); COMMIT; deploy/users.sq
  • 134. Dependencies! > sqitch add users --requires appschema -n 'Creates table to track our users.' Created deploy/users.sql Created revert/users.sql Created test/users.sql Added "users [appschema]" to sqitch.plan > emacs deploy/users.sql >
  • 135. Dependencies! > sqitch add users --requires appschema -n 'Creates table to track our users.' Created deploy/users.sql Created revert/users.sql Created test/users.sql Added "users [appschema]" to sqitch.plan > emacs deploy/users.sql >emacs revert/users.sql
  • 136. revert/users.sql -- Revert users BEGIN; -- XXX Add DDLs here. COMMIT; revert/users.sq
  • 137. revert/users.sql -- Revert users BEGIN; DROP TABLE flipr.users; COMMIT; revert/users.sq
  • 139. Make Users >sqitch deploy Deploying changes to flipr_test + users >
  • 140. Make Users >sqitch deploy Deploying changes to flipr_test + users >
  • 141. Make Users >sqitch deploy Deploying changes to flipr_test + users >psql -d flipr_test -c 'd flipr.users' Table "flipr.users" Column | Type | Modifiers -----------+-------------+------------------------ nickname | text | not null password | text | not null timestamp | timestamptz | not null default now() Indexes: "users_pkey" PRIMARY KEY, btree (nickname) >
  • 143. Status Update > sqitch status # On database flipr_test # Project: flipr # Change: 0521530ed75365d16163e3b46d292c2a29e13dfa # Name: users # Deployed: 2012-08-16 19:01:06 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 144. Status Update > sqitch status # On database flipr_test # Project: flipr # Change: 0521530ed75365d16163e3b46d292c2a29e13dfa # Name: users # Deployed: 2012-08-16 19:01:06 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 145. Status Update > sqitch status # On database flipr_test # Project: flipr # Change: 0521530ed75365d16163e3b46d292c2a29e13dfa # Name: users # Deployed: 2012-08-16 19:01:06 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >sqitch revert --to @LAST^ Reverting changes to appschema from flipr_test - users >
  • 146. Status Update > sqitch status # On database flipr_test # Project: flipr # Change: 0521530ed75365d16163e3b46d292c2a29e13dfa # Name: users # Deployed: 2012-08-16 19:01:06 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >sqitch revert --to @LAST^ Reverting changes to appschema from flipr_test - users >
  • 148. Symbolic Tags @LAST Last deployed change
  • 149. Symbolic Tags @LAST Last deployed change @FIRST First deployed change
  • 150. Symbolic Tags @LAST Last deployed change @FIRST First deployed change @HEAD Last change in the plan
  • 151. Symbolic Tags @LAST Last deployed change @FIRST First deployed change @HEAD Last change in the plan @ROOT First change in the plan
  • 152. Symbolic Tags @LAST Last deployed change @FIRST First deployed change @HEAD Last change in the plan @ROOT First change in the plan ^ Previous change
  • 153. Symbolic Tags @LAST Last deployed change @FIRST First deployed change @HEAD Last change in the plan @ROOT First change in the plan ^ Previous change ~ Following change
  • 155. Lose Users > psql -d flipr_test -c 'd flipr.users' Did not find any relation named "flipr.users". >
  • 156. Lose Users > psql -d flipr_test -c 'd flipr.users' Did not find any relation named "flipr.users". >git add . > git commit -am 'Add users table.' [master dfa6952] Add users table. 5 files changed, 30 insertions(+) create mode 100644 deploy/users.sql create mode 100644 revert/users.sql create mode 100644 test/users.sql >
  • 157. Lose Users > psql -d flipr_test -c 'd flipr.users' Did not find any relation named "flipr.users". >git add . > git commit -am 'Add users table.' [master dfa6952] Add users table. 5 files changed, 30 insertions(+) create mode 100644 deploy/users.sql create mode 100644 revert/users.sql create mode 100644 test/users.sql >sqitch deploy Deploying changes to flipr_test + users >
  • 159. Up to Date > sqitch status # On database flipr_test # Project: flipr # Change: 0521530ed75365d16163e3b46d292c2a29e13dfa # Name: users # Deployed: 2012-08-16 19:03:48 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 160. Up to Date > sqitch status # On database flipr_test # Project: flipr # Change: 0521530ed75365d16163e3b46d292c2a29e13dfa # Name: users # Deployed: 2012-08-16 19:03:48 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 161. Up to Date > sqitch status # On database flipr_test # Project: flipr # Change: 0521530ed75365d16163e3b46d292c2a29e13dfa # Name: users # Deployed: 2012-08-16 19:03:48 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 163. A Twofer > sqitch add insert_user -r users -r appschema -n 'Creates a function to insert a user.' Created deploy/insert_user.sql Created revert/insert_user.sql Created test/insert_user.sql Added "insert_user [users appschema]" to sqitch.plan >
  • 164. A Twofer > sqitch add insert_user -r users -r appschema -n 'Creates a function to insert a user.' Created deploy/insert_user.sql Created revert/insert_user.sql Created test/insert_user.sql Added "insert_user [users appschema]" to sqitch.plan >
  • 165. A Twofer > sqitch add insert_user -r users -r appschema -n 'Creates a function to insert a user.' Created deploy/insert_user.sql Created revert/insert_user.sql Created test/insert_user.sql Added "insert_user [users appschema]" to sqitch.plan >sqitch add change_pass -r users -r appschema -n 'Creates a function to change a user password.' Created deploy/change_pass.sql Created revert/change_pass.sql Created test/change_pass.sql Added "change_pass [users appschema]" to sqitch.plan >
  • 166. A Twofer > sqitch add insert_user -r users -r appschema -n 'Creates a function to insert a user.' Created deploy/insert_user.sql Created revert/insert_user.sql Created test/insert_user.sql Added "insert_user [users appschema]" to sqitch.plan >sqitch add change_pass -r users -r appschema -n 'Creates a function to change a user password.' Created deploy/change_pass.sql Created revert/change_pass.sql Created test/change_pass.sql Added "change_pass [users appschema]" to sqitch.plan >
  • 167. A Twofer > sqitch add insert_user -r users -r appschema -n 'Creates a function to insert a user.' Created deploy/insert_user.sql Created revert/insert_user.sql Created test/insert_user.sql Added "insert_user [users appschema]" to sqitch.plan >sqitch add change_pass -r users -r appschema -n 'Creates a function to change a user password.' Created deploy/change_pass.sql Created revert/change_pass.sql Created test/change_pass.sql Added "change_pass [users appschema]" to sqitch.plan >emacs sqitch.plan
  • 168. sqitch.plan %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. sqitch.plan
  • 169. sqitch.plan %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. sqitch.plan
  • 170. sqitch.plan %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. sqitch.plan
  • 171. sqitch.plan %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. sqitch.plan
  • 172. sqitch.plan %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. sqitch.plan
  • 173. sqitch.plan %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. sqitch.plan
  • 174. sqitch.plan %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. sqitch.plan
  • 175. sqitch.plan %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. sqitch.plan
  • 177. A Twofer >emacs sqitch.plan > emacs deploy/insert_user.sql
  • 178. deploy/insert_user.sql -- Deploy insert_user -- requires: appuser -- requires: users BEGIN; -- XXX Add DDLs here. COMMIT; deploy/insert_u
  • 179. deploy/insert_user.sql -- Deploy insert_user -- requires: appuser -- requires: users BEGIN; -- XXX Add DDLs here. COMMIT; deploy/insert_u
  • 180. deploy/insert_user.sql -- Deploy insert_user -- requires: appuser -- requires: users BEGIN; CREATE OR REPLACE FUNCTION flipr.insert_user( nickname TEXT, password TEXT ) RETURNS VOID LANGUAGE SQL SECURITY DEFINER AS $$ INSERT INTO users VALUES($1, md5($2)); $$; COMMIT; deploy/insert_u
  • 181. A Twofer >emacs sqitch.plan > emacs deploy/insert_user.sql >
  • 182. A Twofer >emacs sqitch.plan > emacs deploy/insert_user.sql >emacs deploy/change_pass.sql
  • 183. deploy/change_pass.sql -- Deploy change_pass -- :requires: appuser -- :requires: users BEGIN; -- XXX Add DDLs here. COMMIT; deploy/change_u
  • 184. deploy/change_pass.sql -- Deploy change_pass -- :requires: appuser -- :requires: users BEGIN; CREATE OR REPLACE FUNCTION flipr.change_pass( nick TEXT, oldpass TEXT, newpass TEXT ) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER AS $$ BEGIN UPDATE users SET password = md5($3) WHERE nickname = $1 AND password = md5($2); RETURN FOUND; END; $$; COMMIT; deploy/change_u
  • 186. Deploy Functions > sqitch deploy Deploying changes to flipr_test + insert_user + change_pass >
  • 187. Deploy Functions > sqitch deploy Deploying changes to flipr_test + insert_user + change_pass > psql -d flipr_test -c 'df flipr.*' List of function Schema | Name | Result data type | --------+-------------+------------------+---------- flipr | change_pass | boolean | nick text flipr | insert_user | void | nickname >
  • 188. Deploy Functions > sqitch deploy Deploying changes to flipr_test + insert_user + change_pass > psql -d flipr_test -c 'df flipr.*' List of function Schema | Name | Result data type | --------+-------------+------------------+---------- flipr | change_pass | boolean | nick text flipr | insert_user | void | nickname >
  • 190. Status Update > sqitch status # On database flipr_test # Project: flipr # Change: 99408db589f6031b6e851bce17aec7f870ed11e6 # Name: change_pass # Deployed: 2012-08-16 19:10:58 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date) >
  • 192. Revert > sqitch revert --to @LAST^^ Reverting changes to users from flipr_test - change_pass - insert_user >
  • 193. Revert > sqitch revert --to @LAST^^ Reverting changes to users from flipr_test - change_pass - insert_user >
  • 194. Revert > sqitch revert --to @LAST^^ Reverting changes to users from flipr_test - change_pass - insert_user >psql -d flipr_test -c 'df flipr.*' List of functions Schema | Name | Result data type | Argument data ty --------+------+------------------+----------------- >
  • 196. Commit It git add && git commit
  • 197. Commit It git add && git commit sqitch deploy
  • 198. Commit It git add && git commit sqitch deploy And now…
  • 199. Commit It git add && git commit sqitch deploy And now… Tag
  • 200. Commit It git add && git commit sqitch deploy And now… Tag Bundle
  • 201. Commit It git add && git commit sqitch deploy And now… Tag Bundle Ship!
  • 203. Tag It! > sqitch tag v1.0.0-dev1 -n 'Tag v1.0.0-dev1.' Tagged "change_pass" with @v1.0.0-dev1 >
  • 204. Tag It! > sqitch tag v1.0.0-dev1 -n 'Tag v1.0.0-dev1.' Tagged "change_pass" with @v1.0.0-dev1 >
  • 205. Tag It! > sqitch tag v1.0.0-dev1 -n 'Tag v1.0.0-dev1.' Tagged "change_pass" with @v1.0.0-dev1 >git commit -am 'Tag the database with v1.0.0-dev1.' [master 067ef73] Tag the database with v1.0.0-dev1. 1 file changed, 1 insertion(+) >
  • 206. Tag It! > sqitch tag v1.0.0-dev1 -n 'Tag v1.0.0-dev1.' Tagged "change_pass" with @v1.0.0-dev1 >git commit -am 'Tag the database with v1.0.0-dev1.' [master 067ef73] Tag the database with v1.0.0-dev1. 1 file changed, 1 insertion(+) >git tag v1.0.0-dev1 -am 'Tag v1.0.0-dev1' >
  • 208. Bundle It! > sqitch bundle Bundling into bundle/ Writing config Writing plan Writing scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 >
  • 209. Bundle It! > sqitch bundle Bundling into bundle/ Writing config Writing plan Writing scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 >
  • 210. Test and Ship It! >
  • 211. Test and Ship It! >cd bundle >
  • 212. Test and Ship It! >cd bundle >createdb flipr_stage >
  • 213. Test and Ship It! >cd bundle >createdb flipr_stage >sqitch --db-name flipr_stage deploy Adding metadata tables to flipr_stage Deploying changes to flipr_stage + appschema + users + insert_user + change_pass @v1.0.0-dev1 >
  • 214. Test and Ship It! >cd bundle >createdb flipr_stage >sqitch --db-name flipr_stage deploy Adding metadata tables to flipr_stage Deploying changes to flipr_stage + appschema + users + insert_user + change_pass @v1.0.0-dev1 > cd .. > mv bundle flipr-1.0.0-dev1 > tar -czf flipr-1.0.0-dev1.tar.gz flipr-1.0.0-dev1 >
  • 217. Ruh-Roh >psql -d flipr_test -c " SELECT insert_user('foo', 'secr3t'), insert_user('bar', 'secr3t'); SELECT nickname, password FROM users; " nickname | password ----------+---------------------------------- foo | 9695da4dd567a19f9b92065f240c6725 bar | 9695da4dd567a19f9b92065f240c6725
  • 218. Ruh-Roh >psql -d flipr_test -c " SELECT insert_user('foo', 'secr3t'), insert_user('bar', 'secr3t'); SELECT nickname, password FROM users; " nickname | password ----------+---------------------------------- foo | 9695da4dd567a19f9b92065f240c6725 bar | 9695da4dd567a19f9b92065f240c6725 Not good.
  • 220. Add pgcrypto >sqitch add pgcrypto -n 'Loads pgcrypto extension.' Adding deploy/pgcrypto.sql Adding revert/pgcrypto.sql Adding test/pgcrypto.sql Added "pgcrypto" to sqitch.plan >
  • 221. Add pgcrypto >sqitch add pgcrypto -n 'Loads pgcrypto extension.' Adding deploy/pgcrypto.sql Adding revert/pgcrypto.sql Adding test/pgcrypto.sql Added "pgcrypto" to sqitch.plan >emacs deploy/pgcrpyto.sql
  • 222. deploy/pgcrypto.sql -- Deploy pgcrypto BEGIN; -- XXX Add DDLs here. COMMIT; deploy/pgcrypto
  • 223. deploy/pgcrypto.sql -- Deploy pgcrypto BEGIN; CREATE EXTENSION pgcrypto; COMMIT; deploy/pgcrypto
  • 225. How to Modify? Copy insert_user.sql to new deploy file
  • 226. How to Modify? Copy insert_user.sql to new deploy file Change that new file
  • 227. How to Modify? Copy insert_user.sql to new deploy file Change that new file Copy insert_user.sql to new revert file
  • 228. How to Modify? Copy insert_user.sql to new deploy file Change that new file Copy insert_user.sql to new revert file Test it
  • 229. How to Modify? Copy insert_user.sql to new deploy file Change that new file Copy insert_user.sql to new revert file Test it Do the same for change_pass.sql
  • 230. How to Modify? Copy insert_user.sql to new deploy file Change that new file Copy insert_user.sql to new revert file Test it Do the same for change_pass.sql The problem with that…
  • 231. >
  • 232. > git diff HEAD^ diff --git a/deploy/insert_user_crypt.sql b/deploy/insert_user_crypto.sql new file mode 100644 index 0000000..fa8d0c6 --- /dev/null +++ b/deploy/insert_user_crypt.sql @@ -0,0 +1,8 @@ +-- requires: users, appuser, pgcrypto + +CREATE OR REPLACE FUNCTION insert_user( + nickname TEXT, + password TEXT +) RETURNS VOID LANGUAGE SQL AS $$ + INSERT INTO users values($1, crypt($2, gen_salt('md5'))); +$$; diff --git a/revert/insert_user_crypt.sql b/revert/insert_user_crypto.sql new file mode 100644 index 0000000..a7f4e31 --- /dev/null +++ b/revert/insert_user_crypt.sql @@ -0,0 +1,8 @@ +-- requires: users, appuser + +CREATE OR REPLACE FUNCTION insert_user( + nickname TEXT, + password TEXT +) RETURNS VOID LANGUAGE SQL AS $$ + INSERT INTO users values($1, md5($2)); +$$;
  • 233. > git diff HEAD^ diff --git a/deploy/insert_user_crypt.sql b/deploy/insert_user_crypto.sql new file mode 100644 index 0000000..fa8d0c6 --- /dev/null +++ b/deploy/insert_user_crypt.sql @@ -0,0 +1,8 @@ +-- requires: users, appuser, pgcrypto + +CREATE OR REPLACE FUNCTION insert_user( + nickname TEXT, + password TEXT +) RETURNS VOID LANGUAGE SQL AS $$ + INSERT INTO users values($1, crypt($2, gen_salt('md5'))); +$$; diff --git a/revert/insert_user_crypt.sql b/revert/insert_user_crypto.sql new file mode 100644 index 0000000..a7f4e31 --- /dev/null +++ b/revert/insert_user_crypt.sql @@ -0,0 +1,8 @@ +-- requires: users, appuser + +CREATE OR REPLACE FUNCTION insert_user( + nickname TEXT, + password TEXT +) RETURNS VOID LANGUAGE SQL AS $$ + INSERT INTO users values($1, md5($2)); +$$; Oy.
  • 234. Let Sqitch do the work.
  • 236. Rework It >sqitch rework insert_user -r pgcrypto -n 'Changes insert_user to use pgcrypto.' Added "insert_user [insert_user@v1.0.0-dev1 pgcrypto]" to sqitch.plan. Modify these files as appropriate: * deploy/insert_user.sql * revert/insert_user.sql * test/insert_user.sql >
  • 237. Rework It >sqitch rework insert_user -r pgcrypto -n 'Changes insert_user to use pgcrypto.' Added "insert_user [insert_user@v1.0.0-dev1 pgcrypto]" to sqitch.plan. Modify these files as appropriate: * deploy/insert_user.sql * revert/insert_user.sql * test/insert_user.sql >
  • 238. Rework It >sqitch rework insert_user -r pgcrypto -n 'Changes insert_user to use pgcrypto.' Added "insert_user [insert_user@v1.0.0-dev1 pgcrypto]" to sqitch.plan. Modify these files as appropriate: * deploy/insert_user.sql * revert/insert_user.sql * test/insert_user.sql >
  • 239. Rework It >sqitch rework insert_user -r pgcrypto -n 'Changes insert_user to use pgcrypto.' Added "insert_user [insert_user@v1.0.0-dev1 pgcrypto]" to sqitch.plan. Modify these files as appropriate: * deploy/insert_user.sql * revert/insert_user.sql * test/insert_user.sql > Same files?
  • 241. Same Files? >git status # On branch master # Your branch and 'origin/master' have diverged, # and have 13 and 14 different commits each, respectively. # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working direct # # modified: revert/insert_user.sql # modified: sqitch.plan # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # deploy/insert_user@v1.0.0-dev1.sql # revert/insert_user@v1.0.0-dev1.sql # test/insert_user@v1.0.0-dev1.sql no changes added to commit (use "git add" and/or "git commit -a")
  • 242. Same Files? >git status # On branch master # Your branch and 'origin/master' have diverged, # and have 13 and 14 different commits each, respectively. # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working direct # # modified: revert/insert_user.sql # modified: sqitch.plan # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # deploy/insert_user@v1.0.0-dev1.sql # revert/insert_user@v1.0.0-dev1.sql # test/insert_user@v1.0.0-dev1.sql no changes added to commit (use "git add" and/or "git commit -a")
  • 243. Same Files? >git status # On branch master # Your branch and 'origin/master' have diverged, # and have 13 and 14 different commits each, respectively. # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working direct # # modified: revert/insert_user.sql # modified: sqitch.plan # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # deploy/insert_user@v1.0.0-dev1.sql # revert/insert_user@v1.0.0-dev1.sql As of # test/insert_user@v1.0.0-dev1.sql @v1.0.0-dev1 no changes added to commit (use "git add" and/or "git commit -a")
  • 244. Same Files? >git status # On branch master # Your branch and 'origin/master' have diverged, # and have 13 and 14 different commits each, respectively. # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working direct # # modified: revert/insert_user.sql # modified: sqitch.plan # # Untracked files: # (use "git add <file>..." to include in what will be committed) # # deploy/insert_user@v1.0.0-dev1.sql # revert/insert_user@v1.0.0-dev1.sql # test/insert_user@v1.0.0-dev1.sql no changes added to commit (use "git add" and/or "git commit -a")
  • 245. Same Files? >git status # On branch master # Your branch and 'origin/master' have diverged, # and have 13 and 14 different commits each, respectively. # # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working direct # # modified: revert/insert_user.sql # modified: sqitch.plan Previous deploy # # Untracked files: becomes revert # (use "git add <file>..." to include in what will be committed) # # deploy/insert_user@v1.0.0-dev1.sql # revert/insert_user@v1.0.0-dev1.sql # test/insert_user@v1.0.0-dev1.sql no changes added to commit (use "git add" and/or "git commit -a")
  • 247. What’s the Diff? >diff -u deploy/insert_user.sql @@ -1,6 +1,7 @@ -- Deploy insert_user -- requires: users -- requires: appschema +-- requires: pgcrypto BEGIN; @@ -8,7 +9,7 @@ CREATE OR REPLACE FUNCTION flipr.insert_user( nickname TEXT, password TEXT ) RETURNS VOID LANGUAGE SQL SECURITY DEFINER AS $$ - INSERT INTO flipr.users VALUES($1, md5($2)); + INSERT INTO flipr.users values($1, crypt($2, gen_salt('md5'))); $$; COMMIT;
  • 249. Rework change_pass >sqitch rework change_pass -r pgcrypto -n 'Change change_pass to use pgcrypto.' Added "change_pass [change_pass@v1.0.0-dev1 pgcrypto]" to sqitch.plan. Modify these files as appropriate: * deploy/change_pass.sql * revert/change_pass.sql * test/change_pass.sql >
  • 250. Rework change_pass >sqitch rework change_pass -r pgcrypto -n 'Change change_pass to use pgcrypto.' Added "change_pass [change_pass@v1.0.0-dev1 pgcrypto]" to sqitch.plan. Modify these files as appropriate: * deploy/change_pass.sql * revert/change_pass.sql * test/change_pass.sql >
  • 251. Rework change_pass >sqitch rework change_pass -r pgcrypto -n 'Change change_pass to use pgcrypto.' Added "change_pass [change_pass@v1.0.0-dev1 pgcrypto]" to sqitch.plan. Modify these files as appropriate: * deploy/change_pass.sql * revert/change_pass.sql * test/change_pass.sql >
  • 252. Rework change_pass >sqitch rework change_pass -r pgcrypto -n 'Change change_pass to use pgcrypto.' Added "change_pass [change_pass@v1.0.0-dev1 pgcrypto]" to sqitch.plan. Modify these files as appropriate: * deploy/change_pass.sql * revert/change_pass.sql * test/change_pass.sql > Same files?
  • 254. What’s the Diff? >diff -u deploy/change_pass.sql @@ -1,6 +1,7 @@ -- Deploy change_pass -- requires: users -- requires: appschema +-- requires: pgcrypto BEGIN; @@ -11,9 +12,9 @@ CREATE OR REPLACE FUNCTION flipr.change_pass( ) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER AS $$ BEGIN UPDATE flipr.users - SET password = md5($3) + SET password = crypt($3, gen_salt('md5')) WHERE nickname = $1 - AND password = md5($2); + AND password = crypt($2, password); RETURN FOUND; END; $$;
  • 256. Send it Up! > sqitch deploy Deploying changes to flipr_test + insert_user + change_pass >
  • 257. Send it Up! > sqitch deploy Deploying changes to flipr_test + insert_user + change_pass >psql -d flipr_test -c " DELETE FROM users; SELECT insert_user('foo', 'secr3t'), insert_user('bar', 'secr3t'); SELECT nickname, password FROM users; " nickname | password ----------+------------------------------------ foo | $1$l6OEKyF3$kv5ae7505ROub75d9QKTh/ bar | $1$J4NJDgaJ$578i9Lt6b8ohJwi6WhNNO1 >
  • 258. Send it Up! > sqitch deploy Deploying changes to flipr_test + insert_user + change_pass >psql -d flipr_test -c " o/ DELETE FROM users; SELECT insert_user('foo', 'secr3t'), insert_user('bar', 'secr3t'); SELECT nickname, password FROM users; " nickname | password ----------+------------------------------------ foo | $1$l6OEKyF3$kv5ae7505ROub75d9QKTh/ bar | $1$J4NJDgaJ$578i9Lt6b8ohJwi6WhNNO1 >
  • 259. Can We Go Back? >
  • 260. Can We Go Back? > sqitch revert --to @LAST^^ Reverting changes to pgcrypto from flipr_test - change_pass - insert_user >
  • 261. Can We Go Back? > sqitch revert --to @LAST^^ Reverting changes to pgcrypto from flipr_test - change_pass - insert_user >psql -d flipr_test -c " DELETE FROM users; SELECT insert_user('foo', 'secr3t'), insert_user('bar', 'secr3t'); SELECT nickname, password FROM users; " nickname | password ----------+---------------------------------- foo | 9695da4dd567a19f9b92065f240c6725 bar | 9695da4dd567a19f9b92065f240c6725 >
  • 263. What About Bundling? > sqitch tag v1.0.0-b1 -n 'Tag v1.0.0-b1.' > git tag v1.0.0-b1 -am 'Tag v1.0.0-b1' > sqitch bundle Bundling into bundle Writing config Writing plan Writing scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 + pgcrypto + insert_user + change_pass @v1.0.0-b1 >
  • 264. What About Bundling? > sqitch tag v1.0.0-b1 -n 'Tag v1.0.0-b1.' > git tag v1.0.0-b1 -am 'Tag v1.0.0-b1' > sqitch bundle Bundling into bundle Writing config Writing plan Writing scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 + pgcrypto + insert_user + change_pass @v1.0.0-b1 >
  • 265. What About Bundling? > sqitch tag v1.0.0-b1 -n 'Tag v1.0.0-b1.' > git tag v1.0.0-b1 -am 'Tag v1.0.0-b1' > sqitch bundle Bundling into bundle Writing config Writing plan Writing scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 + pgcrypto + insert_user + change_pass @v1.0.0-b1 >
  • 266. What About Bundling? > sqitch tag v1.0.0-b1 -n 'Tag v1.0.0-b1.' > git tag v1.0.0-b1 -am 'Tag v1.0.0-b1' > sqitch bundle Bundling into bundle Writing config Writing plan Writing scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 + pgcrypto + insert_user + change_pass @v1.0.0-b1 >emacs bundle/sqitch.plan
  • 267. What’s the Plan? %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. @v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1. pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads the pgcrypto extension. insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N. O’Vera <marge@example.com> # Change insert_user to use pgcrypto. change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N. O’Vera <marge@example.com> # Change change_pass to use pgcrypto. @v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag bundle/sqitch.p
  • 268. What’s the Plan? %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. @v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1. pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads the pgcrypto extension. insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N. O’Vera <marge@example.com> # Change insert_user to use pgcrypto. change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N. O’Vera <marge@example.com> # Change change_pass to use pgcrypto. @v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag bundle/sqitch.p
  • 269. What’s the Plan? %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. @v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1. pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads the pgcrypto extension. insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N. O’Vera <marge@example.com> # Change insert_user to use pgcrypto. change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N. O’Vera <marge@example.com> # Change change_pass to use pgcrypto. @v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag bundle/sqitch.p
  • 270. What’s the Plan? %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. @v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1. pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads the pgcrypto extension. insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N. O’Vera <marge@example.com> # Change insert_user to use pgcrypto. change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N. O’Vera <marge@example.com> # Change change_pass to use pgcrypto. @v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag bundle/sqitch.p
  • 271. What’s the Plan? %syntax-version=1.0.0-b2 %project=flipr %uri=https://github.com/theory/sqitch-intro/ appschema 2012-08-17T01:49:33Z Marge N. O’Vera <marge@example.com> # App schema for all flipr objects. users [appschema] 2012-08-17T01:58:43Z Marge N. O’Vera <marge@example.com> # Creates table to track our users. insert_user [users appschema] 2012-08-17T02:07:53Z Marge N. O’Vera <marge@example.com> # Creates a function to insert a user. change_pass [users appschema] 2012-08-17T02:08:10Z Marge N. O’Vera <marge@example.com> # Creates a function to change a user password. @v1.0.0-dev1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag v1.0.0-dev1. pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loads the pgcrypto extension. insert_user [insert_user@v1.0.0-dev1 pgcrypto] 2012-08-17T23:24:34Z Marge N. O’Vera <marge@example.com> # Change insert_user to use pgcrypto. change_pass [change_pass@v1.0.0-dev1 pgcrypto] 2012-08-17T23:26:47Z Marge N. O’Vera <marge@example.com> # Change change_pass to use pgcrypto. @v1.0.0-b1 2012-08-17T05:24:20Z Marge N. O’Vera <marge@example.com> # Tag bundle/sqitch.p
  • 273. Make it So >cd bundle >
  • 274. Make it So >cd bundle >sqitch --db-name flipr_stage deploy Deploying changes to flipr_stage + pgcrypto + insert_user + change_pass @v1.0.0-b1 >
  • 275. Make it So >cd bundle >sqitch --db-name flipr_stage deploy Deploying changes to flipr_stage + pgcrypto + insert_user + change_pass @v1.0.0-b1 >sqitch --db-name flipr_stage status # On database flipr_stage # Project: flipr # Change: d0eb9c5ff822877696e834d686a4d9ee8a5cd2a9 # Name: change_pass # Tag: @v1.0.0-b1 # Deployed: 2012-08-17 13:42:09 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date)
  • 276. Make it So >cd bundle >sqitch --db-name flipr_stage deploy Deploying changes to flipr_stage + pgcrypto + insert_user + change_pass @v1.0.0-b1 >sqitch --db-name flipr_stage status # On database flipr_stage # Project: flipr # Change: d0eb9c5ff822877696e834d686a4d9ee8a5cd2a9 # Name: change_pass # Tag: @v1.0.0-b1 # Deployed: 2012-08-17 13:42:09 -0700 # By: Marge N. O’Vera <marge@example.com> # Nothing to deploy (up-to-date)
  • 280. Other Commands help - Get it log - Like git log
  • 281. Other Commands help - Get it log - Like git log check - Validate plan & database
  • 282. Other Commands help - Get it log - Like git log check - Validate plan & database test - Test deployment success
  • 285. Current Status Adding locale support Porting to SQLite
  • 286. Current Status Adding locale support Porting to SQLite Adding VCS/SCM integration
  • 287. Current Status Adding locale support Porting to SQLite Adding VCS/SCM integration Sync tags
  • 288. Current Status Adding locale support Porting to SQLite Adding VCS/SCM integration Sync tags Fetch reworked files from history
  • 290. Fork It http:/ /sqitch.org/
  • 291. Fork It http:/ /sqitch.org/ https:/ /github.com/theory/sqitch/
  • 292. Fork It http:/ /sqitch.org/ https:/ /github.com/theory/sqitch/ Opinions wanted
  • 293. Fork It http:/ /sqitch.org/ https:/ /github.com/theory/sqitch/ Opinions wanted Coders wanted
  • 294. Fork It http:/ /sqitch.org/ https:/ /github.com/theory/sqitch/ Opinions wanted Coders wanted Doc writers and web designers wanted!
  • 295. Fork It http:/ /sqitch.org/ https:/ /github.com/theory/sqitch/ Opinions wanted Coders wanted Doc writers and web designers wanted! Make it great!
  • 297. Sane SQL Change Management with Sqitch David E. Wheeler http:/ /sqitch.org/ PDXPUG September 20, 2012 Text: Attribution-Noncommercial-Share Alike 3.0 United States: http://creativecommons.org/licenses/by-nc-sa/3.0/us/ Images licensed independently and © Their respective owners.

Notas do Editor

  1. TODO:\n&amp;#x2022; Add more privilege stuff?\n&amp;#x2022; Add example of renaming `flips.timestamp`?\n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. \n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n
  175. \n
  176. \n
  177. \n
  178. \n
  179. \n
  180. \n
  181. \n
  182. \n
  183. \n
  184. \n
  185. \n
  186. \n
  187. \n
  188. \n
  189. \n
  190. \n
  191. \n
  192. \n
  193. \n
  194. \n
  195. \n
  196. \n
  197. \n
  198. \n
  199. \n
  200. \n
  201. \n
  202. \n
  203. \n
  204. \n
  205. \n
  206. \n
  207. \n
  208. \n
  209. \n
  210. \n
  211. \n
  212. \n
  213. \n
  214. \n
  215. \n
  216. \n
  217. \n
  218. \n
  219. \n
  220. \n
  221. \n
  222. \n
  223. \n
  224. \n
  225. \n
  226. \n
  227. \n
  228. \n
  229. \n
  230. \n
  231. \n
  232. \n
  233. \n
  234. \n
  235. \n
  236. \n
  237. \n
  238. \n
  239. \n
  240. \n
  241. \n
  242. \n
  243. \n
  244. \n
  245. \n
  246. \n
  247. \n
  248. \n
  249. \n
  250. \n
  251. \n
  252. \n
  253. \n
  254. \n
  255. \n
  256. \n
  257. \n
  258. \n
  259. \n
  260. \n
  261. \n
  262. \n
  263. \n
  264. \n
  265. \n
  266. \n
  267. \n
  268. \n
  269. \n
  270. \n
  271. \n
  272. \n
  273. \n
  274. \n
  275. \n
  276. \n
  277. \n
  278. \n
  279. \n
  280. \n
  281. \n
  282. \n
  283. \n
  284. \n
  285. \n
  286. \n
  287. \n
  288. \n
  289. \n
  290. \n
  291. \n
  292. \n
  293. \n
  294. \n
  295. \n
  296. \n
  297. \n
  298. \n
  299. \n
  300. \n
  301. \n
  302. \n
  303. \n
  304. \n
  305. \n
  306. \n
  307. \n
  308. \n
  309. \n
  310. \n
  311. \n
  312. \n
  313. \n
  314. \n
  315. \n
  316. \n
  317. \n
  318. \n
  319. \n
  320. \n
  321. \n
  322. \n
  323. \n
  324. \n
  325. \n
  326. \n
  327. \n
  328. \n
  329. \n
  330. \n
  331. \n
  332. \n
  333. \n
  334. \n
  335. \n
  336. \n
  337. \n
  338. \n
  339. \n
  340. \n
  341. \n
  342. \n
  343. \n
  344. \n
  345. \n
  346. \n
  347. \n
  348. \n
  349. \n
  350. \n
  351. \n
  352. \n
  353. \n
  354. \n
  355. \n
  356. TODO:\n&amp;#x2022; Add more privilege stuff?\n&amp;#x2022; Add example of renaming `flips.timestamp`?\n