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