dm-core 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/.autotest +26 -0
  2. data/{CHANGELOG → History.txt} +78 -77
  3. data/Manifest.txt +123 -0
  4. data/{README → README.txt} +0 -0
  5. data/Rakefile +29 -0
  6. data/SPECS +63 -0
  7. data/TODO +1 -0
  8. data/lib/dm-core.rb +6 -1
  9. data/lib/dm-core/adapters/data_objects_adapter.rb +29 -32
  10. data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
  11. data/lib/dm-core/adapters/postgres_adapter.rb +1 -1
  12. data/lib/dm-core/adapters/sqlite3_adapter.rb +2 -2
  13. data/lib/dm-core/associations.rb +26 -0
  14. data/lib/dm-core/associations/many_to_many.rb +34 -25
  15. data/lib/dm-core/associations/many_to_one.rb +4 -4
  16. data/lib/dm-core/associations/one_to_many.rb +48 -13
  17. data/lib/dm-core/associations/one_to_one.rb +4 -4
  18. data/lib/dm-core/associations/relationship.rb +144 -42
  19. data/lib/dm-core/associations/relationship_chain.rb +31 -24
  20. data/lib/dm-core/auto_migrations.rb +0 -4
  21. data/lib/dm-core/collection.rb +40 -7
  22. data/lib/dm-core/dependency_queue.rb +31 -0
  23. data/lib/dm-core/hook.rb +2 -2
  24. data/lib/dm-core/is.rb +2 -2
  25. data/lib/dm-core/logger.rb +10 -10
  26. data/lib/dm-core/model.rb +94 -41
  27. data/lib/dm-core/property.rb +72 -41
  28. data/lib/dm-core/property_set.rb +8 -14
  29. data/lib/dm-core/query.rb +34 -9
  30. data/lib/dm-core/repository.rb +0 -0
  31. data/lib/dm-core/resource.rb +13 -13
  32. data/lib/dm-core/scope.rb +25 -2
  33. data/lib/dm-core/type.rb +3 -3
  34. data/lib/dm-core/types/discriminator.rb +10 -8
  35. data/lib/dm-core/types/object.rb +4 -0
  36. data/lib/dm-core/types/paranoid_boolean.rb +15 -4
  37. data/lib/dm-core/types/paranoid_datetime.rb +15 -4
  38. data/lib/dm-core/version.rb +3 -0
  39. data/script/all +5 -0
  40. data/script/performance.rb +191 -0
  41. data/script/profile.rb +86 -0
  42. data/spec/integration/association_spec.rb +288 -204
  43. data/spec/integration/association_through_spec.rb +9 -3
  44. data/spec/integration/associations/many_to_many_spec.rb +97 -31
  45. data/spec/integration/associations/many_to_one_spec.rb +41 -6
  46. data/spec/integration/associations/one_to_many_spec.rb +18 -2
  47. data/spec/integration/auto_migrations_spec.rb +0 -0
  48. data/spec/integration/collection_spec.rb +89 -42
  49. data/spec/integration/dependency_queue_spec.rb +58 -0
  50. data/spec/integration/model_spec.rb +67 -8
  51. data/spec/integration/postgres_adapter_spec.rb +19 -20
  52. data/spec/integration/property_spec.rb +17 -8
  53. data/spec/integration/query_spec.rb +273 -191
  54. data/spec/integration/resource_spec.rb +108 -10
  55. data/spec/integration/strategic_eager_loading_spec.rb +138 -0
  56. data/spec/integration/transaction_spec.rb +3 -3
  57. data/spec/integration/type_spec.rb +121 -0
  58. data/spec/lib/logging_helper.rb +18 -0
  59. data/spec/lib/model_loader.rb +91 -0
  60. data/spec/lib/publicize_methods.rb +28 -0
  61. data/spec/models/vehicles.rb +34 -0
  62. data/spec/models/zoo.rb +48 -0
  63. data/spec/spec.opts +3 -0
  64. data/spec/spec_helper.rb +25 -62
  65. data/spec/unit/adapters/data_objects_adapter_spec.rb +1 -0
  66. data/spec/unit/associations/many_to_many_spec.rb +3 -0
  67. data/spec/unit/associations/many_to_one_spec.rb +9 -1
  68. data/spec/unit/associations/one_to_many_spec.rb +12 -4
  69. data/spec/unit/associations/relationship_spec.rb +19 -15
  70. data/spec/unit/associations_spec.rb +37 -0
  71. data/spec/unit/collection_spec.rb +8 -0
  72. data/spec/unit/data_mapper_spec.rb +14 -0
  73. data/spec/unit/model_spec.rb +2 -2
  74. data/spec/unit/property_set_spec.rb +0 -13
  75. data/spec/unit/property_spec.rb +92 -21
  76. data/spec/unit/query_spec.rb +49 -4
  77. data/spec/unit/resource_spec.rb +122 -60
  78. data/spec/unit/scope_spec.rb +11 -0
  79. data/tasks/ci.rb +68 -0
  80. data/tasks/dm.rb +63 -0
  81. data/tasks/doc.rb +20 -0
  82. data/tasks/hoe.rb +38 -0
  83. data/tasks/install.rb +20 -0
  84. metadata +63 -22
data/.autotest ADDED
@@ -0,0 +1,26 @@
1
+ Autotest.add_hook :initialize do |at|
2
+ ignore = %w[ .git burn www log plugins script tasks bin CHANGELOG FAQ MIT-LICENSE PERFORMANCE QUICKLINKS README ]
3
+
4
+ unless ENV['AUTOTEST'] == 'integration'
5
+ ignore << 'spec/integration'
6
+ end
7
+
8
+ ignore.each do |exception|
9
+ at.add_exception(exception)
10
+ end
11
+
12
+ at.clear_mappings
13
+
14
+ at.add_mapping(%r{^spec/.+_spec\.rb$}) do |filename,_|
15
+ filename
16
+ end
17
+
18
+ at.add_mapping(%r{^lib/data_mapper/(.+)\.rb$}) do |_,match|
19
+ [ "spec/unit/#{match[1]}_spec.rb" ] +
20
+ at.files_matching(%r{^spec/integration/.+_spec\.rb$})
21
+ end
22
+
23
+ at.add_mapping(%r{^spec/spec_helper\.rb$}) do
24
+ at.files_matching(%r{^spec/.+_spec\.rb$})
25
+ end
26
+ end
@@ -1,37 +1,52 @@
1
- -- 0.1.0
2
- * Initial Public Release
3
1
 
4
- -- 0.1.1
5
- * Removed /lib/data_mapper/extensions
6
- * Moved ActiveRecordImpersonation into DataMapper::Support module
7
- * Moved CallbackHelper methods into DataMapper::Base class
8
- * Moved ValidationHelper into DataMapper::Validations module
9
- * Removed LoadedSet since it's not necessary for it to reference the Database, so it's nothing more than an array now; Replaced with Array
10
- * Modified data_mapper.rb to load DataMapper::Support::Enumerable
11
- * Modified example.rb and performance.rb to require 'lib/data_mapper' instead of modifying $LOADPATH
12
- * Created SqlAdapter base-class
13
- * Refactored MysqlAdapter to use SqlAdapter superclass
14
- * Refactored Sqlite3Adapter to use SqlAdapter superclass
15
- * Moved /lib/data_mapper/queries to /lib/data_mapper/adapters/sql/queries
16
- * Moved Connection, Result and Reader classes along with Coersion and Quoting modules to DataMapper::Adapters::Sql module
17
- * Moved DataMapper::Adapters::Sql::Queries to ::Commands
18
- * Moved Mappings to SqlAdapter
19
- * Added monolithic DeleteCommand
20
- * Added monolithic SaveCommand
21
- * Added TableExistsCommand
22
- * Moved save/delete logic out of Session
23
- * Added create-table functionality to SaveCommand
24
- * Cleaned up Session; #find no longer supported, use #all or #first
25
- * Moved object materialization into LoadCommand
26
- * Migrated Sqlite3Adapter::Commands
27
- * Added Session#query support back in
28
- * Removed Connection/Reader/Result classes
29
- * Set DataMapper::Base#key on load to avoid double-hit against Schema
30
- * Added DataMapper::Support::Struct for increased Session#query performance
31
- * Added AdvancedHasManyAssociation (preview status)
32
- * Added benchmarks comparing ActiveRecord::Base::find_by_sql with Session#query
2
+ == 0.3.0
3
+ * HasManyAssociation::Set now has a nil? method, so we can do stuff like cage.animal.nil?
4
+
5
+ == 0.2.5
6
+ * has_one bugfixes
7
+ * Added syntax for setting CHECK-constraints directly in your properties (Postgres)
8
+ * You can now set indexes with :index => true and :index => :unique
9
+ * Support for composite indexes (thanks to Jeffrey Gelens)
10
+ * Add composite scope to validates_uniqueness
11
+ * Added private/protected properties
12
+ * Remove HasOneAssociation, Make HasManyAssociation impersonate has_one relationships
13
+ * Added #get method
14
+ * Persistence module added, inheriting from DataMapper::Base no longer necessary
15
+
16
+ == 0.2.4
17
+ * Bug fixes
18
+ * Added paranoia
19
+
20
+ == 0.2.3
21
+ * Added String#t for translation and overrides for default validation messages
22
+ * Give credit where it's due: zapnap, not pimpmaster, submitted the String#blank? patch. My bad. :-(
23
+ * MAJOR: Resolve issue with non-unique-hash values and #dirty?; now frozen original values are stored instead
24
+ * Added Base#update_attributes
25
+ * MAJOR: Queries are now passed to the database drivers in a parameterized fashion
26
+ * Updated PostgreSQL driver and adapter to current
27
+
28
+ == 0.2.2
29
+ * Removed C extension bundles and log files from package
30
+
31
+ == 0.2.1
32
+ * Added :float column support
33
+ * Added association proxies: ie: Zoo.first.exhibits.animals
34
+ * Columns stored in SortedSet
35
+ * Swig files are no longer RDOCed
36
+ * Added :date column support
37
+ * BUG: Fixed UTC issues with datetimes
38
+ * Added #to_yaml method
39
+ * Added #to_xml method
40
+ * Added #to_json method
41
+ * BUG: Fixed HasManyAssociation::Set#inspect
42
+ * BUG: Fixed #reload!
43
+ * BUG: Column copy for STI moved into Table#initialize to better handle STI with multiple mapped databases
44
+ * BUG: before_create callbacks moved in the execution flow since they weren't guaranteed to fire before
45
+ * Threading enhancements: Removed single_threaded_mode, #database block form adjusted for thread-safety
46
+ * BUG: Fixed String#blank? when a multi-line string contained a blank line (thanks zapnap!)
47
+ * Performance enhancements: (thanks wycats!)
33
48
 
34
- -- 0.2.0
49
+ == 0.2.0
35
50
  * AdvancedHasManyAssociation now functional for fetches
36
51
  * AdvancedHasManyAssociation renamed to HasNAssociation
37
52
  * HasManyAssociation refactored to use HasNAssociation superclass
@@ -96,49 +111,35 @@
96
111
  * Most command implementations moved to methods in SqlAdapter
97
112
  * Removed UnitOfWork module, instead moving a slightly refactored implementation into Base
98
113
 
99
- -- 0.2.1
100
- * Added :float column support
101
- * Added association proxies: ie: Zoo.first.exhibits.animals
102
- * Columns stored in SortedSet
103
- * Swig files are no longer RDOCed
104
- * Added :date column support
105
- * BUG: Fixed UTC issues with datetimes
106
- * Added #to_yaml method
107
- * Added #to_xml method
108
- * Added #to_json method
109
- * BUG: Fixed HasManyAssociation::Set#inspect
110
- * BUG: Fixed #reload!
111
- * BUG: Column copy for STI moved into Table#initialize to better handle STI with multiple mapped databases
112
- * BUG: before_create callbacks moved in the execution flow since they weren't guaranteed to fire before
113
- * Threading enhancements: Removed single_threaded_mode, #database block form adjusted for thread-safety
114
- * BUG: Fixed String#blank? when a multi-line string contained a blank line (thanks zapnap!)
115
- * Performance enhancements: (thanks wycats!)
116
-
117
- -- 0.2.2
118
- * Removed C extension bundles and log files from package
119
-
120
- -- 0.2.3
121
- * Added String#t for translation and overrides for default validation messages
122
- * Give credit where it's due: zapnap, not pimpmaster, submitted the String#blank? patch. My bad. :-(
123
- * MAJOR: Resolve issue with non-unique-hash values and #dirty?; now frozen original values are stored instead
124
- * Added Base#update_attributes
125
- * MAJOR: Queries are now passed to the database drivers in a parameterized fashion
126
- * Updated PostgreSQL driver and adapter to current
127
-
128
- -- 0.2.4
129
- * Bug fixes
130
- * Added paranoia
131
-
132
- -- 0.2.5
133
- * has_one bugfixes
134
- * Added syntax for setting CHECK-constraints directly in your properties (Postgres)
135
- * You can now set indexes with :index => true and :index => :unique
136
- * Support for composite indexes (thanks to Jeffrey Gelens)
137
- * Add composite scope to validates_uniqueness
138
- * Added private/protected properties
139
- * Remove HasOneAssociation, Make HasManyAssociation impersonate has_one relationships
140
- * Added #get method
141
- * Persistence module added, inheriting from DataMapper::Base no longer necessary
114
+ == 0.1.1
115
+ * Removed /lib/data_mapper/extensions
116
+ * Moved ActiveRecordImpersonation into DataMapper::Support module
117
+ * Moved CallbackHelper methods into DataMapper::Base class
118
+ * Moved ValidationHelper into DataMapper::Validations module
119
+ * Removed LoadedSet since it's not necessary for it to reference the Database, so it's nothing more than an array now; Replaced with Array
120
+ * Modified data_mapper.rb to load DataMapper::Support::Enumerable
121
+ * Modified example.rb and performance.rb to require 'lib/data_mapper' instead of modifying $LOADPATH
122
+ * Created SqlAdapter base-class
123
+ * Refactored MysqlAdapter to use SqlAdapter superclass
124
+ * Refactored Sqlite3Adapter to use SqlAdapter superclass
125
+ * Moved /lib/data_mapper/queries to /lib/data_mapper/adapters/sql/queries
126
+ * Moved Connection, Result and Reader classes along with Coersion and Quoting modules to DataMapper::Adapters::Sql module
127
+ * Moved DataMapper::Adapters::Sql::Queries to ::Commands
128
+ * Moved Mappings to SqlAdapter
129
+ * Added monolithic DeleteCommand
130
+ * Added monolithic SaveCommand
131
+ * Added TableExistsCommand
132
+ * Moved save/delete logic out of Session
133
+ * Added create-table functionality to SaveCommand
134
+ * Cleaned up Session; #find no longer supported, use #all or #first
135
+ * Moved object materialization into LoadCommand
136
+ * Migrated Sqlite3Adapter::Commands
137
+ * Added Session#query support back in
138
+ * Removed Connection/Reader/Result classes
139
+ * Set DataMapper::Base#key on load to avoid double-hit against Schema
140
+ * Added DataMapper::Support::Struct for increased Session#query performance
141
+ * Added AdvancedHasManyAssociation (preview status)
142
+ * Added benchmarks comparing ActiveRecord::Base::find_by_sql with Session#query
142
143
 
143
- -- 0.3.0
144
- * HasManyAssociation::Set now has a nil? method, so we can do stuff like cage.animal.nil?
144
+ == 0.1.0
145
+ * Initial Public Release
data/Manifest.txt ADDED
@@ -0,0 +1,123 @@
1
+ .autotest
2
+ FAQ
3
+ History.txt
4
+ MIT-LICENSE
5
+ Manifest.txt
6
+ QUICKLINKS
7
+ README.txt
8
+ Rakefile
9
+ SPECS
10
+ TODO
11
+ lib/dm-core.rb
12
+ lib/dm-core/adapters.rb
13
+ lib/dm-core/adapters/abstract_adapter.rb
14
+ lib/dm-core/adapters/data_objects_adapter.rb
15
+ lib/dm-core/adapters/mysql_adapter.rb
16
+ lib/dm-core/adapters/postgres_adapter.rb
17
+ lib/dm-core/adapters/sqlite3_adapter.rb
18
+ lib/dm-core/associations.rb
19
+ lib/dm-core/associations/many_to_many.rb
20
+ lib/dm-core/associations/many_to_one.rb
21
+ lib/dm-core/associations/one_to_many.rb
22
+ lib/dm-core/associations/one_to_one.rb
23
+ lib/dm-core/associations/relationship.rb
24
+ lib/dm-core/associations/relationship_chain.rb
25
+ lib/dm-core/auto_migrations.rb
26
+ lib/dm-core/collection.rb
27
+ lib/dm-core/dependency_queue.rb
28
+ lib/dm-core/hook.rb
29
+ lib/dm-core/identity_map.rb
30
+ lib/dm-core/is.rb
31
+ lib/dm-core/logger.rb
32
+ lib/dm-core/migrations/destructive_migrations.rb
33
+ lib/dm-core/migrator.rb
34
+ lib/dm-core/model.rb
35
+ lib/dm-core/naming_conventions.rb
36
+ lib/dm-core/property.rb
37
+ lib/dm-core/property_set.rb
38
+ lib/dm-core/query.rb
39
+ lib/dm-core/repository.rb
40
+ lib/dm-core/resource.rb
41
+ lib/dm-core/scope.rb
42
+ lib/dm-core/support.rb
43
+ lib/dm-core/support/array.rb
44
+ lib/dm-core/support/assertions.rb
45
+ lib/dm-core/support/errors.rb
46
+ lib/dm-core/support/kernel.rb
47
+ lib/dm-core/support/symbol.rb
48
+ lib/dm-core/transaction.rb
49
+ lib/dm-core/type.rb
50
+ lib/dm-core/type_map.rb
51
+ lib/dm-core/types.rb
52
+ lib/dm-core/types/boolean.rb
53
+ lib/dm-core/types/discriminator.rb
54
+ lib/dm-core/types/object.rb
55
+ lib/dm-core/types/paranoid_boolean.rb
56
+ lib/dm-core/types/paranoid_datetime.rb
57
+ lib/dm-core/types/serial.rb
58
+ lib/dm-core/types/text.rb
59
+ lib/dm-core/version.rb
60
+ script/all
61
+ script/performance.rb
62
+ script/profile.rb
63
+ spec/integration/association_spec.rb
64
+ spec/integration/association_through_spec.rb
65
+ spec/integration/associations/many_to_many_spec.rb
66
+ spec/integration/associations/many_to_one_spec.rb
67
+ spec/integration/associations/one_to_many_spec.rb
68
+ spec/integration/auto_migrations_spec.rb
69
+ spec/integration/collection_spec.rb
70
+ spec/integration/data_objects_adapter_spec.rb
71
+ spec/integration/dependency_queue_spec.rb
72
+ spec/integration/model_spec.rb
73
+ spec/integration/mysql_adapter_spec.rb
74
+ spec/integration/postgres_adapter_spec.rb
75
+ spec/integration/property_spec.rb
76
+ spec/integration/query_spec.rb
77
+ spec/integration/repository_spec.rb
78
+ spec/integration/resource_spec.rb
79
+ spec/integration/sqlite3_adapter_spec.rb
80
+ spec/integration/sti_spec.rb
81
+ spec/integration/strategic_eager_loading_spec.rb
82
+ spec/integration/transaction_spec.rb
83
+ spec/integration/type_spec.rb
84
+ spec/lib/logging_helper.rb
85
+ spec/lib/mock_adapter.rb
86
+ spec/lib/model_loader.rb
87
+ spec/lib/publicize_methods.rb
88
+ spec/models/vehicles.rb
89
+ spec/models/zoo.rb
90
+ spec/spec.opts
91
+ spec/spec_helper.rb
92
+ spec/unit/adapters/abstract_adapter_spec.rb
93
+ spec/unit/adapters/adapter_shared_spec.rb
94
+ spec/unit/adapters/data_objects_adapter_spec.rb
95
+ spec/unit/adapters/postgres_adapter_spec.rb
96
+ spec/unit/associations/many_to_many_spec.rb
97
+ spec/unit/associations/many_to_one_spec.rb
98
+ spec/unit/associations/one_to_many_spec.rb
99
+ spec/unit/associations/one_to_one_spec.rb
100
+ spec/unit/associations/relationship_spec.rb
101
+ spec/unit/associations_spec.rb
102
+ spec/unit/auto_migrations_spec.rb
103
+ spec/unit/collection_spec.rb
104
+ spec/unit/data_mapper_spec.rb
105
+ spec/unit/identity_map_spec.rb
106
+ spec/unit/is_spec.rb
107
+ spec/unit/migrator_spec.rb
108
+ spec/unit/model_spec.rb
109
+ spec/unit/naming_conventions_spec.rb
110
+ spec/unit/property_set_spec.rb
111
+ spec/unit/property_spec.rb
112
+ spec/unit/query_spec.rb
113
+ spec/unit/repository_spec.rb
114
+ spec/unit/resource_spec.rb
115
+ spec/unit/scope_spec.rb
116
+ spec/unit/transaction_spec.rb
117
+ spec/unit/type_map_spec.rb
118
+ spec/unit/type_spec.rb
119
+ tasks/ci.rb
120
+ tasks/dm.rb
121
+ tasks/doc.rb
122
+ tasks/hoe.rb
123
+ tasks/install.rb
File without changes
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'rake/rdoctask'
6
+ require 'spec/rake/spectask'
7
+
8
+ require 'lib/dm-core/version'
9
+
10
+ ROOT = Pathname(__FILE__).dirname.expand_path
11
+
12
+ AUTHOR = "Sam Smoot"
13
+ EMAIL = "ssmoot@gmail.com"
14
+ GEM_NAME = "dm-core"
15
+ GEM_VERSION = DataMapper::VERSION
16
+ GEM_DEPENDENCIES = ["data_objects", GEM_VERSION], ["extlib", GEM_VERSION],
17
+ ["rspec", ">=1.1.3"], ["addressable", ">=1.0.4"]
18
+
19
+
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"
24
+
25
+ require ROOT + 'tasks/hoe'
26
+ require ROOT + 'tasks/install'
27
+ require ROOT + 'tasks/dm'
28
+ require ROOT + 'tasks/doc'
29
+ require ROOT + 'tasks/ci'
data/SPECS ADDED
@@ -0,0 +1,63 @@
1
+ Reading Specs
2
+ =============
3
+
4
+ Blah blah blah...
5
+
6
+ Writing Specs
7
+ =============
8
+
9
+ Here are some general dos and don'ts
10
+
11
+ = DO:
12
+
13
+ * Write more specs for error conditions than clean conditions.
14
+ * Write specs with readability in mind. Somebody knew to DataMapper should be
15
+ able to read specs to learn how something works.
16
+ * Use existing models that are part of a metaphor.
17
+ * Nest describe blocks (2 or 3 levels deep is probably fine).
18
+ * Limit a describe block to 10 - 15 examples.
19
+ * Group specs by method being tested. (See the 'Ordering Specs' section)
20
+ * Use custom matchers.
21
+
22
+ = DON'T:
23
+
24
+ * Spec more than one unit of functionality in an example. An example should be
25
+ as short as possible (while still remaining readable).
26
+ * Spec implementation. Refactoring code should not break specs.
27
+ * Declare models in the spec file.
28
+
29
+ And a final do: Do go against the guidelines if your best judgement tells you
30
+ to. These are just guidelines and are obviously not fast rules.
31
+
32
+ Models
33
+ ======
34
+
35
+ Models are declared in separate files as opposed to individual spec files for
36
+ two reasons. The first is to improve readability. By creating as few models
37
+ as possible and sharing these models throughout the specs, a reader can
38
+ become familiar with the models being used quicker. Models also follow a
39
+ few simple metaphors, such as a zoo, a blog implementation, etc... Following
40
+ metaphors makes it easier for a reader to guess what is going on with respect
41
+ to the models.
42
+
43
+ The second reason is to allow the spec environment to be as pristine as
44
+ possible going into an example. Models being loaded from the model directory
45
+ are tracked and reloaded before each example. Any changes that might be made
46
+ to the model are reset at the end.
47
+
48
+ Mocks and Stubs
49
+ ===============
50
+
51
+ Obviously, mocks and stubs are a powerful feature when it comes to BDD;
52
+ however, remember that you are writing specs for behavior and NOT
53
+ implementation.
54
+
55
+ Ordering Specs
56
+ ==============
57
+
58
+ Specs aren't much use if nobody can find where anything is, so keeping specs
59
+ well organized is critical. Currently, we are trying out the following
60
+ structure:
61
+
62
+ * List guidelines here...
63
+
data/TODO ADDED
@@ -0,0 +1 @@
1
+ See: http://github.com/sam/dm-core/wikis
data/lib/dm-core.rb CHANGED
@@ -20,7 +20,7 @@ require 'rubygems'
20
20
  gem 'addressable', '>=1.0.4'
21
21
  require 'addressable/uri'
22
22
 
23
- gem 'extlib', '=0.9.2'
23
+ gem 'extlib', '=0.9.3'
24
24
  require 'extlib'
25
25
 
26
26
  begin
@@ -35,6 +35,7 @@ require dir / 'support'
35
35
  require dir / 'resource'
36
36
  require dir / 'model'
37
37
 
38
+ require dir / 'dependency_queue'
38
39
  require dir / 'type'
39
40
  require dir / 'type_map'
40
41
  require dir / 'types'
@@ -210,4 +211,8 @@ module DataMapper
210
211
  def self.prepare(*args, &blk)
211
212
  yield repository(*args)
212
213
  end
214
+
215
+ def self.dependency_queue
216
+ @dependency_queue ||= DependencyQueue.new
217
+ end
213
218
  end
@@ -1,4 +1,4 @@
1
- gem 'data_objects', '=0.9.2'
1
+ gem 'data_objects', '=0.9.3'
2
2
  require 'data_objects'
3
3
 
4
4
  module DataMapper
@@ -228,6 +228,7 @@ module DataMapper
228
228
  statement << " FROM #{quote_table_name(query.model.storage_name(query.repository.name))}"
229
229
  statement << links_statement(query) if query.links.any?
230
230
  statement << " WHERE #{conditions_statement(query)}" if query.conditions.any?
231
+ statement << " GROUP BY #{group_by_statement(query)}" if query.unique? && query.fields.any? { |p| p.kind_of?(Property) }
231
232
  statement << " ORDER BY #{order_statement(query)}" if query.order.any?
232
233
  statement << " LIMIT #{quote_column_value(query.limit)}" if query.limit
233
234
  statement << " OFFSET #{quote_column_value(query.offset)}" if query.offset && query.offset > 0
@@ -256,17 +257,7 @@ module DataMapper
256
257
 
257
258
  def fields_statement(query)
258
259
  qualify = query.links.any?
259
-
260
- query.fields.map do |property|
261
- # TODO Should we raise an error if there is no such property in the
262
- # repository of the query?
263
- #
264
- #if property.model.properties(query.repository.name)[property.name].nil?
265
- # raise "Property #{property.model.to_s}.#{property.name.to_s} not available in repository #{name}."
266
- #end
267
- #
268
- property_to_column_name(query.repository, property, qualify)
269
- end * ', '
260
+ query.fields.map { |p| property_to_column_name(query.repository, p, qualify) } * ', '
270
261
  end
271
262
 
272
263
  def links_statement(query)
@@ -292,29 +283,35 @@ module DataMapper
292
283
  end
293
284
 
294
285
  def conditions_statement(query)
295
- query.conditions.map do |operator, property, bind_value|
296
- condition_statement(query, operator, property, bind_value)
297
- end * ' AND '
286
+ query.conditions.map { |o,p,b| condition_statement(query, o, p, b) } * ' AND '
287
+ end
288
+
289
+ def group_by_statement(query)
290
+ repository = query.repository
291
+ qualify = query.links.any?
292
+ query.fields.select { |p| p.kind_of?(Property) }.map { |p| property_to_column_name(repository, p, qualify) } * ', '
298
293
  end
299
294
 
300
295
  def order_statement(query)
301
- qualify = query.links.any?
296
+ repository = query.repository
297
+ qualify = query.links.any?
298
+ query.order.map { |i| order_column(repository, i, qualify) } * ', '
299
+ end
302
300
 
303
- query.order.map do |item|
304
- property, descending = nil, false
301
+ def order_column(repository, item, qualify)
302
+ property, descending = nil, false
305
303
 
306
- case item
307
- when Property
308
- property = item
309
- when Query::Direction
310
- property = item.property
311
- descending = true if item.direction == :desc
312
- end
304
+ case item
305
+ when Property
306
+ property = item
307
+ when Query::Direction
308
+ property = item.property
309
+ descending = true if item.direction == :desc
310
+ end
313
311
 
314
- order = property_to_column_name(query.repository, property, qualify)
315
- order << ' DESC' if descending
316
- order
317
- end * ', '
312
+ order_column = property_to_column_name(repository, property, qualify)
313
+ order_column << ' DESC' if descending
314
+ order_column
318
315
  end
319
316
 
320
317
  def condition_statement(query, operator, left_condition, right_condition)
@@ -330,7 +327,7 @@ module DataMapper
330
327
  query.merge_subquery(operator, opposite, condition)
331
328
  "(#{read_statement(condition)})"
332
329
  elsif condition.kind_of?(Array) && condition.all? { |p| p.kind_of?(Property) }
333
- "(#{condition.map { |p| property_to_column_name(query.repository, property, qualify) } * ', '})"
330
+ "(#{condition.map { |p| property_to_column_name(query.repository, p, qualify) } * ', '})"
334
331
  else
335
332
  '?'
336
333
  end
@@ -598,8 +595,8 @@ module DataMapper
598
595
  tm.map(String).to('VARCHAR').with(:size => Property::DEFAULT_LENGTH)
599
596
  tm.map(Class).to('VARCHAR').with(:size => Property::DEFAULT_LENGTH)
600
597
  tm.map(DM::Discriminator).to('VARCHAR').with(:size => Property::DEFAULT_LENGTH)
601
- tm.map(BigDecimal).to('DECIMAL').with(:precision => Property::DEFAULT_PRECISION, :scale => Property::DEFAULT_SCALE)
602
- tm.map(Float).to('FLOAT').with(:precision => Property::DEFAULT_PRECISION, :scale => Property::DEFAULT_SCALE)
598
+ tm.map(BigDecimal).to('DECIMAL').with(:precision => Property::DEFAULT_PRECISION, :scale => Property::DEFAULT_SCALE_BIGDECIMAL)
599
+ tm.map(Float).to('FLOAT').with(:precision => Property::DEFAULT_PRECISION)
603
600
  tm.map(DateTime).to('DATETIME')
604
601
  tm.map(Date).to('DATE')
605
602
  tm.map(Time).to('TIMESTAMP')