prick 0.2.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -5
  3. data/Gemfile +4 -1
  4. data/TODO +10 -0
  5. data/doc/prick.txt +114 -0
  6. data/exe/prick +328 -402
  7. data/lib/ext/fileutils.rb +18 -0
  8. data/lib/ext/forward_method.rb +18 -0
  9. data/lib/ext/shortest_path.rb +44 -0
  10. data/lib/prick.rb +20 -10
  11. data/lib/prick/branch.rb +254 -0
  12. data/lib/prick/builder.rb +164 -0
  13. data/lib/prick/cache.rb +34 -0
  14. data/lib/prick/command.rb +19 -11
  15. data/lib/prick/constants.rb +122 -48
  16. data/lib/prick/database.rb +28 -20
  17. data/lib/prick/diff.rb +125 -0
  18. data/lib/prick/exceptions.rb +15 -3
  19. data/lib/prick/git.rb +77 -30
  20. data/lib/prick/head.rb +183 -0
  21. data/lib/prick/migration.rb +40 -200
  22. data/lib/prick/program.rb +493 -0
  23. data/lib/prick/project.rb +523 -351
  24. data/lib/prick/rdbms.rb +4 -13
  25. data/lib/prick/schema.rb +16 -90
  26. data/lib/prick/share.rb +64 -0
  27. data/lib/prick/state.rb +192 -0
  28. data/lib/prick/version.rb +62 -29
  29. data/libexec/strip-comments +33 -0
  30. data/make_releases +48 -345
  31. data/make_schema +10 -0
  32. data/prick.gemspec +14 -23
  33. data/share/diff/diff.after-tables.sql +4 -0
  34. data/share/diff/diff.before-tables.sql +4 -0
  35. data/share/diff/diff.tables.sql +8 -0
  36. data/share/migration/diff.tables.sql +8 -0
  37. data/share/migration/features.yml +6 -0
  38. data/share/migration/migrate.sql +3 -0
  39. data/share/migration/migrate.yml +8 -0
  40. data/share/migration/tables.sql +3 -0
  41. data/share/schema/build.yml +14 -0
  42. data/share/schema/schema.sql +5 -0
  43. data/share/schema/schema/build.yml +3 -0
  44. data/share/schema/schema/prick/build.yml +14 -0
  45. data/share/schema/schema/prick/data.sql +7 -0
  46. data/share/schema/schema/prick/schema.sql +5 -0
  47. data/share/{schemas/prick/schema.sql → schema/schema/prick/tables.sql} +2 -5
  48. data/{file → share/schema/schema/public/.keep} +0 -0
  49. data/share/schema/schema/public/build.yml +14 -0
  50. data/share/schema/schema/public/schema.sql +3 -0
  51. data/test_assorted +192 -0
  52. data/test_feature +112 -0
  53. data/test_refactor +34 -0
  54. data/test_single_dev +83 -0
  55. metadata +43 -68
  56. data/lib/prick/build.rb +0 -376
  57. data/lib/prick/migra.rb +0 -22
  58. data/share/schemas/prick/data.sql +0 -8
@@ -0,0 +1,34 @@
1
+
2
+ module Prick
3
+ class Cache
4
+ def initialize
5
+ end
6
+
7
+ def exist?(version)
8
+ File.exist?(file(version))
9
+ end
10
+
11
+ def list
12
+ Dir.glob(File.join(CACHE_DIR, "*.sql.gz"))
13
+ end
14
+
15
+ def load(database, version)
16
+ Rdbms.load(database, file(version))
17
+ end
18
+
19
+ def save(database, version = database.version)
20
+ Rdbms.save(database, file(version))
21
+ end
22
+
23
+ # Returns list of removed files
24
+ def clean
25
+ l = list
26
+ FileUtils.rm(l)
27
+ l
28
+ end
29
+
30
+ def file(version)
31
+ File.join(CACHE_DIR, "#{version}.sql.gz")
32
+ end
33
+ end
34
+ end
data/lib/prick/command.rb CHANGED
@@ -14,14 +14,13 @@ module Command
14
14
  end
15
15
  end
16
16
 
17
- # Execute the shell command 'cmd' and return the output as an array of
18
- # strings
19
- #
20
- # If :stderr is true, it returns return a tuple of [stdout, stderr] instead
21
- #
22
- # The shell command is executed with the `errexit` and `pipefail` bash
23
- # options. It raises a Command::Error exception if the command fails unless
24
- # :fail is true. The exit status of the last command is stored in ::status
17
+ # Execute the shell command 'cmd' and return standard output as an array of
18
+ # strings while stderr is passed through unless stderr: is false. If stderr:
19
+ # is true, it returns a tuple of [stdout, stderr] instead. The shell command
20
+ # is executed with the `errexit` and `pipefail` bash options
21
+ #
22
+ # It raises a Command::Error exception if the command fails unless :fail is
23
+ # true. The exit status of the last command is stored in ::status
25
24
  #
26
25
  def command(cmd, stderr: false, fail: true)
27
26
  cmd = "set -o errexit\nset -o pipefail\n#{cmd}"
@@ -62,10 +61,19 @@ module Command
62
61
  pr[0].close
63
62
  pe[0].close
64
63
 
64
+ result =
65
+ case stderr
66
+ when true; [out, err]
67
+ when false; out
68
+ when NilClass; $stderr.puts err
69
+ else
70
+ raise Internal, "Unexpected value for :stderr - #{stderr.inspect}"
71
+ end
72
+
65
73
  if @status == 0 || fail == false
66
- stderr ? [out, err] : out
67
- else
68
- raise Command::Error.new((out + err).join("\n") + "\n", status, out, err)
74
+ result
75
+ elsif fail
76
+ raise Command::Error.new("\n" + cmd + "\n" + (out + err).join("\n") + "\n", status, out, err)
69
77
  end
70
78
  end
71
79
 
@@ -1,62 +1,96 @@
1
1
 
2
2
  module Prick
3
+ ### DIRECTORIES AND FILE NAMES
4
+
3
5
  # Shared files (part of the installation)
4
6
  SHARE_PATH = "#{File.dirname(File.dirname(__dir__))}/share"
7
+ LIBEXEC_PATH = "#{File.dirname(File.dirname(__dir__))}/libexec"
5
8
 
6
9
  # Project directories
7
10
  DIRS = [
8
- RELEASE_DIR = "releases",
9
- MIGRATION_DIR = "migrations",
10
- FEATURE_DIR = "features",
11
- SCHEMA_DIR = "schemas",
11
+ MIGRATION_DIR = "migration",
12
+ SCHEMA_DIR = "schema",
12
13
  PRICK_DIR = "#{SCHEMA_DIR}/prick",
13
14
  PUBLIC_DIR = "#{SCHEMA_DIR}/public",
14
15
  VAR_DIR = "var",
15
16
  CACHE_DIR = "#{VAR_DIR}/cache",
17
+ SPOOL_DIR = "#{VAR_DIR}/spool",
16
18
  TMP_DIR = "tmp",
17
19
  CLONE_DIR = "tmp/clone",
18
20
  SPEC_DIR = "spec"
19
21
  ]
20
22
 
23
+ # The project state file
24
+ PROJECT_STATE_FILE = ".prick-project"
25
+ PROJECT_STATE_PATH = PROJECT_STATE_FILE
26
+
27
+ # The .prick-version file
28
+ PRICK_VERSION_FILE = ".prick-version"
29
+ PRICK_VERSION_PATH = PRICK_VERSION_FILE
30
+
31
+ # The prick.versions data file. This is where the Schema saves its version
32
+ SCHEMA_VERSION_FILE = "data.sql"
33
+ SCHEMA_VERSION_PATH = File.join(PRICK_DIR, SCHEMA_VERSION_FILE)
34
+
35
+ # The the .prick-migration file
36
+ PRICK_MIGRATION_FILE = ".prick-migration"
37
+ PRICK_MIGRATION_PATH = File.join(MIGRATION_DIR, PRICK_MIGRATION_FILE)
38
+
39
+ # The the .prick-feature file
40
+ PRICK_FEATURE_FILE = ".prick-feature"
41
+ PRICK_FEATURE_PATH = File.join(MIGRATION_DIR, PRICK_FEATURE_FILE)
42
+
43
+ # The strip-comments executable
44
+ STRIP_COMMENTS_NAME = "strip-comments"
45
+ STRIP_COMMENTS_PATH = File.join(LIBEXEC_PATH, "strip-comments")
46
+
47
+ # Diff files
48
+ DIFF_FILE = "diff.sql"
49
+ BEFORE_TABLES_DIFF_NAME = "diff.before-tables.sql"
50
+ TABLES_DIFF_NAME = "diff.tables.sql"
51
+ AFTER_TABLES_DIFF_NAME = "diff.after-tables.sql"
52
+
53
+ BEFORE_TABLES_DIFF_PATH = File.join(MIGRATION_DIR, BEFORE_TABLES_DIFF_NAME)
54
+ TABLES_DIFF_PATH = File.join(MIGRATION_DIR, TABLES_DIFF_NAME)
55
+ AFTER_TABLES_DIFF_PATH = File.join(MIGRATION_DIR, AFTER_TABLES_DIFF_NAME)
56
+
57
+ TABLES_DIFF_SHARE_PATH = File.join(SHARE_PATH, "diff", TABLES_DIFF_NAME)
58
+
59
+
21
60
  # Dump files
22
61
  DUMP_EXT = "dump.gz"
23
62
  DUMP_GLOB = "*-[0-9]*.#{DUMP_EXT}"
24
63
  def self.dump_glob(project_name) "#{project_name}-*.#{DUMP_EXT}" end
25
64
 
65
+ ### REGULAR EXPRESSIONS
66
+
67
+ # Matches a system name. System names are used for objects that are external to prick
68
+ # (like usernames)
69
+ NAME_SUB_RE = /[a-z][a-z0-9_-]*/
70
+ NAME_RE = /^#{NAME_SUB_RE}$/
26
71
 
27
72
  # Matches an identifier. Identifiers consist of lower case letters, digits
28
73
  # and underscores but not dashes because they're used as separators
29
74
  IDENT_SUB_RE = /[a-z][a-z0-9_]*/
30
75
  IDENT_RE = /^#{IDENT_SUB_RE}$/
31
76
 
32
- # Matches an uppercase identifier
33
- # UPCASE_IDENT_SUB_RE = /[A-Z][A-Z0-9_]*/
34
- # UPCASE_IDENT_RE = /#{UPCASE_IDENT_SUB_RE}/
35
-
36
- # A (system) name. Names are used for projects and usernames that are
37
- # external to prick and can include both dashes and underscores but dashes
38
- # have to be followed by a character and not a digit so 'ident-1234' is not
39
- # allowed but 'ident_1234' and 'ident1234' are
40
- NAME_SUB_RE = /#{IDENT_SUB_RE}/
41
- NAME_RE = /^#{NAME_SUB_RE}$/
42
-
43
77
  # Matches a project name
44
- PROJECT_NAME_SUB_RE = NAME_SUB_RE
45
- PROJECT_NAME_RE = NAME_RE
78
+ PROJECT_NAME_SUB_RE = IDENT_SUB_RE
79
+ PROJECT_NAME_RE = IDENT_RE
46
80
 
47
81
  # Matches a custom name
48
- CUSTOM_NAME_SUB_RE = NAME_SUB_RE
49
- CUSTOM_NAME_RE = NAME_RE
82
+ CUSTOM_NAME_SUB_RE = IDENT_SUB_RE
83
+ CUSTOM_NAME_RE = IDENT_RE
50
84
 
51
85
  # Matches a feature name
52
- FEATURE_NAME_SUB_RE = NAME_SUB_RE
53
- FEATURE_NAME_RE = NAME_RE
86
+ FEATURE_NAME_SUB_RE = /(?!initial)#{IDENT_SUB_RE}/
87
+ FEATURE_NAME_RE = /^#{FEATURE_NAME_SUB_RE}$/
54
88
 
55
89
  # Matches a postgres user name
56
90
  USER_NAME_SUB_RE = NAME_SUB_RE
57
91
  USER_NAME_RE = NAME_RE
58
92
 
59
- # Matches a major.minor.patch version
93
+ # Matches a major.minor.patch ('MMP') version
60
94
  #
61
95
  # The *_SEMVER REs are derived from the canonical RE
62
96
  #
@@ -81,15 +115,48 @@ module Prick
81
115
  SEMVER_SUB_RE = /#{MMP_SEMVER_SUB_RE}(?:-#{PRE_SEMVER_SUB_RE})?/
82
116
  SEMVER_RE = /^#{SEMVER_SUB_RE}$/
83
117
 
84
- # Version RE. The general syntax for a version is '<custom>-<version>_<feature>'
118
+ # Tag RE. The general syntax for a tag is '<custom>-v<version>_<feature>'
85
119
  #
86
120
  # The RE defines the following captures:
87
121
  # $1 - custom name, can be nil
88
122
  # $2 - semantic version
89
123
  # $3 - feature name, can be nil
90
124
  #
125
+ TAG_SUB_RE = /
126
+ (?:(#{CUSTOM_NAME_SUB_RE})-)?
127
+ v
128
+ (#{SEMVER_SUB_RE})
129
+ (?:_(#{FEATURE_NAME_SUB_RE}))?
130
+ /x
131
+ TAG_RE = /^#{TAG_SUB_RE}$/
132
+
133
+ # TODO: Handle initial branches (0.0.0-initial)
134
+
135
+ # Branch RE. The general syntax for a branch is '<custom>-<version>_<feature>'
136
+ #
137
+ # The RE defines the following captures:
138
+ # $1 - custom name, can be nil
139
+ # $2 - semantic version
140
+ # $3 - feature name, can be nil
141
+ #
142
+ BRANCH_SUB_RE = /
143
+ (?:(#{CUSTOM_NAME_SUB_RE})-)?
144
+ (#{SEMVER_SUB_RE})
145
+ (?:_(#{FEATURE_NAME_SUB_RE}))?
146
+ /x
147
+ BRANCH_RE = /^#{BRANCH_SUB_RE}$/
148
+
149
+ # Tag or branch RE. The general syntax for a branch is '<custom>-v?<version>_<feature>'
150
+ #
151
+ # The RE defines the following captures:
152
+ # $1 - custom name, can be nil
153
+ # $2 - tag, nil or 'v'
154
+ # $3 - semantic version
155
+ # $4 - feature name, can be nil
156
+ #
91
157
  VERSION_SUB_RE = /
92
158
  (?:(#{CUSTOM_NAME_SUB_RE})-)?
159
+ (v)?
93
160
  (#{SEMVER_SUB_RE})
94
161
  (?:_(#{FEATURE_NAME_SUB_RE}))?
95
162
  /x
@@ -113,24 +180,11 @@ module Prick
113
180
  # $1 - custom name, can be nil
114
181
  # $2 - semantic version
115
182
  #
116
- RELEASE_SUB_RE = /
117
- (?:(#{CUSTOM_NAME_SUB_RE})-)?
118
- (#{MMP_SEMVER_SUB_RE})
119
- /x
120
- RELEASE_RE = /^#{RELEASE_SUB_RE}$/
121
-
122
- # Migration RE. The syntax is <version>_<version>
123
- #
124
- # The RE defines the following captures
125
- # $1 - from version
126
- # $2 - from custom name, can be nil
127
- # $3 - from semantic version
128
- # $4 - to version
129
- # $5 - to custom name, can be nil
130
- # $6 - to semantic version
131
- #
132
- MIGRATION_SUB_RE = /(#{RELEASE_SUB_RE})_(#{RELEASE_SUB_RE})/
133
- MIGRATION_RE = /^#{MIGRATION_SUB_RE}$/
183
+ # RELEASE_SUB_RE = /
184
+ # (?:(#{CUSTOM_NAME_SUB_RE})-)?
185
+ # (#{MMP_SEMVER_SUB_RE})
186
+ # /x
187
+ # RELEASE_RE = /^#{RELEASE_SUB_RE}$/
134
188
 
135
189
  # Matches a prerelease branch
136
190
  #
@@ -138,11 +192,11 @@ module Prick
138
192
  # $1 - custom name, can be nil
139
193
  # $2 - semantic version
140
194
  #
141
- PRERELEASE_SUB_RE = /
142
- (?:(#{CUSTOM_NAME_SUB_RE})-)?
143
- (#{MMP_SEMVER_SUB_RE}-#{PRE_SEMVER_SUB_RE})
144
- /x
145
- PRERELEASE_RE = /^#{PRERELEASE_SUB_RE}$/
195
+ # PRERELEASE_SUB_RE = /
196
+ # (?:(#{CUSTOM_NAME_SUB_RE})-)?
197
+ # (#{MMP_SEMVER_SUB_RE}-#{PRE_SEMVER_SUB_RE})
198
+ # /x
199
+ # PRERELEASE_RE = /^#{PRERELEASE_SUB_RE}$/
146
200
 
147
201
  # Matches a feature branch
148
202
  #
@@ -151,8 +205,21 @@ module Prick
151
205
  # $2 - semantic version
152
206
  # $3 - feature name
153
207
  #
154
- FEATURE_SUB_RE = /#{ABSTRACT_RELEASE_SUB_RE}_(#{FEATURE_NAME_SUB_RE})/
155
- FEATURE_RE = /^#{FEATURE_SUB_RE}$/
208
+ # FEATURE_SUB_RE = /#{ABSTRACT_RELEASE_SUB_RE}_(#{FEATURE_NAME_SUB_RE})/
209
+ # FEATURE_RE = /^#{FEATURE_SUB_RE}$/
210
+
211
+ # Migration RE. The syntax is <version>_<version>
212
+ #
213
+ # The RE defines the following captures
214
+ # $1 - from version
215
+ # $2 - from custom name, can be nil
216
+ # $3 - from semantic version
217
+ # $4 - to version
218
+ # $5 - to custom name, can be nil
219
+ # $6 - to semantic version
220
+ #
221
+ # MIGRATION_SUB_RE = /(#{RELEASE_SUB_RE})_(#{RELEASE_SUB_RE})/
222
+ # MIGRATION_RE = /^#{MIGRATION_SUB_RE}$/
156
223
 
157
224
  # Project release RE. The general syntax is '<project>-<custom>-<version>'
158
225
  #
@@ -195,5 +262,12 @@ module Prick
195
262
  ALL_DATABASES_RE = /^#{ALL_DATABASES_SUB_RE}$/
196
263
  def self.all_databases_sub_re(project_name) /(#{project_name})(?:-(#{ABSTRACT_RELEASE_SUB_RE}))?/ end
197
264
  def self.all_databases_re(project_name) /^#{all_databases_sub_re(project_name)}$/ end
265
+
266
+ # Matches temporary databases. Mostly useful when debugging because temporary databases
267
+ # should be deleted on exit
268
+ TMP_DATABASES_SUB_RE = /#{PROJECT_NAME_SUB_RE}-(?:base|next)/
269
+ TMP_DATABASES_RE = /^#{TMP_DATABASES_SUB_RE}$/
270
+ def self.tmp_databases_sub_re(project_name) /#{project_name}-(?:base|next)/ end
271
+ def self.tmp_databases_re(project_name) /^#{tmp_databases_sub_re(project_name)}$/ end
198
272
  end
199
273
 
@@ -1,26 +1,29 @@
1
1
 
2
- require "prick/ensure.rb"
3
-
4
2
  module Prick
5
3
  class Database
6
4
  attr_reader :name
7
5
  attr_reader :user
8
6
 
9
7
  def initialize(name, user)
8
+ name != "" or raise "Illegal database name"
10
9
  @name = name
11
10
  @user = user
12
11
  @version = nil
13
12
  end
14
13
 
15
- def version
16
- @version ||= begin
17
- version =
18
- if exist? && Rdbms.exist_table?(name, "prick", "versions")
19
- Rdbms.select(name, "select version from prick.versions")&.first&.first
20
- else
21
- nil
22
- end
23
- version && Version.new(version)
14
+ def version(cache: true)
15
+ if cache && @version
16
+ @version
17
+ else
18
+ @version = begin
19
+ version =
20
+ if exist? && Rdbms.exist_table?(name, "prick", "versions")
21
+ Rdbms.select(name, "select version from prick.versions")&.first&.first
22
+ else
23
+ nil
24
+ end
25
+ version && Version.new(version)
26
+ end
24
27
  end
25
28
  end
26
29
 
@@ -42,17 +45,22 @@ module Prick
42
45
  def recreate() drop if exist?; create; @version = nil end
43
46
  def drop() Rdbms.drop_database(name, fail: false); @version = nil end
44
47
 
45
- def loaded?() exist? && !version.nil? end
46
- def load(file) Rdbms.load(name, file, user: user); @version = nil end
48
+ def loaded?() !version.nil? end
49
+
50
+ def load(file)
51
+ !loaded? or raise Internal, "Database #{name} is already loaded"
52
+ Rdbms.load(name, file, user: user)
53
+ version # Provoke load of version
54
+ end
47
55
 
48
- def save(file) Rdbms.save(name, file); @version = nil end
56
+ def save(file)
57
+ loaded? or raise Internal, "Database #{name} is not loaded"
58
+ Rdbms.save(name, file)
59
+ @version = nil
60
+ end
49
61
 
50
- include Ensure
62
+ def clean() recreate end # TODO: Find solution that doesn't involve dropping the database
51
63
 
52
- private
53
- @states = {
54
- exist: [:create, :drop],
55
- loaded: [:exist, :load, :recreate]
56
- }
64
+ def to_s() name end
57
65
  end
58
66
  end
data/lib/prick/diff.rb ADDED
@@ -0,0 +1,125 @@
1
+ module Prick
2
+ class Diff
3
+ # Diff as a list of lines
4
+ attr_reader :diff
5
+
6
+ # Subject of the diff
7
+ attr_reader :before_table_changes
8
+ attr_reader :table_changes
9
+ attr_reader :after_table_changes
10
+
11
+ def initialize(db1, db2)
12
+ @db1, @db2 = db1, db2
13
+ do_diff
14
+ split_on_table_changes
15
+ end
16
+
17
+ def self.same?(db1, db2) Diff.new(db1, db2).same? end
18
+
19
+ # Return true if the two databases are equal. Named #same? to avoid name
20
+ # collision with the built in #equal?
21
+ def same?() diff.empty? end
22
+
23
+ # Write the diff between the databases to the given file(s). Return true if
24
+ # the databases are equal
25
+ def write_segments(file1, file2 = nil, file3 = nil, mark: true)
26
+ if file2.nil? && file3.nil?
27
+ file2 = file3 = file1
28
+ elsif file2.nil? ^ !file3.nil?
29
+ raise Internal, "Either none or both of `file2` and `file3` should be nil"
30
+ end
31
+ write_segment(file1, :before_table_changes, mark: mark)
32
+ write_segment(file2, :table_changes, mark: mark)
33
+ write_segment(file3, :after_table_changes, mark: mark)
34
+ end
35
+
36
+ def write_segment(file, segment, mark: true)
37
+ lines = self.send(segment)
38
+ if lines.empty?
39
+ FileUtils.rm_f(file) if file != "/dev/stdout"
40
+ else
41
+ File.open(file, "w") { |f|
42
+ f.puts "--" + segment.to_s.gsub("_", " ").upcase if mark
43
+ f.puts lines
44
+ }
45
+ end
46
+ end
47
+
48
+ private
49
+ def do_diff(file = nil)
50
+ command = "migra --unsafe --with-privileges postgres:///#{@db1} postgres:///#{@db2}"
51
+ @diff = Command.command(command, fail: false)
52
+ [0,2].include?(Command.status) or
53
+ raise Internal, "migrate command failed with status #{Command.status}: #{command}"
54
+ end
55
+
56
+ # Initialize table change variables
57
+ def split_on_table_changes
58
+ @before_table_changes = []
59
+ @table_changes = []
60
+ @after_table_changes = []
61
+
62
+ before = true
63
+ tables = false
64
+ after = false
65
+
66
+ in_table = false
67
+
68
+ diff.each { |l|
69
+ if before
70
+ if l =~ /^alter table/
71
+ @table_changes << l
72
+ before = false
73
+ tables = true
74
+ elsif l =~ /^create table/
75
+ @table_changes << l
76
+ before = false
77
+ tables = true
78
+ in_table = true
79
+ elsif l =~ /^drop table/
80
+ @table_changes << l
81
+ before = false
82
+ tables = true
83
+ else
84
+ @before_table_changes << l
85
+ end
86
+ elsif tables
87
+ if in_table
88
+ if l =~ /^\)/
89
+ @table_changes << l
90
+ in_table = false
91
+ else
92
+ @table_changes << l
93
+ end
94
+ elsif l =~ /^alter table/
95
+ @table_changes << l
96
+ elsif l =~ /^create table/
97
+ @table_changes << l
98
+ in_table = true
99
+ elsif l =~ /^drop table/
100
+ @table_changes << l
101
+ elsif l =~ /^\s*$/
102
+ @table_changes << l
103
+ else
104
+ @after_table_changes << l
105
+ tables = false
106
+ after = true
107
+ end
108
+ else
109
+ @after_table_changes << l
110
+ end
111
+ }
112
+ end
113
+ end
114
+ end
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+