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,4 +1,5 @@
1
1
  require 'data_mapper/associations/has_many_association'
2
+ require 'data_mapper/associations/advanced_has_many_association'
2
3
  require 'data_mapper/associations/belongs_to_association'
3
4
  require 'data_mapper/associations/has_one_association'
4
5
  require 'data_mapper/associations/has_and_belongs_to_many_association'
@@ -9,6 +10,7 @@ module DataMapper
9
10
  def self.included(base)
10
11
  base.class_eval do
11
12
  include DataMapper::Associations::HasMany
13
+ include DataMapper::Associations::AdvancedHasMany
12
14
  include DataMapper::Associations::BelongsTo
13
15
  include DataMapper::Associations::HasOne
14
16
  include DataMapper::Associations::HasAndBelongsToMany
@@ -0,0 +1,55 @@
1
+ module DataMapper
2
+ module Associations
3
+
4
+ class AdvancedHasManyAssociation
5
+ include Enumerable
6
+
7
+ def initialize(klass, association_name, options)
8
+ @association_name = association_name.to_sym
9
+ @options = options
10
+
11
+ # Define the association instance method (i.e. Project#tasks)
12
+ klass.class_eval <<-EOS
13
+ def #{association_name}
14
+ @#{association_name} || (@#{association_name} = HasManyAssociation.new(self, "#{association_name}", #{options.inspect}))
15
+ end
16
+ EOS
17
+ end
18
+
19
+ def name
20
+ @association_name
21
+ end
22
+
23
+ def constant
24
+ @associated_class || @associated_class = if @options.has_key?(:class) || @options.has_key?(:class_name)
25
+ associated_class_name = (@options[:class] || @options[:class_name])
26
+ if associated_class_name.kind_of?(String)
27
+ Kernel.const_get(Inflector.classify(associated_class_name))
28
+ else
29
+ associated_class_name
30
+ end
31
+ else
32
+ Kernel.const_get(Inflector.classify(association_name))
33
+ end
34
+ end
35
+
36
+ def foreign_key
37
+ @foreign_key || (@foreign_key = (@options[:foreign_key] || @instance.session.schema[@instance.class].default_foreign_key))
38
+ end
39
+
40
+ end
41
+
42
+ module AdvancedHasMany
43
+ def self.included(base)
44
+ base.extend(ClassMethods)
45
+ end
46
+
47
+ module ClassMethods
48
+ def advanced_has_many(association_name, options = {})
49
+ database.schema[self].associations << AdvancedHasManyAssociation.new(self, association_name, options)
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -60,10 +60,10 @@ module DataMapper
60
60
  setter_method = "#{@association_name}=".to_sym
61
61
  instance_variable_name = "@#{foreign_key}".to_sym
62
62
 
63
- set = @instance.loaded_set.instances.group_by { |instance| instance.instance_variable_get(instance_variable_name) }
63
+ set = @instance.loaded_set.group_by { |instance| instance.instance_variable_get(instance_variable_name) }
64
64
 
65
65
  # Fetch the foreign objects for all instances in the current object's loaded-set.
66
- @instance.session.find(@associated_class, :all, :id => set.keys).each do |owner|
66
+ @instance.session.all(@associated_class, :id => set.keys).each do |owner|
67
67
  set[owner.key].each do |instance|
68
68
  instance.send(setter_method, owner)
69
69
  end
@@ -22,7 +22,7 @@ module DataMapper
22
22
  end
23
23
 
24
24
  def self.setup(klass, association_name, options)
25
-
25
+
26
26
  # Define the association instance method (i.e. Project#tasks)
27
27
  klass.class_eval <<-EOS
28
28
  def #{association_name}
@@ -57,10 +57,10 @@ module DataMapper
57
57
  # Temp variable for the instance variable name.
58
58
  instance_variable_name = "@#{foreign_key}".to_sym
59
59
 
60
- set = @instance.loaded_set.instances.group_by { |instance| instance.key }
60
+ set = @instance.loaded_set.group_by { |instance| instance.key }
61
61
 
62
62
  # Fetch the foreign objects for all instances in the current object's loaded-set.
63
- @instance.session.find(@associated_class, :all, foreign_key.to_sym => set.keys).group_by do |association|
63
+ @instance.session.all(@associated_class, foreign_key.to_sym => set.keys).group_by do |association|
64
64
  association.instance_variable_get(instance_variable_name)
65
65
  end.each_pair do |id, results|
66
66
  set[id].first.send(@association_name).set(results)
@@ -58,10 +58,10 @@ module DataMapper
58
58
  setter_method = "#{@association_name}=".to_sym
59
59
  instance_variable_name = "@#{foreign_key}".to_sym
60
60
 
61
- set = @instance.loaded_set.instances.group_by { |instance| instance.key }
61
+ set = @instance.loaded_set.group_by { |instance| instance.key }
62
62
 
63
63
  # Fetch the foreign objects for all instances in the current object's loaded-set.
64
- @instance.session.find(@associated_class, :all, foreign_key => set.keys).each do |association|
64
+ @instance.session.all(@associated_class, foreign_key => set.keys).each do |association|
65
65
  set[association.instance_variable_get(instance_variable_name)].first.send(setter_method, association)
66
66
  end
67
67
  end
@@ -1,8 +1,8 @@
1
1
  require 'data_mapper/unit_of_work'
2
- require 'data_mapper/extensions/active_record_impersonation'
3
- require 'data_mapper/extensions/callback_helpers'
2
+ require 'data_mapper/support/active_record_impersonation'
4
3
  require 'data_mapper/validations/validation_helper'
5
4
  require 'data_mapper/associations'
5
+ require 'data_mapper/callbacks'
6
6
 
7
7
  module DataMapper
8
8
 
@@ -12,9 +12,8 @@ module DataMapper
12
12
  attr_accessor :loaded_set
13
13
 
14
14
  include UnitOfWork
15
- include Extensions::ActiveRecordImpersonation
16
- include Extensions::CallbackHelpers
17
- include Extensions::ValidationHelper
15
+ include Support::ActiveRecordImpersonation
16
+ include Validations::ValidationHelper
18
17
  include Associations
19
18
 
20
19
  def self.inherited(klass)
@@ -93,7 +92,7 @@ module DataMapper
93
92
  value = instance_variable_get(column.instance_variable_name)
94
93
  return value unless value.nil?
95
94
 
96
- session.find(self.class, :all, :select => [:id, name], :reload => true, :id => loaded_set.instances.map(&:id)).each do |instance|
95
+ session.all(self.class, :select => [:id, name], :reload => true, :id => loaded_set.map(&:id)).each do |instance|
97
96
  (class << self; self end).send(:attr_accessor, name)
98
97
  end
99
98
 
@@ -127,7 +126,7 @@ module DataMapper
127
126
  end
128
127
 
129
128
  def self.foreign_key
130
- Inflector.underscore(self.name) + "_id"
129
+ String::memoized_underscore(self.name) + "_id"
131
130
  end
132
131
 
133
132
  def inspect
@@ -147,14 +146,34 @@ module DataMapper
147
146
  end
148
147
 
149
148
  def session
150
- @session ||= database
149
+ @session || ( @session = database )
151
150
  end
152
151
 
153
152
  def key
154
- key_column = session.schema[self.class].key
155
- key_column.type_cast_value(instance_variable_get(key_column.instance_variable_name))
153
+ @__key || @__key = begin
154
+ key_column = session.schema[self.class].key
155
+ key_column.type_cast_value(instance_variable_get(key_column.instance_variable_name))
156
+ end
156
157
  end
157
-
158
+
159
+ # Callbacks associated with this class.
160
+ def self.callbacks
161
+ @callbacks || ( @callbacks = Callbacks.new )
162
+ end
163
+
164
+ # Declare helpers for the standard callbacks
165
+ DataMapper::Callbacks::EVENTS.each do |name|
166
+ class_eval <<-EOS
167
+ def self.#{name}(string = nil, &block)
168
+ if string.nil?
169
+ callbacks.add(:#{name}, &block)
170
+ else
171
+ callbacks.add(:#{name}, string)
172
+ end
173
+ end
174
+ EOS
175
+ end
176
+
158
177
  end
159
178
 
160
179
  end
@@ -12,7 +12,10 @@ module DataMapper
12
12
  ]
13
13
 
14
14
  def initialize
15
- @callbacks = Hash.new { |h,k| h[k.to_sym] = [] }
15
+ @callbacks = Hash.new do |h,k|
16
+ raise 'Callback names must be Symbols' unless k.kind_of?(Symbol)
17
+ h[k] = []
18
+ end
16
19
  end
17
20
 
18
21
  alias ruby_method_missing method_missing
@@ -1,6 +1,5 @@
1
1
  require 'logger'
2
2
  require 'data_mapper/session'
3
- require 'data_mapper/mappings/schema'
4
3
 
5
4
  # Delegates to DataMapper::database.
6
5
  # Will not overwrite if a method of the same name is pre-defined.
@@ -18,11 +17,12 @@ module DataMapper
18
17
  # a new Session.
19
18
  def self.database(name = :default)
20
19
  unless block_given?
21
- Database.context.last || Session.new(Database[name])
20
+ Database.context.last || Session.new(Database[name].adapter)
22
21
  else
23
- Database.context.push(Session.new(Database[name]))
24
- yield Database.context.last
22
+ Database.context.push(Session.new(Database[name].adapter))
23
+ result = yield(Database.context.last)
25
24
  Database.context.pop
25
+ result
26
26
  end
27
27
  end
28
28
 
@@ -51,28 +51,8 @@ module DataMapper
51
51
 
52
52
  def initialize(name)
53
53
  @name = name
54
- end
55
-
56
- # Shortcut to adapter.class::Queries::FooStatement.new
57
- def method_missing(sym, *args)
58
- return super if sym.to_s !~ /_statement$/
59
- @adapter.class::Queries.const_get(Inflector.classify(sym.to_s)).new(self, *args)
60
- end
61
-
62
- def syntax(token)
63
- @adapter.class::SYNTAX[token]
64
- end
65
-
66
- def [](klass_or_table_name)
67
- schema[klass_or_table_name]
68
- end
69
-
70
- def schema
71
- @schema ||= Mappings::Schema.new(self)
72
54
  end
73
55
 
74
- class ConditionEscapeError < StandardError; end
75
-
76
56
  attr_reader :name
77
57
 
78
58
  def adapter(value = nil)
@@ -80,12 +60,9 @@ module DataMapper
80
60
 
81
61
  raise ArgumentError.new('The adapter is readonly after being set') unless @adapter.nil?
82
62
 
83
- require "data_mapper/adapters/#{Inflector.underscore(value)}_adapter"
63
+ require "data_mapper/adapters/#{String::memoized_underscore(value)}_adapter"
84
64
  adapter_class = Adapters::const_get(Inflector.classify(value) + "Adapter")
85
65
 
86
- (class << self; self end).send(:include, adapter_class::Quoting)
87
- (class << self; self end).send(:include, adapter_class::Coersion)
88
-
89
66
  @adapter = adapter_class.new(self)
90
67
  end
91
68
 
@@ -94,6 +71,9 @@ module DataMapper
94
71
  def username(value = nil); value.nil? ? @username : @username = value end
95
72
  def password(value = nil); value.nil? ? (@password || '') : @password = value end
96
73
 
74
+ # single_threaded mode is disabled by default currently since it's buggy.
75
+ def single_threaded(value = nil); value.nil? ? (@single_threaded.nil? ? @single_threaded = false : @single_threaded) : @single_threaded = value end
76
+
97
77
  def log(value = nil)
98
78
  @log = value unless value.nil?
99
79
 
@@ -116,19 +96,6 @@ module DataMapper
116
96
  @log_stream = value
117
97
  end
118
98
 
119
- def connection
120
- @adapter.connection do |db|
121
- results = yield(db)
122
- end
123
- end
124
-
125
- def query(sql)
126
- connection { |db| db.query(sql) }
127
- end
128
-
129
- def execute(sql)
130
- connection { |db| db.execute(sql) }
131
- end
132
99
  end
133
100
 
134
101
  end
@@ -1,20 +1,40 @@
1
1
  require 'data_mapper/support/weak_hash'
2
2
 
3
3
  module DataMapper
4
+
5
+ # Tracks objects to help ensure that each object gets loaded only once.
6
+ # See: http://www.martinfowler.com/eaaCatalog/identityMap.html
4
7
  class IdentityMap
5
8
 
6
9
  def initialize
7
- @cache = Hash.new { |h,k| h[k] = Support::WeakHash.new }
10
+ # WeakHash is much more expensive, and not necessary if the IdentityMap is tied to Session instead of Database.
11
+ # @cache = Hash.new { |h,k| h[k] = Support::WeakHash.new }
12
+ @cache = Hash.new { |h,k| h[k] = Hash.new }
8
13
  end
9
14
 
15
+ # Pass a Class and a key, and to retrieve an instance.
16
+ # If the instance isn't found, nil is returned.
10
17
  def get(klass, key)
11
18
  @cache[klass][key]
12
19
  end
13
20
 
21
+ # Pass an instance to add it to the IdentityMap.
22
+ # The instance must have an assigned key.
14
23
  def set(instance)
15
- raise "Can't store an instance with a nil key in the IdentityMap" if instance.key == nil
24
+ instance_key = instance.key
25
+ raise "Can't store an instance with a nil key in the IdentityMap" if instance_key.nil?
16
26
 
17
- @cache[instance.class][instance.key] = instance
27
+ @cache[instance.class][instance_key] = instance
28
+ end
29
+
30
+ # Remove an instance from the IdentityMap.
31
+ def delete(instance)
32
+ @cache[instance.class].delete(instance.key)
33
+ end
34
+
35
+ # Clears a particular set of classes from the IdentityMap.
36
+ def clear!(klass)
37
+ @cache.delete(klass)
18
38
  end
19
39
 
20
40
  end
@@ -1,240 +1,88 @@
1
- require 'data_mapper/loaded_set'
2
1
  require 'data_mapper/identity_map'
3
2
 
4
3
  module DataMapper
5
4
 
6
5
  class Session
7
-
8
- FIND_OPTIONS = [
9
- :select, :limit, :class, :include, :reload, :conditions, :order
10
- ]
11
6
 
12
7
  class MaterializationError < StandardError
13
8
  end
14
9
 
15
- def initialize(database)
16
- @database = database
10
+ attr_reader :adapter
11
+
12
+ def initialize(adapter)
13
+ @adapter = adapter
17
14
  end
18
15
 
19
16
  def identity_map
20
17
  @identity_map || ( @identity_map = IdentityMap.new )
21
18
  end
22
19
 
23
- def find(klass, type_or_id, options = {}, &b)
24
- options.merge! b.to_hash if block_given?
20
+ def first(klass, *args, &b)
21
+ id = nil
22
+ options = nil
25
23
 
26
- results = case type_or_id
27
- when :first then
28
- first(@database.select_statement(options.merge(:class => klass, :limit => 1)))
29
- when :all then
30
- all(@database.select_statement(options.merge(:class => klass)))
24
+ if args.empty? # No id, no options
25
+ options = { :limit => 1 }
26
+ elsif args.size == 2 && args.last.kind_of?(Hash) # id AND options
27
+ options = args.last.merge(:id => args.first)
28
+ elsif args.size == 1 # id OR options
29
+ if args.first.kind_of?(Hash)
30
+ options = args.first.merge(:limit => 1) # no id, add limit
31
31
  else
32
- first(@database.select_statement(options.merge(:class => klass, :id => type_or_id)))
33
- end
34
-
35
- case results
36
- when Array then results.each { |instance| instance.session = self }
37
- when Base then results.session = self
38
- end
39
- return results
40
- end
41
-
42
- def first(options)
43
- if options.has_id? && !options.reload?
44
- instance = identity_map.get(options.klass, options.instance_id)
45
- return instance unless instance.nil?
46
- end
47
-
48
- reader = @database.query(options)
49
- instance = reader.eof? ? nil : load(options, reader.next)
50
- reader.close
51
- return instance
52
- rescue DatabaseError => de
53
- de.options = options
54
- raise de
55
- end
56
-
57
- def all(options)
58
- set = LoadedSet.new(@database)
59
- reader = @database.query(options)
60
- instances = reader.map do |hash|
61
- load(options, hash, set)
62
- end
63
- reader.close
64
- return instances
65
- rescue => error
66
- @database.log.error(error)
67
- raise error
68
- end
69
-
70
- def load(options, hash, set = LoadedSet.new(@database))
71
-
72
- instance_class = unless hash['type'].nil?
73
- Kernel::const_get(hash['type'])
32
+ options = { :id => args.first } # no options, set id
33
+ end
74
34
  else
75
- options.klass
35
+ raise ArgumentError.new('Session#first takes a class, and optional type_or_id and/or options arguments')
76
36
  end
77
37
 
78
- mapping = @database[instance_class]
38
+ options.merge!(b.to_hash) if block_given?
79
39
 
80
- instance_id = mapping.key.type_cast_value(hash['id'])
81
- instance = identity_map.get(instance_class, instance_id)
82
-
83
- if instance.nil? || options.reload?
84
- instance ||= instance_class.new
85
- instance.class.callbacks.execute(:before_materialize, instance)
86
-
87
- instance.instance_variable_set(:@new_record, false)
88
- hash.each_pair do |name_as_string,raw_value|
89
- name = name_as_string.to_sym
90
- if column = mapping.find_by_column_name(name)
91
- value = column.type_cast_value(raw_value)
92
- instance.instance_variable_set(column.instance_variable_name, value)
93
- else
94
- instance.instance_variable_set("@#{name}", value)
95
- end
96
- instance.original_hashes[name] = value.hash
97
- end
98
-
99
- instance.class.callbacks.execute(:after_materialize, instance)
100
-
101
- identity_map.set(instance)
102
- end
103
-
104
- instance.instance_variable_set(:@loaded_set, set)
105
- set.instances << instance
106
- return instance
107
- end
108
-
109
- def save(instance)
110
- return false unless instance.dirty?
111
- instance.class.callbacks.execute(:before_save, instance)
112
- result = instance.new_record? ? insert(instance) : update(instance)
113
- instance.session = self
114
- instance.class.callbacks.execute(:after_save, instance)
115
- result.success?
40
+ @adapter.load(self, klass, options)
116
41
  end
117
42
 
118
- def insert(instance, inserted_id = nil)
119
- instance.class.callbacks.execute(:before_create, instance)
120
- result = @database.execute(@database.insert_statement(instance))
121
-
122
- if result.success?
123
- instance.instance_variable_set(:@new_record, false)
124
- instance.instance_variable_set(:@id, inserted_id || result.last_inserted_id)
125
- calculate_original_hashes(instance)
126
- identity_map.set(instance)
127
- instance.class.callbacks.execute(:after_create, instance)
128
- end
129
-
130
- return result
131
- rescue => error
132
- @database.log.error(error)
133
- raise error
43
+ def all(klass, options = {})
44
+ @adapter.load(self, klass, options)
134
45
  end
135
46
 
136
- def update(instance)
137
- instance.class.callbacks.execute(:before_update, instance)
138
- result = @database.execute(@database.update_statement(instance))
139
- calculate_original_hashes(instance)
140
- instance.class.callbacks.execute(:after_update, instance)
141
- return result
142
- rescue => error
143
- @database.log.error(error)
144
- raise error
47
+ def save(instance)
48
+ @adapter.save(self, instance)
145
49
  end
146
50
 
147
51
  def destroy(instance)
148
- instance.class.callbacks.execute(:before_destroy, instance)
149
- result = @database.execute(@database.delete_statement(instance))
150
- if result.success?
151
- instance.instance_variable_set(:@new_record, true)
152
- instance.original_hashes.clear
153
- instance.class.callbacks.execute(:after_destroy, instance)
154
- end
155
- return result.success?
156
- rescue => error
157
- @database.log.error(error)
158
- raise error
52
+ @adapter.delete(instance, :session => self)
159
53
  end
160
54
 
161
55
  def delete_all(klass)
162
- @database.execute(@database.delete_statement(klass))
56
+ @adapter.delete(klass, :session => self)
163
57
  end
164
58
 
165
59
  def truncate(klass)
166
- @database.connection do |db|
167
- db.execute(@database.truncate_table_statement(klass))
168
- end
60
+ @adapter.delete(klass, :truncate => true, :session => self)
169
61
  end
170
62
 
171
63
  def create_table(klass)
172
- @database.connection do |db|
173
- db.execute(@database.create_table_statement(klass))
174
- end unless table_exists?(klass)
64
+ @adapter[klass].create!
175
65
  end
176
66
 
177
67
  def drop_table(klass)
178
- @database.connection do |db|
179
- db.execute(@database.drop_table_statement(klass))
180
- end if table_exists?(klass)
68
+ @adapter[klass].drop!
181
69
  end
182
70
 
183
71
  def table_exists?(klass)
184
- reader = @database.connection do |db|
185
- db.query(@database.table_exists_statement(klass))
186
- end
187
- result = !reader.eof?
188
- reader.close
189
- result
72
+ @adapter[klass].exists?
190
73
  end
191
74
 
192
- def query(*args)
193
- sql = args.shift
194
-
195
- unless args.empty?
196
- sql.gsub!(/\?/) do |x|
197
- @database.quote_value(args.shift)
198
- end
199
- end
200
-
201
- reader = @database.connection do |db|
202
- db.query(sql)
203
- end
204
-
205
- columns = reader.columns.keys
206
- klass = Struct.new(*columns.map { |c| c.to_sym })
207
-
208
- rows = reader.map do |row|
209
- klass.new(*columns.map { |c| row[c] })
210
- end
211
-
212
- reader.close
213
- return rows
75
+ def query(*args)
76
+ @adapter.query(*args)
214
77
  end
215
78
 
216
79
  def schema
217
- @database.schema
80
+ @adapter.schema
218
81
  end
219
82
 
220
83
  def log
221
- @database.log
222
- end
223
-
224
- private
225
-
226
- # Make sure this uses the factory changes later...
227
- def type_cast_value(klass, name, raw_value)
228
- @database[klass][name].type_cast_value(raw_value)
229
- end
230
-
231
- # Calculates the original hashes for each value
232
- # in an instance's set of attributes, and adds
233
- # them to the original_hashes hash.
234
- def calculate_original_hashes(instance)
235
- instance.attributes.each_pair do |name, value|
236
- instance.original_hashes[name] = value.hash
237
- end
84
+ @adapter.log
238
85
  end
86
+
239
87
  end
240
88
  end