datamapper 0.1.0
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.
- 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
|