datamapper 0.1.0 → 0.1.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.
- data/CHANGELOG +31 -1
- data/MIT-LICENSE +1 -1
- data/README +9 -1
- data/example.rb +23 -15
- data/lib/data_mapper.rb +5 -0
- data/lib/data_mapper/adapters/abstract_adapter.rb +9 -207
- data/lib/data_mapper/adapters/mysql_adapter.rb +132 -108
- data/lib/data_mapper/adapters/postgresql_adapter.rb +242 -0
- data/lib/data_mapper/adapters/sql/coersion.rb +74 -0
- data/lib/data_mapper/adapters/sql/commands/advanced_load_command.rb +140 -0
- data/lib/data_mapper/adapters/sql/commands/conditions.rb +161 -0
- data/lib/data_mapper/adapters/sql/commands/delete_command.rb +113 -0
- data/lib/data_mapper/adapters/sql/commands/load_command.rb +296 -0
- data/lib/data_mapper/adapters/sql/commands/save_command.rb +141 -0
- data/lib/data_mapper/adapters/sql/commands/table_exists_command.rb +33 -0
- data/lib/data_mapper/adapters/sql/mappings/column.rb +91 -0
- data/lib/data_mapper/adapters/sql/mappings/schema.rb +30 -0
- data/lib/data_mapper/adapters/sql/mappings/table.rb +143 -0
- data/lib/data_mapper/adapters/sql/quoting.rb +38 -0
- data/lib/data_mapper/adapters/sql_adapter.rb +163 -0
- data/lib/data_mapper/adapters/sqlite3_adapter.rb +155 -116
- data/lib/data_mapper/associations.rb +2 -0
- data/lib/data_mapper/associations/advanced_has_many_association.rb +55 -0
- data/lib/data_mapper/associations/belongs_to_association.rb +2 -2
- data/lib/data_mapper/associations/has_many_association.rb +3 -3
- data/lib/data_mapper/associations/has_one_association.rb +2 -2
- data/lib/data_mapper/base.rb +30 -11
- data/lib/data_mapper/callbacks.rb +4 -1
- data/lib/data_mapper/database.rb +8 -41
- data/lib/data_mapper/identity_map.rb +23 -3
- data/lib/data_mapper/session.rb +34 -186
- data/lib/data_mapper/{extensions → support}/active_record_impersonation.rb +16 -12
- data/lib/data_mapper/support/blank.rb +35 -0
- data/lib/data_mapper/support/connection_pool.rb +2 -1
- data/lib/data_mapper/support/string.rb +27 -0
- data/lib/data_mapper/support/struct.rb +26 -0
- data/lib/data_mapper/validations/unique_validator.rb +1 -3
- data/lib/data_mapper/validations/validation_helper.rb +1 -1
- data/performance.rb +24 -7
- data/profile_data_mapper.rb +24 -2
- data/rakefile.rb +2 -2
- data/spec/basic_finder.rb +2 -2
- data/spec/belongs_to.rb +1 -1
- data/spec/delete_command_spec.rb +9 -0
- data/spec/fixtures/zoos.yaml +4 -0
- data/spec/has_many.rb +1 -1
- data/spec/load_command_spec.rb +44 -0
- data/spec/models/zoo.rb +2 -0
- data/spec/save_command_spec.rb +13 -0
- data/spec/spec_helper.rb +10 -1
- data/spec/support/string_spec.rb +7 -0
- data/spec/validates_confirmation_of.rb +1 -1
- data/spec/validates_format_of.rb +1 -1
- data/spec/validates_length_of.rb +1 -1
- data/spec/validations.rb +1 -1
- metadata +23 -20
- data/lib/data_mapper/extensions/callback_helpers.rb +0 -35
- data/lib/data_mapper/loaded_set.rb +0 -45
- data/lib/data_mapper/mappings/column.rb +0 -78
- data/lib/data_mapper/mappings/schema.rb +0 -28
- data/lib/data_mapper/mappings/table.rb +0 -99
- data/lib/data_mapper/queries/conditions.rb +0 -141
- data/lib/data_mapper/queries/connection.rb +0 -34
- data/lib/data_mapper/queries/create_table_statement.rb +0 -38
- data/lib/data_mapper/queries/delete_statement.rb +0 -17
- data/lib/data_mapper/queries/drop_table_statement.rb +0 -17
- data/lib/data_mapper/queries/insert_statement.rb +0 -29
- data/lib/data_mapper/queries/reader.rb +0 -42
- data/lib/data_mapper/queries/result.rb +0 -19
- data/lib/data_mapper/queries/select_statement.rb +0 -103
- data/lib/data_mapper/queries/table_exists_statement.rb +0 -17
- data/lib/data_mapper/queries/truncate_table_statement.rb +0 -17
- data/lib/data_mapper/queries/update_statement.rb +0 -25
@@ -1,141 +0,0 @@
|
|
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
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/result'
|
2
|
-
require File.dirname(__FILE__) + '/reader'
|
3
|
-
|
4
|
-
module DataMapper
|
5
|
-
module Queries
|
6
|
-
|
7
|
-
class Connection
|
8
|
-
|
9
|
-
def initialize(logger)
|
10
|
-
@logger = logger
|
11
|
-
end
|
12
|
-
|
13
|
-
def log
|
14
|
-
@logger
|
15
|
-
end
|
16
|
-
|
17
|
-
def execute(sql)
|
18
|
-
raise NotImplementedError.new
|
19
|
-
Results.new
|
20
|
-
end
|
21
|
-
|
22
|
-
def query(sql)
|
23
|
-
raise NotImplementedError.new
|
24
|
-
Reader.new
|
25
|
-
end
|
26
|
-
|
27
|
-
def close
|
28
|
-
raise NotImplementedError.new
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
end # module Queries
|
34
|
-
end # module DataMapper
|
@@ -1,38 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module Queries
|
3
|
-
|
4
|
-
class CreateTableStatement
|
5
|
-
|
6
|
-
def initialize(database, klass)
|
7
|
-
@database, @klass = database, klass
|
8
|
-
end
|
9
|
-
|
10
|
-
def to_sql
|
11
|
-
table = @database[@klass]
|
12
|
-
|
13
|
-
sql = "CREATE TABLE " << table.to_sql << " ("
|
14
|
-
|
15
|
-
sql << table.columns.map do |column|
|
16
|
-
column_long_form(column)
|
17
|
-
end.join(', ')
|
18
|
-
|
19
|
-
sql << ", PRIMARY KEY (#{table.key.to_sql}))"
|
20
|
-
|
21
|
-
return sql
|
22
|
-
end
|
23
|
-
|
24
|
-
def column_long_form(column)
|
25
|
-
long_form = "#{column.to_sql} #{@database.adapter.class::TYPES[column.type] || column.type}"
|
26
|
-
|
27
|
-
long_form << "(#{column.size})" unless column.size.nil?
|
28
|
-
long_form << " NOT NULL" unless column.nullable?
|
29
|
-
long_form << " " << @database.syntax(:auto_increment) if column.key?
|
30
|
-
long_form << " default #{column.options[:default]}" if column.options.has_key?(:default)
|
31
|
-
|
32
|
-
return long_form
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module Queries
|
3
|
-
|
4
|
-
class DeleteStatement
|
5
|
-
|
6
|
-
def initialize(database, instance)
|
7
|
-
@database, @instance = database, instance
|
8
|
-
end
|
9
|
-
|
10
|
-
def to_sql
|
11
|
-
"DELETE FROM " << @database[@instance.class].to_sql << " WHERE id = " << @database.quote_value(@instance.key)
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module Queries
|
3
|
-
|
4
|
-
class InsertStatement
|
5
|
-
|
6
|
-
def initialize(database, instance)
|
7
|
-
@database, @instance = database, instance
|
8
|
-
end
|
9
|
-
|
10
|
-
# The only thing this method is responsible for is generating the insert statement.
|
11
|
-
# It is the database adapters responsibility to get the last inserted id
|
12
|
-
def to_sql
|
13
|
-
|
14
|
-
table = @database[@instance.class]
|
15
|
-
|
16
|
-
keys = []
|
17
|
-
values = []
|
18
|
-
|
19
|
-
@instance.dirty_attributes.each_pair { |k,v| keys << table[k].to_sql; values << v }
|
20
|
-
|
21
|
-
# Formatting is a bit off here, but it looks nicer in the log this way.
|
22
|
-
sql = "INSERT INTO #{table.to_sql} (#{keys.join(', ')}) \
|
23
|
-
VALUES (#{values.map { |v| @database.quote_value(v) }.join(', ')})"
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module Queries
|
3
|
-
|
4
|
-
class Reader
|
5
|
-
|
6
|
-
attr_reader :columns
|
7
|
-
|
8
|
-
def initialize(database_result_set)
|
9
|
-
end
|
10
|
-
|
11
|
-
def eof?
|
12
|
-
raise NotImplementedError.new
|
13
|
-
end
|
14
|
-
|
15
|
-
def records_affected
|
16
|
-
raise NotImplementedError.new
|
17
|
-
end
|
18
|
-
|
19
|
-
def each
|
20
|
-
raise NotImplementedError.new
|
21
|
-
end
|
22
|
-
|
23
|
-
def entries
|
24
|
-
raise NotImplementedError.new
|
25
|
-
end
|
26
|
-
|
27
|
-
def [](column)
|
28
|
-
raise NotImplementedError.new
|
29
|
-
end
|
30
|
-
|
31
|
-
def each_pair
|
32
|
-
raise NotImplementedError.new
|
33
|
-
end
|
34
|
-
|
35
|
-
def close
|
36
|
-
raise NotImplementedError.new
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
end # module Queries
|
42
|
-
end # module DataMapper
|
@@ -1,19 +0,0 @@
|
|
1
|
-
module DataMapper
|
2
|
-
module Queries
|
3
|
-
|
4
|
-
class Result
|
5
|
-
|
6
|
-
attr_accessor :size, :last_inserted_id
|
7
|
-
|
8
|
-
def initialize(size, last_inserted_id = nil)
|
9
|
-
@size, @last_inserted_id = size, last_inserted_id
|
10
|
-
end
|
11
|
-
|
12
|
-
def success?
|
13
|
-
size > 0
|
14
|
-
end
|
15
|
-
|
16
|
-
end # class Result
|
17
|
-
|
18
|
-
end # module Queries
|
19
|
-
end # module DataMapper
|
@@ -1,103 +0,0 @@
|
|
1
|
-
require 'data_mapper/queries/conditions'
|
2
|
-
|
3
|
-
module DataMapper
|
4
|
-
module Queries
|
5
|
-
|
6
|
-
class SelectStatement
|
7
|
-
|
8
|
-
def initialize(database, options)
|
9
|
-
@database, @options = database, options
|
10
|
-
end
|
11
|
-
|
12
|
-
def limit
|
13
|
-
@options[:limit]
|
14
|
-
end
|
15
|
-
|
16
|
-
def order
|
17
|
-
@options[:order]
|
18
|
-
end
|
19
|
-
|
20
|
-
def klass
|
21
|
-
@options[:class]
|
22
|
-
end
|
23
|
-
|
24
|
-
def has_id?
|
25
|
-
conditions.has_id?
|
26
|
-
end
|
27
|
-
|
28
|
-
def escape(conditions)
|
29
|
-
@database.escape(conditions)
|
30
|
-
end
|
31
|
-
|
32
|
-
def inspect
|
33
|
-
@options.inspect
|
34
|
-
end
|
35
|
-
|
36
|
-
def include?(association_name)
|
37
|
-
return false if includes.empty?
|
38
|
-
includes.include?(association_name)
|
39
|
-
end
|
40
|
-
|
41
|
-
def includes
|
42
|
-
list = @options[:include] ||= []
|
43
|
-
list.kind_of?(Array) ? list : [list]
|
44
|
-
end
|
45
|
-
|
46
|
-
def reload?
|
47
|
-
@options[:reload]
|
48
|
-
end
|
49
|
-
|
50
|
-
def select
|
51
|
-
select_columns = @options[:select]
|
52
|
-
unless select_columns.nil?
|
53
|
-
select_columns = select_columns.kind_of?(Array) ? select_columns : (@options[:select] = [select_columns])
|
54
|
-
select_columns.map { |column| @database.quote_column_name(column.to_s) }
|
55
|
-
else
|
56
|
-
@options[:select] = @database[klass].columns.select do |column|
|
57
|
-
include?(column.name) || !column.lazy?
|
58
|
-
end.map { |column| column.to_sql }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def instance_id
|
63
|
-
@options[:id]
|
64
|
-
end
|
65
|
-
|
66
|
-
def conditions
|
67
|
-
@conditions ||= Conditions.new(@database, @options)
|
68
|
-
end
|
69
|
-
|
70
|
-
def table
|
71
|
-
@table_name || @table_name = if @options.has_key?(:table)
|
72
|
-
@database.quote_table_name(@options[:table])
|
73
|
-
else
|
74
|
-
@database[klass].to_sql
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def to_sql
|
79
|
-
sql = 'SELECT ' << select.join(', ') << ' FROM ' << table
|
80
|
-
|
81
|
-
where = []
|
82
|
-
|
83
|
-
where += conditions.to_a unless conditions.empty?
|
84
|
-
|
85
|
-
unless where.empty?
|
86
|
-
sql << ' WHERE (' << where.join(') AND (') << ')'
|
87
|
-
end
|
88
|
-
|
89
|
-
unless order.nil?
|
90
|
-
sql << ' ORDER BY ' << order.to_s
|
91
|
-
end
|
92
|
-
|
93
|
-
unless limit.nil?
|
94
|
-
sql << ' LIMIT ' << limit.to_s
|
95
|
-
end
|
96
|
-
|
97
|
-
return sql
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
103
|
-
end
|