datamapper-dm-core 0.9.11 → 0.10.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 (192) hide show
  1. data/.autotest +17 -14
  2. data/.gitignore +3 -1
  3. data/FAQ +6 -5
  4. data/History.txt +5 -39
  5. data/Manifest.txt +67 -76
  6. data/QUICKLINKS +1 -1
  7. data/README.txt +21 -15
  8. data/Rakefile +16 -15
  9. data/SPECS +2 -29
  10. data/TODO +1 -1
  11. data/dm-core.gemspec +11 -15
  12. data/lib/dm-core/adapters/abstract_adapter.rb +182 -185
  13. data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
  14. data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
  15. data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
  16. data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
  17. data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
  18. data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
  19. data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
  20. data/lib/dm-core/adapters.rb +135 -16
  21. data/lib/dm-core/associations/many_to_many.rb +372 -90
  22. data/lib/dm-core/associations/many_to_one.rb +220 -73
  23. data/lib/dm-core/associations/one_to_many.rb +319 -255
  24. data/lib/dm-core/associations/one_to_one.rb +66 -53
  25. data/lib/dm-core/associations/relationship.rb +560 -158
  26. data/lib/dm-core/collection.rb +1104 -381
  27. data/lib/dm-core/core_ext/kernel.rb +12 -0
  28. data/lib/dm-core/core_ext/symbol.rb +10 -0
  29. data/lib/dm-core/identity_map.rb +4 -34
  30. data/lib/dm-core/migrations.rb +1283 -0
  31. data/lib/dm-core/model/descendant_set.rb +81 -0
  32. data/lib/dm-core/model/hook.rb +45 -0
  33. data/lib/dm-core/model/is.rb +32 -0
  34. data/lib/dm-core/model/property.rb +248 -0
  35. data/lib/dm-core/model/relationship.rb +335 -0
  36. data/lib/dm-core/model/scope.rb +90 -0
  37. data/lib/dm-core/model.rb +570 -369
  38. data/lib/dm-core/property.rb +753 -280
  39. data/lib/dm-core/property_set.rb +141 -98
  40. data/lib/dm-core/query/conditions/comparison.rb +814 -0
  41. data/lib/dm-core/query/conditions/operation.rb +247 -0
  42. data/lib/dm-core/query/direction.rb +43 -0
  43. data/lib/dm-core/query/operator.rb +42 -0
  44. data/lib/dm-core/query/path.rb +102 -0
  45. data/lib/dm-core/query/sort.rb +45 -0
  46. data/lib/dm-core/query.rb +974 -492
  47. data/lib/dm-core/repository.rb +147 -107
  48. data/lib/dm-core/resource.rb +644 -429
  49. data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
  50. data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
  51. data/lib/dm-core/support/chainable.rb +20 -0
  52. data/lib/dm-core/support/deprecate.rb +12 -0
  53. data/lib/dm-core/support/equalizer.rb +23 -0
  54. data/lib/dm-core/support/logger.rb +13 -0
  55. data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
  56. data/lib/dm-core/transaction.rb +333 -92
  57. data/lib/dm-core/type.rb +98 -60
  58. data/lib/dm-core/types/boolean.rb +1 -1
  59. data/lib/dm-core/types/discriminator.rb +34 -20
  60. data/lib/dm-core/types/object.rb +7 -4
  61. data/lib/dm-core/types/paranoid_boolean.rb +11 -9
  62. data/lib/dm-core/types/paranoid_datetime.rb +11 -9
  63. data/lib/dm-core/types/serial.rb +3 -3
  64. data/lib/dm-core/types/text.rb +3 -4
  65. data/lib/dm-core/version.rb +1 -1
  66. data/lib/dm-core.rb +106 -110
  67. data/script/performance.rb +102 -109
  68. data/script/profile.rb +169 -38
  69. data/spec/lib/adapter_helpers.rb +105 -0
  70. data/spec/lib/collection_helpers.rb +18 -0
  71. data/spec/lib/counter_adapter.rb +34 -0
  72. data/spec/lib/pending_helpers.rb +27 -0
  73. data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
  74. data/spec/public/associations/many_to_many_spec.rb +193 -0
  75. data/spec/public/associations/many_to_one_spec.rb +73 -0
  76. data/spec/public/associations/one_to_many_spec.rb +77 -0
  77. data/spec/public/associations/one_to_one_spec.rb +156 -0
  78. data/spec/public/collection_spec.rb +65 -0
  79. data/spec/public/model/relationship_spec.rb +924 -0
  80. data/spec/public/model_spec.rb +159 -0
  81. data/spec/public/property_spec.rb +829 -0
  82. data/spec/public/resource_spec.rb +71 -0
  83. data/spec/public/sel_spec.rb +44 -0
  84. data/spec/public/setup_spec.rb +145 -0
  85. data/spec/public/shared/association_collection_shared_spec.rb +317 -0
  86. data/spec/public/shared/collection_shared_spec.rb +1723 -0
  87. data/spec/public/shared/finder_shared_spec.rb +1619 -0
  88. data/spec/public/shared/resource_shared_spec.rb +924 -0
  89. data/spec/public/shared/sel_shared_spec.rb +112 -0
  90. data/spec/public/transaction_spec.rb +129 -0
  91. data/spec/public/types/discriminator_spec.rb +130 -0
  92. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  93. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
  94. data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
  95. data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
  96. data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
  97. data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
  98. data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
  99. data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
  100. data/spec/semipublic/associations/relationship_spec.rb +194 -0
  101. data/spec/semipublic/associations_spec.rb +177 -0
  102. data/spec/semipublic/collection_spec.rb +142 -0
  103. data/spec/semipublic/property_spec.rb +61 -0
  104. data/spec/semipublic/query/conditions_spec.rb +528 -0
  105. data/spec/semipublic/query/path_spec.rb +443 -0
  106. data/spec/semipublic/query_spec.rb +2626 -0
  107. data/spec/semipublic/resource_spec.rb +47 -0
  108. data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
  109. data/spec/spec.opts +3 -1
  110. data/spec/spec_helper.rb +80 -57
  111. data/tasks/ci.rb +19 -31
  112. data/tasks/dm.rb +43 -48
  113. data/tasks/doc.rb +8 -11
  114. data/tasks/gemspec.rb +5 -5
  115. data/tasks/hoe.rb +15 -16
  116. data/tasks/install.rb +8 -10
  117. metadata +72 -93
  118. data/lib/dm-core/associations/relationship_chain.rb +0 -81
  119. data/lib/dm-core/associations.rb +0 -207
  120. data/lib/dm-core/auto_migrations.rb +0 -105
  121. data/lib/dm-core/dependency_queue.rb +0 -32
  122. data/lib/dm-core/hook.rb +0 -11
  123. data/lib/dm-core/is.rb +0 -16
  124. data/lib/dm-core/logger.rb +0 -232
  125. data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
  126. data/lib/dm-core/migrator.rb +0 -29
  127. data/lib/dm-core/scope.rb +0 -58
  128. data/lib/dm-core/support/array.rb +0 -13
  129. data/lib/dm-core/support/assertions.rb +0 -8
  130. data/lib/dm-core/support/errors.rb +0 -23
  131. data/lib/dm-core/support/kernel.rb +0 -11
  132. data/lib/dm-core/support/symbol.rb +0 -41
  133. data/lib/dm-core/support.rb +0 -7
  134. data/lib/dm-core/type_map.rb +0 -80
  135. data/lib/dm-core/types.rb +0 -19
  136. data/script/all +0 -4
  137. data/spec/integration/association_spec.rb +0 -1382
  138. data/spec/integration/association_through_spec.rb +0 -203
  139. data/spec/integration/associations/many_to_many_spec.rb +0 -449
  140. data/spec/integration/associations/many_to_one_spec.rb +0 -163
  141. data/spec/integration/associations/one_to_many_spec.rb +0 -188
  142. data/spec/integration/auto_migrations_spec.rb +0 -413
  143. data/spec/integration/collection_spec.rb +0 -1073
  144. data/spec/integration/data_objects_adapter_spec.rb +0 -32
  145. data/spec/integration/dependency_queue_spec.rb +0 -46
  146. data/spec/integration/model_spec.rb +0 -197
  147. data/spec/integration/mysql_adapter_spec.rb +0 -85
  148. data/spec/integration/postgres_adapter_spec.rb +0 -731
  149. data/spec/integration/property_spec.rb +0 -253
  150. data/spec/integration/query_spec.rb +0 -514
  151. data/spec/integration/repository_spec.rb +0 -61
  152. data/spec/integration/resource_spec.rb +0 -513
  153. data/spec/integration/sqlite3_adapter_spec.rb +0 -352
  154. data/spec/integration/sti_spec.rb +0 -273
  155. data/spec/integration/strategic_eager_loading_spec.rb +0 -156
  156. data/spec/integration/transaction_spec.rb +0 -75
  157. data/spec/integration/type_spec.rb +0 -275
  158. data/spec/lib/logging_helper.rb +0 -18
  159. data/spec/lib/mock_adapter.rb +0 -27
  160. data/spec/lib/model_loader.rb +0 -100
  161. data/spec/lib/publicize_methods.rb +0 -28
  162. data/spec/models/content.rb +0 -16
  163. data/spec/models/vehicles.rb +0 -34
  164. data/spec/models/zoo.rb +0 -48
  165. data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
  166. data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
  167. data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
  168. data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
  169. data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
  170. data/spec/unit/associations/many_to_many_spec.rb +0 -32
  171. data/spec/unit/associations/many_to_one_spec.rb +0 -159
  172. data/spec/unit/associations/one_to_many_spec.rb +0 -393
  173. data/spec/unit/associations/one_to_one_spec.rb +0 -7
  174. data/spec/unit/associations/relationship_spec.rb +0 -71
  175. data/spec/unit/associations_spec.rb +0 -242
  176. data/spec/unit/auto_migrations_spec.rb +0 -111
  177. data/spec/unit/collection_spec.rb +0 -182
  178. data/spec/unit/data_mapper_spec.rb +0 -35
  179. data/spec/unit/identity_map_spec.rb +0 -126
  180. data/spec/unit/is_spec.rb +0 -80
  181. data/spec/unit/migrator_spec.rb +0 -33
  182. data/spec/unit/model_spec.rb +0 -321
  183. data/spec/unit/naming_conventions_spec.rb +0 -36
  184. data/spec/unit/property_set_spec.rb +0 -90
  185. data/spec/unit/property_spec.rb +0 -753
  186. data/spec/unit/query_spec.rb +0 -571
  187. data/spec/unit/repository_spec.rb +0 -93
  188. data/spec/unit/resource_spec.rb +0 -649
  189. data/spec/unit/scope_spec.rb +0 -142
  190. data/spec/unit/transaction_spec.rb +0 -493
  191. data/spec/unit/type_map_spec.rb +0 -114
  192. data/spec/unit/type_spec.rb +0 -119
@@ -0,0 +1,112 @@
1
+ share_examples_for 'A Collection supporting Strategic Eager Loading' do
2
+ describe 'using SEL when looping within a loop' do
3
+ before :all do
4
+ @many_to_many = @articles.kind_of?(DataMapper::Associations::ManyToMany::Collection)
5
+ end
6
+
7
+ before :all do
8
+ attributes = {}
9
+
10
+ unless @many_to_many
11
+ attributes[:author] = @author
12
+ end
13
+
14
+ @revision = @article.revisions.create(attributes.merge(:title => 'Revision'))
15
+
16
+ @new_article = @article_model.create(attributes.merge(:title => 'Sample Article'))
17
+ @new_revision = @new_article.revisions.create(attributes.merge(:title => 'New Revision'))
18
+ end
19
+
20
+ before :all do
21
+ @original_adapter = @adapter
22
+
23
+ @adapter.meta_class.class_eval do
24
+ def eql?(other)
25
+ super || self == other
26
+ end
27
+ end
28
+
29
+ @adapter = DataMapper::Repository.adapters[@adapter.name] = CounterAdapter.new(@adapter)
30
+ @repository.instance_variable_set(:@adapter, @adapter)
31
+ end
32
+
33
+ before :all do
34
+ @results = []
35
+
36
+ @articles.each do |article|
37
+ article.revisions.each do |revision|
38
+ @results << [ article, revision ]
39
+ end
40
+ end
41
+ end
42
+
43
+ after :all do
44
+ @adapter = @original_adapter
45
+ end
46
+
47
+ it "should only execute the Adapter#read #{loaded ? 'once' : 'twice'}" do
48
+ @adapter.counts[:read].should == (loaded ? 1 : 2)
49
+ end
50
+
51
+ it 'should return the expected results' do
52
+ # if the collection is already loaded, then when it iterates it will
53
+ # not know about the newly added articles and their revisions
54
+ if loaded
55
+ @results.should == [ [ @article, @revision ] ]
56
+ else
57
+ pending_if 'TODO: make m:m not kick when delegating to the relationship', @many_to_many do
58
+ @results.should == [ [ @article, @revision ], [ @new_article, @new_revision ] ]
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ share_examples_for 'A Resource supporting Strategic Eager Loading' do
66
+ describe 'using SEL when inside a Collection' do
67
+ before :all do
68
+ @referrer = @user_model.create(:name => 'Referrer', :comment => @comment)
69
+
70
+ @user.update(:referrer => @referrer)
71
+
72
+ @new_user = @user_model.create(:name => 'Another User', :referrer => @referrer, :comment => @comment)
73
+ end
74
+
75
+ before :all do
76
+ @original_adapter = @adapter
77
+
78
+ @adapter.meta_class.class_eval do
79
+ def eql?(other)
80
+ super || other == self
81
+ end
82
+ end
83
+
84
+ @adapter = DataMapper::Repository.adapters[@adapter.name] = CounterAdapter.new(@adapter)
85
+ @repository.instance_variable_set(:@adapter, @adapter)
86
+ end
87
+
88
+ before :all do
89
+ @results = []
90
+
91
+ @user_model.all.each do |user|
92
+ @results << [ user, user.referrer ]
93
+ end
94
+
95
+ # some storage engines return the data in a different order
96
+ @results.sort!
97
+ end
98
+
99
+ after :all do
100
+ @adapter = @original_adapter
101
+ end
102
+
103
+ it 'should only execute the Adapter#read twice' do
104
+ @adapter.counts[:read].should == 2
105
+ end
106
+
107
+ it 'should return the expected results' do
108
+ # results are ordered alphabetically by the User name
109
+ @results.should == [ [ @new_user, @referrer ], [ @referrer, nil ], [ @user, @referrer ] ]
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,129 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe DataMapper::Resource, 'Transactions' do
4
+ before :all do
5
+ module ::Blog
6
+ class User
7
+ include DataMapper::Resource
8
+
9
+ property :name, String, :key => true
10
+ property :age, Integer
11
+ property :summary, Text
12
+ property :description, Text
13
+ property :admin, Boolean, :accessor => :private
14
+
15
+ belongs_to :referrer, self, :nullable => true
16
+ has n, :comments
17
+
18
+ # FIXME: figure out a different approach than stubbing things out
19
+ def comment=(*)
20
+ # do nothing with comment
21
+ end
22
+ end
23
+
24
+ class Author < User; end
25
+
26
+ class Comment
27
+ include DataMapper::Resource
28
+
29
+ property :id, Serial
30
+ property :body, Text
31
+
32
+ belongs_to :user
33
+ end
34
+
35
+ class Article
36
+ include DataMapper::Resource
37
+
38
+ property :id, Serial
39
+ property :body, Text
40
+
41
+ has n, :paragraphs
42
+ end
43
+
44
+ class Paragraph
45
+ include DataMapper::Resource
46
+
47
+ property :id, Serial
48
+ property :text, String
49
+
50
+ belongs_to :article
51
+ end
52
+ end
53
+
54
+ @user_model = Blog::User
55
+ @author_model = Blog::Author
56
+ @comment_model = Blog::Comment
57
+ @article_model = Blog::Article
58
+ @paragraph_model = Blog::Paragraph
59
+ end
60
+
61
+ supported_by :postgres, :mysql, :sqlite3, :oracle do
62
+ before :all do
63
+ user = @user_model.create(:name => 'dbussink', :age => 25, :description => 'Test')
64
+
65
+ @user = @user_model.get(*user.key)
66
+ end
67
+
68
+ before do
69
+ # --- Temporary private api use to get around rspec limitations ---
70
+ @repository.scope do |repository|
71
+ transaction = DataMapper::Transaction.new(repository)
72
+ transaction.begin
73
+ repository.adapter.push_transaction(transaction)
74
+ end
75
+ end
76
+
77
+ after do
78
+ while @repository.adapter.current_transaction
79
+ @repository.adapter.pop_transaction.rollback
80
+ end
81
+ end
82
+
83
+ it_should_behave_like 'A public Resource'
84
+ it_should_behave_like 'A Resource supporting Strategic Eager Loading'
85
+ end
86
+
87
+ supported_by :postgres, :mysql, :sqlite3, :oracle do
88
+ describe '#transaction' do
89
+ before do
90
+ @user_model.all.destroy!
91
+ end
92
+
93
+ it 'should have access to resources presisted before the transaction' do
94
+ @user_model.create(:name => 'carllerche')
95
+ @user_model.transaction do
96
+ @user_model.first.name.should == 'carllerche'
97
+ end
98
+ end
99
+
100
+ it 'should have access to resources persisted in the transaction' do
101
+ @user_model.transaction do
102
+ @user_model.create(:name => 'carllerche')
103
+ @user_model.first.name.should == 'carllerche'
104
+ end
105
+ end
106
+
107
+ it 'should not mark saved resources as new records' do
108
+ @user_model.transaction do
109
+ @user_model.create(:name => 'carllerche').should_not be_new
110
+ end
111
+ end
112
+
113
+ it 'should rollback when an error is thrown in a transaction' do
114
+ @user_model.all.should have(0).entries
115
+ lambda {
116
+ @user_model.transaction do
117
+ @user_model.create(:name => 'carllerche')
118
+ raise 'I love coffee'
119
+ end
120
+ }.should raise_error('I love coffee')
121
+ @user_model.all.should have(0).entries
122
+ end
123
+
124
+ it 'should return the last statement in the transaction block' do
125
+ @user_model.transaction { 1 }.should == 1
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,130 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe DataMapper::Types::Discriminator do
4
+ before :all do
5
+ module ::Blog
6
+ class Article
7
+ include DataMapper::Resource
8
+
9
+ property :id, Serial
10
+ property :title, String, :nullable => false
11
+ property :type, Discriminator
12
+ end
13
+
14
+ class Announcement < Article; end
15
+ class Release < Announcement; end
16
+ end
17
+
18
+ @article_model = Blog::Article
19
+ @announcement_model = Blog::Announcement
20
+ @release_model = Blog::Release
21
+ end
22
+
23
+ it 'should typecast to a Model' do
24
+ @article_model.properties[:type].typecast('Blog::Release').should equal(@release_model)
25
+ end
26
+
27
+ describe 'Model#new' do
28
+ describe 'when provided a String discriminator in the attributes' do
29
+ before :all do
30
+ @resource = @article_model.new(:type => 'Blog::Release')
31
+ end
32
+
33
+ it 'should return a Resource' do
34
+ @resource.should be_kind_of(DataMapper::Resource)
35
+ end
36
+
37
+ it 'should be an descendant instance' do
38
+ @resource.should be_instance_of(Blog::Release)
39
+ end
40
+ end
41
+
42
+ describe 'when provided a Class discriminator in the attributes' do
43
+ before :all do
44
+ @resource = @article_model.new(:type => Blog::Release)
45
+ end
46
+
47
+ it 'should return a Resource' do
48
+ @resource.should be_kind_of(DataMapper::Resource)
49
+ end
50
+
51
+ it 'should be an descendant instance' do
52
+ @resource.should be_instance_of(Blog::Release)
53
+ end
54
+ end
55
+
56
+ describe 'when not provided a discriminator in the attributes' do
57
+ before :all do
58
+ @resource = @article_model.new
59
+ end
60
+
61
+ it 'should return a Resource' do
62
+ @resource.should be_kind_of(DataMapper::Resource)
63
+ end
64
+
65
+ it 'should be a base model instance' do
66
+ @resource.should be_instance_of(@article_model)
67
+ end
68
+ end
69
+ end
70
+
71
+ describe 'Model#descendants' do
72
+ it 'should set the descendants for the grandparent model' do
73
+ @article_model.descendants.to_a.should == [ @article_model, @announcement_model, @release_model ]
74
+ end
75
+
76
+ it 'should set the descendants for the parent model' do
77
+ @announcement_model.descendants.to_a.should == [ @announcement_model, @release_model ]
78
+ end
79
+
80
+ it 'should set the descendants for the child model' do
81
+ @release_model.descendants.to_a.should == [ @release_model ]
82
+ end
83
+ end
84
+
85
+ describe 'Model#default_scope' do
86
+ it 'should set the default scope for the grandparent model' do
87
+ @article_model.default_scope[:type].should equal(@article_model.descendants)
88
+ end
89
+
90
+ it 'should set the default scope for the parent model' do
91
+ @announcement_model.default_scope[:type].should equal(@announcement_model.descendants)
92
+ end
93
+
94
+ it 'should set the default scope for the child model' do
95
+ @release_model.default_scope[:type].should equal(@release_model.descendants)
96
+ end
97
+ end
98
+
99
+ supported_by :all do
100
+ before :all do
101
+ @skip = defined?(DataMapper::Adapters::YamlAdapter) && @adapter.kind_of?(DataMapper::Adapters::YamlAdapter)
102
+ end
103
+
104
+ before do
105
+ pending if @skip
106
+ end
107
+
108
+ before :all do
109
+ rescue_if 'TODO: fix YAML serialization/deserialization', @skip do
110
+ @announcement = @announcement_model.create(:title => 'Announcement')
111
+ end
112
+ end
113
+
114
+ it 'should persist the type' do
115
+ @announcement.model.get(*@announcement.key).type.should equal(@announcement_model)
116
+ end
117
+
118
+ it 'should be retrieved as an instance of the correct class' do
119
+ @announcement.model.get(*@announcement.key).should be_instance_of(@announcement_model)
120
+ end
121
+
122
+ it 'should include descendants in finders' do
123
+ @article_model.first.should eql(@announcement)
124
+ end
125
+
126
+ it 'should not include ancestors' do
127
+ @release_model.first.should be_nil
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,30 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ describe 'AbstractAdapter' do
4
+ before :all do
5
+ @adapter = DataMapper::Adapters::AbstractAdapter.new(:abstract, :foo => 'bar')
6
+ @adapter_class = @adapter.class
7
+ @scheme = Extlib::Inflection.underscore(Extlib::Inflection.demodulize(@adapter_class).chomp('Adapter'))
8
+ @adapter_name = "test_#{@scheme}".to_sym
9
+ end
10
+
11
+ describe 'initialization' do
12
+
13
+ describe 'name' do
14
+ it 'should have a name' do
15
+ @adapter.name.should == :abstract
16
+ end
17
+ end
18
+
19
+ it 'should set options' do
20
+ @adapter.options.should == {:foo => 'bar'}
21
+ end
22
+
23
+ it 'should set naming conventions' do
24
+ @adapter.resource_naming_convention.should == DataMapper::NamingConventions::Resource::UnderscoredAndPluralized
25
+ @adapter.field_naming_convention.should == DataMapper::NamingConventions::Field::Underscored
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+ require DataMapper.root / 'lib' / 'dm-core' / 'spec' / 'adapter_shared_spec'
3
+
4
+ describe 'Adapter' do
5
+ supported_by :in_memory do
6
+ describe DataMapper::Adapters::InMemoryAdapter do
7
+
8
+ it_should_behave_like 'An Adapter'
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ dir = DataMapper.root / 'lib' / 'dm-core' / 'spec'
4
+
5
+ require dir / 'adapter_shared_spec'
6
+ require dir / 'data_objects_adapter_shared_spec'
7
+
8
+ describe 'Adapter' do
9
+ supported_by :mysql do
10
+ describe DataMapper::Adapters::MysqlAdapter do
11
+
12
+ it_should_behave_like 'An Adapter'
13
+ it_should_behave_like 'A DataObjects Adapter'
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,194 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ dir = DataMapper.root / 'lib' / 'dm-core' / 'spec'
4
+
5
+ require dir / 'adapter_shared_spec'
6
+ require dir / 'data_objects_adapter_shared_spec'
7
+
8
+ module SQLLogHelper
9
+ class SQLLogger
10
+ attr_accessor :buffer
11
+ def initialize
12
+ @buffer = ""
13
+ end
14
+
15
+ def level; 0; end
16
+
17
+ def debug(string)
18
+ @buffer << string << "\n"
19
+ # puts "#{string.gsub(/\n/m,"<br/>\n")}<br/>"
20
+ end
21
+ end
22
+
23
+ def start_sql_log!
24
+ return if @sql_log_on
25
+ @sql_log_on = true
26
+ @old_logger = DataObjects::Oracle.logger
27
+ DataObjects::Oracle.logger = SQLLogger.new
28
+ end
29
+
30
+ def stop_sql_log!
31
+ return unless @sql_log_on
32
+ @sql_log_on = nil
33
+ DataObjects::Oracle.logger = @old_logger
34
+ end
35
+
36
+ def clear_sql_log!
37
+ return unless @sql_log_on
38
+ DataObjects::Oracle.logger.buffer = ""
39
+ end
40
+
41
+ def sql_log_buffer
42
+ DataObjects::Oracle.logger.buffer
43
+ end
44
+ end
45
+
46
+ describe 'Adapter' do
47
+ supported_by :oracle do
48
+ describe DataMapper::Adapters::OracleAdapter do
49
+
50
+ it_should_behave_like 'An Adapter'
51
+ it_should_behave_like 'A DataObjects Adapter'
52
+
53
+ describe "sequences" do
54
+ include SQLLogHelper
55
+
56
+ before(:all) do
57
+ @auto_migrate_with = DataMapper::Adapters::OracleAdapter.auto_migrate_with
58
+ DataMapper::Adapters::OracleAdapter.auto_migrate_with :drop_and_create
59
+ start_sql_log!
60
+ end
61
+
62
+ after(:all) do
63
+ stop_sql_log!
64
+ DataMapper::Adapters::OracleAdapter.auto_migrate_with @auto_migrate_with
65
+ end
66
+
67
+ describe "create default sequence and trigger" do
68
+ before(:all) do
69
+ class ::Employee
70
+ include DataMapper::Resource
71
+ property :employee_id, Serial
72
+ end
73
+ Employee.auto_migrate!
74
+ end
75
+
76
+ after(:all) do
77
+ Employee.auto_migrate_down!
78
+ end
79
+
80
+ it "should not have sequence name in options" do
81
+ Employee.properties[:employee_id].options[:sequence].should be_nil
82
+ end
83
+
84
+ it "should create default sequence" do
85
+ sql_log_buffer.should =~ /CREATE SEQUENCE "EMPLOYEES_SEQ"/
86
+ end
87
+
88
+ it "should create trigger" do
89
+ sql_log_buffer.should =~ /CREATE OR REPLACE TRIGGER "EMPLOYEES_PKT"/
90
+ end
91
+
92
+ end
93
+
94
+ describe "create custom sequence" do
95
+
96
+ before(:all) do
97
+ class ::Employee
98
+ include DataMapper::Resource
99
+ property :employee_id, Serial, :sequence => "emp_seq"
100
+ end
101
+ Employee.auto_migrate!
102
+ end
103
+
104
+ after(:all) do
105
+ Employee.auto_migrate_down!
106
+ end
107
+
108
+ it "should have custom sequence name" do
109
+ Employee.properties[:employee_id].options[:sequence].should == "emp_seq"
110
+ end
111
+
112
+ it "should create custom sequence" do
113
+ sql_log_buffer.should =~ /CREATE SEQUENCE "EMP_SEQ"/
114
+ end
115
+
116
+ it "should not create trigger" do
117
+ sql_log_buffer.should_not =~ /TRIGGER/
118
+ end
119
+
120
+ end
121
+
122
+ describe "create custom sequence in non-default repository" do
123
+
124
+ before(:all) do
125
+ stop_sql_log!
126
+ DataMapper.setup :oracle, DataMapper::Repository.adapters[:default].options
127
+ start_sql_log!
128
+ class ::Employee
129
+ include DataMapper::Resource
130
+ property :id, Serial
131
+ repository(:oracle) do
132
+ property :id, Serial, :field => "employee_id", :sequence => "emp_seq"
133
+ end
134
+ end
135
+ repository(:oracle) do
136
+ Employee.auto_migrate!
137
+ end
138
+ end
139
+
140
+ after(:all) do
141
+ repository(:oracle) do
142
+ Employee.auto_migrate_down!
143
+ end
144
+ end
145
+
146
+ it "should have custom sequence name" do
147
+ Employee.properties(:oracle)[:id].options[:sequence].should == "emp_seq"
148
+ end
149
+
150
+ it "should create custom sequence" do
151
+ sql_log_buffer.should =~ /CREATE SEQUENCE "EMP_SEQ"/
152
+ end
153
+
154
+ it "should not create trigger" do
155
+ sql_log_buffer.should_not =~ /TRIGGER/
156
+ end
157
+
158
+ end
159
+
160
+ describe "prefetch key value from custom sequence" do
161
+
162
+ before(:all) do
163
+ class ::Employee
164
+ include DataMapper::Resource
165
+ property :employee_id, Serial, :sequence => "emp_seq"
166
+ property :first_name, String
167
+ end
168
+ Employee.auto_migrate!
169
+ end
170
+
171
+ after(:all) do
172
+ Employee.auto_migrate_down!
173
+ end
174
+
175
+ it "should prefetch sequence value when inserting new record" do
176
+ e = Employee.create
177
+ e.employee_id.should == 1
178
+ e = Employee.create(:first_name => "Raimonds")
179
+ e.employee_id.should == 2
180
+ end
181
+
182
+ it "should insert explicitly specified primary key value" do
183
+ e = Employee.create(:employee_id => 100,:first_name => "Raimonds")
184
+ e.employee_id.should == 100
185
+ end
186
+
187
+ end
188
+
189
+
190
+ end
191
+
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ dir = DataMapper.root / 'lib' / 'dm-core' / 'spec'
4
+
5
+ require dir / 'adapter_shared_spec'
6
+ require dir / 'data_objects_adapter_shared_spec'
7
+
8
+ describe 'Adapter' do
9
+ supported_by :postgres do
10
+ describe DataMapper::Adapters::PostgresAdapter do
11
+
12
+ it_should_behave_like 'An Adapter'
13
+ it_should_behave_like 'A DataObjects Adapter'
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+
3
+ dir = DataMapper.root / 'lib' / 'dm-core' / 'spec'
4
+
5
+ require dir / 'adapter_shared_spec'
6
+ require dir / 'data_objects_adapter_shared_spec'
7
+
8
+ describe 'Adapter' do
9
+ supported_by :sqlite3 do
10
+ describe DataMapper::Adapters::Sqlite3Adapter do
11
+
12
+ it_should_behave_like 'An Adapter'
13
+ it_should_behave_like 'A DataObjects Adapter'
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_helper'))
2
+ require DataMapper.root / 'lib' / 'dm-core' / 'spec' / 'adapter_shared_spec'
3
+
4
+ describe 'Adapter' do
5
+ supported_by :yaml do
6
+ describe DataMapper::Adapters::YamlAdapter do
7
+
8
+ it_should_behave_like 'An Adapter'
9
+
10
+ end
11
+ end
12
+ end