datamapper 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/CHANGELOG +31 -1
  2. data/MIT-LICENSE +1 -1
  3. data/README +9 -1
  4. data/example.rb +23 -15
  5. data/lib/data_mapper.rb +5 -0
  6. data/lib/data_mapper/adapters/abstract_adapter.rb +9 -207
  7. data/lib/data_mapper/adapters/mysql_adapter.rb +132 -108
  8. data/lib/data_mapper/adapters/postgresql_adapter.rb +242 -0
  9. data/lib/data_mapper/adapters/sql/coersion.rb +74 -0
  10. data/lib/data_mapper/adapters/sql/commands/advanced_load_command.rb +140 -0
  11. data/lib/data_mapper/adapters/sql/commands/conditions.rb +161 -0
  12. data/lib/data_mapper/adapters/sql/commands/delete_command.rb +113 -0
  13. data/lib/data_mapper/adapters/sql/commands/load_command.rb +296 -0
  14. data/lib/data_mapper/adapters/sql/commands/save_command.rb +141 -0
  15. data/lib/data_mapper/adapters/sql/commands/table_exists_command.rb +33 -0
  16. data/lib/data_mapper/adapters/sql/mappings/column.rb +91 -0
  17. data/lib/data_mapper/adapters/sql/mappings/schema.rb +30 -0
  18. data/lib/data_mapper/adapters/sql/mappings/table.rb +143 -0
  19. data/lib/data_mapper/adapters/sql/quoting.rb +38 -0
  20. data/lib/data_mapper/adapters/sql_adapter.rb +163 -0
  21. data/lib/data_mapper/adapters/sqlite3_adapter.rb +155 -116
  22. data/lib/data_mapper/associations.rb +2 -0
  23. data/lib/data_mapper/associations/advanced_has_many_association.rb +55 -0
  24. data/lib/data_mapper/associations/belongs_to_association.rb +2 -2
  25. data/lib/data_mapper/associations/has_many_association.rb +3 -3
  26. data/lib/data_mapper/associations/has_one_association.rb +2 -2
  27. data/lib/data_mapper/base.rb +30 -11
  28. data/lib/data_mapper/callbacks.rb +4 -1
  29. data/lib/data_mapper/database.rb +8 -41
  30. data/lib/data_mapper/identity_map.rb +23 -3
  31. data/lib/data_mapper/session.rb +34 -186
  32. data/lib/data_mapper/{extensions → support}/active_record_impersonation.rb +16 -12
  33. data/lib/data_mapper/support/blank.rb +35 -0
  34. data/lib/data_mapper/support/connection_pool.rb +2 -1
  35. data/lib/data_mapper/support/string.rb +27 -0
  36. data/lib/data_mapper/support/struct.rb +26 -0
  37. data/lib/data_mapper/validations/unique_validator.rb +1 -3
  38. data/lib/data_mapper/validations/validation_helper.rb +1 -1
  39. data/performance.rb +24 -7
  40. data/profile_data_mapper.rb +24 -2
  41. data/rakefile.rb +2 -2
  42. data/spec/basic_finder.rb +2 -2
  43. data/spec/belongs_to.rb +1 -1
  44. data/spec/delete_command_spec.rb +9 -0
  45. data/spec/fixtures/zoos.yaml +4 -0
  46. data/spec/has_many.rb +1 -1
  47. data/spec/load_command_spec.rb +44 -0
  48. data/spec/models/zoo.rb +2 -0
  49. data/spec/save_command_spec.rb +13 -0
  50. data/spec/spec_helper.rb +10 -1
  51. data/spec/support/string_spec.rb +7 -0
  52. data/spec/validates_confirmation_of.rb +1 -1
  53. data/spec/validates_format_of.rb +1 -1
  54. data/spec/validates_length_of.rb +1 -1
  55. data/spec/validations.rb +1 -1
  56. metadata +23 -20
  57. data/lib/data_mapper/extensions/callback_helpers.rb +0 -35
  58. data/lib/data_mapper/loaded_set.rb +0 -45
  59. data/lib/data_mapper/mappings/column.rb +0 -78
  60. data/lib/data_mapper/mappings/schema.rb +0 -28
  61. data/lib/data_mapper/mappings/table.rb +0 -99
  62. data/lib/data_mapper/queries/conditions.rb +0 -141
  63. data/lib/data_mapper/queries/connection.rb +0 -34
  64. data/lib/data_mapper/queries/create_table_statement.rb +0 -38
  65. data/lib/data_mapper/queries/delete_statement.rb +0 -17
  66. data/lib/data_mapper/queries/drop_table_statement.rb +0 -17
  67. data/lib/data_mapper/queries/insert_statement.rb +0 -29
  68. data/lib/data_mapper/queries/reader.rb +0 -42
  69. data/lib/data_mapper/queries/result.rb +0 -19
  70. data/lib/data_mapper/queries/select_statement.rb +0 -103
  71. data/lib/data_mapper/queries/table_exists_statement.rb +0 -17
  72. data/lib/data_mapper/queries/truncate_table_statement.rb +0 -17
  73. 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,17 +0,0 @@
1
- module DataMapper
2
- module Queries
3
-
4
- class DropTableStatement
5
-
6
- def initialize(database, klass)
7
- @database, @klass = database, klass
8
- end
9
-
10
- def to_sql
11
- "DROP TABLE #{@database[@klass].to_sql}"
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