datamapper 0.1.1 → 0.2.0

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 (131) hide show
  1. data/CHANGELOG +65 -0
  2. data/README +193 -1
  3. data/do_performance.rb +153 -0
  4. data/environment.rb +45 -0
  5. data/example.rb +119 -22
  6. data/lib/data_mapper.rb +36 -16
  7. data/lib/data_mapper/adapters/abstract_adapter.rb +8 -0
  8. data/lib/data_mapper/adapters/data_object_adapter.rb +360 -0
  9. data/lib/data_mapper/adapters/mysql_adapter.rb +30 -179
  10. data/lib/data_mapper/adapters/postgresql_adapter.rb +90 -199
  11. data/lib/data_mapper/adapters/sql/coersion.rb +32 -3
  12. data/lib/data_mapper/adapters/sql/commands/conditions.rb +97 -128
  13. data/lib/data_mapper/adapters/sql/commands/load_command.rb +234 -231
  14. data/lib/data_mapper/adapters/sql/commands/loader.rb +99 -0
  15. data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +30 -0
  16. data/lib/data_mapper/adapters/sql/mappings/column.rb +68 -6
  17. data/lib/data_mapper/adapters/sql/mappings/schema.rb +6 -3
  18. data/lib/data_mapper/adapters/sql/mappings/table.rb +71 -42
  19. data/lib/data_mapper/adapters/sql/quoting.rb +8 -2
  20. data/lib/data_mapper/adapters/sqlite3_adapter.rb +32 -201
  21. data/lib/data_mapper/associations.rb +21 -7
  22. data/lib/data_mapper/associations/belongs_to_association.rb +96 -80
  23. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +158 -67
  24. data/lib/data_mapper/associations/has_many_association.rb +96 -78
  25. data/lib/data_mapper/associations/has_n_association.rb +64 -0
  26. data/lib/data_mapper/associations/has_one_association.rb +49 -79
  27. data/lib/data_mapper/associations/reference.rb +47 -0
  28. data/lib/data_mapper/base.rb +216 -50
  29. data/lib/data_mapper/callbacks.rb +71 -24
  30. data/lib/data_mapper/{session.rb → context.rb} +20 -8
  31. data/lib/data_mapper/database.rb +176 -45
  32. data/lib/data_mapper/embedded_value.rb +65 -0
  33. data/lib/data_mapper/identity_map.rb +12 -4
  34. data/lib/data_mapper/support/active_record_impersonation.rb +12 -8
  35. data/lib/data_mapper/support/enumerable.rb +8 -0
  36. data/lib/data_mapper/support/serialization.rb +13 -0
  37. data/lib/data_mapper/support/string.rb +1 -12
  38. data/lib/data_mapper/support/symbol.rb +3 -0
  39. data/lib/data_mapper/validations/unique_validator.rb +1 -2
  40. data/lib/data_mapper/validations/validation_helper.rb +18 -1
  41. data/performance.rb +109 -34
  42. data/plugins/can_has_sphinx/LICENSE +23 -0
  43. data/plugins/can_has_sphinx/README +4 -0
  44. data/plugins/can_has_sphinx/REVISION +1 -0
  45. data/plugins/can_has_sphinx/Rakefile +22 -0
  46. data/plugins/can_has_sphinx/init.rb +1 -0
  47. data/plugins/can_has_sphinx/install.rb +1 -0
  48. data/plugins/can_has_sphinx/lib/acts_as_sphinx.rb +123 -0
  49. data/plugins/can_has_sphinx/lib/sphinx.rb +460 -0
  50. data/plugins/can_has_sphinx/scripts/sphinx.sh +47 -0
  51. data/plugins/can_has_sphinx/tasks/acts_as_sphinx_tasks.rake +41 -0
  52. data/plugins/dataobjects/REVISION +1 -0
  53. data/plugins/dataobjects/Rakefile +7 -0
  54. data/plugins/dataobjects/do.rb +246 -0
  55. data/plugins/dataobjects/do_mysql.rb +179 -0
  56. data/plugins/dataobjects/do_postgres.rb +181 -0
  57. data/plugins/dataobjects/do_sqlite3.rb +153 -0
  58. data/plugins/dataobjects/spec/do_spec.rb +150 -0
  59. data/plugins/dataobjects/spec/spec_helper.rb +81 -0
  60. data/plugins/dataobjects/swig_mysql/do_mysql.bundle +0 -0
  61. data/plugins/dataobjects/swig_mysql/extconf.rb +33 -0
  62. data/plugins/dataobjects/swig_mysql/mysql_c.c +18800 -0
  63. data/plugins/dataobjects/swig_mysql/mysql_c.i +8 -0
  64. data/plugins/dataobjects/swig_mysql/mysql_supp.i +46 -0
  65. data/plugins/dataobjects/swig_postgres/Makefile +146 -0
  66. data/plugins/dataobjects/swig_postgres/extconf.rb +29 -0
  67. data/plugins/dataobjects/swig_postgres/postgres_c.bundle +0 -0
  68. data/plugins/dataobjects/swig_postgres/postgres_c.c +8185 -0
  69. data/plugins/dataobjects/swig_postgres/postgres_c.i +73 -0
  70. data/plugins/dataobjects/swig_sqlite/db +0 -0
  71. data/plugins/dataobjects/swig_sqlite/extconf.rb +9 -0
  72. data/plugins/dataobjects/swig_sqlite/sqlite3_c.c +4725 -0
  73. data/plugins/dataobjects/swig_sqlite/sqlite_c.i +168 -0
  74. data/rakefile.rb +45 -23
  75. data/spec/acts_as_tree_spec.rb +39 -0
  76. data/spec/associations_spec.rb +220 -0
  77. data/spec/attributes_spec.rb +15 -0
  78. data/spec/base_spec.rb +44 -0
  79. data/spec/callbacks_spec.rb +45 -0
  80. data/spec/can_has_sphinx.rb +6 -0
  81. data/spec/coersion_spec.rb +34 -0
  82. data/spec/conditions_spec.rb +49 -0
  83. data/spec/conversions_to_yaml_spec.rb +17 -0
  84. data/spec/count_command_spec.rb +11 -0
  85. data/spec/delete_command_spec.rb +1 -1
  86. data/spec/embedded_value_spec.rb +23 -0
  87. data/spec/fixtures/animals_exhibits.yaml +2 -0
  88. data/spec/fixtures/people.yaml +18 -1
  89. data/spec/{legacy.rb → legacy_spec.rb} +3 -3
  90. data/spec/load_command_spec.rb +157 -20
  91. data/spec/magic_columns_spec.rb +9 -0
  92. data/spec/mock_adapter.rb +20 -0
  93. data/spec/models/animal.rb +1 -1
  94. data/spec/models/animals_exhibit.rb +6 -0
  95. data/spec/models/exhibit.rb +2 -0
  96. data/spec/models/person.rb +26 -1
  97. data/spec/models/project.rb +19 -0
  98. data/spec/models/sales_person.rb +1 -0
  99. data/spec/models/section.rb +6 -0
  100. data/spec/models/zoo.rb +3 -1
  101. data/spec/query_spec.rb +9 -0
  102. data/spec/save_command_spec.rb +65 -1
  103. data/spec/schema_spec.rb +89 -0
  104. data/spec/single_table_inheritance_spec.rb +27 -0
  105. data/spec/spec_helper.rb +9 -55
  106. data/spec/{symbolic_operators.rb → symbolic_operators_spec.rb} +9 -5
  107. data/spec/{validates_confirmation_of.rb → validates_confirmation_of_spec.rb} +4 -3
  108. data/spec/{validates_format_of.rb → validates_format_of_spec.rb} +5 -4
  109. data/spec/{validates_length_of.rb → validates_length_of_spec.rb} +8 -7
  110. data/spec/{validates_uniqueness_of.rb → validates_uniqueness_of_spec.rb} +7 -10
  111. data/spec/{validations.rb → validations_spec.rb} +24 -6
  112. data/tasks/drivers.rb +20 -0
  113. data/tasks/fixtures.rb +42 -0
  114. metadata +181 -42
  115. data/lib/data_mapper/adapters/sql/commands/advanced_load_command.rb +0 -140
  116. data/lib/data_mapper/adapters/sql/commands/delete_command.rb +0 -113
  117. data/lib/data_mapper/adapters/sql/commands/save_command.rb +0 -141
  118. data/lib/data_mapper/adapters/sql/commands/table_exists_command.rb +0 -33
  119. data/lib/data_mapper/adapters/sql_adapter.rb +0 -163
  120. data/lib/data_mapper/associations/advanced_has_many_association.rb +0 -55
  121. data/lib/data_mapper/support/blank_slate.rb +0 -3
  122. data/lib/data_mapper/support/proc.rb +0 -69
  123. data/lib/data_mapper/support/struct.rb +0 -26
  124. data/lib/data_mapper/unit_of_work.rb +0 -38
  125. data/spec/basic_finder.rb +0 -67
  126. data/spec/belongs_to.rb +0 -47
  127. data/spec/has_and_belongs_to_many.rb +0 -25
  128. data/spec/has_many.rb +0 -34
  129. data/spec/new_record.rb +0 -24
  130. data/spec/sub_select.rb +0 -16
  131. data/spec/support/string_spec.rb +0 -7
@@ -1,55 +0,0 @@
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
@@ -1,3 +0,0 @@
1
- class BlankSlate #:nodoc:
2
- instance_methods.each { |m| undef_method m unless m =~ /^(__|instance_eval)/ }
3
- end
@@ -1,69 +0,0 @@
1
- require File.dirname(__FILE__) + '/blank_slate'
2
-
3
- class Proc
4
-
5
- # Yeah, all this is kinda the suck.
6
- def to_hash
7
- Conditions.new(&self).__to_hash__
8
- end
9
-
10
- class Conditions < BlankSlate
11
-
12
- def initialize(&block)
13
- @block = block
14
- @conditions = []
15
- end
16
-
17
- def method_missing(sym, *args)
18
- attribute = Attribute.new(sym)
19
- @conditions << attribute
20
- attribute
21
- end
22
-
23
- def __to_hash__
24
- instance_eval(&@block)
25
- @conditions.inject({}) do |h,attribute|
26
- h[attribute.__operator__] = *attribute.__args__; h
27
- end
28
- end
29
-
30
- class Attribute < BlankSlate
31
-
32
- def initialize(message)
33
- @message = message
34
- @args = nil
35
- @operator = nil
36
- end
37
-
38
- def method_missing(sym, *args)
39
- op = case sym
40
- when :==, :===, :in then :eql
41
- when :=~ then :like
42
- when :"<=>" then :not
43
- when :< then :lt
44
- when :<= then :lte
45
- when :> then :gt
46
- when :>= then :gte
47
- else sym
48
- end
49
-
50
- @operator = Symbol::Operator.new(@message, op)
51
- @args = args
52
- end
53
-
54
- def __operator__
55
- @operator
56
- end
57
-
58
- def __args__
59
- @args
60
- end
61
-
62
- def __message__
63
- @message
64
- end
65
-
66
- end
67
-
68
- end
69
- end
@@ -1,26 +0,0 @@
1
- module DataMapper
2
- module Support
3
- class Struct
4
-
5
- def self.define(raw_fields)
6
-
7
- normalized_fields = raw_fields.map { |field| Inflector.underscore(field).to_sym }
8
-
9
- Class.new(self) do
10
- define_method(:fields) do
11
- normalized_fields
12
- end
13
- end
14
- end
15
-
16
- def initialize(values)
17
- @values = values
18
- end
19
-
20
- def method_missing(sym, *args)
21
- @values[fields.index(sym)]
22
- end
23
-
24
- end # class Struct
25
- end # module Support
26
- end # module DataMapper
@@ -1,38 +0,0 @@
1
- module DataMapper
2
-
3
- # Should this track relations?
4
- module UnitOfWork
5
-
6
- def new_record?
7
- @new_record.nil? || @new_record
8
- end
9
-
10
- def dirty?(name = nil)
11
- if name.nil?
12
- session.schema[self.class].columns.any? { |column| self.instance_variable_get(column.instance_variable_name).hash != original_hashes[column.name] }
13
- else
14
- key = name.kind_of?(Symbol) ? name : name.to_sym
15
- self.instance_variable_get("@#{name}").hash != original_hashes[key]
16
- end
17
- end
18
-
19
- def dirty_attributes
20
- if new_record?
21
- session.schema[self.class].columns.reject do |column|
22
- instance_variable_get(column.instance_variable_name).nil?
23
- end
24
- else
25
- session.schema[self.class].columns.select do |column|
26
- column.name != :id && instance_variable_get(column.instance_variable_name).hash != original_hashes[column.name]
27
- end
28
- end.inject({}) do |fields, column|
29
- fields[column.name] = instance_variable_get(column.instance_variable_name); fields
30
- end
31
- end
32
-
33
- def original_hashes
34
- @original_hashes || (@original_hashes = {})
35
- end
36
- end
37
-
38
- end
data/spec/basic_finder.rb DELETED
@@ -1,67 +0,0 @@
1
- context 'Finder' do
2
-
3
- specify 'database-specific load should not fail' do
4
-
5
- DataMapper::database do |db|
6
- froggy = db.first(Animal, :conditions => ['name = ?', 'Frog'])
7
- froggy.name.should == 'Frog'
8
- end
9
-
10
- end
11
-
12
- specify 'current-database load should not fail' do
13
- froggy = DataMapper::database.first(Animal).name.should == 'Frog'
14
- end
15
-
16
- specify 'load through ActiveRecord impersonation should not fail' do
17
- Animal.find(:all).size.should == 16
18
- end
19
-
20
- specify 'load through Og impersonation should not fail' do
21
- Animal.all.size.should == 16
22
- end
23
-
24
- specify ':conditions option should accept a hash' do
25
- Animal.all(:conditions => { :name => 'Frog' }).size.should == 1
26
- end
27
-
28
- specify 'non-standard options should be considered part of the conditions' do
29
- database.log.debug('non-standard options should be considered part of the conditions')
30
- zebra = Animal.first(:name => 'Zebra')
31
- zebra.name.should == 'Zebra'
32
-
33
- elephant = Animal[:name => 'Elephant']
34
- elephant.name.should == 'Elephant'
35
-
36
- aged = Person.all(:age => 29)
37
- aged.size.should == 2
38
- aged.first.name.should == 'Sam'
39
- aged.last.name.should == 'Bob'
40
-
41
- fixtures(:animals)
42
- end
43
-
44
- specify 'should not find deleted objects' do
45
- database do
46
- wally = Animal[:name => 'Whale']
47
- wally.destroy!.should == true
48
-
49
- wallys_evil_twin = Animal[:name => 'Whale']
50
- wallys_evil_twin.should == nil
51
-
52
- wally.new_record?.should == true
53
- wally.save
54
-
55
- Animal[:name => 'Whale'].should == wally
56
- end
57
- end
58
-
59
- specify 'lazy-loads should issue for whole sets' do
60
- people = Person.all
61
-
62
- people.each do |person|
63
- person.notes
64
- end
65
- end
66
-
67
- end
data/spec/belongs_to.rb DELETED
@@ -1,47 +0,0 @@
1
- context 'An Exhibit' do
2
-
3
- setup do
4
- @aviary = Exhibit[:name => 'Monkey Mayhem']
5
- end
6
-
7
- specify 'has a zoo association' do
8
- @aviary.zoo.class.should == Zoo
9
- Exhibit.new.zoo.should == nil
10
- end
11
-
12
- specify 'belongs to a zoo' do
13
- database do |db|
14
- @aviary.zoo.should == @aviary.session.first(Zoo, :name => 'San Diego')
15
- end
16
- end
17
-
18
- specify 'can build its zoo' do
19
- database do |db|
20
- e = Exhibit.new({:name => 'Super Extra Crazy Monkey Cage'})
21
- e.zoo.should == nil
22
- e.build_zoo({:name => 'Monkey Zoo'})
23
- e.zoo.class == Zoo
24
- e.zoo.new_record?.should == true
25
-
26
- # Need to get associations working properly before this works ....
27
- e.save
28
- end
29
- end
30
-
31
- specify 'can build its zoo' do
32
- database do |db|
33
- e = Exhibit.new({:name => 'Super Extra Crazy Monkey Cage'})
34
- e.zoo.should == nil
35
- e.create_zoo({:name => 'Monkey Zoo'})
36
- e.zoo.class == Zoo
37
- e.zoo.new_record?.should == false
38
- e.save
39
- end
40
- end
41
-
42
- teardown do
43
- fixtures('zoos')
44
- fixtures('exhibits')
45
- end
46
-
47
- end
@@ -1,25 +0,0 @@
1
- # context 'An Exhibit' do
2
- #
3
- # setup do
4
- # @amazonia = Exhibit[:name => 'Amazonia']
5
- # end
6
- #
7
- # specify 'has an animals association' do
8
- # [@amazonia, Exhibit.new].each do |exhibit|
9
- # exhibit.animals.class.should == DataMapper::Associations::HasAndBelongsToManyAssociation
10
- # end
11
- # end
12
- #
13
- # specify 'has many animals' do
14
- # @amazonia.animals.size.should == 2
15
- # end
16
- #
17
- # specify 'should load associations magically' do
18
- # Exhibit.all.each do |exhibit|
19
- # exhibit.animals.each do |animal|
20
- # animal.exhibits.should.include?(exhibit)
21
- # end
22
- # end
23
- # end
24
- #
25
- # end
data/spec/has_many.rb DELETED
@@ -1,34 +0,0 @@
1
- describe DataMapper::Associations::HasManyAssociation do
2
-
3
- before(:all) do
4
- fixtures(:zoos)
5
- fixtures(:exhibits)
6
-
7
- @san_diego = Zoo[:name => 'San Diego']
8
- @dallas = Zoo[:name => 'Dallas']
9
- @miami = Zoo[:name => 'Miami']
10
- end
11
-
12
- it 'should expose a proxy for the accessor' do
13
- [@miami, Zoo.new].each do |z|
14
- z.exhibits.class.should == DataMapper::Associations::HasManyAssociation
15
- end
16
- end
17
-
18
- it 'should lazily-load the association when Enumerable methods are called' do
19
- database do |db|
20
- @san_diego.exhibits.size.should == 2
21
- @san_diego.exhibits.should include(@san_diego.session.first(Exhibit, :name => 'Monkey Mayhem'))
22
- end
23
- end
24
-
25
- it 'should eager-load associations for an entire set' do
26
- zoos = Zoo.all
27
- zoos.each do |zoo|
28
- zoo.exhibits.each do |exhibit|
29
- exhibit.zoo.should == zoo
30
- end
31
- end
32
- end
33
-
34
- end
data/spec/new_record.rb DELETED
@@ -1,24 +0,0 @@
1
- context 'A new record' do
2
-
3
- setup do
4
- @bob = Person.new(:name => 'Bob', :age => 30, :occupation => 'Sales')
5
- end
6
-
7
- specify 'should be dirty' do
8
- @bob.dirty?.should == true
9
- end
10
-
11
- specify 'set attributes should be dirty' do
12
- attributes = @bob.attributes.dup.reject { |k,v| k == :id }
13
- @bob.dirty_attributes.should == { :name => 'Bob', :age => 30, :occupation => 'Sales' }
14
- end
15
-
16
- specify 'should be marked as new' do
17
- @bob.new_record?.should == true
18
- end
19
-
20
- specify 'should have a nil id' do
21
- @bob.id.should == nil
22
- end
23
-
24
- end
data/spec/sub_select.rb DELETED
@@ -1,16 +0,0 @@
1
- =begin
2
- context 'Sub-selection' do
3
-
4
- specify 'should return a Cup' do
5
- Animal[:id.select => { :name => 'cup' }].name.should == 'Cup'
6
- end
7
-
8
- specify 'should return all exhibits for Galveston zoo' do
9
- Exhibit.all(:zoo_id.select(Zoo) => { :name => 'Galveston' }).size.should == 3
10
- end
11
-
12
- specify 'should allow a sub-select in the select-list' do
13
- Animal[:select => [ :id.count ]]
14
- end
15
- end
16
- =end
@@ -1,7 +0,0 @@
1
- describe DataMapper::Support::String do
2
-
3
- it 'should underscore camel-cased words' do
4
- String::memoized_underscore('DataMapper').should == 'data_mapper'
5
- end
6
-
7
- end