sequel-annotate 1.3.1 → 1.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6bc04d174477ed481ef99f6d4173ed4ad691f55d4283c42cb971b8a32772bb41
4
- data.tar.gz: d8bfaa715162f40446c079e91dfa32555e18200578dce2f1ad218580157c8ca3
3
+ metadata.gz: 00ae8faeab78d5bf3db91c08be72e190c23c5937aff9a134b0f60d8a8a28fd46
4
+ data.tar.gz: 3324fec486219f6324ff300046ee1f80608c84621f3eb159e5192a0e7f42bdbf
5
5
  SHA512:
6
- metadata.gz: c45070f85dd3dd1acf89946a18463dd7f2245adb2881888b145c93b54dec5b294235adc603a1033ddb6ba2a611d198694d152950f8626a8f101a846c1977e8d8
7
- data.tar.gz: 574cee166afd77a7a9353fbeb3ebd4bbbaf2afeb4055265f0371c67218676596594ee316758e4cda2641f7da51a923d271ecfab64c429baf65f583a2ac3301cc
6
+ metadata.gz: 898b3c06f2728c69570071f04b14b506925d87e794b63fdbe0882bc710e03fc76c6c824f0c01384f96e19b1ee59894766722fa4bb12c668068794d632c3651c7
7
+ data.tar.gz: 0ac394e89f13a0d8f005b90ff7263fe882ce67aca63f9d19b7327d0561eb7666df04cb6e4031a01ad6f318c87372b7d59ae9aba39b38e0ffed870036ad1ff035
data/CHANGELOG CHANGED
@@ -1,3 +1,9 @@
1
+ === 1.4.0 (2018-11-15)
2
+
3
+ * Support adding borders to the beginning and end of comments via :border option (kreynolds) (#9)
4
+
5
+ * Support excluding indexes, constraints, and triggers from annotation via options (kreynolds) (#9)
6
+
1
7
  === 1.3.1 (2018-09-27)
2
8
 
3
9
  * Make sure all annotation lines are commented by handling newlines inside annotations (jeremyevans)
data/README.rdoc CHANGED
@@ -83,6 +83,15 @@ Then you can use the +:namespace+ option to set the namespace to use:
83
83
 
84
84
  Sequel::Annotate.annotate(Dir['models/*.rb'], namespace: 'ModelNamespace')
85
85
 
86
+ For PostgreSQL, you can optionally leave out indexes, foreign_keys, references,
87
+ triggers, and constraints by passing in false as a parameter as follows:
88
+
89
+ Sequel::Annotate.annotate(Dir['models/*.rb'], foreign_keys: false, :indexes: false, constraints: false)
90
+
91
+ The columns section can have a border on the top and bottom for easier visual distinction by setting the :border option to true
92
+
93
+ Sequel::Annotate.annotate(Dir['models/*.rb'], border: true)
94
+
86
95
  === Rake Task
87
96
 
88
97
  Here's an example rake task for sequel-annotate:
@@ -41,7 +41,7 @@ module Sequel
41
41
 
42
42
  if options[:position] == :before
43
43
  current = current.gsub(/\A#\sTable[^\n\r]+\r?\n(?:#[^\n\r]*\r?\n)*/m, '').lstrip
44
- current = "#{schema_comment}#{$/}#{$/}#{current}"
44
+ current = "#{schema_comment(options)}#{$/}#{$/}#{current}"
45
45
  else
46
46
  if m = current.reverse.match(/#{"#{$/}# Table: ".reverse}/m)
47
47
  offset = current.length - m.end(0) + 1
@@ -52,7 +52,7 @@ module Sequel
52
52
  current = current[0...offset].rstrip
53
53
  end
54
54
  end
55
- current += "#{$/}#{$/}#{schema_comment}"
55
+ current += "#{$/}#{$/}#{schema_comment(options)}"
56
56
  end
57
57
 
58
58
  if orig != current
@@ -67,17 +67,36 @@ module Sequel
67
67
  # key constraints in this table referencing other tables.
68
68
  # On PostgreSQL, also includes check constraints, triggers,
69
69
  # and foreign key constraints in other tables referencing this table.
70
- def schema_comment
70
+ #
71
+ # Options:
72
+ # :border :: Include a border above and below the comment.
73
+ # :indexes :: Do not include indexes in annotation if set to +false+.
74
+ # :foreign_keys :: Do not include foreign key constraints in annotation if set to +false+.
75
+ #
76
+ # PostgreSQL-specific options:
77
+ # :constraints :: Do not include check constraints if set to +false+.
78
+ # :references :: Do not include foreign key constraints in other tables referencing
79
+ # this table if set to +false+.
80
+ # :triggers :: Do not include triggers in annotation if set to +false+.
81
+ def schema_comment(options = {})
71
82
  output = []
72
83
  output << "# Table: #{model.table_name}"
73
84
 
74
85
  meth = :"_schema_comment_#{model.db.database_type}"
75
86
  if respond_to?(meth, true)
76
- send(meth, output)
87
+ send(meth, output, options)
77
88
  else
78
89
  schema_comment_columns(output)
79
- schema_comment_indexes(output)
80
- schema_comment_foreign_keys(output)
90
+ schema_comment_indexes(output) unless options[:indexes] == false
91
+ schema_comment_foreign_keys(output) unless options[:foreign_keys] == false
92
+ end
93
+
94
+
95
+ # Add beginning and end to the table if specified
96
+ if options[:border]
97
+ border = "# #{'-' * (output.map(&:size).max - 2)}"
98
+ output.push(border)
99
+ output.insert(1, border)
81
100
  end
82
101
 
83
102
  output.join($/)
@@ -107,87 +126,97 @@ module Sequel
107
126
 
108
127
  # Use the standard columns schema output, but use PostgreSQL specific
109
128
  # code for additional schema information.
110
- def _schema_comment_postgres(output)
111
- schema_comment_columns(output)
129
+ def _schema_comment_postgres(output, options = {})
130
+ schema_comment_columns(output, options)
112
131
  oid = model.db.send(:regclass_oid, model.table_name)
113
132
 
114
133
  # These queries below are all based on the queries that psql
115
134
  # uses, captured using the -E option to psql.
116
135
 
117
- rows = model.db.fetch(<<SQL, :oid=>oid).all
136
+ unless options[:indexes] == false
137
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
118
138
  SELECT c2.relname, i.indisprimary, i.indisunique, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)
119
139
  FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
120
140
  LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))
121
141
  WHERE c.oid = :oid AND c.oid = i.indrelid AND i.indexrelid = c2.oid AND indisvalid
122
142
  ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
123
143
  SQL
124
- unless rows.empty?
125
- output << "# Indexes:"
126
- rows = rows.map do |r|
127
- [r[:relname], "#{"PRIMARY KEY " if r[:indisprimary]}#{"UNIQUE " if r[:indisunique] && !r[:indisprimary]}#{r[:pg_get_indexdef].match(/USING (.+)\z/m)[1]}"]
144
+ unless rows.empty?
145
+ output << "# Indexes:"
146
+ rows = rows.map do |r|
147
+ [r[:relname], "#{"PRIMARY KEY " if r[:indisprimary]}#{"UNIQUE " if r[:indisunique] && !r[:indisprimary]}#{r[:pg_get_indexdef].match(/USING (.+)\z/m)[1]}"]
148
+ end
149
+ output.concat(align(rows))
128
150
  end
129
- output.concat(align(rows))
130
151
  end
131
152
 
132
- rows = model.db.fetch(<<SQL, :oid=>oid).all
153
+ unless options[:constraints] == false
154
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
133
155
  SELECT r.conname, pg_catalog.pg_get_constraintdef(r.oid, true)
134
156
  FROM pg_catalog.pg_constraint r
135
157
  WHERE r.conrelid = :oid AND r.contype = 'c'
136
158
  ORDER BY 1;
137
159
  SQL
138
- unless rows.empty?
139
- output << "# Check constraints:"
140
- rows = rows.map do |r|
141
- [r[:conname], r[:pg_get_constraintdef].match(/CHECK (.+)\z/m)[1]]
160
+ unless rows.empty?
161
+ output << "# Check constraints:"
162
+ rows = rows.map do |r|
163
+ [r[:conname], r[:pg_get_constraintdef].match(/CHECK (.+)\z/m)[1]]
164
+ end
165
+ output.concat(align(rows))
142
166
  end
143
- output.concat(align(rows))
144
167
  end
145
168
 
146
- rows = model.db.fetch(<<SQL, :oid=>oid).all
169
+ unless options[:foreign_keys] == false
170
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
147
171
  SELECT conname,
148
172
  pg_catalog.pg_get_constraintdef(r.oid, true) as condef
149
173
  FROM pg_catalog.pg_constraint r
150
174
  WHERE r.conrelid = :oid AND r.contype = 'f' ORDER BY 1;
151
175
  SQL
152
- unless rows.empty?
153
- output << "# Foreign key constraints:"
154
- rows = rows.map do |r|
155
- [r[:conname], r[:condef].match(/FOREIGN KEY (.+)\z/m)[1]]
176
+ unless rows.empty?
177
+ output << "# Foreign key constraints:"
178
+ rows = rows.map do |r|
179
+ [r[:conname], r[:condef].match(/FOREIGN KEY (.+)\z/m)[1]]
180
+ end
181
+ output.concat(align(rows))
156
182
  end
157
- output.concat(align(rows))
158
183
  end
159
184
 
160
- rows = model.db.fetch(<<SQL, :oid=>oid).all
185
+ unless options[:references] == false
186
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
161
187
  SELECT conname, conrelid::pg_catalog.regclass,
162
188
  pg_catalog.pg_get_constraintdef(c.oid, true) as condef
163
189
  FROM pg_catalog.pg_constraint c
164
190
  WHERE c.confrelid = :oid AND c.contype = 'f' ORDER BY 2, 1;
165
191
  SQL
166
- unless rows.empty?
167
- output << "# Referenced By:"
168
- rows = rows.map do |r|
169
- [r[:conrelid], r[:conname], r[:condef].match(/FOREIGN KEY (.+)\z/m)[1]]
192
+ unless rows.empty?
193
+ output << "# Referenced By:"
194
+ rows = rows.map do |r|
195
+ [r[:conrelid], r[:conname], r[:condef].match(/FOREIGN KEY (.+)\z/m)[1]]
196
+ end
197
+ output.concat(align(rows))
170
198
  end
171
- output.concat(align(rows))
172
199
  end
173
200
 
174
- rows = model.db.fetch(<<SQL, :oid=>oid).all
201
+ unless options[:triggers] == false
202
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
175
203
  SELECT t.tgname, pg_catalog.pg_get_triggerdef(t.oid, true), t.tgenabled, t.tgisinternal
176
204
  FROM pg_catalog.pg_trigger t
177
205
  WHERE t.tgrelid = :oid AND (NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D'))
178
206
  ORDER BY 1;
179
207
  SQL
180
- unless rows.empty?
181
- output << "# Triggers:"
182
- rows = rows.map do |r|
183
- [r[:tgname], r[:pg_get_triggerdef].match(/((?:BEFORE|AFTER) .+)\z/m)[1]]
208
+ unless rows.empty?
209
+ output << "# Triggers:"
210
+ rows = rows.map do |r|
211
+ [r[:tgname], r[:pg_get_triggerdef].match(/((?:BEFORE|AFTER) .+)\z/m)[1]]
212
+ end
213
+ output.concat(align(rows))
184
214
  end
185
- output.concat(align(rows))
186
215
  end
187
216
  end
188
217
 
189
218
  # The standard column schema information to output.
190
- def schema_comment_columns(output)
219
+ def schema_comment_columns(output, options = {})
191
220
  if cpk = model.primary_key.is_a?(Array)
192
221
  output << "# Primary Key: (#{model.primary_key.join(', ')})"
193
222
  end
@@ -107,6 +107,46 @@ describe Sequel::Annotate do
107
107
  Dir['spec/tmp/*.rb'].each{|f| File.delete(f)}
108
108
  end
109
109
 
110
+ it "#schema_info should not return sections we set to false" do
111
+ Sequel::Annotate.new(Item).schema_comment(:indexes => false, :constraints => false, :foreign_keys => false, :triggers => false).must_equal(fix_pg_comment((<<OUTPUT).chomp))
112
+ # Table: items
113
+ # Columns:
114
+ # id | integer | PRIMARY KEY DEFAULT nextval('items_id_seq'::regclass)
115
+ # category_id | integer | NOT NULL
116
+ # manufacturer_name | character varying(50) |
117
+ # manufacturer_location | text |
118
+ # in_stock | boolean | DEFAULT false
119
+ # name | text | DEFAULT 'John'::text
120
+ # price | double precision | DEFAULT 0
121
+ OUTPUT
122
+
123
+ Sequel::Annotate.new(Category).schema_comment(:references => false).must_equal(fix_pg_comment((<<OUTPUT).chomp))
124
+ # Table: categories
125
+ # Columns:
126
+ # id | integer | PRIMARY KEY DEFAULT nextval('categories_id_seq'::regclass)
127
+ # name | text | NOT NULL
128
+ # Indexes:
129
+ # categories_pkey | PRIMARY KEY btree (id)
130
+ # categories_name_key | UNIQUE btree (name)
131
+ OUTPUT
132
+ end
133
+
134
+ it "#schema_info should return a border if we want one" do
135
+ Sequel::Annotate.new(Item).schema_comment(:border => true, :indexes => false, :constraints => false, :foreign_keys => false, :triggers => false).gsub(/----+/, '---').must_equal(fix_pg_comment((<<OUTPUT).chomp))
136
+ # Table: items
137
+ # ---
138
+ # Columns:
139
+ # id | integer | PRIMARY KEY DEFAULT nextval('items_id_seq'::regclass)
140
+ # category_id | integer | NOT NULL
141
+ # manufacturer_name | character varying(50) |
142
+ # manufacturer_location | text |
143
+ # in_stock | boolean | DEFAULT false
144
+ # name | text | DEFAULT 'John'::text
145
+ # price | double precision | DEFAULT 0
146
+ # ---
147
+ OUTPUT
148
+ end
149
+
110
150
  it "#schema_info should return the model schema comment" do
111
151
  Sequel::Annotate.new(Item).schema_comment.must_equal(fix_pg_comment((<<OUTPUT).chomp))
112
152
  # Table: items
@@ -238,5 +278,8 @@ OUTPUT
238
278
  FileUtils.cp('spec/namespaced/itm_unannotated.rb', 'spec/tmp/')
239
279
  Sequel::Annotate.annotate(["spec/tmp/itm_unannotated.rb"], :namespace=>'ModelNamespace')
240
280
  File.read("spec/tmp/itm_unannotated.rb").must_equal fix_pg_comment(File.read('spec/namespaced/itm_annotated.rb'))
281
+ Sequel::Annotate.annotate(["spec/tmp/itm_unannotated.rb"], :namespace=>'ModelNamespace', :border=>true)
282
+ Sequel::Annotate.annotate(["spec/tmp/itm_unannotated.rb"], :namespace=>'ModelNamespace')
283
+ File.read("spec/tmp/itm_unannotated.rb").must_equal fix_pg_comment(File.read('spec/namespaced/itm_annotated.rb'))
241
284
  end
242
285
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel-annotate
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-27 00:00:00.000000000 Z
11
+ date: 2018-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel