schema_plus 1.0.1 → 1.1.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.
@@ -51,6 +51,12 @@ module SchemaPlus
51
51
  :update
52
52
  end
53
53
  end
54
+
55
+ # The default as_jon includes all instance variables. but
56
+ # @connection can't be dumped (it contains circular references)
57
+ def as_json(options=nil)
58
+ instance_values.except "connection"
59
+ end
54
60
  end
55
61
  end
56
62
  end
@@ -9,6 +9,10 @@ module SchemaPlus
9
9
  # :set_null
10
10
  # :set_default
11
11
  # :no_action
12
+ #
13
+ # The deferrable attribute can take on the following values:
14
+ # true
15
+ # :initially_deferred
12
16
  class ForeignKeyDefinition
13
17
 
14
18
  # The name of the foreign key constraint
@@ -65,9 +69,9 @@ module SchemaPlus
65
69
  dump = (opts[:inline] ? " t.foreign_key" : "add_foreign_key #{table_name.inspect},")
66
70
  dump << " [#{Array(column_names).collect{ |name| name.inspect }.join(', ')}]"
67
71
  dump << ", #{references_table_name.inspect}, [#{Array(references_column_names).collect{ |name| name.inspect }.join(', ')}]"
68
- dump << ", :on_update => :#{on_update}" if on_update
69
- dump << ", :on_delete => :#{on_delete}" if on_delete
70
- dump << ", :deferrable => #{deferrable}" if deferrable
72
+ dump << ", :on_update => #{on_update.inspect}" if on_update
73
+ dump << ", :on_delete => #{on_delete.inspect}" if on_delete
74
+ dump << ", :deferrable => #{deferrable.inspect}" if deferrable
71
75
  dump << ", :name => #{name.inspect}" if name
72
76
  dump << "\n"
73
77
  dump
@@ -79,6 +83,7 @@ module SchemaPlus
79
83
  sql << " ON UPDATE #{ACTIONS[on_update]}" if on_update
80
84
  sql << " ON DELETE #{ACTIONS[on_delete]}" if on_delete
81
85
  sql << " DEFERRABLE" if deferrable
86
+ sql << " INITIALLY DEFERRED" if deferrable == :initially_deferred
82
87
  sql
83
88
  end
84
89
 
@@ -107,11 +112,16 @@ module SchemaPlus
107
112
  end
108
113
 
109
114
  def self.default_name(table_name, column_names)
110
- "fk_#{table_name}_#{Array.wrap(column_names).join('_and_')}"
115
+ "fk_#{fixup_schema_name(table_name)}_#{Array.wrap(column_names).join('_and_')}"
111
116
  end
112
117
 
113
118
  def self.auto_index_name(table_name, column_name)
114
- "fk__#{table_name}_#{Array.wrap(column_name).join('_and_')}"
119
+ "fk__#{fixup_schema_name(table_name)}_#{Array.wrap(column_name).join('_and_')}"
120
+ end
121
+
122
+ def self.fixup_schema_name(table_name)
123
+ # replace . with _
124
+ table_name.to_s.gsub(/[.]/, '_')
115
125
  end
116
126
 
117
127
  end
@@ -47,6 +47,12 @@ module SchemaPlus
47
47
  exec_stmt_without_schema_plus(sql, name, binds, &block)
48
48
  end
49
49
 
50
+ # implement cascade by removing foreign keys
51
+ def drop_table(name, options={})
52
+ reverse_foreign_keys(name).each{ |foreign_key| remove_foreign_key(foreign_key.table_name, foreign_key.name) } if options[:cascade]
53
+ super
54
+ end
55
+
50
56
  def remove_foreign_key(table_name, foreign_key_name, options = {})
51
57
  execute "ALTER TABLE #{quote_table_name(table_name)} DROP FOREIGN KEY #{foreign_key_name}"
52
58
  end
@@ -54,6 +60,9 @@ module SchemaPlus
54
60
  def foreign_keys(table_name, name = nil)
55
61
  results = execute("SHOW CREATE TABLE #{quote_table_name(table_name)}", name)
56
62
 
63
+ table_name = table_name.to_s
64
+ namespace_prefix = table_namespace_prefix(table_name)
65
+
57
66
  foreign_keys = []
58
67
 
59
68
  results.each do |row|
@@ -62,6 +71,7 @@ module SchemaPlus
62
71
  name = $1
63
72
  column_names = $2
64
73
  references_table_name = $3
74
+ references_table_name = namespace_prefix + references_table_name if table_namespace_prefix(references_table_name).blank?
65
75
  references_column_names = $4
66
76
  on_update = $8
67
77
  on_delete = $6
@@ -69,7 +79,7 @@ module SchemaPlus
69
79
  on_delete = on_delete ? on_delete.downcase.gsub(' ', '_').to_sym : :restrict
70
80
 
71
81
  foreign_keys << ForeignKeyDefinition.new(name,
72
- table_name, column_names.gsub('`', '').split(', '),
82
+ namespace_prefix + table_name, column_names.gsub('`', '').split(', '),
73
83
  references_table_name, references_column_names.gsub('`', '').split(', '),
74
84
  on_update, on_delete)
75
85
  end
@@ -83,17 +93,23 @@ module SchemaPlus
83
93
  results = execute(<<-SQL, name)
84
94
  SELECT constraint_name, table_name, column_name, referenced_table_name, referenced_column_name
85
95
  FROM information_schema.key_column_usage
86
- WHERE table_schema = SCHEMA()
96
+ WHERE table_schema = #{table_schema_sql(table_name)}
87
97
  AND referenced_table_schema = table_schema
88
98
  ORDER BY constraint_name, ordinal_position;
89
99
  SQL
90
100
  current_foreign_key = nil
91
101
  foreign_keys = []
92
102
 
103
+ namespace_prefix = table_namespace_prefix(table_name)
104
+
93
105
  results.each do |row|
94
- next unless table_name.casecmp(row[3]) == 0
106
+ next unless table_name_without_namespace(table_name).casecmp(row[3]) == 0
95
107
  if current_foreign_key != row[0]
96
- foreign_keys << ForeignKeyDefinition.new(row[0], row[1], [], row[3], [])
108
+ referenced_table_name = row[1]
109
+ referenced_table_name = namespace_prefix + referenced_table_name if table_namespace_prefix(referenced_table_name).blank?
110
+ references_table_name = row[3]
111
+ references_table_name = namespace_prefix + references_table_name if table_namespace_prefix(references_table_name).blank?
112
+ foreign_keys << ForeignKeyDefinition.new(row[0], referenced_table_name, [], references_table_name, [])
97
113
  current_foreign_key = row[0]
98
114
  end
99
115
 
@@ -134,6 +150,21 @@ module SchemaPlus
134
150
  when :now then 'CURRENT_TIMESTAMP'
135
151
  end
136
152
  end
153
+
154
+ private
155
+
156
+ def table_namespace_prefix(table_name)
157
+ table_name.to_s =~ /(.*[.])/ ? $1 : ""
158
+ end
159
+
160
+ def table_schema_sql(table_name)
161
+ table_name.to_s =~ /(.*)[.]/ ? "'#{$1}'" : "SCHEMA()"
162
+ end
163
+
164
+ def table_name_without_namespace(table_name)
165
+ table_name.to_s.sub /.*[.]/, ''
166
+ end
167
+
137
168
  end
138
169
  end
139
170
  end
@@ -53,6 +53,7 @@ module SchemaPlus
53
53
  alias_method_chain :rename_table, :schema_plus
54
54
  alias_method_chain :exec_cache, :schema_plus
55
55
  end
56
+ ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.send(:include, PostgreSQLColumn) unless ::ActiveRecord::ConnectionAdapters::PostgreSQLColumn.include?(PostgreSQLColumn)
56
57
  end
57
58
 
58
59
  # SchemaPlus provides the following extra options for Postgres
@@ -126,8 +127,8 @@ module SchemaPlus
126
127
  INNER JOIN pg_am m ON i.relam = m.oid
127
128
  WHERE i.relkind = 'i'
128
129
  AND d.indisprimary = 'f'
129
- AND t.relname = '#{table_name}'
130
- AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )
130
+ AND t.relname = '#{table_name_without_namespace(table_name)}'
131
+ AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = #{namespace_sql(table_name)} )
131
132
  ORDER BY i.relname
132
133
  SQL
133
134
 
@@ -200,8 +201,8 @@ module SchemaPlus
200
201
  FROM pg_class t, pg_constraint f
201
202
  WHERE f.conrelid = t.oid
202
203
  AND f.contype = 'f'
203
- AND t.relname = '#{table_name}'
204
- AND t.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )
204
+ AND t.relname = '#{table_name_without_namespace(table_name)}'
205
+ AND t.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = #{namespace_sql(table_name)} )
205
206
  SQL
206
207
  end
207
208
 
@@ -212,17 +213,19 @@ module SchemaPlus
212
213
  WHERE f.confrelid = t.oid
213
214
  AND f.conrelid = t2.oid
214
215
  AND f.contype = 'f'
215
- AND t.relname = '#{table_name}'
216
- AND t.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )
216
+ AND t.relname = '#{table_name_without_namespace(table_name)}'
217
+ AND t.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = #{namespace_sql(table_name)} )
217
218
  SQL
218
219
  end
219
220
 
220
221
  def views(name = nil) #:nodoc:
221
- query(<<-SQL, name).map { |row| row[0] }
222
- SELECT viewname
223
- FROM pg_views
224
- WHERE schemaname = ANY (current_schemas(false))
222
+ sql = <<-SQL
223
+ SELECT viewname
224
+ FROM pg_views
225
+ WHERE schemaname = ANY (current_schemas(false))
225
226
  SQL
227
+ sql += " AND schemaname != 'postgis'" if adapter_name == 'PostGIS'
228
+ query(sql, name).map { |row| row[0] }
226
229
  end
227
230
 
228
231
  def view_definition(view_name, name = nil) #:nodoc:
@@ -238,11 +241,19 @@ module SchemaPlus
238
241
 
239
242
  private
240
243
 
244
+ def namespace_sql(table_name)
245
+ (table_name.to_s =~ /(.*)[.]/) ? "'#{$1}'" : "ANY (current_schemas(false))"
246
+ end
247
+
248
+ def table_name_without_namespace(table_name)
249
+ table_name.to_s.sub /.*[.]/, ''
250
+ end
251
+
241
252
  def load_foreign_keys(sql, name = nil) #:nodoc:
242
253
  foreign_keys = []
243
254
 
244
255
  query(sql, name).each do |row|
245
- if row[1] =~ /^FOREIGN KEY \((.+?)\) REFERENCES (.+?)\((.+?)\)( ON UPDATE (.+?))?( ON DELETE (.+?))?( (DEFERRABLE|NOT DEFERRABLE))?$/
256
+ if row[1] =~ /^FOREIGN KEY \((.+?)\) REFERENCES (.+?)\((.+?)\)( ON UPDATE (.+?))?( ON DELETE (.+?))?( (DEFERRABLE|NOT DEFERRABLE)( (INITIALLY DEFERRED|INITIALLY IMMEDIATE))?)?$/
246
257
  name = row[0]
247
258
  from_table_name = row[2]
248
259
  column_names = $1
@@ -251,6 +262,7 @@ module SchemaPlus
251
262
  on_update = $5
252
263
  on_delete = $7
253
264
  deferrable = $9 == "DEFERRABLE"
265
+ deferrable = :initially_deferred if ($11 == "INITIALLY DEFERRED" )
254
266
  on_update = on_update ? on_update.downcase.gsub(' ', '_').to_sym : :no_action
255
267
  on_delete = on_delete ? on_delete.downcase.gsub(' ', '_').to_sym : :no_action
256
268
 
@@ -22,6 +22,9 @@ module SchemaPlus::ActiveRecord::ConnectionAdapters
22
22
  config_options = {}
23
23
  options.keys.each { |key| config_options[key] = options.delete(key) if SchemaPlus.config.class.attributes.include? key }
24
24
 
25
+ # override rails' :force to cascade
26
+ drop_table(table, if_exists: true, cascade: true) if options.delete(:force)
27
+
25
28
  indexes = []
26
29
  create_table_without_schema_plus(table, options) do |table_definition|
27
30
  table_definition.schema_plus_config = SchemaPlus.config.merge(config_options)
@@ -21,6 +21,7 @@ module SchemaPlus
21
21
  alias_method_chain :indexes, :schema_plus
22
22
  alias_method_chain :rename_table, :schema_plus
23
23
  end
24
+ ::ActiveRecord::ConnectionAdapters::SQLiteColumn.send(:include, SQLiteColumn) unless ::ActiveRecord::ConnectionAdapters::SQLiteColumn.include?(SQLiteColumn)
24
25
  end
25
26
 
26
27
  def indexes_with_schema_plus(table_name, name = nil)
@@ -39,7 +40,6 @@ module SchemaPlus
39
40
  rename_indexes_and_foreign_keys(oldname, newname)
40
41
  end
41
42
 
42
-
43
43
  def add_foreign_key(table_name, column_names, references_table_name, references_column_names, options = {})
44
44
  raise NotImplementedError, "Sqlite3 does not support altering a table to add foreign key constraints (table #{table_name.inspect} column #{column_names.inspect})"
45
45
  end
@@ -48,6 +48,10 @@ module SchemaPlus
48
48
  raise NotImplementedError, "Sqlite3 does not support altering a table to remove foreign key constraints (table #{table_name.inspect} constraint #{foreign_key_name.inspect})"
49
49
  end
50
50
 
51
+ def drop_table(name, options={})
52
+ super(name, options.except(:cascade))
53
+ end
54
+
51
55
  def foreign_keys(table_name, name = nil)
52
56
  get_foreign_keys(table_name, name)
53
57
  end
@@ -83,22 +87,24 @@ module SchemaPlus
83
87
  \s*REFERENCES\s*[`"](.+?)[`"]\s*\((.+?)\)
84
88
  (\s+ON\s+UPDATE\s+(.+?))?
85
89
  (\s*ON\s+DELETE\s+(.+?))?
90
+ (\s*DEFERRABLE(\s+INITIALLY\s+DEFERRED)?)?
86
91
  \s*[,)]
87
92
  ]x
88
93
 
89
94
  foreign_keys = []
90
95
  results.each do |row|
91
96
  table_name = row["name"]
92
- row["sql"].scan(re).each do |d0, name, column_names, references_table_name, references_column_names, d1, on_update, d2, on_delete|
97
+ row["sql"].scan(re).each do |d0, name, column_names, references_table_name, references_column_names, d1, on_update, d2, on_delete, deferrable, initially_deferred|
93
98
  column_names = column_names.gsub('`', '').split(', ')
94
99
 
95
100
  references_column_names = references_column_names.gsub('`"', '').split(', ')
96
101
  on_update = on_update ? on_update.downcase.gsub(' ', '_').to_sym : :no_action
97
102
  on_delete = on_delete ? on_delete.downcase.gsub(' ', '_').to_sym : :no_action
103
+ deferrable = deferrable ? (initially_deferred ? :initially_deferred : true) : false
98
104
  foreign_keys << ForeignKeyDefinition.new(name,
99
105
  table_name, column_names,
100
106
  references_table_name, references_column_names,
101
- on_update, on_delete)
107
+ on_update, on_delete, deferrable)
102
108
  end
103
109
  end
104
110
 
@@ -1,3 +1,3 @@
1
1
  module SchemaPlus
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
data/runspecs CHANGED
@@ -97,7 +97,7 @@ combos.each_with_index do |combo, n|
97
97
  Tempfile.open('runspecs') do |file|
98
98
  system("(#{command}) 2>&1 | tee #{file.path}")
99
99
  file.rewind
100
- errs << "ruby #{ruby}, rails #{rails}#{db_adapter && ", db_adapter #{db_adapter}"}" if file.readlines.grep(/^Failed examples/).any?
100
+ errs << "ruby #{ruby}, rails #{rails}#{db_adapter && ", db_adapter #{db_adapter}"}" if file.readlines.grep(/(^Failed examples)|(rake aborted)/).any?
101
101
  end
102
102
  end
103
103
  puts errs.any? ? "\n*** #{errs.size} failures:\n\t#{errs.join("\n\t")}" : "\n*** #{combos.size > 1 ? 'all versions' : 'spec'} succeeded ***" unless o.dry_run
@@ -133,7 +133,7 @@ describe "Column definition" do
133
133
  subject { @sql}
134
134
 
135
135
  it "should give the default as false" do
136
- should match /boolean DEFAULT (\'f\'|0)/
136
+ should =~ /boolean DEFAULT (\'f\'|0)/
137
137
  end
138
138
  end
139
139
 
@@ -145,7 +145,7 @@ describe "Column definition" do
145
145
  subject { @sql}
146
146
 
147
147
  it "should give the default as true" do
148
- should match /boolean DEFAULT (\'t\'|1)/
148
+ should =~ /boolean DEFAULT (\'t\'|1)/
149
149
  end
150
150
  end
151
151
  end
data/spec/column_spec.rb CHANGED
@@ -8,6 +8,16 @@ describe "Column" do
8
8
 
9
9
  let(:migration) { ::ActiveRecord::Migration }
10
10
 
11
+ context "JSON serialization" do
12
+ before(:each) do
13
+ create_table(User, :login => { :index => true})
14
+ @login = User.columns.find{|column| column.name == "login"}
15
+ end
16
+ it "works properly" do
17
+ JSON.parse(@login.to_json).should include("name" => "login", "type" => "string")
18
+ end
19
+ end
20
+
11
21
  context "regarding indexes" do
12
22
 
13
23
  context "if not unique" do
@@ -78,7 +88,7 @@ describe "Column" do
78
88
  User.columns.find{|column| column.name == "login"}.required_on.should == :save
79
89
  end
80
90
 
81
- it "must have a value on :updae if there's default" do
91
+ it "must have a value on :update if there's default" do
82
92
  create_table(User, :login => { :null => false, :default => "foo" })
83
93
  User.columns.find{|column| column.name == "login"}.required_on.should == :update
84
94
  end
@@ -4,10 +4,20 @@ describe "Foreign Key definition" do
4
4
 
5
5
  let(:definition) { SchemaPlus::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new("posts_user_fkey", :posts, :user, :users, :id) }
6
6
 
7
- it "it is dumped to sql with quoted values" do
7
+ it "dumps to sql with quoted values" do
8
8
  definition.to_sql.should == %Q{CONSTRAINT posts_user_fkey FOREIGN KEY (#{quote_column_name('user')}) REFERENCES #{quote_table_name('users')} (#{quote_column_name('id')})}
9
9
  end
10
10
 
11
+ it "dumps to sql with deferrable values" do
12
+ deferred_definition = SchemaPlus::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new("posts_user_fkey", :posts, :user, :users, :id, nil, nil, true)
13
+ deferred_definition.to_sql.should == %Q{CONSTRAINT posts_user_fkey FOREIGN KEY (#{quote_column_name('user')}) REFERENCES #{quote_table_name('users')} (#{quote_column_name('id')}) DEFERRABLE}
14
+ end
15
+
16
+ it "dumps to sql with initially deferrable values" do
17
+ initially_deferred_definition = SchemaPlus::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new("posts_user_fkey", :posts, :user, :users, :id, nil, nil, :initially_deferred)
18
+ initially_deferred_definition.to_sql.should == %Q{CONSTRAINT posts_user_fkey FOREIGN KEY (#{quote_column_name('user')}) REFERENCES #{quote_table_name('users')} (#{quote_column_name('id')}) DEFERRABLE INITIALLY DEFERRED}
19
+ end
20
+
11
21
  def quote_table_name(table)
12
22
  ActiveRecord::Base.connection.quote_table_name(table)
13
23
  end
@@ -4,7 +4,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
4
4
  describe ActiveRecord::Migration do
5
5
  include SchemaPlusHelpers
6
6
 
7
- before(:all) do
7
+ before(:each) do
8
8
  define_schema(:auto_create => true) do
9
9
 
10
10
  create_table :users, :force => true do |t|
@@ -293,14 +293,14 @@ describe ActiveRecord::Migration do
293
293
  end
294
294
  end
295
295
 
296
- it "should use default on_update action" do
297
- with_fk_config(:on_update => :cascade) do
296
+ [false, true, :initially_deferred].each do |status|
297
+ it "should create and detect deferrable #{status.inspect}" do
298
298
  recreate_table @model do |t|
299
- t.integer :user_id
299
+ t.integer :user_id, :on_delete => :cascade, :deferrable => status
300
300
  end
301
- @model.should reference.on(:user_id).on_update(:cascade)
301
+ @model.should reference.on(:user_id).deferrable(status)
302
302
  end
303
- end
303
+ end unless SchemaPlusHelpers.mysql?
304
304
 
305
305
  it "should use default on_delete action" do
306
306
  with_fk_config(:on_delete => :cascade) do
@@ -121,6 +121,98 @@ describe "with multiple schemas" do
121
121
 
122
122
  end
123
123
 
124
+ context "foreign key migrations" do
125
+ before(:each) do
126
+ define_schema do
127
+ create_table "items", :force => true do |t|
128
+ end
129
+ create_table "schema_plus_test2.groups", :force => true do |t|
130
+ end
131
+ create_table "schema_plus_test2.members", :force => true do |t|
132
+ t.integer :item_id, :foreign_key => true unless SchemaPlusHelpers.mysql?
133
+ t.integer :group_id, :foreign_key => { references: "schema_plus_test2.groups" }
134
+ end
135
+ end
136
+ class Group < ::ActiveRecord::Base
137
+ self.table_name = "schema_plus_test2.groups"
138
+ end
139
+ class Item < ::ActiveRecord::Base
140
+ self.table_name = "items"
141
+ end
142
+ class Member < ::ActiveRecord::Base
143
+ self.table_name = "schema_plus_test2.members"
144
+ end
145
+ end
146
+
147
+ around(:each) do |example|
148
+ begin
149
+ example.run
150
+ ensure
151
+ connection.execute 'DROP TABLE IF EXISTS schema_plus_test2.members'
152
+ connection.execute 'DROP TABLE IF EXISTS schema_plus_test2.groups'
153
+ connection.execute 'DROP TABLE IF EXISTS items'
154
+ end
155
+ end
156
+
157
+ it "should find foreign keys" do
158
+ Member.foreign_keys.should_not be_empty
159
+ end
160
+
161
+ it "should find reverse foreign keys" do
162
+ Group.reverse_foreign_keys.should_not be_empty
163
+ end
164
+
165
+ it "should reference table in same schema" do
166
+ Member.foreign_keys.map(&:references_table_name).should include "schema_plus_test2.groups"
167
+ end
168
+
169
+ it "should reference table in default schema" do
170
+ Member.foreign_keys.map(&:references_table_name).should include "items"
171
+ end unless SchemaPlusHelpers.mysql?
172
+
173
+ it "should include the schema in the constraint name" do
174
+ expected_names = ["fk_schema_plus_test2_members_group_id"]
175
+ expected_names << "fk_schema_plus_test2_members_item_id" unless SchemaPlusHelpers.mysql?
176
+ Member.foreign_keys.map(&:name).should =~ expected_names
177
+ end
178
+ end
179
+
180
+ if SchemaPlusHelpers.postgresql?
181
+ context "when using PostGIS" do
182
+ before(:all) do
183
+ begin
184
+ connection.execute "CREATE SCHEMA postgis"
185
+ rescue ActiveRecord::StatementInvalid => e
186
+ raise unless e.message =~ /already exists/
187
+ end
188
+ end
189
+
190
+ around (:each) do |example|
191
+ begin
192
+ connection.execute "SET search_path to '$user','public','postgis'"
193
+ example.run
194
+ ensure
195
+ connection.execute "SET search_path to '$user','public'"
196
+ end
197
+ end
198
+
199
+ before(:each) do
200
+ connection.stub :adapter_name => 'PostGIS'
201
+ end
202
+
203
+ it "should hide views in postgis schema" do
204
+ begin
205
+ connection.create_view "postgis.hidden", "select 1", :force => true
206
+ connection.create_view :myview, "select 2", :force => true
207
+ connection.views.should == ["myview"]
208
+ ensure
209
+ connection.execute 'DROP VIEW postgis.hidden' rescue nil
210
+ connection.execute 'DROP VIEW myview' rescue nil
211
+ end
212
+ end
213
+ end
214
+ end
215
+
124
216
  end
125
217
 
126
218