Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Sane SQL Change Management with Sqitch

7,059 views

Published on

Published in: Technology
  • Be the first to comment

Sane SQL Change Management with Sqitch

  1. 1. Sane SQL Change Management with Sqitch David E. Wheeler http:/ /sqitch.org/ PDXPUG September 20, 2012Text: 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. 2. Whats Wrong with Migrations?
  3. 3. Whats Wrong with Migrations?Incomplete mini-language
  4. 4. Whats Wrong with Migrations?Incomplete mini-languageNo logical replication integration
  5. 5. Whats Wrong with Migrations?Incomplete mini-languageNo logical replication integrationNumbered scripts hard to track
  6. 6. Whats Wrong with Migrations?Incomplete mini-languageNo logical replication integrationNumbered scripts hard to trackNo VCS awareness
  7. 7. What about SQL Migrations?Incomplete mini-languageNo logical replication integrationNumbered scripts hard to trackNo VCS awareness
  8. 8. What about SQL Migrations?———————————————Incomplete mini-languageNo logical replication integrationNumbered scripts hard to trackNo VCS awareness
  9. 9. What about SQL Migrations?———————————————Incomplete mini-language———————————————————No logical replication integrationNumbered scripts hard to trackNo VCS awareness
  10. 10. What about SQL Migrations?———————————————Incomplete mini-language———————————————————No logical replication integrationNumbered scripts hard to trackNo VCS awarenessManaging procedures is a PITA
  11. 11. Imagine this Change>
  12. 12. Imagine this Change>git diffdiff --git a/deploy/recur.sql b/deploy/recur.sqlindex 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. 13. Imagine this Change>git diffdiff --git a/deploy/recur.sql b/deploy/recur.sqlindex 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
  14. 14. Not So Much
  15. 15. Not So MuchPaste entire function to new “up” script
  16. 16. Not So MuchPaste entire function to new “up” scriptEdit the new file
  17. 17. Not So MuchPaste entire function to new “up” scriptEdit the new fileCopy the function to the new “down” script
  18. 18. Not So MuchPaste entire function to new “up” scriptEdit the new fileCopy the function to the new “down” scriptThree copies of the function!
  19. 19. Not So MuchPaste entire function to new “up” scriptEdit the new fileCopy the function to the new “down” scriptThree copies of the function!No real source code management
  20. 20. Not So MuchPaste entire function to new “up” scriptEdit the new fileCopy the function to the new “down” scriptThree copies of the function!No real source code managementThis sucks
  21. 21. What about Liquibase?filename
  22. 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. 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. 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
  25. 25. depesz’s Versioning?
  26. 26. depesz’s Versioning?https:/ /github.com/depesz/versioning
  27. 27. depesz’s Versioning?https:/ /github.com/depesz/versioningNice dependency specification
  28. 28. depesz’s Versioning?https:/ /github.com/depesz/versioningNice dependency specificationTight PostgreSQL integration
  29. 29. depesz’s Versioning?https:/ /github.com/depesz/versioningNice dependency specificationTight PostgreSQL integrationNo VCS integration
  30. 30. depesz’s Versioning?https:/ /github.com/depesz/versioningNice dependency specificationTight PostgreSQL integrationNo VCS integrationNo tools
  31. 31. depesz’s Versioning?https:/ /github.com/depesz/versioningNice dependency specificationTight PostgreSQL integrationNo VCS integrationNo toolsManaging procedures still a PITA
  32. 32. Introducing Sqitch
  33. 33. Sq—what?sql ch anges
  34. 34. Sq—what?sq ch
  35. 35. Sq—what?sqitch
  36. 36. Sq—what?sqitchThere is no “u”
  37. 37. Sqitch Philosophy
  38. 38. Sqitch PhilosophyNo opinions
  39. 39. Sqitch PhilosophyNo opinionsNative scripting
  40. 40. Sqitch PhilosophyNo opinionsNative scriptingDependency resolution
  41. 41. Sqitch PhilosophyNo opinionsNative scriptingDependency resolutionNo numbering
  42. 42. Sqitch PhilosophyNo opinionsNative scriptingDependency resolutionNo numberingDistribution bundling
  43. 43. Sqitch PhilosophyNo opinionsNative scriptingDependency resolutionNo numberingDistribution bundlingVCS integration
  44. 44. Sqitch Philosophy
  45. 45. Sqitch PhilosophyReduced duplication
  46. 46. Sqitch PhilosophyReduced duplicationBuilt-in configuration
  47. 47. Sqitch PhilosophyReduced duplicationBuilt-in configurationDeployment planning
  48. 48. Sqitch PhilosophyReduced duplicationBuilt-in configurationDeployment planningGit-style interface
  49. 49. Sqitch PhilosophyReduced duplicationBuilt-in configurationDeployment planningGit-style interfaceDeployment tagging
  50. 50. Sqitch Terminology
  51. 51. Sqitch Terminologychange
  52. 52. Sqitch Terminologychangetag
  53. 53. Sqitch Terminologychangetagstate
  54. 54. Sqitch Terminologychangetagstateplan
  55. 55. Sqitch Terminologychange addtagstateplan
  56. 56. Sqitch Terminologychange addtag deploystateplan
  57. 57. Sqitch Terminologychange addtag deploystate revertplan
  58. 58. Sqitch Terminologychange addtag deploystate revertplan committer
  59. 59. How it Works>
  60. 60. 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!>
  61. 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!>sqitch --engine pg init flipr --uri https://githubCreated sqitch.confCreated sqitch.planCreated deploy/Created revert/Created test/>
  62. 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://githubCreated sqitch.confCreated sqitch.planCreated deploy/Created revert/Created test/>
  63. 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://githubCreated sqitch.confCreated sqitch.planCreated deploy/Created revert/Created test/>emacs sqitch.conf
  64. 64. 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
  65. 65. 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
  66. 66. Add User Config>
  67. 67. Add User Config>sqitch config --user core.pg.client /usr/local/pgsql/bin/psql>
  68. 68. Add User Config>sqitch config --user core.pg.client /usr/local/pgsql/bin/psql>
  69. 69. Add User Config>sqitch config --user core.pg.client /usr/local/pgsql/bin/psql>sqitch config --user user.name Marge N. O’Vera>
  70. 70. 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>
  71. 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>emacs ~/.sqitch/sqitch.conf
  72. 72. ~/ .sqitch/sqitch.conf[core "pg"] client = /usr/local/pgsql/bin/psql[user] name = Marge N. O’Vera email = marge@example.com ~/.sqitch/sqitc
  73. 73. ~/ .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
  74. 74. What’s the Plan Man?>
  75. 75. What’s the Plan Man?>emacs sqitch.plan
  76. 76. sqitch.plan%syntax-version=1.0.0-b1%project=flipr%uri=https://github.com/theory/sqitch-intro/ sqitch.plan
  77. 77. sqitch.plan%syntax-version=1.0.0-b1%project=flipr%uri=https://github.com/theory/sqitch-intro/ Identified sqitch.plan
  78. 78. Make It So>
  79. 79. 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>
  80. 80. First Deployment>
  81. 81. First Deployment> sqitch add appschema -n Adds flipr app schema.Created deploy/appschema.sqlCreated revert/appschema.sqlCreated test/appschema.sqlAdded "appschema" to sqitch.plan>
  82. 82. First Deployment> sqitch add appschema -n Adds flipr app schema.Created deploy/appschema.sqlCreated revert/appschema.sqlCreated test/appschema.sqlAdded "appschema" to sqitch.plan>
  83. 83. First Deployment> sqitch add appschema -n Adds flipr app schema.Created deploy/appschema.sqlCreated revert/appschema.sqlCreated test/appschema.sqlAdded "appschema" to sqitch.plan>
  84. 84. First Deployment> sqitch add appschema -n Adds flipr app schema.Created deploy/appschema.sqlCreated revert/appschema.sqlCreated test/appschema.sqlAdded "appschema" to sqitch.plan>emacs deploy/appschema.sql
  85. 85. deploy/appschema.sql-- Deploy appschemaBEGIN;-- XXX Add DDLs here.COMMIT; deploy/ appschem
  86. 86. deploy/appschema.sql-- Deploy appschemaBEGIN;CREATE SCHEMA flipr;COMMIT; deploy/ appschem
  87. 87. First Deployment> sqitch add appschema -n Adds flipr app schema.Created deploy/appschema.sqlCreated revert/appschema.sqlCreated test/appschema.sqlAdded "appschema" to sqitch.plan> emacs deploy/appschema.sql>
  88. 88. First Deployment> sqitch add appschema -n Adds flipr app schema.Created deploy/appschema.sqlCreated revert/appschema.sqlCreated test/appschema.sqlAdded "appschema" to sqitch.plan> emacs deploy/appschema.sql>emacs revert/appschema.sql
  89. 89. revert/appschema.sql-- Revert appschemaBEGIN;-- XXX Add DDLs here.COMMIT; revert/appschem
  90. 90. revert/appschema.sql-- Revert appschemaBEGIN;DROP SCHEMA flipr;COMMIT; revert/appschem
  91. 91. Make it So!>
  92. 92. Make it So!>createdb flipr_test> sqitch --db-name flipr_test deployAdding metadata tables to flipr_testDeploying to flipr_test + appschema>
  93. 93. Make it So!>createdb flipr_test> sqitch --db-name flipr_test deployAdding metadata tables to flipr_testDeploying to flipr_test + appschema>
  94. 94. Make it So!>createdb flipr_test> sqitch --db-name flipr_test deployAdding metadata tables to flipr_testDeploying to flipr_test + appschema>
  95. 95. Make it So!>createdb flipr_test> sqitch --db-name flipr_test deployAdding metadata tables to flipr_testDeploying to flipr_test + appschema>
  96. 96. Make it So!>createdb flipr_test> sqitch --db-name flipr_test deployAdding metadata tables to flipr_testDeploying to flipr_test + appschema> psql -d flipr_test -c dn fliprList of schemas Name | Owner-------+------- flipr | marge>
  97. 97. How’s it Look?>
  98. 98. 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)>
  99. 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. 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. 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. 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. 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. 104. Go Back>
  105. 105. Go Back> sqitch --db-name flipr_test revertReverting all changes from flipr_test - appschema>
  106. 106. Go Back> sqitch --db-name flipr_test revertReverting all changes from flipr_test - appschema>
  107. 107. Go Back> sqitch --db-name flipr_test revertReverting all changes from flipr_test - appschema>
  108. 108. Go Back> sqitch --db-name flipr_test revertReverting all changes from flipr_test - appschema>psql -d flipr_test -c dn flipr List of rolesList of schemas Name | Owner------+-------
  109. 109. What’s The Status?>
  110. 110. What’s The Status?> sqitch -d flipr_test status# On database flipr_testNo changes deployed>
  111. 111. What’s The Status?> sqitch -d flipr_test status# On database flipr_testNo changes deployed>
  112. 112. History>
  113. 113. History> sqitch -d flipr_test logOn database flipr_testRevert 9b24259744da156552479197872adba6a01a1aceName: appschemaCommitter: Marge N. O’Vera <marge@example.com>Date: 2012-08-16 18:54:55 -0700 App schema for all flipr objects.Deploy 9b24259744da156552479197872adba6a01a1aceName: appschemaCommitter: Marge N. O’Vera <marge@example.com>Date: 2012-08-16 18:52:40 -0700 App schema for all flipr objects.
  114. 114. History> sqitch -d flipr_test logOn database flipr_testRevert 9b24259744da156552479197872adba6a01a1aceName: appschemaCommitter: Marge N. O’Vera <marge@example.com>Date: 2012-08-16 18:54:55 -0700 App schema for all flipr objects.Deploy 9b24259744da156552479197872adba6a01a1aceName: appschemaCommitter: Marge N. O’Vera <marge@example.com>Date: 2012-08-16 18:52:40 -0700 App schema for all flipr objects.
  115. 115. History> sqitch -d flipr_test logOn database flipr_testRevert 9b24259744da156552479197872adba6a01a1aceName: appschemaCommitter: Marge N. O’Vera <marge@example.com>Date: 2012-08-16 18:54:55 -0700 App schema for all flipr objects.Deploy 9b24259744da156552479197872adba6a01a1aceName: appschemaCommitter: Marge N. O’Vera <marge@example.com>Date: 2012-08-16 18:52:40 -0700 App schema for all flipr objects.
  116. 116. Commit It!>
  117. 117. 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>
  118. 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>sqitch --db-name flipr_test deployDeploying changes to flipr_test + appschema>
  119. 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 deployDeploying changes to flipr_test + appschema>
  120. 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 deployDeploying changes to flipr_test + appschema>psql -d flipr_test -c dn fliprList of schemas Name | Owner-------+------- flipr | marge
  121. 121. Status Update>
  122. 122. 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)>
  123. 123. Save My Fingers>
  124. 124. Save My Fingers>sqitch config core.pg.db_name flipr_test>
  125. 125. 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)>
  126. 126. Dependencies!>
  127. 127. Dependencies!> sqitch add users --requires appschema -n Creates table to track our users.Created deploy/users.sqlCreated revert/users.sqlCreated test/users.sqlAdded "users [appschema]" to sqitch.plan>
  128. 128. Dependencies!> sqitch add users --requires appschema -n Creates table to track our users.Created deploy/users.sqlCreated revert/users.sqlCreated test/users.sqlAdded "users [appschema]" to sqitch.plan>
  129. 129. Dependencies!> sqitch add users --requires appschema -n Creates table to track our users.Created deploy/users.sqlCreated revert/users.sqlCreated test/users.sqlAdded "users [appschema]" to sqitch.plan>emacs deploy/users.sql
  130. 130. deploy/users.sql-- Deploy users-- requires: appschemaBEGIN;-- XXX Add DDLs here.COMMIT; deploy/users.sq
  131. 131. deploy/users.sql-- Deploy users-- requires: appschemaBEGIN;-- XXX Add DDLs here.COMMIT; deploy/users.sq
  132. 132. deploy/users.sql-- Deploy users-- requires: appschemaBEGIN;CREATE TABLE flipr.users ( nickname TEXT PRIMARY KEY, password TEXT NOT NULL, timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW());COMMIT; deploy/users.sq
  133. 133. Dependencies!> sqitch add users --requires appschema -n Creates table to track our users.Created deploy/users.sqlCreated revert/users.sqlCreated test/users.sqlAdded "users [appschema]" to sqitch.plan> emacs deploy/users.sql>
  134. 134. Dependencies!> sqitch add users --requires appschema -n Creates table to track our users.Created deploy/users.sqlCreated revert/users.sqlCreated test/users.sqlAdded "users [appschema]" to sqitch.plan> emacs deploy/users.sql>emacs revert/users.sql
  135. 135. revert/users.sql-- Revert usersBEGIN;-- XXX Add DDLs here.COMMIT; revert/users.sq
  136. 136. revert/users.sql-- Revert usersBEGIN;DROP TABLE flipr.users;COMMIT; revert/users.sq
  137. 137. Make Users>
  138. 138. Make Users>sqitch deployDeploying changes to flipr_test + users>
  139. 139. Make Users>sqitch deployDeploying changes to flipr_test + users>
  140. 140. Make Users>sqitch deployDeploying 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)>
  141. 141. Status Update>
  142. 142. 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)>
  143. 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. 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)>sqitch revert --to @LAST^Reverting changes to appschema from flipr_test - users>
  145. 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. 146. Symbolic Tags
  147. 147. Symbolic Tags@LAST Last deployed change
  148. 148. Symbolic Tags@LAST Last deployed change@FIRST First deployed change
  149. 149. Symbolic Tags@LAST Last deployed change@FIRST First deployed change@HEAD Last change in the plan
  150. 150. Symbolic Tags@LAST Last deployed change@FIRST First deployed change@HEAD Last change in the plan@ROOT First change in the plan
  151. 151. Symbolic Tags@LAST Last deployed change@FIRST First deployed change@HEAD Last change in the plan@ROOT First change in the plan^ Previous change
  152. 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~ Following change
  153. 153. Lose Users>
  154. 154. Lose Users> psql -d flipr_test -c d flipr.usersDid not find any relation named "flipr.users".>
  155. 155. Lose Users> psql -d flipr_test -c d flipr.usersDid 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>
  156. 156. Lose Users> psql -d flipr_test -c d flipr.usersDid 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 deployDeploying changes to flipr_test + users>
  157. 157. Up to Date>
  158. 158. 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)>
  159. 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. 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. 161. A Twofer>
  162. 162. A Twofer> sqitch add insert_user -r users -r appschema -n Creates a function to insert a user.Created deploy/insert_user.sqlCreated revert/insert_user.sqlCreated test/insert_user.sqlAdded "insert_user [users appschema]" to sqitch.plan>
  163. 163. A Twofer> sqitch add insert_user -r users -r appschema -n Creates a function to insert a user.Created deploy/insert_user.sqlCreated revert/insert_user.sqlCreated test/insert_user.sqlAdded "insert_user [users appschema]" to sqitch.plan>
  164. 164. A Twofer> sqitch add insert_user -r users -r appschema -n Creates a function to insert a user.Created deploy/insert_user.sqlCreated revert/insert_user.sqlCreated test/insert_user.sqlAdded "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.sqlCreated revert/change_pass.sqlCreated test/change_pass.sqlAdded "change_pass [users appschema]" to sqitch.plan>
  165. 165. A Twofer> sqitch add insert_user -r users -r appschema -n Creates a function to insert a user.Created deploy/insert_user.sqlCreated revert/insert_user.sqlCreated test/insert_user.sqlAdded "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.sqlCreated revert/change_pass.sqlCreated test/change_pass.sqlAdded "change_pass [users appschema]" to sqitch.plan>
  166. 166. A Twofer> sqitch add insert_user -r users -r appschema -n Creates a function to insert a user.Created deploy/insert_user.sqlCreated revert/insert_user.sqlCreated test/insert_user.sqlAdded "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.sqlCreated revert/change_pass.sqlCreated test/change_pass.sqlAdded "change_pass [users appschema]" to sqitch.plan>emacs sqitch.plan
  167. 167. 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
  168. 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. 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. 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. 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. 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. 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. 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. 175. A Twofer>
  176. 176. A Twofer>emacs sqitch.plan> emacs deploy/insert_user.sql
  177. 177. deploy/insert_user.sql-- Deploy insert_user-- requires: appuser-- requires: usersBEGIN;-- XXX Add DDLs here.COMMIT; deploy/insert_u
  178. 178. deploy/insert_user.sql-- Deploy insert_user-- requires: appuser-- requires: usersBEGIN;-- XXX Add DDLs here.COMMIT; deploy/insert_u
  179. 179. deploy/insert_user.sql-- Deploy insert_user-- requires: appuser-- requires: usersBEGIN;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
  180. 180. A Twofer>emacs sqitch.plan> emacs deploy/insert_user.sql>
  181. 181. A Twofer>emacs sqitch.plan> emacs deploy/insert_user.sql>emacs deploy/change_pass.sql
  182. 182. deploy/change_pass.sql-- Deploy change_pass-- :requires: appuser-- :requires: usersBEGIN;-- XXX Add DDLs here.COMMIT; deploy/change_u
  183. 183. deploy/change_pass.sql-- Deploy change_pass-- :requires: appuser-- :requires: usersBEGIN;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
  184. 184. Deploy Functions>
  185. 185. Deploy Functions> sqitch deployDeploying changes to flipr_test + insert_user + change_pass>
  186. 186. Deploy Functions> sqitch deployDeploying 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>
  187. 187. Deploy Functions> sqitch deployDeploying 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. 188. Status Update>
  189. 189. 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)>
  190. 190. Revert>
  191. 191. Revert> sqitch revert --to @LAST^^Reverting changes to users from flipr_test - change_pass - insert_user>
  192. 192. Revert> sqitch revert --to @LAST^^Reverting changes to users from flipr_test - change_pass - insert_user>
  193. 193. 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--------+------+------------------+----------------->
  194. 194. Commit It
  195. 195. Commit Itgit add && git commit
  196. 196. Commit Itgit add && git commitsqitch deploy
  197. 197. Commit Itgit add && git commitsqitch deployAnd now…
  198. 198. Commit Itgit add && git commitsqitch deployAnd now… Tag
  199. 199. Commit Itgit add && git commitsqitch deployAnd now… Tag Bundle
  200. 200. Commit Itgit add && git commitsqitch deployAnd now… Tag Bundle Ship!
  201. 201. Tag It!>
  202. 202. Tag It!> sqitch tag v1.0.0-dev1 -n Tag v1.0.0-dev1.Tagged "change_pass" with @v1.0.0-dev1>
  203. 203. Tag It!> sqitch tag v1.0.0-dev1 -n Tag v1.0.0-dev1.Tagged "change_pass" with @v1.0.0-dev1>
  204. 204. 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(+)>
  205. 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(+)>git tag v1.0.0-dev1 -am Tag v1.0.0-dev1>
  206. 206. Bundle It!>
  207. 207. Bundle It!> sqitch bundleBundling into bundle/Writing configWriting planWriting scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1>
  208. 208. Bundle It!> sqitch bundleBundling into bundle/Writing configWriting planWriting scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1>
  209. 209. Test and Ship It!>
  210. 210. Test and Ship It!>cd bundle>
  211. 211. Test and Ship It!>cd bundle>createdb flipr_stage>
  212. 212. Test and Ship It!>cd bundle>createdb flipr_stage>sqitch --db-name flipr_stage deployAdding metadata tables to flipr_stageDeploying changes to flipr_stage + appschema + users + insert_user + change_pass @v1.0.0-dev1>
  213. 213. Test and Ship It!>cd bundle>createdb flipr_stage>sqitch --db-name flipr_stage deployAdding metadata tables to flipr_stageDeploying 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>
  214. 214. Reworking Changes
  215. 215. Ruh-Roh>
  216. 216. 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
  217. 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 Not good.
  218. 218. Add pgcrypto>
  219. 219. Add pgcrypto>sqitch add pgcrypto -n Loads pgcrypto extension.Adding deploy/pgcrypto.sqlAdding revert/pgcrypto.sqlAdding test/pgcrypto.sqlAdded "pgcrypto" to sqitch.plan>
  220. 220. Add pgcrypto>sqitch add pgcrypto -n Loads pgcrypto extension.Adding deploy/pgcrypto.sqlAdding revert/pgcrypto.sqlAdding test/pgcrypto.sqlAdded "pgcrypto" to sqitch.plan>emacs deploy/pgcrpyto.sql
  221. 221. deploy/pgcrypto.sql-- Deploy pgcryptoBEGIN;-- XXX Add DDLs here.COMMIT; deploy/pgcrypto
  222. 222. deploy/pgcrypto.sql-- Deploy pgcryptoBEGIN;CREATE EXTENSION pgcrypto;COMMIT; deploy/pgcrypto
  223. 223. How to Modify?
  224. 224. How to Modify?Copy insert_user.sql to new deploy file
  225. 225. How to Modify?Copy insert_user.sql to new deploy fileChange that new file
  226. 226. How to Modify?Copy insert_user.sql to new deploy fileChange that new fileCopy insert_user.sql to new revert file
  227. 227. How to Modify?Copy insert_user.sql to new deploy fileChange that new fileCopy insert_user.sql to new revert fileTest it
  228. 228. How to Modify?Copy insert_user.sql to new deploy fileChange that new fileCopy insert_user.sql to new revert fileTest itDo the same for change_pass.sql
  229. 229. How to Modify?Copy insert_user.sql to new deploy fileChange that new fileCopy insert_user.sql to new revert fileTest itDo the same for change_pass.sqlThe problem with that…
  230. 230. >
  231. 231. > git diff HEAD^diff --git a/deploy/insert_user_crypt.sql b/deploy/insert_user_crypto.sqlnew file mode 100644index 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.sqlnew file mode 100644index 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));+$$;
  232. 232. > git diff HEAD^diff --git a/deploy/insert_user_crypt.sql b/deploy/insert_user_crypto.sqlnew file mode 100644index 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.sqlnew file mode 100644index 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.
  233. 233. Let Sqitch do the work.
  234. 234. Rework It>
  235. 235. 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>
  236. 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. 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. 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> Same files?
  239. 239. Same Files?>
  240. 240. 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.sqlno changes added to commit (use "git add" and/or "git commit -a")
  241. 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.sqlno changes added to commit (use "git add" and/or "git commit -a")
  242. 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 As of# test/insert_user@v1.0.0-dev1.sql @v1.0.0-dev1no changes added to commit (use "git add" and/or "git commit -a")
  243. 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# test/insert_user@v1.0.0-dev1.sqlno changes added to commit (use "git add" and/or "git commit -a")
  244. 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 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.sqlno changes added to commit (use "git add" and/or "git commit -a")
  245. 245. What’s the Diff?>
  246. 246. What’s the Diff?>diff -u deploy/insert_user.sql@@ -1,6 +1,7 @@ -- Deploy insert_user -- requires: users -- requires: appschema+-- requires: pgcryptoBEGIN;@@ -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;
  247. 247. Rework change_pass>
  248. 248. 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>
  249. 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. 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. 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> Same files?
  252. 252. What’s the Diff?>
  253. 253. What’s the Diff?>diff -u deploy/change_pass.sql@@ -1,6 +1,7 @@ -- Deploy change_pass -- requires: users -- requires: appschema+-- requires: pgcryptoBEGIN;@@ -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; $$;
  254. 254. Send it Up!>
  255. 255. Send it Up!> sqitch deployDeploying changes to flipr_test + insert_user + change_pass>
  256. 256. Send it Up!> sqitch deployDeploying 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>
  257. 257. Send it Up!> sqitch deployDeploying 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>
  258. 258. Can We Go Back?>
  259. 259. Can We Go Back?> sqitch revert --to @LAST^^Reverting changes to pgcrypto from flipr_test - change_pass - insert_user>
  260. 260. 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>
  261. 261. What About Bundling?>
  262. 262. 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 bundleBundling into bundleWriting configWriting planWriting scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 + pgcrypto + insert_user + change_pass @v1.0.0-b1>
  263. 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 bundleBundling into bundleWriting configWriting planWriting scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 + pgcrypto + insert_user + change_pass @v1.0.0-b1>
  264. 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 bundleBundling into bundleWriting configWriting planWriting scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 + pgcrypto + insert_user + change_pass @v1.0.0-b1>
  265. 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 bundleBundling into bundleWriting configWriting planWriting scripts + appschema + users + insert_user + change_pass @v1.0.0-dev1 + pgcrypto + insert_user + change_pass @v1.0.0-b1>emacs bundle/sqitch.plan
  266. 266. 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> # Appschema 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> # Tagv1.0.0-dev1.pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loadsthe 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
  267. 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> # Appschema 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> # Tagv1.0.0-dev1.pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loadsthe 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. 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> # Appschema 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> # Tagv1.0.0-dev1.pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loadsthe 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. 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> # Appschema 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> # Tagv1.0.0-dev1.pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loadsthe 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. 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> # Appschema 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> # Tagv1.0.0-dev1.pgcrypto 2012-08-17T23:22:54Z Marge N. O’Vera <marge@example.com> # Loadsthe 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. 271. Make it So>
  272. 272. Make it So>cd bundle>
  273. 273. Make it So>cd bundle>sqitch --db-name flipr_stage deployDeploying changes to flipr_stage + pgcrypto + insert_user + change_pass @v1.0.0-b1>
  274. 274. Make it So>cd bundle>sqitch --db-name flipr_stage deployDeploying 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)
  275. 275. Make it So>cd bundle>sqitch --db-name flipr_stage deployDeploying 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. 276. Ship It!
  277. 277. Other Commands
  278. 278. Other Commandshelp - Get it
  279. 279. Other Commandshelp - Get itlog - Like git log
  280. 280. Other Commandshelp - Get itlog - Like git logcheck - Validate plan & database
  281. 281. Other Commandshelp - Get itlog - Like git logcheck - Validate plan & databasetest - Test deployment success
  282. 282. Current Status
  283. 283. Current StatusAdding locale support
  284. 284. Current StatusAdding locale supportPorting to SQLite
  285. 285. Current StatusAdding locale supportPorting to SQLiteAdding VCS/SCM integration
  286. 286. Current StatusAdding locale supportPorting to SQLiteAdding VCS/SCM integration Sync tags
  287. 287. Current StatusAdding locale supportPorting to SQLiteAdding VCS/SCM integration Sync tags Fetch reworked files from history
  288. 288. Fork It
  289. 289. Fork Ithttp:/ /sqitch.org/
  290. 290. Fork Ithttp:/ /sqitch.org/https:/ /github.com/theory/sqitch/
  291. 291. Fork Ithttp:/ /sqitch.org/https:/ /github.com/theory/sqitch/Opinions wanted
  292. 292. Fork Ithttp:/ /sqitch.org/https:/ /github.com/theory/sqitch/Opinions wantedCoders wanted
  293. 293. Fork Ithttp:/ /sqitch.org/https:/ /github.com/theory/sqitch/Opinions wantedCoders wantedDoc writers and web designers wanted!
  294. 294. Fork Ithttp:/ /sqitch.org/https:/ /github.com/theory/sqitch/Opinions wantedCoders wantedDoc writers and web designers wanted!Make it great!
  295. 295. Thank you.
  296. 296. Sane SQL Change Management with Sqitch David E. Wheeler http:/ /sqitch.org/ PDXPUG September 20, 2012Text: 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.

×