pg_saurus 4.0.3 → 5.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
  SHA256:
3
- metadata.gz: 778a1bfb5f393bfecb57a2fdd90ac89044043622d4ad1a7eaae64c4fded53dd5
4
- data.tar.gz: e7d4a61024004a1c2cc93667c0d1aeee63d5c7196723aa0908e23fe90e5a9d40
3
+ metadata.gz: 7a6d057b35291dc622b20193e085fc52c5807fd8310b1d8925b9c0636d72d95b
4
+ data.tar.gz: 7f0257ad41a044c887519c844a54334172fa5e829f7c6e06c0aca6280f8f6625
5
5
  SHA512:
6
- metadata.gz: 047a944035bfead9aa7789d3b70a1712a661a79758eb7fcd700147f33845489175087f602aa8c8b1871dbaaeeb98c0c1476faf96cd585c8dc812035cecf3500d
7
- data.tar.gz: c60056f0f70e57a931390138f1a12f61c2177f619b15de78a0057fe09995b403f3076018eade54a27a9e899f218cf48e1a288ff3d07ecad2c0a0d9effef6abc8
6
+ metadata.gz: ab15973698f38c460f51ee4879913be9c6fc4d9b7c5fde71d4e597cb230b8097b1011330017da05d2b67d8fac6c7e852c21e2d2314602ecf0892a9c3ed7251e7
7
+ data.tar.gz: 680092950b8eeb8d1716edf301d14a94744ecdb352423b9550b5b84abbd59ffd323dcb226bac13707e1b4edbe4753808ccfe955cbb5f2f0890a168f1f0d3658c
@@ -29,7 +29,7 @@ module ActiveRecord
29
29
  WHERE schemaname = ANY (ARRAY['public'])
30
30
  SQL
31
31
  end
32
-
32
+
33
33
  # Returns an array of indexes for the given table.
34
34
  #
35
35
  # == Patch 1:
@@ -135,13 +135,9 @@ module ActiveRecord
135
135
  # the column is difficult to target for quoting.
136
136
  skip_column_quoting = options.delete(:skip_column_quoting) or false
137
137
 
138
- index_name,
139
- index_type,
140
- index_columns_and_opclasses,
141
- index_options,
142
- index_algorithm,
143
- index_using,
144
- comment = add_index_options(table_name, column_name, options)
138
+ index, algorithm, if_not_exists = add_index_options(table_name, column_name, **options)
139
+ algorithm = creation_method || algorithm
140
+ create_index = CreateIndexDefinition.new(index, algorithm, if_not_exists)
145
141
 
146
142
  # GOTCHA:
147
143
  # It ensures that there is no existing index only for the case when the index
@@ -156,24 +152,11 @@ module ActiveRecord
156
152
  # -- zekefast 2012-09-25
157
153
  if creation_method.present? && index_exists?(table_name, column_name, options)
158
154
  raise ::PgSaurus::IndexExistsError,
159
- "Index #{index_name} for `#{table_name}.#{column_name}` " \
155
+ "Index #{index.name} for `#{table_name}.#{column_name}` " \
160
156
  "column can not be created concurrently, because such index already exists."
161
157
  end
162
158
 
163
- statements = []
164
- statements << "CREATE #{index_type} INDEX"
165
- statements << creation_method if creation_method.present?
166
- statements << index_algorithm if index_algorithm.present?
167
- statements << quote_column_name(index_name)
168
- statements << "ON"
169
- statements << quote_table_name(table_name)
170
- statements << index_using if index_using.present?
171
- statements << "(#{index_columns_and_opclasses})" if index_columns_and_opclasses.present? unless skip_column_quoting
172
- statements << "(#{column_name})" if column_name.present? and skip_column_quoting
173
- statements << index_options if index_options.present?
174
-
175
- sql = statements.join(' ')
176
- execute(sql)
159
+ execute schema_creation.accept(create_index)
177
160
  end
178
161
 
179
162
  # Check to see if an index exists on a table for a given index definition.
@@ -250,7 +233,7 @@ module ActiveRecord
250
233
  column_name, operator_name = split_column_name(name)
251
234
 
252
235
  result_name = if column_name =~ FUNCTIONAL_INDEX_REGEXP
253
- _name = "#{$1}(#{$2}#{quote_column_name($3)})"
236
+ _name = column_name.gsub(/\b#{$3}\b/, quote_column_name($3))
254
237
  _name += " #{operator_name}"
255
238
  _name
256
239
  else
@@ -260,9 +243,8 @@ module ActiveRecord
260
243
  end
261
244
  ]
262
245
 
263
- add_options_for_index_columns(quoted_columns, options).values
246
+ add_options_for_index_columns(quoted_columns, **options).values.join(", ")
264
247
  end
265
- protected :quoted_columns_for_index
266
248
 
267
249
  # Map an expression to a name appropriate for an index.
268
250
  def expression_index_name(name)
@@ -280,6 +262,36 @@ module ActiveRecord
280
262
  end
281
263
  private :expression_index_name
282
264
 
265
+
266
+ # == Patch 1:
267
+ # Remove schema name part from table name when sequence name doesn't include it.
268
+ def new_column_from_field(table_name, field)
269
+ column_name, type, default, notnull, oid, fmod, collation, comment = field
270
+ type_metadata = fetch_type_metadata(column_name, type, oid.to_i, fmod.to_i)
271
+ default_value = extract_value_from_default(default)
272
+ default_function = extract_default_function(default_value, default)
273
+
274
+ if match = default_function&.match(/\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z/)
275
+ sequence_name = match[:sequence_name]
276
+ is_schema_name_included = sequence_name.split(".").size > 1
277
+ _table_name = is_schema_name_included ? table_name : table_name.split(".").last
278
+
279
+ serial = sequence_name_from_parts(_table_name, column_name, match[:suffix]) == sequence_name
280
+ end
281
+
282
+ PostgreSQL::Column.new(
283
+ column_name,
284
+ default_value,
285
+ type_metadata,
286
+ !notnull,
287
+ default_function,
288
+ collation: collation,
289
+ comment: comment.presence,
290
+ serial: serial
291
+ )
292
+ end
293
+ private :new_column_from_field
294
+
283
295
  # Split column name to name and operator class if possible.
284
296
  def split_column_name(name)
285
297
  if name =~ OPERATOR_REGEXP
@@ -4,17 +4,19 @@ module PgSaurus::ConnectionAdapters::AbstractAdapter::SchemaMethods
4
4
 
5
5
  # Provide :schema option to +create_table+ method.
6
6
  def create_table(table_name, options = {}, &block)
7
- options = options.dup
8
- schema_name = options.delete(:schema)
9
- table_name = "#{schema_name}.#{table_name}" if schema_name
7
+ table_name, options = extract_table_options(table_name, options)
10
8
  super(table_name, options, &block)
11
9
  end
12
10
 
13
11
  # Provide :schema option to +drop_table+ method.
14
12
  def drop_table(table_name, options = {})
13
+ super(*extract_table_options(table_name, options))
14
+ end
15
+
16
+ def extract_table_options(table_name, options)
15
17
  options = options.dup
16
18
  schema_name = options.delete(:schema)
17
19
  table_name = "#{schema_name}.#{table_name}" if schema_name
18
- super(table_name, options)
20
+ [table_name, options]
19
21
  end
20
22
  end
@@ -112,8 +112,7 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::ExtensionMethods
112
112
  # @return [Hash{String => Hash{Symbol => String}}] A list of loaded extensions with their options
113
113
  def pg_extensions
114
114
  # Check postgresql version to not break on Postgresql < 9.1 during schema dump
115
- pg_version_str = select_value('SELECT version()')
116
- return {} unless pg_version_str =~ /^PostgreSQL (\d+\.\d+.\d+)/ && ($1 >= '9.1')
115
+ return {} if (::PgSaurus::Engine.pg_server_version <=> [9, 1]) < 0
117
116
 
118
117
  sql = <<-SQL
119
118
  SELECT pge.extname AS ext_name, pgn.nspname AS schema_name, pge.extversion AS ext_version
@@ -11,12 +11,13 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::FunctionMethods
11
11
 
12
12
  # Return a list of defined DB functions. Ignore function definitions that can't be parsed.
13
13
  def functions
14
+ pg_major = ::PgSaurus::Engine.pg_server_version[0]
14
15
  res = select_all <<-SQL
15
16
  SELECT n.nspname AS "Schema",
16
17
  p.proname AS "Name",
17
18
  pg_catalog.pg_get_function_result(p.oid) AS "Returning",
18
19
  CASE
19
- WHEN p.proiswindow THEN 'window'
20
+ WHEN #{pg_major >= 11 ? "p.prokind = 'w'" : "p.proiswindow"} THEN 'window'
20
21
  WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN 'trigger'
21
22
  ELSE 'normal'
22
23
  END AS "Type",
@@ -26,7 +27,7 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::FunctionMethods
26
27
  WHERE pg_catalog.pg_function_is_visible(p.oid)
27
28
  AND n.nspname <> 'pg_catalog'
28
29
  AND n.nspname <> 'information_schema'
29
- AND p.proisagg <> TRUE
30
+ AND #{pg_major >= 11 ? "p.prokind <> 'a'" : "p.proisagg <> TRUE"}
30
31
  ORDER BY 1, 2, 3, 4;
31
32
  SQL
32
33
  res.inject([]) do |buffer, row|
@@ -5,14 +5,15 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::TranslateException
5
5
  INSUFFICIENT_PRIVILEGE = "42501"
6
6
 
7
7
  # Intercept insufficient privilege PG::Error and raise active_record wrapped database exception
8
- def translate_exception(exception, message)
8
+ def translate_exception(exception, message:, sql:, binds:)
9
+ return exception unless exception.respond_to?(:result)
9
10
  exception_result = exception.result
10
11
 
11
12
  case exception_result.try(:error_field, PG::Result::PG_DIAG_SQLSTATE)
12
13
  when INSUFFICIENT_PRIVILEGE
13
14
  exc_message = exception_result.try(:error_field, PG::Result::PG_DIAG_MESSAGE_PRIMARY)
14
15
  exc_message ||= message
15
- ::ActiveRecord::InsufficientPrivilege.new(exc_message)
16
+ ::ActiveRecord::InsufficientPrivilege.new(exc_message, sql: sql, binds: binds)
16
17
  else
17
18
  super
18
19
  end
@@ -95,7 +95,7 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::TriggerMethods
95
95
 
96
96
  # Parse the condition from the trigger definition.
97
97
  def parse_condition(trigger_definition)
98
- trigger_definition[/WHEN[\s](.*?)[\s]EXECUTE[\s]PROCEDURE/m, 1]
98
+ trigger_definition[/WHEN[\s](.*?)[\s]EXECUTE[\s](FUNCTION|PROCEDURE)/m, 1]
99
99
  end
100
100
  private :parse_condition
101
101
 
@@ -107,7 +107,7 @@ module PgSaurus::ConnectionAdapters::PostgreSQLAdapter::TriggerMethods
107
107
 
108
108
  # Parse the procedure name from the trigger definition.
109
109
  def parse_proc_name(trigger_definition)
110
- trigger_definition[/EXECUTE[\s]PROCEDURE[\s](.*?)$/m,1]
110
+ trigger_definition[/EXECUTE[\s](FUNCTION|PROCEDURE)[\s](.*?)$/m, 2]
111
111
  end
112
112
  private :parse_proc_name
113
113
 
@@ -72,7 +72,7 @@ module PgSaurus::CreateIndexConcurrently
72
72
  def add_index(table_name, column_name, options = {}, &block)
73
73
  table_name = proper_table_name(table_name)
74
74
  # GOTCHA:
75
- # checks if index should be created concurretnly then put it into
75
+ # checks if index should be created concurrently then put it into
76
76
  # the queue to wait till queue processing will be called (should be
77
77
  # happended after closing transaction).
78
78
  # Otherwise just delegate call to PgSaurus's `add_index`.
@@ -2,13 +2,24 @@ module PgSaurus
2
2
  # :nodoc:
3
3
  class Engine < Rails::Engine
4
4
 
5
+ # Postgres server version.
6
+ #
7
+ # @return [Array<Integer>]
8
+ def self.pg_server_version
9
+ @pg_server_version ||=
10
+ ::ActiveRecord::Base.connection.
11
+ select_value('SHOW SERVER_VERSION').
12
+ split('.')[0..1].map(&:to_i)
13
+ end
14
+
5
15
  initializer "pg_saurus" do
6
16
  ActiveSupport.on_load(:active_record) do
7
17
  # load monkey patches
8
- %w(schema_dumper
9
- errors
10
- connection_adapters/postgresql/schema_statements
11
- connection_adapters/postgresql/column).each do |path|
18
+ %w[
19
+ schema_dumper
20
+ errors
21
+ connection_adapters/postgresql/schema_statements
22
+ ].each do |path|
12
23
  require ::PgSaurus::Engine.root + "lib/core_ext/active_record/" + path
13
24
  end
14
25
 
@@ -15,8 +15,8 @@ module PgSaurus::SchemaDumper::ExtensionMethods
15
15
  extensions = @connection.pg_extensions
16
16
  commands = extensions.map do |extension_name, options|
17
17
  result = [%Q|create_extension "#{extension_name}"|]
18
- result << %Q|:schema_name => "#{options[:schema_name]}"| unless options[:schema_name] == 'public'
19
- result << %Q|:version => "#{options[:version]}"|
18
+ result << %Q|schema_name: "#{options[:schema_name]}"| unless options[:schema_name] == 'public'
19
+ result << %Q|version: "#{options[:version]}"|
20
20
  result.join(', ')
21
21
  end
22
22
 
@@ -1,4 +1,4 @@
1
1
  module PgSaurus
2
2
  # Version of pg_saurus gem.
3
- VERSION = "4.0.3"
3
+ VERSION = "5.0.0"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_saurus
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.3
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Potapov Sergey
@@ -10,10 +10,10 @@ authors:
10
10
  - Matt Dressel
11
11
  - Bruce Burdick
12
12
  - HornsAndHooves
13
- autorequire:
13
+ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2020-01-31 00:00:00.000000000 Z
16
+ date: 2022-01-06 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: pg
@@ -29,62 +29,76 @@ dependencies:
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
31
  version: '0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: psych
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - "~>"
37
+ - !ruby/object:Gem::Version
38
+ version: '3'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - "~>"
44
+ - !ruby/object:Gem::Version
45
+ version: '3'
32
46
  - !ruby/object:Gem::Dependency
33
47
  name: railties
34
48
  requirement: !ruby/object:Gem::Requirement
35
49
  requirements:
36
50
  - - "~>"
37
51
  - !ruby/object:Gem::Version
38
- version: 5.2.3
52
+ version: '6.0'
39
53
  type: :runtime
40
54
  prerelease: false
41
55
  version_requirements: !ruby/object:Gem::Requirement
42
56
  requirements:
43
57
  - - "~>"
44
58
  - !ruby/object:Gem::Version
45
- version: 5.2.3
59
+ version: '6.0'
46
60
  - !ruby/object:Gem::Dependency
47
61
  name: activemodel
48
62
  requirement: !ruby/object:Gem::Requirement
49
63
  requirements:
50
64
  - - "~>"
51
65
  - !ruby/object:Gem::Version
52
- version: 5.2.3
66
+ version: '6.0'
53
67
  type: :runtime
54
68
  prerelease: false
55
69
  version_requirements: !ruby/object:Gem::Requirement
56
70
  requirements:
57
71
  - - "~>"
58
72
  - !ruby/object:Gem::Version
59
- version: 5.2.3
73
+ version: '6.0'
60
74
  - !ruby/object:Gem::Dependency
61
75
  name: activerecord
62
76
  requirement: !ruby/object:Gem::Requirement
63
77
  requirements:
64
78
  - - "~>"
65
79
  - !ruby/object:Gem::Version
66
- version: 5.2.3
80
+ version: '6.0'
67
81
  type: :runtime
68
82
  prerelease: false
69
83
  version_requirements: !ruby/object:Gem::Requirement
70
84
  requirements:
71
85
  - - "~>"
72
86
  - !ruby/object:Gem::Version
73
- version: 5.2.3
87
+ version: '6.0'
74
88
  - !ruby/object:Gem::Dependency
75
89
  name: activesupport
76
90
  requirement: !ruby/object:Gem::Requirement
77
91
  requirements:
78
92
  - - "~>"
79
93
  - !ruby/object:Gem::Version
80
- version: 5.2.3
94
+ version: '6.0'
81
95
  type: :runtime
82
96
  prerelease: false
83
97
  version_requirements: !ruby/object:Gem::Requirement
84
98
  requirements:
85
99
  - - "~>"
86
100
  - !ruby/object:Gem::Version
87
- version: 5.2.3
101
+ version: '6.0'
88
102
  - !ruby/object:Gem::Dependency
89
103
  name: rspec-rails
90
104
  requirement: !ruby/object:Gem::Requirement
@@ -212,7 +226,6 @@ extra_rdoc_files:
212
226
  files:
213
227
  - README.markdown
214
228
  - lib/colorized_text.rb
215
- - lib/core_ext/active_record/connection_adapters/postgresql/column.rb
216
229
  - lib/core_ext/active_record/connection_adapters/postgresql/schema_statements.rb
217
230
  - lib/core_ext/active_record/errors.rb
218
231
  - lib/core_ext/active_record/schema_dumper.rb
@@ -270,7 +283,7 @@ homepage: https://github.com/HornsAndHooves/pg_saurus
270
283
  licenses:
271
284
  - MIT
272
285
  metadata: {}
273
- post_install_message:
286
+ post_install_message:
274
287
  rdoc_options: []
275
288
  require_paths:
276
289
  - lib
@@ -285,9 +298,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
285
298
  - !ruby/object:Gem::Version
286
299
  version: '0'
287
300
  requirements: []
288
- rubyforge_project:
289
- rubygems_version: 2.7.9
290
- signing_key:
301
+ rubygems_version: 3.0.8
302
+ signing_key:
291
303
  specification_version: 4
292
304
  summary: ActiveRecord extensions for PostgreSQL.
293
305
  test_files: []
@@ -1,19 +0,0 @@
1
- module ActiveRecord
2
- module ConnectionAdapters
3
- # PostgreSQL-specific extensions to column definitions in a table.
4
- class PostgreSQLColumn < Column #:nodoc:
5
- # == Patch 1:
6
- # Remove schema name part from table name when sequence name doesn't include it.
7
- def serial?
8
- return unless default_function
9
-
10
- if %r{\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z} =~ default_function
11
- is_schema_name_included = sequence_name.split(".").size > 1
12
- _table_name = is_schema_name_included ? table_name : table_name.split(".").last
13
-
14
- sequence_name_from_parts(_table_name, name, suffix) == sequence_name
15
- end
16
- end
17
- end
18
- end
19
- end