pg_saurus 4.0.3 → 5.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
  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