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.
- data/.autotest +17 -14
- data/.gitignore +3 -1
- data/FAQ +6 -5
- data/History.txt +5 -50
- data/Manifest.txt +66 -76
- data/QUICKLINKS +1 -1
- data/README.txt +21 -15
- data/Rakefile +6 -7
- data/SPECS +2 -29
- data/TODO +1 -1
- data/deps.rip +2 -0
- data/dm-core.gemspec +11 -15
- data/lib/dm-core.rb +105 -110
- data/lib/dm-core/adapters.rb +135 -16
- data/lib/dm-core/adapters/abstract_adapter.rb +251 -181
- data/lib/dm-core/adapters/data_objects_adapter.rb +482 -534
- data/lib/dm-core/adapters/in_memory_adapter.rb +90 -69
- data/lib/dm-core/adapters/mysql_adapter.rb +22 -115
- data/lib/dm-core/adapters/oracle_adapter.rb +249 -0
- data/lib/dm-core/adapters/postgres_adapter.rb +7 -173
- data/lib/dm-core/adapters/sqlite3_adapter.rb +4 -97
- data/lib/dm-core/adapters/yaml_adapter.rb +116 -0
- data/lib/dm-core/associations/many_to_many.rb +372 -90
- data/lib/dm-core/associations/many_to_one.rb +220 -73
- data/lib/dm-core/associations/one_to_many.rb +319 -255
- data/lib/dm-core/associations/one_to_one.rb +66 -53
- data/lib/dm-core/associations/relationship.rb +561 -156
- data/lib/dm-core/collection.rb +1101 -379
- data/lib/dm-core/core_ext/kernel.rb +12 -0
- data/lib/dm-core/core_ext/symbol.rb +10 -0
- data/lib/dm-core/identity_map.rb +4 -34
- data/lib/dm-core/migrations.rb +1283 -0
- data/lib/dm-core/model.rb +570 -369
- data/lib/dm-core/model/descendant_set.rb +81 -0
- data/lib/dm-core/model/hook.rb +45 -0
- data/lib/dm-core/model/is.rb +32 -0
- data/lib/dm-core/model/property.rb +247 -0
- data/lib/dm-core/model/relationship.rb +335 -0
- data/lib/dm-core/model/scope.rb +90 -0
- data/lib/dm-core/property.rb +808 -273
- data/lib/dm-core/property_set.rb +141 -98
- data/lib/dm-core/query.rb +1037 -483
- data/lib/dm-core/query/conditions/comparison.rb +872 -0
- data/lib/dm-core/query/conditions/operation.rb +221 -0
- data/lib/dm-core/query/direction.rb +43 -0
- data/lib/dm-core/query/operator.rb +84 -0
- data/lib/dm-core/query/path.rb +138 -0
- data/lib/dm-core/query/sort.rb +45 -0
- data/lib/dm-core/repository.rb +210 -94
- data/lib/dm-core/resource.rb +641 -421
- data/lib/dm-core/spec/adapter_shared_spec.rb +294 -0
- data/lib/dm-core/spec/data_objects_adapter_shared_spec.rb +106 -0
- data/lib/dm-core/support/chainable.rb +22 -0
- data/lib/dm-core/support/deprecate.rb +12 -0
- data/lib/dm-core/support/logger.rb +13 -0
- data/lib/dm-core/{naming_conventions.rb → support/naming_conventions.rb} +6 -6
- data/lib/dm-core/transaction.rb +333 -92
- data/lib/dm-core/type.rb +98 -60
- data/lib/dm-core/types/boolean.rb +1 -1
- data/lib/dm-core/types/discriminator.rb +34 -20
- data/lib/dm-core/types/object.rb +7 -4
- data/lib/dm-core/types/paranoid_boolean.rb +11 -9
- data/lib/dm-core/types/paranoid_datetime.rb +11 -9
- data/lib/dm-core/types/serial.rb +3 -3
- data/lib/dm-core/types/text.rb +3 -4
- data/lib/dm-core/version.rb +1 -1
- data/script/performance.rb +102 -109
- data/script/profile.rb +169 -38
- data/spec/lib/adapter_helpers.rb +105 -0
- data/spec/lib/collection_helpers.rb +18 -0
- data/spec/lib/counter_adapter.rb +34 -0
- data/spec/lib/pending_helpers.rb +27 -0
- data/spec/lib/rspec_immediate_feedback_formatter.rb +53 -0
- data/spec/public/associations/many_to_many_spec.rb +193 -0
- data/spec/public/associations/many_to_one_spec.rb +73 -0
- data/spec/public/associations/one_to_many_spec.rb +77 -0
- data/spec/public/associations/one_to_one_spec.rb +156 -0
- data/spec/public/collection_spec.rb +65 -0
- data/spec/public/migrations_spec.rb +359 -0
- data/spec/public/model/relationship_spec.rb +924 -0
- data/spec/public/model_spec.rb +159 -0
- data/spec/public/property_spec.rb +829 -0
- data/spec/public/resource_spec.rb +71 -0
- data/spec/public/sel_spec.rb +44 -0
- data/spec/public/setup_spec.rb +145 -0
- data/spec/public/shared/association_collection_shared_spec.rb +317 -0
- data/spec/public/shared/collection_shared_spec.rb +1670 -0
- data/spec/public/shared/finder_shared_spec.rb +1619 -0
- data/spec/public/shared/resource_shared_spec.rb +924 -0
- data/spec/public/shared/sel_shared_spec.rb +112 -0
- data/spec/public/transaction_spec.rb +129 -0
- data/spec/public/types/discriminator_spec.rb +130 -0
- data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
- data/spec/semipublic/adapters/in_memory_adapter_spec.rb +12 -0
- data/spec/semipublic/adapters/mysql_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/oracle_adapter_spec.rb +194 -0
- data/spec/semipublic/adapters/postgres_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/sqlite3_adapter_spec.rb +17 -0
- data/spec/semipublic/adapters/yaml_adapter_spec.rb +12 -0
- data/spec/semipublic/associations/many_to_one_spec.rb +53 -0
- data/spec/semipublic/associations/relationship_spec.rb +194 -0
- data/spec/semipublic/associations_spec.rb +177 -0
- data/spec/semipublic/collection_spec.rb +142 -0
- data/spec/semipublic/property_spec.rb +61 -0
- data/spec/semipublic/query/conditions_spec.rb +528 -0
- data/spec/semipublic/query/path_spec.rb +443 -0
- data/spec/semipublic/query_spec.rb +2626 -0
- data/spec/semipublic/resource_spec.rb +47 -0
- data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
- data/spec/semipublic/shared/resource_shared_spec.rb +126 -0
- data/spec/spec.opts +3 -1
- data/spec/spec_helper.rb +80 -57
- data/tasks/ci.rb +19 -31
- data/tasks/dm.rb +43 -48
- data/tasks/doc.rb +8 -11
- data/tasks/gemspec.rb +5 -5
- data/tasks/hoe.rb +15 -16
- data/tasks/install.rb +8 -10
- metadata +74 -111
- data/lib/dm-core/associations.rb +0 -207
- data/lib/dm-core/associations/relationship_chain.rb +0 -81
- data/lib/dm-core/auto_migrations.rb +0 -105
- data/lib/dm-core/dependency_queue.rb +0 -32
- data/lib/dm-core/hook.rb +0 -11
- data/lib/dm-core/is.rb +0 -16
- data/lib/dm-core/logger.rb +0 -232
- data/lib/dm-core/migrations/destructive_migrations.rb +0 -17
- data/lib/dm-core/migrator.rb +0 -29
- data/lib/dm-core/scope.rb +0 -58
- data/lib/dm-core/support.rb +0 -7
- data/lib/dm-core/support/array.rb +0 -13
- data/lib/dm-core/support/assertions.rb +0 -8
- data/lib/dm-core/support/errors.rb +0 -23
- data/lib/dm-core/support/kernel.rb +0 -11
- data/lib/dm-core/support/symbol.rb +0 -41
- data/lib/dm-core/type_map.rb +0 -80
- data/lib/dm-core/types.rb +0 -19
- data/script/all +0 -4
- data/spec/integration/association_spec.rb +0 -1382
- data/spec/integration/association_through_spec.rb +0 -203
- data/spec/integration/associations/many_to_many_spec.rb +0 -449
- data/spec/integration/associations/many_to_one_spec.rb +0 -163
- data/spec/integration/associations/one_to_many_spec.rb +0 -188
- data/spec/integration/auto_migrations_spec.rb +0 -413
- data/spec/integration/collection_spec.rb +0 -1073
- data/spec/integration/data_objects_adapter_spec.rb +0 -32
- data/spec/integration/dependency_queue_spec.rb +0 -46
- data/spec/integration/model_spec.rb +0 -197
- data/spec/integration/mysql_adapter_spec.rb +0 -85
- data/spec/integration/postgres_adapter_spec.rb +0 -731
- data/spec/integration/property_spec.rb +0 -253
- data/spec/integration/query_spec.rb +0 -514
- data/spec/integration/repository_spec.rb +0 -61
- data/spec/integration/resource_spec.rb +0 -513
- data/spec/integration/sqlite3_adapter_spec.rb +0 -352
- data/spec/integration/sti_spec.rb +0 -273
- data/spec/integration/strategic_eager_loading_spec.rb +0 -156
- data/spec/integration/transaction_spec.rb +0 -75
- data/spec/integration/type_spec.rb +0 -275
- data/spec/lib/logging_helper.rb +0 -18
- data/spec/lib/mock_adapter.rb +0 -27
- data/spec/lib/model_loader.rb +0 -100
- data/spec/lib/publicize_methods.rb +0 -28
- data/spec/models/content.rb +0 -16
- data/spec/models/vehicles.rb +0 -34
- data/spec/models/zoo.rb +0 -48
- data/spec/unit/adapters/abstract_adapter_spec.rb +0 -133
- data/spec/unit/adapters/adapter_shared_spec.rb +0 -15
- data/spec/unit/adapters/data_objects_adapter_spec.rb +0 -632
- data/spec/unit/adapters/in_memory_adapter_spec.rb +0 -98
- data/spec/unit/adapters/postgres_adapter_spec.rb +0 -133
- data/spec/unit/associations/many_to_many_spec.rb +0 -32
- data/spec/unit/associations/many_to_one_spec.rb +0 -159
- data/spec/unit/associations/one_to_many_spec.rb +0 -393
- data/spec/unit/associations/one_to_one_spec.rb +0 -7
- data/spec/unit/associations/relationship_spec.rb +0 -71
- data/spec/unit/associations_spec.rb +0 -242
- data/spec/unit/auto_migrations_spec.rb +0 -111
- data/spec/unit/collection_spec.rb +0 -182
- data/spec/unit/data_mapper_spec.rb +0 -35
- data/spec/unit/identity_map_spec.rb +0 -126
- data/spec/unit/is_spec.rb +0 -80
- data/spec/unit/migrator_spec.rb +0 -33
- data/spec/unit/model_spec.rb +0 -321
- data/spec/unit/naming_conventions_spec.rb +0 -36
- data/spec/unit/property_set_spec.rb +0 -90
- data/spec/unit/property_spec.rb +0 -753
- data/spec/unit/query_spec.rb +0 -571
- data/spec/unit/repository_spec.rb +0 -93
- data/spec/unit/resource_spec.rb +0 -649
- data/spec/unit/scope_spec.rb +0 -142
- data/spec/unit/transaction_spec.rb +0 -493
- data/spec/unit/type_map_spec.rb +0 -114
- data/spec/unit/type_spec.rb +0 -119
data/SPECS
CHANGED
|
@@ -11,7 +11,7 @@ Writing Specs
|
|
|
11
11
|
= DO:
|
|
12
12
|
|
|
13
13
|
* Write more specs for error conditions than clean conditions.
|
|
14
|
-
* Write specs with readability in mind. Somebody
|
|
14
|
+
* Write specs with readability in mind. Somebody new to DataMapper should be
|
|
15
15
|
able to read specs to learn how something works.
|
|
16
16
|
* Use existing models that are part of a metaphor.
|
|
17
17
|
* Nest describe blocks (2 or 3 levels deep is probably fine).
|
|
@@ -29,34 +29,7 @@ Writing Specs
|
|
|
29
29
|
And a final do: Do go against the guidelines if your best judgement tells you
|
|
30
30
|
to. These are just guidelines and are obviously not fast rules.
|
|
31
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
32
|
Mocks and Stubs
|
|
49
33
|
===============
|
|
50
34
|
|
|
51
|
-
|
|
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...
|
|
35
|
+
Do not use mocks or stubs for any specs in DataMapper.
|
data/TODO
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
See: http://github.com/
|
|
1
|
+
See: http://wiki.github.com/datamapper/dm-core
|
data/deps.rip
ADDED
data/dm-core.gemspec
CHANGED
|
@@ -2,39 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = %q{dm-core}
|
|
5
|
-
s.version = "0.
|
|
5
|
+
s.version = "0.10.0"
|
|
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-
|
|
9
|
+
s.date = %q{2009-07-30}
|
|
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"]
|
|
13
|
-
s.files = [".autotest", ".gitignore", "CONTRIBUTING", "FAQ", "History.txt", "MIT-LICENSE", "Manifest.txt", "QUICKLINKS", "README.txt", "Rakefile", "SPECS", "TODO", "dm-core.gemspec", "lib/dm-core.rb", "lib/dm-core/adapters.rb", "lib/dm-core/adapters/abstract_adapter.rb", "lib/dm-core/adapters/data_objects_adapter.rb", "lib/dm-core/adapters/in_memory_adapter.rb", "lib/dm-core/adapters/mysql_adapter.rb", "lib/dm-core/adapters/postgres_adapter.rb", "lib/dm-core/adapters/sqlite3_adapter.rb", "lib/dm-core/
|
|
14
|
-
s.has_rdoc = true
|
|
13
|
+
s.files = [".autotest", ".gitignore", "CONTRIBUTING", "FAQ", "History.txt", "MIT-LICENSE", "Manifest.txt", "QUICKLINKS", "README.txt", "Rakefile", "SPECS", "TODO", "dm-core.gemspec", "lib/dm-core.rb", "lib/dm-core/adapters.rb", "lib/dm-core/adapters/abstract_adapter.rb", "lib/dm-core/adapters/data_objects_adapter.rb", "lib/dm-core/adapters/in_memory_adapter.rb", "lib/dm-core/adapters/mysql_adapter.rb", "lib/dm-core/adapters/oracle_adapter.rb", "lib/dm-core/adapters/postgres_adapter.rb", "lib/dm-core/adapters/sqlite3_adapter.rb", "lib/dm-core/adapters/yaml_adapter.rb", "lib/dm-core/associations/many_to_many.rb", "lib/dm-core/associations/many_to_one.rb", "lib/dm-core/associations/one_to_many.rb", "lib/dm-core/associations/one_to_one.rb", "lib/dm-core/associations/relationship.rb", "lib/dm-core/collection.rb", "lib/dm-core/core_ext/kernel.rb", "lib/dm-core/core_ext/symbol.rb", "lib/dm-core/identity_map.rb", "lib/dm-core/migrations.rb", "lib/dm-core/model.rb", "lib/dm-core/model/descendant_set.rb", "lib/dm-core/model/hook.rb", "lib/dm-core/model/is.rb", "lib/dm-core/model/property.rb", "lib/dm-core/model/relationship.rb", "lib/dm-core/model/scope.rb", "lib/dm-core/property.rb", "lib/dm-core/property_set.rb", "lib/dm-core/query.rb", "lib/dm-core/query/conditions/comparison.rb", "lib/dm-core/query/conditions/operation.rb", "lib/dm-core/query/direction.rb", "lib/dm-core/query/operator.rb", "lib/dm-core/query/path.rb", "lib/dm-core/query/sort.rb", "lib/dm-core/repository.rb", "lib/dm-core/resource.rb", "lib/dm-core/spec/adapter_shared_spec.rb", "lib/dm-core/spec/data_objects_adapter_shared_spec.rb", "lib/dm-core/support/chainable.rb", "lib/dm-core/support/deprecate.rb", "lib/dm-core/support/logger.rb", "lib/dm-core/support/naming_conventions.rb", "lib/dm-core/transaction.rb", "lib/dm-core/type.rb", "lib/dm-core/types/boolean.rb", "lib/dm-core/types/discriminator.rb", "lib/dm-core/types/object.rb", "lib/dm-core/types/paranoid_boolean.rb", "lib/dm-core/types/paranoid_datetime.rb", "lib/dm-core/types/serial.rb", "lib/dm-core/types/text.rb", "lib/dm-core/version.rb", "script/performance.rb", "script/profile.rb", "spec/lib/adapter_helpers.rb", "spec/lib/collection_helpers.rb", "spec/lib/counter_adapter.rb", "spec/lib/pending_helpers.rb", "spec/lib/rspec_immediate_feedback_formatter.rb", "spec/public/associations/many_to_many_spec.rb", "spec/public/associations/many_to_one_spec.rb", "spec/public/associations/one_to_many_spec.rb", "spec/public/associations/one_to_one_spec.rb", "spec/public/collection_spec.rb", "spec/public/model/relationship_spec.rb", "spec/public/model_spec.rb", "spec/public/property_spec.rb", "spec/public/resource_spec.rb", "spec/public/sel_spec.rb", "spec/public/setup_spec.rb", "spec/public/shared/association_collection_shared_spec.rb", "spec/public/shared/collection_shared_spec.rb", "spec/public/shared/finder_shared_spec.rb", "spec/public/shared/resource_shared_spec.rb", "spec/public/shared/sel_shared_spec.rb", "spec/public/transaction_spec.rb", "spec/public/types/discriminator_spec.rb", "spec/semipublic/adapters/abstract_adapter_spec.rb", "spec/semipublic/adapters/in_memory_adapter_spec.rb", "spec/semipublic/adapters/mysql_adapter_spec.rb", "spec/semipublic/adapters/oracle_adapter_spec.rb", "spec/semipublic/adapters/postgres_adapter_spec.rb", "spec/semipublic/adapters/sqlite3_adapter_spec.rb", "spec/semipublic/adapters/yaml_adapter_spec.rb", "spec/semipublic/associations/many_to_one_spec.rb", "spec/semipublic/associations/relationship_spec.rb", "spec/semipublic/associations_spec.rb", "spec/semipublic/collection_spec.rb", "spec/semipublic/property_spec.rb", "spec/semipublic/query/conditions_spec.rb", "spec/semipublic/query/path_spec.rb", "spec/semipublic/query_spec.rb", "spec/semipublic/resource_spec.rb", "spec/semipublic/shared/resource_shared_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/ci.rb", "tasks/dm.rb", "tasks/doc.rb", "tasks/gemspec.rb", "tasks/hoe.rb", "tasks/install.rb"]
|
|
15
14
|
s.homepage = %q{http://datamapper.org}
|
|
16
15
|
s.rdoc_options = ["--main", "README.txt"]
|
|
17
16
|
s.require_paths = ["lib"]
|
|
18
17
|
s.rubyforge_project = %q{datamapper}
|
|
19
|
-
s.rubygems_version = %q{1.3.
|
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
|
20
19
|
s.summary = %q{An Object/Relational Mapper for Ruby}
|
|
21
20
|
|
|
22
21
|
if s.respond_to? :specification_version then
|
|
23
22
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
24
|
-
s.specification_version =
|
|
23
|
+
s.specification_version = 3
|
|
25
24
|
|
|
26
25
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
27
|
-
s.add_runtime_dependency(%q<
|
|
28
|
-
s.add_runtime_dependency(%q<
|
|
29
|
-
s.add_runtime_dependency(%q<addressable>, ["~> 2.0.2"])
|
|
26
|
+
s.add_runtime_dependency(%q<extlib>, ["~> 0.9.13"])
|
|
27
|
+
s.add_runtime_dependency(%q<addressable>, ["~> 2.0"])
|
|
30
28
|
else
|
|
31
|
-
s.add_dependency(%q<
|
|
32
|
-
s.add_dependency(%q<
|
|
33
|
-
s.add_dependency(%q<addressable>, ["~> 2.0.2"])
|
|
29
|
+
s.add_dependency(%q<extlib>, ["~> 0.9.13"])
|
|
30
|
+
s.add_dependency(%q<addressable>, ["~> 2.0"])
|
|
34
31
|
end
|
|
35
32
|
else
|
|
36
|
-
s.add_dependency(%q<
|
|
37
|
-
s.add_dependency(%q<
|
|
38
|
-
s.add_dependency(%q<addressable>, ["~> 2.0.2"])
|
|
33
|
+
s.add_dependency(%q<extlib>, ["~> 0.9.13"])
|
|
34
|
+
s.add_dependency(%q<addressable>, ["~> 2.0"])
|
|
39
35
|
end
|
|
40
36
|
end
|
data/lib/dm-core.rb
CHANGED
|
@@ -4,27 +4,20 @@
|
|
|
4
4
|
# * Requires fastthread, support libs, and base.
|
|
5
5
|
# * Sets the application root and environment for compatibility with frameworks
|
|
6
6
|
# such as Rails or Merb.
|
|
7
|
-
# * Checks for the database.yml and loads it if it exists.
|
|
8
|
-
# * Sets up the database using the config from the Yaml file or from the
|
|
9
|
-
# environment.
|
|
10
7
|
#
|
|
11
8
|
|
|
9
|
+
require 'addressable/uri'
|
|
10
|
+
require 'base64'
|
|
11
|
+
require 'bigdecimal'
|
|
12
|
+
require 'bigdecimal/util'
|
|
12
13
|
require 'date'
|
|
14
|
+
require 'extlib'
|
|
13
15
|
require 'pathname'
|
|
14
|
-
require 'rubygems'
|
|
15
16
|
require 'set'
|
|
16
17
|
require 'time'
|
|
17
18
|
require 'yaml'
|
|
18
19
|
|
|
19
|
-
gem 'addressable', '~>2.0.2'
|
|
20
|
-
require 'addressable/uri'
|
|
21
|
-
|
|
22
|
-
gem 'extlib', '~>0.9.11'
|
|
23
|
-
require 'extlib'
|
|
24
|
-
require 'extlib/inflection'
|
|
25
|
-
|
|
26
20
|
begin
|
|
27
|
-
gem 'fastthread', '~>1.0.4'
|
|
28
21
|
require 'fastthread'
|
|
29
22
|
rescue LoadError
|
|
30
23
|
# fastthread not installed
|
|
@@ -32,30 +25,57 @@ end
|
|
|
32
25
|
|
|
33
26
|
dir = Pathname(__FILE__).dirname.expand_path / 'dm-core'
|
|
34
27
|
|
|
35
|
-
require dir / 'support'
|
|
36
|
-
require dir / '
|
|
28
|
+
require dir / 'support' / 'chainable'
|
|
29
|
+
require dir / 'support' / 'deprecate'
|
|
30
|
+
|
|
37
31
|
require dir / 'model'
|
|
32
|
+
require dir / 'model' / 'descendant_set'
|
|
33
|
+
require dir / 'model' / 'hook'
|
|
34
|
+
require dir / 'model' / 'is'
|
|
35
|
+
require dir / 'model' / 'scope'
|
|
36
|
+
require dir / 'model' / 'relationship'
|
|
37
|
+
require dir / 'model' / 'property'
|
|
38
38
|
|
|
39
|
-
require dir / '
|
|
40
|
-
|
|
41
|
-
require dir / '
|
|
42
|
-
require dir / '
|
|
43
|
-
require dir / '
|
|
44
|
-
require dir / 'associations'
|
|
45
|
-
require dir / '
|
|
39
|
+
require dir / 'collection'
|
|
40
|
+
|
|
41
|
+
require dir / 'adapters'
|
|
42
|
+
require dir / 'adapters' / 'abstract_adapter'
|
|
43
|
+
require dir / 'associations' / 'relationship'
|
|
44
|
+
require dir / 'associations' / 'one_to_many'
|
|
45
|
+
require dir / 'associations' / 'one_to_one'
|
|
46
|
+
require dir / 'associations' / 'many_to_one'
|
|
47
|
+
require dir / 'associations' / 'many_to_many'
|
|
46
48
|
require dir / 'identity_map'
|
|
47
|
-
require dir / '
|
|
48
|
-
require dir / '
|
|
49
|
-
require dir / 'naming_conventions'
|
|
49
|
+
require dir / 'migrations' # TODO: move to dm-more
|
|
50
|
+
require dir / 'property'
|
|
50
51
|
require dir / 'property_set'
|
|
51
52
|
require dir / 'query'
|
|
52
|
-
require dir / '
|
|
53
|
+
require dir / 'query' / 'conditions' / 'operation'
|
|
54
|
+
require dir / 'query' / 'conditions' / 'comparison'
|
|
55
|
+
require dir / 'query' / 'operator'
|
|
56
|
+
require dir / 'query' / 'direction'
|
|
57
|
+
require dir / 'query' / 'path'
|
|
58
|
+
require dir / 'query' / 'sort'
|
|
53
59
|
require dir / 'repository'
|
|
54
|
-
require dir / '
|
|
55
|
-
require dir / '
|
|
56
|
-
require dir / '
|
|
57
|
-
require dir / '
|
|
58
|
-
require dir / '
|
|
60
|
+
require dir / 'resource'
|
|
61
|
+
require dir / 'support' / 'logger'
|
|
62
|
+
require dir / 'support' / 'naming_conventions'
|
|
63
|
+
require dir / 'transaction' # TODO: move to dm-more
|
|
64
|
+
require dir / 'type'
|
|
65
|
+
require dir / 'types' / 'boolean'
|
|
66
|
+
require dir / 'types' / 'discriminator'
|
|
67
|
+
require dir / 'types' / 'text'
|
|
68
|
+
require dir / 'types' / 'paranoid_datetime' # TODO: move to dm-more
|
|
69
|
+
require dir / 'types' / 'paranoid_boolean' # TODO: move to dm-more
|
|
70
|
+
require dir / 'types' / 'object'
|
|
71
|
+
require dir / 'types' / 'serial'
|
|
72
|
+
require dir / 'version'
|
|
73
|
+
|
|
74
|
+
require dir / 'core_ext' / 'kernel' # TODO: do not load automatically
|
|
75
|
+
require dir / 'core_ext' / 'symbol' # TODO: do not load automatically
|
|
76
|
+
|
|
77
|
+
# A logger should always be present. Lets be consistent with DO
|
|
78
|
+
DataMapper::Logger.new(StringIO.new, :fatal)
|
|
59
79
|
|
|
60
80
|
# == Setup and Configuration
|
|
61
81
|
# DataMapper uses URIs or a connection hash to connect to your data-store.
|
|
@@ -76,10 +96,10 @@ require dir / 'is'
|
|
|
76
96
|
# address the data-store on the server.
|
|
77
97
|
#
|
|
78
98
|
# Here's some examples
|
|
79
|
-
# DataMapper.setup(:default,
|
|
80
|
-
# DataMapper.setup(:default,
|
|
99
|
+
# DataMapper.setup(:default, 'sqlite3://path/to/your/project/db/development.db')
|
|
100
|
+
# DataMapper.setup(:default, 'mysql://localhost/dm_core_test')
|
|
81
101
|
# # no auth-info
|
|
82
|
-
# DataMapper.setup(:default,
|
|
102
|
+
# DataMapper.setup(:default, 'postgres://root:supahsekret@127.0.0.1/dm_core_test')
|
|
83
103
|
# # with auth-info
|
|
84
104
|
#
|
|
85
105
|
#
|
|
@@ -88,7 +108,7 @@ require dir / 'is'
|
|
|
88
108
|
#
|
|
89
109
|
# DataMapper.setup(:default, {
|
|
90
110
|
# :adapter => 'adapter_name_here',
|
|
91
|
-
# :database =>
|
|
111
|
+
# :database => 'path/to/repo',
|
|
92
112
|
# :username => 'username',
|
|
93
113
|
# :password => 'password',
|
|
94
114
|
# :host => 'hostname'
|
|
@@ -97,67 +117,71 @@ require dir / 'is'
|
|
|
97
117
|
# === Logging
|
|
98
118
|
# To turn on error logging to STDOUT, issue:
|
|
99
119
|
#
|
|
100
|
-
# DataMapper::Logger.new(STDOUT,
|
|
120
|
+
# DataMapper::Logger.new(STDOUT, :debug)
|
|
101
121
|
#
|
|
102
122
|
# You can pass a file location ("/path/to/log/file.log") in place of STDOUT.
|
|
103
123
|
# see DataMapper::Logger for more information.
|
|
104
124
|
#
|
|
105
125
|
module DataMapper
|
|
106
|
-
extend Assertions
|
|
126
|
+
extend Extlib::Assertions
|
|
127
|
+
|
|
128
|
+
# TODO: move to dm-validations
|
|
129
|
+
class ValidationError < StandardError; end
|
|
130
|
+
|
|
131
|
+
class ObjectNotFoundError < StandardError; end
|
|
132
|
+
|
|
133
|
+
class RepositoryNotSetupError < StandardError; end
|
|
134
|
+
|
|
135
|
+
class IncompleteModelError < StandardError; end
|
|
107
136
|
|
|
137
|
+
class PluginNotFoundError < StandardError; end
|
|
138
|
+
|
|
139
|
+
class UpdateConflictError < StandardError; end
|
|
140
|
+
|
|
141
|
+
class UnknownRelationshipError < StandardError; end
|
|
142
|
+
|
|
143
|
+
# Raised on attempt to operate on collection of child objects
|
|
144
|
+
# when parent object is not yet saved.
|
|
145
|
+
# For instance, if your article object is not saved,
|
|
146
|
+
# but you try to fetch or scope down comments (1:n case), or
|
|
147
|
+
# publications (n:m case), operation cannot be completed
|
|
148
|
+
# because parent object's keys are not yet persisted,
|
|
149
|
+
# and thus there is no FK value to use in the query.
|
|
150
|
+
class UnsavedParentError < RuntimeError; end
|
|
151
|
+
|
|
152
|
+
# TODO: document
|
|
153
|
+
# @api private
|
|
108
154
|
def self.root
|
|
109
|
-
@root ||= Pathname(__FILE__).dirname.parent.expand_path
|
|
155
|
+
@root ||= Pathname(__FILE__).dirname.parent.expand_path.freeze
|
|
110
156
|
end
|
|
111
157
|
|
|
112
|
-
##
|
|
113
158
|
# Setups up a connection to a data-store
|
|
114
159
|
#
|
|
115
|
-
# @param Symbol name
|
|
116
|
-
#
|
|
160
|
+
# @param [Symbol] name
|
|
161
|
+
# a name for the context, defaults to :default
|
|
162
|
+
# @param [Hash(Symbol => String), Addressable::URI, String] uri_or_options
|
|
117
163
|
# connection information
|
|
118
164
|
#
|
|
119
|
-
# @return
|
|
165
|
+
# @return [DataMapper::Adapters::AbstractAdapter]
|
|
166
|
+
# the resulting setup adapter
|
|
120
167
|
#
|
|
121
|
-
# @raise ArgumentError "+name+ must be a Symbol, but was..."
|
|
122
|
-
# an invalid argument was passed for name[Symbol]
|
|
123
|
-
# @raise [ArgumentError] "+uri_or_options+ must be a Hash, URI or String,
|
|
124
|
-
#
|
|
125
|
-
#
|
|
168
|
+
# @raise [ArgumentError] "+name+ must be a Symbol, but was..."
|
|
169
|
+
# indicates that an invalid argument was passed for name[Symbol]
|
|
170
|
+
# @raise [ArgumentError] "+uri_or_options+ must be a Hash, URI or String, but was..."
|
|
171
|
+
# indicates that connection information could not be gleaned from
|
|
172
|
+
# the given uri_or_options[Hash, Addressable::URI, String]
|
|
126
173
|
#
|
|
127
|
-
# -
|
|
128
174
|
# @api public
|
|
129
|
-
def self.setup(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
when Hash
|
|
135
|
-
adapter_name = uri_or_options[:adapter].to_s
|
|
136
|
-
when String, DataObjects::URI, Addressable::URI
|
|
137
|
-
uri_or_options = DataObjects::URI.parse(uri_or_options) if uri_or_options.kind_of?(String)
|
|
138
|
-
adapter_name = uri_or_options.scheme
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
class_name = Extlib::Inflection.classify(adapter_name) + 'Adapter'
|
|
142
|
-
|
|
143
|
-
unless Adapters::const_defined?(class_name)
|
|
144
|
-
lib_name = "#{Extlib::Inflection.underscore(adapter_name)}_adapter"
|
|
145
|
-
begin
|
|
146
|
-
require root / 'lib' / 'dm-core' / 'adapters' / lib_name
|
|
147
|
-
rescue LoadError => e
|
|
148
|
-
begin
|
|
149
|
-
require lib_name
|
|
150
|
-
rescue Exception
|
|
151
|
-
# library not found, raise the original error
|
|
152
|
-
raise e
|
|
153
|
-
end
|
|
154
|
-
end
|
|
175
|
+
def self.setup(*args)
|
|
176
|
+
adapter = if args.first.kind_of?(Adapters::AbstractAdapter)
|
|
177
|
+
args.first
|
|
178
|
+
else
|
|
179
|
+
DataMapper::Adapters.new(*args)
|
|
155
180
|
end
|
|
156
181
|
|
|
157
|
-
Repository.adapters[name] =
|
|
182
|
+
Repository.adapters[adapter.name] = adapter
|
|
158
183
|
end
|
|
159
184
|
|
|
160
|
-
##
|
|
161
185
|
# Block Syntax
|
|
162
186
|
# Pushes the named repository onto the context-stack,
|
|
163
187
|
# yields a new session, and pops the context-stack.
|
|
@@ -167,12 +191,14 @@ module DataMapper
|
|
|
167
191
|
# a new Session.
|
|
168
192
|
#
|
|
169
193
|
# @param [Symbol] args the name of a repository to act within or return, :default is default
|
|
194
|
+
#
|
|
170
195
|
# @yield [Proc] (optional) block to execute within the context of the named repository
|
|
171
|
-
#
|
|
172
|
-
|
|
196
|
+
#
|
|
197
|
+
# @api public
|
|
198
|
+
def self.repository(name = nil)
|
|
173
199
|
current_repository = if name
|
|
174
|
-
|
|
175
|
-
Repository.context.detect { |
|
|
200
|
+
assert_kind_of 'name', name, Symbol
|
|
201
|
+
Repository.context.detect { |repository| repository.name == name } || Repository.new(name)
|
|
176
202
|
else
|
|
177
203
|
Repository.context.last || Repository.new(Repository.default_name)
|
|
178
204
|
end
|
|
@@ -183,35 +209,4 @@ module DataMapper
|
|
|
183
209
|
current_repository
|
|
184
210
|
end
|
|
185
211
|
end
|
|
186
|
-
|
|
187
|
-
# A logger should always be present. Lets be consistent with DO
|
|
188
|
-
Logger.new(nil, :off)
|
|
189
|
-
|
|
190
|
-
##
|
|
191
|
-
# destructively migrates the repository upwards to match model definitions
|
|
192
|
-
#
|
|
193
|
-
# @param [Symbol] name repository to act on, :default is the default
|
|
194
|
-
def self.migrate!(name = Repository.default_name)
|
|
195
|
-
repository(name).migrate!
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
##
|
|
199
|
-
# drops and recreates the repository upwards to match model definitions
|
|
200
|
-
#
|
|
201
|
-
# @param [Symbol] name repository to act on, :default is the default
|
|
202
|
-
def self.auto_migrate!(repository_name = nil)
|
|
203
|
-
AutoMigrator.auto_migrate(repository_name)
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
def self.auto_upgrade!(repository_name = nil)
|
|
207
|
-
AutoMigrator.auto_upgrade(repository_name)
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
def self.prepare(*args, &blk)
|
|
211
|
-
yield repository(*args)
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def self.dependency_queue
|
|
215
|
-
@dependency_queue ||= DependencyQueue.new
|
|
216
|
-
end
|
|
217
212
|
end
|
data/lib/dm-core/adapters.rb
CHANGED
|
@@ -1,16 +1,135 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
module DataMapper
|
|
2
|
+
module Adapters
|
|
3
|
+
extend Chainable
|
|
4
|
+
extend Extlib::Assertions
|
|
5
|
+
|
|
6
|
+
# Set up an adapter for a storage engine
|
|
7
|
+
#
|
|
8
|
+
# @see DataMapper.setup
|
|
9
|
+
#
|
|
10
|
+
# @api private
|
|
11
|
+
def self.new(repository_name, options)
|
|
12
|
+
options = normalize_options(options)
|
|
13
|
+
adapter_class(options[:adapter]).new(repository_name, options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
# Normalize the arguments passed to new()
|
|
20
|
+
#
|
|
21
|
+
# Turns options hash or connection URI into the options hash used
|
|
22
|
+
# by the adapter.
|
|
23
|
+
#
|
|
24
|
+
# @param [Hash, Addressable::URI, String] options
|
|
25
|
+
# the options to be normalized
|
|
26
|
+
#
|
|
27
|
+
# @return [Mash]
|
|
28
|
+
# the options normalized as a Mash
|
|
29
|
+
#
|
|
30
|
+
# @api private
|
|
31
|
+
def normalize_options(options)
|
|
32
|
+
case options
|
|
33
|
+
when Hash then normalize_options_hash(options)
|
|
34
|
+
when Addressable::URI then normalize_options_uri(options)
|
|
35
|
+
when String then normalize_options_string(options)
|
|
36
|
+
else
|
|
37
|
+
assert_kind_of 'options', options, Hash, Addressable::URI, String
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Normalize Hash options into a Mash
|
|
42
|
+
#
|
|
43
|
+
# @param [Hash] hash
|
|
44
|
+
# the hash to be normalized
|
|
45
|
+
#
|
|
46
|
+
# @return [Mash]
|
|
47
|
+
# the options normalized as a Mash
|
|
48
|
+
#
|
|
49
|
+
# @api private
|
|
50
|
+
def normalize_options_hash(hash)
|
|
51
|
+
hash.to_mash
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Normalize Addressable::URI options into a Mash
|
|
55
|
+
#
|
|
56
|
+
# @param [Addressable::URI] uri
|
|
57
|
+
# the uri to be normalized
|
|
58
|
+
#
|
|
59
|
+
# @return [Mash]
|
|
60
|
+
# the options normalized as a Mash
|
|
61
|
+
#
|
|
62
|
+
# @api private
|
|
63
|
+
def normalize_options_uri(uri)
|
|
64
|
+
options = normalize_options_hash(uri.to_hash)
|
|
65
|
+
|
|
66
|
+
# Extract the name/value pairs from the query portion of the
|
|
67
|
+
# connection uri, and set them as options directly.
|
|
68
|
+
if options[:query]
|
|
69
|
+
options.update(uri.query_values)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
options[:adapter] = options[:scheme]
|
|
73
|
+
|
|
74
|
+
options
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Normalize String options into a Mash
|
|
78
|
+
#
|
|
79
|
+
# @param [String] string
|
|
80
|
+
# the string to be normalized
|
|
81
|
+
#
|
|
82
|
+
# @return [Mash]
|
|
83
|
+
# the options normalized as a Mash
|
|
84
|
+
#
|
|
85
|
+
# @api private
|
|
86
|
+
def normalize_options_string(string)
|
|
87
|
+
normalize_options_uri(Addressable::URI.parse(string))
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Return the adapter class constant
|
|
91
|
+
#
|
|
92
|
+
# @param [Symbol] name
|
|
93
|
+
# the name of the adapter
|
|
94
|
+
#
|
|
95
|
+
# @return [Class]
|
|
96
|
+
# the AbstractAdapter subclass
|
|
97
|
+
#
|
|
98
|
+
# @api private
|
|
99
|
+
def adapter_class(name)
|
|
100
|
+
class_name = (Extlib::Inflection.camelize(name) << 'Adapter').to_sym
|
|
101
|
+
load_adapter(name) unless const_defined?(class_name)
|
|
102
|
+
const_get(class_name)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Require the adapter library
|
|
106
|
+
#
|
|
107
|
+
# @param [String, Symbol] name
|
|
108
|
+
# the name of the adapter
|
|
109
|
+
#
|
|
110
|
+
# @return [Boolean]
|
|
111
|
+
# true if the adapter is loaded
|
|
112
|
+
#
|
|
113
|
+
# @api private
|
|
114
|
+
def load_adapter(name)
|
|
115
|
+
assert_kind_of 'name', name, String, Symbol
|
|
116
|
+
|
|
117
|
+
lib = "#{name}_adapter"
|
|
118
|
+
file = DataMapper.root / 'lib' / 'dm-core' / 'adapters' / "#{lib}.rb"
|
|
119
|
+
|
|
120
|
+
if file.file?
|
|
121
|
+
require file
|
|
122
|
+
else
|
|
123
|
+
require lib
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
extendable do
|
|
129
|
+
# TODO: document
|
|
130
|
+
# @api private
|
|
131
|
+
def const_added(const_name)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end # module Adapters
|
|
135
|
+
end # module DataMapper
|