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.
- checksums.yaml +4 -4
- data/CHANGELOG +36 -0
- data/README.rdoc +39 -1
- data/Rakefile +2 -10
- data/lib/sequel/annotate.rb +134 -45
- data/spec/annotated_after/manufacturer.rb +1 -1
- data/spec/annotated_after/scomplexdataset.rb +7 -0
- data/spec/annotated_after/sitemwithcoding.rb +20 -0
- data/spec/annotated_after/sitemwithencoding.rb +20 -0
- data/spec/annotated_after/sitemwithfrozenliteral.rb +20 -0
- data/spec/annotated_after/sitemwithwarnindent.rb +20 -0
- data/spec/annotated_after/sitemwithwarnpastscope.rb +21 -0
- data/spec/annotated_before/manufacturer.rb +1 -1
- data/spec/annotated_before/scomplexdataset.rb +7 -0
- data/spec/annotated_before/sitemwithcoding.rb +20 -0
- data/spec/annotated_before/sitemwithencoding.rb +20 -0
- data/spec/annotated_before/sitemwithfrozenliteral.rb +20 -0
- data/spec/annotated_before/sitemwithwarnindent.rb +20 -0
- data/spec/annotated_before/sitemwithwarnpastscope.rb +21 -0
- data/spec/namespaced/itm_annotated.rb +24 -0
- data/spec/namespaced/itm_unannotated.rb +3 -0
- data/spec/sequel-annotate_spec.rb +170 -10
- data/spec/unannotated/manufacturer.rb +1 -1
- data/spec/unannotated/not_model.rb +4 -0
- data/spec/unannotated/scomplexdataset.rb +7 -0
- data/spec/unannotated/sitemwithcoding.rb +4 -0
- data/spec/unannotated/sitemwithencoding.rb +4 -0
- data/spec/unannotated/sitemwithfrozenliteral.rb +4 -0
- data/spec/unannotated/sitemwithmagiccomment.rb +4 -0
- data/spec/unannotated/sitemwithwarnindent.rb +4 -0
- data/spec/unannotated/sitemwithwarnpastscope.rb +5 -0
- metadata +44 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42122bfc730bb5345c90160c5a17b0861c3a5a8308dfc6a008c1fccc0b73fe3e
|
4
|
+
data.tar.gz: 7bbb33c84261d97a66c17b942c19fc0b432d4029b8e384f148ec79ddf96c196e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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)
|
data/README.rdoc
CHANGED
@@ -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
|
-
|
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
|
-
|
data/lib/sequel/annotate.rb
CHANGED
@@ -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
|
-
|
15
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
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
|
-
|
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
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
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
|
-
|
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
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
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
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
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
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
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
|
@@ -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
|
@@ -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()
|
@@ -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
|
-
|
7
|
-
|
8
|
-
|
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 <
|
1
|
+
class Manufacturer < ABC
|
2
2
|
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.
|
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:
|
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
|
-
|
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
|