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