tern 0.7.0 → 0.7.1

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.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -211,6 +211,14 @@ This will result in:
211
211
 
212
212
  DROP FUNCTION rendered_function();
213
213
 
214
+ Version History
215
+ ===============
216
+
217
+ * **0.7.1**
218
+ * Print friendly error message when database error occurs instead of stack trace.
219
+ * **0.7.0**
220
+ * Added ERB processing to SQL files
221
+
214
222
  License
215
223
  =======
216
224
 
@@ -2,6 +2,9 @@ require 'sequel'
2
2
  require 'yaml'
3
3
  require 'erb'
4
4
 
5
+ class TernError < StandardError
6
+ end
7
+
5
8
  class Parser
6
9
  def render_text(text)
7
10
  ERB.new(text).result(binding)
@@ -14,12 +17,25 @@ class Parser
14
17
  end
15
18
 
16
19
  class Change
20
+ class DatabaseError < TernError
21
+ end
22
+
17
23
  SPLIT_MARKER = '---- CREATE above / DROP below ----'
18
24
 
19
25
  def self.parse(string)
20
26
  create_sql, drop_sql = Parser.new.render_text(string).split(SPLIT_MARKER)
21
27
  [create_sql, drop_sql]
22
28
  end
29
+
30
+ def run(sql, context)
31
+ DB.run sql
32
+ rescue Sequel::DatabaseError
33
+ raise DatabaseError, "Error in #{context}\n#{$!.to_s}"
34
+ end
35
+
36
+ attr_reader :create_sql
37
+ attr_reader :drop_sql
38
+ attr_reader :name
23
39
  end
24
40
 
25
41
  class Definition < Change
@@ -41,7 +57,7 @@ class Definition < Change
41
57
 
42
58
  def load_existing
43
59
  table.order(:id).all.map do |row|
44
- new row[:id], row[:sequence], row[:create_sql], row[:drop_sql]
60
+ new "existing definition: #{row[:id]}", row[:id], row[:sequence], row[:create_sql], row[:drop_sql]
45
61
  end.group_by { |d| d.sequence }
46
62
  end
47
63
 
@@ -51,8 +67,9 @@ class Definition < Change
51
67
 
52
68
  definition_sequences.keys.each do |sequence|
53
69
  definition_sequences[sequence] = definition_sequences[sequence].map do |f|
54
- create_sql, drop_sql = parse File.read(File.join(sequence_dir, f))
55
- Definition.new nil, sequence, create_sql, drop_sql
70
+ path = File.join(sequence_dir, f)
71
+ create_sql, drop_sql = parse File.read(path)
72
+ Definition.new path, nil, sequence, create_sql, drop_sql
56
73
  end
57
74
  end
58
75
 
@@ -62,10 +79,9 @@ class Definition < Change
62
79
 
63
80
  attr_reader :id
64
81
  attr_reader :sequence
65
- attr_reader :create_sql
66
- attr_reader :drop_sql
67
-
68
- def initialize(id, sequence, create_sql, drop_sql)
82
+
83
+ def initialize(name, id, sequence, create_sql, drop_sql)
84
+ @name = name
69
85
  @id = id
70
86
  @sequence = sequence
71
87
  @create_sql = create_sql
@@ -73,12 +89,12 @@ class Definition < Change
73
89
  end
74
90
 
75
91
  def create
76
- DB.run create_sql
92
+ run create_sql, name
77
93
  table.insert :sequence => sequence, :create_sql => create_sql, :drop_sql => drop_sql
78
94
  end
79
95
 
80
96
  def drop
81
- DB.run drop_sql
97
+ run drop_sql, name
82
98
  table.filter(:id => id).delete
83
99
  end
84
100
 
@@ -88,13 +104,13 @@ class Definition < Change
88
104
  end
89
105
 
90
106
  class Alteration < Change
91
- class IrreversibleAlteration < StandardError
107
+ class IrreversibleAlteration < TernError
92
108
  end
93
109
 
94
- class MissingAlteration < StandardError
110
+ class MissingAlteration < TernError
95
111
  end
96
112
 
97
- class DuplicateAlteration < StandardError
113
+ class DuplicateAlteration < TernError
98
114
  end
99
115
 
100
116
  class << self
@@ -126,7 +142,7 @@ class Alteration < Change
126
142
  raise "This can't happen" unless File.basename(path) =~ /^(\d+)/
127
143
  version = $1.to_i
128
144
  create_sql, drop_sql = parse File.read(path)
129
- new version, create_sql, drop_sql
145
+ new path, version, create_sql, drop_sql
130
146
  end.sort_by(&:version)
131
147
 
132
148
  alterations.each_with_index do |a, i|
@@ -140,23 +156,22 @@ class Alteration < Change
140
156
  end
141
157
 
142
158
  attr_reader :version
143
- attr_reader :create_sql
144
- attr_reader :drop_sql
145
159
 
146
- def initialize(version, create_sql, drop_sql)
160
+ def initialize(name, version, create_sql, drop_sql)
161
+ @name = name
147
162
  @version = version
148
163
  @create_sql = create_sql
149
164
  @drop_sql = drop_sql
150
165
  end
151
166
 
152
167
  def create
153
- DB.run create_sql
168
+ run create_sql, name
154
169
  Alteration.version = version
155
170
  end
156
171
 
157
172
  def drop
158
173
  raise IrreversibleAlteration, "Alteration #{version.to_s.rjust(3, "0")} is irreversible" unless drop_sql
159
- DB.run drop_sql
174
+ run drop_sql, name
160
175
  Alteration.version = version - 1
161
176
  end
162
177
  end
@@ -33,7 +33,7 @@ class App < Thor
33
33
  begin
34
34
  tern = Tern.new(config['alterations']['table'], config['alterations']['column'], config['definitions']['table'])
35
35
  tern.migrate(:version => options["alteration_version"], :sequences => options["definition_sequences"])
36
- rescue Alteration::IrreversibleAlteration, Alteration::MissingAlteration, Alteration::DuplicateAlteration
36
+ rescue TernError
37
37
  say $!, :red
38
38
  end
39
39
  end
@@ -0,0 +1,8 @@
1
+ CREATE TABLE people(
2
+ id serial PRIMARY KEY,
3
+ name varchar NOT NULL
4
+ );
5
+
6
+ ---- CREATE above / DROP below ----
7
+
8
+ DROP TABLE people;
@@ -0,0 +1,8 @@
1
+ CREATE TABLE animals(
2
+ id serial PRIMARY KEY,
3
+ name varchar NOT NULL
4
+ );
5
+
6
+ ---- CREATE above / DROP below ----
7
+
8
+ DROP TABLE animals;
@@ -0,0 +1,10 @@
1
+ INVALID SQL;
2
+
3
+ CREATE TABLE plants(
4
+ id serial PRIMARY KEY,
5
+ name varchar NOT NULL
6
+ );
7
+
8
+ ---- CREATE above / DROP below ----
9
+
10
+ DROP TABLE plants;
@@ -0,0 +1,15 @@
1
+ alterations:
2
+ table: tern_alterations
3
+ column: version
4
+ definitions:
5
+ table: tern_definitions
6
+ environments:
7
+ development:
8
+ adapter: postgres
9
+ database: tern_test_development
10
+ test:
11
+ adapter: postgres
12
+ database: tern_test_test
13
+ production:
14
+ adapter: postgres
15
+ database: tern_test_production
@@ -0,0 +1,18 @@
1
+ # Put the relative path to your definition files in the sequence they should run.
2
+ #
3
+ # Most definitions should go in the default list. These will be dropped and
4
+ # recreated every migration.
5
+ #
6
+ # Definitions that should not automatically be dropped and created can be put in
7
+ # different lists. This is useful for definitions that make take prohibitively
8
+ # to drop and create every migration such as check constraints.
9
+ #
10
+ # Run alternative sequences by specifying sequences in order to migrate command.
11
+ # Example: rake migrate sequences=expensive,default
12
+ #
13
+ # default:
14
+ # - ultimate_answer.sql
15
+ # expensive:
16
+ # - super_slow_check_constraint.sql
17
+
18
+ default: []
@@ -0,0 +1,7 @@
1
+ CREATE FUNCTION ultimate_answer() RETURNS integer AS $$
2
+ SELECT 42;
3
+ $$ LANGUAGE SQL;
4
+
5
+ ---- CREATE above / DROP below ----
6
+
7
+ DROP FUNCTION ultimate_answer();
@@ -0,0 +1,16 @@
1
+ Sequel.migration do
2
+ up do
3
+ run <<-END_SQL
4
+ CREATE TABLE people(
5
+ id serial PRIMARY KEY,
6
+ name varchar NOT NULL
7
+ );
8
+ END_SQL
9
+ end
10
+
11
+ down do
12
+ run <<-END_SQL
13
+ DROP TABLE people;
14
+ END_SQL
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ alterations:
2
+ table: tern_alterations
3
+ column: version
4
+ definitions:
5
+ table: tern_definitions
6
+ environments:
7
+ development:
8
+ adapter: postgres
9
+ database: tern_test_development
10
+ test:
11
+ adapter: postgres
12
+ database: tern_test_test
13
+ production:
14
+ adapter: postgres
15
+ database: tern_test_production
@@ -0,0 +1,19 @@
1
+ # Put the relative path to your definition files in the sequence they should run.
2
+ #
3
+ # Most definitions should go in the default list. These will be dropped and
4
+ # recreated every migration.
5
+ #
6
+ # Definitions that should not automatically be dropped and created can be put in
7
+ # different lists. This is useful for definitions that make take prohibitively
8
+ # to drop and create every migration such as check constraints.
9
+ #
10
+ # Run alternative sequences by specifying sequences in order to migrate command.
11
+ # Example: rake migrate sequences=expensive,default
12
+ #
13
+ # default:
14
+ # - ultimate_answer.sql
15
+ # expensive:
16
+ # - super_slow_check_constraint.sql
17
+
18
+ default:
19
+ - ultimate_answer.sql
@@ -0,0 +1,9 @@
1
+ INVALID SQL;
2
+
3
+ CREATE FUNCTION ultimate_answer() RETURNS integer AS $$
4
+ SELECT 42;
5
+ $$ LANGUAGE SQL;
6
+
7
+ ---- CREATE above / DROP below ----
8
+
9
+ DROP FUNCTION ultimate_answer();
@@ -233,5 +233,19 @@ describe "tern" do
233
233
  expect { @dev_db[:a].all }.to raise_error(Sequel::DatabaseError)
234
234
  end
235
235
  end
236
+
237
+ context "alteration with database error" do
238
+ it "prints an error message with file name" do
239
+ tern_migrate("spec/projects/alteration_with_error").should match /Error in alterations\/003_create_plants.sql/
240
+ end
241
+ end
242
+
243
+ context "definition with database error" do
244
+ it "prints an error message with file name" do
245
+ tern_migrate("spec/projects/definition_with_error").should match /Error in definitions\/ultimate_answer.sql/
246
+ end
247
+ end
248
+
249
+
236
250
  end
237
251
  end
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "tern"
6
- s.version = '0.7.0'
6
+ s.version = '0.7.1'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ["Jack Christensen"]
9
9
  s.email = ["jack@jackchristensen.com"]
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 7
8
- - 0
9
- version: 0.7.0
8
+ - 1
9
+ version: 0.7.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jack Christensen
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-04-06 00:00:00 -05:00
17
+ date: 2011-06-25 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -73,6 +73,7 @@ extra_rdoc_files: []
73
73
 
74
74
  files:
75
75
  - .gitignore
76
+ - .rspec
76
77
  - MIT-LICENSE
77
78
  - README.markdown
78
79
  - Rakefile
@@ -85,12 +86,22 @@ files:
85
86
  - lib/tern/generators/new/config.yml.tt
86
87
  - lib/tern/generators/new/definitions/sequence.yml
87
88
  - lib/tern/generators/new/definitions/ultimate_answer.sql.example
89
+ - spec/projects/alteration_with_error/alterations/001_create_people.sql
90
+ - spec/projects/alteration_with_error/alterations/002_create_animals.sql
91
+ - spec/projects/alteration_with_error/alterations/003_create_plants.sql
92
+ - spec/projects/alteration_with_error/config.yml
93
+ - spec/projects/alteration_with_error/definitions/sequence.yml
94
+ - spec/projects/alteration_with_error/definitions/ultimate_answer.sql.example
88
95
  - spec/projects/alterations/alterations/001_create_people.sql
89
96
  - spec/projects/alterations/alterations/002_create_animals.sql
90
97
  - spec/projects/alterations/alterations/003_create_plants.sql
91
98
  - spec/projects/alterations/config.yml
92
99
  - spec/projects/alterations/definitions/sequence.yml
93
100
  - spec/projects/alterations/definitions/ultimate_answer.sql.example
101
+ - spec/projects/definition_with_error/alterations/001_create_people.sql.example
102
+ - spec/projects/definition_with_error/config.yml
103
+ - spec/projects/definition_with_error/definitions/sequence.yml
104
+ - spec/projects/definition_with_error/definitions/ultimate_answer.sql
94
105
  - spec/projects/definitions/alterations/001_create_people.sql.example
95
106
  - spec/projects/definitions/config.yml
96
107
  - spec/projects/definitions/definitions/sequence.yml