pg_saurus 4.3.0 → 5.2.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: d0658a18dcaee8fd3acbe9334daf053e0a22568157b53d1b182add67970dd799
4
- data.tar.gz: 87468b4dca614127ebdea002e67d92e610c3d0057ede82dc4d6a18dd90d60c18
3
+ metadata.gz: 2e34851f56966751c37812d080ed193b3423044b8195b6b719a5e694a4079774
4
+ data.tar.gz: 30ec47321e4d6216016b16b3c322d176175e11b43a675a866cf33654a4102e9c
5
5
  SHA512:
6
- metadata.gz: f9305018ca8cf965346683abcf7296a3459f2d81d9887829c75f3eb26aa3a0f5341af4c58b0c0459e9fb679481bf3c778f94ba981c8676d0c52dfe36d84f1802
7
- data.tar.gz: 41a869cf2aa17cde12b29f684ec39c9d89862c11c9dd1f909d39cbaa3ae29163f634d1ec5070d27c60bb7cc4281ba0e1b30da8bffb81b09538a847260d2463a2
6
+ metadata.gz: d961c60aea3f5f0c12d5b7fa8db0829bfae06a89c25f26352dc4be834b8e180bc78fed0079355f425324e4a7278b41e6a751069008044b1556596999b7eec961
7
+ data.tar.gz: 98fdf87d1e1e084e6b2dddd90d74f01c08a22e2e6a9322a755dab3e3f339ad516312a257a6337d20a733425070eccf0bf58fe9c1d4eaf51da1c4ac1ebec95951
@@ -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,20 @@ 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
+ # Extract the table-specific options for the given table name from the options.
17
+ def extract_table_options(table_name, options)
15
18
  options = options.dup
16
19
  schema_name = options.delete(:schema)
17
20
  table_name = "#{schema_name}.#{table_name}" if schema_name
18
- super(table_name, options)
21
+ [table_name, options]
19
22
  end
20
23
  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
@@ -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
 
@@ -15,7 +15,7 @@ module PgSaurus::SchemaDumper::FunctionMethods
15
15
  # Writes out a command to create each detected function.
16
16
  def dump_functions(stream)
17
17
  @connection.functions.each do |function|
18
- statement = " create_function '#{function.name}', :#{function.returning}, <<-FUNCTION_DEFINITION.gsub(/^[\s]{4}/, ''), volatility: :#{function.volatility}"
18
+ statement = " create_function '#{function.name}', '#{function.returning}', <<-FUNCTION_DEFINITION.gsub(/^[\s]{4}/, ''), volatility: :#{function.volatility}"
19
19
  statement << "\n#{function.definition.split("\n").map{|line| " #{line}" }.join("\n")}"
20
20
  statement << "\n FUNCTION_DEFINITION\n\n"
21
21
 
@@ -1,4 +1,4 @@
1
1
  module PgSaurus
2
2
  # Version of pg_saurus gem.
3
- VERSION = "4.3.0"
3
+ VERSION = "5.2.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.3.0
4
+ version: 5.2.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-22 00:00:00.000000000 Z
16
+ date: 2022-07-09 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,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
299
298
  - !ruby/object:Gem::Version
300
299
  version: '0'
301
300
  requirements: []
302
- rubygems_version: 3.0.9
301
+ rubygems_version: 3.0.8
303
302
  signing_key:
304
303
  specification_version: 4
305
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