Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Agile Database Development

Agile Database Development

Hi, I'm David. I like to write database apps. Just as much as I like to write web apps. (Maybe more!) How? Not by relying on bolted-on, half-baked database integration tools like migrations, I'll tell you that!. Instead, I make extensive use of best-of-breed tools for source control ([Git](http://git-scm.org/)), database unit testing ([pgTAP](http://pgtap.org/)), and database change management and deployment ([Sqitch](http://sqitch.org/). If you'd like to get as much pleasure out of database development as you do application development, join me for this tutorial. We'll develop a sample application using the processes and tools I've come to depend on, and you'll find out whether they might work for you. Either way, I promise it will at least be an amusing use of your time.

[Originally presented at PGCon 2013](http://www.pgcon.org/2013/schedule/events/615.en.html).

397f829eea921e02e35c37c22f9e6d3b?s=128

David E. Wheeler

May 22, 2013
Tweet

Transcript

  1. Agile Database Development David E. Wheeler PGCon 2013 Ottawa 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. iovation 1 Wednesday, May 22, 13
  2. Agile Database Development David E. Wheeler PGCon 2013 Ottawa 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. ✘ iovation 1 Wednesday, May 22, 13
  3. David E. Wheeler PGCon 2013 Ottawa 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. 1 Wednesday, May 22, 13
  4. David E. Wheeler PGCon 2013 Ottawa License: Attribution-Noncommercial-Share Alike 3.0

    United States: http:/ /creativecommons.org/licenses/by-nc-sa/3.0/us/ 2 Wednesday, May 22, 13
  5. Build My VC-Funded App for Me for Free David E.

    Wheeler PGCon 2013 Ottawa License: Attribution-Noncommercial-Share Alike 3.0 United States: http:/ /creativecommons.org/licenses/by-nc-sa/3.0/us/ ✔ CEO, Data Architect Agile Assholes, Inc. 2 Wednesday, May 22, 13
  6. This is Genius 3 Wednesday, May 22, 13

  7. This is Genius I had this idea 3 Wednesday, May

    22, 13
  8. This is Genius I had this idea Social networking is

    HAWT 3 Wednesday, May 22, 13
  9. This is Genius I had this idea Social networking is

    HAWT Has been for waaaay too long 3 Wednesday, May 22, 13
  10. This is Genius I had this idea Social networking is

    HAWT Has been for waaaay too long The backlash is long overdue 3 Wednesday, May 22, 13
  11. This is Genius I had this idea Social networking is

    HAWT Has been for waaaay too long The backlash is long overdue Getting ahead of the curve 3 Wednesday, May 22, 13
  12. This is Genius I had this idea Social networking is

    HAWT Has been for waaaay too long The backlash is long overdue Getting ahead of the curve Introducing… 3 Wednesday, May 22, 13
  13. http:/ /flic.kr/p/8j5gG8 © 2010 Strongrrl. All rights reserved. Used with

    permission. 4 Wednesday, May 22, 13
  14. antisocial network http:/ /flic.kr/p/8j5gG8 © 2010 Strongrrl. All rights reserved.

    Used with permission. 4 Wednesday, May 22, 13
  15. How it Works antisocial network 5 Wednesday, May 22, 13

  16. How it Works Microblogging platform antisocial network 5 Wednesday, May

    22, 13
  17. How it Works Microblogging platform Everyone follows you antisocial network

    5 Wednesday, May 22, 13
  18. How it Works Microblogging platform Everyone follows you New users

    follow everyone antisocial network 5 Wednesday, May 22, 13
  19. How it Works Microblogging platform Everyone follows you New users

    follow everyone Goal: Alienate your followers antisocial network 5 Wednesday, May 22, 13
  20. How it Works Microblogging platform Everyone follows you New users

    follow everyone Goal: Alienate your followers Get them to unfollow you antisocial network 5 Wednesday, May 22, 13
  21. How it Works Microblogging platform Everyone follows you New users

    follow everyone Goal: Alienate your followers Get them to unfollow you Leaderboard: Those with fewest followers antisocial network 5 Wednesday, May 22, 13
  22. Your Task antisocial network 6 Wednesday, May 22, 13

  23. Your Task Create the database antisocial network 6 Wednesday, May

    22, 13
  24. Your Task Create the database Use agile development to make

    it right antisocial network 6 Wednesday, May 22, 13
  25. Your Task Create the database Use agile development to make

    it right Contribute to VC-funded Corp antisocial network 6 Wednesday, May 22, 13
  26. Your Task Create the database Use agile development to make

    it right Contribute to VC-funded Corp Profit! antisocial network 6 Wednesday, May 22, 13
  27. Your Task Create the database Use agile development to make

    it right Contribute to VC-funded Corp Profit! For VC-funded Corp antisocial network 6 Wednesday, May 22, 13
  28. http:/ /flic.kr/p/2honiQ © 2007 James Duncan Davidson. All rights reserved.

    Used with permission. 7 Wednesday, May 22, 13
  29. antisocial network 8 Wednesday, May 22, 13

  30. Agile WTF? antisocial network 8 Wednesday, May 22, 13

  31. We’ll get there antisocial network 9 Wednesday, May 22, 13

  32. But first… antisocial network 10 Wednesday, May 22, 13

  33. NDA antisocial network 11 Wednesday, May 22, 13

  34. Okay, now that that’s out of the way… antisocial network

    12 Wednesday, May 22, 13
  35. Please organize into pairs antisocial network 13 Wednesday, May 22,

    13
  36. Yes, that’s right antisocial network 14 Wednesday, May 22, 13

  37. You’re gonna do pair database programming antisocial network 15 Wednesday,

    May 22, 13
  38. App developers partner with DBAs antisocial network 16 Wednesday, May

    22, 13
  39. I’m waiting… antisocial network 17 Wednesday, May 22, 13

  40. Job Requirements antisocial network 18 Wednesday, May 22, 13

  41. Job Requirements PostgreSQL http:/ /postgresql.org/download antisocial network 18 Wednesday, May

    22, 13
  42. Job Requirements PostgreSQL http:/ /postgresql.org/download Git http:/ /git-scm.com/ antisocial network

    18 Wednesday, May 22, 13
  43. Job Requirements PostgreSQL http:/ /postgresql.org/download Git http:/ /git-scm.com/ Sqitch http:/

    /sqitch.org/ antisocial network 18 Wednesday, May 22, 13
  44. Job Requirements PostgreSQL http:/ /postgresql.org/download Git http:/ /git-scm.com/ Sqitch http:/

    /sqitch.org/ pgTAP http:/ /pgtap.org/ antisocial network 18 Wednesday, May 22, 13
  45. Job Requirements PostgreSQL http:/ /postgresql.org/download Git http:/ /git-scm.com/ Sqitch http:/

    /sqitch.org/ pgTAP http:/ /pgtap.org/ pg_prove http:/ /metacpan.org/module/pg_prove antisocial network 18 Wednesday, May 22, 13
  46. We good? antisocial network 19 Wednesday, May 22, 13

  47. Let’s do this thang. antisocial network 20 Wednesday, May 22,

    13
  48. > Who Am I? 21 Wednesday, May 22, 13

  49. ""git"config"**global"user.name"'David"E."Wheeler' > > Who Am I? 21 Wednesday, May 22,

    13
  50. ""git"config"**global"user.name"'David"E."Wheeler' > > Who Am I? 21 Wednesday, May 22,

    13
  51. ""git"config"**global"user.name"'David"E."Wheeler' > ""git"config"**global"user.email"david@justatheory.com > > Who Am I? 21 Wednesday,

    May 22, 13
  52. ""git"config"**global"user.name"'David"E."Wheeler' > ""git"config"**global"user.email"david@justatheory.com > > Who Am I? 21 Wednesday,

    May 22, 13
  53. ""git"config"**global"user.name"'David"E."Wheeler' > ""git"config"**global"user.email"david@justatheory.com > > Who Am I? Please use

    your own name and email. 21 Wednesday, May 22, 13
  54. ""git"config"**global"user.name"'David"E."Wheeler' > ""git"config"**global"user.email"david@justatheory.com > > Who Am I? ""emacs"~/.gitconfig >

    21 Wednesday, May 22, 13
  55. ~/.gitconfig ~/ .gitconfig [user] "" name"="David"E."Wheeler """ email"="david@justatheory.com 22 Wednesday,

    May 22, 13
  56. ~/.gitconfig ~/ .gitconfig [user] "" name"="David"E."Wheeler """ email"="david@justatheory.com Good for

    all projects 22 Wednesday, May 22, 13
  57. Create a Remote 23 Wednesday, May 22, 13

  58. Create a Remote Create Git project on GitHub 23 Wednesday,

    May 22, 13
  59. Create a Remote Create Git project on GitHub Or BitBucket

    23 Wednesday, May 22, 13
  60. Create a Remote Create Git project on GitHub Or BitBucket

    Wherever you like 23 Wednesday, May 22, 13
  61. Create a Remote Create Git project on GitHub Or BitBucket

    Wherever you like Record remote URL 23 Wednesday, May 22, 13
  62. Create a Remote Create Git project on GitHub Or BitBucket

    Wherever you like Record remote URL 23 Wednesday, May 22, 13
  63. Or a Local Remote > 24 Wednesday, May 22, 13

  64. Or a Local Remote ""mkdir"flipr*remote >"cd"flipr*remote > > 24 Wednesday,

    May 22, 13
  65. Or a Local Remote ""mkdir"flipr*remote >"cd"flipr*remote > ""git"init"**bare Initialized"empty"Git"repository"in"flipr*remote/ >

    > 24 Wednesday, May 22, 13
  66. Or a Local Remote ""mkdir"flipr*remote >"cd"flipr*remote > ""git"init"**bare Initialized"empty"Git"repository"in"flipr*remote/ >

    > Remote URL is simply the path to this directory. 24 Wednesday, May 22, 13
  67. Or a Local Remote ""mkdir"flipr*remote >"cd"flipr*remote > ""git"init"**bare Initialized"empty"Git"repository"in"flipr*remote/ >

    > ""cd".. > 24 Wednesday, May 22, 13
  68. Gitiup > 25 Wednesday, May 22, 13

  69. ""mkdir"flipr*db >"cd"flipr*db >"git"init Initialized"empty"Git"repository"in"flipr*db/.git/ > Gitiup > 25 Wednesday, May

    22, 13
  70. ""mkdir"flipr*db >"cd"flipr*db >"git"init Initialized"empty"Git"repository"in"flipr*db/.git/ > Gitiup > 25 Wednesday, May

    22, 13
  71. ""mkdir"flipr*db >"cd"flipr*db >"git"init Initialized"empty"Git"repository"in"flipr*db/.git/ > Gitiup > ""echo"Flipr"Database"Project">"README.md > 25

    Wednesday, May 22, 13
  72. ""mkdir"flipr*db >"cd"flipr*db >"git"init Initialized"empty"Git"repository"in"flipr*db/.git/ > Gitiup > ""echo"Flipr"Database"Project">"README.md > ""git"add".

    > 25 Wednesday, May 22, 13
  73. ""mkdir"flipr*db >"cd"flipr*db >"git"init Initialized"empty"Git"repository"in"flipr*db/.git/ > Gitiup > ""echo"Flipr"Database"Project">"README.md > ""git"add".

    > ""git"commit"*m"'Initialize"repo,"add"README.' [master"(root*commit)"2c4b510]"Initialize"repo,"add"README. 1"file"changed,"1"insertion(+) "create"mode"100644"README.md > 25 Wednesday, May 22, 13
  74. ""mkdir"flipr*db >"cd"flipr*db >"git"init Initialized"empty"Git"repository"in"flipr*db/.git/ > Gitiup > ""echo"Flipr"Database"Project">"README.md > ""git"add".

    > ""git"commit"*m"'Initialize"repo,"add"README.' [master"(root*commit)"2c4b510]"Initialize"repo,"add"README. 1"file"changed,"1"insertion(+) "create"mode"100644"README.md > 25 Wednesday, May 22, 13
  75. ""mkdir"flipr*db >"cd"flipr*db >"git"init Initialized"empty"Git"repository"in"flipr*db/.git/ > Gitiup > ""echo"Flipr"Database"Project">"README.md > ""git"add".

    > ""git"commit"*m"'Initialize"repo,"add"README.' [master"(root*commit)"2c4b510]"Initialize"repo,"add"README. 1"file"changed,"1"insertion(+) "create"mode"100644"README.md > We have a Git repo. 25 Wednesday, May 22, 13
  76. > Origin 26 Wednesday, May 22, 13

  77. ""git"remote"add"origin"../flipr*remote > > Origin 26 Wednesday, May 22, 13

  78. ""git"remote"add"origin"../flipr*remote > > Origin Or remote URL 26 Wednesday, May

    22, 13
  79. ""git"push"*u"origin"master Counting"objects:"3,"done. Writing"objects:"100%"(3/3),"260"bytes,"done. Total"3"(delta"0),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""master"*>"master Branch"master"set"up"to"track"remote"branch"master"from" origin. > ""git"remote"add"origin"../flipr*remote

    > > Origin 26 Wednesday, May 22, 13
  80. ""git"push"*u"origin"master Counting"objects:"3,"done. Writing"objects:"100%"(3/3),"260"bytes,"done. Total"3"(delta"0),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""master"*>"master Branch"master"set"up"to"track"remote"branch"master"from" origin. > ""git"remote"add"origin"../flipr*remote

    > > Origin 26 Wednesday, May 22, 13
  81. ""git"push"*u"origin"master Counting"objects:"3,"done. Writing"objects:"100%"(3/3),"260"bytes,"done. Total"3"(delta"0),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""master"*>"master Branch"master"set"up"to"track"remote"branch"master"from" origin. > ""git"remote"add"origin"../flipr*remote

    > > Origin 26 Wednesday, May 22, 13
  82. ""git"push"*u"origin"master Counting"objects:"3,"done. Writing"objects:"100%"(3/3),"260"bytes,"done. Total"3"(delta"0),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""master"*>"master Branch"master"set"up"to"track"remote"branch"master"from" origin. > ""git"remote"add"origin"../flipr*remote

    > > Origin 26 Wednesday, May 22, 13
  83. Swimming Upstream > 27 Wednesday, May 22, 13

  84. ""git"remote"add"upstream"\ ""https://github.com/theory/agile*flipr.git > Swimming Upstream > 27 Wednesday, May 22,

    13
  85. ""git"remote"add"upstream"\ ""https://github.com/theory/agile*flipr.git > Swimming Upstream > ""git"fetch"upstream From"https://github.com/theory/agile*flipr "*"[new"branch]""""""flips""""""*>"upstream/flips "*"[new"branch]""""""master"""""*>"upstream/master

    "*"[new"branch]""""""userfuncs""*>"upstream/userfuncs "*"[new"branch]""""""users""""""*>"upstream/users "*"[new"tag]"""""""""insert_user"*>"insert_user "*"[new"tag]"""""""""appschema"*>"appschema "*"[new"tag]"""""""""v1.0.0*r1""*>"v1.0.0*r1 "*"[new"tag]"""""""""reltag"""""*>"reltag "*"[new"tag]"""""""""insert_user2"*>"insert_user2 > 27 Wednesday, May 22, 13
  86. ""git"remote"add"upstream"\ ""https://github.com/theory/agile*flipr.git > Swimming Upstream > ""git"fetch"upstream From"https://github.com/theory/agile*flipr "*"[new"branch]""""""flips""""""*>"upstream/flips "*"[new"branch]""""""master"""""*>"upstream/master

    "*"[new"branch]""""""userfuncs""*>"upstream/userfuncs "*"[new"branch]""""""users""""""*>"upstream/users "*"[new"tag]"""""""""insert_user"*>"insert_user "*"[new"tag]"""""""""appschema"*>"appschema "*"[new"tag]"""""""""v1.0.0*r1""*>"v1.0.0*r1 "*"[new"tag]"""""""""reltag"""""*>"reltag "*"[new"tag]"""""""""insert_user2"*>"insert_user2 > For resetting later 27 Wednesday, May 22, 13
  87. Git? antisocial network 28 Wednesday, May 22, 13

  88. Git? Manage tree of files over time antisocial network 28

    Wednesday, May 22, 13
  89. Git? Manage tree of files over time Distributed development antisocial

    network 28 Wednesday, May 22, 13
  90. Git? Manage tree of files over time Distributed development Commit

    changes locally antisocial network 28 Wednesday, May 22, 13
  91. Git? Manage tree of files over time Distributed development Commit

    changes locally Merge to remote (origin, upstream) antisocial network 28 Wednesday, May 22, 13
  92. Git? Manage tree of files over time Distributed development Commit

    changes locally Merge to remote (origin, upstream) Speedy, responsive antisocial network 28 Wednesday, May 22, 13
  93. Git? Manage tree of files over time Distributed development Commit

    changes locally Merge to remote (origin, upstream) Speedy, responsive Flexible, robust antisocial network 28 Wednesday, May 22, 13
  94. Why Git? antisocial network 29 Wednesday, May 22, 13

  95. Why Git? Anyone can clone antisocial network 29 Wednesday, May

    22, 13
  96. Why Git? Anyone can clone Complete repository copy antisocial network

    29 Wednesday, May 22, 13
  97. Why Git? Anyone can clone Complete repository copy Cheap branching

    antisocial network 29 Wednesday, May 22, 13
  98. Why Git? Anyone can clone Complete repository copy Cheap branching

    Make and test local changes antisocial network 29 Wednesday, May 22, 13
  99. Why Git? Anyone can clone Complete repository copy Cheap branching

    Make and test local changes Submit patches, pull requests antisocial network 29 Wednesday, May 22, 13
  100. Why Git? Anyone can clone Complete repository copy Cheap branching

    Make and test local changes Submit patches, pull requests Pull from upstream antisocial network 29 Wednesday, May 22, 13
  101. PiSHA1 antisocial network 30 Wednesday, May 22, 13

  102. PiSHA1 SHA1 ID for every object antisocial network 30 Wednesday,

    May 22, 13
  103. PiSHA1 SHA1 ID for every object commit, tag, tree, blob

    antisocial network 30 Wednesday, May 22, 13
  104. PiSHA1 SHA1 ID for every object commit, tag, tree, blob

    Hashed commit text includes: antisocial network 30 Wednesday, May 22, 13
  105. PiSHA1 SHA1 ID for every object commit, tag, tree, blob

    Hashed commit text includes: tree ID antisocial network 30 Wednesday, May 22, 13
  106. PiSHA1 SHA1 ID for every object commit, tag, tree, blob

    Hashed commit text includes: tree ID parent ID antisocial network 30 Wednesday, May 22, 13
  107. PiSHA1 SHA1 ID for every object commit, tag, tree, blob

    Hashed commit text includes: tree ID parent ID author antisocial network 30 Wednesday, May 22, 13
  108. PiSHA1 SHA1 ID for every object commit, tag, tree, blob

    Hashed commit text includes: tree ID parent ID author committer antisocial network 30 Wednesday, May 22, 13
  109. PiSHA1 SHA1 ID for every object commit, tag, tree, blob

    Hashed commit text includes: tree ID parent ID author committer message antisocial network 30 Wednesday, May 22, 13
  110. > Making a hash of it 31 Wednesday, May 22,

    13
  111. > ""git"cat*file"commit"HEAD tree"8b0955fd015782a26953e20d41db5fadbb347c14 parent"0f38581c4d19313d910c2080b3470cae07f3694e author"David"Wheeler"<david@justatheory.com>"1367971872"*0700 committer"David"Wheeler"<david@justatheory.com>"1367971872"*0700 Get"through""Ship"it!". > Making a

    hash of it 31 Wednesday, May 22, 13
  112. > ""git"cat*file"commit"HEAD tree"8b0955fd015782a26953e20d41db5fadbb347c14 parent"0f38581c4d19313d910c2080b3470cae07f3694e author"David"Wheeler"<david@justatheory.com>"1367971872"*0700 committer"David"Wheeler"<david@justatheory.com>"1367971872"*0700 Get"through""Ship"it!". > Making a

    hash of it 31 Wednesday, May 22, 13
  113. > ""git"cat*file"commit"HEAD tree"8b0955fd015782a26953e20d41db5fadbb347c14 parent"0f38581c4d19313d910c2080b3470cae07f3694e author"David"Wheeler"<david@justatheory.com>"1367971872"*0700 committer"David"Wheeler"<david@justatheory.com>"1367971872"*0700 Get"through""Ship"it!". > Making a

    hash of it 31 Wednesday, May 22, 13
  114. > ""git"cat*file"commit"HEAD tree"8b0955fd015782a26953e20d41db5fadbb347c14 parent"0f38581c4d19313d910c2080b3470cae07f3694e author"David"Wheeler"<david@justatheory.com>"1367971872"*0700 committer"David"Wheeler"<david@justatheory.com>"1367971872"*0700 Get"through""Ship"it!". > Making a

    hash of it 31 Wednesday, May 22, 13
  115. > ""git"cat*file"commit"HEAD tree"8b0955fd015782a26953e20d41db5fadbb347c14 parent"0f38581c4d19313d910c2080b3470cae07f3694e author"David"Wheeler"<david@justatheory.com>"1367971872"*0700 committer"David"Wheeler"<david@justatheory.com>"1367971872"*0700 Get"through""Ship"it!". > Making a

    hash of it 31 Wednesday, May 22, 13
  116. > ""git"cat*file"commit"HEAD tree"8b0955fd015782a26953e20d41db5fadbb347c14 parent"0f38581c4d19313d910c2080b3470cae07f3694e author"David"Wheeler"<david@justatheory.com>"1367971872"*0700 committer"David"Wheeler"<david@justatheory.com>"1367971872"*0700 Get"through""Ship"it!". > Making a

    hash of it 31 Wednesday, May 22, 13
  117. SHAzam! antisocial network 32 Wednesday, May 22, 13

  118. SHAzam! Each commit (except first) includes parent antisocial network 32

    Wednesday, May 22, 13
  119. SHAzam! Each commit (except first) includes parent Can trace from

    any commit to the beginning antisocial network 32 Wednesday, May 22, 13
  120. SHAzam! Each commit (except first) includes parent Can trace from

    any commit to the beginning Tampering (corruption) detectable antisocial network 32 Wednesday, May 22, 13
  121. SHAzam! Each commit (except first) includes parent Can trace from

    any commit to the beginning Tampering (corruption) detectable Because the hash will be wrong antisocial network 32 Wednesday, May 22, 13
  122. SHAzam! Each commit (except first) includes parent Can trace from

    any commit to the beginning Tampering (corruption) detectable Because the hash will be wrong Linus Torvalds’s “greatest invention” http:/ /perl.plover.com/yak/git/ antisocial network 32 Wednesday, May 22, 13
  123. antisocial network Your Turn 33 Wednesday, May 22, 13

  124. antisocial network Your Turn Configure Git 33 Wednesday, May 22,

    13
  125. antisocial network Your Turn Configure Git Initialize repository 33 Wednesday,

    May 22, 13
  126. antisocial network Your Turn Configure Git Initialize repository Add origin

    remote 33 Wednesday, May 22, 13
  127. antisocial network Your Turn Configure Git Initialize repository Add origin

    remote Add upstream remote 33 Wednesday, May 22, 13
  128. antisocial network Your Turn Configure Git Initialize repository Add origin

    remote Add upstream remote https:/ /github.com/ theory/agile-flipr.git 33 Wednesday, May 22, 13
  129. Who am I again? > 34 Wednesday, May 22, 13

  130. Who am I again? ""sqitch"config"**user"user.name"'David"E."Wheeler' > > 34 Wednesday, May

    22, 13
  131. Who am I again? ""sqitch"config"**user"user.name"'David"E."Wheeler' > > 34 Wednesday, May

    22, 13
  132. Who am I again? ""sqitch"config"**user"user.email"david@justatheory.com > ""sqitch"config"**user"user.name"'David"E."Wheeler' > > 34

    Wednesday, May 22, 13
  133. Who am I again? ""sqitch"config"**user"user.email"david@justatheory.com > ""sqitch"config"**user"core.pg.client"/opt/local/pgsql/bin/psql > ""sqitch"config"**user"user.name"'David"E."Wheeler' >

    > 34 Wednesday, May 22, 13
  134. Who am I again? ""sqitch"config"**user"user.email"david@justatheory.com > ""sqitch"config"**user"core.pg.client"/opt/local/pgsql/bin/psql > ""sqitch"config"**user"user.name"'David"E."Wheeler' >

    ""emacs"~/.sqitch/sqitch.conf > > 34 Wednesday, May 22, 13
  135. ~/.sqitch/sqitc ~/ .sqitch/sqitch.conf [core""pg"] " client"="/opt/local/pgsql/bin/psql [user] "" name"="David"E."Wheeler """

    email"="david@justatheory.com 35 Wednesday, May 22, 13
  136. ~/.sqitch/sqitc ~/ .sqitch/sqitch.conf [core""pg"] " client"="/opt/local/pgsql/bin/psql [user] "" name"="David"E."Wheeler """

    email"="david@justatheory.com Good for all projects 35 Wednesday, May 22, 13
  137. > Scratch that Sqitch 36 Wednesday, May 22, 13

  138. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch 36 Wednesday, May 22, 13
  139. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch 36 Wednesday, May 22, 13
  140. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch Use remote URL 36 Wednesday, May 22, 13
  141. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch 36 Wednesday, May 22, 13
  142. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch 36 Wednesday, May 22, 13
  143. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch 36 Wednesday, May 22, 13
  144. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch 36 Wednesday, May 22, 13
  145. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch 36 Wednesday, May 22, 13
  146. >"sqitch"**engine"pg"init"flipr"\ ""**uri"file://../flipr*remote Created"sqitch.conf Created"sqitch.plan Created"deploy/ Created"revert/ Created"verify/ > > Scratch

    that Sqitch ""emacs"sqitch.conf > 36 Wednesday, May 22, 13
  147. sqitch.conf sqitch.conf [core] " engine"="pg " #"plan_file"="sqitch.plan " #"top_dir"=". "

    #"deploy_dir"="deploy " #"revert_dir"="revert " #"verify_dir"="verify " #"extension"="sql #"[core""pg"] " #"client"="/usr/local/pgsql/bin/psql " #"username"=" " #"password"=" " #"db_name"=" " #"host"=" " #"port"=" " #"sqitch_schema"="sqitch 37 Wednesday, May 22, 13
  148. sqitch.conf sqitch.conf [core] " engine"="pg " #"plan_file"="sqitch.plan " #"top_dir"=". "

    #"deploy_dir"="deploy " #"revert_dir"="revert " #"verify_dir"="verify " #"extension"="sql #"[core""pg"] " #"client"="/usr/local/pgsql/bin/psql " #"username"=" " #"password"=" " #"db_name"=" " #"host"=" " #"port"=" " #"sqitch_schema"="sqitch --engine pg 37 Wednesday, May 22, 13
  149. What’s the Plan Man? > 38 Wednesday, May 22, 13

  150. What’s the Plan Man? ""emacs"sqitch.plan > > 38 Wednesday, May

    22, 13
  151. sqitch.plan sqitch.plan %syntax*version=1.0.0*b1 %project=flipr %uri=file://../flipr*remote 39 Wednesday, May 22, 13

  152. sqitch.plan sqitch.plan %syntax*version=1.0.0*b1 %project=flipr %uri=file://../flipr*remote Identified 39 Wednesday, May 22,

    13
  153. Make It So > 40 Wednesday, May 22, 13

  154. Make It So > ""git"add". >"git"commit"*m"'Initialize"Sqitch"configuration.' [master"297c07d]"Initialize"Sqitch"configuration. "2"files"changed,"20"insertions(+) "create"mode"100644"sqitch.conf "create"mode"100644"sqitch.plan

    > 40 Wednesday, May 22, 13
  155. Make It So > ""git"add". >"git"commit"*m"'Initialize"Sqitch"configuration.' [master"297c07d]"Initialize"Sqitch"configuration. "2"files"changed,"20"insertions(+) "create"mode"100644"sqitch.conf "create"mode"100644"sqitch.plan

    > 40 Wednesday, May 22, 13
  156. Make It So > ""git"add". >"git"commit"*m"'Initialize"Sqitch"configuration.' [master"297c07d]"Initialize"Sqitch"configuration. "2"files"changed,"20"insertions(+) "create"mode"100644"sqitch.conf "create"mode"100644"sqitch.plan

    > 40 Wednesday, May 22, 13
  157. Make It So > ""git"add". >"git"commit"*m"'Initialize"Sqitch"configuration.' [master"297c07d]"Initialize"Sqitch"configuration. "2"files"changed,"20"insertions(+) "create"mode"100644"sqitch.conf "create"mode"100644"sqitch.plan

    > ""git"push Counting"objects:"5,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(4/4),"done. Writing"objects:"100%"(4/4),"564"bytes,"done. Total"4"(delta"0),"reused"0"(delta"0) To"../flipr*remote """7d28be0..297c07d""master"*>"master > 40 Wednesday, May 22, 13
  158. Make It So > ""git"add". >"git"commit"*m"'Initialize"Sqitch"configuration.' [master"297c07d]"Initialize"Sqitch"configuration. "2"files"changed,"20"insertions(+) "create"mode"100644"sqitch.conf "create"mode"100644"sqitch.plan

    > ""git"push Counting"objects:"5,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(4/4),"done. Writing"objects:"100%"(4/4),"564"bytes,"done. Total"4"(delta"0),"reused"0"(delta"0) To"../flipr*remote """7d28be0..297c07d""master"*>"master > 40 Wednesday, May 22, 13
  159. Make It So > ""git"add". >"git"commit"*m"'Initialize"Sqitch"configuration.' [master"297c07d]"Initialize"Sqitch"configuration. "2"files"changed,"20"insertions(+) "create"mode"100644"sqitch.conf "create"mode"100644"sqitch.plan

    > ""git"push Counting"objects:"5,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(4/4),"done. Writing"objects:"100%"(4/4),"564"bytes,"done. Total"4"(delta"0),"reused"0"(delta"0) To"../flipr*remote """7d28be0..297c07d""master"*>"master > 40 Wednesday, May 22, 13
  160. Where’ve We Been? > 41 Wednesday, May 22, 13

  161. ""git"log commit"a4f765f88c1875ffe9427e73f72a6b66ce363ed4 Author:"David"E."Wheeler"<david@justatheory.com> Date:"""Tue"May"21"15:00:33"2013"*0400 """"Initialize"Sqitch"configuration. commit"2c4b51017929634a30f4a74e20268c05effdfcb3 Author:"David"E."Wheeler"<david@justatheory.com> Date:"""Tue"May"21"14:59:16"2013"*0400 """"Initialize"repo,"add"README. >

    Where’ve We Been? > 41 Wednesday, May 22, 13
  162. ""git"log commit"a4f765f88c1875ffe9427e73f72a6b66ce363ed4 Author:"David"E."Wheeler"<david@justatheory.com> Date:"""Tue"May"21"15:00:33"2013"*0400 """"Initialize"Sqitch"configuration. commit"2c4b51017929634a30f4a74e20268c05effdfcb3 Author:"David"E."Wheeler"<david@justatheory.com> Date:"""Tue"May"21"14:59:16"2013"*0400 """"Initialize"repo,"add"README. >

    Where’ve We Been? > 41 Wednesday, May 22, 13
  163. ""git"log commit"a4f765f88c1875ffe9427e73f72a6b66ce363ed4 Author:"David"E."Wheeler"<david@justatheory.com> Date:"""Tue"May"21"15:00:33"2013"*0400 """"Initialize"Sqitch"configuration. commit"2c4b51017929634a30f4a74e20268c05effdfcb3 Author:"David"E."Wheeler"<david@justatheory.com> Date:"""Tue"May"21"14:59:16"2013"*0400 """"Initialize"repo,"add"README. >

    Where’ve We Been? > 41 Wednesday, May 22, 13
  164. First Change > 42 Wednesday, May 22, 13

  165. First Change >"sqitch"add"appschema"*n"'Adds"flipr"app"schema.' Created"deploy/appschema.sql Created"revert/appschema.sql Created"verify/appschema.sql Added""appschema""to"sqitch.plan > > 42

    Wednesday, May 22, 13
  166. First Change >"sqitch"add"appschema"*n"'Adds"flipr"app"schema.' Created"deploy/appschema.sql Created"revert/appschema.sql Created"verify/appschema.sql Added""appschema""to"sqitch.plan > > 42

    Wednesday, May 22, 13
  167. First Change >"sqitch"add"appschema"*n"'Adds"flipr"app"schema.' Created"deploy/appschema.sql Created"revert/appschema.sql Created"verify/appschema.sql Added""appschema""to"sqitch.plan > > 42

    Wednesday, May 22, 13
  168. First Change >"sqitch"add"appschema"*n"'Adds"flipr"app"schema.' Created"deploy/appschema.sql Created"revert/appschema.sql Created"verify/appschema.sql Added""appschema""to"sqitch.plan > > ""emacs"deploy/appschema.sql

    > 42 Wednesday, May 22, 13
  169. deploy/appschem deploy/appschema.sql **"Deploy"appschema BEGIN; COMMIT; **"XXX"Add"DDLs"here. 43 Wednesday, May 22,

    13
  170. deploy/appschem deploy/appschema.sql **"Deploy"appschema BEGIN; COMMIT; CREATE"SCHEMA"flipr; 43 Wednesday, May 22,

    13
  171. >"sqitch"add"appschema"*n"'Adds"flipr"app"schema.' Created"deploy/appschema.sql Created"revert/appschema.sql Created"verify/appschema.sql Added""appschema""to"sqitch.plan > First Change > ""emacs"deploy/appschema.sql

    > 44 Wednesday, May 22, 13
  172. >"sqitch"add"appschema"*n"'Adds"flipr"app"schema.' Created"deploy/appschema.sql Created"revert/appschema.sql Created"verify/appschema.sql Added""appschema""to"sqitch.plan > First Change > ""emacs"deploy/appschema.sql

    > ""emacs"revert/appschema.sql > 44 Wednesday, May 22, 13
  173. revert/appschem revert/appschema.sql **"Revert"appschema BEGIN; COMMIT; **"XXX"Add"DDLs"here. 45 Wednesday, May 22,

    13
  174. revert/appschem revert/appschema.sql **"Revert"appschema BEGIN; COMMIT; DROP"SCHEMA"flipr; 45 Wednesday, May 22,

    13
  175. Make it So! > 46 Wednesday, May 22, 13

  176. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    46 Wednesday, May 22, 13
  177. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    Might need -U postgres 46 Wednesday, May 22, 13
  178. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    46 Wednesday, May 22, 13
  179. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    46 Wednesday, May 22, 13
  180. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    46 Wednesday, May 22, 13
  181. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    46 Wednesday, May 22, 13
  182. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    ""psql"*d"flipr_test"*c"'\dn"flipr' List"of"schemas "Name""|"Owner" *******+******* "flipr"|"david > 46 Wednesday, May 22, 13
  183. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    ""psql"*d"flipr_test"*c"'\dn"flipr' List"of"schemas "Name""|"Owner" *******+******* "flipr"|"david > Trust, but verify 46 Wednesday, May 22, 13
  184. ""createdb"flipr_test >"sqitch"**db*name"flipr_test"deploy Adding"metadata"tables"to"flipr_test Deploying"to"flipr_test ""+"appschema".."ok > Make it So! >

    ""psql"*d"flipr_test"*c"'\dn"flipr' List"of"schemas "Name""|"Owner" *******+******* "flipr"|"david > ""emacs"verify/appschema.sql 46 Wednesday, May 22, 13
  185. **"Verify"appschema BEGIN; ROLLBACK; verify/appschem verify/appschema.sql **"XXX"Add"verifications"here. 47 Wednesday, May 22,

    13
  186. **"Verify"appschema BEGIN; ROLLBACK; SELECT"pg_catalog.has_schema_privilege('nada',"'usage'); verify/appschem verify/appschema.sql 47 Wednesday, May 22,

    13
  187. **"Verify"appschema BEGIN; ROLLBACK; SELECT"pg_catalog.has_schema_privilege('nada',"'usage'); verify/appschem verify/appschema.sql Let’s try it, first

    47 Wednesday, May 22, 13
  188. Trust, But Verify > ""emacs"verify/appschema.sql > 48 Wednesday, May 22,

    13
  189. Trust, But Verify > ""emacs"verify/appschema.sql > ""sqitch"**db*name"flipr_test"verify Verifying"flipr_test ""*"appschema".."psql:verify/appschema.sql:5:" ERROR:""schema""nada""does"not"exist

    #"Verify"script""verify/appschema.sql""failed. not"ok Verify"Summary"Report ********************* Changes:"1 Errors:""1 Verify"failed > 48 Wednesday, May 22, 13
  190. Trust, But Verify > ""emacs"verify/appschema.sql > ""sqitch"**db*name"flipr_test"verify Verifying"flipr_test ""*"appschema".."psql:verify/appschema.sql:5:" ERROR:""schema""nada""does"not"exist

    #"Verify"script""verify/appschema.sql""failed. not"ok Verify"Summary"Report ********************* Changes:"1 Errors:""1 Verify"failed > 48 Wednesday, May 22, 13
  191. Trust, But Verify > ""emacs"verify/appschema.sql > ""sqitch"**db*name"flipr_test"verify Verifying"flipr_test ""*"appschema".."psql:verify/appschema.sql:5:" ERROR:""schema""nada""does"not"exist

    #"Verify"script""verify/appschema.sql""failed. not"ok Verify"Summary"Report ********************* Changes:"1 Errors:""1 Verify"failed > 48 Wednesday, May 22, 13
  192. Trust, But Verify > ""emacs"verify/appschema.sql > ""sqitch"**db*name"flipr_test"verify Verifying"flipr_test ""*"appschema".."psql:verify/appschema.sql:5:" ERROR:""schema""nada""does"not"exist

    #"Verify"script""verify/appschema.sql""failed. not"ok Verify"Summary"Report ********************* Changes:"1 Errors:""1 Verify"failed > 48 Wednesday, May 22, 13
  193. Trust, But Verify > 49 Wednesday, May 22, 13

  194. ""perl"*i"*pe"'s/nada/flipr/'"verify/appschema.sql >" Trust, But Verify > 49 Wednesday, May 22,

    13
  195. ""sqitch"**db*name"flipr_test"verify Verifying"flipr_test ""*"appschema".."ok Verify"successful > ""perl"*i"*pe"'s/nada/flipr/'"verify/appschema.sql >" Trust, But Verify

    > Mo betta. 49 Wednesday, May 22, 13
  196. > How’s it Look? 50 Wednesday, May 22, 13

  197. > How’s it Look? >"sqitch"*d"flipr_test"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3 #"Name:"""""appschema #"Deployed:"2013*05*21"15:04:08"*0400

    #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) > 50 Wednesday, May 22, 13
  198. > How’s it Look? >"sqitch"*d"flipr_test"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3 #"Name:"""""appschema #"Deployed:"2013*05*21"15:04:08"*0400

    #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) > 50 Wednesday, May 22, 13
  199. > How’s it Look? >"sqitch"*d"flipr_test"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3 #"Name:"""""appschema #"Deployed:"2013*05*21"15:04:08"*0400

    #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) > 50 Wednesday, May 22, 13
  200. > How’s it Look? >"sqitch"*d"flipr_test"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3 #"Name:"""""appschema #"Deployed:"2013*05*21"15:04:08"*0400

    #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) > 50 Wednesday, May 22, 13
  201. > How’s it Look? >"sqitch"*d"flipr_test"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3 #"Name:"""""appschema #"Deployed:"2013*05*21"15:04:08"*0400

    #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) > 50 Wednesday, May 22, 13
  202. > How’s it Look? >"sqitch"*d"flipr_test"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3 #"Name:"""""appschema #"Deployed:"2013*05*21"15:04:08"*0400

    #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) > 50 Wednesday, May 22, 13
  203. Go Back > 51 Wednesday, May 22, 13

  204. >"sqitch"**db*name"flipr_test"revert ""Revert"all"changes"from"flipr_test?"[Yes] Go Back >  51 Wednesday, May 22,

    13
  205. >"sqitch"**db*name"flipr_test"revert ""Revert"all"changes"from"flipr_test?"[Yes] Go Back >  51 Wednesday, May 22,

    13
  206. >"sqitch"**db*name"flipr_test"revert ""Revert"all"changes"from"flipr_test?"[Yes] Go Back > ""*"appschema".."ok > 51 Wednesday, May

    22, 13
  207. >"sqitch"**db*name"flipr_test"revert ""Revert"all"changes"from"flipr_test?"[Yes] Go Back > ""psql"*d"flipr_test"*c"'\dn"flipr' """"""""""""List"of"roles List"of"schemas "Name"|"Owner" ******+*******

    > ""*"appschema".."ok > 51 Wednesday, May 22, 13
  208. >"sqitch"**db*name"flipr_test"revert ""Revert"all"changes"from"flipr_test?"[Yes] Go Back > ""psql"*d"flipr_test"*c"'\dn"flipr' """"""""""""List"of"roles List"of"schemas "Name"|"Owner" ******+*******

    > ""*"appschema".."ok > ""sqitch"*d"flipr_test"status #"On"database"flipr_test No"changes"deployed > 51 Wednesday, May 22, 13
  209. History > 52 Wednesday, May 22, 13

  210. History > >"sqitch"*d"flipr_test"log On"database"flipr_test Revert"748346dfe73cf2af32a8b7088fd75ad8d7aecda3 Name:""""""appschema Committer:"David"E."Wheeler"<david@justatheory.com> Date:""""""2013*05*21"15:07:07"*0400 """"Adds"flipr"app"schema. Deploy"748346dfe73cf2af32a8b7088fd75ad8d7aecda3

    Name:""""""appschema Committer:"David"E."Wheeler"<david@justatheory.com> Date:""""""2013*05*21"15:04:08"*0400 """"Adds"flipr"app"schema. 52 Wednesday, May 22, 13
  211. History > >"sqitch"*d"flipr_test"log On"database"flipr_test Revert"748346dfe73cf2af32a8b7088fd75ad8d7aecda3 Name:""""""appschema Committer:"David"E."Wheeler"<david@justatheory.com> Date:""""""2013*05*21"15:07:07"*0400 """"Adds"flipr"app"schema. Deploy"748346dfe73cf2af32a8b7088fd75ad8d7aecda3

    Name:""""""appschema Committer:"David"E."Wheeler"<david@justatheory.com> Date:""""""2013*05*21"15:04:08"*0400 """"Adds"flipr"app"schema. 52 Wednesday, May 22, 13
  212. History > >"sqitch"*d"flipr_test"log On"database"flipr_test Revert"748346dfe73cf2af32a8b7088fd75ad8d7aecda3 Name:""""""appschema Committer:"David"E."Wheeler"<david@justatheory.com> Date:""""""2013*05*21"15:07:07"*0400 """"Adds"flipr"app"schema. Deploy"748346dfe73cf2af32a8b7088fd75ad8d7aecda3

    Name:""""""appschema Committer:"David"E."Wheeler"<david@justatheory.com> Date:""""""2013*05*21"15:04:08"*0400 """"Adds"flipr"app"schema. 52 Wednesday, May 22, 13
  213. Commit It! > 53 Wednesday, May 22, 13

  214. Commit It! > ""git"add". >"git"commit"*m"'Add"flipr"schema.' [master"dc23038]"Add"flipr"schema. "4"files"changed,"22"insertions(+) "create"mode"100644"deploy/appschema.sql "create"mode"100644"revert/appschema.sql "create"mode"100644"verify/appschema.sql

    > 53 Wednesday, May 22, 13
  215. Commit It! > ""git"add". >"git"commit"*m"'Add"flipr"schema.' [master"dc23038]"Add"flipr"schema. "4"files"changed,"22"insertions(+) "create"mode"100644"deploy/appschema.sql "create"mode"100644"revert/appschema.sql "create"mode"100644"verify/appschema.sql

    > 53 Wednesday, May 22, 13
  216. Commit It! > ""git"add". >"git"commit"*m"'Add"flipr"schema.' [master"dc23038]"Add"flipr"schema. "4"files"changed,"22"insertions(+) "create"mode"100644"deploy/appschema.sql "create"mode"100644"revert/appschema.sql "create"mode"100644"verify/appschema.sql

    > 53 Wednesday, May 22, 13
  217. Commit It! > ""git"add". >"git"commit"*m"'Add"flipr"schema.' [master"dc23038]"Add"flipr"schema. "4"files"changed,"22"insertions(+) "create"mode"100644"deploy/appschema.sql "create"mode"100644"revert/appschema.sql "create"mode"100644"verify/appschema.sql

    > ""git"push Counting"objects:"11,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(6/6),"done. Writing"objects:"100%"(9/9),"943"bytes,"done. Total"9"(delta"0),"reused"0"(delta"0) To"../flipr*remote """a4f765f..dc23038""master"*>"master 53 Wednesday, May 22, 13
  218. Commit It! > ""git"add". >"git"commit"*m"'Add"flipr"schema.' [master"dc23038]"Add"flipr"schema. "4"files"changed,"22"insertions(+) "create"mode"100644"deploy/appschema.sql "create"mode"100644"revert/appschema.sql "create"mode"100644"verify/appschema.sql

    > ""git"push Counting"objects:"11,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(6/6),"done. Writing"objects:"100%"(9/9),"943"bytes,"done. Total"9"(delta"0),"reused"0"(delta"0) To"../flipr*remote """a4f765f..dc23038""master"*>"master 53 Wednesday, May 22, 13
  219. Redeploy > 54 Wednesday, May 22, 13

  220. >"sqitch"**db*name"flipr_test"deploy"**verify Deploying"changes"to"flipr_test ""+"appschema".."ok > Redeploy > 54 Wednesday, May 22,

    13
  221. >"sqitch"**db*name"flipr_test"deploy"**verify Deploying"changes"to"flipr_test ""+"appschema".."ok > Redeploy > Integrated! 54 Wednesday, May

    22, 13
  222. >"sqitch"**db*name"flipr_test"deploy"**verify Deploying"changes"to"flipr_test ""+"appschema".."ok > Redeploy > 54 Wednesday, May 22,

    13
  223. >"sqitch"**db*name"flipr_test"deploy"**verify Deploying"changes"to"flipr_test ""+"appschema".."ok > Redeploy > ""psql"*d"flipr_test"*c"'\dn"flipr' List"of"schemas "Name""|"Owner" *******+*******

    "flipr"|"david > 54 Wednesday, May 22, 13
  224. Status Update > 55 Wednesday, May 22, 13

  225. >"sqitch"*d"flipr_test"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3 #"Name:"""""appschema #"Deployed:"2013*05*21"15:10:02"*0400 #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) >

    Status Update > 55 Wednesday, May 22, 13
  226. Save My Fingers > 56 Wednesday, May 22, 13

  227. Save My Fingers > ""sqitch"config"core.pg.db_name"flipr_test > 56 Wednesday, May 22,

    13
  228. Save My Fingers > ""sqitch"config"core.pg.db_name"flipr_test > ""sqitch"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3

    #"Name:"""""appschema #"Deployed:"2013*05*21"15:10:02"*0400 #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) > No --db-name 56 Wednesday, May 22, 13
  229. Save My Fingers > ""sqitch"config"core.pg.db_name"flipr_test > ""sqitch"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3

    #"Name:"""""appschema #"Deployed:"2013*05*21"15:10:02"*0400 #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Nothing"to"deploy"(up*to*date) > No --db-name >"sqitch"config"**bool"deploy.verify"true >"sqitch"config"**bool"rebase.verify"true > Always verify. 56 Wednesday, May 22, 13
  230. Commit Config > 57 Wednesday, May 22, 13

  231. Commit Config > ""git"add". >"git"commit"*m"'Add"db_name"and"verify"to"config.' [master"795697f]"Add"db_name"and"verify"to"config. "1"file"changed,"6"insertions(+) > 57 Wednesday,

    May 22, 13
  232. Commit Config > ""git"add". >"git"commit"*m"'Add"db_name"and"verify"to"config.' [master"795697f]"Add"db_name"and"verify"to"config. "1"file"changed,"6"insertions(+) > 57 Wednesday,

    May 22, 13
  233. Commit Config > ""git"push Counting"objects:"5,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(3/3),"done. Writing"objects:"100%"(3/3),"376"bytes,"done. Total"3"(delta"2),"reused"0"(delta"0) To"../flipr*remote

    """dc23038..795697f""master"*>"master > ""git"add". >"git"commit"*m"'Add"db_name"and"verify"to"config.' [master"795697f]"Add"db_name"and"verify"to"config. "1"file"changed,"6"insertions(+) > 57 Wednesday, May 22, 13
  234. Not Migrations? antisocial network 58 Wednesday, May 22, 13

  235. Not Migrations? Incomplete mini-language antisocial network 58 Wednesday, May 22,

    13
  236. Not Migrations? Incomplete mini-language No logical replication integration antisocial network

    58 Wednesday, May 22, 13
  237. Not Migrations? Incomplete mini-language No logical replication integration Numbered scripts

    difficult to track antisocial network 58 Wednesday, May 22, 13
  238. Not Migrations? Incomplete mini-language No logical replication integration Numbered scripts

    difficult to track No VCS awareness antisocial network 58 Wednesday, May 22, 13
  239. SQL Migrations? Incomplete mini-language No logical replication integration Numbered scripts

    hard to track No VCS awareness antisocial network 59 Wednesday, May 22, 13
  240. SQL Migrations? Incomplete mini-language No logical replication integration Numbered scripts

    hard to track No VCS awareness ——————————————— antisocial network 59 Wednesday, May 22, 13
  241. SQL Migrations? Incomplete mini-language No logical replication integration Numbered scripts

    hard to track No VCS awareness ——————————————— ——————————————————— antisocial network 59 Wednesday, May 22, 13
  242. SQL Migrations? Incomplete mini-language No logical replication integration Numbered scripts

    hard to track No VCS awareness ——————————————— ——————————————————— Managing procedures is a PITA antisocial network 59 Wednesday, May 22, 13
  243. Sq—what? sql anges ch antisocial network 60 Wednesday, May 22,

    13
  244. Sq—what? sq ch antisocial network 60 Wednesday, May 22, 13

  245. it Sq—what? sq ch antisocial network 60 Wednesday, May 22,

    13
  246. it Sq—what? sq ch There is no “u” antisocial network

    60 Wednesday, May 22, 13
  247. Sqitch Philosophy antisocial network 61 Wednesday, May 22, 13

  248. Sqitch Philosophy No opinions antisocial network 61 Wednesday, May 22,

    13
  249. Sqitch Philosophy No opinions Native scripting (psql, sqlite3, SQL*Plus) antisocial

    network 61 Wednesday, May 22, 13
  250. Sqitch Philosophy No opinions Native scripting (psql, sqlite3, SQL*Plus) Cross-project

    dependency resolution antisocial network 61 Wednesday, May 22, 13
  251. Sqitch Philosophy No opinions Native scripting (psql, sqlite3, SQL*Plus) Cross-project

    dependency resolution Distribution bundling antisocial network 61 Wednesday, May 22, 13
  252. Sqitch Philosophy No opinions Native scripting (psql, sqlite3, SQL*Plus) Cross-project

    dependency resolution Distribution bundling Integrated verification testing antisocial network 61 Wednesday, May 22, 13
  253. Sqitch Philosophy No opinions Native scripting (psql, sqlite3, SQL*Plus) Cross-project

    dependency resolution Distribution bundling Integrated verification testing No numbering antisocial network 61 Wednesday, May 22, 13
  254. Sqitch Philosophy No opinions Native scripting (psql, sqlite3, SQL*Plus) Cross-project

    dependency resolution Distribution bundling Integrated verification testing No numbering Reliable sequential deployment ordering antisocial network 61 Wednesday, May 22, 13
  255. SHAzbat antisocial network 62 Wednesday, May 22, 13

  256. SHAzbat SHA1 ID for every object antisocial network 62 Wednesday,

    May 22, 13
  257. SHAzbat SHA1 ID for every object Stolen from Git antisocial

    network 62 Wednesday, May 22, 13
  258. SHAzbat SHA1 ID for every object Stolen from Git change,

    tag, deploy, revert, verify antisocial network 62 Wednesday, May 22, 13
  259. SHAzbat SHA1 ID for every object Stolen from Git change,

    tag, deploy, revert, verify Hashed change text includes: antisocial network 62 Wednesday, May 22, 13
  260. SHAzbat SHA1 ID for every object Stolen from Git change,

    tag, deploy, revert, verify Hashed change text includes: Project antisocial network 62 Wednesday, May 22, 13
  261. SHAzbat SHA1 ID for every object Stolen from Git change,

    tag, deploy, revert, verify Hashed change text includes: Project Name antisocial network 62 Wednesday, May 22, 13
  262. SHAzbat SHA1 ID for every object Stolen from Git change,

    tag, deploy, revert, verify Hashed change text includes: Project Name Parent ID antisocial network 62 Wednesday, May 22, 13
  263. SHAzbat SHA1 ID for every object Stolen from Git change,

    tag, deploy, revert, verify Hashed change text includes: Project Name Parent ID Planner… antisocial network 62 Wednesday, May 22, 13
  264. SHAsome > 63 Wednesday, May 22, 13

  265. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  266. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > Symbolic Sqitch tag 63 Wednesday, May 22, 13
  267. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  268. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  269. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  270. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  271. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  272. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  273. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  274. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  275. SHAsome > ""sqitch"show"change"@HEAD project"pgxn_manager uri"https://github.com/pgxn/pgxn*manager.git change"distview parent"39d7e105cb00e1798cfabb45f4b74cbc14a82513 planner"David"E."Wheeler"<david@justatheory.com> date"2013*02*08T23:51:19Z requires

    ""+"roles ""+"pgxn_core:types ""+"distributions ""+"extensions Adds"the"filters"table. > 63 Wednesday, May 22, 13
  276. SHApay! antisocial network 64 Wednesday, May 22, 13

  277. SHApay! Each change (except first) includes parent antisocial network 64

    Wednesday, May 22, 13
  278. SHApay! Each change (except first) includes parent Can trace from

    any change to the beginning antisocial network 64 Wednesday, May 22, 13
  279. SHApay! Each change (except first) includes parent Can trace from

    any change to the beginning Change tampering (corruption) detectable antisocial network 64 Wednesday, May 22, 13
  280. SHApay! Each change (except first) includes parent Can trace from

    any change to the beginning Change tampering (corruption) detectable Because the hash will be wrong antisocial network 64 Wednesday, May 22, 13
  281. SHApay! Each change (except first) includes parent Can trace from

    any change to the beginning Change tampering (corruption) detectable Because the hash will be wrong Stole Linus Torvalds’s “greatest invention” antisocial network 64 Wednesday, May 22, 13
  282. Sqitch Features antisocial network 65 Wednesday, May 22, 13

  283. Sqitch Features Reduced duplication antisocial network 65 Wednesday, May 22,

    13
  284. Sqitch Features Reduced duplication Built-in configuration antisocial network 65 Wednesday,

    May 22, 13
  285. Sqitch Features Reduced duplication Built-in configuration Iterative development antisocial network

    65 Wednesday, May 22, 13
  286. Sqitch Features Reduced duplication Built-in configuration Iterative development Deployment planning

    antisocial network 65 Wednesday, May 22, 13
  287. Sqitch Features Reduced duplication Built-in configuration Iterative development Deployment planning

    Git-style interface antisocial network 65 Wednesday, May 22, 13
  288. Sqitch Features Reduced duplication Built-in configuration Iterative development Deployment planning

    Git-style interface Deployment tagging antisocial network 65 Wednesday, May 22, 13
  289. antisocial network Your Turn 66 Wednesday, May 22, 13

  290. antisocial network Your Turn Configure Sqitch 66 Wednesday, May 22,

    13
  291. antisocial network Your Turn Configure Sqitch Initialize project 66 Wednesday,

    May 22, 13
  292. antisocial network Your Turn Configure Sqitch Initialize project Add appschema

    change 66 Wednesday, May 22, 13
  293. antisocial network Your Turn Configure Sqitch Initialize project Add appschema

    change Deploy/Revert 66 Wednesday, May 22, 13
  294. antisocial network Your Turn Configure Sqitch Initialize project Add appschema

    change Deploy/Revert Commit/push 66 Wednesday, May 22, 13
  295. antisocial network Your Turn Configure Sqitch Initialize project Add appschema

    change Deploy/Revert Commit/push https:/ /github.com/ theory/agile-flipr.git 66 Wednesday, May 22, 13
  296. Add Tests > 67 Wednesday, May 22, 13

  297. Add Tests > ""mkdir"test > 67 Wednesday, May 22, 13

  298. Add Tests > ""mkdir"test > ""emacs"test/appschema.sql > 67 Wednesday, May

    22, 13
  299. test/appschema. pgTAP Basics 68 Wednesday, May 22, 13

  300. test/appschema. pgTAP Basics SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; **"Plan"the"tests. SELECT"plan(1); SELECT"has_schema('nada');

    **"Clean"up. SELECT"finish(); ROLLBACK; 68 Wednesday, May 22, 13
  301. test/appschema. pgTAP Basics SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; **"Plan"the"tests. SELECT"plan(1); SELECT"has_schema('nada');

    **"Clean"up. SELECT"finish(); ROLLBACK; 68 Wednesday, May 22, 13
  302. test/appschema. pgTAP Basics SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; **"Plan"the"tests. SELECT"plan(1); SELECT"has_schema('nada');

    **"Clean"up. SELECT"finish(); ROLLBACK; 68 Wednesday, May 22, 13
  303. test/appschema. pgTAP Basics SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; **"Plan"the"tests. SELECT"plan(1); SELECT"has_schema('nada');

    **"Clean"up. SELECT"finish(); ROLLBACK; 68 Wednesday, May 22, 13
  304. test/appschema. pgTAP Basics SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; **"Plan"the"tests. SELECT"plan(1); SELECT"has_schema('nada');

    **"Clean"up. SELECT"finish(); ROLLBACK; 68 Wednesday, May 22, 13
  305. test/appschema. pgTAP Basics SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; **"Plan"the"tests. SELECT"plan(1); SELECT"has_schema('nada');

    **"Clean"up. SELECT"finish(); ROLLBACK; 68 Wednesday, May 22, 13
  306. test/appschema. pgTAP Basics SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; **"Plan"the"tests. SELECT"plan(1); SELECT"has_schema('nada');

    **"Clean"up. SELECT"finish(); ROLLBACK; 68 Wednesday, May 22, 13
  307. > Run the Test 69 Wednesday, May 22, 13

  308. > Run the Test ""pg_prove"*v"*d"flipr_test"test/appschema.sql test/appschema.sql".." 1..1 not"ok"1"*"Schema"nada"should"exist #"Failed"test"1:""Schema"nada"should"exist" #"Looks"like"you"failed"1"test"of"1

    Failed"1/1"subtests" Test"Summary"Report ******************* test/appschema.sql"(Wstat:"0"Tests:"1"Failed:"1) ""Failed"test:""1 Files=1,"Tests=1,""0"wallclock"secs Result:"FAIL 69 Wednesday, May 22, 13
  309. > Run the Test ""pg_prove"*v"*d"flipr_test"test/appschema.sql test/appschema.sql".." 1..1 not"ok"1"*"Schema"nada"should"exist #"Failed"test"1:""Schema"nada"should"exist" #"Looks"like"you"failed"1"test"of"1

    Failed"1/1"subtests" Test"Summary"Report ******************* test/appschema.sql"(Wstat:"0"Tests:"1"Failed:"1) ""Failed"test:""1 Files=1,"Tests=1,""0"wallclock"secs Result:"FAIL 69 Wednesday, May 22, 13
  310. > Run the Test ""pg_prove"*v"*d"flipr_test"test/appschema.sql test/appschema.sql".." 1..1 not"ok"1"*"Schema"nada"should"exist #"Failed"test"1:""Schema"nada"should"exist" #"Looks"like"you"failed"1"test"of"1

    Failed"1/1"subtests" Test"Summary"Report ******************* test/appschema.sql"(Wstat:"0"Tests:"1"Failed:"1) ""Failed"test:""1 Files=1,"Tests=1,""0"wallclock"secs Result:"FAIL 69 Wednesday, May 22, 13
  311. First Pass > 70 Wednesday, May 22, 13

  312. ""perl"*i"*pe"'s/nada/flipr/'"test/appschema.sql > First Pass > 70 Wednesday, May 22, 13

  313. ""perl"*i"*pe"'s/nada/flipr/'"test/appschema.sql > First Pass > >"pg_prove"*v"*d"flipr_test"test/appschema.sql"""" " test/appschema.sql".." 1..1 ok"1"*"Schema"flipr"should"exist

    ok All"tests"successful. Files=1,"Tests=1,""0"wallclock"secs Result:"PASS 70 Wednesday, May 22, 13
  314. ""perl"*i"*pe"'s/nada/flipr/'"test/appschema.sql > First Pass W00t! > >"pg_prove"*v"*d"flipr_test"test/appschema.sql"""" " test/appschema.sql".." 1..1

    ok"1"*"Schema"flipr"should"exist ok All"tests"successful. Files=1,"Tests=1,""0"wallclock"secs Result:"PASS 70 Wednesday, May 22, 13
  315. Pass it On > 71 Wednesday, May 22, 13

  316. ""git"add". > Pass it On > 71 Wednesday, May 22,

    13
  317. ""git"add". > ""git"commit"*m"'Add"appschema"test.' [master"e46bdf9]"Add"appschema"test. "1"file"changed,"14"insertions(+) "create"mode"100644"test/appschema.sql > Pass it On

    > 71 Wednesday, May 22, 13
  318. ""git"add". > ""git"commit"*m"'Add"appschema"test.' [master"e46bdf9]"Add"appschema"test. "1"file"changed,"14"insertions(+) "create"mode"100644"test/appschema.sql > Pass it On

    > ""git"push Counting"objects:"5,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(3/3),"done. Writing"objects:"100%"(4/4),"487"bytes,"done. Total"4"(delta"1),"reused"0"(delta"0) To"../flipr*remote """795697f..e46bdf9""master"*>"master > 71 Wednesday, May 22, 13
  319. OMG TAP WTF? The Test Anything Protocol (TAP) is a

    protocol to allow communication between unit tests and a test harness. It allows individual tests (TAP producers) to communicate test results to the testing harness in a language-agnostic way. —Wikipedia 72 Wednesday, May 22, 13
  320. What is TAP? antisocial network 73 Wednesday, May 22, 13

  321. What does that mean in practice? What is TAP? antisocial

    network 73 Wednesday, May 22, 13
  322. What does that mean in practice? Test output easy to

    interpret What is TAP? antisocial network 73 Wednesday, May 22, 13
  323. What does that mean in practice? Test output easy to

    interpret By humans What is TAP? antisocial network 73 Wednesday, May 22, 13
  324. What does that mean in practice? Test output easy to

    interpret By humans By computers What is TAP? antisocial network 73 Wednesday, May 22, 13
  325. What does that mean in practice? Test output easy to

    interpret By humans By computers pg_prove (the harness) What is TAP? antisocial network 73 Wednesday, May 22, 13
  326. What does that mean in practice? Test output easy to

    interpret By humans By computers pg_prove (the harness) By aliens What is TAP? antisocial network 73 Wednesday, May 22, 13
  327. What does that mean in practice? Test output easy to

    interpret By humans By computers pg_prove (the harness) By aliens By gum! What is TAP? antisocial network 73 Wednesday, May 22, 13
  328. What’s the plan, man? antisocial network 74 Wednesday, May 22,

    13
  329. What’s the plan, man? Includes Test controls: antisocial network 74

    Wednesday, May 22, 13
  330. What’s the plan, man? Includes Test controls: plan() — How

    many tests? antisocial network 74 Wednesday, May 22, 13
  331. What’s the plan, man? Includes Test controls: plan() — How

    many tests? no_plan() — Unknown number of tests antisocial network 74 Wednesday, May 22, 13
  332. What’s the plan, man? Includes Test controls: plan() — How

    many tests? no_plan() — Unknown number of tests diag() — Diagnostic output antisocial network 74 Wednesday, May 22, 13
  333. What’s the plan, man? Includes Test controls: plan() — How

    many tests? no_plan() — Unknown number of tests diag() — Diagnostic output finish() — Test finished, report! antisocial network 74 Wednesday, May 22, 13
  334. Scalarly antisocial network 75 Wednesday, May 22, 13

  335. Scalarly Includes simple scalar test functions: antisocial network 75 Wednesday,

    May 22, 13
  336. Scalarly Includes simple scalar test functions: ok() — Boolean antisocial

    network 75 Wednesday, May 22, 13
  337. Scalarly Includes simple scalar test functions: ok() — Boolean is()

    — Value comparison antisocial network 75 Wednesday, May 22, 13
  338. Scalarly Includes simple scalar test functions: ok() — Boolean is()

    — Value comparison isnt() — NOT is() antisocial network 75 Wednesday, May 22, 13
  339. Scalarly Includes simple scalar test functions: ok() — Boolean is()

    — Value comparison isnt() — NOT is() cmp_ok() — Compare with specific operator antisocial network 75 Wednesday, May 22, 13
  340. Scalarly Includes simple scalar test functions: ok() — Boolean is()

    — Value comparison isnt() — NOT is() cmp_ok() — Compare with specific operator matches() — Regex comparison antisocial network 75 Wednesday, May 22, 13
  341. Scalarly Includes simple scalar test functions: ok() — Boolean is()

    — Value comparison isnt() — NOT is() cmp_ok() — Compare with specific operator matches() — Regex comparison imatches() — Case-insensitive regex comparison antisocial network 75 Wednesday, May 22, 13
  342. It’s All Relative antisocial network 76 Wednesday, May 22, 13

  343. It’s All Relative Includes functions for testing relations: antisocial network

    76 Wednesday, May 22, 13
  344. It’s All Relative Includes functions for testing relations: results_eq() —

    Ordered results antisocial network 76 Wednesday, May 22, 13
  345. It’s All Relative Includes functions for testing relations: results_eq() —

    Ordered results set_eq() — Set of values antisocial network 76 Wednesday, May 22, 13
  346. It’s All Relative Includes functions for testing relations: results_eq() —

    Ordered results set_eq() — Set of values bag_eq() — Bag of values antisocial network 76 Wednesday, May 22, 13
  347. It’s All Relative Includes functions for testing relations: results_eq() —

    Ordered results set_eq() — Set of values bag_eq() — Bag of values row_eq() — Single row antisocial network 76 Wednesday, May 22, 13
  348. It’s All Relative Includes functions for testing relations: results_eq() —

    Ordered results set_eq() — Set of values bag_eq() — Bag of values row_eq() — Single row is_empty() — No results antisocial network 76 Wednesday, May 22, 13
  349. I’m Okay, You’re Okay antisocial network 77 Wednesday, May 22,

    13
  350. I’m Okay, You’re Okay throws_ok() — Throws an exception antisocial

    network 77 Wednesday, May 22, 13
  351. I’m Okay, You’re Okay throws_ok() — Throws an exception throws_like()

    — Exception matches regex antisocial network 77 Wednesday, May 22, 13
  352. I’m Okay, You’re Okay throws_ok() — Throws an exception throws_like()

    — Exception matches regex skip() — Skip a subset of tests antisocial network 77 Wednesday, May 22, 13
  353. I’m Okay, You’re Okay throws_ok() — Throws an exception throws_like()

    — Exception matches regex skip() — Skip a subset of tests todo() — Expect subset of tests to fail antisocial network 77 Wednesday, May 22, 13
  354. Schematics antisocial network 78 Wednesday, May 22, 13

  355. Schematics has_table(), has_view(), has_function(), etc. antisocial network 78 Wednesday, May

    22, 13
  356. Schematics has_table(), has_view(), has_function(), etc. columns_are(), has_pk(), fk_ok(), etc. antisocial

    network 78 Wednesday, May 22, 13
  357. Schematics has_table(), has_view(), has_function(), etc. columns_are(), has_pk(), fk_ok(), etc. col_type_is(),

    col_not_null(), col_default_is() antisocial network 78 Wednesday, May 22, 13
  358. Schematics has_table(), has_view(), has_function(), etc. columns_are(), has_pk(), fk_ok(), etc. col_type_is(),

    col_not_null(), col_default_is() So, so much more… antisocial network 78 Wednesday, May 22, 13
  359. Other Features and Topics antisocial network 79 Wednesday, May 22,

    13
  360. Other Features and Topics xUnit-Style testing antisocial network 79 Wednesday,

    May 22, 13
  361. Other Features and Topics xUnit-Style testing Test-Driven development antisocial network

    79 Wednesday, May 22, 13
  362. Other Features and Topics xUnit-Style testing Test-Driven development Integration with

    Perl unit tests antisocial network 79 Wednesday, May 22, 13
  363. Other Features and Topics xUnit-Style testing Test-Driven development Integration with

    Perl unit tests Integration with pg_regress antisocial network 79 Wednesday, May 22, 13
  364. Other Features and Topics xUnit-Style testing Test-Driven development Integration with

    Perl unit tests Integration with pg_regress Negative assertions antisocial network 79 Wednesday, May 22, 13
  365. Other Features and Topics xUnit-Style testing Test-Driven development Integration with

    Perl unit tests Integration with pg_regress Negative assertions Roles and privileges assertions antisocial network 79 Wednesday, May 22, 13
  366. Other Features and Topics xUnit-Style testing Test-Driven development Integration with

    Perl unit tests Integration with pg_regress Negative assertions Roles and privileges assertions http:/ /pgtap.org/ antisocial network 79 Wednesday, May 22, 13
  367. Other Features and Topics xUnit-Style testing Test-Driven development Integration with

    Perl unit tests Integration with pg_regress Negative assertions Roles and privileges assertions http:/ /pgtap.org/ http:/ /pgxn.org/extension/pgtap/ antisocial network 79 Wednesday, May 22, 13
  368. Other Features and Topics xUnit-Style testing Test-Driven development Integration with

    Perl unit tests Integration with pg_regress Negative assertions Roles and privileges assertions http:/ /pgtap.org/ http:/ /pgxn.org/extension/pgtap/ antisocial network 79 Wednesday, May 22, 13
  369. antisocial network Let’s do it! 80 Wednesday, May 22, 13

  370. antisocial network Let’s do it! Create appschema test 80 Wednesday,

    May 22, 13
  371. antisocial network Let’s do it! Create appschema test Use pgTAP

    80 Wednesday, May 22, 13
  372. antisocial network Let’s do it! Create appschema test Use pgTAP

    Run test with pg_prove 80 Wednesday, May 22, 13
  373. antisocial network Let’s do it! Create appschema test Use pgTAP

    Run test with pg_prove Make it fail 80 Wednesday, May 22, 13
  374. antisocial network Let’s do it! Create appschema test Use pgTAP

    Run test with pg_prove Make it fail Make it pass! 80 Wednesday, May 22, 13
  375. antisocial network Let’s do it! Create appschema test Use pgTAP

    Run test with pg_prove Make it fail Make it pass! Commit/Push 80 Wednesday, May 22, 13
  376. antisocial network Let’s do it! Create appschema test Use pgTAP

    Run test with pg_prove Make it fail Make it pass! Commit/Push https:/ /github.com/ theory/agile-flipr.git 80 Wednesday, May 22, 13
  377. Let’s talk about… antisocial network antisocial network antisocial network 81

    Wednesday, May 22, 13
  378. antisocial network antisocial network 82 Wednesday, May 22, 13

  379. TDD antisocial network antisocial network 82 Wednesday, May 22, 13

  380. 83 Wednesday, May 22, 13

  381. “The act of writing a unit test is more an

    act of design than of verification. It is also more an act of documentation than of verification. The act of writing a unit test closes a remarkable number of feedback loops, the least of which is the one per– taining to the verification of function.” —Robert C. Martin 83 Wednesday, May 22, 13
  382. antisocial network 84 Wednesday, May 22, 13

  383. TDD is an act of design. antisocial network 84 Wednesday,

    May 22, 13
  384. antisocial network 85 Wednesday, May 22, 13

  385. TDD is an act of documentation. antisocial network 85 Wednesday,

    May 22, 13
  386. antisocial network 86 Wednesday, May 22, 13

  387. Okay. antisocial network 86 Wednesday, May 22, 13

  388. antisocial network 87 Wednesday, May 22, 13

  389. But… antisocial network 87 Wednesday, May 22, 13

  390. Database Design antisocial network 88 Wednesday, May 22, 13

  391. Database Design Specify requirements antisocial network 88 Wednesday, May 22,

    13
  392. Database Design Specify requirements Implement schema design antisocial network 88

    Wednesday, May 22, 13
  393. Database Design Specify requirements Implement schema design Program applications antisocial

    network 88 Wednesday, May 22, 13
  394. Database Design Specify requirements Implement schema design Program applications QA

    antisocial network 88 Wednesday, May 22, 13
  395. Database Design Specify requirements Implement schema design Program applications QA

    Big jump! antisocial network 88 Wednesday, May 22, 13
  396. Database Design Specify requirements Implement schema design Program applications QA

    Pricy to fix antisocial network 88 Wednesday, May 22, 13
  397. Database Design Specify requirements Implement schema design Program applications QA

    Never mind bureaucracy of DBA department antisocial network 88 Wednesday, May 22, 13
  398. Why TDDD antisocial network 89 Wednesday, May 22, 13

  399. Why TDDD Ensure data quality antisocial network 89 Wednesday, May

    22, 13
  400. Why TDDD Ensure data quality Data is a core asset

    antisocial network 89 Wednesday, May 22, 13
  401. Why TDDD Ensure data quality Data is a core asset

    Validate business rules antisocial network 89 Wednesday, May 22, 13
  402. Why TDDD Ensure data quality Data is a core asset

    Validate business rules Stored procedures antisocial network 89 Wednesday, May 22, 13
  403. Why TDDD Ensure data quality Data is a core asset

    Validate business rules Stored procedures Triggers antisocial network 89 Wednesday, May 22, 13
  404. Why TDDD Ensure data quality Data is a core asset

    Validate business rules Stored procedures Triggers Views antisocial network 89 Wednesday, May 22, 13
  405. Why TDDD antisocial network 90 Wednesday, May 22, 13

  406. Why TDDD Identify defects early antisocial network 90 Wednesday, May

    22, 13
  407. Why TDDD Identify defects early …and often! antisocial network 90

    Wednesday, May 22, 13
  408. Why TDDD Identify defects early …and often! Create design iteratively

    antisocial network 90 Wednesday, May 22, 13
  409. Why TDDD Identify defects early …and often! Create design iteratively

    Evolutionarily antisocial network 90 Wednesday, May 22, 13
  410. Why TDDD Identify defects early …and often! Create design iteratively

    Evolutionarily Validate refactorings antisocial network 90 Wednesday, May 22, 13
  411. Why TDDD Identify defects early …and often! Create design iteratively

    Evolutionarily Validate refactorings Make sure nothing breaks antisocial network 90 Wednesday, May 22, 13
  412. Three Questions for Database Professionals from Scott Ambler antisocial network

    91 Wednesday, May 22, 13
  413. 92 Wednesday, May 22, 13

  414. “If you’re implementing code in the DB in the form

    of stored procedures, triggers... shouldn’t you test that code to the same level that you test your app code?” 92 Wednesday, May 22, 13
  415. 93 Wednesday, May 22, 13

  416. “Think of all the data quality problems you’ve run into

    over the years. Wouldn't it have been nice if someone had originally tested and discovered those problems before you did?” 93 Wednesday, May 22, 13
  417. 94 Wednesday, May 22, 13

  418. “Wouldn’t it be nice to have a test suite to

    run so that you could determine how (and if) the DB actually works?” 94 Wednesday, May 22, 13
  419. antisocial network 95 Wednesday, May 22, 13

  420. Okay. antisocial network 95 Wednesday, May 22, 13

  421. antisocial network 96 Wednesday, May 22, 13

  422. How? antisocial network 96 Wednesday, May 22, 13

  423. TDD How antisocial network 97 Wednesday, May 22, 13

  424. TDD How Ideally separate from app tests antisocial network 97

    Wednesday, May 22, 13
  425. TDD How Ideally separate from app tests May be many

    apps antisocial network 97 Wednesday, May 22, 13
  426. TDD How Ideally separate from app tests May be many

    apps DB should present interface to all antisocial network 97 Wednesday, May 22, 13
  427. TDD How Ideally separate from app tests May be many

    apps DB should present interface to all Apps may use different permissions antisocial network 97 Wednesday, May 22, 13
  428. TDD How Ideally separate from app tests May be many

    apps DB should present interface to all Apps may use different permissions Ideally use DB test Framework antisocial network 97 Wednesday, May 22, 13
  429. TDD How Ideally separate from app tests May be many

    apps DB should present interface to all Apps may use different permissions Ideally use DB test Framework Like…pgTAP! antisocial network 97 Wednesday, May 22, 13
  430. Branching Out > 98 Wednesday, May 22, 13

  431. ""git"checkout"*b"users"master Switched"to"a"new"branch"'users' > Branching Out > 98 Wednesday, May 22,

    13
  432. ""git"checkout"*b"users"master Switched"to"a"new"branch"'users' > Branching Out > Branched off from others

    98 Wednesday, May 22, 13
  433. ""git"checkout"*b"users"master Switched"to"a"new"branch"'users' > Branching Out > >"emacs"test/users.sql > 98 Wednesday,

    May 22, 13
  434. test/users.sql Table For One 99 Wednesday, May 22, 13

  435. SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; SELECT"no_plan(); SET"search_path"TO"flipr,public; SELECT"has_table("'users'"); SELECT"finish(); ROLLBACK; test/users.sql

    Table For One 99 Wednesday, May 22, 13
  436. SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; SELECT"no_plan(); SET"search_path"TO"flipr,public; SELECT"has_table("'users'"); SELECT"finish(); ROLLBACK; test/users.sql

    Table For One 99 Wednesday, May 22, 13
  437. SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; SELECT"no_plan(); SET"search_path"TO"flipr,public; SELECT"has_table("'users'"); SELECT"finish(); ROLLBACK; test/users.sql

    Table For One 99 Wednesday, May 22, 13
  438. SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; SELECT"no_plan(); SET"search_path"TO"flipr,public; SELECT"has_table("'users'"); SELECT"finish(); ROLLBACK; test/users.sql

    Table For One 99 Wednesday, May 22, 13
  439. Run ’Em > 100 Wednesday, May 22, 13

  440. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." not"ok"1"*"Table"users"should"exist #"Failed"test"1:""Table"users"should"exist" 1..1 #"Looks"like"you"failed"1"test"of"1 Failed"1/1"subtests" Test"Summary"Report ******************* test/users.sql"(Wstat:"0"Tests:"1"Failed:"1)

    ""Failed"test:""1 Files=1,"Tests=1,""0"wallclock"secs Result:"FAIL > Run ’Em > 100 Wednesday, May 22, 13
  441. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." not"ok"1"*"Table"users"should"exist #"Failed"test"1:""Table"users"should"exist" 1..1 #"Looks"like"you"failed"1"test"of"1 Failed"1/1"subtests" Test"Summary"Report ******************* test/users.sql"(Wstat:"0"Tests:"1"Failed:"1)

    ""Failed"test:""1 Files=1,"Tests=1,""0"wallclock"secs Result:"FAIL > Run ’Em > 100 Wednesday, May 22, 13
  442. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." not"ok"1"*"Table"users"should"exist #"Failed"test"1:""Table"users"should"exist" 1..1 #"Looks"like"you"failed"1"test"of"1 Failed"1/1"subtests" Test"Summary"Report ******************* test/users.sql"(Wstat:"0"Tests:"1"Failed:"1)

    ""Failed"test:""1 Files=1,"Tests=1,""0"wallclock"secs Result:"FAIL > Run ’Em As expected. > 100 Wednesday, May 22, 13
  443. Sqitch Dependencies! > 101 Wednesday, May 22, 13

  444. Sqitch Dependencies! > >"sqitch"add"users"**requires"appschema"\ ""*n"'Creates"table"to"track"our"users.' Created"deploy/users.sql Created"revert/users.sql Created"verify/users.sql Added""users"[appschema]""to"sqitch.plan >

    101 Wednesday, May 22, 13
  445. Sqitch Dependencies! > >"sqitch"add"users"**requires"appschema"\ ""*n"'Creates"table"to"track"our"users.' Created"deploy/users.sql Created"revert/users.sql Created"verify/users.sql Added""users"[appschema]""to"sqitch.plan >

    101 Wednesday, May 22, 13
  446. Sqitch Dependencies! > >"sqitch"add"users"**requires"appschema"\ ""*n"'Creates"table"to"track"our"users.' Created"deploy/users.sql Created"revert/users.sql Created"verify/users.sql Added""users"[appschema]""to"sqitch.plan >

    ""emacs"deploy/users.sql > 101 Wednesday, May 22, 13
  447. deploy/users.sq deploy/users.sql **"XXX"Add"DDLs"here. COMMIT; **"Deploy"users **"requires:"appschema BEGIN; 102 Wednesday, May

    22, 13
  448. deploy/users.sq deploy/users.sql **"XXX"Add"DDLs"here. COMMIT; **"Deploy"users **"requires:"appschema BEGIN; 102 Wednesday, May

    22, 13
  449. SET"client_min_messages"="'warning'; CREATE"TABLE"flipr.users"( """"nickname""TEXT ); deploy/users.sq deploy/users.sql COMMIT; **"Deploy"users **"requires:"appschema BEGIN;

    102 Wednesday, May 22, 13
  450. SET"client_min_messages"="'warning'; CREATE"TABLE"flipr.users"( """"nickname""TEXT ); deploy/users.sq deploy/users.sql COMMIT; **"Deploy"users **"requires:"appschema BEGIN;

    Bare Minimum 102 Wednesday, May 22, 13
  451. Verily, Users > >"sqitch"add"users"**requires"appschema"\ ""*n"'Creates"table"to"track"our"users.' Created"deploy/users.sql Created"revert/users.sql Created"verify/users.sql Added""users"[appschema]""to"sqitch.plan >"emacs"deploy/users.sql

    > 103 Wednesday, May 22, 13
  452. Verily, Users > >"sqitch"add"users"**requires"appschema"\ ""*n"'Creates"table"to"track"our"users.' Created"deploy/users.sql Created"revert/users.sql Created"verify/users.sql Added""users"[appschema]""to"sqitch.plan >"emacs"deploy/users.sql

    > ""emacs"verify/users.sql 103 Wednesday, May 22, 13
  453. **"Verify"users BEGIN; verify/users.sq verify/users.sql **"XXX"Add"verifications"here. ROLLBACK; 104 Wednesday, May 22,

    13
  454. **"Verify"users BEGIN; SELECT"nickname ""FROM"flipr.users "WHERE"FALSE; verify/users.sq verify/users.sql ROLLBACK; 104 Wednesday,

    May 22, 13
  455. Unusered > >"sqitch"add"users"**requires"appschema"\ ""*n"'Creates"table"to"track"our"users.' Created"deploy/users.sql Created"revert/users.sql Created"verify/users.sql Added""users"[appschema]""to"sqitch.plan >"emacs"deploy/users.sql >"emacs"verify/users.sql

    > 105 Wednesday, May 22, 13
  456. Unusered > >"sqitch"add"users"**requires"appschema"\ ""*n"'Creates"table"to"track"our"users.' Created"deploy/users.sql Created"revert/users.sql Created"verify/users.sql Added""users"[appschema]""to"sqitch.plan >"emacs"deploy/users.sql >"emacs"verify/users.sql

    > >"emacs"revert/users.sql 105 Wednesday, May 22, 13
  457. revert/users.sq revert/users.sql **"Revert"users BEGIN; COMMIT; **"XXX"Add"DDLs"here. 106 Wednesday, May 22,

    13
  458. revert/users.sq revert/users.sql **"Revert"users BEGIN; COMMIT; DROP"TABLE"flipr.users; 106 Wednesday, May 22,

    13
  459. Make Users > 107 Wednesday, May 22, 13

  460. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Make Users > 107 Wednesday, May

    22, 13
  461. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Make Users > 107 Wednesday, May

    22, 13
  462. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Make Users > ""psql"*d"flipr_test"*c"'\d"flipr.users' """""Table""flipr.users" ""Column""|"Type"|"Modifiers"

    **********+******+*********** "nickname"|"text"|" > 107 Wednesday, May 22, 13
  463. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Make Users > ""psql"*d"flipr_test"*c"'\d"flipr.users' """""Table""flipr.users" ""Column""|"Type"|"Modifiers"

    **********+******+*********** "nickname"|"text"|" > ""sqitch"verify Verifying"flipr_test ""*"appschema".."ok ""*"users"......"ok Verify"successful > 107 Wednesday, May 22, 13
  464. Make Users > 108 Wednesday, May 22, 13

  465. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." ok"1"*"Table"users"should"exist 1..1 ok All"tests"successful. Files=1,"Tests=1,""1"wallclock"secs Result:"PASS > Make

    Users > 108 Wednesday, May 22, 13
  466. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." ok"1"*"Table"users"should"exist 1..1 ok All"tests"successful. Files=1,"Tests=1,""1"wallclock"secs Result:"PASS > Make

    Users > 108 Wednesday, May 22, 13
  467. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." ok"1"*"Table"users"should"exist 1..1 ok All"tests"successful. Files=1,"Tests=1,""1"wallclock"secs Result:"PASS > Make

    Users > Woohoo! 108 Wednesday, May 22, 13
  468. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." ok"1"*"Table"users"should"exist 1..1 ok All"tests"successful. Files=1,"Tests=1,""1"wallclock"secs Result:"PASS > Make

    Users > ""emacs"test/users.sql > 108 Wednesday, May 22, 13
  469. SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; SELECT"no_plan(); SET"search_path"TO"flipr,public; SELECT"has_table("'users'"); test/users.sql Columnist SELECT"finish();

    ROLLBACK; 109 Wednesday, May 22, 13
  470. SELECT"has_column("'users',"'nickname'""); SELECT"has_column("'users',"'password'""); SELECT"has_column("'users',"'timestamp'"); SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; BEGIN; SELECT"no_plan(); SET"search_path"TO"flipr,public; SELECT"has_table("'users'");

    test/users.sql Columnist SELECT"finish(); ROLLBACK; 109 Wednesday, May 22, 13
  471. Dead Again > 110 Wednesday, May 22, 13

  472. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." ok"1"*"Table"users"should"exist ok"2"*"Column"users.nickname"should"exist not"ok"3"*"Column"users.password"should"exist #"Failed"test"3:""Column"users.password"should"exist" not"ok"4"*"Column"users."timestamp""should"exist #"Failed"test"4:""Column"users."timestamp""should"exist" 1..4 #"Looks"like"you"failed"2"tests"of"4

    Failed"2/4"subtests" Test"Summary"Report ******************* test/users.sql"(Wstat:"0"Tests:"4"Failed:"2) ""Failed"tests:""3*4 Files=1,"Tests=4,""0"wallclock"secs Result:"FAIL Dead Again > 110 Wednesday, May 22, 13
  473. ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".." ok"1"*"Table"users"should"exist ok"2"*"Column"users.nickname"should"exist not"ok"3"*"Column"users.password"should"exist #"Failed"test"3:""Column"users.password"should"exist" not"ok"4"*"Column"users."timestamp""should"exist #"Failed"test"4:""Column"users."timestamp""should"exist" 1..4 #"Looks"like"you"failed"2"tests"of"4

    Failed"2/4"subtests" Test"Summary"Report ******************* test/users.sql"(Wstat:"0"Tests:"4"Failed:"2) ""Failed"tests:""3*4 Files=1,"Tests=4,""0"wallclock"secs Result:"FAIL Dead Again > Guess we should add them. 110 Wednesday, May 22, 13
  474. MOAR Deploy > 111 Wednesday, May 22, 13

  475. >"emacs"deploy/users.sql > MOAR Deploy > 111 Wednesday, May 22, 13

  476. **"Deploy"users **"requires:"appschema BEGIN; SET"client_min_messages"="'warning'; CREATE"TABLE"flipr.users"( """"nickname""TEXT deploy/users.sq deploy/users.sql ); COMMIT;

    112 Wednesday, May 22, 13
  477. **"Deploy"users **"requires:"appschema BEGIN; SET"client_min_messages"="'warning'; CREATE"TABLE"flipr.users"( """"nickname""TEXT """""""""""""""""", """"password""TEXT, """"timestamp"TIMESTAMPTZ deploy/users.sq

    deploy/users.sql ); COMMIT; 112 Wednesday, May 22, 13
  478. >"emacs"deploy/users.sql > Update Verify > 113 Wednesday, May 22, 13

  479. >"emacs"deploy/users.sql > Update Verify > ""emacs"verify/users.sql > 113 Wednesday, May

    22, 13
  480. **"Verify"users BEGIN; SELECT"nickname ""FROM"flipr.users "WHERE"FALSE; COMMIT; verify/users.sq verify/users.sql 114 Wednesday,

    May 22, 13
  481. **"Verify"users BEGIN; SELECT"nickname ""FROM"flipr.users "WHERE"FALSE; COMMIT; ,"password,"timestamp verify/users.sq verify/users.sql 114

    Wednesday, May 22, 13
  482. Revert Overhead >"emacs"deploy/users.sql >"emacs"verify/users.sql > 115 Wednesday, May 22, 13

  483. Revert Overhead ""sqitch"revert"**to"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok > >"emacs"deploy/users.sql >"emacs"verify/users.sql > 115

    Wednesday, May 22, 13
  484. Revert Overhead ""sqitch"revert"**to"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok > Yes, really. >"emacs"deploy/users.sql >"emacs"verify/users.sql

    > 115 Wednesday, May 22, 13
  485. Revert Overhead ""sqitch"revert"**to"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok > >"emacs"deploy/users.sql >"emacs"verify/users.sql > 115

    Wednesday, May 22, 13
  486. Revert Overhead ""sqitch"revert"**to"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok > Remove >"emacs"deploy/users.sql >"emacs"verify/users.sql >

    115 Wednesday, May 22, 13
  487. Revert Overhead ""sqitch"revert"**to"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok > >"emacs"deploy/users.sql >"emacs"verify/users.sql > What’s

    that? 115 Wednesday, May 22, 13
  488. Sqitch Tags antisocial network 116 Wednesday, May 22, 13

  489. Sqitch Tags Start with @ antisocial network 116 Wednesday, May

    22, 13
  490. Sqitch Tags Start with @ To distinguish from changes antisocial

    network 116 Wednesday, May 22, 13
  491. Sqitch Tags Start with @ To distinguish from changes Two

    symbolic tags: antisocial network 116 Wednesday, May 22, 13
  492. Sqitch Tags Start with @ To distinguish from changes Two

    symbolic tags: @HEAD Last change antisocial network 116 Wednesday, May 22, 13
  493. Sqitch Tags Start with @ To distinguish from changes Two

    symbolic tags: @HEAD Last change @ROOT First change antisocial network 116 Wednesday, May 22, 13
  494. Sqitch Tags Start with @ To distinguish from changes Two

    symbolic tags: @HEAD Last change @ROOT First change Two modifiers: antisocial network 116 Wednesday, May 22, 13
  495. Sqitch Tags Start with @ To distinguish from changes Two

    symbolic tags: @HEAD Last change @ROOT First change Two modifiers: ^ Previous change antisocial network 116 Wednesday, May 22, 13
  496. Sqitch Tags Start with @ To distinguish from changes Two

    symbolic tags: @HEAD Last change @ROOT First change Two modifiers: ^ Previous change ~ Following change antisocial network 116 Wednesday, May 22, 13
  497. Specifying Changes antisocial network 117 Wednesday, May 22, 13

  498. Specifying Changes users Change named “users” antisocial network 117 Wednesday,

    May 22, 13
  499. Specifying Changes users Change named “users” @HEAD^ Second to last

    change antisocial network 117 Wednesday, May 22, 13
  500. Specifying Changes users Change named “users” @HEAD^ Second to last

    change users^ Change before users antisocial network 117 Wednesday, May 22, 13
  501. Specifying Changes users Change named “users” @HEAD^ Second to last

    change users^ Change before users @ROOT~ Second change antisocial network 117 Wednesday, May 22, 13
  502. Specifying Changes users Change named “users” @HEAD^ Second to last

    change users^ Change before users @ROOT~ Second change appschema~ Change after appschema antisocial network 117 Wednesday, May 22, 13
  503. Specifying Changes users Change named “users” @HEAD^ Second to last

    change users^ Change before users @ROOT~ Second change appschema~ Change after appschema @HEAD^^ Third to last change antisocial network 117 Wednesday, May 22, 13
  504. Specifying Changes users Change named “users” @HEAD^ Second to last

    change users^ Change before users @ROOT~ Second change appschema~ Change after appschema @HEAD^^ Third to last change users~4 4th change after users antisocial network 117 Wednesday, May 22, 13
  505. >""sqitch"revert"**to"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok > Whither Users > 118 Wednesday, May

    22, 13
  506. >""sqitch"revert"**to"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok > Whither Users > >"psql"*d"flipr_test"*c"'\d"flipr.users' Did"not"find"any"relation"named""flipr.users". >

    118 Wednesday, May 22, 13
  507. >""sqitch"revert"**to"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok > ""sqitch"status #"On"database"flipr_test #"Project:""flipr #"Change:"""748346dfe73cf2af32a8b7088fd75ad8d7aecda3 #"Name:"""""appschema #"Deployed:"2013*05*21"15:10:02"*0400

    #"By:"""""""David"E."Wheeler"<david@justatheory.com> #" Undeployed"change: ""*"users Whither Users > >"psql"*d"flipr_test"*c"'\d"flipr.users' Did"not"find"any"relation"named""flipr.users". > 118 Wednesday, May 22, 13
  508. Whither Users > 119 Wednesday, May 22, 13

  509. >"sqitch"verify Verifying"flipr_test ""*"appschema".."ok Undeployed"change: ""*"users Verify"successful > Whither Users >

    119 Wednesday, May 22, 13
  510. Back At It > 120 Wednesday, May 22, 13

  511. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Back At It > 120 Wednesday,

    May 22, 13
  512. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Back At It > Add 120

    Wednesday, May 22, 13
  513. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Back At It > ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".."

    ok"1"*"Table"users"should"exist ok"2"*"Column"users.nickname"should"exist ok"3"*"Column"users.password"should"exist ok"4"*"Column"users."timestamp""should"exist 1..4 ok All"tests"successful. Files=1,"Tests=4,""0"wallclock"secs Result:"PASS > 120 Wednesday, May 22, 13
  514. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Back At It > ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".."

    ok"1"*"Table"users"should"exist ok"2"*"Column"users.nickname"should"exist ok"3"*"Column"users.password"should"exist ok"4"*"Column"users."timestamp""should"exist 1..4 ok All"tests"successful. Files=1,"Tests=4,""0"wallclock"secs Result:"PASS > Woot! 120 Wednesday, May 22, 13
  515. ""sqitch"deploy Deploying"changes"to"flipr_test ""+"users".."ok > Back At It > ""pg_prove"*d"flipr_test"*v"test/users.sql test/users.sql".."

    ok"1"*"Table"users"should"exist ok"2"*"Column"users.nickname"should"exist ok"3"*"Column"users.password"should"exist ok"4"*"Column"users."timestamp""should"exist 1..4 ok All"tests"successful. Files=1,"Tests=4,""0"wallclock"secs Result:"PASS > ""emacs"verify/users.sql 120 Wednesday, May 22, 13
  516. SET"search_path"="public,tap; BEGIN; SELECT"*"FROM"no_plan(); SELECT"has_table(""'users'"); SELECT"has_column(""""""""'users',"'timestamp'"); test/users.sql SELECT"has_column(""""""""'users',"'nickname'"); SELECT"has_column(""""""""'users',"'password'"); SELECT"finish(); ROLLBACK;

    121 Wednesday, May 22, 13
  517. SET"search_path"="public,tap; BEGIN; SELECT"*"FROM"no_plan(); SELECT"has_table(""'users'"); SELECT"has_column(""""""""'users',"'timestamp'"); test/users.sql SELECT"has_column(""""""""'users',"'nickname'"); SELECT"has_column(""""""""'users',"'password'"); SELECT"has_pk("""""'users'"); SELECT"finish();

    ROLLBACK; 121 Wednesday, May 22, 13
  518. SELECT"col_type_is("""""""'users',"'nickname',"'text'"); SELECT"col_hasnt_default("'users',"'nickname'"); SELECT"col_is_pk("""""""""'users',"'nickname'"); SET"search_path"="public,tap; BEGIN; SELECT"*"FROM"no_plan(); SELECT"has_table(""'users'"); SELECT"has_column(""""""""'users',"'timestamp'"); test/users.sql SELECT"has_column(""""""""'users',"'nickname'");

    SELECT"has_column(""""""""'users',"'password'"); SELECT"has_pk("""""'users'"); SELECT"finish(); ROLLBACK; 121 Wednesday, May 22, 13
  519. SELECT"col_type_is("""""""'users',"'nickname',"'text'"); SELECT"col_hasnt_default("'users',"'nickname'"); SELECT"col_is_pk("""""""""'users',"'nickname'"); SET"search_path"="public,tap; BEGIN; SELECT"*"FROM"no_plan(); SELECT"has_table(""'users'"); SELECT"has_column(""""""""'users',"'timestamp'"); test/users.sql SELECT"has_column(""""""""'users',"'nickname'");

    SELECT"has_column(""""""""'users',"'password'"); SELECT"has_pk("""""'users'"); SELECT"col_type_is("""""""'users',"'password',"'text'"); SELECT"col_not_null(""""""'users',"'password'"); SELECT"col_hasnt_default("'users',"'password'"); SELECT"finish(); ROLLBACK; 121 Wednesday, May 22, 13
  520. SELECT"col_type_is("""""""'users',"'nickname',"'text'"); SELECT"col_hasnt_default("'users',"'nickname'"); SELECT"col_is_pk("""""""""'users',"'nickname'"); SET"search_path"="public,tap; BEGIN; SELECT"*"FROM"no_plan(); SELECT"has_table(""'users'"); SELECT"has_column(""""""""'users',"'timestamp'"); test/users.sql SELECT"has_column(""""""""'users',"'nickname'");

    SELECT"has_column(""""""""'users',"'password'"); SELECT"has_pk("""""'users'"); SELECT"col_type_is('users',"'timestamp',"'timestamp"with"time"zone'); SELECT"col_not_null(""""""'users',"'timestamp'"); SELECT"col_has_default("""'users',"'timestamp'"); SELECT"col_default_is(""""'users',"'timestamp',"'now()'"); SELECT"col_type_is("""""""'users',"'password',"'text'"); SELECT"col_not_null(""""""'users',"'password'"); SELECT"col_hasnt_default("'users',"'password'"); SELECT"finish(); ROLLBACK; 121 Wednesday, May 22, 13
  521. Columny > 122 Wednesday, May 22, 13

  522. >"pg_prove"*d"flipr_test"test/users.sql test/users.sql".."1/?" #"Failed"test"2:""Table"users"should"have"a"primary"key" #"Failed"test"6:""Column"users(nickname)"should"be"a"primary"key" #"""""""""have:"NULL #"""""""""want:"{nickname} #"Failed"test"9:""Column"users.password"should"be"NOT"NULL" #"Failed"test"13:""Column"users."timestamp""should"be"NOT"NULL" #"Failed"test"14:""Column"users."timestamp""should"have"a"default" #"Failed"test"15:""Column"users."timestamp""should"default"to"'now()'"

    #"""""Column"users."timestamp""has"no"default #"Looks"like"you"failed"6"tests"of"15 test/users.sql".."Failed"6/15"subtests" Test"Summary"Report ******************* test/users.sql"(Wstat:"0"Tests:"15"Failed:"6) ""Failed"tests:""2,"6,"9,"13*15 Files=1,"Tests=15,""0"wallclock"secs Result:"FAIL Columny > 122 Wednesday, May 22, 13
  523. >"pg_prove"*d"flipr_test"test/users.sql test/users.sql".."1/?" #"Failed"test"2:""Table"users"should"have"a"primary"key" #"Failed"test"6:""Column"users(nickname)"should"be"a"primary"key" #"""""""""have:"NULL #"""""""""want:"{nickname} #"Failed"test"9:""Column"users.password"should"be"NOT"NULL" #"Failed"test"13:""Column"users."timestamp""should"be"NOT"NULL" #"Failed"test"14:""Column"users."timestamp""should"have"a"default" #"Failed"test"15:""Column"users."timestamp""should"default"to"'now()'"

    #"""""Column"users."timestamp""has"no"default #"Looks"like"you"failed"6"tests"of"15 test/users.sql".."Failed"6/15"subtests" Test"Summary"Report ******************* test/users.sql"(Wstat:"0"Tests:"15"Failed:"6) ""Failed"tests:""2,"6,"9,"13*15 Files=1,"Tests=15,""0"wallclock"secs Result:"FAIL Columny > Let’s make it so. 122 Wednesday, May 22, 13
  524. User Typography > 123 Wednesday, May 22, 13

  525. ""emacs"deploy/users.sql > User Typography > 123 Wednesday, May 22, 13

  526. **"Deploy"users **"requires:"appschema BEGIN; SET"client_min_messages"="'warning'; CREATE"TABLE"flipr.users"( """"nickname""TEXT """"password""TEXT """"timestamp"TIMESTAMPTZ ); COMMIT;

    deploy/users.sq deploy/users.sql , , 124 Wednesday, May 22, 13
  527. **"Deploy"users **"requires:"appschema BEGIN; SET"client_min_messages"="'warning'; CREATE"TABLE"flipr.users"( """"nickname""TEXT """"password""TEXT """"timestamp"TIMESTAMPTZ ); COMMIT;

    deploy/users.sq deploy/users.sql , """"""""PRIMARY"KEY, 124 Wednesday, May 22, 13
  528. **"Deploy"users **"requires:"appschema BEGIN; SET"client_min_messages"="'warning'; CREATE"TABLE"flipr.users"( """"nickname""TEXT """"password""TEXT """"timestamp"TIMESTAMPTZ ); COMMIT;

    deploy/users.sq deploy/users.sql """"""""PRIMARY"KEY, """"""""NOT"NULL, 124 Wednesday, May 22, 13
  529. **"Deploy"users **"requires:"appschema BEGIN; SET"client_min_messages"="'warning'; CREATE"TABLE"flipr.users"( """"nickname""TEXT """"password""TEXT """"timestamp"TIMESTAMPTZ ); COMMIT;

    deploy/users.sq deploy/users.sql """"""""PRIMARY"KEY, """"""""NOT"NULL, "NOT"NULL"DEFAULT"NOW() 124 Wednesday, May 22, 13
  530. User Typography >"emacs"deploy/users.sql > 125 Wednesday, May 22, 13

  531. ""sqitch"rebase"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok Deploying"changes"to"flipr_test ""+"users".."ok > User Typography >"emacs"deploy/users.sql >

    125 Wednesday, May 22, 13
  532. ""sqitch"rebase"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok Deploying"changes"to"flipr_test ""+"users".."ok > User Typography >"emacs"deploy/users.sql >

    125 Wednesday, May 22, 13
  533. ""sqitch"rebase"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok Deploying"changes"to"flipr_test ""+"users".."ok > User Typography >"emacs"deploy/users.sql >

    125 Wednesday, May 22, 13
  534. ""sqitch"rebase"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok Deploying"changes"to"flipr_test ""+"users".."ok > User Typography >"emacs"deploy/users.sql >

    ""pg_prove"*d"flipr_test"test/users.sql test/users.sql".."ok"""" All"tests"successful. Files=1,"Tests=15,""0"wallclock"secs Result:"PASS > 125 Wednesday, May 22, 13
  535. ""sqitch"rebase"@HEAD^"*y Reverting"changes"to"appschema"from"flipr_test ""*"users".."ok Deploying"changes"to"flipr_test ""+"users".."ok > User Typography >"emacs"deploy/users.sql >

    ""pg_prove"*d"flipr_test"test/users.sql test/users.sql".."ok"""" All"tests"successful. Files=1,"Tests=15,""0"wallclock"secs Result:"PASS > Boom. 125 Wednesday, May 22, 13
  536. Additives > 126 Wednesday, May 22, 13

  537. Additives > ""git"add". > 126 Wednesday, May 22, 13

  538. Additives > ""git"add". > ""git"commit"*am"'Add"users"table.' [users"610b318]"Add"users"table. "5"files"changed,"59"insertions(+) "create"mode"100644"deploy/users.sql "create"mode"100644"revert/users.sql "create"mode"100644"test/users.sql

    "create"mode"100644"verify/users.sql > 126 Wednesday, May 22, 13
  539. Pushers > 127 Wednesday, May 22, 13

  540. Pushers > ""git"push"**set*upstream"origin"users Counting"objects:"17,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(11/11),"done. Writing"objects:"100%"(11/11),"1.53"KiB,"done. Total"11"(delta"1),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""users"*>"users

    Branch"users"set"up"to"track"remote"branch"users" from"origin. > 127 Wednesday, May 22, 13
  541. Pushers > ""git"push"**set*upstream"origin"users Counting"objects:"17,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(11/11),"done. Writing"objects:"100%"(11/11),"1.53"KiB,"done. Total"11"(delta"1),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""users"*>"users

    Branch"users"set"up"to"track"remote"branch"users" from"origin. > 127 Wednesday, May 22, 13
  542. Pushers > ""git"push"**set*upstream"origin"users Counting"objects:"17,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(11/11),"done. Writing"objects:"100%"(11/11),"1.53"KiB,"done. Total"11"(delta"1),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""users"*>"users

    Branch"users"set"up"to"track"remote"branch"users" from"origin. > 127 Wednesday, May 22, 13
  543. Wash, Rinse, Repeat antisocial network 128 Wednesday, May 22, 13

  544. Wash, Rinse, Repeat Add failing simple test antisocial network 128

    Wednesday, May 22, 13
  545. Wash, Rinse, Repeat Add failing simple test Add and deploy

    change antisocial network 128 Wednesday, May 22, 13
  546. Wash, Rinse, Repeat Add failing simple test Add and deploy

    change Revise test antisocial network 128 Wednesday, May 22, 13
  547. Wash, Rinse, Repeat Add failing simple test Add and deploy

    change Revise test Revise and rebase change antisocial network 128 Wednesday, May 22, 13
  548. Wash, Rinse, Repeat Add failing simple test Add and deploy

    change Revise test Revise and rebase change Wash, Rinse, Repeat antisocial network 128 Wednesday, May 22, 13
  549. Wash, Rinse, Repeat Add failing simple test Add and deploy

    change Revise test Revise and rebase change Wash, Rinse, Repeat Commit/Push when done antisocial network 128 Wednesday, May 22, 13
  550. Wash, Rinse, Repeat Add failing simple test Add and deploy

    change Revise test Revise and rebase change Wash, Rinse, Repeat Commit/Push when done Breathe in, breathe out antisocial network 128 Wednesday, May 22, 13
  551. Time to Work! antisocial network 129 Wednesday, May 22, 13

  552. Time to Work! Prepare to hack! antisocial network 129 Wednesday,

    May 22, 13
  553. Time to Work! Prepare to hack! git checkout master antisocial

    network 129 Wednesday, May 22, 13
  554. Time to Work! Prepare to hack! git checkout master git

    branch -D users antisocial network 129 Wednesday, May 22, 13
  555. Time to Work! Prepare to hack! git checkout master git

    branch -D users git checkout -b users antisocial network 129 Wednesday, May 22, 13
  556. Time to Work! Prepare to hack! git checkout master git

    branch -D users git checkout -b users git reset --hard upstream/users antisocial network 129 Wednesday, May 22, 13
  557. Time to Work! Prepare to hack! git checkout master git

    branch -D users git checkout -b users git reset --hard upstream/users git log antisocial network 129 Wednesday, May 22, 13
  558. Time to Work! Prepare to hack! git checkout master git

    branch -D users git checkout -b users git reset --hard upstream/users git log Should be at “Add users table.” antisocial network 129 Wednesday, May 22, 13
  559. Caution: Hard Reset Ahead 130 Wednesday, May 22, 13

  560. Caution: Hard Reset Ahead A rare destructive Git command 130

    Wednesday, May 22, 13
  561. Caution: Hard Reset Ahead A rare destructive Git command Deletes

    HEAD snapshot 130 Wednesday, May 22, 13
  562. Caution: Hard Reset Ahead A rare destructive Git command Deletes

    HEAD snapshot Replaces it with new snapshot 130 Wednesday, May 22, 13
  563. Caution: Hard Reset Ahead A rare destructive Git command Deletes

    HEAD snapshot Replaces it with new snapshot Almost un-reversible 130 Wednesday, May 22, 13
  564. Caution: Hard Reset Ahead A rare destructive Git command Deletes

    HEAD snapshot Replaces it with new snapshot Almost un-reversible Useful for starting from known point 130 Wednesday, May 22, 13
  565. Caution: Hard Reset Ahead A rare destructive Git command Deletes

    HEAD snapshot Replaces it with new snapshot Almost un-reversible Useful for starting from known point USE WITH CAUTION! 130 Wednesday, May 22, 13
  566. antisocial network Flip Out 131 Wednesday, May 22, 13

  567. antisocial network Flip Out Create flips branch 131 Wednesday, May

    22, 13
  568. antisocial network Flip Out Create flips branch Create flips table

    131 Wednesday, May 22, 13
  569. antisocial network Flip Out Create flips branch Create flips table

    flip_id SERIAL PK 131 Wednesday, May 22, 13
  570. antisocial network Flip Out Create flips branch Create flips table

    flip_id SERIAL PK nickname FK 131 Wednesday, May 22, 13
  571. antisocial network Flip Out Create flips branch Create flips table

    flip_id SERIAL PK nickname FK body TEXT 131 Wednesday, May 22, 13
  572. antisocial network Flip Out Create flips branch Create flips table

    flip_id SERIAL PK nickname FK body TEXT timestamptz 131 Wednesday, May 22, 13
  573. antisocial network Flip Out Create flips branch Create flips table

    flip_id SERIAL PK nickname FK body TEXT timestamptz Use TDDD 131 Wednesday, May 22, 13
  574. antisocial network Flip Out Create flips branch Create flips table

    flip_id SERIAL PK nickname FK body TEXT timestamptz Use TDDD https:/ /github.com/ theory/agile-flipr.git 131 Wednesday, May 22, 13
  575. Functional Testing > 132 Wednesday, May 22, 13

  576. Functional Testing ""git"checkout"*b"userfuncs"users Switched"to"a"new"branch"'userfuncs' > > Branches from users 132

    Wednesday, May 22, 13
  577. Functional Testing ""git"checkout"*b"userfuncs"users Switched"to"a"new"branch"'userfuncs' > > ""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"verify/insert_user.sql Added""insert_user"[users"appschema]""to"sqitch.plan > 132 Wednesday, May 22, 13
  578. Functional Testing ""git"checkout"*b"userfuncs"users Switched"to"a"new"branch"'userfuncs' > > ""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"verify/insert_user.sql Added""insert_user"[users"appschema]""to"sqitch.plan > ""emacs"test/insert_user.sql > 132 Wednesday, May 22, 13
  579. test/insert_use test/insert_user.sql 133 Wednesday, May 22, 13

  580. test/insert_use test/insert_user.sql SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; SET"search_path"TO"flipr,public; 133 Wednesday, May 22,

    13
  581. test/insert_use test/insert_user.sql SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; SET"search_path"TO"flipr,public; 133 Wednesday, May 22,

    13
  582. test/insert_use test/insert_user.sql SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; SET"search_path"TO"flipr,public; **"Plan"the"tests. BEGIN; select"plan(11); 133

    Wednesday, May 22, 13
  583. test/insert_use test/insert_user.sql SET"client_min_messages"TO"warning; CREATE"EXTENSION"IF"NOT"EXISTS"pgtap; RESET"client_min_messages; SET"search_path"TO"flipr,public; **"Plan"the"tests. BEGIN; select"plan(11); 133

    Wednesday, May 22, 13
  584. test/insert_use SELECT"plan(11); 134 Wednesday, May 22, 13

  585. test/insert_use SELECT"plan(11); SELECT"has_function("'insert_user'"); SELECT"has_function( """"'insert_user',"ARRAY['text',"'text'] ); SELECT"function_lang_is( """"'insert_user',"ARRAY['text',"'text'], """"'sql' );

    SELECT"function_returns( """"'insert_user',"ARRAY['text',"'text'], """"'void' ); SELECT"volatility_is( """"'insert_user',"ARRAY['text',"'text'], """"'volatile' ); 134 Wednesday, May 22, 13
  586. test/insert_use SELECT"plan(11); SELECT"has_function("'insert_user'"); SELECT"has_function( """"'insert_user',"ARRAY['text',"'text'] ); SELECT"function_lang_is( """"'insert_user',"ARRAY['text',"'text'], """"'sql' );

    SELECT"function_returns( """"'insert_user',"ARRAY['text',"'text'], """"'void' ); SELECT"volatility_is( """"'insert_user',"ARRAY['text',"'text'], """"'volatile' ); 134 Wednesday, May 22, 13
  587. test/insert_use SELECT"plan(11); SELECT"has_function("'insert_user'"); SELECT"has_function( """"'insert_user',"ARRAY['text',"'text'] ); SELECT"function_lang_is( """"'insert_user',"ARRAY['text',"'text'], """"'sql' );

    SELECT"function_returns( """"'insert_user',"ARRAY['text',"'text'], """"'void' ); SELECT"volatility_is( """"'insert_user',"ARRAY['text',"'text'], """"'volatile' ); 134 Wednesday, May 22, 13
  588. test/insert_use SELECT"plan(11); SELECT"has_function("'insert_user'"); SELECT"has_function( """"'insert_user',"ARRAY['text',"'text'] ); SELECT"function_lang_is( """"'insert_user',"ARRAY['text',"'text'], """"'sql' );

    SELECT"function_returns( """"'insert_user',"ARRAY['text',"'text'], """"'void' ); SELECT"volatility_is( """"'insert_user',"ARRAY['text',"'text'], """"'volatile' ); 134 Wednesday, May 22, 13
  589. test/insert_use SELECT"plan(11); SELECT"has_function("'insert_user'"); SELECT"has_function( """"'insert_user',"ARRAY['text',"'text'] ); SELECT"function_lang_is( """"'insert_user',"ARRAY['text',"'text'], """"'sql' );

    SELECT"function_returns( """"'insert_user',"ARRAY['text',"'text'], """"'void' ); SELECT"volatility_is( """"'insert_user',"ARRAY['text',"'text'], """"'volatile' ); 134 Wednesday, May 22, 13
  590. test/insert_use test/insert_user.sql """"'volatile' ); 135 Wednesday, May 22, 13

  591. test/insert_use test/insert_user.sql """"'volatile' ); SELECT"lives_ok( """"$$"SELECT"insert_user('theory',"'foo')"$$, """"'Insert"a"user' ); SELECT"row_eq( """'SELECT"*"FROM"users',

    """ROW('theory',"md5('foo'),"NOW())::users, """'The"user"should"have"been"inserted' ); 135 Wednesday, May 22, 13
  592. test/insert_use test/insert_user.sql """"'volatile' ); SELECT"lives_ok( """"$$"SELECT"insert_user('theory',"'foo')"$$, """"'Insert"a"user' ); SELECT"row_eq( """'SELECT"*"FROM"users',

    """ROW('theory',"md5('foo'),"NOW())::users, """'The"user"should"have"been"inserted' ); 135 Wednesday, May 22, 13
  593. test/insert_use test/insert_user.sql """"'volatile' ); SELECT"lives_ok( """"$$"SELECT"insert_user('theory',"'foo')"$$, """"'Insert"a"user' ); SELECT"row_eq( """'SELECT"*"FROM"users',

    """ROW('theory',"md5('foo'),"NOW())::users, """'The"user"should"have"been"inserted' ); 135 Wednesday, May 22, 13
  594. test/insert_use test/insert_user.sql """"'volatile' ); SELECT"lives_ok( """"$$"SELECT"insert_user('theory',"'foo')"$$, """"'Insert"a"user' ); SELECT"row_eq( """'SELECT"*"FROM"users',

    """ROW('theory',"md5('foo'),"NOW())::users, """'The"user"should"have"been"inserted' ); 135 Wednesday, May 22, 13
  595. test/insert_use test/insert_user.sql """"'volatile' ); SELECT"lives_ok( """"$$"SELECT"insert_user('theory',"'foo')"$$, """"'Insert"a"user' ); SELECT"row_eq( """'SELECT"*"FROM"users',

    """ROW('theory',"md5('foo'),"NOW())::users, """'The"user"should"have"been"inserted' ); 135 Wednesday, May 22, 13
  596. test/insert_use test/insert_user.sql """'The"user"should"have"been"inserted' ); 136 Wednesday, May 22, 13

  597. test/insert_use test/insert_user.sql """'The"user"should"have"been"inserted' ); SELECT"lives_ok( """"$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """"'Insert"another"user' ); SELECT"bag_eq( """"'SELECT"*"FROM"users',

    """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()), """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Both"users"should"be"present' ); 136 Wednesday, May 22, 13
  598. test/insert_use test/insert_user.sql """'The"user"should"have"been"inserted' ); SELECT"lives_ok( """"$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """"'Insert"another"user' ); SELECT"bag_eq( """"'SELECT"*"FROM"users',

    """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()), """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Both"users"should"be"present' ); 136 Wednesday, May 22, 13
  599. test/insert_use test/insert_user.sql """'The"user"should"have"been"inserted' ); SELECT"lives_ok( """"$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """"'Insert"another"user' ); SELECT"bag_eq( """"'SELECT"*"FROM"users',

    """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()), """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Both"users"should"be"present' ); Includes dupes 136 Wednesday, May 22, 13
  600. test/insert_use test/insert_user.sql """'The"user"should"have"been"inserted' ); SELECT"lives_ok( """"$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """"'Insert"another"user' ); SELECT"bag_eq( """"'SELECT"*"FROM"users',

    """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()), """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Both"users"should"be"present' ); 136 Wednesday, May 22, 13
  601. test/insert_use test/insert_user.sql """'The"user"should"have"been"inserted' ); SELECT"lives_ok( """"$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """"'Insert"another"user' ); SELECT"bag_eq( """"'SELECT"*"FROM"users',

    """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()), """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Both"users"should"be"present' ); 136 Wednesday, May 22, 13
  602. test/insert_use """"'Both"users"should"be"present' ); 137 Wednesday, May 22, 13

  603. SELECT"throws_ok( """"$$"SELECT"insert_user('theory',"'ha*ha')"$$, """"23505,"**"duplicate"key"violation """"NULL,""**"localized"error"message """"'Should"get"an"error"for"duplicate"nickname' ); SELECT"bag_eq( """"'SELECT"*"FROM"users', """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()),

    """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Should"still"have"just"the"two"users' ); test/insert_use """"'Both"users"should"be"present' ); 137 Wednesday, May 22, 13
  604. SELECT"throws_ok( """"$$"SELECT"insert_user('theory',"'ha*ha')"$$, """"23505,"**"duplicate"key"violation """"NULL,""**"localized"error"message """"'Should"get"an"error"for"duplicate"nickname' ); SELECT"bag_eq( """"'SELECT"*"FROM"users', """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()),

    """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Should"still"have"just"the"two"users' ); test/insert_use """"'Both"users"should"be"present' ); 137 Wednesday, May 22, 13
  605. SELECT"throws_ok( """"$$"SELECT"insert_user('theory',"'ha*ha')"$$, """"23505,"**"duplicate"key"violation """"NULL,""**"localized"error"message """"'Should"get"an"error"for"duplicate"nickname' ); SELECT"bag_eq( """"'SELECT"*"FROM"users', """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()),

    """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Should"still"have"just"the"two"users' ); test/insert_use """"'Both"users"should"be"present' ); Appendix A 137 Wednesday, May 22, 13
  606. SELECT"throws_ok( """"$$"SELECT"insert_user('theory',"'ha*ha')"$$, """"23505,"**"duplicate"key"violation """"NULL,""**"localized"error"message """"'Should"get"an"error"for"duplicate"nickname' ); SELECT"bag_eq( """"'SELECT"*"FROM"users', """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()),

    """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Should"still"have"just"the"two"users' ); test/insert_use """"'Both"users"should"be"present' ); 137 Wednesday, May 22, 13
  607. SELECT"throws_ok( """"$$"SELECT"insert_user('theory',"'ha*ha')"$$, """"23505,"**"duplicate"key"violation """"NULL,""**"localized"error"message """"'Should"get"an"error"for"duplicate"nickname' ); SELECT"bag_eq( """"'SELECT"*"FROM"users', """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()),

    """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Should"still"have"just"the"two"users' ); test/insert_use """"'Both"users"should"be"present' ); 137 Wednesday, May 22, 13
  608. SELECT"throws_ok( """"$$"SELECT"insert_user('theory',"'ha*ha')"$$, """"23505,"**"duplicate"key"violation """"NULL,""**"localized"error"message """"'Should"get"an"error"for"duplicate"nickname' ); SELECT"bag_eq( """"'SELECT"*"FROM"users', """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()),

    """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Should"still"have"just"the"two"users' ); test/insert_use """"'Both"users"should"be"present' ); 137 Wednesday, May 22, 13
  609. SELECT"throws_ok( """"$$"SELECT"insert_user('theory',"'ha*ha')"$$, """"23505,"**"duplicate"key"violation """"NULL,""**"localized"error"message """"'Should"get"an"error"for"duplicate"nickname' ); SELECT"bag_eq( """"'SELECT"*"FROM"users', """"$$"VALUES """"""""('theory',""""md5('foo'),""NOW()),

    """"""""('strongrrl',"md5('w00t'),"NOW()) """"$$, """"'Should"still"have"just"the"two"users' ); test/insert_use """"'Both"users"should"be"present' ); SELECT"finish(); ROLLBACK; 137 Wednesday, May 22, 13
  610. Functional Testing ""emacs"test/insert_user.sql > > 138 Wednesday, May 22, 13

  611. Functional Testing ""emacs"test/insert_user.sql > > ""emacs"deploy/insert_user.sql > 138 Wednesday, May

    22, 13
  612. deploy/insert_u deploy/insert_user.sql **"Deploy"insert_user **"requires:"users **"requires:"appschema BEGIN; **"XXX"Add"DDLs"here. COMMIT; 139 Wednesday,

    May 22, 13
  613. deploy/insert_u deploy/insert_user.sql **"Deploy"insert_user **"requires:"users **"requires:"appschema BEGIN; 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)); $$; COMMIT; 139 Wednesday, May 22, 13
  614. Functional Testing ""emacs"deploy/insert_user.sql > > 140 Wednesday, May 22, 13

  615. Functional Testing ""emacs"deploy/insert_user.sql > > ""emacs"revert/insert_user.sql > 140 Wednesday, May

    22, 13
  616. revert/insert_u revert/insert_user.sql **"Revert"insert_user BEGIN; COMMIT; **"XXX"Add"DDLs"here. 141 Wednesday, May 22,

    13
  617. revert/insert_u revert/insert_user.sql **"Revert"insert_user BEGIN; COMMIT; DROP"FUNCTION"flipr.insert_user(TEXT,"TEXT); 141 Wednesday, May 22,

    13
  618. Functional Testing ""emacs"revert/insert_user.sql > > 142 Wednesday, May 22, 13

  619. Functional Testing ""emacs"revert/insert_user.sql > > ""emacs"verify/insert_user.sql > 142 Wednesday, May

    22, 13
  620. verify/insert_u verify/insert_user.sql **"Verify"insert_user BEGIN; **"XXX"Add"DDLs"here. ROLLBACK; 143 Wednesday, May 22,

    13
  621. verify/insert_u verify/insert_user.sql **"Verify"insert_user BEGIN; SELECT"has_function_privilege( """"'flipr.insert_user(text,"text)', """"'execute' ); ROLLBACK; 143

    Wednesday, May 22, 13
  622. verify/insert_u verify/insert_user.sql **"Verify"insert_user BEGIN; SELECT"has_function_privilege( """"'flipr.insert_user(text,"text)', """"'execute' ); ROLLBACK; Convenient!

    143 Wednesday, May 22, 13
  623. We Good? ""emacs"verify/insert_user.sql > > 144 Wednesday, May 22, 13

  624. We Good? ""emacs"verify/insert_user.sql > > ""pg_prove"*d"flipr_test"test/*.sql"""""""""" test/appschema.sql"...."ok""" test/insert_user.sql".."ok""""" test/users.sql"........"ok"""" All"tests"successful.

    Files=3,"Tests=27,""0"wallclock"secs Result:"PASS > 144 Wednesday, May 22, 13
  625. Commitment > 145 Wednesday, May 22, 13

  626. ""git"add". >"git"commit"*m"'Add"`insert_user()`.' [userfuncs"40eabe1]"Add"`insert_user()`. "6"files"changed,"101"insertions(+) "create"mode"100644"*n "create"mode"100644"deploy/insert_user.sql "create"mode"100644"revert/insert_user.sql "create"mode"100644"test/insert_user.sql "create"mode"100644"verify/insert_user.sql >

    Commitment > 145 Wednesday, May 22, 13
  627. Push It Real Good… > 146 Wednesday, May 22, 13

  628. ""git"push"origin"**set*upstream"userfuncs Counting"objects:"18,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(11/11),"done. Writing"objects:"100%"(12/12),"1.96"KiB,"done. Total"12"(delta"1),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""userfuncs"*>"userfuncs Branch"userfuncs"set"up"to"track"remote"branch" userfuncs"from"origin.

    > Push It Real Good… > 146 Wednesday, May 22, 13
  629. ""git"push"origin"**set*upstream"userfuncs Counting"objects:"18,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(11/11),"done. Writing"objects:"100%"(12/12),"1.96"KiB,"done. Total"12"(delta"1),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""userfuncs"*>"userfuncs Branch"userfuncs"set"up"to"track"remote"branch" userfuncs"from"origin.

    > Push It Real Good… > 146 Wednesday, May 22, 13
  630. ""git"push"origin"**set*upstream"userfuncs Counting"objects:"18,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(11/11),"done. Writing"objects:"100%"(12/12),"1.96"KiB,"done. Total"12"(delta"1),"reused"0"(delta"0) To"../flipr*remote "*"[new"branch]""""""userfuncs"*>"userfuncs Branch"userfuncs"set"up"to"track"remote"branch" userfuncs"from"origin.

    > Push It Real Good… > 146 Wednesday, May 22, 13
  631. Reset, Mes Amis! antisocial network 147 Wednesday, May 22, 13

  632. Reset, Mes Amis! git checkout users antisocial network 147 Wednesday,

    May 22, 13
  633. Reset, Mes Amis! git checkout users git reset --hard upstream/users

    antisocial network 147 Wednesday, May 22, 13
  634. Reset, Mes Amis! git checkout users git reset --hard upstream/users

    git checkout -b userfuncs antisocial network 147 Wednesday, May 22, 13
  635. Reset, Mes Amis! git checkout users git reset --hard upstream/users

    git checkout -b userfuncs git reset --hard insert_user antisocial network 147 Wednesday, May 22, 13
  636. antisocial network None Shall Pass 148 Wednesday, May 22, 13

  637. antisocial network None Shall Pass Create change_pass() 148 Wednesday, May

    22, 13
  638. antisocial network None Shall Pass Create change_pass() Params: 148 Wednesday,

    May 22, 13
  639. antisocial network None Shall Pass Create change_pass() Params: nickname 148

    Wednesday, May 22, 13
  640. antisocial network None Shall Pass Create change_pass() Params: nickname old_pass

    148 Wednesday, May 22, 13
  641. antisocial network None Shall Pass Create change_pass() Params: nickname old_pass

    new_pass 148 Wednesday, May 22, 13
  642. antisocial network None Shall Pass Create change_pass() Params: nickname old_pass

    new_pass Only update if old pass correct 148 Wednesday, May 22, 13
  643. antisocial network None Shall Pass Create change_pass() Params: nickname old_pass

    new_pass Only update if old pass correct Use TDDD 148 Wednesday, May 22, 13
  644. antisocial network None Shall Pass Create change_pass() Params: nickname old_pass

    new_pass Only update if old pass correct Use TDDD https:/ /github.com/ theory/agile-flipr.git 148 Wednesday, May 22, 13
  645. Resets > 149 Wednesday, May 22, 13

  646. >"git"reset"**hard"upstream/userfuncs HEAD"is"now"at"048017a"Add"`change_pass()`. > Resets > My solution 149 Wednesday, May

    22, 13
  647. >"git"reset"**hard"upstream/userfuncs HEAD"is"now"at"048017a"Add"`change_pass()`. > >"git"checkout"master > Resets > 149 Wednesday, May

    22, 13
  648. >"git"reset"**hard"upstream/userfuncs HEAD"is"now"at"048017a"Add"`change_pass()`. > ""git"reset"**hard"appschema HEAD"is"now"at"e46bdf9"Add"appschema"test. > >"git"checkout"master > Resets >

    149 Wednesday, May 22, 13
  649. >"git"reset"**hard"upstream/userfuncs HEAD"is"now"at"048017a"Add"`change_pass()`. > ""git"reset"**hard"appschema HEAD"is"now"at"e46bdf9"Add"appschema"test. > >"git"checkout"master > Resets >

    Known good. 149 Wednesday, May 22, 13
  650. Mergers and Acquisitions > 150 Wednesday, May 22, 13

  651. ""git"merge"users"""""""""""""""""""""""""""""""""""""""""" Updating"e46bdf9..610b318 Fast*forward "deploy/users.sql"|"13"+++++++++++++ "revert/users.sql"|""7"+++++++ "sqitch.plan""""""|""1"+ "test/users.sql"""|"29"+++++++++++++++++++++++++++++ "verify/users.sql"|""9"+++++++++ "5"files"changed,"59"insertions(+) "create"mode"100644"deploy/users.sql

    "create"mode"100644"revert/users.sql "create"mode"100644"test/users.sql "create"mode"100644"verify/users.sql > Mergers and Acquisitions > 150 Wednesday, May 22, 13
  652. ""git"merge"users"""""""""""""""""""""""""""""""""""""""""" Updating"e46bdf9..610b318 Fast*forward "deploy/users.sql"|"13"+++++++++++++ "revert/users.sql"|""7"+++++++ "sqitch.plan""""""|""1"+ "test/users.sql"""|"29"+++++++++++++++++++++++++++++ "verify/users.sql"|""9"+++++++++ "5"files"changed,"59"insertions(+) "create"mode"100644"deploy/users.sql

    "create"mode"100644"revert/users.sql "create"mode"100644"test/users.sql "create"mode"100644"verify/users.sql > Mergers and Acquisitions > So far… 150 Wednesday, May 22, 13
  653. Mergers and Acquisitions > 151 Wednesday, May 22, 13

  654. >"git"merge"flips"""""""""""""""""""""""""""""""""""""""""" Updating"610b318..fbf8469 Fast*forward "deploy/flips.sql"|"15"+++++++++++++++ "revert/flips.sql"|""7"+++++++ "sqitch.plan""""""|""1"+ "test/flips.sql"""|"38"+++++++++++++++++++++++++++++++++++++ "verify/flips.sql"|"12"++++++++++++ "5"files"changed,"73"insertions(+) "create"mode"100644"deploy/flips.sql

    "create"mode"100644"revert/flips.sql "create"mode"100644"test/flips.sql "create"mode"100644"verify/flips.sql > Mergers and Acquisitions > 151 Wednesday, May 22, 13
  655. >"git"merge"flips"""""""""""""""""""""""""""""""""""""""""" Updating"610b318..fbf8469 Fast*forward "deploy/flips.sql"|"15"+++++++++++++++ "revert/flips.sql"|""7"+++++++ "sqitch.plan""""""|""1"+ "test/flips.sql"""|"38"+++++++++++++++++++++++++++++++++++++ "verify/flips.sql"|"12"++++++++++++ "5"files"changed,"73"insertions(+) "create"mode"100644"deploy/flips.sql

    "create"mode"100644"revert/flips.sql "create"mode"100644"test/flips.sql "create"mode"100644"verify/flips.sql > Mergers and Acquisitions > So good… 151 Wednesday, May 22, 13
  656. Mergers and Acquisitions > 152 Wednesday, May 22, 13

  657. >"git"merge"userfuncs Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Automatic"merge"failed;"fix"conflicts"and"then" commit"the"result. > Mergers and Acquisitions >

    152 Wednesday, May 22, 13
  658. >"git"merge"userfuncs Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Automatic"merge"failed;"fix"conflicts"and"then" commit"the"result. > Mergers and Acquisitions >

    152 Wednesday, May 22, 13
  659. >"git"merge"userfuncs Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Automatic"merge"failed;"fix"conflicts"and"then" commit"the"result. > Mergers and Acquisitions >

    152 Wednesday, May 22, 13
  660. >"git"merge"userfuncs Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Automatic"merge"failed;"fix"conflicts"and"then" commit"the"result. > Mergers and Acquisitions >

    Wha??? 152 Wednesday, May 22, 13
  661. Back in Time… > 153 Wednesday, May 22, 13

  662. Back in Time… ""git"checkout"*b"userfuncs"users Switched"to"a"new"branch"'userfuncs' > > 153 Wednesday, May

    22, 13
  663. Back in Time… ""git"checkout"*b"userfuncs"users Switched"to"a"new"branch"'userfuncs' > > Ah-ha! 153 Wednesday,

    May 22, 13
  664. Branching Out antisocial network 154 Wednesday, May 22, 13

  665. Branching Out users branched from master antisocial network 154 Wednesday,

    May 22, 13
  666. Branching Out users branched from master flips branched from users

    antisocial network 154 Wednesday, May 22, 13
  667. Branching Out users branched from master flips branched from users

    userfuncs branched from users antisocial network 154 Wednesday, May 22, 13
  668. Branching Out users branched from master flips branched from users

    userfuncs branched from users users and flips merged to master antisocial network 154 Wednesday, May 22, 13
  669. Branching Out users branched from master flips branched from users

    userfuncs branched from users users and flips merged to master userfuncs unaware of flips antisocial network 154 Wednesday, May 22, 13
  670. Backbrancher master A 155 Wednesday, May 22, 13

  671. Backbrancher master users A branch 155 Wednesday, May 22, 13

  672. Backbrancher master users A B Add users table branch 155

    Wednesday, May 22, 13
  673. Backbrancher master users A B flips branch branch 155 Wednesday,

    May 22, 13
  674. Backbrancher master users A B flips C Add flips table

    branch branch 155 Wednesday, May 22, 13
  675. Backbrancher master users A B flips C userfuncs branch branch

    branch 155 Wednesday, May 22, 13
  676. Backbrancher master users A B flips C userfuncs Add insert_user

    function D branch branch branch 155 Wednesday, May 22, 13
  677. Backbrancher master users A B flips C userfuncs D branch

    branch branch E Add change_pass function 155 Wednesday, May 22, 13
  678. Backbrancher master users A B flips C userfuncs B merge

    B D branch branch branch E 155 Wednesday, May 22, 13
  679. Backbrancher master users A B flips C userfuncs B merge

    B C merge C D branch branch branch E 155 Wednesday, May 22, 13
  680. Backbrancher master users A B flips C userfuncs B merge

    B C merge C D F merge D & E branch branch branch E 155 Wednesday, May 22, 13
  681. Backbrancher master users A B flips C userfuncs B merge

    B C merge C D No C! F merge D & E branch branch branch E 155 Wednesday, May 22, 13
  682. Backbrancher master users A B flips C userfuncs B merge

    B C merge C D conflict! branch branch branch E 155 Wednesday, May 22, 13
  683. Backbrancher master users A B flips C userfuncs B merge

    B C merge C D conflict! Now what? branch branch branch E 155 Wednesday, May 22, 13
  684. Rebase master master users A B flips C userfuncs B

    merge B C merge C branch branch branch D E 156 Wednesday, May 22, 13
  685. Rebase master master users A B flips C userfuncs B

    merge B C merge C branch branch branch Last common with master: B 156 Wednesday, May 22, 13
  686. Rebase master master users A B flips C userfuncs B

    merge B C merge C branch branch branch C 156 Wednesday, May 22, 13
  687. Rebase master master users A B flips C userfuncs B

    merge B C merge C branch branch branch C D Rebased E 156 Wednesday, May 22, 13
  688. Rebase master master users A B flips C userfuncs B

    merge B C merge C branch branch branch C D E merge D & E E 156 Wednesday, May 22, 13
  689. \o/ Rebase master master users A B flips C userfuncs

    B merge B C merge C branch branch branch C D E merge D & E E 156 Wednesday, May 22, 13
  690. Reset > 157 Wednesday, May 22, 13

  691. ""git"reset"**hard"HEAD HEAD"is"now"at"fbf8469"Add"flips"table. > Reset > 157 Wednesday, May 22, 13

  692. ""git"reset"**hard"HEAD HEAD"is"now"at"fbf8469"Add"flips"table. > Reset > Use with care! 157 Wednesday,

    May 22, 13
  693. ""git"reset"**hard"HEAD HEAD"is"now"at"fbf8469"Add"flips"table. > Reset > 157 Wednesday, May 22, 13

  694. ""git"reset"**hard"HEAD HEAD"is"now"at"fbf8469"Add"flips"table. > Reset > ""git"checkout"userfuncs Switched"to"branch"'userfuncs' > 157 Wednesday,

    May 22, 13
  695. Rebase > 158 Wednesday, May 22, 13

  696. >"git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Failed"to"merge"in"the"changes.

    Patch"failed"at"0001"Add"`insert_user()`. The"copy"of"the"patch"that"failed"is"found"in: """/Users/david/Desktop/flipr*db/.git/rebase*apply/patch When"you"have"resolved"this"problem,"run""git"rebase"**contin If"you"prefer"to"skip"this"patch,"run""git"rebase"**skip""ins To"check"out"the"original"branch"and"stop"rebasing,"run""git" rebase"**abort". > Rebase > 158 Wednesday, May 22, 13
  697. >"git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Failed"to"merge"in"the"changes.

    Patch"failed"at"0001"Add"`insert_user()`. The"copy"of"the"patch"that"failed"is"found"in: """/Users/david/Desktop/flipr*db/.git/rebase*apply/patch When"you"have"resolved"this"problem,"run""git"rebase"**contin If"you"prefer"to"skip"this"patch,"run""git"rebase"**skip""ins To"check"out"the"original"branch"and"stop"rebasing,"run""git" rebase"**abort". > Rebase > Back to B, apply C. 158 Wednesday, May 22, 13
  698. >"git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Failed"to"merge"in"the"changes.

    Patch"failed"at"0001"Add"`insert_user()`. The"copy"of"the"patch"that"failed"is"found"in: """/Users/david/Desktop/flipr*db/.git/rebase*apply/patch When"you"have"resolved"this"problem,"run""git"rebase"**contin If"you"prefer"to"skip"this"patch,"run""git"rebase"**skip""ins To"check"out"the"original"branch"and"stop"rebasing,"run""git" rebase"**abort". > Rebase > That’s D 158 Wednesday, May 22, 13
  699. >"git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Failed"to"merge"in"the"changes.

    Patch"failed"at"0001"Add"`insert_user()`. The"copy"of"the"patch"that"failed"is"found"in: """/Users/david/Desktop/flipr*db/.git/rebase*apply/patch When"you"have"resolved"this"problem,"run""git"rebase"**contin If"you"prefer"to"skip"this"patch,"run""git"rebase"**skip""ins To"check"out"the"original"branch"and"stop"rebasing,"run""git" rebase"**abort". > Rebase > Here comes D… 158 Wednesday, May 22, 13
  700. >"git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Failed"to"merge"in"the"changes.

    Patch"failed"at"0001"Add"`insert_user()`. The"copy"of"the"patch"that"failed"is"found"in: """/Users/david/Desktop/flipr*db/.git/rebase*apply/patch When"you"have"resolved"this"problem,"run""git"rebase"**contin If"you"prefer"to"skip"this"patch,"run""git"rebase"**skip""ins To"check"out"the"original"branch"and"stop"rebasing,"run""git" rebase"**abort". > Rebase > D’oh! 158 Wednesday, May 22, 13
  701. >"git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan CONFLICT"(content):"Merge"conflict"in"sqitch.plan Failed"to"merge"in"the"changes.

    Patch"failed"at"0001"Add"`insert_user()`. The"copy"of"the"patch"that"failed"is"found"in: """/Users/david/Desktop/flipr*db/.git/rebase*apply/patch When"you"have"resolved"this"problem,"run""git"rebase"**contin If"you"prefer"to"skip"this"patch,"run""git"rebase"**skip""ins To"check"out"the"original"branch"and"stop"rebasing,"run""git" rebase"**abort". > Rebase > 158 Wednesday, May 22, 13
  702. Wha Happen? antisocial network 159 Wednesday, May 22, 13

  703. Wha Happen? Same conflict antisocial network 159 Wednesday, May 22,

    13
  704. Wha Happen? Same conflict Both branches modified sqitch.plan antisocial network

    159 Wednesday, May 22, 13
  705. Wha Happen? Same conflict Both branches modified sqitch.plan The same

    line! antisocial network 159 Wednesday, May 22, 13
  706. Wha Happen? > 160 Wednesday, May 22, 13

  707. >"git"diff diff"**cc"sqitch.plan index"0d5a515,96b1b7e..0000000 ***"a/sqitch.plan +++"b/sqitch.plan @@@"*4,4"*4,4"+4,8"@@@ "" ""appschema"2013*05*15T06:03:09Z"David"E."Wheeler"<d ""users"[appschema]"2013*05*17T04:59:01Z"David"E."Wh ++<<<<<<<"HEAD

    ""flips"[appschema"users]"2013*05*18T00:04:56Z"David ++======= +"insert_user"[users"appschema]"2013*05*20T20:53:56Z ++>>>>>>>"Add"`insert_user()`. > Wha Happen? > 160 Wednesday, May 22, 13
  708. >"git"diff diff"**cc"sqitch.plan index"0d5a515,96b1b7e..0000000 ***"a/sqitch.plan +++"b/sqitch.plan @@@"*4,4"*4,4"+4,8"@@@ "" ""appschema"2013*05*15T06:03:09Z"David"E."Wheeler"<d ""users"[appschema]"2013*05*17T04:59:01Z"David"E."Wh ++<<<<<<<"HEAD

    ""flips"[appschema"users]"2013*05*18T00:04:56Z"David ++======= +"insert_user"[users"appschema]"2013*05*20T20:53:56Z ++>>>>>>>"Add"`insert_user()`. > Wha Happen? > 160 Wednesday, May 22, 13
  709. >"git"diff diff"**cc"sqitch.plan index"0d5a515,96b1b7e..0000000 ***"a/sqitch.plan +++"b/sqitch.plan @@@"*4,4"*4,4"+4,8"@@@ "" ""appschema"2013*05*15T06:03:09Z"David"E."Wheeler"<d ""users"[appschema]"2013*05*17T04:59:01Z"David"E."Wh ++<<<<<<<"HEAD

    ""flips"[appschema"users]"2013*05*18T00:04:56Z"David ++======= +"insert_user"[users"appschema]"2013*05*20T20:53:56Z ++>>>>>>>"Add"`insert_user()`. > Wha Happen? > B 160 Wednesday, May 22, 13
  710. >"git"diff diff"**cc"sqitch.plan index"0d5a515,96b1b7e..0000000 ***"a/sqitch.plan +++"b/sqitch.plan @@@"*4,4"*4,4"+4,8"@@@ "" ""appschema"2013*05*15T06:03:09Z"David"E."Wheeler"<d ""users"[appschema]"2013*05*17T04:59:01Z"David"E."Wh ++<<<<<<<"HEAD

    ""flips"[appschema"users]"2013*05*18T00:04:56Z"David ++======= +"insert_user"[users"appschema]"2013*05*20T20:53:56Z ++>>>>>>>"Add"`insert_user()`. > Wha Happen? > C B 160 Wednesday, May 22, 13
  711. >"git"diff diff"**cc"sqitch.plan index"0d5a515,96b1b7e..0000000 ***"a/sqitch.plan +++"b/sqitch.plan @@@"*4,4"*4,4"+4,8"@@@ "" ""appschema"2013*05*15T06:03:09Z"David"E."Wheeler"<d ""users"[appschema]"2013*05*17T04:59:01Z"David"E."Wh ++<<<<<<<"HEAD

    ""flips"[appschema"users]"2013*05*18T00:04:56Z"David ++======= +"insert_user"[users"appschema]"2013*05*20T20:53:56Z ++>>>>>>>"Add"`insert_user()`. > Wha Happen? > C D B 160 Wednesday, May 22, 13
  712. Scratch that Sqitch antisocial network 161 Wednesday, May 22, 13

  713. Scratch that Sqitch Screwed either way? antisocial network 161 Wednesday,

    May 22, 13
  714. Scratch that Sqitch Screwed either way? Fortunately, this is Git

    antisocial network 161 Wednesday, May 22, 13
  715. Scratch that Sqitch Screwed either way? Fortunately, this is Git

    Tell it to treat Sqitch plans differently antisocial network 161 Wednesday, May 22, 13
  716. Scratch that Sqitch Screwed either way? Fortunately, this is Git

    Tell it to treat Sqitch plans differently Changes on single lines antisocial network 161 Wednesday, May 22, 13
  717. Scratch that Sqitch Screwed either way? Fortunately, this is Git

    Tell it to treat Sqitch plans differently Changes on single lines Only appended to plan file antisocial network 161 Wednesday, May 22, 13
  718. Scratch that Sqitch Screwed either way? Fortunately, this is Git

    Tell it to treat Sqitch plans differently Changes on single lines Only appended to plan file Use the “union” merge antisocial network 161 Wednesday, May 22, 13
  719. Re: Union Merge 162 Wednesday, May 22, 13

  720. Re: Union Merge Run 3-way file level merge for text

    files, but take lines from both versions, instead of leaving conflict markers. This tends to leave the added lines in the resulting file in random order and the user should verify the result. Do not use this if you do not understand the implications. —Git Manual 162 Wednesday, May 22, 13
  721. Hallelunion antisocial network 163 Wednesday, May 22, 13

  722. Hallelunion Just appends lines antisocial network 163 Wednesday, May 22,

    13
  723. Hallelunion Just appends lines Exactly how changes work antisocial network

    163 Wednesday, May 22, 13
  724. Hallelunion Just appends lines Exactly how changes work Let’s clean

    up our mess antisocial network 163 Wednesday, May 22, 13
  725. Hallelunion Just appends lines Exactly how changes work Let’s clean

    up our mess And try again antisocial network 163 Wednesday, May 22, 13
  726. Reemerge > 164 Wednesday, May 22, 13

  727. ""git"rebase"**abort > Reemerge > 164 Wednesday, May 22, 13

  728. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"**abort > Reemerge > 164 Wednesday, May 22,

    13
  729. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan

    Applying:"Add"`change_pass()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan > ""git"rebase"**abort > Reemerge > 164 Wednesday, May 22, 13
  730. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan

    Applying:"Add"`change_pass()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan > ""git"rebase"**abort > Reemerge > Back to B, applies C 164 Wednesday, May 22, 13
  731. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan

    Applying:"Add"`change_pass()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan > ""git"rebase"**abort > Reemerge > That’s D 164 Wednesday, May 22, 13
  732. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan

    Applying:"Add"`change_pass()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan > ""git"rebase"**abort > Reemerge > Union merge 164 Wednesday, May 22, 13
  733. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan

    Applying:"Add"`change_pass()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan > ""git"rebase"**abort > Reemerge > That’s E 164 Wednesday, May 22, 13
  734. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan

    Applying:"Add"`change_pass()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan > ""git"rebase"**abort > Reemerge > Union merge 164 Wednesday, May 22, 13
  735. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan

    Applying:"Add"`change_pass()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan > ""git"rebase"**abort > Reemerge > Success! 164 Wednesday, May 22, 13
  736. ""echo"sqitch.plan"merge=union">".gitattributes > ""git"rebase"master First,"rewinding"head"to"replay"your"work"on"top"of"it... Applying:"Add"`insert_user()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan

    Applying:"Add"`change_pass()`. Using"index"info"to"reconstruct"a"base"tree... M" sqitch.plan Falling"back"to"patching"base"and"3*way"merge... Auto*merging"sqitch.plan > ""git"rebase"**abort > Reemerge > ""emacs"sqitch.plan > Success! 164 Wednesday, May 22, 13
  737. sqitch.plan What’s the Plan, Man? %syntax*version=1.0.0*b2 %project=flipr %uri=file://../flipr*remote appschema"2013*05*21T19:01:04Z"David"E."Wheeler" <david@justatheory.com>"#"Adds"flipr"app"schema.

    users"[appschema]"2013*05*21T19:41:54Z"David"E."Wheeler" <david@justatheory.com>"#"Creates"table"to"track"our" users. flips"[appschema"users]"2013*05*21T20:38:21Z"David"E." Wheeler"<david@justatheory.com>"#"Adds"table"for"storing" flips. insert_user"[users"appschema]"2013*05*21T20:51:05Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to" insert"a"user. change_pass"[users"appschema]"2013*05*21T21:05:42Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to 165 Wednesday, May 22, 13
  738. sqitch.plan What’s the Plan, Man? %syntax*version=1.0.0*b2 %project=flipr %uri=file://../flipr*remote appschema"2013*05*21T19:01:04Z"David"E."Wheeler" <david@justatheory.com>"#"Adds"flipr"app"schema.

    users"[appschema]"2013*05*21T19:41:54Z"David"E."Wheeler" <david@justatheory.com>"#"Creates"table"to"track"our" users. flips"[appschema"users]"2013*05*21T20:38:21Z"David"E." Wheeler"<david@justatheory.com>"#"Adds"table"for"storing" flips. insert_user"[users"appschema]"2013*05*21T20:51:05Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to" insert"a"user. change_pass"[users"appschema]"2013*05*21T21:05:42Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to 165 Wednesday, May 22, 13
  739. sqitch.plan What’s the Plan, Man? %syntax*version=1.0.0*b2 %project=flipr %uri=file://../flipr*remote appschema"2013*05*21T19:01:04Z"David"E."Wheeler" <david@justatheory.com>"#"Adds"flipr"app"schema.

    users"[appschema]"2013*05*21T19:41:54Z"David"E."Wheeler" <david@justatheory.com>"#"Creates"table"to"track"our" users. flips"[appschema"users]"2013*05*21T20:38:21Z"David"E." Wheeler"<david@justatheory.com>"#"Adds"table"for"storing" flips. insert_user"[users"appschema]"2013*05*21T20:51:05Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to" insert"a"user. change_pass"[users"appschema]"2013*05*21T21:05:42Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to 165 Wednesday, May 22, 13
  740. sqitch.plan What’s the Plan, Man? %syntax*version=1.0.0*b2 %project=flipr %uri=file://../flipr*remote appschema"2013*05*21T19:01:04Z"David"E."Wheeler" <david@justatheory.com>"#"Adds"flipr"app"schema.

    users"[appschema]"2013*05*21T19:41:54Z"David"E."Wheeler" <david@justatheory.com>"#"Creates"table"to"track"our" users. flips"[appschema"users]"2013*05*21T20:38:21Z"David"E." Wheeler"<david@justatheory.com>"#"Adds"table"for"storing" flips. insert_user"[users"appschema]"2013*05*21T20:51:05Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to" insert"a"user. change_pass"[users"appschema]"2013*05*21T21:05:42Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to 165 Wednesday, May 22, 13
  741. sqitch.plan What’s the Plan, Man? %syntax*version=1.0.0*b2 %project=flipr %uri=file://../flipr*remote appschema"2013*05*21T19:01:04Z"David"E."Wheeler" <david@justatheory.com>"#"Adds"flipr"app"schema.

    users"[appschema]"2013*05*21T19:41:54Z"David"E."Wheeler" <david@justatheory.com>"#"Creates"table"to"track"our" users. flips"[appschema"users]"2013*05*21T20:38:21Z"David"E." Wheeler"<david@justatheory.com>"#"Adds"table"for"storing" flips. insert_user"[users"appschema]"2013*05*21T20:51:05Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to" insert"a"user. change_pass"[users"appschema]"2013*05*21T21:05:42Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to 165 Wednesday, May 22, 13
  742. sqitch.plan What’s the Plan, Man? %syntax*version=1.0.0*b2 %project=flipr %uri=file://../flipr*remote appschema"2013*05*21T19:01:04Z"David"E."Wheeler" <david@justatheory.com>"#"Adds"flipr"app"schema.

    users"[appschema]"2013*05*21T19:41:54Z"David"E."Wheeler" <david@justatheory.com>"#"Creates"table"to"track"our" users. flips"[appschema"users]"2013*05*21T20:38:21Z"David"E." Wheeler"<david@justatheory.com>"#"Adds"table"for"storing" flips. insert_user"[users"appschema]"2013*05*21T20:51:05Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to" insert"a"user. change_pass"[users"appschema]"2013*05*21T21:05:42Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to 165 Wednesday, May 22, 13
  743. sqitch.plan What’s the Plan, Man? %syntax*version=1.0.0*b2 %project=flipr %uri=file://../flipr*remote appschema"2013*05*21T19:01:04Z"David"E."Wheeler" <david@justatheory.com>"#"Adds"flipr"app"schema.

    users"[appschema]"2013*05*21T19:41:54Z"David"E."Wheeler" <david@justatheory.com>"#"Creates"table"to"track"our" users. flips"[appschema"users]"2013*05*21T20:38:21Z"David"E." Wheeler"<david@justatheory.com>"#"Adds"table"for"storing" flips. insert_user"[users"appschema]"2013*05*21T20:51:05Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to" insert"a"user. change_pass"[users"appschema]"2013*05*21T21:05:42Z"David" E."Wheeler"<david@justatheory.com>"#"Creates"a"function"to Perfect 165 Wednesday, May 22, 13
  744. Work It > 166 Wednesday, May 22, 13

  745. >"sqitch"rebase"*y Reverting"all"changes"from"flipr_test ""*"change_pass".."ok ""*"insert_user".."ok ""*"users"........"ok ""*"appschema"...."ok Deploying"changes"to"flipr_test ""+"appschema"...."ok ""+"users"........"ok ""+"flips"........"ok

    ""+"insert_user".."ok ""+"change_pass".."ok > Work It > 166 Wednesday, May 22, 13
  746. >"sqitch"rebase"*y Reverting"all"changes"from"flipr_test ""*"change_pass".."ok ""*"insert_user".."ok ""*"users"........"ok ""*"appschema"...."ok Deploying"changes"to"flipr_test ""+"appschema"...."ok ""+"users"........"ok ""+"flips"........"ok

    ""+"insert_user".."ok ""+"change_pass".."ok > Work It > { 166 Wednesday, May 22, 13
  747. >"sqitch"rebase"*y Reverting"all"changes"from"flipr_test ""*"change_pass".."ok ""*"insert_user".."ok ""*"users"........"ok ""*"appschema"...."ok Deploying"changes"to"flipr_test ""+"appschema"...."ok ""+"users"........"ok ""+"flips"........"ok

    ""+"insert_user".."ok ""+"change_pass".."ok > Work It > { { 166 Wednesday, May 22, 13
  748. >"sqitch"rebase"*y Reverting"all"changes"from"flipr_test ""*"change_pass".."ok ""*"insert_user".."ok ""*"users"........"ok ""*"appschema"...."ok Deploying"changes"to"flipr_test ""+"appschema"...."ok ""+"users"........"ok ""+"flips"........"ok

    ""+"insert_user".."ok ""+"change_pass".."ok > Work It > { { Awesomsauce 166 Wednesday, May 22, 13
  749. Make it So > 167 Wednesday, May 22, 13

  750. >"git"add". > Make it So > 167 Wednesday, May 22,

    13
  751. >"git"add". > ""git"commit"*m"'Use"union"merge"for"`sqitch.plan`.' [userfuncs"0e31da9]"Use"union"merge"for"`sqitch.plan`. "1"file"changed,"1"insertion(+) "create"mode"100644".gitattributes > Make it So

    > 167 Wednesday, May 22, 13
  752. >"git"add". > ""git"commit"*m"'Use"union"merge"for"`sqitch.plan`.' [userfuncs"0e31da9]"Use"union"merge"for"`sqitch.plan`. "1"file"changed,"1"insertion(+) "create"mode"100644".gitattributes > ""git"push"**force"origin"userfuncs Counting"objects:"31,"done. Delta"compression"using"up"to"4"threads.

    Compressing"objects:"100%"(24/24),"done. Writing"objects:"100%"(25/25),"3.83"KiB,"done. Total"25"(delta"7),"reused"0"(delta"0) To"../flipr*remote "+"e7477c...0e31da"userfuncs"*>"userfuncs"(forced"update > Make it So > Overwrite history 167 Wednesday, May 22, 13
  753. >"git"add". > ""git"commit"*m"'Use"union"merge"for"`sqitch.plan`.' [userfuncs"0e31da9]"Use"union"merge"for"`sqitch.plan`. "1"file"changed,"1"insertion(+) "create"mode"100644".gitattributes > ""git"push"**force"origin"userfuncs Counting"objects:"31,"done. Delta"compression"using"up"to"4"threads.

    Compressing"objects:"100%"(24/24),"done. Writing"objects:"100%"(25/25),"3.83"KiB,"done. Total"25"(delta"7),"reused"0"(delta"0) To"../flipr*remote "+"e7477c...0e31da"userfuncs"*>"userfuncs"(forced"update > Make it So > 167 Wednesday, May 22, 13
  754. > 168 Wednesday, May 22, 13

  755. >"git"checkout"master Switched"to"branch"'master' > > 168 Wednesday, May 22, 13

  756. ""git"merge"userfuncs Updating"fbf8469..0e31da9 Fast*forward ".gitattributes"""""""""|""1"+ "deploy/change_pass.sql"|"21"++++++++++++++++++ "deploy/insert_user.sql"|"14"++++++++++++ "revert/change_pass.sql"|""7"++++++ "revert/insert_user.sql"|""7"++++++ "sqitch.plan""""""""""""|""2"++ "test/change_pass.sql"""|"52"++++++++++++++++++++++++++++++++++

    "test/insert_user.sql"""|"69"++++++++++++++++++++++++++++++++++ "verify/change_pass.sql"|""7"++++++ "verify/insert_user.sql"|"10"+++++++++ "10"files"changed,"190"insertions(+) "create"mode"100644".gitattributes "create"mode"100644"deploy/change_pass.sql "create"mode"100644"deploy/insert_user.sql "create"mode"100644"revert/change_pass.sql "create"mode"100644"revert/insert_user.sql "create"mode"100644"test/change_pass.sql "create"mode"100644"test/insert_user.sql "create"mode"100644"verify/change_pass.sql "create"mode"100644"verify/insert_user.sql > >"git"checkout"master Switched"to"branch"'master' > > 168 Wednesday, May 22, 13
  757. ""git"merge"userfuncs Updating"fbf8469..0e31da9 Fast*forward ".gitattributes"""""""""|""1"+ "deploy/change_pass.sql"|"21"++++++++++++++++++ "deploy/insert_user.sql"|"14"++++++++++++ "revert/change_pass.sql"|""7"++++++ "revert/insert_user.sql"|""7"++++++ "sqitch.plan""""""""""""|""2"++ "test/change_pass.sql"""|"52"++++++++++++++++++++++++++++++++++

    "test/insert_user.sql"""|"69"++++++++++++++++++++++++++++++++++ "verify/change_pass.sql"|""7"++++++ "verify/insert_user.sql"|"10"+++++++++ "10"files"changed,"190"insertions(+) "create"mode"100644".gitattributes "create"mode"100644"deploy/change_pass.sql "create"mode"100644"deploy/insert_user.sql "create"mode"100644"revert/change_pass.sql "create"mode"100644"revert/insert_user.sql "create"mode"100644"test/change_pass.sql "create"mode"100644"test/insert_user.sql "create"mode"100644"verify/change_pass.sql "create"mode"100644"verify/insert_user.sql > >"git"checkout"master Switched"to"branch"'master' > > \O/ 168 Wednesday, May 22, 13
  758. Pusher > 169 Wednesday, May 22, 13

  759. ""git"push Counting"objects:"20,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(13/13),"done. Writing"objects:"100%"(14/14),"2.31"KiB,"done. Total"14"(delta"2),"reused"0"(delta"0) To"../flipr*remote """fbf8469..0e31da9""master"*>"master > Pusher

    > 169 Wednesday, May 22, 13
  760. antisocial network 170 Wednesday, May 22, 13

  761. Ship it! antisocial network 170 Wednesday, May 22, 13

  762. Ship Shape antisocial network 171 Wednesday, May 22, 13

  763. Ship Shape Good work so far antisocial network 171 Wednesday,

    May 22, 13
  764. Ship Shape Good work so far People gonna flip out

    antisocial network 171 Wednesday, May 22, 13
  765. Ship Shape Good work so far People gonna flip out

    Let’s tag a dev release antisocial network 171 Wednesday, May 22, 13
  766. Ship Shape Good work so far People gonna flip out

    Let’s tag a dev release Bundle it up antisocial network 171 Wednesday, May 22, 13
  767. Ship Shape Good work so far People gonna flip out

    Let’s tag a dev release Bundle it up And ship it antisocial network 171 Wednesday, May 22, 13
  768. You’re It > 172 Wednesday, May 22, 13

  769. ""sqitch"tag"v1.0.0*r1"*n"'Tag"v1.0.0*r1.' Tagged""change_pass""with"@v1.0.0*r1 > You’re It > 172 Wednesday, May 22,

    13
  770. ""sqitch"tag"v1.0.0*r1"*n"'Tag"v1.0.0*r1.' Tagged""change_pass""with"@v1.0.0*r1 > ""git"commit"*am"'Tag"the"database"@v1.0.0*r1.'""" [master"6661268]"Tag"the"database"@v1.0.0*r1. "1"file"changed,"1"insertion(+) > You’re It >

    172 Wednesday, May 22, 13
  771. ""git"tag"v1.0.0*r1"*am"'Tag"v1.0.0*r1.' > ""sqitch"tag"v1.0.0*r1"*n"'Tag"v1.0.0*r1.' Tagged""change_pass""with"@v1.0.0*r1 > ""git"commit"*am"'Tag"the"database"@v1.0.0*r1.'""" [master"6661268]"Tag"the"database"@v1.0.0*r1. "1"file"changed,"1"insertion(+) > You’re

    It > In sync. In sync. 172 Wednesday, May 22, 13
  772. ""git"tag"v1.0.0*r1"*am"'Tag"v1.0.0*r1.' > ""sqitch"tag"v1.0.0*r1"*n"'Tag"v1.0.0*r1.' Tagged""change_pass""with"@v1.0.0*r1 > ""git"commit"*am"'Tag"the"database"@v1.0.0*r1.'""" [master"6661268]"Tag"the"database"@v1.0.0*r1. "1"file"changed,"1"insertion(+) > ""git"push

    Counting"objects:"5,"done. Writing"objects:"100%"(3/3),"346"bytes,"done. Total"3"(delta"2),"reused"0"(delta"0) To"../flipr*remote """0e31da9..6661268""master"*>"master > You’re It > 172 Wednesday, May 22, 13
  773. ""git"tag"v1.0.0*r1"*am"'Tag"v1.0.0*r1.' > ""sqitch"tag"v1.0.0*r1"*n"'Tag"v1.0.0*r1.' Tagged""change_pass""with"@v1.0.0*r1 > ""git"commit"*am"'Tag"the"database"@v1.0.0*r1.'""" [master"6661268]"Tag"the"database"@v1.0.0*r1. "1"file"changed,"1"insertion(+) > ""git"push

    Counting"objects:"5,"done. Writing"objects:"100%"(3/3),"346"bytes,"done. Total"3"(delta"2),"reused"0"(delta"0) To"../flipr*remote """0e31da9..6661268""master"*>"master > ""git"push"**tags To"../flipr*remote "*"[new"tag]"""""""""v1.0.0*r1"*>"v1.0.0*r1 > You’re It > 172 Wednesday, May 22, 13
  774. Bundle Up > 173 Wednesday, May 22, 13

  775. ""sqitch"bundle"**dest*dir"flipr*1.0.0*r1 Bundling"into"flipr*1.0.0*r1 Writing"config Writing"plan Writing"scripts ""+"appschema ""+"users ""+"flips ""+"insert_user ""+"change_pass"@v1.0.0*r1

    > Bundle Up > 173 Wednesday, May 22, 13
  776. ""sqitch"bundle"**dest*dir"flipr*1.0.0*r1 Bundling"into"flipr*1.0.0*r1 Writing"config Writing"plan Writing"scripts ""+"appschema ""+"users ""+"flips ""+"insert_user ""+"change_pass"@v1.0.0*r1

    > Bundle Up > { 173 Wednesday, May 22, 13
  777. Bundled? > 174 Wednesday, May 22, 13

  778. >"cd"flipr*1.0.0*r1 > Bundled? > 174 Wednesday, May 22, 13

  779. ""createdb"flipr_qa" > >"cd"flipr*1.0.0*r1 > Bundled? > 174 Wednesday, May 22,

    13
  780. ""createdb"flipr_qa" > >"cd"flipr*1.0.0*r1 > Bundled? > ""sqitch"*d"flipr_qa"deploy Adding"metadata"tables"to"flipr_qa Deploying"changes"to"flipr_qa ""+"appschema"..............."ok

    ""+"users"..................."ok ""+"flips"..................."ok ""+"insert_user"@v1.0.0*r1".."ok > 174 Wednesday, May 22, 13
  781. ""createdb"flipr_qa" > >"cd"flipr*1.0.0*r1 > Bundled? > Ship it! ""sqitch"*d"flipr_qa"deploy Adding"metadata"tables"to"flipr_qa

    Deploying"changes"to"flipr_qa ""+"appschema"..............."ok ""+"users"..................."ok ""+"flips"..................."ok ""+"insert_user"@v1.0.0*r1".."ok > 174 Wednesday, May 22, 13
  782. antisocial network Merge Madness 175 Wednesday, May 22, 13

  783. antisocial network Merge Madness Merge everything 175 Wednesday, May 22,

    13
  784. antisocial network Merge Madness Merge everything Back to master 175

    Wednesday, May 22, 13
  785. antisocial network Merge Madness Merge everything Back to master users

    175 Wednesday, May 22, 13
  786. antisocial network Merge Madness Merge everything Back to master users

    flips 175 Wednesday, May 22, 13
  787. antisocial network Merge Madness Merge everything Back to master users

    flips userfuncs 175 Wednesday, May 22, 13
  788. antisocial network Merge Madness Merge everything Back to master users

    flips userfuncs Union merge sqitch.plan 175 Wednesday, May 22, 13
  789. antisocial network Merge Madness Merge everything Back to master users

    flips userfuncs Union merge sqitch.plan Bundle and ship 175 Wednesday, May 22, 13
  790. antisocial network Merge Madness Merge everything Back to master users

    flips userfuncs Union merge sqitch.plan Bundle and ship https:/ /github.com/ theory/agile-flipr.git 175 Wednesday, May 22, 13
  791. Ruh-Roh > 176 Wednesday, May 22, 13

  792. Ruh-Roh > >"git"reset"**hard"reltag HEAD"is"now"at"6661268"Tag"the"database"@v1.0.0*r1. > 176 Wednesday, May 22, 13

  793. ""psql"*d"flipr_test"*c"" """"SELECT"flipr.insert_user('foo',"'secr3t'), """""""""""flipr.insert_user('bar',"'secr3t'); """"SELECT"nickname,"password"FROM"flipr.users; " "nickname"|"""""""""""""password""""""""""""" **********+********************************** "foo""""""|"9695da4dd567a19f9b92065f240c6725 "bar""""""|"9695da4dd567a19f9b92065f240c6725 (2"rows)

    > Ruh-Roh > >"git"reset"**hard"reltag HEAD"is"now"at"6661268"Tag"the"database"@v1.0.0*r1. > Same password 176 Wednesday, May 22, 13
  794. ""psql"*d"flipr_test"*c"" """"SELECT"flipr.insert_user('foo',"'secr3t'), """""""""""flipr.insert_user('bar',"'secr3t'); """"SELECT"nickname,"password"FROM"flipr.users; " "nickname"|"""""""""""""password""""""""""""" **********+********************************** "foo""""""|"9695da4dd567a19f9b92065f240c6725 "bar""""""|"9695da4dd567a19f9b92065f240c6725 (2"rows)

    > Ruh-Roh > >"git"reset"**hard"reltag HEAD"is"now"at"6661268"Tag"the"database"@v1.0.0*r1. > 176 Wednesday, May 22, 13
  795. ""psql"*d"flipr_test"*c"" """"SELECT"flipr.insert_user('foo',"'secr3t'), """""""""""flipr.insert_user('bar',"'secr3t'); """"SELECT"nickname,"password"FROM"flipr.users; " "nickname"|"""""""""""""password""""""""""""" **********+********************************** "foo""""""|"9695da4dd567a19f9b92065f240c6725 "bar""""""|"9695da4dd567a19f9b92065f240c6725 (2"rows)

    > Ruh-Roh > Not good. >"git"reset"**hard"reltag HEAD"is"now"at"6661268"Tag"the"database"@v1.0.0*r1. > 176 Wednesday, May 22, 13
  796. PGCryptonite > 177 Wednesday, May 22, 13

  797. ""sqitch"add"pgcrypto"*n"'Loads"pgcrypto"extension.' Adding"deploy/pgcrypto.sql Adding"revert/pgcrypto.sql Adding"verify/pgcrypto.sql Added""pgcrypto""to"sqitch.plan > PGCryptonite > 177 Wednesday,

    May 22, 13
  798. ""sqitch"add"pgcrypto"*n"'Loads"pgcrypto"extension.' Adding"deploy/pgcrypto.sql Adding"revert/pgcrypto.sql Adding"verify/pgcrypto.sql Added""pgcrypto""to"sqitch.plan > PGCryptonite > ""emacs"deploy/pgcrpyto.sql >

    177 Wednesday, May 22, 13
  799. deploy/pgcrypto deploy/pgcrypto.sql **"Deploy"pgcrypto BEGIN; COMMIT; **"XXX"Add"DDLs"here. 178 Wednesday, May 22,

    13
  800. deploy/pgcrypto deploy/pgcrypto.sql **"Deploy"pgcrypto BEGIN; COMMIT; CREATE"EXTENSION"pgcrypto; 178 Wednesday, May 22,

    13
  801. ""sqitch"add"pgcrypto"*n"'Loads"pgcrypto"extension.' Adding"deploy/pgcrypto.sql Adding"revert/pgcrypto.sql Adding"verify/pgcrypto.sql Added""pgcrypto""to"sqitch.plan >"emacs"deploy/pgcrpyto.sql > PGCryptonite > 179

    Wednesday, May 22, 13
  802. ""sqitch"add"pgcrypto"*n"'Loads"pgcrypto"extension.' Adding"deploy/pgcrypto.sql Adding"revert/pgcrypto.sql Adding"verify/pgcrypto.sql Added""pgcrypto""to"sqitch.plan >"emacs"deploy/pgcrpyto.sql > PGCryptonite > ""emacs"verify/pgcrpyto.sql

    > 179 Wednesday, May 22, 13
  803. **"Verify"pgcrypto BEGIN; verify/pgcrypto verify/pgcrypto.sql **"XXX"Add"verifications"here. COMMIT; 180 Wednesday, May 22,

    13
  804. **"Verify"pgcrypto BEGIN; verify/pgcrypto verify/pgcrypto.sql COMMIT; SELECT"1/count(*)"FROM"pg_extension"WHERE"extname"="'pgcrypto'; SELECT"has_function_privilege('crypt(text,"text)',"'execute'); SELECT"has_function_privilege('gen_salt(text)',"'execute'); 180 Wednesday,

    May 22, 13
  805. **"Verify"pgcrypto BEGIN; verify/pgcrypto verify/pgcrypto.sql COMMIT; SELECT"1/count(*)"FROM"pg_extension"WHERE"extname"="'pgcrypto'; SELECT"has_function_privilege('crypt(text,"text)',"'execute'); SELECT"has_function_privilege('gen_salt(text)',"'execute'); 180 Wednesday,

    May 22, 13
  806. **"Verify"pgcrypto BEGIN; verify/pgcrypto verify/pgcrypto.sql COMMIT; SELECT"1/count(*)"FROM"pg_extension"WHERE"extname"="'pgcrypto'; SELECT"has_function_privilege('crypt(text,"text)',"'execute'); SELECT"has_function_privilege('gen_salt(text)',"'execute'); 180 Wednesday,

    May 22, 13
  807. You Know the Drill antisocial network 181 Wednesday, May 22,

    13
  808. You Know the Drill Write revert script antisocial network 181

    Wednesday, May 22, 13
  809. You Know the Drill Write revert script Add test antisocial

    network 181 Wednesday, May 22, 13
  810. You Know the Drill Write revert script Add test Use

    has_function() antisocial network 181 Wednesday, May 22, 13
  811. You Know the Drill Write revert script Add test Use

    has_function() Commit antisocial network 181 Wednesday, May 22, 13
  812. You Know the Drill Write revert script Add test Use

    has_function() Commit Push antisocial network 181 Wednesday, May 22, 13
  813. You Know the Drill Write revert script Add test Use

    has_function() Commit Push Modify the insert_user test antisocial network 181 Wednesday, May 22, 13
  814. > 182 Wednesday, May 22, 13

  815. ""git"diff"test/insert_user.sql @@"*5,7"+5,7"@@"SET"search_path"TO"flipr,public; " "**"Plan"the"tests. "BEGIN; *SELECT"plan(11); +SELECT"plan(12); " "SELECT"has_function("'insert_user'"); "SELECT"has_function(

    @@"*29,25"+29,25"@@"SELECT"lives_ok( """""'Insert"a"user' "); " *SELECT"row_eq( *"""'SELECT"*"FROM"users', *"""ROW('theory',"md5('foo'),"NOW())::users, *"""'The"user"should"have"been"inserted' *); +SELECT"ok("EXISTS( +""""SELECT"1"FROM"flipr.users +"""""WHERE"nickname"="'theory' +"""""""AND"password"="crypt('foo',"password) +),"'The"user"should"have"been"inserted'"); > 182 Wednesday, May 22, 13
  816. ""git"diff"test/insert_user.sql @@"*5,7"+5,7"@@"SET"search_path"TO"flipr,public; " "**"Plan"the"tests. "BEGIN; *SELECT"plan(11); +SELECT"plan(12); " "SELECT"has_function("'insert_user'"); "SELECT"has_function(

    @@"*29,25"+29,25"@@"SELECT"lives_ok( """""'Insert"a"user' "); " *SELECT"row_eq( *"""'SELECT"*"FROM"users', *"""ROW('theory',"md5('foo'),"NOW())::users, *"""'The"user"should"have"been"inserted' *); +SELECT"ok("EXISTS( +""""SELECT"1"FROM"flipr.users +"""""WHERE"nickname"="'theory' +"""""""AND"password"="crypt('foo',"password) +),"'The"user"should"have"been"inserted'"); > 182 Wednesday, May 22, 13
  817. ""git"diff"test/insert_user.sql @@"*5,7"+5,7"@@"SET"search_path"TO"flipr,public; " "**"Plan"the"tests. "BEGIN; *SELECT"plan(11); +SELECT"plan(12); " "SELECT"has_function("'insert_user'"); "SELECT"has_function(

    @@"*29,25"+29,25"@@"SELECT"lives_ok( """""'Insert"a"user' "); " *SELECT"row_eq( *"""'SELECT"*"FROM"users', *"""ROW('theory',"md5('foo'),"NOW())::users, *"""'The"user"should"have"been"inserted' *); +SELECT"ok("EXISTS( +""""SELECT"1"FROM"flipr.users +"""""WHERE"nickname"="'theory' +"""""""AND"password"="crypt('foo',"password) +),"'The"user"should"have"been"inserted'"); > 182 Wednesday, May 22, 13
  818. "SELECT"lives_ok( """""$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """""'Insert"another"user' "); " *SELECT"bag_eq( *""""'SELECT"*"FROM"users', *""""$$"VALUES *""""""""('theory',""""md5('foo'),""NOW()), *""""""""('strongrrl',"md5('w00t'),"NOW())

    *""""$$, *""""'Both"users"should"be"present' *); +SELECT"is(COUNT(*)::INT,"2,"'There"should"be"two"users') +""FROM"flipr.users; + +SELECT"ok("EXISTS( +""""SELECT"1"FROM"flipr.users +"""""WHERE"nickname"="'strongrrl' +"""""""AND"password"="crypt('w00t',"password) +),"'The"second"user"should"have"been"inserted'"); "SELECT"throws_ok( """""$$"SELECT"insert_user('theory',"'ha*ha')"$$, 183 Wednesday, May 22, 13
  819. "SELECT"lives_ok( """""$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """""'Insert"another"user' "); " *SELECT"bag_eq( *""""'SELECT"*"FROM"users', *""""$$"VALUES *""""""""('theory',""""md5('foo'),""NOW()), *""""""""('strongrrl',"md5('w00t'),"NOW())

    *""""$$, *""""'Both"users"should"be"present' *); +SELECT"is(COUNT(*)::INT,"2,"'There"should"be"two"users') +""FROM"flipr.users; + +SELECT"ok("EXISTS( +""""SELECT"1"FROM"flipr.users +"""""WHERE"nickname"="'strongrrl' +"""""""AND"password"="crypt('w00t',"password) +),"'The"second"user"should"have"been"inserted'"); "SELECT"throws_ok( """""$$"SELECT"insert_user('theory',"'ha*ha')"$$, 183 Wednesday, May 22, 13
  820. "SELECT"lives_ok( """""$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """""'Insert"another"user' "); " *SELECT"bag_eq( *""""'SELECT"*"FROM"users', *""""$$"VALUES *""""""""('theory',""""md5('foo'),""NOW()), *""""""""('strongrrl',"md5('w00t'),"NOW())

    *""""$$, *""""'Both"users"should"be"present' *); +SELECT"is(COUNT(*)::INT,"2,"'There"should"be"two"users') +""FROM"flipr.users; + +SELECT"ok("EXISTS( +""""SELECT"1"FROM"flipr.users +"""""WHERE"nickname"="'strongrrl' +"""""""AND"password"="crypt('w00t',"password) +),"'The"second"user"should"have"been"inserted'"); "SELECT"throws_ok( """""$$"SELECT"insert_user('theory',"'ha*ha')"$$, 183 Wednesday, May 22, 13
  821. "SELECT"lives_ok( """""$$"SELECT"insert_user('strongrrl',"'w00t')"$$, """""'Insert"another"user' "); " *SELECT"bag_eq( *""""'SELECT"*"FROM"users', *""""$$"VALUES *""""""""('theory',""""md5('foo'),""NOW()), *""""""""('strongrrl',"md5('w00t'),"NOW())

    *""""$$, *""""'Both"users"should"be"present' *); +SELECT"is(COUNT(*)::INT,"2,"'There"should"be"two"users') +""FROM"flipr.users; + +SELECT"ok("EXISTS( +""""SELECT"1"FROM"flipr.users +"""""WHERE"nickname"="'strongrrl' +"""""""AND"password"="crypt('w00t',"password) +),"'The"second"user"should"have"been"inserted'"); "SELECT"throws_ok( """""$$"SELECT"insert_user('theory',"'ha*ha')"$$, 183 Wednesday, May 22, 13
  822. @@"*56,14"+56,8"@@"SELECT"throws_ok( """""'Should"get"an"error"for"duplicate"nickname' "); " *SELECT"bag_eq( *""""'SELECT"*"FROM"users', *""""$$"VALUES *""""""""('theory',""""md5('foo'),""NOW()), *""""""""('strongrrl',"md5('w00t'),"NOW()) *""""$$,

    *""""'Should"still"have"just"the"two"users' *); +SELECT"is(COUNT(*)::INT,"2,"'Should"still"have"two"users') +""FROM"flipr.users; " "SELECT"finish(); "ROLLBACK; > 184 Wednesday, May 22, 13
  823. @@"*56,14"+56,8"@@"SELECT"throws_ok( """""'Should"get"an"error"for"duplicate"nickname' "); " *SELECT"bag_eq( *""""'SELECT"*"FROM"users', *""""$$"VALUES *""""""""('theory',""""md5('foo'),""NOW()), *""""""""('strongrrl',"md5('w00t'),"NOW()) *""""$$,

    *""""'Should"still"have"just"the"two"users' *); +SELECT"is(COUNT(*)::INT,"2,"'Should"still"have"two"users') +""FROM"flipr.users; " "SELECT"finish(); "ROLLBACK; > 184 Wednesday, May 22, 13
  824. @@"*56,14"+56,8"@@"SELECT"throws_ok( """""'Should"get"an"error"for"duplicate"nickname' "); " *SELECT"bag_eq( *""""'SELECT"*"FROM"users', *""""$$"VALUES *""""""""('theory',""""md5('foo'),""NOW()), *""""""""('strongrrl',"md5('w00t'),"NOW()) *""""$$,

    *""""'Should"still"have"just"the"two"users' *); +SELECT"is(COUNT(*)::INT,"2,"'Should"still"have"two"users') +""FROM"flipr.users; " "SELECT"finish(); "ROLLBACK; > 184 Wednesday, May 22, 13
  825. FAIL > 185 Wednesday, May 22, 13

  826. FAIL >"pg_prove"*d"flipr_test"test/insert_user.sql test/insert_user.sql".."1/12" #"Failed"test"7:""The"user"should"have"been"inserted" #"Failed"test"10:""The"second"user"should"have"been"inserted" #"Looks"like"you"failed"2"tests"of"12 test/insert_user.sql".."Failed"2/12"subtests" Test"Summary"Report ******************* test/insert_user.sql"(Wstat:"0"Tests:"12"Failed:"2)

    ""Failed"tests:""7,"10 Files=1,"Tests=12,""1"wallclock"secs Result:"FAIL > > 185 Wednesday, May 22, 13
  827. FAIL >"pg_prove"*d"flipr_test"test/insert_user.sql test/insert_user.sql".."1/12" #"Failed"test"7:""The"user"should"have"been"inserted" #"Failed"test"10:""The"second"user"should"have"been"inserted" #"Looks"like"you"failed"2"tests"of"12 test/insert_user.sql".."Failed"2/12"subtests" Test"Summary"Report ******************* test/insert_user.sql"(Wstat:"0"Tests:"12"Failed:"2)

    ""Failed"tests:""7,"10 Files=1,"Tests=12,""1"wallclock"secs Result:"FAIL > > As expected. 185 Wednesday, May 22, 13
  828. Back when discussing traditional migration systems, I said… antisocial network

    186 Wednesday, May 22, 13
  829. Managing procedures is a PITA! antisocial network 187 Wednesday, May

    22, 13
  830. Consider this Change > 188 Wednesday, May 22, 13

  831. Consider this Change ""git"diff diff"**git"a/deploy/insert_user.sql"b/deploy/insert_user.sql index"eb30fed..5c28d02"100644 ***"a/deploy/insert_user.sql +++"b/deploy/insert_user.sql @@"*8,7"+8,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; > 188 Wednesday, May 22, 13
  832. Consider this Change ""git"diff diff"**git"a/deploy/insert_user.sql"b/deploy/insert_user.sql index"eb30fed..5c28d02"100644 ***"a/deploy/insert_user.sql +++"b/deploy/insert_user.sql @@"*8,7"+8,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; > Simple, right? 188 Wednesday, May 22, 13
  833. Not So Much antisocial network 189 Wednesday, May 22, 13

  834. Not So Much Copy insert_user.sql to new deploy file antisocial

    network 189 Wednesday, May 22, 13
  835. Not So Much Copy insert_user.sql to new deploy file Change

    that new file antisocial network 189 Wednesday, May 22, 13
  836. Not So Much Copy insert_user.sql to new deploy file Change

    that new file Copy insert_user.sql to new revert file antisocial network 189 Wednesday, May 22, 13
  837. Not So Much Copy insert_user.sql to new deploy file Change

    that new file Copy insert_user.sql to new revert file Test it antisocial network 189 Wednesday, May 22, 13
  838. Not So Much 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 antisocial network 189 Wednesday, May 22, 13
  839. Not So Much 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… antisocial network 189 Wednesday, May 22, 13
  840. > 190 Wednesday, May 22, 13

  841. >"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)); +$$; > 190 Wednesday, May 22, 13
  842. >"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. 190 Wednesday, May 22, 13
  843. Let Sqitch do the work. antisocial network 191 Wednesday, May

    22, 13
  844. Rework It > 192 Wednesday, May 22, 13

  845. ""sqitch"rework"insert_user"*r"pgcrypto"\ ""*n"'Changes"insert_user"to"use"pgcrypto.' Added""insert_user"[insert_user@v1.0.0*r1"pgcrypto]""to" sqitch.plan. Modify"these"files"as"appropriate: ""*"deploy/insert_user.sql ""*"revert/insert_user.sql ""*"verify/insert_user.sql > Rework

    It > 192 Wednesday, May 22, 13
  846. ""sqitch"rework"insert_user"*r"pgcrypto"\ ""*n"'Changes"insert_user"to"use"pgcrypto.' Added""insert_user"[insert_user@v1.0.0*r1"pgcrypto]""to" sqitch.plan. Modify"these"files"as"appropriate: ""*"deploy/insert_user.sql ""*"revert/insert_user.sql ""*"verify/insert_user.sql > Rework

    It > 192 Wednesday, May 22, 13
  847. ""sqitch"rework"insert_user"*r"pgcrypto"\ ""*n"'Changes"insert_user"to"use"pgcrypto.' Added""insert_user"[insert_user@v1.0.0*r1"pgcrypto]""to" sqitch.plan. Modify"these"files"as"appropriate: ""*"deploy/insert_user.sql ""*"revert/insert_user.sql ""*"verify/insert_user.sql > Rework

    It > 192 Wednesday, May 22, 13
  848. ""sqitch"rework"insert_user"*r"pgcrypto"\ ""*n"'Changes"insert_user"to"use"pgcrypto.' Added""insert_user"[insert_user@v1.0.0*r1"pgcrypto]""to" sqitch.plan. Modify"these"files"as"appropriate: ""*"deploy/insert_user.sql ""*"revert/insert_user.sql ""*"verify/insert_user.sql > Rework

    It > Same files? 192 Wednesday, May 22, 13
  849. Same Files? > 193 Wednesday, May 22, 13

  850. ""git"status #"On"branch"master #"Changes"not"staged"for"commit: #"""(use""git"add"<file>...""to"update"what"will"be"committe #"""(use""git"checkout"**"<file>...""to"discard"changes"in"w # #" modified:"""revert/insert_user.sql #" modified:"""sqitch.plan

    #" modified:"""test/insert_user.sql # #"Untracked"files: #"""(use""git"add"<file>...""to"include"in"what"will"be"comm # #" deploy/insert_user@v1.0.0*r1.sql #" revert/insert_user@v1.0.0*r1.sql #" verify/insert_user@v1.0.0*r1.sql no"changes"added"to"commit"(use""git"add""and/or""git"commit > Same Files? > 193 Wednesday, May 22, 13
  851. ""git"status #"On"branch"master #"Changes"not"staged"for"commit: #"""(use""git"add"<file>...""to"update"what"will"be"committe #"""(use""git"checkout"**"<file>...""to"discard"changes"in"w # #" modified:"""revert/insert_user.sql #" modified:"""sqitch.plan

    #" modified:"""test/insert_user.sql # #"Untracked"files: #"""(use""git"add"<file>...""to"include"in"what"will"be"comm # #" deploy/insert_user@v1.0.0*r1.sql #" revert/insert_user@v1.0.0*r1.sql #" verify/insert_user@v1.0.0*r1.sql no"changes"added"to"commit"(use""git"add""and/or""git"commit > Same Files? > 193 Wednesday, May 22, 13
  852. ""git"status #"On"branch"master #"Changes"not"staged"for"commit: #"""(use""git"add"<file>...""to"update"what"will"be"committe #"""(use""git"checkout"**"<file>...""to"discard"changes"in"w # #" modified:"""revert/insert_user.sql #" modified:"""sqitch.plan

    #" modified:"""test/insert_user.sql # #"Untracked"files: #"""(use""git"add"<file>...""to"include"in"what"will"be"comm # #" deploy/insert_user@v1.0.0*r1.sql #" revert/insert_user@v1.0.0*r1.sql #" verify/insert_user@v1.0.0*r1.sql no"changes"added"to"commit"(use""git"add""and/or""git"commit > Same Files? > As of @v1.0.0-r1 193 Wednesday, May 22, 13
  853. ""git"status #"On"branch"master #"Changes"not"staged"for"commit: #"""(use""git"add"<file>...""to"update"what"will"be"committe #"""(use""git"checkout"**"<file>...""to"discard"changes"in"w # #" modified:"""revert/insert_user.sql #" modified:"""sqitch.plan

    #" modified:"""test/insert_user.sql # #"Untracked"files: #"""(use""git"add"<file>...""to"include"in"what"will"be"comm # #" deploy/insert_user@v1.0.0*r1.sql #" revert/insert_user@v1.0.0*r1.sql #" verify/insert_user@v1.0.0*r1.sql no"changes"added"to"commit"(use""git"add""and/or""git"commit > Same Files? > 193 Wednesday, May 22, 13
  854. ""git"status #"On"branch"master #"Changes"not"staged"for"commit: #"""(use""git"add"<file>...""to"update"what"will"be"committe #"""(use""git"checkout"**"<file>...""to"discard"changes"in"w # #" modified:"""revert/insert_user.sql #" modified:"""sqitch.plan

    #" modified:"""test/insert_user.sql # #"Untracked"files: #"""(use""git"add"<file>...""to"include"in"what"will"be"comm # #" deploy/insert_user@v1.0.0*r1.sql #" revert/insert_user@v1.0.0*r1.sql #" verify/insert_user@v1.0.0*r1.sql no"changes"added"to"commit"(use""git"add""and/or""git"commit > Same Files? > Previous deploy becomes revert 193 Wednesday, May 22, 13
  855. What’s the Diff? > 194 Wednesday, May 22, 13

  856. What’s the Diff? ""diff"*u"deploy/insert_user.sql diff"**git"a/deploy/insert_user.sql"b/deploy/insert_user.sql @@"*1,6"+1,7"@@ "**"Deploy"insert_user "**"requires:"users "**"requires:"appschema +**"requires:"appschema

    " "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; > > 194 Wednesday, May 22, 13
  857. Send it Up! > 195 Wednesday, May 22, 13

  858. Send it Up! >"sqitch"deploy Deploying"changes"to"flipr_test ""+"insert_user".."ok > > 195 Wednesday,

    May 22, 13
  859. >"psql"*d"flipr_test"*c"" """"DELETE"FROM"flipr.users; """"SELECT"flipr.insert_user('foo',"'secr3t'), """""""""""flipr.insert_user('bar',"'secr3t'); """"SELECT"nickname,"password"FROM"flipr.users; " "nickname"|""""""""""""""password"""""""""""""" **********+************************************ "foo""""""|"$1$nKO47p03$YRXYTt4NoNncTThLyxzEq1 "bar""""""|"$1$LbVUs/p.$LVbvPlkD8rJlixW2nS3WP0

    (2"rows) > Send it Up! >"sqitch"deploy Deploying"changes"to"flipr_test ""+"insert_user".."ok > > 195 Wednesday, May 22, 13
  860. >"psql"*d"flipr_test"*c"" """"DELETE"FROM"flipr.users; """"SELECT"flipr.insert_user('foo',"'secr3t'), """""""""""flipr.insert_user('bar',"'secr3t'); """"SELECT"nickname,"password"FROM"flipr.users; " "nickname"|""""""""""""""password"""""""""""""" **********+************************************ "foo""""""|"$1$nKO47p03$YRXYTt4NoNncTThLyxzEq1 "bar""""""|"$1$LbVUs/p.$LVbvPlkD8rJlixW2nS3WP0

    (2"rows) > Send it Up! >"sqitch"deploy Deploying"changes"to"flipr_test ""+"insert_user".."ok > > \o/ 195 Wednesday, May 22, 13
  861. Can We Go Back? > 196 Wednesday, May 22, 13

  862. Can We Go Back? >"sqitch"revert"**to"@HEAD^"*y ""*"insert_user".."ok > > 196 Wednesday,

    May 22, 13
  863. ""psql"*d"flipr_test"*c"" """"DELETE"FROM"flipr.users; """"SELECT"flipr.insert_user('foo',"'secr3t'), """""""""""flipr.insert_user('bar',"'secr3t'); """"SELECT"nickname,"password"FROM"flipr.users; " "nickname"|"""""""""""""password""""""""""""" **********+********************************** "foo""""""|"9695da4dd567a19f9b92065f240c6725 "bar""""""|"9695da4dd567a19f9b92065f240c6725

    (2"rows) Can We Go Back? >"sqitch"revert"**to"@HEAD^"*y ""*"insert_user".."ok > > 196 Wednesday, May 22, 13
  864. Verify How? > 197 Wednesday, May 22, 13

  865. Verify How? >"emacs"verify/insert_user.sql > > 197 Wednesday, May 22, 13

  866. **"Verify"insert_user BEGIN; SELECT"has_function_privilege( """"'flipr.insert_user(text,"text)', """"'execute' ); verify/insert_u verify/insert_user.sql COMMIT; 198

    Wednesday, May 22, 13
  867. SELECT"1/COUNT(*) ""FROM"pg_catalog.pg_proc "WHERE"proname"="'insert_user' """AND"pg_get_functiondef(oid) """""""LIKE"$$%crypt($2,"gen_salt('md5'))%$$; **"Verify"insert_user BEGIN; SELECT"has_function_privilege( """"'flipr.insert_user(text,"text)', """"'execute'

    ); verify/insert_u verify/insert_user.sql COMMIT; 198 Wednesday, May 22, 13
  868. SELECT"1/COUNT(*) ""FROM"pg_catalog.pg_proc "WHERE"proname"="'insert_user' """AND"pg_get_functiondef(oid) """""""LIKE"$$%crypt($2,"gen_salt('md5'))%$$; **"Verify"insert_user BEGIN; SELECT"has_function_privilege( """"'flipr.insert_user(text,"text)', """"'execute'

    ); verify/insert_u verify/insert_user.sql COMMIT; Yeah, compare source. 198 Wednesday, May 22, 13
  869. >"emacs"verify/insert_user.sql > Let’s Go! 199 Wednesday, May 22, 13

  870. >"emacs"verify/insert_user.sql > Let’s Go! >"sqitch"deploy Deploying"changes"to"flipr_test ""+"insert_user".."ok > 199 Wednesday,

    May 22, 13
  871. >"emacs"verify/insert_user.sql > Let’s Go! >"sqitch"deploy Deploying"changes"to"flipr_test ""+"insert_user".."ok > >"psql"*d"flipr_test"*c"'DELETE"FROM"flipr.users' DELETE"2

    > 199 Wednesday, May 22, 13
  872. >"emacs"verify/insert_user.sql > Let’s Go! >"sqitch"deploy Deploying"changes"to"flipr_test ""+"insert_user".."ok > >"psql"*d"flipr_test"*c"'DELETE"FROM"flipr.users' DELETE"2

    > pg_prove"*d"flipr_test"test/insert_user.sql"""" test/insert_user.sql".."ok""""" All"tests"successful. Files=1,"Tests=12,""0"wallclock"secs Result:"PASS > Shazam! 199 Wednesday, May 22, 13
  873. Add, Commit, Push, Go > 200 Wednesday, May 22, 13

  874. ""git"add". >"git"commit"*m"'Update"insert_user"to"use"pgcrypto.' [master"59f5823]"Update"insert_user"to"use"pgcrypto. "8"files"changed,"66"insertions(+),"25"deletions(*) "create"mode"100644"deploy/insert_user@v1.0.0*r1.sql "create"mode"100644"revert/insert_user@v1.0.0*r1.sql "create"mode"100644"verify/insert_user@v1.0.0*r1.sql > Add, Commit,

    Push, Go > 200 Wednesday, May 22, 13
  875. ""git"add". >"git"commit"*m"'Update"insert_user"to"use"pgcrypto.' [master"59f5823]"Update"insert_user"to"use"pgcrypto. "8"files"changed,"66"insertions(+),"25"deletions(*) "create"mode"100644"deploy/insert_user@v1.0.0*r1.sql "create"mode"100644"revert/insert_user@v1.0.0*r1.sql "create"mode"100644"verify/insert_user@v1.0.0*r1.sql > Add, Commit,

    Push, Go >"git"push Counting"objects:"17,"done. Delta"compression"using"up"to"4"threads. Compressing"objects:"100%"(10/10),"done. Writing"objects:"100%"(10/10),"1.75"KiB,"done. Total"10"(delta"6),"reused"0"(delta"0) To"../flipr*remote """5f4c29a..59f5823""master"*>"master > > 200 Wednesday, May 22, 13
  876. antisocial network Change It Up 201 Wednesday, May 22, 13

  877. antisocial network Change It Up git reset --hard insert_user2 201

    Wednesday, May 22, 13
  878. antisocial network Change It Up git reset --hard insert_user2 Rework

    change_pass 201 Wednesday, May 22, 13
  879. antisocial network Change It Up git reset --hard insert_user2 Rework

    change_pass Use pgcrypo 201 Wednesday, May 22, 13
  880. antisocial network Change It Up git reset --hard insert_user2 Rework

    change_pass Use pgcrypo Test first! 201 Wednesday, May 22, 13
  881. antisocial network Change It Up git reset --hard insert_user2 Rework

    change_pass Use pgcrypo Test first! Bundle, tag, release 201 Wednesday, May 22, 13
  882. antisocial network Change It Up git reset --hard insert_user2 Rework

    change_pass Use pgcrypo Test first! Bundle, tag, release https:/ /github.com/ theory/agile-flipr.git 201 Wednesday, May 22, 13
  883. I’m afraid I have some bad news… antisocial network 202

    Wednesday, May 22, 13
  884. 203 Wednesday, May 22, 13

  885. Antisocial Networking Startup Flipr Heads To The Deadpool by Michael

    Arrington on November 2, 2010 antisocial network I loved this site. Flipr, an online “antisocial networking” site that encouraged users to alienate each other in order to increase their antisocial cred, is shutting down. The startup’s homepage now consists of a letter to Flipr users instructing them to download their “flips” by November 30, at which point nearly all of the service’s features will be taken offline and data deleted. In the letter, Flipr CEO David Wheeler writes that despite ample venture funding and a dedicated team of database developers, the site underestimated people’s willingness to be assholes. This is not something I can relate to, although from what I’ve been told by more polite society, it is indeed the case. Such a shame. 203 Wednesday, May 22, 13
  886. I’m afraid it’s true. antisocial network RIP 204 Wednesday, May

    22, 13
  887. I’m sorry I have no money left to pay you.

    antisocial network RIP 205 Wednesday, May 22, 13
  888. I hope you enjoyed working here. antisocial network RIP 206

    Wednesday, May 22, 13
  889. And that you’re able to use the skills you’ve gained

    in your next job. antisocial network RIP 207 Wednesday, May 22, 13
  890. Git Skillz antisocial network RIP 208 Wednesday, May 22, 13

  891. Git Skillz Branching antisocial network RIP 208 Wednesday, May 22,

    13
  892. Git Skillz Branching Diffing antisocial network RIP 208 Wednesday, May

    22, 13
  893. Git Skillz Branching Diffing Rebasing antisocial network RIP 208 Wednesday,

    May 22, 13
  894. Git Skillz Branching Diffing Rebasing Merging antisocial network RIP 208

    Wednesday, May 22, 13
  895. Git Skillz Branching Diffing Rebasing Merging Committing antisocial network RIP

    208 Wednesday, May 22, 13
  896. Git Skillz Branching Diffing Rebasing Merging Committing Pushing antisocial network

    RIP 208 Wednesday, May 22, 13
  897. MOAR Git antisocial network RIP 209 Wednesday, May 22, 13

  898. MOAR Git Bisecting antisocial network RIP 209 Wednesday, May 22,

    13
  899. MOAR Git Bisecting Blaming antisocial network RIP 209 Wednesday, May

    22, 13
  900. MOAR Git Bisecting Blaming Pull requests antisocial network RIP 209

    Wednesday, May 22, 13
  901. MOAR Git Bisecting Blaming Pull requests Submitting patches antisocial network

    RIP 209 Wednesday, May 22, 13
  902. MOAR Git Bisecting Blaming Pull requests Submitting patches Rewriting history

    antisocial network RIP 209 Wednesday, May 22, 13
  903. MOAR Git Bisecting Blaming Pull requests Submitting patches Rewriting history

    Log formatting antisocial network RIP 209 Wednesday, May 22, 13
  904. MOAR Git Bisecting Blaming Pull requests Submitting patches Rewriting history

    Log formatting git help --all antisocial network RIP 209 Wednesday, May 22, 13
  905. pgTAP Skillz antisocial network RIP 210 Wednesday, May 22, 13

  906. pgTAP Skillz TDDD antisocial network RIP 210 Wednesday, May 22,

    13
  907. pgTAP Skillz TDDD Schema testing antisocial network RIP 210 Wednesday,

    May 22, 13
  908. pgTAP Skillz TDDD Schema testing Scalar testing antisocial network RIP

    210 Wednesday, May 22, 13
  909. pgTAP Skillz TDDD Schema testing Scalar testing Functional testing antisocial

    network RIP 210 Wednesday, May 22, 13
  910. pgTAP Skillz TDDD Schema testing Scalar testing Functional testing Relational

    testing antisocial network RIP 210 Wednesday, May 22, 13
  911. MOAR pgTAP antisocial network RIP 211 Wednesday, May 22, 13

  912. MOAR pgTAP Testing privileges antisocial network RIP 211 Wednesday, May

    22, 13
  913. MOAR pgTAP Testing privileges Mocking interfaces antisocial network RIP 211

    Wednesday, May 22, 13
  914. MOAR pgTAP Testing privileges Mocking interfaces Custom test functions antisocial

    network RIP 211 Wednesday, May 22, 13
  915. MOAR pgTAP Testing privileges Mocking interfaces Custom test functions xUnit-style

    testing antisocial network RIP 211 Wednesday, May 22, 13
  916. MOAR pgTAP Testing privileges Mocking interfaces Custom test functions xUnit-style

    testing Tests maintained in functions antisocial network RIP 211 Wednesday, May 22, 13
  917. MOAR pgTAP Testing privileges Mocking interfaces Custom test functions xUnit-style

    testing Tests maintained in functions http:/ /pgtap.org/documentation.html antisocial network RIP 211 Wednesday, May 22, 13
  918. Sqitch Skillz antisocial network RIP 212 Wednesday, May 22, 13

  919. Sqitch Skillz Adding changes antisocial network RIP 212 Wednesday, May

    22, 13
  920. Sqitch Skillz Adding changes Dependency management antisocial network RIP 212

    Wednesday, May 22, 13
  921. Sqitch Skillz Adding changes Dependency management Deploying changes antisocial network

    RIP 212 Wednesday, May 22, 13
  922. Sqitch Skillz Adding changes Dependency management Deploying changes Verifying changes

    antisocial network RIP 212 Wednesday, May 22, 13
  923. Sqitch Skillz Adding changes Dependency management Deploying changes Verifying changes

    Reverting changes antisocial network RIP 212 Wednesday, May 22, 13
  924. Sqitch Skillz Adding changes Dependency management Deploying changes Verifying changes

    Reverting changes Rebasing changes antisocial network RIP 212 Wednesday, May 22, 13
  925. Sqitch Skillz Adding changes Dependency management Deploying changes Verifying changes

    Reverting changes Rebasing changes Reworking changes antisocial network RIP 212 Wednesday, May 22, 13
  926. Sqitch Skillz Adding changes Dependency management Deploying changes Verifying changes

    Reverting changes Rebasing changes Reworking changes antisocial network RIP 212 Wednesday, May 22, 13
  927. MOAR Sqitch antisocial network RIP 213 Wednesday, May 22, 13

  928. MOAR Sqitch Cross-project dependencies antisocial network RIP 213 Wednesday, May

    22, 13
  929. MOAR Sqitch Cross-project dependencies Multiple projects, one database antisocial network

    RIP 213 Wednesday, May 22, 13
  930. MOAR Sqitch Cross-project dependencies Multiple projects, one database Changing Branches

    antisocial network RIP 213 Wednesday, May 22, 13
  931. MOAR Sqitch Cross-project dependencies Multiple projects, one database Changing Branches

    Checkout command antisocial network RIP 213 Wednesday, May 22, 13
  932. MOAR Sqitch Cross-project dependencies Multiple projects, one database Changing Branches

    Checkout command Reverts to last common change antisocial network RIP 213 Wednesday, May 22, 13
  933. MOAR Sqitch Cross-project dependencies Multiple projects, one database Changing Branches

    Checkout command Reverts to last common change Changes Git branch antisocial network RIP 213 Wednesday, May 22, 13
  934. MOAR Sqitch Cross-project dependencies Multiple projects, one database Changing Branches

    Checkout command Reverts to last common change Changes Git branch Deploys antisocial network RIP 213 Wednesday, May 22, 13
  935. MOAR Sqitch Cross-project dependencies Multiple projects, one database Changing Branches

    Checkout command Reverts to last common change Changes Git branch Deploys sqitch help antisocial network RIP 213 Wednesday, May 22, 13
  936. Good luck out there. antisocial network RIP 214 Wednesday, May

    22, 13
  937. Agile Database Development David E. Wheeler PGCon 2013 Ottawa 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. iovation 215 Wednesday, May 22, 13