activerecord-postgres-array 0.0.1

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.
@@ -0,0 +1,15 @@
1
+ require 'rails'
2
+ require 'rails/generators'
3
+ require 'rails/generators/migration'
4
+
5
+ class ActiveRecordPostgresArray < Rails::Railtie
6
+
7
+ initializer 'activerecord-postgres-array' do
8
+ ActiveSupport.on_load :active_record do
9
+ require "activerecord-postgres-array/activerecord"
10
+ end
11
+ end
12
+ end
13
+
14
+ require "activerecord-postgres-array/string"
15
+ require "activerecord-postgres-array/array"
@@ -0,0 +1,70 @@
1
+ module ActiveRecord
2
+ class ArrayTypeMismatch < ActiveRecord::ActiveRecordError
3
+ end
4
+
5
+ module ConnectionAdapters
6
+ class PostgreSQLAdapter < AbstractAdapter
7
+ POSTGRES_ARRAY_TYPES = %w( string text integer float decimal datetime timestamp time date binary boolean )
8
+
9
+ def native_database_types_with_array(*args)
10
+ native_database_types_without_array.merge(POSTGRES_ARRAY_TYPES.inject(Hash.new) {|h, t| h.update("#{t}_array".to_sym => {:name => "#{t}_array"})})
11
+ end
12
+ alias_method_chain :native_database_types, :array
13
+
14
+
15
+ # Quotes a value for use in an SQL statement
16
+ def quote_with_array(value, column = nil)
17
+ if value && column && column.sql_type =~ /\[\]$/
18
+ raise ArrayTypeMismatch, "#{column.name} must have a Hash or a valid array value (#{value})" unless value.kind_of?(Array) || value.valid_postgres_array?
19
+ return value.to_postgres_array
20
+ end
21
+ quote_without_array(value,column)
22
+ end
23
+ alias_method_chain :quote, :array
24
+ end
25
+
26
+ class TableDefinition
27
+ # Adds array type for migrations. So you can add columns to a table like:
28
+ # create_table :people do |t|
29
+ # ...
30
+ # t.string_array :real_energy
31
+ # t.decimal_array :real_energy, :precision => 18, :scale => 6
32
+ # ...
33
+ # end
34
+ PostgreSQLAdapter::POSTGRES_ARRAY_TYPES.each do |column_type|
35
+ define_method("#{column_type}_array") do |*args|
36
+ options = args.extract_options!
37
+ base_type = @base.type_to_sql(column_type.to_sym, options[:limit], options[:precision], options[:scale])
38
+ column_names = args
39
+ column_names.each { |name| column(name, "#{base_type}[]", options) }
40
+ end
41
+ end
42
+ end
43
+
44
+ class PostgreSQLColumn < Column
45
+ # Does the type casting from array columns using String#from_postgres_array or Array#from_postgres_array.
46
+ def type_cast_code_with_array(var_name)
47
+ if type =~ /_array$/
48
+ base_type = type.gsub(/_array/, '')
49
+ "#{var_name}.from_postgres_array(:#{base_type})"
50
+ else
51
+ type_cast_code_without_array(var_name)
52
+ end
53
+ end
54
+ alias_method_chain :type_cast_code, :array
55
+
56
+
57
+ # Adds the array type for the column.
58
+ def simplified_type_with_array(field_type)
59
+ if field_type =~ /^numeric.+\[\]$/
60
+ :decimal_array
61
+ elsif field_type =~ /\[\]$/
62
+ field_type.gsub(/\[\]/, '_array')
63
+ else
64
+ simplified_type_without_array(field_type)
65
+ end
66
+ end
67
+ alias_method_chain :simplified_type, :array
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,20 @@
1
+ class Array
2
+
3
+ # Generates a single quoted postgres array string format. This is the format used
4
+ # to insert or update stuff in the database.
5
+ def to_postgres_array(omit_quotes = false)
6
+ result = "#{omit_quotes ? '' : "'" }{"
7
+
8
+ result << collect do |value|
9
+ value.is_a?(Array) ? value.to_postgres_array(true) : value
10
+ end.join(", ")
11
+
12
+ result << "}#{omit_quotes ? '' : "'" }"
13
+ end
14
+
15
+ # If the method from_postgres_array is called in an Array, it just returns self.
16
+ def from_postgres_array(base_type = :string)
17
+ self
18
+ end
19
+
20
+ end
@@ -0,0 +1,30 @@
1
+ class String
2
+
3
+ def to_postgres_array
4
+ self
5
+ end
6
+
7
+ # Validates the array format. Valid formats are:
8
+ # * An empty string
9
+ # * A string like '{10000, 10000, 10000, 10000}'
10
+ # * TODO A multi dimensional array string like '{{"meeting", "lunch"}, {"training", "presentation"}}'
11
+ def valid_postgres_array?
12
+ # TODO validate formats above
13
+ true
14
+ end
15
+
16
+ # Creates an array from a postgres array string that postgresql spits out.
17
+ def from_postgres_array(base_type = :string)
18
+ if empty?
19
+ return []
20
+ else
21
+ elements = match(/^\{(.+)\}$/).captures.first.split(",").collect(&:strip)
22
+
23
+ if base_type == :decimal
24
+ return elements.collect(&:to_d)
25
+ else
26
+ return elements
27
+ end
28
+ end
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-postgres-array
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Tim Connor
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-14 00:00:00 +12:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Adds support for postgres arrays to ActiveRecord
23
+ email: tim@youdo.co.nz
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/activerecord-postgres-array.rb
32
+ - lib/activerecord-postgres-array/activerecord.rb
33
+ - lib/activerecord-postgres-array/array.rb
34
+ - lib/activerecord-postgres-array/string.rb
35
+ has_rdoc: true
36
+ homepage:
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ hash: 3
50
+ segments:
51
+ - 0
52
+ version: "0"
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.6.2
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Adds support for postgres arrays to ActiveRecord
69
+ test_files: []
70
+