activerecord-postgres-composite-types 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b627568edb4af7a5cf7f1fd39a177bf6d63dbe5b
4
+ data.tar.gz: d8207155ee161a0bd76cc55568fe49454c91e18b
5
+ SHA512:
6
+ metadata.gz: ec183d3ddc32a9362c6239dccfa4a33413f52c1936808387ebf42ea8d4f018ec65d084c2571ab5c41341853c8441c3235aa633b6ff7db574572f81f46c745f20
7
+ data.tar.gz: 56b778cecddabaf1ade15c3389b849c36fa8241e0831fa02c01876c82c5dafefe675fa2497ef66266eaf0017d04e1452bd831b0ebff53113e05228f233f7cad7
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ addons:
5
+ postgresql: "9.3"
6
+ before_script:
7
+ - cp test/internal/config/database.yml.travis test/internal/config/database.yml
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'http://rubygems.org'
2
+
3
+ AR_VERSION = '3.2.0'
4
+
5
+ gem 'activerecord', ">= #{AR_VERSION}"
6
+ gem 'pg', '>= 0.17.0'
7
+
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'
18
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 PuzzleFlow
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 Rafał Bigaj
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.rdoc ADDED
@@ -0,0 +1,67 @@
1
+ {<img src="https://codeclimate.com/github/PuzzleFlow/activerecord-postgres-composite-types/badges/gpa.svg" />}[https://codeclimate.com/github/PuzzleFlow/activerecord-postgres-composite-types]
2
+ {<img src="https://travis-ci.org/PuzzleFlow/activerecord-postgres-composite-types.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/PuzzleFlow/activerecord-postgres-composite-types]
3
+ {<img src="http://inch-ci.org/github/PuzzleFlow/activerecord-postgres-composite-types.png?branch=master" alt="Inline docs" />}[http://inch-ci.org/github/PuzzleFlow/activerecord-postgres-composite-types]
4
+ {<img src="https://badge.fury.io/rb/activerecord-postgres-composite-types.svg" alt="Gem Version" />}[http://badge.fury.io/rb/activerecord-postgres-composite-types]
5
+
6
+ = ActiveRecord PostgreSQL Composite Types
7
+
8
+ This gem adds support to the ActiveRecord (3.x and 4.x) for composite types.
9
+
10
+ One of PostgreSQL interesting feature is composite types — it basically allows to group related columns into a single type declaration like this:
11
+
12
+ create type complex as (
13
+ number real,
14
+ title text
15
+ );
16
+
17
+ Form this moment a type 'complex' is a regular PostgreSQL type and can be used in functions, column definitions, other types definition, etc.
18
+ ActiveRecord, especially from version 4.0, has extended set of supported types like arrays, hstore, json, range, ...
19
+ But there is no support for user defined composite types.
20
+
21
+ == The Goal
22
+
23
+ For my composite type 'complex' and table like this:
24
+
25
+ create_table :foos, :id => false do |t|
26
+ t.column :comp, :complex, default: "(0,\"\")"
27
+ end
28
+
29
+ I can access my data in simple and natural way:
30
+
31
+ class Foo < ActiveRecord::Base
32
+ end
33
+
34
+ foo = Foo.create!(:comp => {:number => 1.2, :title => "Cool!"})
35
+
36
+ or
37
+
38
+ foo = Foo.create!(:comp => [1.2, "Cool!"])
39
+
40
+ and then
41
+
42
+ foo.comp.number # => 1.2
43
+ foo.comp.title # => "Cool!"
44
+
45
+ To achieve this goal I only have to define my composite type in a following way:
46
+
47
+ class ComplexType < PostgresCompositeType
48
+ register_type :complex
49
+ end
50
+
51
+ That's all folks.
52
+
53
+ == Contributing to ActiveRecord PostgreSQL Composite Types
54
+
55
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
56
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
57
+ * Fork the project.
58
+ * Start a feature/bugfix branch.
59
+ * Commit and push until you are happy with your contribution.
60
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
61
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
62
+
63
+ == Copyright
64
+
65
+ Copyright (c) 2014 Rafał Bigaj. See LICENSE.txt for
66
+ further details.
67
+
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
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
28
+ end
29
+
30
+ require 'rake/testtask'
31
+ Rake::TestTask.new(:test) do |test|
32
+ test.libs << 'lib' << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+
37
+ desc "Code coverage detail"
38
+ task :simplecov do
39
+ ENV['COVERAGE'] = "true"
40
+ Rake::Task['test'].execute
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rdoc/task'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "activerecord-postgres-custom-types #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,92 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "activerecord-postgres-composite-types"
8
+ s.version = "0.2.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Rafal Bigaj"]
12
+ s.date = "2014-09-09"
13
+ s.description = "This gem adds support to the ActiveRecord (3.x and 4.x) for composite types."
14
+ s.email = "rafal.bigaj@puzzleflow.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "LICENSE.txt",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".travis.yml",
23
+ "Gemfile",
24
+ "LICENSE",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "activerecord-postgres-composite-types.gemspec",
30
+ "activerecord-postgres-custom-types.gemspec",
31
+ "lib/activerecord-postgres-composite-types.rb",
32
+ "lib/activerecord-postgres-composite-types/active_record.rb",
33
+ "lib/activerecord-postgres-composite-types/active_record_3.rb",
34
+ "lib/activerecord-postgres-composite-types/active_record_4.rb",
35
+ "lib/activerecord-postgres-composite-types/composite_type_parser.rb",
36
+ "lib/activerecord-postgres-composite-types/postgres_composite_type.rb",
37
+ "lib/activerecord-postgres-composite-types/railties.rb",
38
+ "test/composite_types.rb",
39
+ "test/helper.rb",
40
+ "test/internal/config/database.yml",
41
+ "test/internal/config/database.yml.travis",
42
+ "test/internal/db/schema.rb",
43
+ "test/test_composite_type_class.rb",
44
+ "test/test_nested_types.rb",
45
+ "test/test_postgres_composite_types.rb"
46
+ ]
47
+ s.homepage = "http://github.com/puzzleflow/activerecord-postgres-composite-types"
48
+ s.licenses = ["MIT"]
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = "2.0.3"
51
+ s.summary = "ActiveRecord composite types support"
52
+
53
+ if s.respond_to? :specification_version then
54
+ s.specification_version = 4
55
+
56
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
+ s.add_runtime_dependency(%q<activerecord>, [">= 3.2.0"])
58
+ s.add_runtime_dependency(%q<pg>, [">= 0.17.0"])
59
+ s.add_development_dependency(%q<test-unit>, ["~> 2.1"])
60
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
61
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
62
+ s.add_development_dependency(%q<rake>, ["~> 10.3"])
63
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
64
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
65
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
66
+ s.add_development_dependency(%q<combustion>, ["~> 0.5.2"])
67
+ else
68
+ s.add_dependency(%q<activerecord>, [">= 3.2.0"])
69
+ s.add_dependency(%q<pg>, [">= 0.17.0"])
70
+ s.add_dependency(%q<test-unit>, ["~> 2.1"])
71
+ s.add_dependency(%q<shoulda>, [">= 0"])
72
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
73
+ s.add_dependency(%q<rake>, ["~> 10.3"])
74
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
75
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
76
+ s.add_dependency(%q<simplecov>, [">= 0"])
77
+ s.add_dependency(%q<combustion>, ["~> 0.5.2"])
78
+ end
79
+ else
80
+ s.add_dependency(%q<activerecord>, [">= 3.2.0"])
81
+ s.add_dependency(%q<pg>, [">= 0.17.0"])
82
+ s.add_dependency(%q<test-unit>, ["~> 2.1"])
83
+ s.add_dependency(%q<shoulda>, [">= 0"])
84
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
85
+ s.add_dependency(%q<rake>, ["~> 10.3"])
86
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
87
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
88
+ s.add_dependency(%q<simplecov>, [">= 0"])
89
+ s.add_dependency(%q<combustion>, ["~> 0.5.2"])
90
+ end
91
+ end
92
+
@@ -0,0 +1,91 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "activerecord-postgres-custom-types"
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Rafal Bigaj"]
12
+ s.date = "2014-09-09"
13
+ s.description = "This gem adds support to the ActiveRecord (3.x and 4.x) for composite types."
14
+ s.email = "rafal.bigaj@puzzleflow.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "LICENSE.txt",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".travis.yml",
23
+ "Gemfile",
24
+ "LICENSE",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "activerecord-postgres-custom-types.gemspec",
30
+ "lib/activerecord-postgres-composite-types.rb",
31
+ "lib/activerecord-postgres-composite-types/active_record.rb",
32
+ "lib/activerecord-postgres-composite-types/active_record_3.rb",
33
+ "lib/activerecord-postgres-composite-types/active_record_4.rb",
34
+ "lib/activerecord-postgres-composite-types/composite_type_parser.rb",
35
+ "lib/activerecord-postgres-composite-types/postgres_composite_type.rb",
36
+ "lib/activerecord-postgres-composite-types/railties.rb",
37
+ "test/composite_types.rb",
38
+ "test/helper.rb",
39
+ "test/internal/config/database.yml",
40
+ "test/internal/config/database.yml.travis",
41
+ "test/internal/db/schema.rb",
42
+ "test/test_composite_type_class.rb",
43
+ "test/test_nested_types.rb",
44
+ "test/test_postgres_composite_types.rb"
45
+ ]
46
+ s.homepage = "http://github.com/rafalbigaj/activerecord-postgres-custom-types"
47
+ s.licenses = ["MIT"]
48
+ s.require_paths = ["lib"]
49
+ s.rubygems_version = "2.0.3"
50
+ s.summary = "ActiveRecord composite types support"
51
+
52
+ if s.respond_to? :specification_version then
53
+ s.specification_version = 4
54
+
55
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
56
+ s.add_runtime_dependency(%q<activerecord>, [">= 3.2.0"])
57
+ s.add_runtime_dependency(%q<pg>, [">= 0.17.0"])
58
+ s.add_development_dependency(%q<test-unit>, ["~> 2.1"])
59
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
60
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
61
+ s.add_development_dependency(%q<rake>, ["~> 10.3"])
62
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
63
+ s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
64
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
65
+ s.add_development_dependency(%q<combustion>, ["~> 0.5.2"])
66
+ else
67
+ s.add_dependency(%q<activerecord>, [">= 3.2.0"])
68
+ s.add_dependency(%q<pg>, [">= 0.17.0"])
69
+ s.add_dependency(%q<test-unit>, ["~> 2.1"])
70
+ s.add_dependency(%q<shoulda>, [">= 0"])
71
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
72
+ s.add_dependency(%q<rake>, ["~> 10.3"])
73
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
74
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
75
+ s.add_dependency(%q<simplecov>, [">= 0"])
76
+ s.add_dependency(%q<combustion>, ["~> 0.5.2"])
77
+ end
78
+ else
79
+ s.add_dependency(%q<activerecord>, [">= 3.2.0"])
80
+ s.add_dependency(%q<pg>, [">= 0.17.0"])
81
+ s.add_dependency(%q<test-unit>, ["~> 2.1"])
82
+ s.add_dependency(%q<shoulda>, [">= 0"])
83
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
84
+ s.add_dependency(%q<rake>, ["~> 10.3"])
85
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
86
+ s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
87
+ s.add_dependency(%q<simplecov>, [">= 0"])
88
+ s.add_dependency(%q<combustion>, ["~> 0.5.2"])
89
+ end
90
+ end
91
+
@@ -0,0 +1,13 @@
1
+ require 'active_record'
2
+ require 'active_record/connection_adapters/postgresql_adapter'
3
+
4
+ if defined? Rails
5
+ require "activerecord-postgres-composite-types/railties"
6
+ else
7
+ ActiveSupport.on_load :active_record do
8
+ require "activerecord-postgres-composite-types/active_record"
9
+ end
10
+ end
11
+
12
+ require "activerecord-postgres-composite-types/postgres_composite_type"
13
+ require "activerecord-postgres-composite-types/composite_type_parser"
@@ -0,0 +1,166 @@
1
+ # Extends AR to add composite types functionality.
2
+ module ActiveRecord
3
+
4
+ module ConnectionAdapters
5
+
6
+ class PostgreSQLAdapter
7
+
8
+ # Quotes the column value to help prevent {SQL injection attacks}
9
+ def quote_with_composite_types(value, column = nil)
10
+ if value.class < PostgresCompositeType
11
+ "'#{PostgreSQLColumn.composite_type_to_string(value, self).gsub(/'/, "''")}'"
12
+ else
13
+ quote_without_composite_types(value, column)
14
+ end
15
+ end
16
+
17
+ alias_method_chain :quote, :composite_types
18
+
19
+ class << self
20
+ def register_composite_type_class(klass)
21
+ self.composite_type_classes[klass.type] = klass
22
+ TableDefinition.register_composite_type klass.type
23
+ Table.register_composite_type klass.type
24
+ register_arel_visitor klass
25
+ register_oid_type klass
26
+ end
27
+
28
+ def register_arel_visitor(klass)
29
+ Arel::Visitors::ToSql.class_eval <<-RUBY
30
+ def visit_#{klass}(o, a=nil)
31
+ @connection.quote(o) + '::#{klass.type}'
32
+ end
33
+ RUBY
34
+ end
35
+
36
+ def register_oid_type(klass)
37
+ # only AR 4.X
38
+ end
39
+
40
+ # removes composite types definition (for testing)
41
+ def unregister_composite_types(*composite_types)
42
+ composite_types.each { |type| unregister_composite_type type }
43
+ end
44
+
45
+ # removes composite type definition (for testing)
46
+ def unregister_composite_type(type)
47
+ self.composite_type_classes.delete(type.to_sym)
48
+ TableDefinition.unregister_composite_type type
49
+ Table.unregister_composite_type type
50
+ end
51
+
52
+ def composite_type_classes
53
+ @composite_type_classes ||= {}
54
+ end
55
+ end
56
+ end
57
+
58
+ class PostgreSQLColumn < Column
59
+ # Adds composite type for the column.
60
+
61
+ def composite_type_class
62
+ PostgreSQLAdapter.composite_type_classes[type]
63
+ end
64
+
65
+ def klass_with_composite_types
66
+ composite_type_klass = PostgreSQLAdapter.composite_type_classes[type]
67
+ composite_type_klass || klass_without_composite_types
68
+ end
69
+
70
+ alias_method_chain :klass, :composite_types
71
+
72
+ def self.string_to_composite_type(klass, string)
73
+ return string unless String === string
74
+ if string.present?
75
+ klass.new(string)
76
+ end
77
+ end
78
+
79
+ def self.string_to_composite_type(klass, string)
80
+ return string unless String === string
81
+ if string.present?
82
+ fields = CompositeTypeParser.parse_data(string).map.with_index {|val, i| type_cast_composite_type_field(klass, i, val)}
83
+ klass.new(fields)
84
+ end
85
+ end
86
+
87
+ def self.type_cast_composite_type_field(klass, i, value)
88
+ klass.initialize_column_definition
89
+
90
+ column = klass.columns[i]
91
+ raise "Invalid column index: #{i}" unless column
92
+ cv = column.type_cast(value)
93
+ if cv.is_a?(String)
94
+ # unquote
95
+ cv = cv.upcase == 'NULL' ? nil : cv.gsub(/\A"(.*)"\Z/m) { $1.gsub(/\\(.)/, '\1') }
96
+ end
97
+ cv
98
+ end
99
+
100
+ private
101
+
102
+ def simplified_type_with_composite_types(field_type)
103
+ type = field_type.to_sym
104
+ if PostgreSQLAdapter.composite_type_classes.has_key?(type)
105
+ type
106
+ else
107
+ simplified_type_without_composite_types(field_type)
108
+ end
109
+ end
110
+
111
+ alias_method_chain :simplified_type, :composite_types
112
+ end
113
+
114
+ class << TableDefinition
115
+ # Adds composite type for migrations. So you can add columns to a table like:
116
+ # create_table :people do |t|
117
+ # ...
118
+ # t.composite_type :composite_value
119
+ # ...
120
+ # end
121
+ def register_composite_type(composite_type)
122
+ class_eval <<-RUBY
123
+ def #{composite_type}(*args)
124
+ options = args.extract_options!
125
+ column_names = args
126
+ column_names.each { |name| column(name, '#{composite_type}', options) }
127
+ end
128
+ RUBY
129
+ end
130
+
131
+ # Removes composite types from migrations (for testing)
132
+ def unregister_composite_type(composite_type)
133
+ remove_method composite_type
134
+ end
135
+ end
136
+
137
+ class << Table
138
+
139
+ # Adds composite type for migrations. So you can add columns to a table like:
140
+ # change_table :people do |t|
141
+ # ...
142
+ # t.composite_type :composite_value
143
+ # ...
144
+ # end
145
+ def register_composite_type(composite_type)
146
+ class_eval <<-RUBY
147
+ def #{composite_type}(*args)
148
+ options = args.extract_options!
149
+ column_names = args
150
+ column_names.each { |name| column(name, '#{composite_type}', options) }
151
+ end
152
+ RUBY
153
+ end
154
+
155
+ # Removes composite types from migrations (for testing)
156
+ def unregister_composite_type(composite_type)
157
+ remove_method composite_type
158
+ end
159
+
160
+ end
161
+
162
+ end
163
+
164
+ end
165
+
166
+ require_relative "active_record_#{ActiveRecord::VERSION::MAJOR}"