ar_pg_array 0.8.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.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Sokolov Yura aka funny_falcon
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,39 @@
1
+ PostgresArrays
2
+ ==============
3
+
4
+ This library adds ability to use PostgreSQL array types with ActiveRecord.
5
+
6
+ > User.find(:all, :conditions=>['arr @> ?', [1,2,3].pg])
7
+ SELECT * FROM "users" WHERE ('arr' @> E'{"1", "2", "3"}')
8
+ > User.find(:all, :conditions=>['arr @> ?', [1,2,3].pg(:integer)])
9
+ SELECT * FROM "users" WHERE (arr @> '{1,2,3}')
10
+ > User.find(:all, :conditions=>['arr @> ?', [1,2,3].pg(:float)])
11
+ SELECT * FROM "users" WHERE (arr @> '{1.0,2.0,3.0}')
12
+ > u = User.find(1)
13
+ SELECT * FROM "users" WHERE ("users"."id" = 1)
14
+ => #<User id: 1, ..., arr: [1,2]>
15
+ > u.arr = [3,4]
16
+ > u.save
17
+ UPDATE "users" SET "db_ar" = '{3.0,4.0}' WHERE "id" = 19
18
+ > User.find(:all, :conditions=>{:arr=>[3,4].pg})
19
+ SELECT * FROM "users" WHERE ("users"."arr" = E'{"3", "4"}')
20
+ > User.find(:all, :conditions=>{:arr=>[3,4].search_any(:float)})
21
+ SELECT * FROM "users" WHERE ("users"."arr" && '{3.0,4.0}')
22
+ > User.find(:all, :conditions=>{:arr=>[3,4].search_all(:integer)})
23
+ SELECT * FROM "users" WHERE ("users"."arr" @> '{3,4}')
24
+ > User.find(:all, :conditions=>{:arr=>[3,4].search_subarray(:safe)})
25
+ SELECT * FROM "users" WHERE ("users"."arr" <@ '{3,4}')
26
+
27
+ class U < ActiveRecord::Migration
28
+ def self.up
29
+ create_table :users do |t|
30
+ t.integer_array :int_ar
31
+ end
32
+ add_column :users, :fl_ar, :float_array
33
+ end
34
+ end
35
+
36
+ Plugin worked with rails 2.3.x. integer_array works in ActiveRecord 3 at the moment.
37
+
38
+
39
+ Copyright (c) 2010 Sokolov Yura aka funny_falcon, released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the postgres_arrays plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the postgres_arrays plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'PostgresArrays'
19
+ rdoc.options << '--line-numbers' << '--inline-source'
20
+ rdoc.rdoc_files.include('README')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
23
+
24
+ begin
25
+ require 'jeweler'
26
+ Jeweler::Tasks.new do |gemspec|
27
+ gemspec.name = "ar_pg_array"
28
+ gemspec.summary = "Use power of PostgreSQL Arrays in ActiveRecord"
29
+ gemspec.description = "ar_pg_array includes support of PostgreSQL's int[], float[], text[], timestamptz[] etc. into ActiveRecord. You could define migrations for array columns, query on array columns."
30
+ gemspec.email = "funny.falcon@gmail.com"
31
+ gemspec.homepage = "http://github.com/funny-falcon/activerecord-postgresql-arrays"
32
+ gemspec.authors = ["Sokolov Yura aka funny_falcon"]
33
+ gemspec.add_dependency('activerecord', '>=2.3.5')
34
+ gemspec.rubyforge_project = 'ar_pg_array'
35
+ end
36
+ Jeweler::GemcutterTasks.new
37
+ Jeweler::RubyforgeTasks.new do |rubyforge|
38
+ end
39
+ rescue LoadError
40
+ puts "Jeweler not available. Install it with: gem install jeweler"
41
+ end
42
+
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Include hook code here
2
+ require 'ar_pg_array'
3
+
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,88 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ if method_defined? :attribute_condition
5
+ def attribute_condition_with_postgresql_arrays(quoted_column_name, argument)
6
+ if ::PGArrays::PgArray === argument
7
+ case argument
8
+ when ::PGArrays::PgAny then "#{quoted_column_name} && ?"
9
+ when ::PGArrays::PgAll then "#{quoted_column_name} @> ?"
10
+ when ::PGArrays::PgIncludes then "#{quoted_column_name} <@ ?"
11
+ else "#{quoted_column_name} = ?"
12
+ end
13
+ else
14
+ attribute_condition_without_postgresql_arrays(quoted_column_name, argument)
15
+ end
16
+ end
17
+ alias_method_chain :attribute_condition, :postgresql_arrays
18
+ end
19
+
20
+ def quote_bound_value_with_postgresql_arrays(value)
21
+ if ::PGArrays::PgArray === value
22
+ connection.quote_array_by_base_type(value, value.base_type)
23
+ else
24
+ quote_bound_value_without_postgresql_arrays(value)
25
+ end
26
+ end
27
+ alias_method_chain :quote_bound_value, :postgresql_arrays
28
+ end
29
+ end
30
+ end
31
+
32
+ module PGArrays
33
+ class PgArray < Array
34
+ attr_reader :base_type
35
+
36
+ def initialize(array, type=nil)
37
+ super(array)
38
+ @base_type = type if type
39
+ end
40
+
41
+ def base_type
42
+ @base_type || :other
43
+ end
44
+ end
45
+
46
+ class PgAny < PgArray; end
47
+ class PgAll < PgArray; end
48
+ class PgIncludes < PgArray; end
49
+
50
+ if defined? CanCan::Ability
51
+ class PgAny
52
+ def include?(v)
53
+ Array === v && !( v & self ).empty?
54
+ end
55
+ end
56
+
57
+ class PgAll
58
+ def include?
59
+ Array === v && (self - v).empty?
60
+ end
61
+ end
62
+
63
+ class PgIncludes < PgArray
64
+ def include?
65
+ Array === v && (v - self).empty?
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ class Array
72
+
73
+ def pg(type=nil)
74
+ ::PGArrays::PgArray.new(self, type)
75
+ end
76
+
77
+ def search_any(type=nil)
78
+ ::PGArrays::PgAny.new(self, type)
79
+ end
80
+
81
+ def search_all(type=nil)
82
+ ::PGArrays::PgAll.new(self, type)
83
+ end
84
+
85
+ def search_subarray(type=nil)
86
+ ::PGArrays::PgIncludes.new(self, type)
87
+ end
88
+ end
@@ -0,0 +1,74 @@
1
+ module Arel
2
+ module Predicates
3
+ class ArrayAny < Binary
4
+ def eval(row)
5
+ !(operand1.eval(row) & operand2.eval(row)).empty?
6
+ end
7
+
8
+ def predicate_sql
9
+ "&&"
10
+ end
11
+ end
12
+
13
+ class ArrayAll < Binary
14
+ def eval(row)
15
+ (operand2.eval(row) - operand1.eval(row)).empty?
16
+ end
17
+
18
+ def predicate_sql
19
+ "@>"
20
+ end
21
+ end
22
+
23
+ class ArrayIncluded < Binary
24
+ def eval(row)
25
+ (operand1.eval(row) - operand2.eval(row)).empty?
26
+ end
27
+
28
+ def predicate_sql
29
+ "<@"
30
+ end
31
+ end
32
+ end
33
+
34
+ class Attribute
35
+ module Predications
36
+ def ar_any(other)
37
+ Predicates::ArrayAny.new(self, other)
38
+ end
39
+
40
+ def ar_all(other)
41
+ Predicates::ArrayAll.new(self, other)
42
+ end
43
+
44
+ def ar_included(other)
45
+ Predicates::ArrayIncluded.new(self, other)
46
+ end
47
+
48
+ def in(other)
49
+ case other
50
+ when ::PGArrays::PgAny
51
+ ar_any(other)
52
+ when ::PGArrays::PgAll
53
+ ar_all(other)
54
+ when ::PGArrays::PgIncludes
55
+ ar_included(other)
56
+ else
57
+ Predicates::In.new(self, other)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ module PGArrays
65
+ class PgArray
66
+ def to_sql( formatter = nil )
67
+ formatter.engine.quote_array_for_arel_by_base_type(self, base_type)
68
+ end
69
+
70
+ def to_a
71
+ self
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,71 @@
1
+ module PGArrays
2
+ module ReferencesBy
3
+ class RelationHolder < Struct.new(:relation, :field, :klass)
4
+
5
+ def referenced(obj)
6
+ ids = obj.read_attribute(field) || []
7
+ klass.find( ids.sort ).sort_by{|o| ids.index(o.id)}
8
+ end
9
+
10
+ def set_referenced(obj, value)
11
+ value = value.map{|v|
12
+ case v
13
+ when ActiveRecord::Base then v.id
14
+ when nil then nil
15
+ else v.to_i
16
+ end
17
+ }.compact
18
+ obj.write_attribute( field, value )
19
+ end
20
+
21
+ def validate(obj)
22
+ has_ids = klass.find(:all, :select=>'id', :conditions=>{:id=>obj.read_attribute(field)}).map(&:id)
23
+ unless has_ids.sort == obj.read_attribute(field).sort
24
+ obj.errors.add(relation, :wrong_array_reference)
25
+ end
26
+ end
27
+
28
+ def for_referenced(obj_klass)
29
+ condition = lambda do |obj|
30
+ { :conditions=>{field.to_sym => case obj when klass then obj.id else obj.to_i end} }
31
+ end
32
+ obj_klass.send(:named_scope, "#{relation}_include", condition )
33
+ end
34
+
35
+ end
36
+
37
+ module ClassMethods
38
+ def references_by_array( relation, options = {} )
39
+ unless ActiveSupport::Memoizable === self
40
+ extend ActiveSupport::Memoizable
41
+ end
42
+
43
+ relation = relation.to_s.pluralize
44
+ field = "#{relation.singularize}_ids"
45
+ klass_name = (options[:class_name] || relation).to_s.singularize.camelize
46
+ klass = klass_name.constantize
47
+ holder = RelationHolder.new(relation, field, klass )
48
+
49
+ define_method(relation) do
50
+ holder.referenced(self)
51
+ end
52
+ memoize relation
53
+
54
+ define_method("#{relation}=") do |value|
55
+ flush_cache(relation)
56
+ holder.set_referenced(self, value)
57
+ end
58
+
59
+ if options[:validate]
60
+ validate {|o| holder.validate(o)}
61
+ end
62
+
63
+ holder.for_referenced(self)
64
+ end
65
+
66
+ end
67
+ end
68
+ end
69
+
70
+ ActiveRecord::Base.extend PGArrays::ReferencesBy::ClassMethods
71
+
@@ -0,0 +1,237 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class PostgreSQLColumn < Column #:nodoc:
4
+ BASE_TYPE_COLUMNS = Hash.new{|h, base_type|
5
+ base_column= new(nil, nil, base_type, true)
6
+ h[base_type] = h[base_column.type]= base_column
7
+ }
8
+ attr_reader :base_column
9
+
10
+ def initialize(name, default, sql_type = nil, null = true)
11
+ if sql_type =~ /^(.+)\[\]$/
12
+ @base_sql_type = $1
13
+ @base_column = BASE_TYPE_COLUMNS[@base_sql_type]
14
+ end
15
+ super(name, self.class.extract_value_from_default(default), sql_type, null)
16
+ end
17
+
18
+ def simplified_type_with_postgresql_arrays(field_type)
19
+ if field_type=~/^(.+)\[\]$/
20
+ :"#{simplified_type_without_postgresql_arrays($1)}_array"
21
+ else
22
+ simplified_type_without_postgresql_arrays(field_type)
23
+ end
24
+ end
25
+ alias_method_chain :simplified_type, :postgresql_arrays
26
+
27
+ def klass
28
+ if type.to_s =~ /_array$/
29
+ Array
30
+ else
31
+ super
32
+ end
33
+ end
34
+
35
+ def type_cast(value)
36
+ return nil if value.nil?
37
+ case type
38
+ when :integer_array, :float_array
39
+ self.class.string_to_num_array(value)
40
+ when :decimal_array, :date_array, :boolean_array
41
+ safe_string_to_array(value)
42
+ when :timestamp_array, :time_array, :datetime_array, :binary_array
43
+ string_to_array(value)
44
+ when :text_array, :string_array
45
+ self.class.string_to_text_array(value)
46
+ else super
47
+ end
48
+ end
49
+
50
+ def type_cast_code(var_name)
51
+ case type
52
+ when :integer_array, :float_array
53
+ "#{self.class.name}.string_to_num_array(#{var_name})"
54
+ when :decimal_array, :date_array, :boolean_array
55
+ "#{self.class.name}.safe_string_to_array(#{var_name}, #{@base_sql_type.inspect})"
56
+ when :timestamp_array, :time_array, :datetime_array, :binary_array
57
+ "#{self.class.name}.string_to_array(#{var_name}, #{@base_sql_type.inspect})"
58
+ when :text_array, :string_array
59
+ "#{self.class.name}.string_to_text_array(#{var_name})"
60
+ else super
61
+ end
62
+ end
63
+
64
+ def safe_string_to_array(string)
65
+ return string unless string.is_a? String
66
+ return nil if string.empty?
67
+
68
+ string[1...-1].split(',').map{|v| @base_column.type_cast(v)}
69
+ end
70
+
71
+ def string_to_array(string)
72
+ return string unless string.is_a? String
73
+ return nil if string.empty?
74
+
75
+ self.class.string_to_text_array(string).map{|v| @base_column.type_cast(v)}
76
+ end
77
+
78
+ def self.safe_string_to_array(string, sql_type)
79
+ return string unless string.is_a? String
80
+ return nil if string.empty?
81
+
82
+ base_column = BASE_TYPE_COLUMNS[sql_type]
83
+ string[1...-1].split(',').map{|v| base_column.type_cast(v)}
84
+ end
85
+
86
+ def self.string_to_array(string, sql_type)
87
+ return string unless string.is_a? String
88
+ return nil if string.empty?
89
+
90
+ base_column = BASE_TYPE_COLUMNS[sql_type]
91
+ string_to_text_array( string ).map{|v| base_column.type_cast(v)}
92
+ end
93
+
94
+ def self.string_to_num_array(string)
95
+ return string unless string.is_a? String
96
+ return nil if string.empty?
97
+
98
+ eval(string.tr('{}','[]'))
99
+ end
100
+
101
+ SARRAY_QUOTED = /^"(.*[^\\])?"$/m
102
+ SARRAY_PARTIAL = /^".*(\\"|[^"])$/m
103
+ def self.string_to_text_array(value)
104
+ return value unless value.is_a? String
105
+ return nil if value.empty?
106
+
107
+ values = value[1...-1].split(',')
108
+ partial = false
109
+ values.inject([]) do |res, s|
110
+ if partial
111
+ s = res.pop << ",#{s}"
112
+ elsif s=~ SARRAY_PARTIAL
113
+ partial = true
114
+ end
115
+ if s =~ SARRAY_QUOTED
116
+ s = eval(s)
117
+ partial = false
118
+ elsif s == 'NULL'
119
+ s = nil
120
+ end
121
+ res << s
122
+ end
123
+ end
124
+ end
125
+
126
+ class PostgreSQLAdapter #:nodoc:
127
+ def quote_with_postgresql_arrays(value, column = nil)
128
+ if Array === value && column && "#{column.type}" =~ /^(.+)_array$/
129
+ quote_array_by_base_type(value, $1, column)
130
+ else
131
+ quote_without_postgresql_arrays(value, column)
132
+ end
133
+ end
134
+ alias_method_chain :quote, :postgresql_arrays
135
+
136
+ def quote_array_by_base_type(value, base_type, column = nil)
137
+ case base_type.to_sym
138
+ when :integer, :float, :decimal, :boolean, :date, :safe,
139
+ :string, :text, :other, :datetime, :timestamp, :time
140
+ quote_array_for_arel_by_base_type( value, base_type )
141
+ else
142
+ "E'#{ prepare_pg_string_array(value, base_type, column) }'"
143
+ end
144
+ end
145
+
146
+ def quote_array_for_arel_by_base_type( value, base_type )
147
+ case base_type.to_sym
148
+ when :integer, :float, :decimal, :boolean, :date, :safe, :datetime, :timestamp, :time
149
+ "'#{ prepare_array_for_arel_by_base_type(value, base_type) }'"
150
+ when :string, :text, :other
151
+ pa = prepare_array_for_arel_by_base_type(value, base_type)
152
+ "E'#{ quote_string( pa ) }'"
153
+ else
154
+ raise "Unsupported array base type #{base_type} for arel"
155
+ end
156
+ end
157
+
158
+ def prepare_array_for_arel_by_base_type(value, base_type)
159
+ case base_type.to_sym
160
+ when :integer
161
+ prepare_pg_integer_array(value)
162
+ when :float
163
+ prepare_pg_float_array(value)
164
+ when :string, :text, :other
165
+ prepare_pg_text_array(value)
166
+ when :datetime, :timestamp, :time
167
+ prepare_pg_string_array(value, base_type)
168
+ when :decimal, :boolean, :date, :safe
169
+ prepare_pg_string_safe_array(value)
170
+ else
171
+ raise "Unsupported array base type #{base_type} for arel"
172
+ end
173
+ end
174
+
175
+ def prepare_pg_integer_array(value)
176
+ "{#{ value.map{|v| v.nil? ? 'NULL' : v.to_i}.join(',')}}"
177
+ end
178
+
179
+ def prepare_pg_float_array(value)
180
+ "{#{ value.map{|v| v.nil? ? 'NULL' : v.to_f}.join(',')}}"
181
+ end
182
+
183
+ def prepare_pg_string_safe_array(value)
184
+ "{#{ value.map{|v| v.nil? ? 'NULL' : v.to_s}.join(',')}}"
185
+ end
186
+
187
+ def prepare_pg_string_array(value, base_type, column=nil)
188
+ base_column= if column
189
+ column.base_column
190
+ else
191
+ PostgreSQLColumn::BASE_TYPE_COLUMNS[base_type.to_sym]
192
+ end
193
+ value = value.map do|v|
194
+ v = quote_without_postgresql_arrays(v, base_column)
195
+ if v=~/^E?'(.+)'$/ then v = $1 end
196
+ "\"#{v.gsub('"','\"')}\""
197
+ end
198
+ "{#{ value.join(',')}}"
199
+ end
200
+
201
+ def prepare_pg_text_array(value)
202
+ value = value.map{|v|
203
+ v ? v.to_s.gsub('\\','\\\\\\').gsub('"','\"') : 'NULL'
204
+ }.inspect
205
+ value.tr!('[]','{}')
206
+ end
207
+
208
+
209
+ NATIVE_DATABASE_TYPES.keys.each do |key|
210
+ unless key==:primary_key
211
+ base = NATIVE_DATABASE_TYPES[key].dup
212
+ base[:name] = base[:name]+'[]'
213
+ NATIVE_DATABASE_TYPES[:"#{key}_array"]= base
214
+ TableDefinition.class_eval <<-EOV
215
+ def #{key}_array(*args) # def string_array(*args)
216
+ options = args.extract_options! # options = args.extract_options!
217
+ column_names = args # column_names = args
218
+ #
219
+ column_names.each { |name| column(name, '#{key}_array', options) }# column_names.each { |name| column(name, 'string_array', options) }
220
+ end # end
221
+ EOV
222
+ end
223
+ end
224
+
225
+ def type_to_sql_with_postgresql_arrays(type, limit = nil, precision = nil, scale = nil)
226
+ if type.to_s =~ /^(.+)_array$/
227
+ type_to_sql_without_postgresql_arrays($1, limit, precision, scale)+'[]'
228
+ else
229
+ type_to_sql_without_postgresql_arrays(type, limit, precision, scale)
230
+ end
231
+ end
232
+
233
+ alias_method_chain :type_to_sql, :postgresql_arrays
234
+ end
235
+ end
236
+ end
237
+
@@ -0,0 +1,90 @@
1
+ module ActiveRecord
2
+ module ConnectionAdapters
3
+ class PostgreSQLAdapter
4
+ def prepare_for_arel( value, column )
5
+ return value unless value
6
+ if Array === value && "#{column.type}" =~ /^(.+)_array$/
7
+ prepare_array_for_arel_by_base_type(value, $1)
8
+ else
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ module ActiveRecord
17
+ # I hope ticket 5047 will be included in Rails 3 reliz
18
+ unless ConnectionAdapters::AbstractAdapter.method_defined? :prepare_for_arel
19
+ module ConnectionAdapters
20
+ class AbstractAdapter
21
+ def prepare_for_arel( value, column )
22
+ if value && ((value.acts_like?(:date) || value.acts_like?(:time)) || value.is_a?(Hash) || value.is_a?(Array))
23
+ value.to_yaml
24
+ else
25
+ value
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ class Base
32
+ private
33
+ # Returns a copy of the attributes hash where all the values have been safely quoted for use in
34
+ # an Arel insert/update method.
35
+ def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
36
+ attrs = {}
37
+ attribute_names.each do |name|
38
+ if (column = column_for_attribute(name)) && (include_primary_key || !column.primary)
39
+
40
+ if include_readonly_attributes || (!include_readonly_attributes && !self.class.readonly_attributes.include?(name))
41
+ value = read_attribute(name)
42
+
43
+ if value && self.class.serialized_attributes.has_key?(name)
44
+ value = value.to_yaml
45
+ else
46
+ value = self.class.connection.prepare_for_arel(value, column)
47
+ end
48
+ attrs[self.class.arel_table[name]] = value
49
+ end
50
+ end
51
+ end
52
+ attrs
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ module Arel
59
+ module Attributes
60
+ %w{Integer Float Decimal Boolean String Time}.each do |basetype|
61
+ module_eval <<-"END"
62
+ class #{basetype}Array < Attribute
63
+ end
64
+ END
65
+ end
66
+ end
67
+
68
+ module Sql
69
+ module Attributes
70
+ class << self
71
+ def for_with_postgresql_arrays(column)
72
+ if column.type.to_s =~ /^(.+)_array$/
73
+ ('Arel::Sql::Attributes::' + for_without_postgresql_arrays(column.base_column).name.split('::').last + 'Array').constantize
74
+ else
75
+ for_without_postgresql_arrays(column)
76
+ end
77
+ end
78
+ alias_method_chain :for, :postgresql_arrays
79
+ end
80
+
81
+ %w{Integer Float Decimal Boolean String Time}.each do |basetype|
82
+ module_eval <<-"END"
83
+ class #{basetype}Array < Arel::Attributes::#{basetype}Array
84
+ include Attributes
85
+ end
86
+ END
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,11 @@
1
+ require 'active_record'
2
+ require 'active_record/base'
3
+ require 'active_record/connection_adapters/postgresql_adapter'
4
+
5
+ require 'ar_pg_array/schema'
6
+ require 'ar_pg_array/querying'
7
+ require 'ar_pg_array/references_by'
8
+ if defined? ::Arel
9
+ require 'ar_pg_array/schema_arel'
10
+ require 'ar_pg_array/querying_arel'
11
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ar_pg_array
3
+ version: !ruby/object:Gem::Version
4
+ hash: 63
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 8
9
+ - 0
10
+ version: 0.8.0
11
+ platform: ruby
12
+ authors:
13
+ - Sokolov Yura aka funny_falcon
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-06 00:00:00 +04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activerecord
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 9
30
+ segments:
31
+ - 2
32
+ - 3
33
+ - 5
34
+ version: 2.3.5
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: ar_pg_array includes support of PostgreSQL's int[], float[], text[], timestamptz[] etc. into ActiveRecord. You could define migrations for array columns, query on array columns.
38
+ email: funny.falcon@gmail.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - README
45
+ files:
46
+ - MIT-LICENSE
47
+ - README
48
+ - Rakefile
49
+ - init.rb
50
+ - install.rb
51
+ - lib/ar_pg_array.rb
52
+ - lib/ar_pg_array/querying.rb
53
+ - lib/ar_pg_array/querying_arel.rb
54
+ - lib/ar_pg_array/references_by.rb
55
+ - lib/ar_pg_array/schema.rb
56
+ - lib/ar_pg_array/schema_arel.rb
57
+ - uninstall.rb
58
+ has_rdoc: true
59
+ homepage: http://github.com/funny-falcon/activerecord-postgresql-arrays
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --charset=UTF-8
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project: ar_pg_array
88
+ rubygems_version: 1.3.7
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Use power of PostgreSQL Arrays in ActiveRecord
92
+ test_files: []
93
+