sequel-pg-comment 1.0.0 → 2.0.0

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