datamapper 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/MIT-LICENSE +22 -0
- data/README +1 -0
- data/example.rb +25 -0
- data/lib/data_mapper.rb +30 -0
- data/lib/data_mapper/adapters/abstract_adapter.rb +229 -0
- data/lib/data_mapper/adapters/mysql_adapter.rb +171 -0
- data/lib/data_mapper/adapters/sqlite3_adapter.rb +189 -0
- data/lib/data_mapper/associations.rb +19 -0
- data/lib/data_mapper/associations/belongs_to_association.rb +111 -0
- data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +100 -0
- data/lib/data_mapper/associations/has_many_association.rb +101 -0
- data/lib/data_mapper/associations/has_one_association.rb +107 -0
- data/lib/data_mapper/base.rb +160 -0
- data/lib/data_mapper/callbacks.rb +47 -0
- data/lib/data_mapper/database.rb +134 -0
- data/lib/data_mapper/extensions/active_record_impersonation.rb +69 -0
- data/lib/data_mapper/extensions/callback_helpers.rb +35 -0
- data/lib/data_mapper/identity_map.rb +21 -0
- data/lib/data_mapper/loaded_set.rb +45 -0
- data/lib/data_mapper/mappings/column.rb +78 -0
- data/lib/data_mapper/mappings/schema.rb +28 -0
- data/lib/data_mapper/mappings/table.rb +99 -0
- data/lib/data_mapper/queries/conditions.rb +141 -0
- data/lib/data_mapper/queries/connection.rb +34 -0
- data/lib/data_mapper/queries/create_table_statement.rb +38 -0
- data/lib/data_mapper/queries/delete_statement.rb +17 -0
- data/lib/data_mapper/queries/drop_table_statement.rb +17 -0
- data/lib/data_mapper/queries/insert_statement.rb +29 -0
- data/lib/data_mapper/queries/reader.rb +42 -0
- data/lib/data_mapper/queries/result.rb +19 -0
- data/lib/data_mapper/queries/select_statement.rb +103 -0
- data/lib/data_mapper/queries/table_exists_statement.rb +17 -0
- data/lib/data_mapper/queries/truncate_table_statement.rb +17 -0
- data/lib/data_mapper/queries/update_statement.rb +25 -0
- data/lib/data_mapper/session.rb +240 -0
- data/lib/data_mapper/support/blank_slate.rb +3 -0
- data/lib/data_mapper/support/connection_pool.rb +117 -0
- data/lib/data_mapper/support/enumerable.rb +27 -0
- data/lib/data_mapper/support/inflector.rb +329 -0
- data/lib/data_mapper/support/proc.rb +69 -0
- data/lib/data_mapper/support/string.rb +23 -0
- data/lib/data_mapper/support/symbol.rb +91 -0
- data/lib/data_mapper/support/weak_hash.rb +46 -0
- data/lib/data_mapper/unit_of_work.rb +38 -0
- data/lib/data_mapper/validations/confirmation_validator.rb +55 -0
- data/lib/data_mapper/validations/contextual_validations.rb +50 -0
- data/lib/data_mapper/validations/format_validator.rb +85 -0
- data/lib/data_mapper/validations/formats/email.rb +78 -0
- data/lib/data_mapper/validations/generic_validator.rb +27 -0
- data/lib/data_mapper/validations/length_validator.rb +75 -0
- data/lib/data_mapper/validations/required_field_validator.rb +47 -0
- data/lib/data_mapper/validations/unique_validator.rb +65 -0
- data/lib/data_mapper/validations/validation_errors.rb +34 -0
- data/lib/data_mapper/validations/validation_helper.rb +60 -0
- data/performance.rb +156 -0
- data/profile_data_mapper.rb +18 -0
- data/rakefile.rb +80 -0
- data/spec/basic_finder.rb +67 -0
- data/spec/belongs_to.rb +47 -0
- data/spec/fixtures/animals.yaml +32 -0
- data/spec/fixtures/exhibits.yaml +90 -0
- data/spec/fixtures/fruit.yaml +6 -0
- data/spec/fixtures/people.yaml +15 -0
- data/spec/fixtures/zoos.yaml +20 -0
- data/spec/has_and_belongs_to_many.rb +25 -0
- data/spec/has_many.rb +34 -0
- data/spec/legacy.rb +14 -0
- data/spec/models/animal.rb +7 -0
- data/spec/models/exhibit.rb +6 -0
- data/spec/models/fruit.rb +6 -0
- data/spec/models/person.rb +7 -0
- data/spec/models/post.rb +4 -0
- data/spec/models/sales_person.rb +4 -0
- data/spec/models/zoo.rb +5 -0
- data/spec/new_record.rb +24 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/sub_select.rb +16 -0
- data/spec/symbolic_operators.rb +21 -0
- data/spec/validates_confirmation_of.rb +36 -0
- data/spec/validates_format_of.rb +61 -0
- data/spec/validates_length_of.rb +101 -0
- data/spec/validates_uniqueness_of.rb +45 -0
- data/spec/validations.rb +63 -0
- metadata +134 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Extensions
|
3
|
+
|
4
|
+
module ActiveRecordImpersonation
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
def save
|
11
|
+
session.save(self)
|
12
|
+
end
|
13
|
+
|
14
|
+
def reload!
|
15
|
+
session.find(self.class, id, :select => session.mappings[self.class].columns.map(&:name), :reload => true)
|
16
|
+
end
|
17
|
+
|
18
|
+
def reload
|
19
|
+
reload!
|
20
|
+
end
|
21
|
+
|
22
|
+
def destroy!
|
23
|
+
session.destroy(self)
|
24
|
+
end
|
25
|
+
|
26
|
+
module ClassMethods
|
27
|
+
|
28
|
+
def all(options = {}, &b)
|
29
|
+
find(:all, options, &b)
|
30
|
+
end
|
31
|
+
|
32
|
+
def first(options = {}, &b)
|
33
|
+
find(:first, options, &b)
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete_all
|
37
|
+
database.delete_all(self)
|
38
|
+
end
|
39
|
+
|
40
|
+
def truncate!
|
41
|
+
database.truncate(self)
|
42
|
+
end
|
43
|
+
|
44
|
+
def find(*args, &b)
|
45
|
+
DataMapper::database.find(self, *args, &b)
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_by_sql(*args)
|
49
|
+
DataMapper::database.query(*args)
|
50
|
+
end
|
51
|
+
|
52
|
+
def [](id_or_hash)
|
53
|
+
if id_or_hash.kind_of?(Hash)
|
54
|
+
find(:first, id_or_hash)
|
55
|
+
else
|
56
|
+
find(id_or_hash)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def create(attributes)
|
61
|
+
instance = self.new(attributes)
|
62
|
+
instance.save
|
63
|
+
instance
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'data_mapper/callbacks'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Extensions
|
5
|
+
|
6
|
+
module CallbackHelpers
|
7
|
+
|
8
|
+
def self.included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
|
11
|
+
# declare helpers for the standard callbacks
|
12
|
+
Callbacks::EVENTS.each do |name|
|
13
|
+
base.class_eval <<-EOS
|
14
|
+
def self.#{name}(string = nil, &block)
|
15
|
+
if string.nil?
|
16
|
+
callbacks.add(:#{name}, &block)
|
17
|
+
else
|
18
|
+
callbacks.add(:#{name}, string)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
EOS
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
|
27
|
+
def callbacks
|
28
|
+
@callbacks ||= Callbacks.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'data_mapper/support/weak_hash'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
class IdentityMap
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@cache = Hash.new { |h,k| h[k] = Support::WeakHash.new }
|
8
|
+
end
|
9
|
+
|
10
|
+
def get(klass, key)
|
11
|
+
@cache[klass][key]
|
12
|
+
end
|
13
|
+
|
14
|
+
def set(instance)
|
15
|
+
raise "Can't store an instance with a nil key in the IdentityMap" if instance.key == nil
|
16
|
+
|
17
|
+
@cache[instance.class][instance.key] = instance
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'data_mapper/support/enumerable'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
|
5
|
+
# LoadedSet's purpose is to give a common reference for the results of a query,
|
6
|
+
# so that they can be manipulated by the DataMapper, behind-the-scenes, as a set.
|
7
|
+
class LoadedSet
|
8
|
+
|
9
|
+
# Provides a reference to the database that originally loaded the instances.
|
10
|
+
attr_reader :database
|
11
|
+
# Provides an Enumerable of the instances loaded in the set.
|
12
|
+
attr_reader :instances
|
13
|
+
|
14
|
+
def initialize(database)
|
15
|
+
@database = database
|
16
|
+
@instances = [] # ObjectIdCollection.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# Not sure if this is necessary yet...
|
20
|
+
# In other words: Does it make sense to allow portions of a set to be
|
21
|
+
# garbage-collected?
|
22
|
+
#
|
23
|
+
# If so, then this isn't good enough because it's likely to
|
24
|
+
# throw errors. If it's not, then letting Ruby itself track the
|
25
|
+
# references with a simple Array is probably more effecient.
|
26
|
+
class ObjectIdCollection
|
27
|
+
|
28
|
+
include Enumerable
|
29
|
+
include Support::Enumerable
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@object_ids = []
|
33
|
+
end
|
34
|
+
|
35
|
+
def each
|
36
|
+
@object_ids.map { |id| yield ObjectSpace::_id2ref(id) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def <<(object)
|
40
|
+
@object_ids << object.object_id
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Mappings
|
3
|
+
|
4
|
+
# TODO: There are of course many more options to add here.
|
5
|
+
# Ordinal, Length/Size, Nullability are just a few.
|
6
|
+
class Column
|
7
|
+
|
8
|
+
attr_accessor :name, :type, :options
|
9
|
+
|
10
|
+
def initialize(database, name, type, options = {})
|
11
|
+
@database = database
|
12
|
+
@name, @type, @options = name.to_sym, type, options
|
13
|
+
end
|
14
|
+
|
15
|
+
def lazy=(value)
|
16
|
+
@options[:lazy] = value
|
17
|
+
end
|
18
|
+
|
19
|
+
# Determines if the field should be lazy loaded.
|
20
|
+
# You can set this explicitly, or accept the default,
|
21
|
+
# which is false for all but text fields.
|
22
|
+
def lazy?
|
23
|
+
@options[:lazy] || (type == :text)
|
24
|
+
end
|
25
|
+
|
26
|
+
def nullable?
|
27
|
+
@options[:nullable] || true
|
28
|
+
end
|
29
|
+
|
30
|
+
def key?
|
31
|
+
@options[:key] || false
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_sym
|
35
|
+
@name
|
36
|
+
end
|
37
|
+
|
38
|
+
def instance_variable_name
|
39
|
+
@instance_variable_name || (@instance_variable_name = "@#{@name.to_s.gsub(/\?$/, '')}".freeze)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
@name.to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
def type_cast_value(value)
|
47
|
+
@database.type_cast_value(type, value)
|
48
|
+
end
|
49
|
+
|
50
|
+
def column_name
|
51
|
+
@column_name || (@column_name = (@options.has_key?(:column) ? @options[:column].to_s : name.to_s.gsub(/\?$/, '')).freeze)
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_sql
|
55
|
+
@to_sql || (@to_sql = @database.quote_column_name(column_name).freeze)
|
56
|
+
end
|
57
|
+
|
58
|
+
def size
|
59
|
+
@size || begin
|
60
|
+
return @size = @options[:size] if @options.has_key?(:size)
|
61
|
+
return @size = @options[:length] if @options.has_key?(:length)
|
62
|
+
|
63
|
+
@size = case type
|
64
|
+
when :integer then 4
|
65
|
+
when :string, :class then 50
|
66
|
+
else nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def inspect
|
72
|
+
"#<%s:0x%x @name=%s, @type=%s, @options=%s>" % [self.class.name, (object_id * 2), to_sql, type.inspect, options.inspect]
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'data_mapper/mappings/table'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Mappings
|
5
|
+
|
6
|
+
class Schema
|
7
|
+
|
8
|
+
def initialize(database)
|
9
|
+
@database = database
|
10
|
+
@tables = Hash.new { |h,k| h[k] = Table.new(@database, k) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](klass)
|
14
|
+
@tables[klass]
|
15
|
+
rescue
|
16
|
+
raise "#{klass.inspect} can't be mapped to a table"
|
17
|
+
end
|
18
|
+
|
19
|
+
def each
|
20
|
+
@tables.values.each do |table|
|
21
|
+
yield table
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'data_mapper/mappings/column'
|
2
|
+
|
3
|
+
module DataMapper
|
4
|
+
module Mappings
|
5
|
+
|
6
|
+
class Table
|
7
|
+
|
8
|
+
attr_reader :klass
|
9
|
+
|
10
|
+
def initialize(database, klass)
|
11
|
+
unless database.kind_of?(DataMapper::Database) && klass.kind_of?(Class)
|
12
|
+
raise "Database and klass are required: #{ { :database => database, :klass => klass }.inspect }"
|
13
|
+
end
|
14
|
+
|
15
|
+
@database = database
|
16
|
+
@klass = klass
|
17
|
+
@columns = []
|
18
|
+
@columns_hash = Hash.new { |h,k| h[k] = @columns.find { |c| c.name == k } }
|
19
|
+
@columns_by_column_name = Hash.new { |h,k| h[k.to_s] = @columns.find { |c| c.column_name == k.to_s } }
|
20
|
+
end
|
21
|
+
|
22
|
+
def columns
|
23
|
+
key if @key.nil?
|
24
|
+
@columns
|
25
|
+
end
|
26
|
+
|
27
|
+
def key
|
28
|
+
if @key.nil?
|
29
|
+
key_column = @columns.find { |c| c.key? }
|
30
|
+
@key = if key_column.nil?
|
31
|
+
add_column(:id, :integer, :key => true)
|
32
|
+
@klass.send(:attr_reader, :id) unless @klass.methods.include?(:id)
|
33
|
+
@columns.last
|
34
|
+
else
|
35
|
+
key_column
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
@key
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_column(column_name, type, options)
|
43
|
+
column = @columns.find { |c| c.name == column_name.to_sym }
|
44
|
+
|
45
|
+
if column.nil?
|
46
|
+
reset_derived_columns!
|
47
|
+
column = Column.new(@database, column_name, type, options)
|
48
|
+
@columns << column
|
49
|
+
end
|
50
|
+
|
51
|
+
return column
|
52
|
+
end
|
53
|
+
|
54
|
+
def [](column_name)
|
55
|
+
return key if column_name == :id
|
56
|
+
@columns_hash[column_name.kind_of?(Symbol) ? column_name : column_name.to_sym]
|
57
|
+
end
|
58
|
+
|
59
|
+
def find_by_column_name(column_name)
|
60
|
+
@columns_by_column_name[column_name.kind_of?(String) ? column_name : column_name.to_s]
|
61
|
+
end
|
62
|
+
|
63
|
+
def name
|
64
|
+
@name || begin
|
65
|
+
@name = if @klass.superclass != DataMapper::Base
|
66
|
+
@database[@klass.superclass].name
|
67
|
+
else
|
68
|
+
Inflector.tableize(@klass.name)
|
69
|
+
end.freeze
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def name=(value)
|
74
|
+
@name = value
|
75
|
+
end
|
76
|
+
|
77
|
+
def default_foreign_key
|
78
|
+
@default_foreign_key || (@default_foreign_key = "#{Inflector.underscore(Inflector.singularize(name))}_id".freeze)
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_sql
|
82
|
+
@to_sql || (@to_sql = @database.quote_table_name(name).freeze)
|
83
|
+
end
|
84
|
+
|
85
|
+
def inspect
|
86
|
+
"#<%s:0x%x @klass=%s, @name=%s, @columns=%s>" % [self.class.name, (object_id * 2), @klass.name, to_sql, @columns.inspect]
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def reset_derived_columns!
|
91
|
+
@columns_hash.clear
|
92
|
+
@columns_by_column_name.clear
|
93
|
+
@key = nil
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module DataMapper
|
2
|
+
module Queries
|
3
|
+
|
4
|
+
class Conditions
|
5
|
+
|
6
|
+
def initialize(database, options)
|
7
|
+
@database, @options = database, options
|
8
|
+
@has_id = false
|
9
|
+
end
|
10
|
+
|
11
|
+
class NormalizationError < StandardError
|
12
|
+
|
13
|
+
attr_reader :inner_error
|
14
|
+
|
15
|
+
def initialize(clause, inner_error = nil)
|
16
|
+
@clause = clause
|
17
|
+
@inner_error = inner_error
|
18
|
+
|
19
|
+
message = "Failed to normalize clause: #{clause.inspect}"
|
20
|
+
message << ", Error: #{inner_error.inspect}" unless inner_error.nil?
|
21
|
+
|
22
|
+
super(message)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
def normalize(clause, collector)
|
28
|
+
case clause
|
29
|
+
when Hash then
|
30
|
+
clause.each_pair do |k,v|
|
31
|
+
if k.kind_of?(Symbol::Operator)
|
32
|
+
if k.type == :select
|
33
|
+
k.options[:class] ||= @options[:class]
|
34
|
+
|
35
|
+
k.options[:select] ||= if k.value.to_s == @database[k.options[:class]].default_foreign_key
|
36
|
+
@database[k.options[:class]].key.column_name
|
37
|
+
else
|
38
|
+
k.value
|
39
|
+
end
|
40
|
+
|
41
|
+
sub_select = @database.select_statement(k.options.merge(v))
|
42
|
+
normalize(["#{@database[@options[:class]][k.value.to_sym].to_sql} IN ?", sub_select], collector)
|
43
|
+
else
|
44
|
+
@has_id = true if k.value == :id
|
45
|
+
op = case k.type
|
46
|
+
when :gt then '>'
|
47
|
+
when :gte then '>='
|
48
|
+
when :lt then '<'
|
49
|
+
when :lte then '<='
|
50
|
+
when :not then v.nil? ? 'IS NOT' : (v.kind_of?(Array) ? 'NOT IN' : '<>')
|
51
|
+
when :eql then v.nil? ? 'IS' : (v.kind_of?(Array) ? 'IN' : '=')
|
52
|
+
when :like then 'LIKE'
|
53
|
+
when :in then 'IN'
|
54
|
+
else raise ArgumentError.new('Operator type not supported')
|
55
|
+
end
|
56
|
+
normalize(["#{@database[@options[:class]][k.value.to_sym].to_sql} #{op} ?", v], collector)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
@has_id = true if k == :id
|
60
|
+
case v
|
61
|
+
when Array then
|
62
|
+
normalize(["#{@database[@options[:class]][k.to_sym].to_sql} IN ?", v], collector)
|
63
|
+
when SelectStatement then
|
64
|
+
normalize(["#{@database[@options[:class]][k.to_sym].to_sql} IN ?", v], collector)
|
65
|
+
else
|
66
|
+
normalize(["#{@database[@options[:class]][k.to_sym].to_sql} = ?", v], collector)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
when Array then
|
71
|
+
return collector if clause.empty?
|
72
|
+
@has_id = true if clause.first =~ /(^|\s|\`)id(\`|\s|\=|\<)/ && !clause[1].kind_of?(SelectStatement)
|
73
|
+
collector << escape(clause)
|
74
|
+
when String then
|
75
|
+
@has_id = true if clause =~ /(^|\s|\`)id(\`|\s|\=|\<)/
|
76
|
+
collector << clause
|
77
|
+
else raise NormalizationError.new(clause)
|
78
|
+
end
|
79
|
+
|
80
|
+
return collector
|
81
|
+
end
|
82
|
+
|
83
|
+
def escape(conditions)
|
84
|
+
clause = conditions.shift
|
85
|
+
|
86
|
+
clause.gsub(/\?/) do |x|
|
87
|
+
# Check if the condition is an in, clause.
|
88
|
+
case conditions.first
|
89
|
+
when Array then
|
90
|
+
'(' << conditions.shift.map { |c| @database.quote_value(c) }.join(', ') << ')'
|
91
|
+
when SelectStatement then
|
92
|
+
'(' << conditions.shift.to_sql << ')'
|
93
|
+
else
|
94
|
+
@database.quote_value(conditions.shift)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def has_id?
|
100
|
+
normalized_conditions
|
101
|
+
@has_id
|
102
|
+
end
|
103
|
+
|
104
|
+
def normalized_conditions
|
105
|
+
|
106
|
+
if @normalized_conditions.nil?
|
107
|
+
@normalized_conditions = []
|
108
|
+
|
109
|
+
table = @database[@options[:class]]
|
110
|
+
invalid_keys = nil
|
111
|
+
|
112
|
+
implicits = @options.reject do |k,v|
|
113
|
+
standard_key = DataMapper::Session::FIND_OPTIONS.include?(k)
|
114
|
+
(invalid_keys ||= []) << k if !standard_key && table[k.to_sym].nil?
|
115
|
+
standard_key
|
116
|
+
end
|
117
|
+
|
118
|
+
raise "Invalid options: #{invalid_keys.inspect}" unless invalid_keys.nil?
|
119
|
+
|
120
|
+
normalize(implicits, @normalized_conditions)
|
121
|
+
|
122
|
+
if @options.has_key?(:conditions)
|
123
|
+
normalize(@options[:conditions], @normalized_conditions)
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
return @normalized_conditions
|
129
|
+
end
|
130
|
+
|
131
|
+
def empty?
|
132
|
+
normalized_conditions.empty?
|
133
|
+
end
|
134
|
+
|
135
|
+
def to_a
|
136
|
+
normalized_conditions
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|