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
|
+
|