@@ -12,6 +12,26 @@ def dump_mode!
12
12
@_dump_mode = !!!@_dump_mode
13
13
end
14
14
15
+ # List of schemas blocked by the application in the current connection
16
+ def schemas_blacklist
17
+ @schemas_blacklist ||= Torque ::PostgreSQL . config . schemas . blacklist +
18
+ ( @config . dig ( :schemas , 'blacklist' ) || [ ] )
19
+ end
20
+
21
+ # List of schemas used by the application in the current connection
22
+ def schemas_whitelist
23
+ @schemas_whitelist ||= Torque ::PostgreSQL . config . schemas . whitelist +
24
+ ( @config . dig ( :schemas , 'whitelist' ) || [ ] )
25
+ end
26
+
27
+ # A list of schemas on the search path sanitized
28
+ def schemas_search_path_sanitized
29
+ @schemas_search_path_sanitized ||= begin
30
+ db_user = @config [ :username ] || ENV [ 'USER' ] || ENV [ 'USERNAME' ]
31
+ schema_search_path . split ( ',' ) . map { |item | item . strip . sub ( '"$user"' , db_user ) }
32
+ end
33
+ end
34
+
15
35
# Check if a given type is valid.
16
36
def valid_type? ( type )
17
37
super || extended_types . include? ( type )
@@ -22,6 +42,17 @@ def extended_types
22
42
EXTENDED_DATABASE_TYPES
23
43
end
24
44
45
+ # Checks if a given schema exists in the database. If +filtered+ is
46
+ # given as false, then it will check regardless of whitelist and
47
+ # blacklist
48
+ def schema_exists? ( name , filtered : true )
49
+ return user_defined_schemas . include? ( name . to_s ) if filtered
50
+
51
+ query_value ( <<-SQL ) == 1
52
+ SELECT 1 FROM pg_catalog.pg_namespace WHERE nspname = '#{ name } '
53
+ SQL
54
+ end
55
+
25
56
# Returns true if type exists.
26
57
def type_exists? ( name )
27
58
user_defined_types . key? name . to_s
@@ -124,18 +155,41 @@ def user_defined_types(*categories)
124
155
# Get the list of inherited tables associated with their parent tables
125
156
def inherited_tables
126
157
tables = query ( <<-SQL , 'SCHEMA' )
127
- SELECT child.relname AS table_name,
128
- array_agg(parent.relname) AS inheritances
158
+ SELECT inhrelid::regclass AS table_name,
159
+ inhparent::regclass AS inheritances
129
160
FROM pg_inherits
130
161
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
131
162
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
132
- GROUP BY child.relname, pg_inherits.inhrelid
133
- ORDER BY pg_inherits.inhrelid
163
+ ORDER BY inhrelid
134
164
SQL
135
165
136
- tables . map do |( table , refs ) |
137
- [ table , PG ::TextDecoder ::Array . new . decode ( refs ) ]
138
- end . to_h
166
+ tables . each_with_object ( { } ) do |( child , parent ) , result |
167
+ ( result [ child ] ||= [ ] ) << parent
168
+ end
169
+ end
170
+
171
+ # Get the list of schemas that were created by the user
172
+ def user_defined_schemas
173
+ query_values ( user_defined_schemas_sql , 'SCHEMA' )
174
+ end
175
+
176
+ # Build the query for allowed schemas
177
+ def user_defined_schemas_sql
178
+ conditions = [ ]
179
+ conditions << <<-SQL if schemas_blacklist . any?
180
+ nspname NOT LIKE ANY (ARRAY['#{ schemas_blacklist . join ( "', '" ) } '])
181
+ SQL
182
+
183
+ conditions << <<-SQL if schemas_whitelist . any?
184
+ nspname LIKE ANY (ARRAY['#{ schemas_whitelist . join ( "', '" ) } '])
185
+ SQL
186
+
187
+ <<-SQL . squish
188
+ SELECT nspname
189
+ FROM pg_catalog.pg_namespace
190
+ WHERE 1=1 AND #{ conditions . join ( ' AND ' ) }
191
+ ORDER BY oid
192
+ SQL
139
193
end
140
194
141
195
# Get the list of columns, and their definition, but only from the
0 commit comments