sequel-annotate 1.2.0 → 1.6.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +36 -0
  3. data/README.rdoc +39 -1
  4. data/Rakefile +2 -10
  5. data/lib/sequel/annotate.rb +134 -45
  6. data/spec/annotated_after/manufacturer.rb +1 -1
  7. data/spec/annotated_after/scomplexdataset.rb +7 -0
  8. data/spec/annotated_after/sitemwithcoding.rb +20 -0
  9. data/spec/annotated_after/sitemwithencoding.rb +20 -0
  10. data/spec/annotated_after/sitemwithfrozenliteral.rb +20 -0
  11. data/spec/annotated_after/sitemwithwarnindent.rb +20 -0
  12. data/spec/annotated_after/sitemwithwarnpastscope.rb +21 -0
  13. data/spec/annotated_before/manufacturer.rb +1 -1
  14. data/spec/annotated_before/scomplexdataset.rb +7 -0
  15. data/spec/annotated_before/sitemwithcoding.rb +20 -0
  16. data/spec/annotated_before/sitemwithencoding.rb +20 -0
  17. data/spec/annotated_before/sitemwithfrozenliteral.rb +20 -0
  18. data/spec/annotated_before/sitemwithwarnindent.rb +20 -0
  19. data/spec/annotated_before/sitemwithwarnpastscope.rb +21 -0
  20. data/spec/namespaced/itm_annotated.rb +24 -0
  21. data/spec/namespaced/itm_unannotated.rb +3 -0
  22. data/spec/sequel-annotate_spec.rb +170 -10
  23. data/spec/unannotated/manufacturer.rb +1 -1
  24. data/spec/unannotated/not_model.rb +4 -0
  25. data/spec/unannotated/scomplexdataset.rb +7 -0
  26. data/spec/unannotated/sitemwithcoding.rb +4 -0
  27. data/spec/unannotated/sitemwithencoding.rb +4 -0
  28. data/spec/unannotated/sitemwithfrozenliteral.rb +4 -0
  29. data/spec/unannotated/sitemwithmagiccomment.rb +4 -0
  30. data/spec/unannotated/sitemwithwarnindent.rb +4 -0
  31. data/spec/unannotated/sitemwithwarnpastscope.rb +5 -0
  32. metadata +44 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 112ffb3483f88eacd72945f7890fac2d21b8cfa8f4559b13210eb76d80e36e53
4
- data.tar.gz: b2a580e9ddc239a8d2fb948ac5c571733915d9badf2c84385f3d21aaede7ab71
3
+ metadata.gz: 42122bfc730bb5345c90160c5a17b0861c3a5a8308dfc6a008c1fccc0b73fe3e
4
+ data.tar.gz: 7bbb33c84261d97a66c17b942c19fc0b432d4029b8e384f148ec79ddf96c196e
5
5
  SHA512:
6
- metadata.gz: edcaf9424b611f0ec0b08fb511ef2f7f9d245756040e8adf829101264846c0768f24e4d52d143d64fed4e8a05d58aa820758023e6f1d49e83ed0b87e64c0aa70
7
- data.tar.gz: 267dbf8b5693e541abbe3d97154adddfd839d2ea0e3e88475146c0d4739b6f1b42cfd2d01959984d8d7a68851375875a0e11ec28fbf1d5ab8b5c942f2d9f9efd
6
+ metadata.gz: 4ee1e34b6317be4e57f113a33e47c83190157ee3cbbae9cfd209c8806895aacc5e44604bbf2f0cfcbee1114a8822ed0c36a9ccdad628cb66daab58873d9020b8
7
+ data.tar.gz: d27e5074fb1c7642993647185605d0d714482d1f9ce5bc9e7b58817872f69674d0e803fa68210d0d73b2c176a479a44224a3678c602b1681116acae8dbf16d8c
data/CHANGELOG CHANGED
@@ -1,3 +1,39 @@
1
+ === 1.6.0 (2020-10-05)
2
+
3
+ * Add support for :namespace=>true option to attempt to automatically determine namespace (adam12) (#20)
4
+
5
+ * Skip models that select from a subquery (adam12, jeremyevans) (#17)
6
+
7
+ * Allow files to be skipped with sequel-annotate: false magic comment (adam12) (#18)
8
+
9
+ * Ignore opening of singleton classes with class << when looking for models (adam12) (#16)
10
+
11
+ === 1.5.0 (2020-05-04)
12
+
13
+ * Add support for magic comments in model files when using the :position=>:before option (qortex, jeremyevans) (#15)
14
+
15
+ * Add support for PostgreSQL column comments (rgalanakis, jeremyevans) (#14)
16
+
17
+ * Respect domain types on PostgreSQL (chanks) (#13)
18
+
19
+ * Make schema comments handle table names that aren't just symbols (chanks) (#12)
20
+
21
+ === 1.4.0 (2018-11-15)
22
+
23
+ * Support adding borders to the beginning and end of comments via :border option (kreynolds) (#9)
24
+
25
+ * Support excluding indexes, constraints, and triggers from annotation via options (kreynolds) (#9)
26
+
27
+ === 1.3.1 (2018-09-27)
28
+
29
+ * Make sure all annotation lines are commented by handling newlines inside annotations (jeremyevans)
30
+
31
+ === 1.3.0 (2018-07-17)
32
+
33
+ * Support :namespace option to specify namespace to add for models nested in namespaces (jeremyevans)
34
+
35
+ * Make Sequel::Annotate.annotate support STI classes and custom abstract base classes (a0s) (#7)
36
+
1
37
  === 1.2.0 (2018-04-02)
2
38
 
3
39
  * Handle PostgreSQL 10+ identity columns when running on Sequel 5.7+ (jeremyevans)
@@ -5,7 +5,7 @@ default, it includes information on columns, indexes, and foreign key
5
5
  constraints for the current table.
6
6
 
7
7
  On PostgreSQL, this includes more advanced information, including
8
- check constraints, triggers, and foreign keys constraints for other
8
+ check constraints, triggers, comments, and foreign keys constraints for other
9
9
  tables that reference the current table.
10
10
 
11
11
  == Example
@@ -72,16 +72,54 @@ or
72
72
  sa = Sequel::Annotate.new(Item)
73
73
  sa.annotate('models/item.rb', position: :before)
74
74
 
75
+ If your models are nested in a namespace:
76
+
77
+ module ModelNamespace
78
+ class Item < Sequel::Model
79
+ end
80
+ end
81
+
82
+ Then you can use the +:namespace+ option to set the namespace to use:
83
+
84
+ Sequel::Annotate.annotate(Dir['models/*.rb'], namespace: 'ModelNamespace')
85
+
86
+ For PostgreSQL, you can optionally leave out indexes, foreign_keys, references,
87
+ triggers, comments, and constraints by passing in false as a parameter as follows:
88
+
89
+ Sequel::Annotate.annotate(Dir['models/*.rb'], foreign_keys: false,
90
+ :indexes: false, constraints: false, comments: false)
91
+
92
+ The columns section can have a border on the top and bottom for easier visual distinction by setting the :border option to true
93
+
94
+ Sequel::Annotate.annotate(Dir['models/*.rb'], border: true)
95
+
96
+ Models that use datasets that select from subqueries are automatically skipped,
97
+ as annotations don't really make sense for them since they are not backed by a
98
+ table. You can skip other models by using a <tt># sequel-annotate: false</tt>
99
+ magic comment somewhere in the file.
100
+
75
101
  === Rake Task
76
102
 
77
103
  Here's an example rake task for sequel-annotate:
78
104
 
79
105
  desc "Update model annotations"
80
106
  task :annotate do
107
+ # Load the models first
108
+ Dir['models/*.rb'].each{|f| require_relative f}
109
+
81
110
  require 'sequel/annotate'
82
111
  Sequel::Annotate.annotate(Dir['models/*.rb'])
83
112
  end
84
113
 
114
+ == Running Tests
115
+
116
+ Tests of sequel-annotate itself can be run with rake:
117
+
118
+ rake
119
+
120
+ Set the SEQUEL_ANNOTATE_SPEC_POSTGRES_URL environment variable or appropriate
121
+ libpq environment variables to specify which PostgreSQL database to connect to.
122
+
85
123
  == License
86
124
 
87
125
  MIT
data/Rakefile CHANGED
@@ -28,19 +28,11 @@ begin
28
28
  rescue Gem::LoadError
29
29
  end
30
30
 
31
- rdoc_task_class = begin
32
- require "rdoc/task"
33
- RDoc::Task
34
- rescue LoadError
35
- require "rake/rdoctask"
36
- Rake::RDocTask
37
- end
38
-
39
31
  RDOC_OPTS = RDOC_DEFAULT_OPTS + ['--main', 'README.rdoc']
40
32
 
41
- rdoc_task_class.new do |rdoc|
33
+ require "rdoc/task"
34
+ RDoc::Task.new do |rdoc|
42
35
  rdoc.rdoc_dir = "rdoc"
43
36
  rdoc.options += RDOC_OPTS
44
37
  rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/**/*.rb"
45
38
  end
46
-
@@ -10,9 +10,29 @@ module Sequel
10
10
  # Sequel::Annotate.annotate(Dir['models/*.rb'])
11
11
  def self.annotate(paths, options = {})
12
12
  Sequel.extension :inflector
13
+ namespace = options[:namespace]
14
+
13
15
  paths.each do |path|
14
- if match = File.read(path).match(/class (\S+)\s*<\s*Sequel::Model/)
15
- new(match[1].constantize).annotate(path, options)
16
+ text = File.read(path)
17
+
18
+ next if text.match(/^#\s+sequel-annotate:\s+false$/i)
19
+
20
+ name = nil
21
+ if namespace == true
22
+ constants = text.scan(/\bmodule ([^\s]+)|class ([^\s<]+)\s*</).flatten.compact
23
+ name = constants.join("::") if constants.any?
24
+ elsif match = text.match(/class ([^\s<]+)\s*</)
25
+ name = match[1]
26
+ if namespace
27
+ name = "#{namespace}::#{name}"
28
+ end
29
+ end
30
+
31
+ if name
32
+ klass = name.constantize
33
+ if klass.ancestors.include?(Sequel::Model)
34
+ new(klass).annotate(path, options)
35
+ end
16
36
  end
17
37
  end
18
38
  end
@@ -28,11 +48,18 @@ module Sequel
28
48
  # Append the schema comment (or replace it if one already exists) to
29
49
  # the file at the given path.
30
50
  def annotate(path, options = {})
51
+ return if skip_model?
52
+
31
53
  orig = current = File.read(path).rstrip
32
54
 
33
55
  if options[:position] == :before
56
+ if current =~ /\A((?:^\s*$|^#\s*(?:frozen_string_literal|coding|encoding|warn_indent|warn_past_scope)[^\n]*\s*)*)/m
57
+ magic_comments = $1
58
+ current.slice!(0, magic_comments.length)
59
+ end
60
+
34
61
  current = current.gsub(/\A#\sTable[^\n\r]+\r?\n(?:#[^\n\r]*\r?\n)*/m, '').lstrip
35
- current = "#{schema_comment}#{$/}#{$/}#{current}"
62
+ current = "#{magic_comments}#{schema_comment(options)}#{$/}#{$/}#{current}"
36
63
  else
37
64
  if m = current.reverse.match(/#{"#{$/}# Table: ".reverse}/m)
38
65
  offset = current.length - m.end(0) + 1
@@ -43,7 +70,7 @@ module Sequel
43
70
  current = current[0...offset].rstrip
44
71
  end
45
72
  end
46
- current += "#{$/}#{$/}#{schema_comment}"
73
+ current += "#{$/}#{$/}#{schema_comment(options)}"
47
74
  end
48
75
 
49
76
  if orig != current
@@ -58,17 +85,38 @@ module Sequel
58
85
  # key constraints in this table referencing other tables.
59
86
  # On PostgreSQL, also includes check constraints, triggers,
60
87
  # and foreign key constraints in other tables referencing this table.
61
- def schema_comment
88
+ #
89
+ # Options:
90
+ # :border :: Include a border above and below the comment.
91
+ # :indexes :: Do not include indexes in annotation if set to +false+.
92
+ # :foreign_keys :: Do not include foreign key constraints in annotation if set to +false+.
93
+ #
94
+ # PostgreSQL-specific options:
95
+ # :constraints :: Do not include check constraints if set to +false+.
96
+ # :references :: Do not include foreign key constraints in other tables referencing
97
+ # this table if set to +false+.
98
+ # :triggers :: Do not include triggers in annotation if set to +false+.
99
+ def schema_comment(options = {})
100
+ return "" if skip_model?
101
+
62
102
  output = []
63
- output << "# Table: #{model.table_name}"
103
+ output << "# Table: #{model.dataset.with_quote_identifiers(false).literal(model.table_name)}"
64
104
 
65
105
  meth = :"_schema_comment_#{model.db.database_type}"
66
106
  if respond_to?(meth, true)
67
- send(meth, output)
107
+ send(meth, output, options)
68
108
  else
69
109
  schema_comment_columns(output)
70
- schema_comment_indexes(output)
71
- schema_comment_foreign_keys(output)
110
+ schema_comment_indexes(output) unless options[:indexes] == false
111
+ schema_comment_foreign_keys(output) unless options[:foreign_keys] == false
112
+ end
113
+
114
+
115
+ # Add beginning and end to the table if specified
116
+ if options[:border]
117
+ border = "# #{'-' * (output.map(&:size).max - 2)}"
118
+ output.push(border)
119
+ output.insert(1, border)
72
120
  end
73
121
 
74
122
  output.join($/)
@@ -87,105 +135,138 @@ module Sequel
87
135
 
88
136
  cols.times do |i|
89
137
  rows.each do |r|
90
- lengths[i] = r[i].length if r[i].length > lengths[i]
138
+ lengths[i] = r[i].length if r[i] && r[i].length > lengths[i]
91
139
  end
92
140
  end
93
141
 
94
142
  rows.map do |r|
95
- "# #{r.zip(lengths).map{|c, l| c.ljust(l)}.join(' | ')}".strip
143
+ "# #{r.zip(lengths).map{|c, l| c.to_s.ljust(l).gsub("\n", "\n# ")}.join(' | ')}".strip
96
144
  end
97
145
  end
98
146
 
99
147
  # Use the standard columns schema output, but use PostgreSQL specific
100
148
  # code for additional schema information.
101
- def _schema_comment_postgres(output)
102
- schema_comment_columns(output)
149
+ def _schema_comment_postgres(output, options = {})
150
+ schema_comment_columns(output, options)
103
151
  oid = model.db.send(:regclass_oid, model.table_name)
104
152
 
105
153
  # These queries below are all based on the queries that psql
106
154
  # uses, captured using the -E option to psql.
107
155
 
108
- rows = model.db.fetch(<<SQL, :oid=>oid).all
156
+ unless options[:indexes] == false
157
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
109
158
  SELECT c2.relname, i.indisprimary, i.indisunique, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)
110
159
  FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
111
160
  LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))
112
161
  WHERE c.oid = :oid AND c.oid = i.indrelid AND i.indexrelid = c2.oid AND indisvalid
113
162
  ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
114
163
  SQL
115
- unless rows.empty?
116
- output << "# Indexes:"
117
- rows = rows.map do |r|
118
- [r[:relname], "#{"PRIMARY KEY " if r[:indisprimary]}#{"UNIQUE " if r[:indisunique] && !r[:indisprimary]}#{r[:pg_get_indexdef].match(/USING (.+)\z/m)[1]}"]
164
+ unless rows.empty?
165
+ output << "# Indexes:"
166
+ rows = rows.map do |r|
167
+ [r[:relname], "#{"PRIMARY KEY " if r[:indisprimary]}#{"UNIQUE " if r[:indisunique] && !r[:indisprimary]}#{r[:pg_get_indexdef].match(/USING (.+)\z/m)[1]}"]
168
+ end
169
+ output.concat(align(rows))
119
170
  end
120
- output.concat(align(rows))
121
171
  end
122
172
 
123
- rows = model.db.fetch(<<SQL, :oid=>oid).all
173
+ unless options[:constraints] == false
174
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
124
175
  SELECT r.conname, pg_catalog.pg_get_constraintdef(r.oid, true)
125
176
  FROM pg_catalog.pg_constraint r
126
177
  WHERE r.conrelid = :oid AND r.contype = 'c'
127
178
  ORDER BY 1;
128
179
  SQL
129
- unless rows.empty?
130
- output << "# Check constraints:"
131
- rows = rows.map do |r|
132
- [r[:conname], r[:pg_get_constraintdef].match(/CHECK (.+)\z/m)[1]]
180
+ unless rows.empty?
181
+ output << "# Check constraints:"
182
+ rows = rows.map do |r|
183
+ [r[:conname], r[:pg_get_constraintdef].match(/CHECK (.+)\z/m)[1]]
184
+ end
185
+ output.concat(align(rows))
133
186
  end
134
- output.concat(align(rows))
135
187
  end
136
188
 
137
- rows = model.db.fetch(<<SQL, :oid=>oid).all
189
+ unless options[:foreign_keys] == false
190
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
138
191
  SELECT conname,
139
192
  pg_catalog.pg_get_constraintdef(r.oid, true) as condef
140
193
  FROM pg_catalog.pg_constraint r
141
194
  WHERE r.conrelid = :oid AND r.contype = 'f' ORDER BY 1;
142
195
  SQL
143
- unless rows.empty?
144
- output << "# Foreign key constraints:"
145
- rows = rows.map do |r|
146
- [r[:conname], r[:condef].match(/FOREIGN KEY (.+)\z/m)[1]]
196
+ unless rows.empty?
197
+ output << "# Foreign key constraints:"
198
+ rows = rows.map do |r|
199
+ [r[:conname], r[:condef].match(/FOREIGN KEY (.+)\z/m)[1]]
200
+ end
201
+ output.concat(align(rows))
147
202
  end
148
- output.concat(align(rows))
149
203
  end
150
204
 
151
- rows = model.db.fetch(<<SQL, :oid=>oid).all
205
+ unless options[:references] == false
206
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
152
207
  SELECT conname, conrelid::pg_catalog.regclass,
153
208
  pg_catalog.pg_get_constraintdef(c.oid, true) as condef
154
209
  FROM pg_catalog.pg_constraint c
155
210
  WHERE c.confrelid = :oid AND c.contype = 'f' ORDER BY 2, 1;
156
211
  SQL
157
- unless rows.empty?
158
- output << "# Referenced By:"
159
- rows = rows.map do |r|
160
- [r[:conrelid], r[:conname], r[:condef].match(/FOREIGN KEY (.+)\z/m)[1]]
212
+ unless rows.empty?
213
+ output << "# Referenced By:"
214
+ rows = rows.map do |r|
215
+ [r[:conrelid], r[:conname], r[:condef].match(/FOREIGN KEY (.+)\z/m)[1]]
216
+ end
217
+ output.concat(align(rows))
161
218
  end
162
- output.concat(align(rows))
163
219
  end
164
220
 
165
- rows = model.db.fetch(<<SQL, :oid=>oid).all
221
+ unless options[:triggers] == false
222
+ rows = model.db.fetch(<<SQL, :oid=>oid).all
166
223
  SELECT t.tgname, pg_catalog.pg_get_triggerdef(t.oid, true), t.tgenabled, t.tgisinternal
167
224
  FROM pg_catalog.pg_trigger t
168
225
  WHERE t.tgrelid = :oid AND (NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D'))
169
226
  ORDER BY 1;
170
227
  SQL
171
- unless rows.empty?
172
- output << "# Triggers:"
173
- rows = rows.map do |r|
174
- [r[:tgname], r[:pg_get_triggerdef].match(/((?:BEFORE|AFTER) .+)\z/m)[1]]
228
+ unless rows.empty?
229
+ output << "# Triggers:"
230
+ rows = rows.map do |r|
231
+ [r[:tgname], r[:pg_get_triggerdef].match(/((?:BEFORE|AFTER) .+)\z/m)[1]]
232
+ end
233
+ output.concat(align(rows))
175
234
  end
176
- output.concat(align(rows))
177
235
  end
178
236
  end
179
237
 
238
+ def _column_comments_postgres
239
+ model.db.fetch(<<SQL, :oid=>model.db.send(:regclass_oid, model.table_name)).to_hash(:attname, :description)
240
+ SELECT a.attname, d.description
241
+ FROM pg_description d
242
+ JOIN pg_attribute a ON (d.objoid = a.attrelid AND d.objsubid = a.attnum)
243
+ WHERE d.objoid = :oid AND COALESCE(d.description, '') != '';
244
+ SQL
245
+ end
246
+
180
247
  # The standard column schema information to output.
181
- def schema_comment_columns(output)
248
+ def schema_comment_columns(output, options = {})
182
249
  if cpk = model.primary_key.is_a?(Array)
183
250
  output << "# Primary Key: (#{model.primary_key.join(', ')})"
184
251
  end
185
252
  output << "# Columns:"
253
+
254
+ meth = :"_column_comments_#{model.db.database_type}"
255
+ column_comments = if options[:comments] != false && respond_to?(meth, true)
256
+ send(meth)
257
+ else
258
+ {}
259
+ end
260
+
186
261
  rows = model.columns.map do |col|
187
262
  sch = model.db_schema[col]
188
- [col.to_s, sch[:db_type], "#{"PRIMARY KEY #{"AUTOINCREMENT " if sch[:auto_increment] && model.db.database_type != :postgres}" if sch[:primary_key] && !cpk}#{"NOT NULL " if sch[:allow_null] == false && !sch[:primary_key]}#{"DEFAULT #{sch[:default]}" if sch[:default]}#{"GENERATED BY DEFAULT AS IDENTITY" if sch[:auto_increment] && !sch[:default] && model.db.database_type == :postgres && model.db.server_version >= 100000}"]
263
+ parts = [
264
+ col.to_s,
265
+ sch[:db_domain_type] || sch[:db_type],
266
+ "#{"PRIMARY KEY #{"AUTOINCREMENT " if sch[:auto_increment] && model.db.database_type != :postgres}" if sch[:primary_key] && !cpk}#{"NOT NULL " if sch[:allow_null] == false && !sch[:primary_key]}#{"DEFAULT #{sch[:default]}" if sch[:default]}#{"GENERATED BY DEFAULT AS IDENTITY" if sch[:auto_increment] && !sch[:default] && model.db.database_type == :postgres && model.db.server_version >= 100000}",
267
+ ]
268
+ parts << (column_comments[col.to_s] || '') unless column_comments.empty?
269
+ parts
189
270
  end
190
271
  output.concat(align(rows))
191
272
  end
@@ -211,5 +292,13 @@ SQL
211
292
  output.concat(align(rows).sort)
212
293
  end
213
294
  end
295
+
296
+ # Whether we should skip annotations for the model.
297
+ # True if the model selects from a dataset.
298
+ def skip_model?
299
+ model.dataset.joined_dataset? || model.dataset.first_source_table.is_a?(Dataset)
300
+ rescue Sequel::Error
301
+ true
302
+ end
214
303
  end
215
304
  end
@@ -1,4 +1,4 @@
1
- class Manufacturer < Sequel::Model
1
+ class Manufacturer < ABC
2
2
  end
3
3
 
4
4
  # Table: manufacturers
@@ -0,0 +1,7 @@
1
+ dataset =
2
+ SDB[:items]
3
+ .left_join(:categories, { id: :category_id })
4
+ .select { Sequel[:items][:name] }
5
+
6
+ class SComplexDataset < Sequel::Model(dataset)
7
+ end
@@ -0,0 +1,20 @@
1
+ # coding: xyz
2
+
3
+ class SItemWithCoding < Sequel::Model(SDB[:items])
4
+ end
5
+
6
+ # Table: items
7
+ # Columns:
8
+ # id | integer | PRIMARY KEY AUTOINCREMENT
9
+ # category_id | integer | NOT NULL
10
+ # manufacturer_name | varchar(50) |
11
+ # manufacturer_location | varchar(255) |
12
+ # in_stock | boolean | DEFAULT 0
13
+ # name | varchar(255) | DEFAULT 'John'
14
+ # price | double precision | DEFAULT 0
15
+ # Indexes:
16
+ # manufacturer_name | (manufacturer_name)
17
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
18
+ # Foreign key constraints:
19
+ # (category_id) REFERENCES categories
20
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ class SItemWithEncoding < Sequel::Model(SDB[:items])
4
+ end
5
+
6
+ # Table: items
7
+ # Columns:
8
+ # id | integer | PRIMARY KEY AUTOINCREMENT
9
+ # category_id | integer | NOT NULL
10
+ # manufacturer_name | varchar(50) |
11
+ # manufacturer_location | varchar(255) |
12
+ # in_stock | boolean | DEFAULT 0
13
+ # name | varchar(255) | DEFAULT 'John'
14
+ # price | double precision | DEFAULT 0
15
+ # Indexes:
16
+ # manufacturer_name | (manufacturer_name)
17
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
18
+ # Foreign key constraints:
19
+ # (category_id) REFERENCES categories
20
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SItemWithFrozenLiteral < Sequel::Model(SDB[:items])
4
+ end
5
+
6
+ # Table: items
7
+ # Columns:
8
+ # id | integer | PRIMARY KEY AUTOINCREMENT
9
+ # category_id | integer | NOT NULL
10
+ # manufacturer_name | varchar(50) |
11
+ # manufacturer_location | varchar(255) |
12
+ # in_stock | boolean | DEFAULT 0
13
+ # name | varchar(255) | DEFAULT 'John'
14
+ # price | double precision | DEFAULT 0
15
+ # Indexes:
16
+ # manufacturer_name | (manufacturer_name)
17
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
18
+ # Foreign key constraints:
19
+ # (category_id) REFERENCES categories
20
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
@@ -0,0 +1,20 @@
1
+ # warn_indent: true
2
+
3
+ class SItemWithWarnIndent < Sequel::Model(SDB[:items])
4
+ end
5
+
6
+ # Table: items
7
+ # Columns:
8
+ # id | integer | PRIMARY KEY AUTOINCREMENT
9
+ # category_id | integer | NOT NULL
10
+ # manufacturer_name | varchar(50) |
11
+ # manufacturer_location | varchar(255) |
12
+ # in_stock | boolean | DEFAULT 0
13
+ # name | varchar(255) | DEFAULT 'John'
14
+ # price | double precision | DEFAULT 0
15
+ # Indexes:
16
+ # manufacturer_name | (manufacturer_name)
17
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
18
+ # Foreign key constraints:
19
+ # (category_id) REFERENCES categories
20
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
@@ -0,0 +1,21 @@
1
+ # warn_past_scope: true
2
+ # warn_indent: false
3
+ # Additional comment that should stay
4
+ class SItemWithWarnPastScope < Sequel::Model(SDB[:items])
5
+ end
6
+
7
+ # Table: items
8
+ # Columns:
9
+ # id | integer | PRIMARY KEY AUTOINCREMENT
10
+ # category_id | integer | NOT NULL
11
+ # manufacturer_name | varchar(50) |
12
+ # manufacturer_location | varchar(255) |
13
+ # in_stock | boolean | DEFAULT 0
14
+ # name | varchar(255) | DEFAULT 'John'
15
+ # price | double precision | DEFAULT 0
16
+ # Indexes:
17
+ # manufacturer_name | (manufacturer_name)
18
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
19
+ # Foreign key constraints:
20
+ # (category_id) REFERENCES categories
21
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
@@ -8,5 +8,5 @@
8
8
  # Referenced By:
9
9
  # items | items_manufacturer_name_fkey | (manufacturer_name, manufacturer_location) REFERENCES manufacturers(name, location)
10
10
 
11
- class Manufacturer < Sequel::Model
11
+ class Manufacturer < ABC
12
12
  end
@@ -0,0 +1,7 @@
1
+ dataset =
2
+ SDB[:items]
3
+ .left_join(:categories, { id: :category_id })
4
+ .select { Sequel[:items][:name] }
5
+
6
+ class SComplexDataset < Sequel::Model(dataset)
7
+ end
@@ -0,0 +1,20 @@
1
+ # coding: xyz
2
+
3
+ # Table: items
4
+ # Columns:
5
+ # id | integer | PRIMARY KEY AUTOINCREMENT
6
+ # category_id | integer | NOT NULL
7
+ # manufacturer_name | varchar(50) |
8
+ # manufacturer_location | varchar(255) |
9
+ # in_stock | boolean | DEFAULT 0
10
+ # name | varchar(255) | DEFAULT 'John'
11
+ # price | double precision | DEFAULT 0
12
+ # Indexes:
13
+ # manufacturer_name | (manufacturer_name)
14
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
15
+ # Foreign key constraints:
16
+ # (category_id) REFERENCES categories
17
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
18
+
19
+ class SItemWithCoding < Sequel::Model(SDB[:items])
20
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ # Table: items
4
+ # Columns:
5
+ # id | integer | PRIMARY KEY AUTOINCREMENT
6
+ # category_id | integer | NOT NULL
7
+ # manufacturer_name | varchar(50) |
8
+ # manufacturer_location | varchar(255) |
9
+ # in_stock | boolean | DEFAULT 0
10
+ # name | varchar(255) | DEFAULT 'John'
11
+ # price | double precision | DEFAULT 0
12
+ # Indexes:
13
+ # manufacturer_name | (manufacturer_name)
14
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
15
+ # Foreign key constraints:
16
+ # (category_id) REFERENCES categories
17
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
18
+
19
+ class SItemWithEncoding < Sequel::Model(SDB[:items])
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Table: items
4
+ # Columns:
5
+ # id | integer | PRIMARY KEY AUTOINCREMENT
6
+ # category_id | integer | NOT NULL
7
+ # manufacturer_name | varchar(50) |
8
+ # manufacturer_location | varchar(255) |
9
+ # in_stock | boolean | DEFAULT 0
10
+ # name | varchar(255) | DEFAULT 'John'
11
+ # price | double precision | DEFAULT 0
12
+ # Indexes:
13
+ # manufacturer_name | (manufacturer_name)
14
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
15
+ # Foreign key constraints:
16
+ # (category_id) REFERENCES categories
17
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
18
+
19
+ class SItemWithFrozenLiteral < Sequel::Model(SDB[:items])
20
+ end
@@ -0,0 +1,20 @@
1
+ # warn_indent: true
2
+
3
+ # Table: items
4
+ # Columns:
5
+ # id | integer | PRIMARY KEY AUTOINCREMENT
6
+ # category_id | integer | NOT NULL
7
+ # manufacturer_name | varchar(50) |
8
+ # manufacturer_location | varchar(255) |
9
+ # in_stock | boolean | DEFAULT 0
10
+ # name | varchar(255) | DEFAULT 'John'
11
+ # price | double precision | DEFAULT 0
12
+ # Indexes:
13
+ # manufacturer_name | (manufacturer_name)
14
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
15
+ # Foreign key constraints:
16
+ # (category_id) REFERENCES categories
17
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
18
+
19
+ class SItemWithWarnIndent < Sequel::Model(SDB[:items])
20
+ end
@@ -0,0 +1,21 @@
1
+ # warn_past_scope: true
2
+ # warn_indent: false
3
+ # Table: items
4
+ # Columns:
5
+ # id | integer | PRIMARY KEY AUTOINCREMENT
6
+ # category_id | integer | NOT NULL
7
+ # manufacturer_name | varchar(50) |
8
+ # manufacturer_location | varchar(255) |
9
+ # in_stock | boolean | DEFAULT 0
10
+ # name | varchar(255) | DEFAULT 'John'
11
+ # price | double precision | DEFAULT 0
12
+ # Indexes:
13
+ # manufacturer_name | (manufacturer_name)
14
+ # name | UNIQUE (manufacturer_name, manufacturer_location)
15
+ # Foreign key constraints:
16
+ # (category_id) REFERENCES categories
17
+ # (manufacturer_name, manufacturer_location) REFERENCES manufacturers
18
+
19
+ # Additional comment that should stay
20
+ class SItemWithWarnPastScope < Sequel::Model(SDB[:items])
21
+ end
@@ -0,0 +1,24 @@
1
+ module ModelNamespace
2
+ class Itms < Model(:items); end
3
+ end
4
+
5
+ # Table: items
6
+ # Columns:
7
+ # id | integer | PRIMARY KEY DEFAULT nextval('items_id_seq'::regclass)
8
+ # category_id | integer | NOT NULL
9
+ # manufacturer_name | character varying(50) |
10
+ # manufacturer_location | text |
11
+ # in_stock | boolean | DEFAULT false
12
+ # name | text | DEFAULT 'John'::text
13
+ # price | double precision | DEFAULT 0
14
+ # Indexes:
15
+ # items_pkey | PRIMARY KEY btree (id)
16
+ # name | UNIQUE btree (manufacturer_name, manufacturer_location)
17
+ # manufacturer_name | btree (manufacturer_name)
18
+ # Check constraints:
19
+ # pos_id | (id > 0)
20
+ # Foreign key constraints:
21
+ # items_category_id_fkey | (category_id) REFERENCES categories(id)
22
+ # items_manufacturer_name_fkey | (manufacturer_name, manufacturer_location) REFERENCES manufacturers(name, location)
23
+ # Triggers:
24
+ # valid_price | BEFORE INSERT OR UPDATE ON items FOR EACH ROW EXECUTE PROCEDURE valid_price()
@@ -0,0 +1,3 @@
1
+ module ModelNamespace
2
+ class Itms < Model(:items); end
3
+ end
@@ -1,16 +1,23 @@
1
1
  require 'rubygems'
2
2
  require 'fileutils'
3
3
  require File.join(File.dirname(File.expand_path(__FILE__)), '../lib/sequel/annotate')
4
- require 'minitest/autorun'
5
4
 
6
- pg_user = ENV['PGUSER'] || 'postgres'
7
- db_name = ENV['SEQUEL_ANNOTATE_DB'] || 'sequel-annotate_spec'
8
- system("dropdb", "-U", pg_user, db_name)
9
- system("createdb", "-U", pg_user, db_name)
10
- DB = Sequel.postgres(db_name, :user=>pg_user)
11
- SDB = Sequel.sqlite
5
+ ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
6
+ gem 'minitest'
7
+ require 'minitest/global_expectations/autorun'
12
8
 
9
+ DB = Sequel.connect(ENV['SEQUEL_ANNOTATE_SPEC_POSTGRES_URL'] || 'postgres:///sequel_annotate_test?user=sequel_annotate&password=sequel_annotate')
10
+ raise "test database name doesn't end with test" unless DB.get{current_database.function} =~ /test\z/
11
+ if defined?(JRUBY_VERSION)
12
+ SDB = Sequel.connect('jdbc:sqlite::memory:')
13
+ else
14
+ SDB = Sequel.sqlite
15
+ end
16
+
17
+ DB.drop_function(:valid_price) rescue nil
13
18
  [DB, SDB].each do |db|
19
+ db.drop_table?(:newline_tests, :items, :manufacturers, :categories, :comment_tests)
20
+
14
21
  db.create_table :categories do
15
22
  primary_key :id
16
23
  String :name, :index=>{:unique=>true, :name=>'categories_name_key'}, :null=>false
@@ -25,7 +32,7 @@ SDB = Sequel.sqlite
25
32
  db.create_table :items do
26
33
  primary_key :id
27
34
  foreign_key :category_id, :categories, :null => false
28
- foreign_key [:manufacturer_name, :manufacturer_location], :manufacturers
35
+ foreign_key [:manufacturer_name, :manufacturer_location], :manufacturers, :name=>:items_manufacturer_name_fkey
29
36
 
30
37
  String :manufacturer_name, :size => 50
31
38
  String :manufacturer_location
@@ -38,6 +45,12 @@ SDB = Sequel.sqlite
38
45
  index [:manufacturer_name, :manufacturer_location], :name=>:name, :unique=>true
39
46
  index [:manufacturer_name], :name=>:manufacturer_name
40
47
  end
48
+
49
+ db.create_table :newline_tests do
50
+ Integer :abcde_fghi_id
51
+ Integer :jkl_mnopqr_id
52
+ constraint(:valid_stuvw_xyz0, Sequel.case({{:abcde_fghi_id=>[5,6]}=>Sequel.~(:jkl_mnopqr_id=>nil)}, :jkl_mnopqr_id=>nil))
53
+ end
41
54
  end
42
55
 
43
56
  DB.run <<SQL
@@ -57,19 +70,61 @@ CREATE TRIGGER valid_price BEFORE INSERT OR UPDATE ON items
57
70
  FOR EACH ROW EXECUTE PROCEDURE valid_price();
58
71
  SQL
59
72
 
73
+ DB.run "CREATE DOMAIN test_domain AS text"
74
+
75
+ DB.create_table :domain_tests do
76
+ primary_key :id
77
+ test_domain :test_column
78
+ end
79
+
80
+ DB.create_table :comment_tests do
81
+ primary_key :id
82
+ String :name
83
+ end
84
+
85
+ DB.run "COMMENT ON COLUMN comment_tests.name IS 'name column comment'"
86
+
87
+ Minitest.after_run do
88
+ DB.drop_table(:items, :manufacturers, :categories, :domain_tests, :comment_tests)
89
+ DB.run "DROP DOMAIN test_domain"
90
+ DB.drop_function(:valid_price)
91
+ end
92
+
60
93
  class ::Item < Sequel::Model; end
61
94
  class ::Category < Sequel::Model; end
62
95
  class ::Manufacturer < Sequel::Model; end
96
+ class ::DomainTest < Sequel::Model; end
97
+ class ::CommentTest < Sequel::Model; end
63
98
  class ::SItem < Sequel::Model(SDB[:items]); end
99
+ class ::SItemWithFrozenLiteral < Sequel::Model(SDB[:items]); end
100
+ class ::SItemWithCoding < Sequel::Model(SDB[:items]); end
101
+ class ::SItemWithEncoding < Sequel::Model(SDB[:items]); end
102
+ class ::SItemWithWarnIndent < Sequel::Model(SDB[:items]); end
103
+ class ::SItemWithWarnPastScope < Sequel::Model(SDB[:items]); end
104
+ class ::SItemWithMagicComment < Sequel::Model(SDB[:items]); end
64
105
  class ::SCategory < Sequel::Model(SDB[:categories]); end
65
106
  class ::SManufacturer < Sequel::Model(SDB[:manufacturers]); end
107
+ class ::NewlineTest < Sequel::Model; end
108
+ class ::QualifiedTableNameTest < Sequel::Model(Sequel.qualify(:public, :categories)); end
109
+ class SComplexDataset < Sequel::Model(SDB[:items].left_join(:categories, :id => :category_id).select{items[:name]}); end
66
110
 
111
+ # Abstract Base Class
112
+ ABC = Class.new(Sequel::Model)
113
+
114
+ module ModelNamespace
115
+ Model = Class.new(Sequel::Model)
116
+ Model.def_Model(self)
117
+ class Itms < Model(:items); end
118
+ end
67
119
 
68
120
  describe Sequel::Annotate do
69
121
  def fix_pg_comment(comment)
70
122
  if DB.server_version >= 100002 && (Sequel::MAJOR > 5 || (Sequel::MAJOR == 5 && Sequel::MINOR >= 7))
71
123
  comment = comment.sub(/DEFAULT nextval\('[a-z]+_id_seq'::regclass\)/, 'GENERATED BY DEFAULT AS IDENTITY')
72
124
  end
125
+ if DB.server_version >= 120000
126
+ comment = comment.gsub(/FOR EACH ROW EXECUTE PROCEDURE/, 'FOR EACH ROW EXECUTE FUNCTION')
127
+ end
73
128
  comment
74
129
  end
75
130
 
@@ -80,6 +135,52 @@ describe Sequel::Annotate do
80
135
  Dir['spec/tmp/*.rb'].each{|f| File.delete(f)}
81
136
  end
82
137
 
138
+ it "skips files with the sequel-annotate magic comment set to false" do
139
+ FileUtils.cp('spec/unannotated/sitemwithmagiccomment.rb', 'spec/tmp/')
140
+ Sequel::Annotate.annotate(['spec/tmp/sitemwithmagiccomment.rb'])
141
+ File.read('spec/tmp/sitemwithmagiccomment.rb').must_equal File.read('spec/unannotated/sitemwithmagiccomment.rb')
142
+ end
143
+
144
+ it "#schema_info should not return sections we set to false" do
145
+ Sequel::Annotate.new(Item).schema_comment(:indexes => false, :constraints => false, :foreign_keys => false, :triggers => false).must_equal(fix_pg_comment((<<OUTPUT).chomp))
146
+ # Table: items
147
+ # Columns:
148
+ # id | integer | PRIMARY KEY DEFAULT nextval('items_id_seq'::regclass)
149
+ # category_id | integer | NOT NULL
150
+ # manufacturer_name | character varying(50) |
151
+ # manufacturer_location | text |
152
+ # in_stock | boolean | DEFAULT false
153
+ # name | text | DEFAULT 'John'::text
154
+ # price | double precision | DEFAULT 0
155
+ OUTPUT
156
+
157
+ Sequel::Annotate.new(Category).schema_comment(:references => false).must_equal(fix_pg_comment((<<OUTPUT).chomp))
158
+ # Table: categories
159
+ # Columns:
160
+ # id | integer | PRIMARY KEY DEFAULT nextval('categories_id_seq'::regclass)
161
+ # name | text | NOT NULL
162
+ # Indexes:
163
+ # categories_pkey | PRIMARY KEY btree (id)
164
+ # categories_name_key | UNIQUE btree (name)
165
+ OUTPUT
166
+ end
167
+
168
+ it "#schema_info should return a border if we want one" do
169
+ 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))
170
+ # Table: items
171
+ # ---
172
+ # Columns:
173
+ # id | integer | PRIMARY KEY DEFAULT nextval('items_id_seq'::regclass)
174
+ # category_id | integer | NOT NULL
175
+ # manufacturer_name | character varying(50) |
176
+ # manufacturer_location | text |
177
+ # in_stock | boolean | DEFAULT false
178
+ # name | text | DEFAULT 'John'::text
179
+ # price | double precision | DEFAULT 0
180
+ # ---
181
+ OUTPUT
182
+ end
183
+
83
184
  it "#schema_info should return the model schema comment" do
84
185
  Sequel::Annotate.new(Item).schema_comment.must_equal(fix_pg_comment((<<OUTPUT).chomp))
85
186
  # Table: items
@@ -104,6 +205,7 @@ describe Sequel::Annotate do
104
205
  # valid_price | BEFORE INSERT OR UPDATE ON items FOR EACH ROW EXECUTE PROCEDURE valid_price()
105
206
  OUTPUT
106
207
 
208
+ Sequel::Annotate.new(SComplexDataset).schema_comment.must_equal("")
107
209
  Sequel::Annotate.new(Category).schema_comment.must_equal(fix_pg_comment((<<OUTPUT).chomp))
108
210
  # Table: categories
109
211
  # Columns:
@@ -126,6 +228,19 @@ OUTPUT
126
228
  # manufacturers_pkey | PRIMARY KEY btree (name, location)
127
229
  # Referenced By:
128
230
  # items | items_manufacturer_name_fkey | (manufacturer_name, manufacturer_location) REFERENCES manufacturers(name, location)
231
+ OUTPUT
232
+
233
+ Sequel::Annotate.new(NewlineTest).schema_comment.must_equal((<<OUTPUT).chomp)
234
+ # Table: newline_tests
235
+ # Columns:
236
+ # abcde_fghi_id | integer |
237
+ # jkl_mnopqr_id | integer |
238
+ # Check constraints:
239
+ # valid_stuvw_xyz0 | (
240
+ # CASE
241
+ # WHEN abcde_fghi_id = ANY (ARRAY[5, 6]) THEN jkl_mnopqr_id IS NOT NULL
242
+ # ELSE jkl_mnopqr_id IS NULL
243
+ # END)
129
244
  OUTPUT
130
245
 
131
246
  Sequel::Annotate.new(SItem).schema_comment.must_equal((<<OUTPUT).chomp)
@@ -161,6 +276,36 @@ OUTPUT
161
276
  # Columns:
162
277
  # name | varchar(255) |
163
278
  # location | varchar(255) |
279
+ OUTPUT
280
+
281
+ Sequel::Annotate.new(QualifiedTableNameTest).schema_comment.must_equal(fix_pg_comment((<<OUTPUT).chomp))
282
+ # Table: public.categories
283
+ # Columns:
284
+ # id | integer | PRIMARY KEY DEFAULT nextval('categories_id_seq'::regclass)
285
+ # name | text | NOT NULL
286
+ # Indexes:
287
+ # categories_pkey | PRIMARY KEY btree (id)
288
+ # categories_name_key | UNIQUE btree (name)
289
+ # Referenced By:
290
+ # items | items_category_id_fkey | (category_id) REFERENCES categories(id)
291
+ OUTPUT
292
+
293
+ Sequel::Annotate.new(DomainTest).schema_comment.must_equal(fix_pg_comment((<<OUTPUT).chomp))
294
+ # Table: domain_tests
295
+ # Columns:
296
+ # id | integer | PRIMARY KEY DEFAULT nextval('categories_id_seq'::regclass)
297
+ # test_column | test_domain |
298
+ # Indexes:
299
+ # domain_tests_pkey | PRIMARY KEY btree (id)
300
+ OUTPUT
301
+
302
+ Sequel::Annotate.new(CommentTest).schema_comment.must_equal(fix_pg_comment((<<OUTPUT).chomp))
303
+ # Table: comment_tests
304
+ # Columns:
305
+ # id | integer | PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY |
306
+ # name | text | | name column comment
307
+ # Indexes:
308
+ # comment_tests_pkey | PRIMARY KEY btree (id)
164
309
  OUTPUT
165
310
  end
166
311
 
@@ -168,7 +313,7 @@ OUTPUT
168
313
  it "#annotate #{desc} should annotate the file comment" do
169
314
  FileUtils.cp(Dir['spec/unannotated/*.rb'], 'spec/tmp')
170
315
 
171
- [Item, Category, Manufacturer, SItem, SCategory, SManufacturer].each do |model|
316
+ [Item, Category, Manufacturer, SItem, SCategory, SManufacturer, SItemWithFrozenLiteral, SItemWithCoding, SItemWithEncoding, SItemWithWarnIndent, SItemWithWarnPastScope, SComplexDataset].each do |model|
172
317
  filename = model.name.downcase
173
318
  2.times do
174
319
  Sequel::Annotate.new(model).annotate("spec/tmp/#{filename}.rb", *args)
@@ -184,7 +329,7 @@ OUTPUT
184
329
 
185
330
  2.times do
186
331
  Sequel::Annotate.annotate(Dir["spec/tmp/*.rb"], *args)
187
- [Item, Category, Manufacturer, SItem, SCategory, SManufacturer].each do |model|
332
+ [Item, Category, Manufacturer, SItem, SCategory, SManufacturer, SItemWithFrozenLiteral, SItemWithCoding, SItemWithEncoding, SItemWithWarnIndent, SItemWithWarnPastScope, SComplexDataset].each do |model|
188
333
  filename = model.name.downcase
189
334
  expected = File.read("spec/annotated_#{pos}/#{filename}.rb")
190
335
  expected = fix_pg_comment(expected) if model.db == DB
@@ -193,4 +338,19 @@ OUTPUT
193
338
  end
194
339
  end
195
340
  end
341
+
342
+ it ".annotate #{desc} should handle :namespace option" do
343
+ FileUtils.cp('spec/namespaced/itm_unannotated.rb', 'spec/tmp/')
344
+ Sequel::Annotate.annotate(["spec/tmp/itm_unannotated.rb"], :namespace=>'ModelNamespace')
345
+ File.read("spec/tmp/itm_unannotated.rb").must_equal fix_pg_comment(File.read('spec/namespaced/itm_annotated.rb'))
346
+ Sequel::Annotate.annotate(["spec/tmp/itm_unannotated.rb"], :namespace=>'ModelNamespace', :border=>true)
347
+ Sequel::Annotate.annotate(["spec/tmp/itm_unannotated.rb"], :namespace=>'ModelNamespace')
348
+ File.read("spec/tmp/itm_unannotated.rb").must_equal fix_pg_comment(File.read('spec/namespaced/itm_annotated.rb'))
349
+ end
350
+
351
+ it ".annotate #{desc} should handle :namespace => true option" do
352
+ FileUtils.cp('spec/namespaced/itm_unannotated.rb', 'spec/tmp')
353
+ Sequel::Annotate.annotate(["spec/tmp/itm_unannotated.rb"], :namespace=>true)
354
+ File.read("spec/tmp/itm_unannotated.rb").must_equal fix_pg_comment(File.read('spec/namespaced/itm_annotated.rb'))
355
+ end
196
356
  end
@@ -1,2 +1,2 @@
1
- class Manufacturer < Sequel::Model
1
+ class Manufacturer < ABC
2
2
  end
@@ -0,0 +1,4 @@
1
+ class NotModel
2
+ class << self
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ dataset =
2
+ SDB[:items]
3
+ .left_join(:categories, { id: :category_id })
4
+ .select { Sequel[:items][:name] }
5
+
6
+ class SComplexDataset < Sequel::Model(dataset)
7
+ end
@@ -0,0 +1,4 @@
1
+ # coding: xyz
2
+
3
+ class SItemWithCoding < Sequel::Model(SDB[:items])
4
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ class SItemWithEncoding < Sequel::Model(SDB[:items])
4
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SItemWithFrozenLiteral < Sequel::Model(SDB[:items])
4
+ end
@@ -0,0 +1,4 @@
1
+ # sequel-annotate: false
2
+
3
+ class SItemWithMagicComment < Sequel::Model(SDB[:items])
4
+ end
@@ -0,0 +1,4 @@
1
+ # warn_indent: true
2
+
3
+ class SItemWithWarnIndent < Sequel::Model(SDB[:items])
4
+ end
@@ -0,0 +1,5 @@
1
+ # warn_past_scope: true
2
+ # warn_indent: false
3
+ # Additional comment that should stay
4
+ class SItemWithWarnPastScope < Sequel::Model(SDB[:items])
5
+ 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.2.0
4
+ version: 1.6.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-04-02 00:00:00.000000000 Z
11
+ date: 2020-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-global_expectations
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: pg
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -72,7 +86,7 @@ description: |
72
86
  constraints for the current table.
73
87
 
74
88
  On PostgreSQL, this includes more advanced information, including
75
- check constraints, triggers, and foreign keys constraints for other
89
+ check constraints, triggers, comments, and foreign keys constraints for other
76
90
  tables that reference the current table.
77
91
  email: code@jeremyevans.net
78
92
  executables: []
@@ -91,25 +105,50 @@ files:
91
105
  - spec/annotated_after/item.rb
92
106
  - spec/annotated_after/manufacturer.rb
93
107
  - spec/annotated_after/scategory.rb
108
+ - spec/annotated_after/scomplexdataset.rb
94
109
  - spec/annotated_after/sitem.rb
110
+ - spec/annotated_after/sitemwithcoding.rb
111
+ - spec/annotated_after/sitemwithencoding.rb
112
+ - spec/annotated_after/sitemwithfrozenliteral.rb
113
+ - spec/annotated_after/sitemwithwarnindent.rb
114
+ - spec/annotated_after/sitemwithwarnpastscope.rb
95
115
  - spec/annotated_after/smanufacturer.rb
96
116
  - spec/annotated_before/category.rb
97
117
  - spec/annotated_before/item.rb
98
118
  - spec/annotated_before/manufacturer.rb
99
119
  - spec/annotated_before/scategory.rb
120
+ - spec/annotated_before/scomplexdataset.rb
100
121
  - spec/annotated_before/sitem.rb
122
+ - spec/annotated_before/sitemwithcoding.rb
123
+ - spec/annotated_before/sitemwithencoding.rb
124
+ - spec/annotated_before/sitemwithfrozenliteral.rb
125
+ - spec/annotated_before/sitemwithwarnindent.rb
126
+ - spec/annotated_before/sitemwithwarnpastscope.rb
101
127
  - spec/annotated_before/smanufacturer.rb
128
+ - spec/namespaced/itm_annotated.rb
129
+ - spec/namespaced/itm_unannotated.rb
102
130
  - spec/sequel-annotate_spec.rb
103
131
  - spec/unannotated/category.rb
104
132
  - spec/unannotated/item.rb
105
133
  - spec/unannotated/manufacturer.rb
134
+ - spec/unannotated/not_model.rb
106
135
  - spec/unannotated/scategory.rb
136
+ - spec/unannotated/scomplexdataset.rb
107
137
  - spec/unannotated/sitem.rb
138
+ - spec/unannotated/sitemwithcoding.rb
139
+ - spec/unannotated/sitemwithencoding.rb
140
+ - spec/unannotated/sitemwithfrozenliteral.rb
141
+ - spec/unannotated/sitemwithmagiccomment.rb
142
+ - spec/unannotated/sitemwithwarnindent.rb
143
+ - spec/unannotated/sitemwithwarnpastscope.rb
108
144
  - spec/unannotated/smanufacturer.rb
109
145
  homepage: http://github.com/jeremyevans/sequel-annotate
110
146
  licenses:
111
147
  - MIT
112
- metadata: {}
148
+ metadata:
149
+ bug_tracker_uri: https://github.com/jeremyevans/sequel-annotate/issues
150
+ changelog_uri: https://github.com/jeremyevans/sequel-annotate/blob/master/CHANGELOG
151
+ source_code_uri: https://github.com/jeremyevans/sequel-annotate
113
152
  post_install_message:
114
153
  rdoc_options:
115
154
  - "--quiet"
@@ -132,8 +171,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
171
  - !ruby/object:Gem::Version
133
172
  version: '0'
134
173
  requirements: []
135
- rubyforge_project:
136
- rubygems_version: 2.7.6
174
+ rubygems_version: 3.1.4
137
175
  signing_key:
138
176
  specification_version: 4
139
177
  summary: Annotate Sequel models with schema information