ar_pg_array 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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
+