sequel-annotate 1.2.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|