sequel-pg-comment 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 395d855974e2dab38580a5f51fcca0dd417a1d62
4
- data.tar.gz: 5a5d63691292204a7d1144beb8b1a2b58df613e4
3
+ metadata.gz: 3110fff14db57745785e517abfc96b0c67c8f806
4
+ data.tar.gz: 48ebb162456d9d455557dd019b6e706766bd9024
5
5
  SHA512:
6
- metadata.gz: de01d8c954e2bbaaa7224551ffe018c757da9b216797db2242e5f240751a46cc08ce593041ea8a5bfb2bafabee4ed45e9295d3ffb9d823b2e04105662c3eac81
7
- data.tar.gz: f9728263f44b18b9b96fc3117d6a0385fa8d762bdfdc1a94fa9b514805c47e3b84945204d0737e34130fc62149f4abfb445c081e3aa03abc292dc6388b05a453
6
+ metadata.gz: d96a82d756893a528156fed4eeb202fc73d1b60bd7e4ad9c3f6863769427c2763216370d0093e25486191cbbd82b20cda1994363f8bcf30d5603b71b7b8b5614
7
+ data.tar.gz: 4a0d8e466cce89d873d9ea1061561ebbbc527813d35c52171925cdc76eb3215641f42fbd320787a4b76cf48fbc66a9c138bd9f16b2af8a95c76017206a2fbabe
@@ -1,9 +1,52 @@
1
- module Sequel::Extension; end #:nodoc:
1
+ module Sequel::Postgres; end #:nodoc:
2
2
 
3
3
  # PostgreSQL-specific extension to set and retrieve comments on
4
4
  # all database objects.
5
- #
6
- module Sequel::Extension::PgComment
5
+ #
6
+ module Sequel::Postgres::Comment
7
+ # The types of PostgreSQL object that are commented on in their own
8
+ # right.
9
+ STANDALONE_TYPES = [
10
+ :aggregate,
11
+ :cast,
12
+ :collation,
13
+ :conversion,
14
+ :database,
15
+ :domain,
16
+ :extension,
17
+ :event_trigger,
18
+ :foreign_data_wrapper,
19
+ :foreign_table,
20
+ :function,
21
+ :index,
22
+ :large_object,
23
+ :materialized_view,
24
+ :operator,
25
+ :operator_class,
26
+ :operator_family,
27
+ :language,
28
+ :procedural_language,
29
+ :role,
30
+ :schema,
31
+ :sequence,
32
+ :server,
33
+ :table,
34
+ :tablespace,
35
+ :text_search_configuration,
36
+ :text_search_dictionary,
37
+ :text_search_parser,
38
+ :text_search_template,
39
+ :type,
40
+ :view
41
+ ]
42
+
43
+ CONTAINED_TYPES = [
44
+ :column,
45
+ :constraint,
46
+ :rule,
47
+ :trigger
48
+ ]
49
+
7
50
  # Strip indenting whitespace from a comment string.
8
51
  #
9
52
  # Two rules are applied by this method:
@@ -49,7 +92,7 @@ module Sequel::Extension::PgComment
49
92
  # @param comment [String] The comment to mangle for whitespace.
50
93
  #
51
94
  # @return [String] The normalised comment, with whitespace removed.
52
- #
95
+ #
53
96
  def self.normalise_comment(comment)
54
97
  comment.tap do |s|
55
98
  s.gsub!(/\A\n+/, '')
@@ -61,13 +104,10 @@ module Sequel::Extension::PgComment
61
104
  end
62
105
  end
63
106
 
64
- require_relative 'pg_comment/sql_generator'
65
107
  require_relative 'pg_comment/database_methods'
66
108
  require_relative 'pg_comment/dataset_methods'
67
- require_relative 'pg_comment/create_table_generator_methods'
68
- require_relative 'pg_comment/alter_table_generator_methods'
69
109
 
70
110
  Sequel::Database.register_extension(:pg_comment) do |db|
71
- db.extend Sequel::Extension::PgComment::DatabaseMethods
72
- db.extend_datasets Sequel::Extension::PgComment::DatasetMethods
111
+ db.extend Sequel::Postgres::Comment::DatabaseMethods
112
+ db.extend_datasets Sequel::Postgres::Comment::DatasetMethods
73
113
  end
@@ -1,42 +1,51 @@
1
1
  # Support for setting and retrieving comments on all object types
2
2
  # in a PostgreSQL database.
3
3
  #
4
- module Sequel::Extension::PgComment::DatabaseMethods
5
- # Set the comment for a database object.
6
- #
7
- # @param type [#to_s] The type of object that you wish to comment on.
8
- # This can either be a string or symbol. Any object type that PgSQL
9
- # knows about should be fair game. The current list of object types
10
- # that this plugin knows about (and hence will accept) is listed in
11
- # the {Sequel::Extension::PgComment::OBJECT_TYPES} array.
12
- #
13
- # @param id [#to_s] The name of the object that you wish to comment on.
14
- # For most types of object, this should be the literal name of the
15
- # object. However, for columns in a table or view, you should separate
16
- # the table/view name from the column name with a double underscore
17
- # (ie `__`). This is the standard Sequel convention for such things.
4
+ module Sequel::Postgres::Comment::DatabaseMethods
5
+ # @param type [Symbol] The object type you're looking to set the comment
6
+ # on. This is just the PostgreSQL type name, lowercased, with spaces
7
+ # replaced with underscores.
8
+ #
9
+ # @param id [Symbol, String, Array<Symbol, String>] The identifier of the
10
+ # object that you wish to comment on. For most types of object, this
11
+ # should be the literal name of the object. However, for objects which
12
+ # are "contained" in another object (columns in tables/views, and
13
+ # constraints, triggers, and rules in tables) you must pass the
14
+ # identifier as a two-element array, where the first element is the
15
+ # container table or view, and the second element is the contained
16
+ # object (column, constraint, rule, or trigger).
17
+ #
18
+ # In any event, when a `Symbol` is encountered, it is quoted for
19
+ # safety, and split into a schema and object name pair, if appropriate.
20
+ # If a `String` is passed, then **no escaping or quoting is done**.
21
+ # While this is a slight risk, it is necessary to allow you to
22
+ # reference complex object names which can't reasonably be described
23
+ # otherwise (`FUNCTION`, I'm looking at you).
18
24
  #
19
25
  # @param comment [String] The comment you wish to set for the database
20
26
  # object.
21
27
  #
22
- # @see {Sequel::Extension::PgComment.normalise_comment} for details on
28
+ # @raise [Sequel::Error] if the specified `type` isn't recognised.
29
+ #
30
+ # @see {Sequel::Postgres::Comment.normalise_comment} for details on
23
31
  # how the comment string is interpreted.
24
32
  #
25
33
  def comment_on(type, id, comment)
26
- gen = begin
27
- Sequel::Extension::PgComment::SqlGenerator.create(type, id, comment)
28
- rescue ArgumentError
29
- raise ArgumentError,
30
- "Invalid object type: #{type.inspect}"
34
+ if Sequel::Postgres::Comment::STANDALONE_TYPES.include?(type)
35
+ comment_on_standalone_type(type, id, comment)
36
+ elsif Sequel::Postgres::Comment::CONTAINED_TYPES.include?(type)
37
+ comment_on_contained_type(type, id, comment)
38
+ else
39
+ raise Sequel::Error,
40
+ "Unknown object type: #{type.inspect}"
31
41
  end
32
-
33
- execute(gen.generate)
34
42
  end
35
43
 
44
+
36
45
  # Retrieve the comment for a database object.
37
46
  #
38
47
  # @param object [#to_s] The name of the database object to retrieve. For
39
- # most objects, this should be the literal name of the object.
48
+ # most objects, this should be the literal name of the object.
40
49
  # However, for columns on tables and views, the name of the table/view
41
50
  # should be a separated from the name of the column by a double
42
51
  # underscore (ie `__`).
@@ -50,14 +59,19 @@ module Sequel::Extension::PgComment::DatabaseMethods
50
59
  if object.index("__")
51
60
  tbl, col = object.split("__", 2)
52
61
 
53
- execute("SELECT col_description(c.oid, a.attnum) " +
54
- "FROM pg_class c JOIN pg_attribute a " +
55
- "ON (c.oid=a.attrelid) " +
56
- "WHERE c.relname=#{literal(tbl)} " +
57
- "AND a.attname=#{literal(col)}"
58
- )
62
+ (select(Sequel.function(:col_description, :c__oid, :a__attnum).as(:comment)).
63
+ from(Sequel.as(:pg_class, :c)).
64
+ join(Sequel.as(:pg_attribute, :a), :c__oid => :a__attrelid).
65
+ where(:c__relname => tbl).
66
+ and(:a__attname => col).first || {})[:comment]
59
67
  else
60
- execute("SELECT obj_description(#{literal(object.to_s)}::regclass, 'pg_class')")
68
+ (select(
69
+ Sequel.function(
70
+ :obj_description,
71
+ Sequel.cast(object, :regclass),
72
+ "pg_class"
73
+ ).as(:comment)
74
+ ).first || {})[:comment]
61
75
  end
62
76
  end
63
77
 
@@ -78,51 +92,47 @@ module Sequel::Extension::PgComment::DatabaseMethods
78
92
  end
79
93
 
80
94
  #:nodoc:
81
- # Enhanced version to support setting comments on objects created in a
82
- # block-form `create_table` statement.
95
+ # Enhanced to support creating comments on columns, after the table
96
+ # itself (and hence all its columns) have been created.
83
97
  #
84
- def create_table_generator(&block)
85
- super do
86
- extend Sequel::Extension::PgComment::CreateTableGeneratorMethods
87
- @comments = []
88
- instance_eval(&block) if block
98
+ def create_table_from_generator(name, generator, options)
99
+ generator.columns.each do |col|
100
+ if col[:comment]
101
+ comment_on(:column, [name, col[:name]], col[:comment])
102
+ end
103
+ end
104
+
105
+ generator.constraints.each do |c|
106
+ case c[:type]
107
+ when :primary_key
108
+ c_name = c[:name] || "#{name}_pkey".to_sym
109
+ comment_on(:index, c_name, c[:comment])
110
+ when :foreign_key, :check
111
+ if c[:type] == :check && c[:name].nil?
112
+ raise Sequel::Error,
113
+ "Setting comments on unnamed check constraints is not supported"
114
+ end
115
+ c_name = c[:name] || "#{name}_#{c[:columns].first}_fkey".to_sym
116
+ comment_on(:constraint, [name, c_name], c[:comment])
117
+ when :unique
118
+ c_name = c[:name] || ([name] + c[:columns] + ["key"]).join("_").to_sym
119
+ comment_on(:index, c_name, c[:comment])
120
+ end
89
121
  end
90
122
  end
91
123
 
92
124
  #:nodoc:
93
- # Enhanced version to support setting comments on objects created in a
94
- # block-form `create_table` statement.
95
- #
96
- # If you're wondering why we override the
97
- # create_table_indexes_from_generator method, rather than
98
- # create_table_from_generator, it's because the indexes method runs last,
99
- # and we can only create our comments after the objects we're commenting
100
- # on have been created. We *could* set some comments in
101
- # create_table_from_generator, and then set index comments in
102
- # create_table_indexes_from_generator, but why override two methods when
103
- # you can just override one to get the same net result?
125
+ # Enhanced to support creating comments on indexes, after the indexes
126
+ # themselves have been created.
104
127
  #
105
128
  def create_table_indexes_from_generator(name, generator, options)
106
129
  super
107
130
 
108
- generator.comments.each do |sql_gen|
109
- if sql_gen.respond_to? :table_name
110
- sql_gen.table_name = name
131
+ generator.indexes.each do |idx|
132
+ if idx[:comment]
133
+ i_name = idx[:name] || ([name] + idx[:columns] + ["index"]).join("_").to_sym
134
+ comment_on(:index, i_name, idx[:comment])
111
135
  end
112
-
113
- execute(sql_gen.generate)
114
- end
115
- end
116
-
117
- #:nodoc:
118
- # Enhanced version to support setting comments on objects created in a
119
- # block-form `alter_table` statement.
120
- #
121
- def alter_table_generator(&block)
122
- super do
123
- extend Sequel::Extension::PgComment::AlterTableGeneratorMethods
124
- @comments = []
125
- instance_eval(&block) if block
126
136
  end
127
137
  end
128
138
 
@@ -133,12 +143,30 @@ module Sequel::Extension::PgComment::DatabaseMethods
133
143
  def apply_alter_table_generator(name, generator)
134
144
  super
135
145
 
136
- generator.comments.each do |sql_gen|
137
- if sql_gen.respond_to?(:table_name=)
138
- sql_gen.table_name = name
146
+ schema, table = schema_and_table(name)
147
+ fqtable = [schema, table].compact.map { |e| literal e.to_sym }.join('.')
148
+
149
+ generator.operations.each do |op|
150
+ if op[:comment]
151
+ case op[:op]
152
+ when :add_column
153
+ comment_on(:column, [name, op[:name]], op[:comment])
154
+ when :add_constraint
155
+ case op[:type]
156
+ when :primary_key
157
+ comment_on(:index, "#{name}_pkey".to_sym, op[:comment])
158
+ when :foreign_key, :check
159
+ c_name = op[:name] || "#{name}_#{op[:columns].first}_fkey".to_sym
160
+ comment_on(:constraint, [name, c_name], op[:comment])
161
+ when :unique
162
+ c_name = op[:name] || ([name] + op[:columns] + ["key"]).join("_").to_sym
163
+ comment_on(:index, c_name, op[:comment])
164
+ end
165
+ when :add_index
166
+ c_name = op[:name] || ([name] + op[:columns] + ["index"]).join("_").to_sym
167
+ comment_on(:index, c_name, op[:comment])
168
+ end
139
169
  end
140
-
141
- execute(sql_gen.generate)
142
170
  end
143
171
  end
144
172
 
@@ -160,16 +188,41 @@ module Sequel::Extension::PgComment::DatabaseMethods
160
188
 
161
189
  private
162
190
 
163
- # Quote an object name, handling the double underscore convention
164
- # for separating a column name from its containing object.
165
- #
166
- def quote_comment_identifier(id)
167
- id = id.to_s
168
- if id.index("__")
169
- tbl, col = id.split("__", 2)
170
- quote_identifier(tbl) + "." + quote_identifier(col)
191
+ def comment_on_standalone_type(type, id, comment)
192
+ run "COMMENT ON #{type.to_s.gsub("_", " ").upcase} #{quoted_schema_and_table id} IS #{literal comment}"
193
+ end
194
+
195
+ def comment_on_contained_type(type, id, comment)
196
+ unless id.is_a?(Array) and id.length == 2
197
+ raise Sequel::Error,
198
+ "Invalid ID for #{type.inspect}: must be a two-element array"
199
+ end
200
+
201
+ fqtable = quoted_schema_and_table(id[0])
202
+ fqname = if id[1].is_a?(Symbol)
203
+ quote_identifier id[1]
204
+ elsif id[1].is_a?(String)
205
+ id[1]
206
+ else
207
+ raise Sequel::Error,
208
+ "Invalid type for object ID: must be a Symbol or String"
209
+ end
210
+
211
+ if type == :column
212
+ run "COMMENT ON COLUMN #{fqtable}.#{fqname} IS #{literal comment}"
213
+ else
214
+ run "COMMENT ON #{type.to_s.gsub("_", " ").upcase} #{fqname} ON #{fqtable} IS #{literal comment}"
215
+ end
216
+ end
217
+
218
+ def quoted_schema_and_table(id)
219
+ if id.is_a?(Symbol)
220
+ literal id
221
+ elsif id.is_a?(String)
222
+ id
171
223
  else
172
- quote_identifier(id)
224
+ raise Sequel::Error,
225
+ "Invalid type for ID: #{id.inspect} (must by symbol or string)"
173
226
  end
174
227
  end
175
228
  end
@@ -6,7 +6,7 @@
6
6
  # Will retrieve the comment for `foo_tbl.some_column`, if such a
7
7
  # column exists.
8
8
  #
9
- module Sequel::Extension::PgComment::DatasetMethods
9
+ module Sequel::Postgres::Comment::DatasetMethods
10
10
  # Retrieve the comment for the column named `col` in the "primary" table
11
11
  # for this dataset.
12
12
  #
@@ -19,4 +19,19 @@ module Sequel::Extension::PgComment::DatasetMethods
19
19
  def comment_for(col)
20
20
  db.comment_for("#{first_source_table}__#{col}")
21
21
  end
22
+
23
+ # Retrieve the comment for the "primary" table in the dataset.
24
+ #
25
+ # @return [String, NilClass] The comment for the table, or `nil` if there
26
+ # is no comment defined.
27
+ #
28
+ # @example Simple, single-table dataset
29
+ # db[:foo].comment # => comment for table foo
30
+ #
31
+ # @example Multi-table dataset
32
+ # db[:foo].join(:bar, ...).where { id < 20 }.comment # => comment for table foo
33
+ #
34
+ def comment
35
+ db.comment_for(first_source_table)
36
+ end
22
37
  end
@@ -38,14 +38,6 @@ describe "schema modification" do
38
38
  to eq("COMMENT ON COLUMN \"foo\".\"bar_id\" IS 'Over there!'")
39
39
  end
40
40
 
41
- it "sets a column comment on add_foreign_key with custom constraint name" do
42
- db.alter_table :foo do
43
- add_foreign_key :bar_id, :bar, :comment => "Over there!", :name => :fkr
44
- end
45
- expect(db.sqls.last).
46
- to eq("COMMENT ON COLUMN \"foo\".\"bar_id\" IS 'Over there!'")
47
- end
48
-
49
41
  it "sets a constraint comment on composite add_foreign_key" do
50
42
  db.alter_table :foo do
51
43
  add_foreign_key [:name, :dob], :bar, :comment => "Over there!"
@@ -96,7 +88,7 @@ describe "schema modification" do
96
88
 
97
89
  it "sets a constraint comment" do
98
90
  db.alter_table :foo do
99
- add_constraint(:min_length, :comment => "Bigger is better!") do
91
+ add_constraint(:name => :min_length, :comment => "Bigger is better!") do
100
92
  char_length(name) > 2
101
93
  end
102
94
  end
@@ -9,26 +9,27 @@ describe "#comment_for" do
9
9
  it "gets a table comment" do
10
10
  db.comment_for(:foo)
11
11
  expect(db.sqls).
12
- to eq(["SELECT obj_description('foo'::regclass, 'pg_class')"])
12
+ to eq([%{SELECT obj_description(CAST('foo' AS regclass), 'pg_class') } +
13
+ %{AS \"comment\" LIMIT 1}])
13
14
  end
14
15
 
15
16
  it "gets a column comment" do
16
17
  db.comment_for(:foo__column)
17
18
  expect(db.sqls).
18
- to eq(["SELECT col_description(c.oid, a.attnum) " +
19
- "FROM pg_class c " +
20
- "JOIN pg_attribute a ON (c.oid=a.attrelid) " +
21
- "WHERE c.relname='foo' AND a.attname='column'"
19
+ to eq([%{SELECT col_description("c"."oid", "a"."attnum") AS "comment" } +
20
+ %{FROM "pg_class" AS "c" } +
21
+ %{INNER JOIN "pg_attribute" AS "a" ON ("c"."oid" = "a"."attrelid") } +
22
+ %{WHERE (("c"."relname" = 'foo') AND ("a"."attname" = 'column')) LIMIT 1}
22
23
  ])
23
24
  end
24
25
 
25
26
  it "gets a column comment via the dataset" do
26
27
  db[:foo].comment_for(:column)
27
28
  expect(db.sqls).
28
- to eq(["SELECT col_description(c.oid, a.attnum) " +
29
- "FROM pg_class c " +
30
- "JOIN pg_attribute a ON (c.oid=a.attrelid) " +
31
- "WHERE c.relname='foo' AND a.attname='column'"
29
+ to eq([%{SELECT col_description("c"."oid", "a"."attnum") AS "comment" } +
30
+ %{FROM "pg_class" AS "c" } +
31
+ %{INNER JOIN "pg_attribute" AS "a" ON ("c"."oid" = "a"."attrelid") } +
32
+ %{WHERE (("c"."relname" = 'foo') AND ("a"."attname" = 'column')) LIMIT 1}
32
33
  ])
33
34
  end
34
35
  end
@@ -12,8 +12,8 @@ describe "#comment_on" do
12
12
  to eq(["COMMENT ON TABLE \"foo\" IS 'Ohai!'"])
13
13
  end
14
14
 
15
- it "accepts a string as object type" do
16
- db.comment_on("table", :foo, "Ohai!")
15
+ it "accepts a symbol as object name" do
16
+ db.comment_on(:table, :foo, "Ohai!")
17
17
  expect(db.sqls).
18
18
  to eq(["COMMENT ON TABLE \"foo\" IS 'Ohai!'"])
19
19
  end
@@ -39,7 +39,19 @@ describe "#comment_on" do
39
39
  it "explodes if an invalid object type is given" do
40
40
  expect do
41
41
  db.comment_on(:foobooblee, :foo, "O'hai!")
42
- end.to raise_error(ArgumentError, /invalid object type/i)
42
+ end.to raise_error(Sequel::Error)
43
+ end
44
+
45
+ it "explodes if an invalid ID type is given for a table" do
46
+ expect do
47
+ db.comment_on(:table, [:foo, :bar], "Ohai!")
48
+ end.to raise_error(Sequel::Error)
49
+ end
50
+
51
+ it "explodes if an invalid ID type is given for a column" do
52
+ expect do
53
+ db.comment_on(:column, :foo, "Ohai!")
54
+ end.to raise_error(Sequel::Error)
43
55
  end
44
56
 
45
57
  it "quotes the object name" do
@@ -49,8 +61,14 @@ describe "#comment_on" do
49
61
  end
50
62
 
51
63
  it "sets a column comment correctly" do
52
- db.comment_on(:column, :foo__bar_id, "Ohai, column!")
64
+ db.comment_on(:column, [:foo, :bar_id], "Ohai, column!")
53
65
  expect(db.sqls).
54
66
  to eq(["COMMENT ON COLUMN \"foo\".\"bar_id\" IS 'Ohai, column!'"])
55
67
  end
68
+
69
+ it "sets a trigger comment correctly" do
70
+ db.comment_on(:trigger, [:foo, :bar_id], "Whoa there, trigger!")
71
+ expect(db.sqls).
72
+ to eq(["COMMENT ON TRIGGER \"bar_id\" ON \"foo\" IS 'Whoa there, trigger!'"])
73
+ end
56
74
  end
@@ -43,17 +43,6 @@ describe "schema creation" do
43
43
  to eq("COMMENT ON COLUMN \"foo\".\"id\" IS 'I am unique'")
44
44
  end
45
45
 
46
- it "sets a primary key comment on a custom constraint name" do
47
- db.create_table :foo do
48
- primary_key :id,
49
- :comment => "I am unique",
50
- :name => :custom_pk
51
- end
52
-
53
- expect(db.sqls.last).
54
- to eq("COMMENT ON COLUMN \"foo\".\"id\" IS 'I am unique'")
55
- end
56
-
57
46
  it "sets a composite primary key comment" do
58
47
  db.create_table :foo do
59
48
  primary_key [:bar, :baz],
@@ -90,7 +79,7 @@ describe "schema creation" do
90
79
  end
91
80
 
92
81
  expect(db.sqls.last).
93
- to eq("COMMENT ON CONSTRAINT \"bar_bar_name_fkey\" ON \"foo\" IS 'Over there!'")
82
+ to eq("COMMENT ON CONSTRAINT \"foo_bar_name_fkey\" ON \"foo\" IS 'Over there!'")
94
83
  end
95
84
 
96
85
  it "sets a composite foreign_key comment with custom name" do
@@ -168,26 +157,18 @@ describe "schema creation" do
168
157
 
169
158
  it "sets a constraint comment" do
170
159
  db.create_table :foo do
171
- constraint :clamp, :num => 1..5, :comment => "Toight"
160
+ constraint({ :name => :clamp, :comment => "Toight" }, :num => 1..5)
172
161
  end
173
162
 
174
163
  expect(db.sqls.last).
175
164
  to eq("COMMENT ON CONSTRAINT \"clamp\" ON \"foo\" IS 'Toight'")
176
165
  end
177
166
 
178
- it "blows up trying to an unnamed constraint comment" do
179
- expect do
180
- db.create_table :foo do
181
- constraint nil, :num => 1..5, :comment => "Kaboom"
182
- end
183
- end.to raise_error(/not supported/i)
184
- end
185
-
186
167
  it "blows up trying to comment on a check" do
187
168
  expect do
188
169
  db.create_table :foo do
189
170
  check(:comment => "Kaboom") { char_length(name) > 2 }
190
171
  end
191
- end.to raise_error(/not supported/i)
172
+ end.to raise_error(Sequel::Error, /not supported/i)
192
173
  end
193
174
  end
@@ -0,0 +1,20 @@
1
+ require_relative 'spec_helper'
2
+ require 'sequel'
3
+
4
+ describe "Dataset#comment" do
5
+ let(:db) { Sequel.connect("mock://postgres").extension(:pg_comment) }
6
+
7
+ it "gets the comment for the table" do
8
+ db[:foo].comment
9
+ expect(db.sqls).
10
+ to eq([%{SELECT obj_description(CAST('foo' AS regclass), 'pg_class') } +
11
+ %{AS "comment" LIMIT 1}])
12
+ end
13
+
14
+ it "gets the comment for the first table" do
15
+ db[:foo].join(:bar, :id => :bar_id).where { foo__id < 20 }.comment
16
+ expect(db.sqls).
17
+ to eq([%{SELECT obj_description(CAST('foo' AS regclass), 'pg_class') } +
18
+ %{AS "comment" LIMIT 1}])
19
+ end
20
+ end
@@ -2,9 +2,9 @@ require_relative 'spec_helper'
2
2
  require 'sequel'
3
3
  require 'sequel/extensions/pg_comment'
4
4
 
5
- context "Sequel::Extension::PgComment.normalise_comment" do
5
+ context "Sequel::Postgres::Comment.normalise_comment" do
6
6
  def nc(s)
7
- Sequel::Extension::PgComment.normalise_comment(s)
7
+ Sequel::Postgres::Comment.normalise_comment(s)
8
8
  end
9
9
 
10
10
  it "does nothing to a string with no leading whitespace" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel-pg-comment
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Palmer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-15 00:00:00.000000000 Z
11
+ date: 2015-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: git-version-bump
@@ -199,11 +199,8 @@ files:
199
199
  - README.md
200
200
  - Rakefile
201
201
  - lib/sequel/extensions/pg_comment.rb
202
- - lib/sequel/extensions/pg_comment/alter_table_generator_methods.rb
203
- - lib/sequel/extensions/pg_comment/create_table_generator_methods.rb
204
202
  - lib/sequel/extensions/pg_comment/database_methods.rb
205
203
  - lib/sequel/extensions/pg_comment/dataset_methods.rb
206
- - lib/sequel/extensions/pg_comment/sql_generator.rb
207
204
  - sequel-pg-comment.gemspec
208
205
  - spec/alter_table_comment_spec.rb
209
206
  - spec/comment_for_spec.rb
@@ -211,10 +208,10 @@ files:
211
208
  - spec/create_join_table_comment_spec.rb
212
209
  - spec/create_table_comment_spec.rb
213
210
  - spec/create_view_comment_spec.rb
211
+ - spec/dataset_comment_spec.rb
214
212
  - spec/extension_spec.rb
215
213
  - spec/normalise_comment_spec.rb
216
214
  - spec/spec_helper.rb
217
- - spec/sql_generator_spec.rb
218
215
  homepage: http://theshed.hezmatt.org/sequel-pg-comment
219
216
  licenses: []
220
217
  metadata: {}
@@ -1,126 +0,0 @@
1
- #:nodoc:
2
- # Enhancements to the standard schema modification methods in a
3
- # block-form `alter_table` method, to support setting comments via the
4
- # `:comment` option.
5
- #
6
- # Note that not every schema modification method is enhanced in this module;
7
- # some modifications are implemneted in terms of more fundamental methods,
8
- # and so do not require their own method here. For example, `add_foreign_key`
9
- # with a single column is handled by `add_column`, and so doesn't require its
10
- # own implementation. Rest assured that all schema modification methods
11
- # *should* accept a `:comment` option, and set a comment in the database. If
12
- # you find one that doesn't, please file a bug.
13
- #
14
- module Sequel::Extension::PgComment::AlterTableGeneratorMethods
15
- attr_reader :comments
16
-
17
- include Sequel::Extension::PgComment
18
-
19
- # Enhanced version of the `add_column` schema modification method,
20
- # which supports setting a comment on the column.
21
- #
22
- # @option [String] :comment The comment to set on the column
23
- # that is being added.
24
- #
25
- def add_column(*args)
26
- super
27
-
28
- if args.last.is_a?(Hash) && args.last[:comment]
29
- comments << SqlGenerator.create(:column, args.first, args.last[:comment])
30
- end
31
- end
32
-
33
- # Enhanced version of the `add_composite_primary_key` schema modification
34
- # method, which supports setting a comment on the index.
35
- #
36
- # @option [String] :comment The comment to set on the index that is being
37
- # added.
38
- #
39
- def add_composite_primary_key(columns, opts)
40
- super
41
-
42
- if opts[:comment]
43
- comments << PrefixSqlGenerator.new(:index, :_pkey, opts[:comment])
44
- end
45
- end
46
-
47
- # Enhanced version of the `add_composite_foreign_key` schema modification
48
- # method, which supports setting a comment on the constraint.
49
- #
50
- # @option [String] :comment The comment to set on the constraint that is being
51
- # added.
52
- #
53
- def add_composite_foreign_key(columns, table, opts)
54
- super
55
-
56
- if opts[:comment]
57
- comments << if opts[:name]
58
- SqlGenerator.create(:constraint, opts[:name], opts[:comment])
59
- else
60
- PrefixSqlGenerator.new(
61
- :constraint,
62
- "_#{columns.first}_fkey".to_sym,
63
- opts[:comment]
64
- )
65
- end
66
- end
67
- end
68
-
69
- # Enhanced version of the `add_index` schema modification method, which
70
- # supports setting a comment on the index.
71
- #
72
- # @option [String] :comment The comment to set on the index that is being
73
- # added.
74
- #
75
- def add_index(columns, opts = OPTS)
76
- if opts[:comment]
77
- comments << if opts[:name]
78
- SqlGenerator.create(:index, opts[:name], opts[:comment])
79
- else
80
- PrefixSqlGenerator.new(
81
- :index,
82
- "_#{[columns].flatten.map(&:to_s).join("_")}_index".to_sym,
83
- opts[:comment]
84
- )
85
- end
86
- end
87
- end
88
-
89
- # Enhanced version of the `add_constraint` schema modification method,
90
- # which supports setting a comment on the constraint.
91
- #
92
- # @option [String] :comment The comment to set on the constraint that is
93
- # being added.
94
- #
95
- def add_constraint(name, *args, &block)
96
- super
97
-
98
- opts = args.last.is_a?(Hash) ? args.last : {}
99
-
100
- if opts[:comment]
101
- comments << SqlGenerator.create(:constraint, name, opts[:comment])
102
- end
103
- end
104
-
105
- # Enhanced version of the `add_unique_constraint` schema modification
106
- # method, which supports setting a comment on the index.
107
- #
108
- # @option [String] :comment The comment to set on the index that is being
109
- # added.
110
- #
111
- def add_unique_constraint(columns, opts = OPTS)
112
- super
113
-
114
- if opts[:comment]
115
- comments << if opts[:name]
116
- SqlGenerator.create(:index, opts[:name], opts[:comment])
117
- else
118
- PrefixSqlGenerator.new(
119
- :index,
120
- "_#{[columns].flatten.map(&:to_s).join("_")}_key".to_sym,
121
- opts[:comment]
122
- )
123
- end
124
- end
125
- end
126
- end
@@ -1,159 +0,0 @@
1
- #:nodoc:
2
- # Enhancements to the standard schema modification methods in a
3
- # block-form `create_table` method, to support setting comments via the
4
- # `:comment` option.
5
- #
6
- module Sequel::Extension::PgComment::CreateTableGeneratorMethods
7
- # An array of all the comments that this generator has seen fit to
8
- # create.
9
- #
10
- # @return [Array<SqlGenerator>]
11
- #
12
- attr_reader :comments
13
-
14
- include Sequel::Extension::PgComment
15
-
16
- # Enhanced version of the `column` table definition method, which
17
- # supports setting a comment on the column.
18
- #
19
- # @option [String] :comment The comment to set on the column that is
20
- # being defined.
21
- #
22
- def column(*args)
23
- super
24
-
25
- if args.last.is_a?(Hash) && args.last[:comment]
26
- comments << SqlGenerator.create(:column, args.first, args.last[:comment])
27
- end
28
- end
29
-
30
- # Enhanced version of the `primary_key` table definition method, which
31
- # supports setting a comment on either the column or constraint.
32
- #
33
- # If the primary key is composite (`name` is an array), then the comment
34
- # will be placed on the index. Otherwise, the comment will be set
35
- # on the column itself.
36
- #
37
- # @option [String] :comment The comment to set on the column or
38
- # index that is being defined.
39
- #
40
- def primary_key(name, *args)
41
- if args.last.is_a?(Hash) && args.last[:comment] and !name.is_a? Array
42
- # The composite primary key case will be handled by the
43
- # `composite_primary_key` method, so we don't have to deal with it
44
- # here.
45
- comments << SqlGenerator.create(:column, name, args.last[:comment])
46
- end
47
-
48
- super
49
- end
50
-
51
- # Enhanced version of the `composite_primary_key` table definition method,
52
- # which supports setting a comment on the primary key index.
53
- #
54
- # @option [String] :comment The comment to set on the primary key index.
55
- #
56
- def composite_primary_key(columns, *args)
57
- if args.last.is_a?(Hash) and args.last[:comment]
58
- if args.last[:name]
59
- comments << SqlGenerator.create(
60
- :index,
61
- args.last[:name],
62
- args.last[:comment]
63
- )
64
- else
65
- comments << PrefixSqlGenerator.new(:index, :_pkey, args.last[:comment])
66
- end
67
- end
68
-
69
- super
70
- end
71
-
72
- # Enhanced version of the `composite_foreign_key` table definition method,
73
- # which supports setting a comment on the FK constraint.
74
- #
75
- # @option [String] :comment The comment to set on the foreign key constraint.
76
- #
77
- def composite_foreign_key(columns, opts)
78
- if opts.is_a?(Hash) and opts[:comment] and opts[:table]
79
- if opts[:name]
80
- comments << SqlGenerator.create(
81
- :constraint,
82
- opts[:name],
83
- opts[:comment]
84
- )
85
- else
86
- comments << SqlGenerator.create(
87
- :constraint,
88
- "#{opts[:table]}_#{columns.first}_fkey".to_sym,
89
- opts[:comment]
90
- )
91
- end
92
- end
93
-
94
- super
95
- end
96
-
97
- # Enhanced version of the `index` table definition method,
98
- # which supports setting a comment on the index.
99
- #
100
- # @option [String] :comment The comment to set on the index that is being
101
- # defined.
102
- #
103
- def index(columns, opts = OPTS)
104
- if opts[:comment]
105
- if opts[:name]
106
- comments << SqlGenerator.create(:index, opts[:name], opts[:comment])
107
- else
108
- comments << PrefixSqlGenerator.new(
109
- :index,
110
- ("_" + [columns].flatten.map(&:to_s).join('_') + "_index").to_sym,
111
- opts[:comment]
112
- )
113
- end
114
- end
115
-
116
- super
117
- end
118
-
119
- # Enhanced version of the `unique` table definition method,
120
- # which supports setting a comment on the unique index.
121
- #
122
- # @option [String] :comment The comment to set on the index that will be
123
- # defined.
124
- #
125
- def unique(columns, opts = OPTS)
126
- if opts[:comment]
127
- if opts[:name]
128
- comments << SqlGenerator.create(:index, opts[:name], opts[:comment])
129
- else
130
- comments << PrefixSqlGenerator.new(
131
- :index,
132
- ("_" + [columns].flatten.map(&:to_s).join('_') + "_key").to_sym,
133
- opts[:comment]
134
- )
135
- end
136
- end
137
-
138
- super
139
- end
140
-
141
- # Enhanced version of the `constraint` table definition method,
142
- # which supports setting a comment on the constraint.
143
- #
144
- # @option [String] :comment The comment to set on the constraint that is
145
- # being defined.
146
- #
147
- def constraint(name, *args, &block)
148
- opts = name.is_a?(Hash) ? name : (args.last.is_a?(Hash) ? args.last : {})
149
-
150
- if opts[:comment]
151
- if name
152
- comments << SqlGenerator.create(:constraint, name, opts[:comment])
153
- else
154
- raise RuntimeError,
155
- "Setting comments on unnamed or check constraints is not supported"
156
- end
157
- end
158
- end
159
- end
@@ -1,257 +0,0 @@
1
- module Sequel::Extension::PgComment
2
- #:nodoc:
3
- # Generate SQL to set a comment.
4
- #
5
- class SqlGenerator
6
- # The PostgreSQL object types which this class knows how to generate
7
- # comment SQL for.
8
- #
9
- OBJECT_TYPES = %w{AGGREGATE
10
- CAST
11
- COLLATION
12
- CONVERSION
13
- DATABASE
14
- DOMAIN
15
- EXTENSION
16
- EVENT\ TRIGGER
17
- FOREIGN\ DATA\ WRAPPER
18
- FOREIGN\ TABLE
19
- FUNCTION
20
- INDEX
21
- LARGE\ OBJECT
22
- MATERIALIZED\ VIEW
23
- OPERATOR
24
- OPERATOR\ CLASS
25
- OPERATOR\ FAMILY
26
- PROCEDURAL\ LANGUAGE
27
- LANGUAGE
28
- ROLE
29
- SCHEMA
30
- SEQUENCE
31
- SERVER
32
- TABLE
33
- TABLESPACE
34
- TEXT\ SEARCH\ CONFIGURATION
35
- TEXT\ SEARCH\ DICTIONARY
36
- TEXT\ SEARCH\ PARSER
37
- TEXT\ SEARCH\ TEMPLATE
38
- TYPE
39
- VIEW
40
- }
41
-
42
- # Find the correct class for a given object type, and instantiate a
43
- # new one of them.
44
- #
45
- # @param object_type [String, Symbol] The type of object we're going
46
- # to comment on. Strings and symbols are both fine, and any case
47
- # is fine, too. Any underscores get turned into spaces. Apart from
48
- # that, it needs to be the exact name that PostgreSQL uses for the given
49
- # type.
50
- #
51
- # @param object_name [String, Symbol] The name of the database object to
52
- # set the comment on. A string is considered "already quoted", and hence
53
- # is not escaped any further. A symbol is run through the usual Sequel
54
- # identifier escaping code before being unleashed on the world.
55
- #
56
- # @param comment [String] The comment to set.
57
- #
58
- # @return [SqlGenerator] Some sort of `SqlGenerator` object, or a subclass.
59
- #
60
- # @raise [ArgumentError] if you passed in an `object_type` that we don't
61
- # know about.
62
- #
63
- def self.create(object_type, object_name, comment)
64
- generators.each do |gclass|
65
- if gclass.handles?(object_type)
66
- return gclass.new(object_type, object_name, comment)
67
- end
68
- end
69
-
70
- raise ArgumentError,
71
- "Unrecognised object type #{object_type.inspect}"
72
- end
73
-
74
- # Return whether or not this class supports the specified object type.
75
- #
76
- # @param object_type [String, Symbol] @see {.create}
77
- #
78
- # @return [TrueClass, FalseClass] whether or not this class can handle
79
- # the object type you passed.
80
- #
81
- def self.handles?(object_type)
82
- self.const_get(:OBJECT_TYPES).include?(object_type.to_s.upcase.gsub('_', ' '))
83
- end
84
-
85
- private
86
-
87
- # Return all known `SqlGenerator` classes.
88
- #
89
- def self.generators
90
- @generators ||= ObjectSpace.each_object(Class).select do |klass|
91
- klass.ancestors.include?(self)
92
- end
93
- end
94
-
95
- # We just need this so we can quote things.
96
- def self.mock_db
97
- @mock_db ||= Sequel.connect("mock://postgres")
98
- end
99
-
100
- public
101
-
102
- # The canonicalised string (that is, all-uppercase, with words
103
- # separated by spaces) for the object type of this SQL generator.
104
- #
105
- attr_reader :object_type
106
-
107
- # The raw (might-be-a-symbol, might-be-a-string) object name that
108
- # was passed to us originally.
109
- #
110
- attr_reader :object_name
111
-
112
- # The comment.
113
- attr_reader :comment
114
-
115
- # Spawn a new SqlGenerator.
116
- #
117
- # @see {.create}
118
- #
119
- def initialize(object_type, object_name, comment)
120
- @object_type = object_type.to_s.upcase.gsub('_', ' ')
121
- @object_name = object_name
122
- @comment = comment
123
- end
124
-
125
- # SQL to set a comment on the object of our affection.
126
- #
127
- # @return [String] The SQL needed to set the comment.
128
- #
129
- def generate
130
- quoted_object_name = case object_name
131
- when Symbol
132
- literal object_name
133
- else
134
- object_name
135
- end
136
-
137
- "COMMENT ON #{object_type} #{quoted_object_name} IS #{literal comment.to_s}"
138
- end
139
-
140
- private
141
-
142
- # Quote the provided database object (a symbol) or string value
143
- # (a string).
144
- #
145
- def literal(s)
146
- self.class.mock_db.literal(s)
147
- end
148
- end
149
-
150
- #:nodoc:
151
- # A specialised generator for object types that live "inside" a
152
- # table. Specifically, those types are columns, constraints,
153
- # rules, and triggers.
154
- #
155
- # They get their own subclass because these object types can be
156
- # manipulated inside a `create_table` or `alter_table` block, and at the
157
- # time the block is evaluated, the code doesn't know the name of the
158
- # table in which they are contained. So, we just stuff what we *do* know
159
- # into these generators, and then when all's done, we can go to each of
160
- # these generators, say "this is your table name", and then ask for the
161
- # generated SQL.
162
- #
163
- class TableObjectSqlGenerator < SqlGenerator
164
- # The few object types that this class handles.
165
- OBJECT_TYPES = %w{COLUMN CONSTRAINT RULE TRIGGER}
166
-
167
- # The name of the object which contains the object which is the direct
168
- # target of this SQL generator. Basically, it's the table name.
169
- attr_accessor :table_name
170
-
171
- # Overridden constructor to deal with the double-underscore-separated
172
- # names that we all know and love.
173
- #
174
- # @see {SqlGenerator#initialize}
175
- #
176
- def initialize(object_type, object_name, comment)
177
- super
178
-
179
- if object_name.is_a?(Symbol) and object_name.to_s.index("__")
180
- @table_name, @object_name = object_name.to_s.split("__", 2).map(&:to_sym)
181
- end
182
- end
183
-
184
- # Generate special SQL.
185
- #
186
- # @see {SqlGenerator#generate}
187
- #
188
- def generate
189
- if table_name.nil?
190
- raise ArgumentError,
191
- "Cannot generate SQL for #{object_type} #{object_name} " +
192
- "without a table_name"
193
- end
194
-
195
- qualified_object_name = case object_type
196
- when "COLUMN"
197
- "#{maybe_escape table_name}.#{maybe_escape object_name}"
198
- when "CONSTRAINT", "RULE", "TRIGGER"
199
- "#{maybe_escape object_name} ON #{maybe_escape table_name}"
200
- end
201
-
202
- "COMMENT ON #{object_type} #{qualified_object_name} IS #{literal comment}"
203
- end
204
-
205
- private
206
-
207
- # Handle with the vagaries of having both strings and symbols as
208
- # possible names -- we escape symbols, but leave strings to their own
209
- # devices.
210
- #
211
- def maybe_escape(s)
212
- Symbol === s ? literal(s) : s
213
- end
214
- end
215
-
216
- #:nodoc:
217
- # This is an annoying corner-case generator -- it doesn't handle any
218
- # types by default, but it will handle any *other* type where the name of
219
- # a table needs to be prefixed by a name. The only known use case for
220
- # this at present is "implicit" (that is, automatically generated by the
221
- # database) constraints and indexes that get prefixed by the table name,
222
- # and which are generated at a time when the calling code doesn't know the
223
- # name of the table that it is generating SQL for.
224
- #
225
- class PrefixSqlGenerator < SqlGenerator
226
- # This class doesn't handle any object types directly, and must be
227
- # instantiated directly when needed
228
- OBJECT_TYPES = %w{}
229
-
230
- # The name of the table which should be prefixed to the object name
231
- # that was specified when this instance was created.
232
- #
233
- attr_accessor :table_name
234
-
235
- # Generate super-dooper special SQL.
236
- #
237
- # @see {SqlGenerator#generate}
238
- #
239
- def generate
240
- if table_name.nil?
241
- raise ArgumentError,
242
- "Cannot generate SQL for #{object_type} #{object_name} " +
243
- "without a table_name"
244
- end
245
-
246
- prefixed_object_name = "#{table_name}#{object_name}"
247
-
248
- if Symbol === table_name || Symbol === object_name
249
- prefixed_object_name = prefixed_object_name.to_sym
250
- end
251
-
252
- g = SqlGenerator.create(object_type, prefixed_object_name, comment)
253
- g.table_name = table_name if g.respond_to? :table_name
254
- g.generate
255
- end
256
- end
257
- end
@@ -1,96 +0,0 @@
1
- require_relative 'spec_helper'
2
-
3
- require 'sequel'
4
- require 'sequel/extensions/pg_comment'
5
-
6
- describe "SqlGenerator" do
7
- SqlGenerator = Sequel::Extension::PgComment::SqlGenerator
8
- PrefixSqlGenerator = Sequel::Extension::PgComment::PrefixSqlGenerator
9
-
10
- context "a simple type expressed as a string" do
11
- let(:generator) { SqlGenerator.create("TABLE", :foo, "Ohai!") }
12
-
13
- it "generates quoted SQL" do
14
- expect(generator.generate).
15
- to eq("COMMENT ON TABLE \"foo\" IS 'Ohai!'")
16
- end
17
- end
18
-
19
- context "a simple type expressed as a crazy-case string" do
20
- let(:generator) { SqlGenerator.create("TaBlE", :foo, "Ohai!") }
21
-
22
- it "generates quoted SQL" do
23
- expect(generator.generate).
24
- to eq("COMMENT ON TABLE \"foo\" IS 'Ohai!'")
25
- end
26
- end
27
-
28
- context "a simple type expressed as a symbol" do
29
- let(:generator) { SqlGenerator.create(:table, :foo, "Ohai!") }
30
-
31
- it "generates quoted SQL" do
32
- expect(generator.generate).
33
- to eq("COMMENT ON TABLE \"foo\" IS 'Ohai!'")
34
- end
35
- end
36
-
37
- context "a multi-word type expressed as a symbol" do
38
- let(:generator) { SqlGenerator.create(:event_trigger, :foo, "Ohai!") }
39
-
40
- it "generates correct SQL" do
41
- expect(generator.generate).
42
- to eq("COMMENT ON EVENT TRIGGER \"foo\" IS 'Ohai!'")
43
- end
44
- end
45
-
46
- context "with a string as the object name" do
47
- let(:generator) { SqlGenerator.create(:table, "foo", "Ohai!") }
48
-
49
- it "generates unquoted SQL" do
50
- expect(generator.generate).
51
- to eq("COMMENT ON TABLE foo IS 'Ohai!'")
52
- end
53
- end
54
-
55
- it "escapes the comment" do
56
- expect(SqlGenerator.create(:table, :foo, "O'hai!").generate).
57
- to eq("COMMENT ON TABLE \"foo\" IS 'O''hai!'")
58
- end
59
-
60
- it "explodes if an invalid object type is given" do
61
- expect do
62
- SqlGenerator.create(:foobooblee, :foo, "O'hai!")
63
- end.to raise_error(ArgumentError, /unrecognised object type/i)
64
- end
65
-
66
- it "sets a column comment correctly" do
67
- expect(SqlGenerator.create(:column, :foo__bar_id, "Ohai, column!").generate).
68
- to eq("COMMENT ON COLUMN \"foo\".\"bar_id\" IS 'Ohai, column!'")
69
- end
70
-
71
- it "sets a constraint comment correctly" do
72
- g = SqlGenerator.create(:constraint, :foo__not_for_you, "Ohai, constraint!")
73
- expect(g.generate).
74
- to eq("COMMENT ON CONSTRAINT \"not_for_you\" ON \"foo\" IS 'Ohai, constraint!'")
75
- end
76
-
77
- it "sets a rule comment correctly" do
78
- g = SqlGenerator.create(:rule, :foo__not_for_you, "Ohai, rule!")
79
- expect(g.generate).
80
- to eq("COMMENT ON RULE \"not_for_you\" ON \"foo\" IS 'Ohai, rule!'")
81
- end
82
-
83
- it "sets a trigger comment correctly" do
84
- g = SqlGenerator.create(:trigger, :foo__spoing, "Ohai, trigger!")
85
- expect(g.generate).
86
- to eq("COMMENT ON TRIGGER \"spoing\" ON \"foo\" IS 'Ohai, trigger!'")
87
- end
88
-
89
- it "sets a comment on a prefixed name correctly" do
90
- g = PrefixSqlGenerator.new(:index, :_pkey, "Ohai, pkey!")
91
- g.table_name = :foo
92
-
93
- expect(g.generate).
94
- to eq("COMMENT ON INDEX \"foo_pkey\" IS 'Ohai, pkey!'")
95
- end
96
- end