pg_saurus 4.2.0 → 5.1.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: cc48a831f1ab97b0f56ef559766c5284a92eed10583bd02d31729d7554225016
4
- data.tar.gz: 9798c1dd0e4caf1b8407f5c2041ffd52d727375bdfa4c03996ee542419164972
3
+ metadata.gz: 4a5ce70db53d9b1636c43b1e2156bc88eeabebf62fbeb39e9ea6141bec719eb3
4
+ data.tar.gz: '058c5db2a699fba1f9bec20a0136e4fef2721f03a30b8fc74d1a83197dc20f21'
5
5
  SHA512:
6
- metadata.gz: 0e3bc30b1a68e2cfee33264c903b0d34815eb6c9c26692bd85b8157c01a24f9152f3615af2ea25c4b389b02dc4c9f1553cb9fdd05e34cf221a2efc491c945532
7
- data.tar.gz: 26fdd30c2a66cd61f18622febd46ceaa4b8d394afcfe66df6161377bf964f03617e8383f7fbcb03526d4fdd27882045270bc19f0d54362cd3c187bc0564563fb
6
+ metadata.gz: 4909fe1c8a4694daf48598534b9d4e0dac565224be24c055187e1fe1a125e542f48fbbd4af646b81d4cf7c2a729b56712f6687abfc5106386e302abdfbf105ed
7
+ data.tar.gz: a647b93cd3c8ac24b62c9accf944fa1874d7a902a0129eea64e2f3bf20361f855eff2ed5ee0bb18e66055bf8210a8e8aff1d6da38d663eb4679616a5c436f138
@@ -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,25 +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
-
177
- execute(sql)
159
+ execute schema_creation.accept(create_index)
178
160
  end
179
161
 
180
162
  # Check to see if an index exists on a table for a given index definition.
@@ -261,9 +243,8 @@ module ActiveRecord
261
243
  end
262
244
  ]
263
245
 
264
- add_options_for_index_columns(quoted_columns, options).values
246
+ add_options_for_index_columns(quoted_columns, **options).values.join(", ")
265
247
  end
266
- protected :quoted_columns_for_index
267
248
 
268
249
  # Map an expression to a name appropriate for an index.
269
250
  def expression_index_name(name)
@@ -281,6 +262,36 @@ module ActiveRecord
281
262
  end
282
263
  private :expression_index_name
283
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
+
284
295
  # Split column name to name and operator class if possible.
285
296
  def split_column_name(name)
286
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
@@ -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`.
@@ -15,10 +15,11 @@ module PgSaurus
15
15
  initializer "pg_saurus" do
16
16
  ActiveSupport.on_load(:active_record) do
17
17
  # load monkey patches
18
- %w(schema_dumper
19
- errors
20
- connection_adapters/postgresql/schema_statements
21
- connection_adapters/postgresql/column).each do |path|
18
+ %w[
19
+ schema_dumper
20
+ errors
21
+ connection_adapters/postgresql/schema_statements
22
+ ].each do |path|
22
23
  require ::PgSaurus::Engine.root + "lib/core_ext/active_record/" + path
23
24
  end
24
25
 
@@ -7,4 +7,10 @@ module PgSaurus
7
7
 
8
8
  # Raised if config.ensure_role_set = true, but migration have no role set.
9
9
  class RoleNotSetError < Error; end
10
+
11
+ # Raised if set_role used for data change migration.
12
+ class UseKeepDefaultRoleError < Error; end
13
+
14
+ # Raised if keep_default_role used for structure change migration.
15
+ class UseSetRoleError < Error; end
10
16
  end
@@ -13,11 +13,57 @@ module PgSaurus
13
13
  #
14
14
  # @param role [String]
15
15
  def set_role(role)
16
+ if const_defined?("SeedMigrator") && self.ancestors.include?(SeedMigrator)
17
+ msg = <<~MSG
18
+ Use keep_default_role instead of set_role for data change migration #{self}
19
+
20
+ Example:
21
+
22
+ class PopulateExample < ActiveRecord::Migration
23
+ include #{self.ancestors[1]}
24
+
25
+ keep_default_role
26
+
27
+ def up
28
+ apply_update "populate_example_data_update"
29
+ end
30
+
31
+ def down
32
+ revert_update "populate_example_data_update"
33
+ end
34
+ end
35
+ MSG
36
+
37
+ raise PgSaurus::UseKeepDefaultRoleError, msg
38
+ end
39
+
16
40
  @role = role
17
41
  end
18
42
 
19
43
  # Prevents raising exception when ensure_role_set=true and no role is set.
20
44
  def keep_default_role
45
+ if const_defined?("SeedMigrator") && !self.ancestors.include?(SeedMigrator)
46
+ msg = <<~MSG
47
+ Use set_role instead of keep_default_role for structure migration #{self}
48
+
49
+ Example:
50
+
51
+ class CreateExamples < ActiveRecord::Migration
52
+ set_role "superhero"
53
+
54
+ def up
55
+ ...
56
+ end
57
+
58
+ def down
59
+ ...
60
+ end
61
+ end
62
+ MSG
63
+
64
+ raise PgSaurus::UseSetRoleError, msg
65
+ end
66
+
21
67
  @keep_default_role = true
22
68
  end
23
69
 
@@ -1,4 +1,4 @@
1
1
  module PgSaurus
2
2
  # Version of pg_saurus gem.
3
- VERSION = "4.2.0"
3
+ VERSION = "5.1.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.2.0
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Potapov Sergey
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2021-09-02 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
@@ -49,56 +49,56 @@ dependencies:
49
49
  requirements:
50
50
  - - "~>"
51
51
  - !ruby/object:Gem::Version
52
- version: 5.2.3
52
+ version: '6.0'
53
53
  type: :runtime
54
54
  prerelease: false
55
55
  version_requirements: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: 5.2.3
59
+ version: '6.0'
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: activemodel
62
62
  requirement: !ruby/object:Gem::Requirement
63
63
  requirements:
64
64
  - - "~>"
65
65
  - !ruby/object:Gem::Version
66
- version: 5.2.3
66
+ version: '6.0'
67
67
  type: :runtime
68
68
  prerelease: false
69
69
  version_requirements: !ruby/object:Gem::Requirement
70
70
  requirements:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
- version: 5.2.3
73
+ version: '6.0'
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: activerecord
76
76
  requirement: !ruby/object:Gem::Requirement
77
77
  requirements:
78
78
  - - "~>"
79
79
  - !ruby/object:Gem::Version
80
- version: 5.2.3
80
+ version: '6.0'
81
81
  type: :runtime
82
82
  prerelease: false
83
83
  version_requirements: !ruby/object:Gem::Requirement
84
84
  requirements:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: 5.2.3
87
+ version: '6.0'
88
88
  - !ruby/object:Gem::Dependency
89
89
  name: activesupport
90
90
  requirement: !ruby/object:Gem::Requirement
91
91
  requirements:
92
92
  - - "~>"
93
93
  - !ruby/object:Gem::Version
94
- version: 5.2.3
94
+ version: '6.0'
95
95
  type: :runtime
96
96
  prerelease: false
97
97
  version_requirements: !ruby/object:Gem::Requirement
98
98
  requirements:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
- version: 5.2.3
101
+ version: '6.0'
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: rspec-rails
104
104
  requirement: !ruby/object:Gem::Requirement
@@ -226,7 +226,6 @@ extra_rdoc_files:
226
226
  files:
227
227
  - README.markdown
228
228
  - lib/colorized_text.rb
229
- - lib/core_ext/active_record/connection_adapters/postgresql/column.rb
230
229
  - lib/core_ext/active_record/connection_adapters/postgresql/schema_statements.rb
231
230
  - lib/core_ext/active_record/errors.rb
232
231
  - lib/core_ext/active_record/schema_dumper.rb
@@ -299,8 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
299
298
  - !ruby/object:Gem::Version
300
299
  version: '0'
301
300
  requirements: []
302
- rubyforge_project:
303
- rubygems_version: 2.7.9
301
+ rubygems_version: 3.0.9
304
302
  signing_key:
305
303
  specification_version: 4
306
304
  summary: ActiveRecord extensions for PostgreSQL.
@@ -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