activerecord-postgres-composite-types 0.2.4 → 0.2.5

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
  SHA1:
3
- metadata.gz: fab1ca82523eece0cf8b9e0c64fd7cc0903b76ff
4
- data.tar.gz: 218877b1a29bce9e891c450b989be9442c223333
3
+ metadata.gz: 9d4f0647edbf6bedba08366faa187b0920815e9d
4
+ data.tar.gz: 1256ce07b6c0b404b85f872f316d87e344f327ab
5
5
  SHA512:
6
- metadata.gz: f98e1e96acfdd9607f918c7db4c47a8f2625ccb0769e8c6a0416008840f24dfec6a136c82aa4c18800d2be6fa8b9c0f3ff1e8b154e9f8e94150b4a5a3103d43b
7
- data.tar.gz: df68e9973ecfb0d47906f5a1ac22e3f0bbe0dd7b3b2929c36c2363abbf3d7840df3de8304b0240b6e8513fadf4afdfb772fdacfa8a53f2c5a5ce795dc2de005e
6
+ metadata.gz: e1c84c2c8a241aebd3412baa37ac3113468d4df82d84a938be27c8863ff6cdb4645c5ca5e841adfde52fbd7db32125e0e919ff55cc2d3df3fa64e3c6d21cb1b3
7
+ data.tar.gz: 26709a6e15d0b28768228648754654f222074e3ba8a9728e0507ea0bacca0e86998a1d6e539ebe2714888629dc5147f2b90983c6568ef0455a7dcd9a113eca2d
data/Gemfile CHANGED
@@ -6,13 +6,13 @@ gem 'activerecord', ">= #{AR_VERSION}"
6
6
  gem 'pg', '>= 0.17.0'
7
7
 
8
8
  group :development do
9
- gem 'test-unit', '~> 2.1'
10
- gem 'shoulda', '>= 0'
11
- gem 'rdoc', '~> 3.12'
12
- gem 'rake', '~> 10.3'
13
- gem 'bundler', '~> 1.0'
14
- gem 'jeweler', '~> 2.0.1' unless RUBY_PLATFORM =~ /mswin/
15
- gem 'simplecov', '>= 0'
16
- gem 'combustion', '~> 0.5.2'
17
- gem 'tzinfo-data' if AR_VERSION > '3.2.0'
9
+ gem 'test-unit', '~> 2.1'
10
+ gem 'shoulda', '>= 0'
11
+ gem 'rdoc', '~> 3.12'
12
+ gem 'rake', '~> 10.3'
13
+ gem 'bundler', '~> 1.0'
14
+ gem 'jeweler', '~> 2.0.1' unless RUBY_PLATFORM =~ /mswin/
15
+ gem 'simplecov', '>= 0'
16
+ gem 'combustion', '~> 0.5.2'
17
+ gem 'tzinfo-data' if AR_VERSION > '3.2.0'
18
18
  end
data/Rakefile CHANGED
@@ -12,19 +12,19 @@ end
12
12
  require 'rake'
13
13
 
14
14
  unless RUBY_PLATFORM =~ /mswin/
15
- require 'jeweler'
16
- Jeweler::Tasks.new do |gem|
17
- # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
18
- gem.name = "activerecord-postgres-composite-types"
19
- gem.homepage = "http://github.com/puzzleflow/activerecord-postgres-composite-types"
20
- gem.license = "MIT"
21
- gem.summary = %Q{ActiveRecord composite types support}
22
- gem.description = %Q{This gem adds support to the ActiveRecord (3.x and 4.x) for composite types.}
23
- gem.email = "rafal.bigaj@puzzleflow.com"
24
- gem.authors = ["Rafal Bigaj"]
25
- # dependencies defined in Gemfile
26
- end
27
- Jeweler::RubygemsDotOrgTasks.new
15
+ require 'jeweler'
16
+ Jeweler::Tasks.new do |gem|
17
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
18
+ gem.name = "activerecord-postgres-composite-types"
19
+ gem.homepage = "http://github.com/puzzleflow/activerecord-postgres-composite-types"
20
+ gem.license = "MIT"
21
+ gem.summary = %Q{ActiveRecord composite types support}
22
+ gem.description = %Q{This gem adds support to the ActiveRecord (3.x and 4.x) for composite types.}
23
+ gem.email = "rafal.bigaj@puzzleflow.com"
24
+ gem.authors = ["Rafal Bigaj"]
25
+ # dependencies defined in Gemfile
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
28
  end
29
29
 
30
30
  require 'rake/testtask'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.2.5
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: activerecord-postgres-composite-types 0.2.4 ruby lib
5
+ # stub: activerecord-postgres-composite-types 0.2.5 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "activerecord-postgres-composite-types"
9
- s.version = "0.2.4"
9
+ s.version = "0.2.5"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Rafal Bigaj"]
14
- s.date = "2014-11-28"
14
+ s.date = "2014-12-11"
15
15
  s.description = "This gem adds support to the ActiveRecord (3.x and 4.x) for composite types."
16
16
  s.email = "rafal.bigaj@puzzleflow.com"
17
17
  s.extra_rdoc_files = [
@@ -45,7 +45,7 @@ Gem::Specification.new do |s|
45
45
  ]
46
46
  s.homepage = "http://github.com/puzzleflow/activerecord-postgres-composite-types"
47
47
  s.licenses = ["MIT"]
48
- s.rubygems_version = "2.4.2"
48
+ s.rubygems_version = "2.4.3"
49
49
  s.summary = "ActiveRecord composite types support"
50
50
 
51
51
  if s.respond_to? :specification_version then
@@ -1,10 +1,10 @@
1
1
  require 'active_record'
2
2
 
3
3
  if defined? Rails
4
- require "activerecord-postgres-composite-types/railtie"
4
+ require "activerecord-postgres-composite-types/railtie"
5
5
  else
6
- ActiveSupport.on_load :active_record do
7
- require "activerecord-postgres-composite-types/active_record"
8
- require 'postgres_composite_type'
9
- end
6
+ ActiveSupport.on_load :active_record do
7
+ require "activerecord-postgres-composite-types/active_record"
8
+ require 'postgres_composite_type'
9
+ end
10
10
  end
@@ -5,165 +5,158 @@ require 'activerecord-postgres-composite-types/composite_type_parser'
5
5
 
6
6
  module ActiveRecord
7
7
 
8
- module ConnectionAdapters
9
-
10
- class PostgreSQLAdapter
11
-
12
- # Quotes the column value to help prevent {SQL injection attacks}
13
- def quote_with_composite_types(value, column = nil)
14
- if value.class < PostgresCompositeType
15
- "'#{PostgreSQLColumn.composite_type_to_string(value, self).gsub(/'/, "''")}'"
16
- else
17
- quote_without_composite_types(value, column)
18
- end
19
- end
20
-
21
- alias_method_chain :quote, :composite_types
22
-
23
- class << self
24
- def register_composite_type_class(klass)
25
- self.composite_type_classes[klass.type] = klass
26
- TableDefinition.register_composite_type klass.type
27
- Table.register_composite_type klass.type
28
- register_arel_visitor klass
29
- register_oid_type klass
30
- end
31
-
32
- def register_arel_visitor(klass)
33
- Arel::Visitors::Visitor.class_eval <<-RUBY
8
+ module ConnectionAdapters
9
+
10
+ class PostgreSQLAdapter
11
+
12
+ # Quotes the column value to help prevent {SQL injection attacks}
13
+ def quote_with_composite_types(value, column = nil)
14
+ if value.class < PostgresCompositeType
15
+ "'#{PostgreSQLColumn.composite_type_to_string(value, self).gsub(/'/, "''")}'"
16
+ else
17
+ quote_without_composite_types(value, column)
18
+ end
19
+ end
20
+
21
+ alias_method_chain :quote, :composite_types
22
+
23
+ class << self
24
+ def register_composite_type_class(klass)
25
+ self.composite_type_classes[klass.type] = klass
26
+ TableDefinition.register_composite_type klass.type
27
+ Table.register_composite_type klass.type
28
+ register_arel_visitor klass
29
+ register_oid_type klass
30
+ end
31
+
32
+ def register_arel_visitor(klass)
33
+ Arel::Visitors::Visitor.class_eval <<-RUBY
34
34
  def visit_#{klass.name.gsub('::', '_')}(o, a=nil)
35
35
  "'" + ActiveRecord::ConnectionAdapters::PostgreSQLColumn::composite_type_to_string(o, o.class.connection) + "'" + '::#{klass.type}'
36
36
  end
37
- RUBY
38
- end
39
-
40
- def register_oid_type(klass)
41
- # only AR 4.X
42
- end
43
-
44
- # removes composite types definition (for testing)
45
- def unregister_composite_types(*composite_types)
46
- composite_types.each { |type| unregister_composite_type type }
47
- end
48
-
49
- # removes composite type definition (for testing)
50
- def unregister_composite_type(type)
51
- self.composite_type_classes.delete(type.to_sym)
52
- TableDefinition.unregister_composite_type type
53
- Table.unregister_composite_type type
54
- end
55
-
56
- def composite_type_classes
57
- @composite_type_classes ||= {}
58
- end
59
- end
60
- end
61
-
62
- class PostgreSQLColumn < Column
63
- # Adds composite type for the column.
64
-
65
- def composite_type_class
66
- PostgreSQLAdapter.composite_type_classes[type]
67
- end
68
-
69
- def klass_with_composite_types
70
- composite_type_klass = PostgreSQLAdapter.composite_type_classes[type]
71
- composite_type_klass || klass_without_composite_types
72
- end
73
-
74
- alias_method_chain :klass, :composite_types
75
-
76
- def self.string_to_composite_type(klass, string)
77
- return string unless String === string
78
- if string.present?
79
- klass.new(string)
80
- end
81
- end
82
-
83
- def self.string_to_composite_type(klass, string)
84
- return string unless String === string
85
- if string.present?
86
- fields = CompositeTypeParser.parse_data(string).map.with_index {|val, i| type_cast_composite_type_field(klass, i, val)}
87
- klass.new(fields)
88
- end
89
- end
90
-
91
- def self.type_cast_composite_type_field(klass, i, value)
92
- klass.initialize_column_definition
93
-
94
- column = klass.columns[i]
95
- raise "Invalid column index: #{i}" unless column
96
- cv = column.type_cast(value)
97
- if cv.is_a?(String)
98
- # unquote
99
- cv = cv.upcase == 'NULL' ? nil : cv.gsub(/\A"(.*)"\Z/m) { $1.gsub(/\\(.)/, '\1') }
100
- end
101
- cv
102
- end
103
-
104
- private
105
-
106
- def simplified_type_with_composite_types(field_type)
107
- type = field_type.to_sym
108
- if PostgreSQLAdapter.composite_type_classes.has_key?(type)
109
- type
110
- else
111
- simplified_type_without_composite_types(field_type)
112
- end
113
- end
114
-
115
- alias_method_chain :simplified_type, :composite_types
116
- end
117
-
118
- class << TableDefinition
119
- # Adds composite type for migrations. So you can add columns to a table like:
120
- # create_table :people do |t|
121
- # ...
122
- # t.composite_type :composite_value
123
- # ...
124
- # end
125
- def register_composite_type(composite_type)
126
- class_eval <<-RUBY
37
+ RUBY
38
+ end
39
+
40
+ def register_oid_type(klass)
41
+ # only AR 4.X
42
+ end
43
+
44
+ # removes composite types definition (for testing)
45
+ def unregister_composite_types(*composite_types)
46
+ composite_types.each { |type| unregister_composite_type type }
47
+ end
48
+
49
+ # removes composite type definition (for testing)
50
+ def unregister_composite_type(type)
51
+ self.composite_type_classes.delete(type.to_sym)
52
+ TableDefinition.unregister_composite_type type
53
+ Table.unregister_composite_type type
54
+ end
55
+
56
+ def composite_type_classes
57
+ @composite_type_classes ||= {}
58
+ end
59
+ end
60
+ end
61
+
62
+ class PostgreSQLColumn < Column
63
+ # Adds composite type for the column.
64
+
65
+ def composite_type_class
66
+ PostgreSQLAdapter.composite_type_classes[type]
67
+ end
68
+
69
+ def klass_with_composite_types
70
+ composite_type_klass = PostgreSQLAdapter.composite_type_classes[type]
71
+ composite_type_klass || klass_without_composite_types
72
+ end
73
+
74
+ alias_method_chain :klass, :composite_types
75
+
76
+ def self.string_to_composite_type(klass, string)
77
+ return string unless String === string
78
+ if string.present?
79
+ fields = CompositeTypeParser.parse_data(string).map.with_index { |val, i| type_cast_composite_type_field(klass, i, val) }
80
+ klass.new(fields)
81
+ end
82
+ end
83
+
84
+ def self.type_cast_composite_type_field(klass, i, value)
85
+ klass.initialize_column_definition
86
+
87
+ column = klass.columns[i]
88
+ raise "Invalid column index: #{i}" unless column
89
+ cv = column.type_cast(value)
90
+ if cv.is_a?(String)
91
+ # unquote
92
+ cv = cv.upcase == 'NULL' ? nil : cv.gsub(/\A"(.*)"\Z/m) { $1.gsub(/\\(.)/, '\1') }
93
+ end
94
+ cv
95
+ end
96
+
97
+ private
98
+
99
+ def simplified_type_with_composite_types(field_type)
100
+ type = field_type.to_sym
101
+ if PostgreSQLAdapter.composite_type_classes.has_key?(type)
102
+ type
103
+ else
104
+ simplified_type_without_composite_types(field_type)
105
+ end
106
+ end
107
+
108
+ alias_method_chain :simplified_type, :composite_types
109
+ end
110
+
111
+ class << TableDefinition
112
+ # Adds composite type for migrations. So you can add columns to a table like:
113
+ # create_table :people do |t|
114
+ # ...
115
+ # t.composite_type :composite_value
116
+ # ...
117
+ # end
118
+ def register_composite_type(composite_type)
119
+ class_eval <<-RUBY
120
+ def #{composite_type}(*args)
121
+ options = args.extract_options!
122
+ column_names = args
123
+ column_names.each { |name| column(name, '#{composite_type}', options) }
124
+ end
125
+ RUBY
126
+ end
127
+
128
+ # Removes composite types from migrations (for testing)
129
+ def unregister_composite_type(composite_type)
130
+ remove_method composite_type
131
+ end
132
+ end
133
+
134
+ class << Table
135
+
136
+ # Adds composite type for migrations. So you can add columns to a table like:
137
+ # change_table :people do |t|
138
+ # ...
139
+ # t.composite_type :composite_value
140
+ # ...
141
+ # end
142
+ def register_composite_type(composite_type)
143
+ class_eval <<-RUBY
127
144
  def #{composite_type}(*args)
128
145
  options = args.extract_options!
129
146
  column_names = args
130
147
  column_names.each { |name| column(name, '#{composite_type}', options) }
131
148
  end
132
- RUBY
133
- end
134
-
135
- # Removes composite types from migrations (for testing)
136
- def unregister_composite_type(composite_type)
137
- remove_method composite_type
138
- end
139
- end
140
-
141
- class << Table
142
-
143
- # Adds composite type for migrations. So you can add columns to a table like:
144
- # change_table :people do |t|
145
- # ...
146
- # t.composite_type :composite_value
147
- # ...
148
- # end
149
- def register_composite_type(composite_type)
150
- class_eval <<-RUBY
151
- def #{composite_type}(*args)
152
- options = args.extract_options!
153
- column_names = args
154
- column_names.each { |name| column(name, '#{composite_type}', options) }
155
- end
156
- RUBY
157
- end
149
+ RUBY
150
+ end
158
151
 
159
- # Removes composite types from migrations (for testing)
160
- def unregister_composite_type(composite_type)
161
- remove_method composite_type
162
- end
152
+ # Removes composite types from migrations (for testing)
153
+ def unregister_composite_type(composite_type)
154
+ remove_method composite_type
155
+ end
163
156
 
164
- end
157
+ end
165
158
 
166
- end
159
+ end
167
160
 
168
161
  end
169
162
 
@@ -1,104 +1,104 @@
1
1
  # ActiveRecord 3.X specific extensions.
2
2
  module ActiveRecord
3
3
 
4
- module ConnectionAdapters
4
+ module ConnectionAdapters
5
5
 
6
- class PostgreSQLAdapter
7
- # Cast a +value+ to a type that the database understands.
8
- def type_cast_with_composite_types(value, column)
9
- case value
10
- when PostgresCompositeType
11
- PostgreSQLColumn.composite_type_to_string(value, self)
12
- when Array, Hash
13
- if klass = column.composite_type_class
14
- value = klass.new(value)
15
- PostgreSQLColumn.composite_type_to_string(value, self)
16
- else
17
- type_cast_without_composite_types(value, column)
18
- end
19
- else
20
- type_cast_without_composite_types(value, column)
21
- end
22
- end
6
+ class PostgreSQLAdapter
7
+ # Cast a +value+ to a type that the database understands.
8
+ def type_cast_with_composite_types(value, column)
9
+ case value
10
+ when PostgresCompositeType
11
+ PostgreSQLColumn.composite_type_to_string(value, self)
12
+ when Array, Hash
13
+ if klass = column.composite_type_class
14
+ value = klass.new(value)
15
+ PostgreSQLColumn.composite_type_to_string(value, self)
16
+ else
17
+ type_cast_without_composite_types(value, column)
18
+ end
19
+ else
20
+ type_cast_without_composite_types(value, column)
21
+ end
22
+ end
23
23
 
24
- alias_method_chain :type_cast, :composite_types
25
- end
24
+ alias_method_chain :type_cast, :composite_types
25
+ end
26
26
 
27
- class PostgreSQLColumn < Column
28
- # Adds composite type for the column.
27
+ class PostgreSQLColumn < Column
28
+ # Adds composite type for the column.
29
29
 
30
- # Casts value (which is a String) to an appropriate instance.
31
- def type_cast_with_composite_types(value)
32
- if composite_type_klass = PostgreSQLAdapter.composite_type_classes[type]
33
- self.class.string_to_composite_type(composite_type_klass, value)
34
- else
35
- type_cast_without_composite_types(value)
36
- end
37
- end
30
+ # Casts value (which is a String) to an appropriate instance.
31
+ def type_cast_with_composite_types(value)
32
+ if composite_type_klass = PostgreSQLAdapter.composite_type_classes[type]
33
+ self.class.string_to_composite_type(composite_type_klass, value)
34
+ else
35
+ type_cast_without_composite_types(value)
36
+ end
37
+ end
38
38
 
39
- alias_method_chain :type_cast, :composite_types
39
+ alias_method_chain :type_cast, :composite_types
40
40
 
41
- # quote_and_escape - Rails 4 code
41
+ # quote_and_escape - Rails 4 code
42
42
 
43
- ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays
43
+ ARRAY_ESCAPE = "\\" * 2 * 2 # escape the backslash twice for PG arrays
44
44
 
45
- def self.quote_and_escape(value)
46
- case value
47
- when "NULL", Numeric
48
- value
49
- else
50
- value = value.gsub(/\\/, ARRAY_ESCAPE)
51
- value.gsub!(/"/, "\\\"")
52
- "\"#{value}\""
53
- end
54
- end
45
+ def self.quote_and_escape(value)
46
+ case value
47
+ when "NULL", Numeric
48
+ value
49
+ else
50
+ value = value.gsub(/\\/, ARRAY_ESCAPE)
51
+ value.gsub!(/"/, "\\\"")
52
+ "\"#{value}\""
53
+ end
54
+ end
55
55
 
56
- def self.composite_type_to_string(object, adapter)
57
- quoted_values = object.class.columns.collect do |column|
58
- value = object.send(column.name)
59
- if String === value
60
- if value == "NULL"
61
- "\"#{value}\""
62
- else
63
- quote_and_escape(adapter.type_cast(value, column))
64
- end
65
- else
66
- adapter.type_cast(value, column)
67
- end
68
- end
69
- "(#{quoted_values.join(',')})"
70
- end
56
+ def self.composite_type_to_string(object, adapter)
57
+ quoted_values = object.class.columns.collect do |column|
58
+ value = object.send(column.name)
59
+ if String === value
60
+ if value == "NULL"
61
+ "\"#{value}\""
62
+ else
63
+ quote_and_escape(adapter.type_cast(value, column))
64
+ end
65
+ else
66
+ adapter.type_cast(value, column)
67
+ end
68
+ end
69
+ "(#{quoted_values.join(',')})"
70
+ end
71
71
 
72
- def type_cast_code_with_composite_types(var_name)
73
- if composite_type_klass = PostgreSQLAdapter.composite_type_classes[type]
74
- "#{self.class}.string_to_composite_type(#{composite_type_klass}, #{var_name})"
75
- else
76
- type_cast_code_without_composite_types(var_name)
77
- end
78
- end
72
+ def type_cast_code_with_composite_types(var_name)
73
+ if composite_type_klass = PostgreSQLAdapter.composite_type_classes[type]
74
+ "#{self.class}.string_to_composite_type(#{composite_type_klass}, #{var_name})"
75
+ else
76
+ type_cast_code_without_composite_types(var_name)
77
+ end
78
+ end
79
79
 
80
- alias_method_chain :type_cast_code, :composite_types
81
- end
82
- end
80
+ alias_method_chain :type_cast_code, :composite_types
81
+ end
82
+ end
83
83
 
84
- module AttributeMethods
85
- module CompositeTypes
86
- extend ActiveSupport::Concern
84
+ module AttributeMethods
85
+ module CompositeTypes
86
+ extend ActiveSupport::Concern
87
87
 
88
- def type_cast_attribute_for_write(column, value)
89
- if column && klass = column.composite_type_class
90
- # Cast Hash and Array to composite type klass
91
- if value.is_a?(klass)
92
- value
93
- else
94
- klass.new(value)
95
- end
96
- else
97
- super(column, value)
98
- end
99
- end
100
- end
101
- end
88
+ def type_cast_attribute_for_write(column, value)
89
+ if column && klass = column.composite_type_class
90
+ # Cast Hash and Array to composite type klass
91
+ if value.is_a?(klass)
92
+ value
93
+ else
94
+ klass.new(value)
95
+ end
96
+ else
97
+ super(column, value)
98
+ end
99
+ end
100
+ end
101
+ end
102
102
 
103
- Base.send :include, AttributeMethods::CompositeTypes
103
+ Base.send :include, AttributeMethods::CompositeTypes
104
104
  end