dm-core 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/History.txt +25 -5
  2. data/Manifest.txt +1 -0
  3. data/README.txt +67 -23
  4. data/Rakefile +0 -2
  5. data/deps.rip +1 -1
  6. data/dm-core.gemspec +6 -6
  7. data/lib/dm-core/adapters/abstract_adapter.rb +3 -76
  8. data/lib/dm-core/adapters/data_objects_adapter.rb +8 -39
  9. data/lib/dm-core/associations/many_to_many.rb +28 -16
  10. data/lib/dm-core/associations/many_to_one.rb +1 -45
  11. data/lib/dm-core/associations/one_to_many.rb +1 -38
  12. data/lib/dm-core/associations/relationship.rb +43 -20
  13. data/lib/dm-core/collection.rb +33 -32
  14. data/lib/dm-core/model/property.rb +8 -8
  15. data/lib/dm-core/model/relationship.rb +10 -12
  16. data/lib/dm-core/property.rb +20 -85
  17. data/lib/dm-core/property_set.rb +8 -8
  18. data/lib/dm-core/query/conditions/comparison.rb +13 -71
  19. data/lib/dm-core/query/conditions/operation.rb +73 -47
  20. data/lib/dm-core/query/operator.rb +3 -45
  21. data/lib/dm-core/query/path.rb +5 -41
  22. data/lib/dm-core/query.rb +37 -108
  23. data/lib/dm-core/repository.rb +3 -79
  24. data/lib/dm-core/resource.rb +54 -49
  25. data/lib/dm-core/support/chainable.rb +0 -2
  26. data/lib/dm-core/support/equalizer.rb +23 -0
  27. data/lib/dm-core/types/object.rb +4 -4
  28. data/lib/dm-core/version.rb +1 -1
  29. data/lib/dm-core.rb +3 -11
  30. data/spec/public/model/relationship_spec.rb +4 -4
  31. data/spec/public/property_spec.rb +5 -449
  32. data/spec/public/sel_spec.rb +52 -2
  33. data/spec/public/shared/collection_shared_spec.rb +79 -26
  34. data/spec/public/shared/finder_shared_spec.rb +6 -6
  35. data/spec/public/shared/resource_shared_spec.rb +2 -2
  36. data/spec/semipublic/property_spec.rb +524 -9
  37. data/spec/semipublic/query_spec.rb +6 -6
  38. data/tasks/hoe.rb +2 -2
  39. metadata +24 -4
@@ -21,7 +21,7 @@ module DataMapper
21
21
  # @deprecated
22
22
  def self.descendants
23
23
  warn "DataMapper::Resource.descendants is deprecated, use DataMapper::Model.descendants instead (#{caller[0]})"
24
- DataMapper::Model.descendants
24
+ Model.descendants
25
25
  end
26
26
 
27
27
  # Deprecated API for updating attributes and saving Resource
@@ -118,6 +118,16 @@ module DataMapper
118
118
  @saved == true
119
119
  end
120
120
 
121
+ # Checks if this Resource instance is destroyed
122
+ #
123
+ # @return [Boolean]
124
+ # true if the resource has been destroyed
125
+ #
126
+ # @api public
127
+ def destroyed?
128
+ @destroyed == true
129
+ end
130
+
121
131
  # Checks if the resource has no changes to save
122
132
  #
123
133
  # @return [Boolean]
@@ -283,7 +293,7 @@ module DataMapper
283
293
  # @api public
284
294
  def reload
285
295
  if saved?
286
- reload_attributes(loaded_properties)
296
+ eager_load(loaded_properties)
287
297
  child_relationships.each { |relationship| relationship.get!(self).reload }
288
298
  end
289
299
 
@@ -364,13 +374,13 @@ module DataMapper
364
374
  # @api public
365
375
  def destroy!
366
376
  if saved? && repository.delete(Collection.new(query, [ self ])) == 1
377
+ @destroyed = true
367
378
  @collection.delete(self) if @collection
368
379
  reset
369
380
  freeze
370
- true
371
- else
372
- false
373
381
  end
382
+
383
+ destroyed?
374
384
  end
375
385
 
376
386
  # Compares another Resource for equality
@@ -388,9 +398,7 @@ module DataMapper
388
398
  # @api public
389
399
  def eql?(other)
390
400
  return true if equal?(other)
391
- return false unless instance_of?(other.class)
392
-
393
- cmp?(other, :eql?)
401
+ instance_of?(other.class) && cmp?(other, :eql?)
394
402
  end
395
403
 
396
404
  # Compares another Resource for equivalency
@@ -408,8 +416,8 @@ module DataMapper
408
416
  # @api public
409
417
  def ==(other)
410
418
  return true if equal?(other)
411
- return false unless other.respond_to?(:model) && model.base_model.equal?(other.model.base_model)
412
-
419
+ other.respond_to?(:model) &&
420
+ model.base_model.equal?(other.model.base_model) &&
413
421
  cmp?(other, :==)
414
422
  end
415
423
 
@@ -429,7 +437,7 @@ module DataMapper
429
437
  raise ArgumentError, "Cannot compare a #{other.model} instance with a #{model} instance"
430
438
  end
431
439
  cmp = 0
432
- model.default_order(repository_name).map do |direction|
440
+ model.default_order(repository_name).each do |direction|
433
441
  cmp = direction.get(self) <=> direction.get(other)
434
442
  break if cmp != 0
435
443
  end
@@ -506,27 +514,6 @@ module DataMapper
506
514
  properties[name].loaded?(self)
507
515
  end
508
516
 
509
- # Fetches all the names of the attributes that have been loaded,
510
- # even if they are lazy but have been called
511
- #
512
- # @example
513
- # class Foo
514
- # include DataMapper::Resource
515
- #
516
- # property :name, String
517
- # property :description, Text, :lazy => false
518
- # end
519
- #
520
- # Foo.new.loaded_properties #=> [ #<Property @model=Foo @name=:name> ]
521
- #
522
- # @return [Array(Property)]
523
- # names of attributes that have been loaded
524
- #
525
- # @api private
526
- def loaded_properties
527
- properties.select { |property| property.loaded?(self) }
528
- end
529
-
530
517
  # Checks if an attribute has unsaved changes
531
518
  #
532
519
  # @param [Symbol] name
@@ -690,10 +677,9 @@ module DataMapper
690
677
  model.relationships(repository_name)
691
678
  end
692
679
 
693
- # Returns identity map of repository this object
694
- # was loaded from
680
+ # Returns the identity map for the model from the repository
695
681
  #
696
- # @return [DataMapper::IdentityMap]
682
+ # @return [IdentityMap]
697
683
  # identity map of repository this object was loaded from
698
684
  #
699
685
  # @api semipublic
@@ -701,26 +687,41 @@ module DataMapper
701
687
  repository.identity_map(model)
702
688
  end
703
689
 
704
- # Reloads attributes that belong to given lazy loading
705
- # context, and not yet loaded
690
+ # Fetches all the names of the attributes that have been loaded,
691
+ # even if they are lazy but have been called
692
+ #
693
+ # @return [Array<Property>]
694
+ # names of attributes that have been loaded
706
695
  #
707
696
  # @api private
708
- def lazy_load(property_names)
709
- reload_attributes(properties.in_context(property_names) - loaded_properties)
697
+ def loaded_properties
698
+ properties.select { |property| property.loaded?(self) }
699
+ end
700
+
701
+ # Lazy loads attributes not yet loaded
702
+ #
703
+ # @param [Array<Property>] fields
704
+ # the properties to reload
705
+ #
706
+ # @return [self]
707
+ #
708
+ # @api private
709
+ def lazy_load(fields)
710
+ eager_load(fields - loaded_properties)
710
711
  end
711
712
 
712
713
  # Reloads specified attributes
713
714
  #
714
- # @param [Enumerable(Symbol)] attributes
715
- # name(s) of attribute(s) to reload
715
+ # @param [Array<Property>] fields
716
+ # the properties to reload
716
717
  #
717
718
  # @return [Resource]
718
719
  # the receiver, the current Resource instance
719
720
  #
720
721
  # @api private
721
- def reload_attributes(attributes)
722
- unless attributes.empty? || new?
723
- collection.reload(:fields => attributes)
722
+ def eager_load(fields)
723
+ unless fields.empty? || new?
724
+ collection.reload(:fields => fields)
724
725
  end
725
726
 
726
727
  self
@@ -751,9 +752,9 @@ module DataMapper
751
752
  parent_relationships
752
753
  end
753
754
 
754
- # Returns array of child relationships for which this resource is parent and is loaded
755
+ # Returns loaded child relationships
755
756
  #
756
- # @return [Array<DataMapper::Associations::OneToMany::Relationship>]
757
+ # @return [Array<Associations::OneToMany::Relationship>]
757
758
  # array of child relationships for which this resource is parent and is loaded
758
759
  #
759
760
  # @api private
@@ -770,14 +771,13 @@ module DataMapper
770
771
  end
771
772
 
772
773
  many_to_many, other = child_relationships.partition do |relationship|
773
- relationship.kind_of?(DataMapper::Associations::ManyToMany::Relationship)
774
+ relationship.kind_of?(Associations::ManyToMany::Relationship)
774
775
  end
775
776
 
776
777
  many_to_many + other
777
778
  end
778
779
 
779
- # Saves this Resource instance to the repository,
780
- # setting default values for any unset properties
780
+ # Creates the resource with default values
781
781
  #
782
782
  # If resource is not dirty or a new (not yet saved),
783
783
  # this method returns false
@@ -878,6 +878,11 @@ module DataMapper
878
878
 
879
879
  # Raises an exception if #update is performed on a dirty resource
880
880
  #
881
+ # @param [Symbol] method
882
+ # the name of the method to use in the exception
883
+ #
884
+ # @return [undefined]
885
+ #
881
886
  # @raise [UpdateConflictError]
882
887
  # raise if the resource is dirty
883
888
  #
@@ -1,5 +1,3 @@
1
- # TODO: move this to Extlib::Chainable
2
-
3
1
  module DataMapper
4
2
  module Chainable
5
3
 
@@ -0,0 +1,23 @@
1
+ module DataMapper
2
+ module Equalizer
3
+ def equalize(*methods)
4
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
5
+ def eql?(other)
6
+ return true if equal?(other)
7
+ instance_of?(other.class) &&
8
+ #{methods.map { |method| "#{method}.eql?(other.#{method})" }.join(' && ')}
9
+ end
10
+
11
+ def ==(other)
12
+ return true if equal?(other)
13
+ #{methods.map { |method| "other.respond_to?(#{method.inspect})" }.join(' && ')} &&
14
+ #{methods.map { |method| "#{method} == other.#{method}" }.join(' && ')}
15
+ end
16
+
17
+ def hash
18
+ [ #{methods.join(', ')} ].hash
19
+ end
20
+ RUBY
21
+ end
22
+ end
23
+ end
@@ -2,8 +2,8 @@ module DataMapper
2
2
  module Types
3
3
  class Object < Type
4
4
  primitive String
5
- size 65535
6
- lazy true
5
+ length 65535
6
+ lazy true
7
7
 
8
8
  # TODO: document
9
9
  # @api private
@@ -14,13 +14,13 @@ module DataMapper
14
14
  # TODO: document
15
15
  # @api private
16
16
  def self.dump(value, property)
17
- Base64.encode64(Marshal.dump(value))
17
+ [ Marshal.dump(value) ].pack('m')
18
18
  end
19
19
 
20
20
  # TODO: document
21
21
  # @api private
22
22
  def self.load(value, property)
23
- value.nil? ? nil : Marshal.load(Base64.decode64(value))
23
+ Marshal.load(value.unpack('m').first) unless value.nil?
24
24
  end
25
25
  end
26
26
  end
@@ -1,3 +1,3 @@
1
1
  module DataMapper
2
- VERSION = '0.10.0'.freeze
2
+ VERSION = '0.10.1'.freeze
3
3
  end
data/lib/dm-core.rb CHANGED
@@ -1,13 +1,4 @@
1
- # This file begins the loading sequence.
2
- #
3
- # Quick Overview:
4
- # * Requires fastthread, support libs, and base.
5
- # * Sets the application root and environment for compatibility with frameworks
6
- # such as Rails or Merb.
7
- #
8
-
9
1
  require 'addressable/uri'
10
- require 'base64'
11
2
  require 'bigdecimal'
12
3
  require 'bigdecimal/util'
13
4
  require 'date'
@@ -27,6 +18,7 @@ dir = Pathname(__FILE__).dirname.expand_path / 'dm-core'
27
18
 
28
19
  require dir / 'support' / 'chainable'
29
20
  require dir / 'support' / 'deprecate'
21
+ require dir / 'support' / 'equalizer'
30
22
 
31
23
  require dir / 'model'
32
24
  require dir / 'model' / 'descendant_set'
@@ -117,9 +109,9 @@ DataMapper::Logger.new(StringIO.new, :fatal)
117
109
  # === Logging
118
110
  # To turn on error logging to STDOUT, issue:
119
111
  #
120
- # DataMapper::Logger.new(STDOUT, :debug)
112
+ # DataMapper::Logger.new($stdout, :debug)
121
113
  #
122
- # You can pass a file location ("/path/to/log/file.log") in place of STDOUT.
114
+ # You can pass a file location ("/path/to/log/file.log") in place of $stdout.
123
115
  # see DataMapper::Logger for more information.
124
116
  #
125
117
  module DataMapper
@@ -799,8 +799,8 @@ describe DataMapper::Associations do
799
799
  @engine_relationship = ElectricCar.relationships(@repository.name)[:engine]
800
800
  end
801
801
 
802
- it 'should have a source model equal to the descendant' do
803
- @engine_relationship.source_model.should equal(ElectricCar)
802
+ it 'should have a source model equal to the ancestor' do
803
+ @engine_relationship.source_model.should equal(Car)
804
804
  end
805
805
 
806
806
  it 'should have a child key prefix the same as the inverse relationship' do
@@ -823,8 +823,8 @@ describe DataMapper::Associations do
823
823
  @engine_relationship = ElectricCar.relationships(@repository.name)[:engine]
824
824
  end
825
825
 
826
- it 'should have a source model equal to the descendant' do
827
- @engine_relationship.source_model.should equal(ElectricCar)
826
+ it 'should have a source model equal to the ancestor' do
827
+ @engine_relationship.source_model.should equal(Car)
828
828
  end
829
829
 
830
830
  it 'should have a child key prefix inferred from the source model name' do