Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 10 commits
  • 15 files changed
  • 0 commit comments
  • 1 contributor
View
9 Gemfile
@@ -0,0 +1,9 @@
+source "http://rubygems.org"
+
+gem "activerecord", ">= 2.3.5", "< 3.0"
+group :development, :test do
+ gem "fake_arel"
+ gem "cancan"
+ gem "pg"
+ gem "rspec"
+end
View
39 Rakefile
@@ -1,15 +1,15 @@
require 'rake'
-require 'rake/testtask'
-require 'rake/rdoctask'
-
-desc 'Default: run unit tests.'
-task :default => :test
+require 'rdoc/task'
desc 'Test the postgres_arrays plugin.'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
+task :test do
+ Dir.chdir(File.dirname(__FILE__)) do
+ Process.wait2 spawn('rspec spec')
+ end
+end
+
+task :default do
+ # nothing
end
desc 'Generate documentation for the postgres_arrays plugin.'
@@ -20,24 +20,3 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end
-
-begin
- require 'jeweler'
- Jeweler::Tasks.new do |gemspec|
- gemspec.name = "ar_pg_array"
- gemspec.summary = "Use power of PostgreSQL Arrays in ActiveRecord"
- 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."
- gemspec.email = "funny.falcon@gmail.com"
- gemspec.homepage = "http://github.com/funny-falcon/activerecord-postgresql-arrays"
- gemspec.authors = ["Sokolov Yura aka funny_falcon"]
- gemspec.add_dependency('activerecord', '>= 2.3.5', '<4.0')
- gemspec.rubyforge_project = 'ar-pg-array'
- end
- Jeweler::GemcutterTasks.new
- Jeweler::RubyforgeTasks.new do |rubyforge|
-
- end
-rescue LoadError
- puts "Jeweler not available. Install it with: gem install jeweler"
-end
-
View
2  VERSION
@@ -1 +1 @@
-0.9.14
+0.10.2
View
7 lib/ar_pg_array.rb
@@ -7,9 +7,4 @@
require 'ar_pg_array/querying'
require 'ar_pg_array/allways_save'
require 'ar_pg_array/references_by'
-if ActiveRecord::VERSION::MAJOR >= 3
- require 'ar_pg_array/schema_arel'
- require 'ar_pg_array/querying_arel'
-else
- require 'ar_pg_array/schema_fix_will_change'
-end
+require 'ar_pg_array/schema_fix_will_change'
View
40 lib/ar_pg_array/allways_save.rb
@@ -1,37 +1,21 @@
module ActiveRecord
- module CheckArrayBeforeUpdate
- def mark_arrays_for_update
- @attributes_cache.each do |name, value|
- attribute_will_change!(name) if Array === value && _read_attribute(name) != value
- end
+ module CheckArrayBeforeUpdate
+ def mark_arrays_for_update
+ @attributes_cache.each do |name, value|
+ attribute_will_change!(name) if Array === value && _read_attribute(name) != value
end
end
- if VERSION::MAJOR < 3
- module CheckArrayBeforeUpdate
- def self.included(base)
- base.alias_method_chain :update, :check_array
- base.send(:alias_method, :_read_attribute, :read_attribute)
- end
+ end
- def update_with_check_array
- mark_arrays_for_update
- update_without_check_array
- end
+ module CheckArrayBeforeUpdate
+ def self.included(base)
+ base.alias_method_chain :update, :check_array
+ base.send(:alias_method, :_read_attribute, :read_attribute)
end
- else
- module CheckArrayBeforeUpdate
- include ActiveSupport::Concern
- if VERSION::MAJOR == 3 && VERSION::MINOR >= 2
- def _read_attribute(attr_name)
- column_for_attribute(attr_name).type_cast(@attributes[attr_name])
- end
- end
-
- def update(*)
- mark_arrays_for_update
- super
- end
+ def update_with_check_array
+ mark_arrays_for_update
+ update_without_check_array
end
end
Base.__send__ :include, CheckArrayBeforeUpdate
View
78 lib/ar_pg_array/parser.rb
@@ -5,6 +5,7 @@ module PgArrayParser
SQUARE_BRACKETS = '[]'.freeze
NULL = 'NULL'.freeze
NIL = 'nil'.freeze
+ ESCAPE_HASH={'\\'.freeze=>'\\\\'.freeze, '"'.freeze=>'\\"'.freeze}
def parse_numeric_pgarray(text)
text = text.tr(CURLY_BRACKETS, SQUARE_BRACKETS)
@@ -68,7 +69,7 @@ def _parse_pgarray(text, &block)
values << ar
if rest =~ /^\}\s*/
return values, $'
- elsif rest =~ /^,\s*{\s*/
+ elsif rest =~ /^,\s*\{\s*/
rest = $'
else
raise "Mailformed postgres array"
@@ -95,4 +96,79 @@ def _parse_pgarray(text, &block)
end
end
end
+
+ def _remap_array(array, &block)
+ array.map{|v|
+ case v
+ when Array
+ _remap_array(v, &block)
+ when nil
+ nil
+ else
+ yield v
+ end
+ }
+ end
+
+ def prepare_pg_integer_array(value)
+ val = _remap_array(value){|v| v.to_i}.inspect
+ val.gsub!(NIL, NULL)
+ val.tr!(SQUARE_BRACKETS, CURLY_BRACKETS)
+ val
+ end
+
+ def prepare_pg_float_array(value)
+ val = _remap_array(value){|v| v.to_f}.inspect
+ val.gsub!(NIL, NULL)
+ val.tr!(SQUARE_BRACKETS, CURLY_BRACKETS)
+ val
+ end
+
+ def prepare_pg_safe_array(value)
+ value = value.map{|val|
+ case val
+ when Array
+ prepare_pg_safe_array(val)
+ when nil
+ NULL
+ else
+ val.to_s
+ end
+ }.join(',')
+ "{#{value}}"
+ end
+
+ def prepare_pg_text_array(value)
+ value = value.map{|val|
+ case val
+ when Array
+ prepare_pg_text_array(val)
+ when nil
+ NULL
+ else
+ "\"#{val.to_s.gsub(/\\|"/){|s| ESCAPE_HASH[s]}}\""
+ end
+ }.join(',')
+ "{#{value}}"
+ end
+
+ def _prepare_pg_string_array(value, &block)
+ value = value.map{|val|
+ case val
+ when Array
+ _prepare_pg_string_array(val, &block)
+ when nil
+ NULL
+ else
+ val = yield val
+ if val =~ /^'(.*)'$/m
+ "\"#{ $1.gsub(/\\|"/){|s| ESCAPE_HASH[s]} }\""
+ else
+ val
+ end
+ end
+ }.join(',')
+ "{#{value}}"
+ end
+ alias prepare_pg_string_array _prepare_pg_string_array
end
View
42 lib/ar_pg_array/querying.rb
@@ -1,37 +1,25 @@
module ActiveRecord
class Base
class << self
- if private_method_defined? :attribute_condition
- def attribute_condition_with_postgresql_arrays(quoted_column_name, argument)
- if ::PGArrays::PgArray === argument
- case argument
- when ::PGArrays::PgAny then "#{quoted_column_name} && ?"
- when ::PGArrays::PgAll then "#{quoted_column_name} @> ?"
- when ::PGArrays::PgIncludes then "#{quoted_column_name} <@ ?"
- else "#{quoted_column_name} = ?"
- end
- else
- attribute_condition_without_postgresql_arrays(quoted_column_name, argument)
+ def attribute_condition_with_postgresql_arrays(quoted_column_name, argument)
+ if ::PGArrays::PgArray === argument
+ case argument
+ when ::PGArrays::PgAny then "#{quoted_column_name} && ?"
+ when ::PGArrays::PgAll then "#{quoted_column_name} @> ?"
+ when ::PGArrays::PgIncludes then "#{quoted_column_name} <@ ?"
+ else "#{quoted_column_name} = ?"
end
+ else
+ attribute_condition_without_postgresql_arrays(quoted_column_name, argument)
end
- alias_method_chain :attribute_condition, :postgresql_arrays
end
+ alias_method_chain :attribute_condition, :postgresql_arrays
- if instance_method(:quote_bound_value).arity == 1
- def quote_bound_value_with_postgresql_arrays(value)
- if ::PGArrays::PgArray === value
- connection.quote_array_by_base_type(value, value.base_type)
- else
- quote_bound_value_without_postgresql_arrays(value)
- end
- end
- else
- def quote_bound_value_with_postgresql_arrays(value, c = connection)
- if ::PGArrays::PgArray === value
- c.quote_array_by_base_type(value, value.base_type)
- else
- quote_bound_value_without_postgresql_arrays(value, c)
- end
+ def quote_bound_value_with_postgresql_arrays(value)
+ if ::PGArrays::PgArray === value
+ connection.quote_array_by_base_type(value, value.base_type)
+ else
+ quote_bound_value_without_postgresql_arrays(value)
end
end
alias_method_chain :quote_bound_value, :postgresql_arrays
View
234 lib/ar_pg_array/querying_arel.rb
@@ -1,234 +0,0 @@
-if Arel::VERSION >= '2.0'
- module Arel
- module Nodes
- class ArrayAny < Arel::Nodes::Binary
- end
-
- class ArrayAll < Arel::Nodes::Binary
- end
-
- class ArrayIncluded < Arel::Nodes::Binary
- end
- end
-
- module Predications
- def ar_any other
- Nodes::ArrayAny.new self, other
- end
-
- def ar_all other
- Nodes::ArrayAll.new self, other
- end
-
- def ar_included other
- Nodes::ArrayIncluded.new self, other
- end
- end
-
- module Visitors
- class PostgreSQL
- def visit_Arel_Nodes_ArrayAny o
- "#{visit o.left} && #{visit o.right}"
- end
-
- def visit_Arel_Nodes_ArrayAll o
- "#{visit o.left} @> #{visit o.right}"
- end
-
- def visit_Arel_Nodes_ArrayIncluded o
- "#{visit o.left} <@ #{visit o.right}"
- end
-
- def visit_PGArrays_PgArray o
- @connection.quote_array_for_arel_by_base_type(o, o.base_type)
- end
-
- alias :visit_PGArrays_PgAny :visit_PGArrays_PgArray
- alias :visit_PGArrays_PgAll :visit_PGArrays_PgArray
- alias :visit_PGArrays_PgIncluded :visit_PGArrays_PgArray
- end
- end
- end
-else
- module Arel
- module Predicates
- class ArrayAny < Binary
- def eval(row)
- !(operand1.eval(row) & operand2.eval(row)).empty?
- end
-
- def predicate_sql
- "&&"
- end
- end
-
- class ArrayAll < Binary
- def eval(row)
- (operand2.eval(row) - operand1.eval(row)).empty?
- end
-
- def predicate_sql
- "@>"
- end
- end
-
- class ArrayIncluded < Binary
- def eval(row)
- (operand1.eval(row) - operand2.eval(row)).empty?
- end
-
- def predicate_sql
- "<@"
- end
- end
- end
-
- class Attribute
- methods = lambda do
- def ar_any(other)
- Predicates::ArrayAny.new(self, other)
- end
-
- def ar_all(other)
- Predicates::ArrayAll.new(self, other)
- end
-
- def ar_included(other)
- Predicates::ArrayIncluded.new(self, other)
- end
- end
- if defined? PREDICATES
- PREDICATES.concat [:ar_any, :ar_all, :ar_included]
- class_exec &methods
- else
- Predications.class_exec &methods
- end
- end
- end
-
- module PGArrays
- class PgArray
- def to_sql( formatter = nil )
- formatter.engine.connection.quote_array_for_arel_by_base_type(self, base_type)
- end
-
- def to_a
- self
- end
- end
- end
-end
-
-if ActiveRecord::VERSION::STRING < '3.1'
- module ActiveRecord
- class PredicateBuilder
- def build_from_hash(attributes, default_table)
- predicates = attributes.map do |column, value|
- table = default_table
-
- if value.is_a?(Hash)
- table = Arel::Table.new(column, :engine => @engine)
- build_from_hash(value, table)
- else
- column = column.to_s
-
- if column.include?('.')
- table_name, column = column.split('.', 2)
- table = Arel::Table.new(table_name, :engine => @engine)
- end
-
- attribute = table[column] || Arel::Attribute.new(table, column)
-
- case value
- when PGArrays::PgAny
- attribute.ar_any(value)
- when PGArrays::PgAll
- attribute.ar_all(value)
- when PGArrays::PgIncludes
- attribute.ar_included(value)
- when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Relation
- values = value.to_a.map { |x|
- x.is_a?(ActiveRecord::Base) ? x.id : x
- }
- attribute.in(values)
- when Range, Arel::Relation
- attribute.in(value)
- when ActiveRecord::Base
- attribute.eq(value.id)
- when Class
- # FIXME: I think we need to deprecate this behavior
- attribute.eq(value.name)
- else
- attribute.eq(value)
- end
- end
- end
-
- predicates.flatten
- end
- end
- end
-else
- module ActiveRecord
- class PredicateBuilder
- def self.build_from_hash(engine, attributes, default_table)
- predicates = attributes.map do |column, value|
- table = default_table
-
- if value.is_a?(Hash)
- table = Arel::Table.new(column, engine)
- build_from_hash(engine, value, table)
- else
- column = column.to_s
-
- if column.include?('.')
- table_name, column = column.split('.', 2)
- table = Arel::Table.new(table_name, engine)
- end
-
- attribute = table[column.to_sym]
-
- case value
- when PGArrays::PgAny
- attribute.ar_any(value)
- when PGArrays::PgAll
- attribute.ar_all(value)
- when PGArrays::PgIncludes
- attribute.ar_included(value)
- when ActiveRecord::Relation
- value = value.select(value.klass.arel_table[value.klass.primary_key]) if value.select_values.empty?
- attribute.in(value.arel.ast)
- when Array, ActiveRecord::Associations::CollectionProxy
- values = value.to_a.map { |x|
- x.is_a?(ActiveRecord::Base) ? x.id : x
- }
-
- if values.include?(nil)
- values = values.compact
- if values.empty?
- attribute.eq nil
- else
- attribute.in(values.compact).or attribute.eq(nil)
- end
- else
- attribute.in(values)
- end
-
- when Range, Arel::Relation
- attribute.in(value)
- when ActiveRecord::Base
- attribute.eq(value.id)
- when Class
- # FIXME: I think we need to deprecate this behavior
- attribute.eq(value.name)
- else
- attribute.eq(value)
- end
- end
- end
-
- predicates.flatten
- end
- end
- end
-end
View
61 lib/ar_pg_array/schema.rb
@@ -136,6 +136,7 @@ def self.string_to_text_array(string)
end
class PostgreSQLAdapter #:nodoc:
+ include PgArrayParser
def quote_with_postgresql_arrays(value, column = nil)
if Array === value && column && "#{column.type}" =~ /^(.+)_array$/
quote_array_by_base_type(value, $1, column)
@@ -147,26 +148,16 @@ def quote_with_postgresql_arrays(value, column = nil)
def quote_array_by_base_type(value, base_type, column = nil)
case base_type.to_sym
- when :integer, :float, :decimal, :boolean, :date, :safe,
- :string, :text, :other, :datetime, :timestamp, :time
- quote_array_for_arel_by_base_type( value, base_type )
+ when :integer, :float, :decimal, :boolean, :date, :safe, :datetime, :timestamp, :time
+ "'#{ prepare_array_for_arel_by_base_type(value, base_type) }'"
+ when :string, :text, :other
+ pa = prepare_array_for_arel_by_base_type(value, base_type)
+ "'#{ quote_string( pa ) }'"
else
"'#{ prepare_pg_string_array(value, base_type, column) }'"
end
end
- def quote_array_for_arel_by_base_type( value, base_type )
- case base_type.to_sym
- when :integer, :float, :decimal, :boolean, :date, :safe, :datetime, :timestamp, :time
- "'#{ prepare_array_for_arel_by_base_type(value, base_type) }'"
- when :string, :text, :other
- pa = prepare_array_for_arel_by_base_type(value, base_type)
- "'#{ quote_string( pa ) }'"
- else
- raise "Unsupported array base type #{base_type} for arel"
- end
- end
-
def prepare_array_for_arel_by_base_type(value, base_type)
case base_type.to_sym
when :integer
@@ -178,55 +169,19 @@ def prepare_array_for_arel_by_base_type(value, base_type)
when :datetime, :timestamp, :time
prepare_pg_string_array(value, base_type)
when :decimal, :boolean, :date, :safe
- prepare_pg_string_safe_array(value)
+ prepare_pg_safe_array(value)
else
raise "Unsupported array base type #{base_type} for arel"
end
end
- def prepare_pg_integer_array(value)
- "{#{ value.map{|v| v.nil? ? 'NULL' : v.to_i}.join(',')}}"
- end
-
- def prepare_pg_float_array(value)
- "{#{ value.map{|v| v.nil? ? 'NULL' : v.to_f}.join(',')}}"
- end
-
- def prepare_pg_string_safe_array(value)
- "{#{ value.map{|v| v.nil? ? 'NULL' : v.to_s}.join(',')}}"
- end
-
- ESCAPE_HASH={'\\'=>'\\\\', '"'=>'\\"'}
def prepare_pg_string_array(value, base_type, column=nil)
base_column= if column
column.base_column
else
PostgreSQLColumn::BASE_TYPE_COLUMNS[base_type.to_sym]
end
- value = value.map do|v|
- unless v.nil?
- v = quote_without_postgresql_arrays(v, base_column)
- if v=~/^'(.+)'$/m then
- "\"#{$1.gsub(/\\|"/){|s| ESCAPE_HASH[s]}}\""
- else
- v
- end
- else
- 'NULL'
- end
- end
- "{#{ value.join(',')}}"
- end
-
- class CNULL; def inspect; 'NULL'; end; alias to_s inspect end
- NULL = CNULL.new
-
- TESCAPE_HASH={'\\'=>'\\\\', '"'=>'\\"'}
- def prepare_pg_text_array(value)
- value = value.map{|v|
- v ? "\"#{v.to_s.gsub(/\\|"/){|s| TESCAPE_HASH[s]}}\"" : NULL
- }.join(',')
- "{#{value}}"
+ _prepare_pg_string_array(value){|v| quote_without_postgresql_arrays(v, base_column)}
end
NATIVE_DATABASE_TYPES.keys.each do |key|
View
129 lib/ar_pg_array/schema_arel.rb
@@ -1,129 +0,0 @@
-module ActiveRecord
- module ConnectionAdapters
- class PostgreSQLAdapter
- def prepare_for_arel( value, column )
- return value unless value
- if Array === value && "#{column.type}" =~ /^(.+)_array$/
- prepare_array_for_arel_by_base_type(value, $1)
- else
- super
- end
- end
- end
- end
-end
-
-module ActiveRecord
- # I hope ticket 5047 will be included in Rails 3 reliz
- unless ConnectionAdapters::AbstractAdapter.method_defined? :prepare_for_arel
- module ConnectionAdapters
- class AbstractAdapter
- def prepare_for_arel( value, column )
- if value && (value.is_a?(Hash) || value.is_a?(Array))
- value.to_yaml
- else
- value
- end
- end
- end
- end
-
- class Base
- private
- # Returns a copy of the attributes hash where all the values have been safely quoted for use in
- # an Arel insert/update method.
- def arel_attributes_values(include_primary_key = true, include_readonly_attributes = true, attribute_names = @attributes.keys)
- attrs = {}
- attribute_names.each do |name|
- if (column = column_for_attribute(name)) && (include_primary_key || !column.primary)
-
- if include_readonly_attributes || (!include_readonly_attributes && !self.class.readonly_attributes.include?(name))
- value = read_attribute(name)
-
- if value && self.class.serialized_attributes.has_key?(name) && (value.acts_like?(:date) || value.acts_like?(:time))
- value = value.to_yaml
- else
- value = self.class.connection.prepare_for_arel(value, column)
- end
- attrs[self.class.arel_table[name]] = value
- end
- end
- end
- attrs
- end
- end
- end
-end
-
-module Arel
- module Attributes
- %w{Integer Float Decimal Boolean String Time}.each do |basetype|
- module_eval <<-"END"
- class #{basetype}Array < Attribute
- end
- END
- end
- end
-
- if Arel::VERSION < '2.0'
- module Sql
- module Attributes
- class << self
- def for_with_postgresql_arrays(column)
- if column.type.to_s =~ /^(.+)_array$/
- ('Arel::Sql::Attributes::' + for_without_postgresql_arrays(column.base_column).name.split('::').last + 'Array').constantize
- else
- for_without_postgresql_arrays(column)
- end
- end
- alias_method_chain :for, :postgresql_arrays
- end
-
- %w{Integer Float Decimal Boolean String Time}.each do |basetype|
- module_eval <<-"END"
- class #{basetype}Array < Arel::Attributes::#{basetype}Array
- include Attributes
- end
- END
- end
- end
- end
- else
- module Attributes
- class << self
- def for_with_postgresql_arrays(column)
- if column.type.to_s =~ /^(.+)_array$/
- ('Arel::Attributes::' + for_without_postgresql_arrays(column.base_column).name.split('::').last + 'Array').constantize
- else
- for_without_postgresql_arrays(column)
- end
- end
- alias_method_chain :for, :postgresql_arrays
- end
- end
- end
-end
-
-module ActiveRecord
- class << Base
- if method_defined?(:column_defaults)
- alias column_defaults_without_extradup column_defaults
- def column_defaults_with_extradup
- res = {}
- column_defaults_without_extradup.each{|k, v|
- res[k] = Array === v ? v.dup : v
- }
- res
- end
- def column_defaults
- defaults = column_defaults_without_extradup
- if defaults.values.grep(Array).empty?
- alias column_defaults column_defaults_without_extradup
- else
- alias column_defaults column_defaults_with_extradup
- end
- column_defaults
- end
- end
- end
-end
View
5 lib/ar_pg_array/schema_cacheable.rb
@@ -1,7 +1,4 @@
-ar_am = ActiveRecord::AttributeMethods
-atcbd = ActiveRecord::VERSION::MAJOR < 3 ?
- ar_am::ATTRIBUTE_TYPES_CACHED_BY_DEFAULT :
- ar_am::Read::ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
+atcbd = ActiveRecord::AttributeMethods::ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
atcbd << /_array$/
def atcbd.include?(val)
View
3  spec/fixtures/bulk.rb
@@ -1,2 +1,5 @@
class Bulk < ActiveRecord::Base
end
+
+class Bulk1 < Bulk
+end
View
1  spec/fixtures/bulks.yml
@@ -28,6 +28,7 @@ fourth:
decimals: [ ]
fifth:
id: 5
+ type: "Bulk1"
ints: [ 10 ]
strings: [ "#{1+1}", "\\#{1+1}\"'\\z\x01", "\t\n" ]
times: [ ]
View
2  spec/fixtures/schema.rb
@@ -12,6 +12,7 @@
end
create_table "bulks", :force => true do |t|
+ t.string :type, :default => "Bulk"
t.string :value, :default => "'"
t.integer_array :ints, :default => [1, 2]
t.string_array :strings, :default => %w{as so}
@@ -19,6 +20,7 @@
t.float_array :floats, :default => [1.0, 1.2]
t.decimal_array :decimals, :default => [1.0, 1.2]
t.text_array :texts, :default => [nil, 'Text', 'NULL', 'Text with nil', 'Text with , nil, !"\\', 'nil']
+ t.integer_array :empty_def, :default => []
end
create_table "unrelateds", :force => true do |t|
View
68 spec/pg_array_spec.rb
@@ -72,7 +72,7 @@ def ab
bulk.floats.should == [1.0, 2.3]
bulk.decimals.should == [1.0, 2.3]
end
-
+
it "should be created with defaults" do
bulk = Bulk.new
bulk.ints.should == [1, 2]
@@ -82,6 +82,22 @@ def ab
bulk.texts.should == [nil, 'Text', 'NULL', 'Text with nil', 'Text with , nil, !"\\', 'nil']
map_times(bulk.times).should ==
map_times(parse_times(%w{2010-01-01 2010-02-01}))
+ bulk.empty_def.should == []
+ end
+
+ it "should be able to insert" do
+ bulki = Bulk.new
+ bulki.save
+ bulk = Bulk.find(bulki.id)
+ bulk.ints.should == [1, 2]
+ bulk.strings.should == %w{as so}
+ bulk.floats.should == [1.0, 1.2]
+ bulk.decimals.should == [1.0, 1.2]
+ bulk.texts.should == [nil, 'Text', 'NULL', 'Text with nil', 'Text with , nil, !"\\', 'nil']
+ map_times(bulk.times).should ==
+ map_times(parse_times(%w{2010-01-01 2010-02-01}))
+ bulk.empty_def.should == []
+ bulk.destroy
end
it "should not alter defaults" do
@@ -107,11 +123,40 @@ def ab
it "should save right text" do
bulk = Bulk.find(5)
- bulk.texts = ['Text with , nil, !\x01\\\'"',"Text with , nil, !\x01\\\'\""]
+ bulk.texts = ['Text with , nil, !\x01\\\'"',"Text with , nil, !\x01\n\\\'\""]
bulk.save!
bulk.texts = []
bulk = Bulk.find(:first, :conditions=>'5 = id')
- bulk.texts.should == ['Text with , nil, !\x01\\\'"',"Text with , nil, !\x01\\\'\""]
+ bulk.texts.should == ['Text with , nil, !\x01\\\'"',"Text with , nil, !\x01\n\\\'\""]
+ end
+
+ it "should save nested arrays" do
+ Bulk.transaction do
+ bulk = Bulk.find(3)
+ bulk.ints = [[1,2],[3,4]]
+ bulk.floats = [[1.0, 2.3e34],[3.43,6.21]]
+ bulk.times = [parse_times(%w{2010-04-01 2011-04-01}), parse_times(%w{2011-05-01 2010-05-01})]
+ bulk.save!
+ bulk = Bulk.find(:first, :conditions=>'3 = id')
+ bulk.ints.should == [[1,2],[3,4]]
+ bulk.floats.should == [[1.0, 2.3e34],[3.43,6.21]]
+ bulk.times.map{|ts| map_times(ts)}.should == [
+ map_times(parse_times(%w{2010-04-01 2011-04-01})),
+ map_times(parse_times(%w{2011-05-01 2010-05-01}))]
+ raise ActiveRecord::Rollback
+ end
+ end
+
+ it "should save right nested text" do
+ Bulk.transaction do
+ bulk = Bulk.find(5)
+ bulk.texts = [['Text with , nil, !\x01\\\'"',"Text with , nil, !\x01\n\\\'\""], ['asdf', 'fdsa']]
+ bulk.save!
+ bulk.texts = []
+ bulk = Bulk.find(:first, :conditions=>'5 = id')
+ bulk.texts.should == [['Text with , nil, !\x01\\\'"',"Text with , nil, !\x01\n\\\'\""], ['asdf', 'fdsa']]
+ raise ActiveRecord::Rollback
+ end
end
it "should be safe for eval" do
@@ -144,8 +189,8 @@ def ab
bulk.ints.should.equal?(ar)
ard = ar.dup
arn = (bulk.ints << 1)
- arn.should.equal?(ar)
- bulk.ints.should.equal?(ar)
+ arn.should equal(ar)
+ bulk.ints.should equal(ar)
bulk.ints.should == (ard + [1])
end
@@ -192,6 +237,19 @@ def ab
model2.for_custom_serialize.to_yaml.should == obj.to_yaml
end
+ it 'should be workable with sti' do
+ obj = Bulk1.where(:ints => [10].pg).first
+ obj.should be_instance_of Bulk1
+ obj.floats = [1.1, 2.2]
+ obj.save
+ obj1 = Bulk.find(obj.id)
+ obj1.should be_instance_of Bulk1
+ obj1.floats.should == [1.1, 2.2]
+ obj2 = Bulk1.new
+ obj2.save
+ obj2.destroy
+ end
+
def map_times(times)
times.map{|t| t.strftime("%F %T")}
end

No commit comments for this range

Something went wrong with that request. Please try again.