dm-core 0.9.10 → 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,18 @@
1
+ === 0.9.11 / not released
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Added deprecation warning for inferred child_key naming convention change
6
+
7
+ * 6 bug fixes:
8
+
9
+ * Removed unecessary code from SEL
10
+ * 1.9.1 fix for Logger to use Array#join instead of Array#to_s
11
+ * 1.9.1 fix for specs to pass
12
+ * Fix for multiple join models to create correct SQL
13
+ * Fix for STI and lazy loading
14
+ * Fixed Resource#eql?
15
+
1
16
  === 0.9.10 / 2009-01-19
2
17
 
3
18
  * 1 major enhancement:
data/Rakefile CHANGED
@@ -9,18 +9,20 @@ require 'lib/dm-core/version'
9
9
 
10
10
  ROOT = Pathname(__FILE__).dirname.expand_path
11
11
 
12
- AUTHOR = "Dan Kubb"
13
- EMAIL = "dan.kubb@gmail.com"
14
- GEM_NAME = "dm-core"
15
- GEM_VERSION = DataMapper::VERSION
16
- GEM_DEPENDENCIES = ["data_objects", "~>0.9.11"],
17
- ["extlib", "~>0.9.10"],
18
- ["addressable", "~>2.0.1"]
12
+ AUTHOR = 'Dan Kubb'
13
+ EMAIL = 'dan.kubb@gmail.com'
14
+ GEM_NAME = 'dm-core'
15
+ GEM_VERSION = DataMapper::VERSION
16
+ GEM_DEPENDENCIES = [
17
+ %w[ data_objects ~>0.9.11 ],
18
+ %w[ extlib ~>0.9.11 ],
19
+ %w[ addressable ~>2.0.2 ],
20
+ ]
19
21
 
20
- PROJECT_NAME = "datamapper"
21
- PROJECT_DESCRIPTION = "Faster, Better, Simpler."
22
- PROJECT_SUMMARY = "An Object/Relational Mapper for Ruby"
23
- PROJECT_URL = "http://datamapper.org"
22
+ PROJECT_NAME = 'datamapper'
23
+ PROJECT_DESCRIPTION = 'Faster, Better, Simpler.'
24
+ PROJECT_SUMMARY = 'An Object/Relational Mapper for Ruby'
25
+ PROJECT_URL = 'http://datamapper.org'
24
26
 
25
27
  require ROOT + 'tasks/hoe'
26
28
  require ROOT + 'tasks/gemspec'
data/dm-core.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{dm-core}
5
- s.version = "0.9.10"
5
+ s.version = "0.9.11"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Dan Kubb"]
9
- s.date = %q{2009-01-19}
9
+ s.date = %q{2009-03-29}
10
10
  s.description = %q{Faster, Better, Simpler.}
11
11
  s.email = ["dan.kubb@gmail.com"]
12
12
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
@@ -25,16 +25,16 @@ Gem::Specification.new do |s|
25
25
 
26
26
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
27
  s.add_runtime_dependency(%q<data_objects>, ["~> 0.9.11"])
28
- s.add_runtime_dependency(%q<extlib>, ["~> 0.9.10"])
29
- s.add_runtime_dependency(%q<addressable>, ["~> 2.0.1"])
28
+ s.add_runtime_dependency(%q<extlib>, ["~> 0.9.11"])
29
+ s.add_runtime_dependency(%q<addressable>, ["~> 2.0.2"])
30
30
  else
31
31
  s.add_dependency(%q<data_objects>, ["~> 0.9.11"])
32
- s.add_dependency(%q<extlib>, ["~> 0.9.10"])
33
- s.add_dependency(%q<addressable>, ["~> 2.0.1"])
32
+ s.add_dependency(%q<extlib>, ["~> 0.9.11"])
33
+ s.add_dependency(%q<addressable>, ["~> 2.0.2"])
34
34
  end
35
35
  else
36
36
  s.add_dependency(%q<data_objects>, ["~> 0.9.11"])
37
- s.add_dependency(%q<extlib>, ["~> 0.9.10"])
38
- s.add_dependency(%q<addressable>, ["~> 2.0.1"])
37
+ s.add_dependency(%q<extlib>, ["~> 0.9.11"])
38
+ s.add_dependency(%q<addressable>, ["~> 2.0.2"])
39
39
  end
40
40
  end
data/lib/dm-core.rb CHANGED
@@ -16,15 +16,15 @@ require 'set'
16
16
  require 'time'
17
17
  require 'yaml'
18
18
 
19
- gem 'addressable', '~>2.0.1'
19
+ gem 'addressable', '~>2.0.2'
20
20
  require 'addressable/uri'
21
21
 
22
- gem 'extlib', '~>0.9.10'
22
+ gem 'extlib', '~>0.9.11'
23
23
  require 'extlib'
24
24
  require 'extlib/inflection'
25
25
 
26
26
  begin
27
- gem 'fastthread', '~>1.0.1'
27
+ gem 'fastthread', '~>1.0.4'
28
28
  require 'fastthread'
29
29
  rescue LoadError
30
30
  # fastthread not installed
@@ -171,7 +171,7 @@ module DataMapper
171
171
  # @demo spec/integration/repository_spec.rb
172
172
  def self.repository(name = nil) # :yields: current_context
173
173
  current_repository = if name
174
- raise ArgumentError, "First optional argument must be a Symbol, but was #{args.first.inspect}" unless name.is_a?(Symbol)
174
+ raise ArgumentError, "First optional argument must be a Symbol, but was #{name.inspect}" unless name.is_a?(Symbol)
175
175
  Repository.context.detect { |r| r.name == name } || Repository.new(name)
176
176
  else
177
177
  Repository.context.last || Repository.new(Repository.default_name)
@@ -3,20 +3,14 @@ dir = Pathname(__FILE__).dirname.expand_path / 'adapters'
3
3
  require dir / 'abstract_adapter'
4
4
  require dir / 'in_memory_adapter'
5
5
 
6
- # TODO Factor these out into dm-more
7
- require dir / 'data_objects_adapter'
8
- begin
9
- require dir / 'sqlite3_adapter'
10
- rescue LoadError
11
- # ignore it
12
- end
13
- begin
14
- require dir / 'mysql_adapter'
15
- rescue LoadError
16
- # ignore it
17
- end
18
- begin
19
- require dir / 'postgres_adapter'
20
- rescue LoadError
21
- # ignore it
6
+ # NOTE: this is a temporary work-around to the load error problems,
7
+ # and is better fixed in dm-core/next. The main reason the fix is
8
+ # not applied in dm-core/master is because the change is non-trivial.
9
+
10
+ %w[ data_objects sqlite3 mysql postgres ].each do |gem|
11
+ begin
12
+ require dir / "#{gem}_adapter"
13
+ rescue LoadError, Gem::Exception
14
+ # ignore it
15
+ end
22
16
  end
@@ -266,14 +266,21 @@ module DataMapper
266
266
  end
267
267
 
268
268
  def links_statement(query)
269
- table_name = query.model.storage_name(query.repository.name)
269
+ table_list = [query.model.storage_name(query.repository.name)]
270
270
 
271
271
  statement = ''
272
272
  query.links.each do |relationship|
273
273
  parent_table_name = relationship.parent_model.storage_name(query.repository.name)
274
274
  child_table_name = relationship.child_model.storage_name(query.repository.name)
275
275
 
276
- join_table_name = table_name == parent_table_name ? child_table_name : parent_table_name
276
+ join_table_name = if table_list.include?(parent_table_name)
277
+ child_table_name
278
+ elsif table_list.include?(child_table_name)
279
+ parent_table_name
280
+ else
281
+ raise ArgumentError, 'you\'re trying to join a table with no connection to this query'
282
+ end
283
+ table_list << join_table_name
277
284
 
278
285
  # We only do INNER JOIN for now
279
286
  statement << " INNER JOIN #{quote_table_name(join_table_name)} ON "
@@ -18,28 +18,28 @@ module DataMapper
18
18
  module Migration
19
19
  # TODO: move to dm-more/dm-migrations (if possible)
20
20
  def storage_exists?(storage_name)
21
- statement = <<-EOS.compress_lines
21
+ statement = <<-SQL.compress_lines
22
22
  SELECT COUNT(*)
23
- FROM "information_schema"."columns"
24
- WHERE "table_name" = ?
23
+ FROM "information_schema"."tables"
24
+ WHERE "table_type" = 'BASE TABLE'
25
25
  AND "table_schema" = current_schema()
26
- EOS
26
+ AND "table_name" = ?
27
+ SQL
27
28
 
28
29
  query(statement, storage_name).first > 0
29
30
  end
30
31
 
31
32
  # TODO: move to dm-more/dm-migrations (if possible)
32
33
  def field_exists?(storage_name, column_name)
33
- statement = <<-EOS.compress_lines
34
+ statement = <<-SQL.compress_lines
34
35
  SELECT COUNT(*)
35
- FROM "pg_class"
36
- JOIN "pg_attribute" ON "pg_class"."oid" = "pg_attribute"."attrelid"
37
- WHERE "pg_attribute"."attname" = ?
38
- AND "pg_class"."relname" = ?
39
- AND "pg_attribute"."attnum" >= 0
40
- EOS
41
-
42
- query(statement, column_name, storage_name).first > 0
36
+ FROM "information_schema"."columns"
37
+ WHERE "table_schema" = current_schema()
38
+ AND "table_name" = ?
39
+ AND "column_name" = ?
40
+ SQL
41
+
42
+ query(statement, storage_name, column_name).first > 0
43
43
  end
44
44
 
45
45
  # TODO: move to dm-more/dm-migrations
@@ -112,8 +112,9 @@ module DataMapper
112
112
  def sequence_exists?(repository, property)
113
113
  statement = <<-EOS.compress_lines
114
114
  SELECT COUNT(*)
115
- FROM "pg_class"
116
- WHERE "relkind" = 'S' AND "relname" = ?
115
+ FROM "information_schema"."sequences"
116
+ WHERE "sequence_name" = ?
117
+ AND "sequence_schema" = current_schema()
117
118
  EOS
118
119
 
119
120
  query(statement, sequence_name(repository, property)).first > 0
@@ -146,6 +146,13 @@ module DataMapper
146
146
  # @api public
147
147
  def belongs_to(name, options={})
148
148
  @_valid_relations = false
149
+
150
+ if options.key?(:class_name) && !options.key?(:child_key)
151
+ warn "The inferred child_key will changing to be prefixed with the relationship name #{name}. " \
152
+ "When using :class_name in belongs_to specify the :child_key explicitly to avoid problems." \
153
+ "#{caller(0)[1]}"
154
+ end
155
+
149
156
  relationship = ManyToOne.setup(name, self, options)
150
157
  # Please leave this in - I will release contextual serialization soon
151
158
  # which requires this -- guyvdb
@@ -67,7 +67,7 @@ module DataMapper
67
67
  EOS
68
68
 
69
69
  names.each do |n|
70
- model.belongs_to(Extlib::Inflection.underscore(n).gsub("/", "_").to_sym, :class_name => n)
70
+ model.belongs_to(Extlib::Inflection.underscore(n).gsub('/', '_').to_sym)
71
71
  end
72
72
 
73
73
  Object.const_set(model_name, model)
@@ -99,7 +99,7 @@ module DataMapper
99
99
 
100
100
  def push(*resources)
101
101
  assert_mutable
102
- resources.reject { |resource| !resource.new_record? && self.include?(resource) }
102
+ resources.reject! { |resource| !resource.new_record? && self.include?(resource) }
103
103
  children.push(*resources)
104
104
  resources.each { |resource| relate_resource(resource) }
105
105
  self
@@ -107,7 +107,7 @@ module DataMapper
107
107
 
108
108
  def unshift(*resources)
109
109
  assert_mutable
110
- resources.reject { |resource| !resource.new_record? && self.include?(resource) }
110
+ resources.reject! { |resource| !resource.new_record? && self.include?(resource) }
111
111
  children.unshift(*resources)
112
112
  resources.each { |resource| relate_resource(resource) }
113
113
  self
@@ -81,10 +81,8 @@ module DataMapper
81
81
 
82
82
  with_repository(child_model) do |r|
83
83
  parent_identity_map = parent.repository.identity_map(parent_model)
84
- child_identity_map = r.identity_map(child_model)
85
84
 
86
85
  query_values = parent_identity_map.keys
87
- query_values.reject! { |k| child_identity_map[k] }
88
86
 
89
87
  bind_values = query_values unless query_values.empty?
90
88
  query = child_key.zip(bind_values.transpose).to_hash
@@ -35,7 +35,9 @@ module DataMapper
35
35
  # @api public
36
36
  def reload(query = {})
37
37
  @query = scoped_query(query)
38
- @query.update(:fields => @query.fields | @key_properties)
38
+ inheritance_property = model.base_model.inheritance_property
39
+ fields = (@key_properties | [inheritance_property]).compact
40
+ @query.update(:fields => @query.fields | fields)
39
41
  replace(all(:reload => true))
40
42
  end
41
43
 
@@ -178,7 +178,7 @@ module DataMapper
178
178
  #
179
179
  def flush
180
180
  return unless @buffer.size > 0
181
- @log.write_method(@buffer.slice!(0..-1).to_s)
181
+ @log.write_method(@buffer.slice!(0..-1).join)
182
182
  end
183
183
 
184
184
  # Close and remove the current log object.
data/lib/dm-core/model.rb CHANGED
@@ -234,6 +234,10 @@ module DataMapper
234
234
  properties(repository_name).key
235
235
  end
236
236
 
237
+ def inheritance_property(repository_name = default_repository_name)
238
+ @properties[repository_name].detect { |property| property.type == DataMapper::Types::Discriminator }
239
+ end
240
+
237
241
  def default_order(repository_name = default_repository_name)
238
242
  @default_order ||= {}
239
243
  @default_order[repository_name] ||= key(repository_name).map { |property| Query::Direction.new(property) }
@@ -344,6 +348,9 @@ module DataMapper
344
348
  model = values.at(inheritance_property_index) || model
345
349
  end
346
350
 
351
+ key_values = nil
352
+ identity_map = nil
353
+
347
354
  if key_property_indexes = query.key_property_indexes(repository)
348
355
  key_values = values.values_at(*key_property_indexes)
349
356
  identity_map = repository.identity_map(model)
@@ -353,7 +360,6 @@ module DataMapper
353
360
  else
354
361
  resource = model.allocate
355
362
  resource.instance_variable_set(:@repository, repository)
356
- identity_map.set(key_values, resource)
357
363
  end
358
364
  else
359
365
  resource = model.allocate
@@ -376,6 +382,10 @@ module DataMapper
376
382
  end
377
383
  end
378
384
 
385
+ if key_values && identity_map
386
+ identity_map.set(key_values, resource)
387
+ end
388
+
379
389
  resource
380
390
  end
381
391
 
@@ -476,8 +486,9 @@ module DataMapper
476
486
  return DataMapper::Query::Path.new(repository, [ relationship ], klass)
477
487
  end
478
488
 
479
- if property = properties(repository_name)[method]
480
- return property
489
+ property_set = properties(repository_name)
490
+ if property_set.has_property?(method)
491
+ return property_set[method]
481
492
  end
482
493
 
483
494
  super
@@ -149,6 +149,11 @@ module DataMapper
149
149
 
150
150
  # Compares if its the same object or if attributes are equal
151
151
  #
152
+ # The comparaison is
153
+ # * false if object not from same repository
154
+ # * false if object has no all same properties
155
+ #
156
+ #
152
157
  # ==== Parameters
153
158
  # other<Object>:: Object to compare to
154
159
  #
@@ -158,15 +163,25 @@ module DataMapper
158
163
  # -
159
164
  # @api public
160
165
  def eql?(other)
161
- return true if object_id == other.object_id
166
+ return true if equal?(other)
167
+
168
+ # two instances for different models cannot be equivalent
162
169
  return false unless other.kind_of?(model)
163
- return true if repository == other.repository && key == other.key
164
170
 
165
- properties.each do |property|
166
- return false if property.get!(self) != property.get!(other)
171
+ # two instances with different keys cannot be equivalent
172
+ return false if key != other.key
173
+
174
+ # neither object has changed since loaded, so they are equivalent
175
+ return true if repository == other.repository && !dirty? && !other.dirty?
176
+
177
+ # get all the loaded and non-loaded properties that are not keys,
178
+ # since the key comparison was performed earlier
179
+ loaded, not_loaded = properties.select { |p| !p.key? }.partition do |property|
180
+ attribute_loaded?(property.name) && other.attribute_loaded?(property.name)
167
181
  end
168
182
 
169
- true
183
+ # check all loaded properties, and then all unloaded properties
184
+ (loaded + not_loaded).all? { |p| p.get(self) == p.get(other) }
170
185
  end
171
186
 
172
187
  alias == eql?
@@ -264,4 +264,4 @@ module DataMapper
264
264
  end
265
265
 
266
266
  end # class Transaction
267
- end # module DataMapper
267
+ end # module DataMapper
@@ -77,4 +77,4 @@ module DataMapper
77
77
  end
78
78
  end
79
79
  end # class TypeMap
80
- end # module DataMapper
80
+ end # module DataMapper
@@ -1,3 +1,3 @@
1
1
  module DataMapper
2
- VERSION = '0.9.10' unless defined?(DataMapper::VERSION)
2
+ VERSION = '0.9.11'.freeze
3
3
  end
@@ -12,7 +12,7 @@ require 'rbench'
12
12
  gem 'faker', '~>0.3.1'
13
13
  require 'faker'
14
14
 
15
- gem 'activerecord', '~>2.2.2'
15
+ gem 'activerecord', '~>2.3.2'
16
16
  require 'active_record'
17
17
 
18
18
  socket_file = Pathname.glob(%w[
data/script/profile.rb CHANGED
@@ -4,7 +4,7 @@ require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core')
4
4
 
5
5
  require 'rubygems'
6
6
 
7
- gem 'ruby-prof', '~>0.7.1'
7
+ gem 'ruby-prof', '~>0.7.3'
8
8
  require 'ruby-prof'
9
9
 
10
10
  gem 'faker', '~>0.3.1'
@@ -1100,7 +1100,6 @@ if ADAPTER
1100
1100
  customer.name == 'John Johnsen'
1101
1101
  end
1102
1102
  customers.size.should == 1
1103
- # another example can be found here: http://pastie.textmate.org/private/tt1hf1syfsytyxdgo4qxawfl
1104
1103
  end
1105
1104
 
1106
1105
  it 'should return the right children for has n => has 1 relationships' do
@@ -116,7 +116,7 @@ if HAS_SQLITE3
116
116
  }
117
117
 
118
118
  types.each do |name,(klass,type,nullable,default,key)|
119
- describe "a #{klass} property" do
119
+ describe "a #{klass} property (#{name})" do
120
120
  it "should be created as a #{type}" do
121
121
  @table_set[name.to_s].type.should == type
122
122
  end
@@ -228,7 +228,7 @@ if HAS_MYSQL
228
228
  }
229
229
 
230
230
  types.each do |name,(klass,type,nullable,default,key)|
231
- describe "a #{klass} property" do
231
+ describe "a #{klass} property (#{name})" do
232
232
  it "should be created as a #{type}" do
233
233
  @table_set[name.to_s].type.should == type
234
234
  end
@@ -372,7 +372,7 @@ if HAS_POSTGRES
372
372
  }
373
373
 
374
374
  types.each do |name,(klass,type,nullable,default,key)|
375
- describe "a #{Extlib::Inflection.classify(name.to_s)} property" do
375
+ describe "a #{klass} property (#{name})" do
376
376
  it "should be created as a #{type}" do
377
377
  @table_set[name.to_s].type.should == type
378
378
  end
@@ -1,11 +1,11 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
- if RUBY_VERSION >= '1.9.0'
4
- require 'csv'
5
- else
6
- gem 'fastercsv', '~>1.4.0'
7
- require 'fastercsv'
8
- end
3
+ # if RUBY_VERSION >= '1.9.0'
4
+ # require 'csv'
5
+ # else
6
+ # gem 'fastercsv', '~>1.4.0'
7
+ # require 'fastercsv'
8
+ # end
9
9
 
10
10
  describe DataMapper::Property do
11
11
  before do
@@ -9,6 +9,7 @@ if ADAPTER
9
9
  describe "DataMapper::Resource with #{ADAPTER}" do
10
10
 
11
11
  load_models_for_metaphor :zoo
12
+ load_models_for_metaphor :content
12
13
 
13
14
  before(:each) do
14
15
  DataMapper.auto_migrate!(ADAPTER)
@@ -59,12 +60,39 @@ if ADAPTER
59
60
  end
60
61
 
61
62
  describe '#eql?' do
62
- it "should return true if the objects are the same instances"
63
- it "should return false if the other object is not an instance of the same model"
64
- it "should return false if the other object is a different class"
63
+
64
+ it "should return true if the objects are the same instances" do
65
+ z = Zoo.first
66
+ z2 = z
67
+ z.should be_eql(z2)
68
+ end
69
+
70
+ it "should return false if the other object is not an instance of the same model" do
71
+ z = Zoo.first
72
+ z2 = Zoo.create(:name => 'New York')
73
+ z.should_not be_eql(z2)
74
+ end
75
+
76
+ it "should return false if the other object is a different class" do
77
+ z = Zoo.first
78
+ o = Content::Dialect.first
79
+ z.should_not be_eql(o)
80
+ end
81
+
65
82
  it "should return true if the repositories are the same and the primary key is the same"
66
- it "should return true if all the properties are the same"
67
- it "should return false if any of the properties are different"
83
+ it "should return false if the repository is not the same and the primary key is the same"
84
+
85
+ it "should return true if all the properties are the same" do
86
+ z = Zoo.first
87
+ z2 = Zoo.new(z.attributes.delete_if{|key, value| key == :mission})
88
+ z.should be_eql(z2)
89
+ end
90
+
91
+ it "should return false if any of the properties are different" do
92
+ z = Zoo.first
93
+ z2 = Zoo.new(z.attributes.delete_if{|key, value| key == :mission}.merge(:description => 'impressive'))
94
+ z.should_not be_eql(z2)
95
+ end
68
96
  end
69
97
 
70
98
  describe '#hash' do
@@ -162,127 +190,127 @@ end
162
190
 
163
191
  # ---------- Old specs... BOOOOOOOOOO ---------------
164
192
  if ADAPTER
165
- class Orange
166
- include DataMapper::Resource
193
+ describe "DataMapper::Resource with #{ADAPTER}" do
194
+ before :all do
195
+ class ::Orange
196
+ include DataMapper::Resource
167
197
 
168
- def self.default_repository_name
169
- ADAPTER
170
- end
198
+ def self.default_repository_name
199
+ ADAPTER
200
+ end
171
201
 
172
- property :name, String, :key => true
173
- property :color, String
174
- end
202
+ property :name, String, :key => true
203
+ property :color, String
204
+ end
175
205
 
176
- class Apple
177
- include DataMapper::Resource
206
+ class ::Apple
207
+ include DataMapper::Resource
178
208
 
179
- def self.default_repository_name
180
- ADAPTER
181
- end
209
+ def self.default_repository_name
210
+ ADAPTER
211
+ end
182
212
 
183
- property :id, Serial
184
- property :color, String, :default => 'green', :nullable => true
185
- end
213
+ property :id, Serial
214
+ property :color, String, :default => 'green', :nullable => true
215
+ end
186
216
 
187
- class FortunePig
188
- include DataMapper::Resource
217
+ class ::FortunePig
218
+ include DataMapper::Resource
189
219
 
190
- def self.default_repository_name
191
- ADAPTER
192
- end
220
+ def self.default_repository_name
221
+ ADAPTER
222
+ end
193
223
 
194
- property :id, Serial
195
- property :name, String
224
+ property :id, Serial
225
+ property :name, String
196
226
 
197
- def to_s
198
- name
199
- end
227
+ def to_s
228
+ name
229
+ end
200
230
 
201
- after :create do
202
- @created_id = self.id
203
- end
231
+ after :create do
232
+ @created_id = self.id
233
+ end
204
234
 
205
- after :save do
206
- @save_id = self.id
207
- end
208
- end
235
+ after :save do
236
+ @save_id = self.id
237
+ end
238
+ end
209
239
 
210
- class Car
211
- include DataMapper::Resource
240
+ class ::Car
241
+ include DataMapper::Resource
212
242
 
213
- def self.default_repository_name
214
- ADAPTER
215
- end
243
+ def self.default_repository_name
244
+ ADAPTER
245
+ end
216
246
 
217
- property :brand, String, :key => true
218
- property :color, String
219
- property :created_on, Date
220
- property :touched_on, Date
221
- property :updated_on, Date
247
+ property :brand, String, :key => true
248
+ property :color, String
249
+ property :created_on, Date
250
+ property :touched_on, Date
251
+ property :updated_on, Date
222
252
 
223
- before :save do
224
- self.touched_on = Date.today
225
- end
253
+ before :save do
254
+ self.touched_on = Date.today
255
+ end
226
256
 
227
- before :create do
228
- self.created_on = Date.today
229
- end
257
+ before :create do
258
+ self.created_on = Date.today
259
+ end
230
260
 
231
- before :update do
232
- self.updated_on = Date.today
233
- end
234
- end
261
+ before :update do
262
+ self.updated_on = Date.today
263
+ end
264
+ end
235
265
 
236
- class Male
237
- include DataMapper::Resource
266
+ class ::Male
267
+ include DataMapper::Resource
238
268
 
239
- def self.default_repository_name
240
- ADAPTER
241
- end
269
+ def self.default_repository_name
270
+ ADAPTER
271
+ end
242
272
 
243
- property :id, Serial
244
- property :name, String
245
- property :iq, Integer, :default => 100
246
- property :type, Discriminator
247
- property :data, Object
273
+ property :id, Serial
274
+ property :name, String
275
+ property :iq, Integer, :default => 100
276
+ property :type, Discriminator
277
+ property :data, Object
248
278
 
249
- def iq=(i)
250
- attribute_set(:iq, i - 1)
251
- end
252
- end
279
+ def iq=(i)
280
+ attribute_set(:iq, i - 1)
281
+ end
282
+ end
253
283
 
254
- class Bully < Male; end
284
+ class ::Bully < Male; end
255
285
 
256
- class Mugger < Bully; end
286
+ class ::Mugger < Bully; end
257
287
 
258
- class Maniac < Bully; end
288
+ class ::Maniac < Bully; end
259
289
 
260
- class Psycho < Maniac; end
290
+ class ::Psycho < Maniac; end
261
291
 
262
- class Geek < Male
263
- property :awkward, Boolean, :default => true
292
+ class ::Geek < Male
293
+ property :awkward, Boolean, :default => true
264
294
 
265
- def iq=(i)
266
- attribute_set(:iq, i + 30)
267
- end
268
- end
295
+ def iq=(i)
296
+ attribute_set(:iq, i + 30)
297
+ end
298
+ end
269
299
 
270
- class Flanimal
271
- include DataMapper::Resource
300
+ class ::Flanimal
301
+ include DataMapper::Resource
272
302
 
273
- def self.default_repository_name
274
- ADAPTER
275
- end
303
+ def self.default_repository_name
304
+ ADAPTER
305
+ end
276
306
 
277
- property :id, Serial
278
- property :type, Discriminator
279
- property :name, String
280
- end
307
+ property :id, Serial
308
+ property :type, Discriminator
309
+ property :name, String
310
+ end
281
311
 
282
- class Sprog < Flanimal; end
312
+ class ::Sprog < Flanimal; end
283
313
 
284
- describe "DataMapper::Resource with #{ADAPTER}" do
285
- before :all do
286
314
  Orange.auto_migrate!(ADAPTER)
287
315
  Apple.auto_migrate!(ADAPTER)
288
316
  FortunePig.auto_migrate!(ADAPTER)
@@ -14,6 +14,7 @@ if HAS_SQLITE3
14
14
  property :id, Serial
15
15
  property :title, String, :nullable => false
16
16
  property :isbn, Integer, :nullable => false
17
+ property :content, Text
17
18
  property :class_type, Discriminator
18
19
  end
19
20
 
@@ -226,5 +227,47 @@ if HAS_SQLITE3
226
227
  end
227
228
  end
228
229
  end
230
+
231
+ describe "with lazy property" do
232
+ before :all do
233
+ Book.auto_migrate!(:sqlite3)
234
+ repository(:sqlite3) do
235
+ ShortStory.create(
236
+ :title => "The Science of Happiness",
237
+ :isbn => "129038",
238
+ :content => 'This doesn\'t feel like a normal academic conference. True, the three-day Positive Psychology Summit i',
239
+ :moral => "Bullshit might get you to the top, but it won't keep you there."
240
+ )
241
+
242
+ ShortStory.create(
243
+ :title => "Blank as white paper",
244
+ :isbn => "129039",
245
+ :content => '',
246
+ :moral => "none."
247
+ )
248
+ end
249
+ end
250
+
251
+ it "should be able to access the properties from the parent collection" do
252
+ repository(:sqlite3) do
253
+ books = Book.all
254
+
255
+ books.each do |book|
256
+ book.title.should_not be_nil
257
+ book.isbn.should_not be_nil
258
+ book.moral.should_not be_nil
259
+ end
260
+
261
+ books[0].content
262
+
263
+ books.each do |book|
264
+ book.title.should_not be_nil
265
+ book.isbn.should_not be_nil
266
+ book.moral.should_not be_nil
267
+ end
268
+
269
+ end
270
+ end
271
+ end
229
272
  end
230
273
  end
@@ -1,11 +1,11 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
- if RUBY_VERSION >= '1.9.0'
4
- require 'csv'
5
- else
6
- gem 'fastercsv', '~>1.4.0'
7
- require 'fastercsv'
8
- end
3
+ # if RUBY_VERSION >= '1.9.0'
4
+ # require 'csv'
5
+ # else
6
+ # gem 'fastercsv', '~>1.4.0'
7
+ # require 'fastercsv'
8
+ # end
9
9
 
10
10
  if ADAPTER
11
11
  module ::TypeTests
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'pathname'
2
2
  require 'rubygems'
3
3
 
4
- gem 'rspec', '~>1.1.11'
4
+ gem 'rspec', '~>1.2'
5
5
  require 'spec'
6
6
 
7
7
  SPEC_ROOT = Pathname(__FILE__).dirname.expand_path
@@ -339,7 +339,7 @@ describe DataMapper::Adapters::DataObjectsAdapter do
339
339
 
340
340
  if method == :read_one
341
341
  it 'should return a DataMapper::Resource' do
342
- do_read.should == be_kind_of(DataMapper::Resource)
342
+ do_read.should be_kind_of(DataMapper::Resource)
343
343
  end
344
344
  else
345
345
  it 'should return a DataMapper::Collection' do
@@ -36,7 +36,7 @@ if HAS_POSTGRES
36
36
  end
37
37
 
38
38
  it 'should check to make sure the sequences exist' do
39
- statement = %q[SELECT COUNT(*) FROM "pg_class" WHERE "relkind" = 'S' AND "relname" = ?]
39
+ statement = %q[SELECT COUNT(*) FROM "information_schema"."sequences" WHERE "sequence_name" = ? AND "sequence_schema" = current_schema()]
40
40
  @adapter.should_receive(:query).with(statement, 'models_property_seq').and_return([ 0 ])
41
41
  @adapter.upgrade_model_storage(@repository, @model)
42
42
  end
@@ -78,7 +78,7 @@ if HAS_POSTGRES
78
78
  end
79
79
 
80
80
  it 'should check to make sure the sequences exist' do
81
- statement = %q[SELECT COUNT(*) FROM "pg_class" WHERE "relkind" = 'S' AND "relname" = ?]
81
+ statement = %q[SELECT COUNT(*) FROM "information_schema"."sequences" WHERE "sequence_name" = ? AND "sequence_schema" = current_schema()]
82
82
  @adapter.should_receive(:query).with(statement, 'models_property_seq').and_return([ 0 ])
83
83
  @adapter.create_model_storage(@repository, @model)
84
84
  end
@@ -231,11 +231,11 @@ describe "DataMapper::Associations" do
231
231
 
232
232
  it "should create a many-to-one association with options" do
233
233
  DataMapper::Associations::ManyToOne.should_receive(:setup).
234
- with(:vehicle, Manufacturer, { :class_name => 'Car' }).
234
+ with(:vehicle, Manufacturer, :class_name => 'Car', :child_key => [ :car_id ]).
235
235
  and_return(@relationship)
236
236
 
237
237
  class ::Manufacturer
238
- belongs_to(:vehicle, :class_name => 'Car').should == mock_relationship
238
+ belongs_to(:vehicle, :class_name => 'Car', :child_key => [ :car_id ]).should == mock_relationship
239
239
  end
240
240
  end
241
241
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.10
4
+ version: 0.9.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Kubb
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-19 00:00:00 -08:00
12
+ date: 2009-03-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.10
33
+ version: 0.9.11
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: addressable
@@ -40,7 +40,7 @@ dependencies:
40
40
  requirements:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
- version: 2.0.1
43
+ version: 2.0.2
44
44
  version:
45
45
  description: Faster, Better, Simpler.
46
46
  email: