datamapper 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/example.rb +5 -5
  2. data/lib/data_mapper/adapters/abstract_adapter.rb +2 -2
  3. data/lib/data_mapper/adapters/data_object_adapter.rb +141 -147
  4. data/lib/data_mapper/adapters/mysql_adapter.rb +14 -1
  5. data/lib/data_mapper/adapters/postgresql_adapter.rb +123 -18
  6. data/lib/data_mapper/adapters/sql/coersion.rb +21 -9
  7. data/lib/data_mapper/adapters/sql/commands/load_command.rb +36 -19
  8. data/lib/data_mapper/adapters/sql/mappings/column.rb +111 -17
  9. data/lib/data_mapper/adapters/sql/mappings/schema.rb +27 -0
  10. data/lib/data_mapper/adapters/sql/mappings/table.rb +256 -29
  11. data/lib/data_mapper/adapters/sqlite3_adapter.rb +93 -8
  12. data/lib/data_mapper/associations/belongs_to_association.rb +53 -54
  13. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +157 -25
  14. data/lib/data_mapper/associations/has_many_association.rb +45 -15
  15. data/lib/data_mapper/associations/has_n_association.rb +79 -20
  16. data/lib/data_mapper/associations/has_one_association.rb +2 -2
  17. data/lib/data_mapper/associations/reference.rb +1 -1
  18. data/lib/data_mapper/auto_migrations.rb +40 -0
  19. data/lib/data_mapper/base.rb +201 -98
  20. data/lib/data_mapper/context.rb +16 -10
  21. data/lib/data_mapper/database.rb +22 -11
  22. data/lib/data_mapper/dependency_queue.rb +28 -0
  23. data/lib/data_mapper/embedded_value.rb +61 -17
  24. data/lib/data_mapper/property.rb +4 -0
  25. data/lib/data_mapper/support/active_record_impersonation.rb +13 -5
  26. data/lib/data_mapper/support/errors.rb +5 -0
  27. data/lib/data_mapper/support/serialization.rb +8 -4
  28. data/lib/data_mapper/validatable_extensions/errors.rb +12 -0
  29. data/lib/data_mapper/validatable_extensions/macros.rb +7 -0
  30. data/lib/data_mapper/validatable_extensions/validatable_instance_methods.rb +62 -0
  31. data/lib/data_mapper/validatable_extensions/validation_base.rb +18 -0
  32. data/lib/data_mapper/validatable_extensions/validations/formats/email.rb +43 -0
  33. data/lib/data_mapper/validatable_extensions/validations/validates_acceptance_of.rb +7 -0
  34. data/lib/data_mapper/validatable_extensions/validations/validates_confirmation_of.rb +7 -0
  35. data/lib/data_mapper/validatable_extensions/validations/validates_each.rb +7 -0
  36. data/lib/data_mapper/validatable_extensions/validations/validates_format_of.rb +28 -0
  37. data/lib/data_mapper/validatable_extensions/validations/validates_length_of.rb +15 -0
  38. data/lib/data_mapper/validatable_extensions/validations/validates_numericality_of.rb +7 -0
  39. data/lib/data_mapper/validatable_extensions/validations/validates_presence_of.rb +7 -0
  40. data/lib/data_mapper/validatable_extensions/validations/validates_true_for.rb +7 -0
  41. data/lib/data_mapper/validatable_extensions/validations/validates_uniqueness_of.rb +33 -0
  42. data/lib/data_mapper/validations.rb +20 -0
  43. data/lib/data_mapper.rb +39 -34
  44. data/performance.rb +24 -18
  45. data/plugins/dataobjects/do_rb +0 -0
  46. data/rakefile.rb +12 -2
  47. data/spec/active_record_impersonation_spec.rb +133 -0
  48. data/spec/acts_as_tree_spec.rb +25 -9
  49. data/spec/associations_spec.rb +124 -4
  50. data/spec/attributes_spec.rb +13 -0
  51. data/spec/auto_migrations_spec.rb +44 -0
  52. data/spec/base_spec.rb +189 -1
  53. data/spec/column_spec.rb +85 -7
  54. data/spec/conditions_spec.rb +2 -2
  55. data/spec/dependency_spec.rb +25 -0
  56. data/spec/embedded_value_spec.rb +123 -3
  57. data/spec/fixtures/animals.yaml +1 -0
  58. data/spec/fixtures/careers.yaml +5 -0
  59. data/spec/fixtures/comments.yaml +1 -0
  60. data/spec/fixtures/people.yaml +14 -9
  61. data/spec/fixtures/projects.yaml +4 -0
  62. data/spec/fixtures/sections.yaml +5 -0
  63. data/spec/fixtures/serializers.yaml +6 -0
  64. data/spec/fixtures/users.yaml +1 -0
  65. data/spec/load_command_spec.rb +5 -4
  66. data/spec/mock_adapter.rb +2 -2
  67. data/spec/models/animal.rb +2 -1
  68. data/spec/models/animals_exhibit.rb +2 -2
  69. data/spec/models/career.rb +6 -0
  70. data/spec/models/comment.rb +4 -0
  71. data/spec/models/exhibit.rb +4 -0
  72. data/spec/models/person.rb +3 -13
  73. data/spec/models/project.rb +1 -1
  74. data/spec/models/serializer.rb +3 -0
  75. data/spec/models/user.rb +4 -0
  76. data/spec/models/zoo.rb +8 -1
  77. data/spec/natural_key_spec.rb +36 -0
  78. data/spec/paranoia_spec.rb +36 -0
  79. data/spec/property_spec.rb +70 -0
  80. data/spec/schema_spec.rb +10 -2
  81. data/spec/serialization_spec.rb +6 -3
  82. data/spec/serialize_spec.rb +19 -0
  83. data/spec/single_table_inheritance_spec.rb +7 -1
  84. data/spec/spec_helper.rb +26 -8
  85. data/spec/table_spec.rb +33 -0
  86. data/spec/validates_confirmation_of_spec.rb +20 -4
  87. data/spec/validates_format_of_spec.rb +22 -8
  88. data/spec/validates_length_of_spec.rb +26 -13
  89. data/spec/validates_uniqueness_of_spec.rb +18 -5
  90. data/spec/validations_spec.rb +55 -10
  91. data/tasks/fixtures.rb +13 -7
  92. metadata +189 -153
  93. data/lib/data_mapper/validations/confirmation_validator.rb +0 -53
  94. data/lib/data_mapper/validations/contextual_validations.rb +0 -50
  95. data/lib/data_mapper/validations/format_validator.rb +0 -85
  96. data/lib/data_mapper/validations/formats/email.rb +0 -78
  97. data/lib/data_mapper/validations/generic_validator.rb +0 -22
  98. data/lib/data_mapper/validations/length_validator.rb +0 -76
  99. data/lib/data_mapper/validations/required_field_validator.rb +0 -41
  100. data/lib/data_mapper/validations/unique_validator.rb +0 -56
  101. data/lib/data_mapper/validations/validation_errors.rb +0 -37
  102. data/lib/data_mapper/validations/validation_helper.rb +0 -77
  103. data/plugins/dataobjects/REVISION +0 -1
  104. data/plugins/dataobjects/Rakefile +0 -9
  105. data/plugins/dataobjects/do.rb +0 -348
  106. data/plugins/dataobjects/do_mysql.rb +0 -212
  107. data/plugins/dataobjects/do_postgres.rb +0 -196
  108. data/plugins/dataobjects/do_sqlite3.rb +0 -157
  109. data/plugins/dataobjects/spec/do_spec.rb +0 -150
  110. data/plugins/dataobjects/spec/spec_helper.rb +0 -81
  111. data/plugins/dataobjects/swig_mysql/extconf.rb +0 -45
  112. data/plugins/dataobjects/swig_mysql/mysql_c.c +0 -16602
  113. data/plugins/dataobjects/swig_mysql/mysql_c.i +0 -67
  114. data/plugins/dataobjects/swig_mysql/mysql_supp.i +0 -46
  115. data/plugins/dataobjects/swig_postgres/extconf.rb +0 -29
  116. data/plugins/dataobjects/swig_postgres/postgres_c.c +0 -8185
  117. data/plugins/dataobjects/swig_postgres/postgres_c.i +0 -73
  118. data/plugins/dataobjects/swig_sqlite/extconf.rb +0 -9
  119. data/plugins/dataobjects/swig_sqlite/sqlite3_c.c +0 -4725
  120. data/plugins/dataobjects/swig_sqlite/sqlite_c.i +0 -168
  121. data/tasks/drivers.rb +0 -20
@@ -14,8 +14,8 @@ module DataMapper
14
14
  class CoersionError < StandardError
15
15
  end
16
16
 
17
- TRUE_ALIASES = ['true'.freeze, 'TRUE'.freeze, '1'.freeze]
18
- FALSE_ALIASES = [nil, '0'.freeze]
17
+ TRUE_ALIASES = ['true'.freeze, 'TRUE'.freeze, '1'.freeze, 1]
18
+ FALSE_ALIASES = [nil, '0'.freeze, 0]
19
19
 
20
20
  def self.included(base)
21
21
  base.const_set('TRUE_ALIASES', TRUE_ALIASES.dup)
@@ -27,20 +27,20 @@ module DataMapper
27
27
  when TrueClass, FalseClass then raw_value
28
28
  when *self::class::TRUE_ALIASES then true
29
29
  when *self::class::FALSE_ALIASES then false
30
- else "Can't type-cast #{value.inspect} to a boolean"
30
+ else "Can't type-cast #{raw_value.inspect} to a boolean"
31
31
  end
32
32
  end
33
33
 
34
34
  def type_cast_string(raw_value)
35
35
  return nil if raw_value.blank?
36
36
  # type-cast values should be immutable for memory conservation
37
- raw_value.freeze
37
+ raw_value
38
38
  end
39
39
 
40
40
  def type_cast_text(raw_value)
41
41
  return nil if raw_value.blank?
42
42
  # type-cast values should be immutable for memory conservation
43
- raw_value.freeze
43
+ raw_value
44
44
  end
45
45
 
46
46
  def type_cast_class(raw_value)
@@ -75,9 +75,10 @@ module DataMapper
75
75
  return nil if raw_value.blank?
76
76
 
77
77
  case raw_value
78
- when DateTime then raw_value.freeze
79
- when Date then DateTime.new(raw_value)
80
- when String then DateTime::parse(raw_value)
78
+ when "0000-00-00 00:00:00" then nil
79
+ when DateTime then raw_value
80
+ when Date then DateTime.new(raw_value) rescue nil
81
+ when String then DateTime::parse(raw_value) rescue nil
81
82
  else raise CoersionError.new("Can't type-cast #{raw_value.inspect} to a datetime")
82
83
  end
83
84
  end
@@ -86,13 +87,23 @@ module DataMapper
86
87
  return nil if raw_value.blank?
87
88
 
88
89
  case raw_value
89
- when Date then raw_value.freeze
90
+ when Date then raw_value
90
91
  when DateTime, Time then Date::civil(raw_value.year, raw_value.month, raw_value.day)
91
92
  when String then Date::parse(raw_value)
92
93
  else raise CoersionError.new("Can't type-cast #{raw_value.inspect} to a date")
93
94
  end
94
95
  end
95
96
 
97
+ def type_cast_object(raw_value)
98
+ return nil if raw_value.blank?
99
+
100
+ begin
101
+ YAML.load(raw_value)
102
+ rescue
103
+ raise CoersionError.new("Can't type-cast #{raw_value.inspect} to an object")
104
+ end
105
+ end
106
+
96
107
  def type_cast_value(type, raw_value)
97
108
  return nil if raw_value.blank?
98
109
 
@@ -106,6 +117,7 @@ module DataMapper
106
117
  when :float then type_cast_float(raw_value)
107
118
  when :datetime then type_cast_datetime(raw_value)
108
119
  when :date then type_cast_date(raw_value)
120
+ when :object then type_cast_object(raw_value)
109
121
  else
110
122
  if respond_to?("type_cast_#{type}")
111
123
  send("type_cast_#{type}", raw_value)
@@ -15,7 +15,7 @@ module DataMapper
15
15
  @type_override_present = false
16
16
  @type_override_index = nil
17
17
  @type_override = nil
18
- @session = load_command.session
18
+ @database_context = load_command.database_context
19
19
  @reload = load_command.reload?
20
20
  @set = []
21
21
  end
@@ -40,11 +40,13 @@ module DataMapper
40
40
  def materialize(values)
41
41
 
42
42
  instance_id = @key.type_cast_value(values[@key_index])
43
- instance = if @type_override_present
44
- create_instance(instance_id, @type_override.type_cast_value(values[@type_override_index]))
45
- else
46
- create_instance(instance_id)
47
- end
43
+ instance = create_instance(instance_id,
44
+ if @type_override_present
45
+ @type_override.type_cast_value(values[@type_override_index]) || @klass
46
+ else
47
+ @klass
48
+ end
49
+ )
48
50
 
49
51
  @klass.callbacks.execute(:before_materialize, instance)
50
52
 
@@ -55,10 +57,16 @@ module DataMapper
55
57
  # setting both the original_value, and the
56
58
  # instance-variable through method chaining to avoid
57
59
  # lots of extra short-lived local variables.
58
- original_values[column.name] = instance.instance_variable_set(
60
+ type_cast_value = instance.instance_variable_set(
59
61
  column.instance_variable_name,
60
62
  column.type_cast_value(values[index])
61
63
  )
64
+
65
+ original_values[column.name] = case type_cast_value
66
+ when String, Date, Time then type_cast_value.dup
67
+ when column.type == :object then Marshal.dump(type_cast_value)
68
+ else type_cast_value
69
+ end
62
70
  end
63
71
 
64
72
  instance.instance_variable_set(:@loaded_set, @set)
@@ -67,6 +75,9 @@ module DataMapper
67
75
  @klass.callbacks.execute(:after_materialize, instance)
68
76
 
69
77
  return instance
78
+
79
+ rescue => e
80
+ raise MaterializationError.new("Failed to materialize row: #{values.inspect}\n#{e.to_yaml}")
70
81
  end
71
82
 
72
83
  def loaded_set
@@ -74,21 +85,23 @@ module DataMapper
74
85
  end
75
86
 
76
87
  private
77
-
78
- def create_instance(instance_id, instance_type = @klass)
79
- instance = @session.identity_map.get(@klass, instance_id)
88
+
89
+ class MaterializationError < StandardError; end
90
+
91
+ def create_instance(instance_id, instance_type)
92
+ instance = @database_context.identity_map.get(@klass, instance_id)
80
93
 
81
94
  if instance.nil? || @reload
82
95
  instance = instance_type.new() if instance.nil?
83
96
  instance.instance_variable_set(:@__key, instance_id)
84
97
  instance.instance_variable_set(:@new_record, false)
85
- @session.identity_map.set(instance)
98
+ @database_context.identity_map.set(instance)
86
99
  elsif instance.new_record?
87
100
  instance.instance_variable_set(:@__key, instance_id)
88
101
  instance.instance_variable_set(:@new_record, false)
89
102
  end
90
103
 
91
- instance.session = @session
104
+ instance.database_context = @database_context
92
105
 
93
106
  return instance
94
107
  end
@@ -113,10 +126,10 @@ module DataMapper
113
126
 
114
127
  end
115
128
 
116
- attr_reader :conditions, :session, :options
129
+ attr_reader :conditions, :database_context, :options
117
130
 
118
- def initialize(adapter, session, primary_class, options = {})
119
- @adapter, @session, @primary_class = adapter, session, primary_class
131
+ def initialize(adapter, database_context, primary_class, options = {})
132
+ @adapter, @database_context, @primary_class = adapter, database_context, primary_class
120
133
 
121
134
  # BEGIN: Partion out the options hash into general options,
122
135
  # and conditions.
@@ -192,7 +205,7 @@ module DataMapper
192
205
  # just skip that and go straight for the query.
193
206
  unless reload? || @instance_id.blank? || @instance_id.is_a?(Array)
194
207
  # If the id is for only a single record, attempt to find it.
195
- if instance = @session.identity_map.get(@primary_class, @instance_id)
208
+ if instance = @database_context.identity_map.get(@primary_class, @instance_id)
196
209
  return [instance]
197
210
  end
198
211
  end
@@ -347,7 +360,7 @@ module DataMapper
347
360
  when Symbol then
348
361
  collector << ["#{primary_class_table[clause].to_sql(qualify_columns)} #{equality_operator(value)} ?", value]
349
362
  when String then
350
- collector << [clause, value]
363
+ collector << [clause, *value]
351
364
  when Mappings::Column then
352
365
  collector << ["#{clause.to_sql(qualify_columns)} #{equality_operator(value)} ?", value]
353
366
  else raise "CAN HAS CRASH? #{clause.inspect}"
@@ -382,7 +395,7 @@ module DataMapper
382
395
  @columns += included_columns
383
396
 
384
397
  included_associations.each do |assoc|
385
- @columns += assoc.association_columns
398
+ @columns += assoc.associated_columns
386
399
  end
387
400
 
388
401
  shallow_included_associations.each do |assoc|
@@ -486,7 +499,11 @@ module DataMapper
486
499
  else
487
500
  raise "Unable to parse conditions: #{x.inspect}" if x
488
501
  end
489
-
502
+
503
+ if primary_class_table.paranoid?
504
+ conditions_hash[primary_class_table.paranoid_column.name] = nil
505
+ end
506
+
490
507
  conditions_hash.each_pair do |key,value|
491
508
  expression_to_sql(key, value, collection)
492
509
  end
@@ -6,26 +6,37 @@ module DataMapper
6
6
  # TODO: There are of course many more options to add here.
7
7
  # Ordinal, Length/Size, Nullability are just a few.
8
8
  class Column
9
-
10
- attr_accessor :table, :name, :type, :options
11
-
9
+
10
+ attr_reader :type, :name
11
+ attr_accessor :table, :options
12
+
12
13
  def initialize(adapter, table, name, type, ordinal, options = {})
13
14
  @adapter = adapter
14
15
  @table = table
15
- @name, @type, @options = name.to_sym, type, options
16
+ @name, self.type, @options = name.to_sym, type, options
16
17
  @ordinal = ordinal
17
18
 
18
- @key = (@options[:key] == true)
19
+ @key = @options[:key] == true || @options[:serial] == true
19
20
  @nullable = @options.has_key?(:nullable) ? @options[:nullable] : !@key
20
- @lazy = @options.has_key?(:lazy) ? @options[:lazy] : @type == :text
21
- @serial = (@key == true && @type == :integer && @options[:serial] != false)
21
+ @lazy = @options.has_key?(:lazy) ? @options[:lazy] : (@type == :text && !@key)
22
+ @serial = @options[:serial] == true
22
23
  @default = @options[:default]
23
-
24
+ end
25
+
26
+ def type=(value)
27
+ self.flush_sql_caches!
28
+ @type = value
24
29
  (class << self; self end).class_eval <<-EOS
25
30
  def type_cast_value(value)
26
- @adapter.type_cast_#{type}(value)
31
+ @adapter.type_cast_#{@type}(value)
27
32
  end
28
33
  EOS
34
+ @type
35
+ end
36
+
37
+ def name=(value)
38
+ flush_sql_caches!
39
+ @name = value
29
40
  end
30
41
 
31
42
  def ordinal
@@ -59,6 +70,11 @@ module DataMapper
59
70
  @default
60
71
  end
61
72
 
73
+ def default=(value)
74
+ self.flush_sql_caches!
75
+ @default = value
76
+ end
77
+
62
78
  def to_sym
63
79
  @name
64
80
  end
@@ -91,7 +107,7 @@ module DataMapper
91
107
  return @size = @options[:length] if @options.has_key?(:length)
92
108
 
93
109
  @size = case type
94
- when :integer then 4
110
+ when :integer then 11
95
111
  when :string, :class then 50
96
112
  else nil
97
113
  end
@@ -102,6 +118,73 @@ module DataMapper
102
118
  "#<%s:0x%x @name=%s, @type=%s, @options=%s>" % [self.class.name, (object_id * 2), to_sql, type.inspect, options.inspect]
103
119
  end
104
120
 
121
+ def to_create_sql
122
+ "ALTER TABLE " << table.to_sql << " ADD " << to_long_form
123
+ end
124
+
125
+ def to_alter_sql
126
+ "ALTER TABLE " << table.to_sql << " MODIFY COLUMN " << to_long_form
127
+ end
128
+
129
+ def to_drop_sql
130
+ "ALTER TABLE " << table.to_sql << " DROP COLUMN " << to_sql
131
+ end
132
+
133
+ def create!
134
+ @table.columns << self
135
+ flush_sql_caches!
136
+
137
+ @adapter.connection do |db|
138
+ command = db.create_command(to_create_sql)
139
+ command.execute_non_query
140
+ end
141
+ true
142
+ end
143
+
144
+ def drop!
145
+ @table.columns.delete(self)
146
+ flush_sql_caches!
147
+
148
+ @adapter.connection do |db|
149
+ command = db.create_command(to_drop_sql)
150
+ command.execute_non_query
151
+ end
152
+ true
153
+ end
154
+
155
+ def alter!
156
+ flush_sql_caches!
157
+ @adapter.connection do |db|
158
+ command = db.create_command(to_alter_sql)
159
+ command.execute_non_query
160
+ end
161
+ true
162
+ end
163
+
164
+ def rename!(new_name)
165
+ old_name = name # Store the old_name
166
+
167
+ new_column = @table.add_column(new_name, self.type, self.options)
168
+
169
+ # Create the new column
170
+ new_column.create!
171
+
172
+ # Copy the data from one column to the other.
173
+ @adapter.connection do |db|
174
+ command = db.create_command <<-EOS.compress_lines
175
+ UPDATE #{@table.to_sql} SET
176
+ #{new_column.to_sql} = #{to_sql}
177
+ EOS
178
+ command.execute_non_query
179
+ end
180
+
181
+ # Swap column names
182
+ self.name, new_column.name = new_column.name, self.name
183
+ # Drop the old column
184
+ new_column.drop!
185
+ true
186
+ end
187
+
105
188
  def to_long_form
106
189
  @to_long_form || begin
107
190
  @to_long_form = "#{to_sql} #{type_declaration}"
@@ -110,7 +193,10 @@ module DataMapper
110
193
  @to_long_form << " #{not_null_declaration}"
111
194
  end
112
195
 
113
- if key? && !primary_key_declaration.blank?
196
+ # NOTE: We only do inline PRIMARY KEY declarations
197
+ # if the column is also serial since we know
198
+ # "there can be only one".
199
+ if key? && serial? && !primary_key_declaration.blank?
114
200
  @to_long_form << " #{primary_key_declaration}"
115
201
  end
116
202
 
@@ -118,8 +204,8 @@ module DataMapper
118
204
  @to_long_form << " #{serial_declaration}"
119
205
  end
120
206
 
121
- if default && !default_declaration.blank?
122
- @to_long_form << " #{default_declaration}"
207
+ unless default.nil? || (value = default_declaration).blank?
208
+ @to_long_form << " #{value}"
123
209
  end
124
210
 
125
211
  @to_long_form
@@ -131,14 +217,14 @@ module DataMapper
131
217
  end
132
218
 
133
219
  def hash
134
- name.hash
220
+ @hash || @hash = to_sql(true).hash
135
221
  end
136
222
 
137
223
  def eql?(other)
138
224
  name == other.name
139
225
  end
140
226
 
141
- private
227
+ protected
142
228
 
143
229
  def primary_key_declaration
144
230
  "PRIMARY KEY"
@@ -159,7 +245,15 @@ module DataMapper
159
245
  end
160
246
 
161
247
  def default_declaration
162
- "DEFAULT #{default}"
248
+ @adapter.connection { |db| db.create_command("DEFAULT ?").escape_sql([default]) }
249
+ end
250
+
251
+ def flush_sql_caches!
252
+ @to_long_form = nil
253
+ @to_sql = nil
254
+ @to_sql_with_table_name = nil
255
+ @column_name = nil
256
+ @table.flush_sql_caches!(false)
163
257
  end
164
258
 
165
259
  end
@@ -167,4 +261,4 @@ module DataMapper
167
261
  end
168
262
  end
169
263
  end
170
- end
264
+ end
@@ -24,6 +24,33 @@ module DataMapper
24
24
  yield table
25
25
  end
26
26
  end
27
+
28
+ def delete(table)
29
+ @tables.delete(table.name)
30
+ end
31
+
32
+ def <<(table)
33
+ @tables[table.name] = table
34
+ end
35
+
36
+ def to_tables_sql
37
+ @to_column_exists_sql || @to_column_exists_sql = <<-EOS.compress_lines
38
+ SELECT TABLE_NAME
39
+ FROM INFORMATION_SCHEMA.TABLES
40
+ WHERE TABLE_SCHEMA LIKE ?
41
+ EOS
42
+ end
43
+
44
+ def get_database_tables(schema = "%")
45
+ tables = []
46
+ @adapter.connection do |db|
47
+ command = db.create_command(to_tables_sql)
48
+ command.execute_reader(schema) do |reader|
49
+ tables = reader.map { @adapter.class::Mappings::Table.new(@adapter, reader.item(0)) }
50
+ end
51
+ end
52
+ tables
53
+ end
27
54
 
28
55
  end
29
56