ghost_dm-core 1.3.0.beta

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 (254) hide show
  1. data/.autotest +29 -0
  2. data/.document +5 -0
  3. data/.gitignore +35 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +65 -0
  6. data/LICENSE +20 -0
  7. data/README.md +269 -0
  8. data/Rakefile +4 -0
  9. data/dm-core.gemspec +24 -0
  10. data/lib/dm-core.rb +292 -0
  11. data/lib/dm-core/adapters.rb +222 -0
  12. data/lib/dm-core/adapters/abstract_adapter.rb +237 -0
  13. data/lib/dm-core/adapters/in_memory_adapter.rb +113 -0
  14. data/lib/dm-core/associations/many_to_many.rb +499 -0
  15. data/lib/dm-core/associations/many_to_one.rb +290 -0
  16. data/lib/dm-core/associations/one_to_many.rb +348 -0
  17. data/lib/dm-core/associations/one_to_one.rb +86 -0
  18. data/lib/dm-core/associations/relationship.rb +663 -0
  19. data/lib/dm-core/backwards.rb +13 -0
  20. data/lib/dm-core/collection.rb +1515 -0
  21. data/lib/dm-core/core_ext/kernel.rb +23 -0
  22. data/lib/dm-core/core_ext/pathname.rb +6 -0
  23. data/lib/dm-core/core_ext/symbol.rb +10 -0
  24. data/lib/dm-core/identity_map.rb +7 -0
  25. data/lib/dm-core/model.rb +874 -0
  26. data/lib/dm-core/model/hook.rb +103 -0
  27. data/lib/dm-core/model/is.rb +32 -0
  28. data/lib/dm-core/model/property.rb +249 -0
  29. data/lib/dm-core/model/relationship.rb +378 -0
  30. data/lib/dm-core/model/scope.rb +89 -0
  31. data/lib/dm-core/property.rb +866 -0
  32. data/lib/dm-core/property/binary.rb +21 -0
  33. data/lib/dm-core/property/boolean.rb +20 -0
  34. data/lib/dm-core/property/class.rb +17 -0
  35. data/lib/dm-core/property/date.rb +10 -0
  36. data/lib/dm-core/property/date_time.rb +10 -0
  37. data/lib/dm-core/property/decimal.rb +36 -0
  38. data/lib/dm-core/property/discriminator.rb +44 -0
  39. data/lib/dm-core/property/float.rb +16 -0
  40. data/lib/dm-core/property/integer.rb +22 -0
  41. data/lib/dm-core/property/invalid_value_error.rb +22 -0
  42. data/lib/dm-core/property/lookup.rb +27 -0
  43. data/lib/dm-core/property/numeric.rb +38 -0
  44. data/lib/dm-core/property/object.rb +34 -0
  45. data/lib/dm-core/property/serial.rb +14 -0
  46. data/lib/dm-core/property/string.rb +38 -0
  47. data/lib/dm-core/property/text.rb +9 -0
  48. data/lib/dm-core/property/time.rb +10 -0
  49. data/lib/dm-core/property_set.rb +177 -0
  50. data/lib/dm-core/query.rb +1366 -0
  51. data/lib/dm-core/query/conditions/comparison.rb +911 -0
  52. data/lib/dm-core/query/conditions/operation.rb +721 -0
  53. data/lib/dm-core/query/direction.rb +36 -0
  54. data/lib/dm-core/query/operator.rb +35 -0
  55. data/lib/dm-core/query/path.rb +114 -0
  56. data/lib/dm-core/query/sort.rb +39 -0
  57. data/lib/dm-core/relationship_set.rb +72 -0
  58. data/lib/dm-core/repository.rb +226 -0
  59. data/lib/dm-core/resource.rb +1214 -0
  60. data/lib/dm-core/resource/persistence_state.rb +75 -0
  61. data/lib/dm-core/resource/persistence_state/clean.rb +40 -0
  62. data/lib/dm-core/resource/persistence_state/deleted.rb +30 -0
  63. data/lib/dm-core/resource/persistence_state/dirty.rb +96 -0
  64. data/lib/dm-core/resource/persistence_state/immutable.rb +34 -0
  65. data/lib/dm-core/resource/persistence_state/persisted.rb +29 -0
  66. data/lib/dm-core/resource/persistence_state/transient.rb +80 -0
  67. data/lib/dm-core/spec/lib/adapter_helpers.rb +64 -0
  68. data/lib/dm-core/spec/lib/collection_helpers.rb +21 -0
  69. data/lib/dm-core/spec/lib/counter_adapter.rb +38 -0
  70. data/lib/dm-core/spec/lib/pending_helpers.rb +50 -0
  71. data/lib/dm-core/spec/lib/spec_helper.rb +74 -0
  72. data/lib/dm-core/spec/setup.rb +174 -0
  73. data/lib/dm-core/spec/shared/adapter_spec.rb +341 -0
  74. data/lib/dm-core/spec/shared/public/property_spec.rb +229 -0
  75. data/lib/dm-core/spec/shared/resource_spec.rb +1232 -0
  76. data/lib/dm-core/spec/shared/sel_spec.rb +111 -0
  77. data/lib/dm-core/spec/shared/semipublic/property_spec.rb +176 -0
  78. data/lib/dm-core/spec/shared/semipublic/query/conditions/abstract_comparison_spec.rb +261 -0
  79. data/lib/dm-core/support/assertions.rb +8 -0
  80. data/lib/dm-core/support/chainable.rb +18 -0
  81. data/lib/dm-core/support/deprecate.rb +12 -0
  82. data/lib/dm-core/support/descendant_set.rb +89 -0
  83. data/lib/dm-core/support/equalizer.rb +48 -0
  84. data/lib/dm-core/support/ext/array.rb +22 -0
  85. data/lib/dm-core/support/ext/blank.rb +25 -0
  86. data/lib/dm-core/support/ext/hash.rb +67 -0
  87. data/lib/dm-core/support/ext/module.rb +47 -0
  88. data/lib/dm-core/support/ext/object.rb +57 -0
  89. data/lib/dm-core/support/ext/string.rb +24 -0
  90. data/lib/dm-core/support/ext/try_dup.rb +12 -0
  91. data/lib/dm-core/support/hook.rb +405 -0
  92. data/lib/dm-core/support/inflections.rb +60 -0
  93. data/lib/dm-core/support/inflector/inflections.rb +211 -0
  94. data/lib/dm-core/support/inflector/methods.rb +151 -0
  95. data/lib/dm-core/support/lazy_array.rb +451 -0
  96. data/lib/dm-core/support/local_object_space.rb +13 -0
  97. data/lib/dm-core/support/logger.rb +201 -0
  98. data/lib/dm-core/support/mash.rb +176 -0
  99. data/lib/dm-core/support/naming_conventions.rb +90 -0
  100. data/lib/dm-core/support/ordered_set.rb +380 -0
  101. data/lib/dm-core/support/subject.rb +33 -0
  102. data/lib/dm-core/support/subject_set.rb +250 -0
  103. data/lib/dm-core/version.rb +3 -0
  104. data/script/performance.rb +275 -0
  105. data/script/profile.rb +218 -0
  106. data/spec/lib/rspec_immediate_feedback_formatter.rb +54 -0
  107. data/spec/public/associations/many_to_many/read_multiple_join_spec.rb +68 -0
  108. data/spec/public/associations/many_to_many_spec.rb +197 -0
  109. data/spec/public/associations/many_to_one_spec.rb +83 -0
  110. data/spec/public/associations/many_to_one_with_boolean_cpk_spec.rb +40 -0
  111. data/spec/public/associations/many_to_one_with_custom_fk_spec.rb +49 -0
  112. data/spec/public/associations/one_to_many_spec.rb +81 -0
  113. data/spec/public/associations/one_to_one_spec.rb +176 -0
  114. data/spec/public/associations/one_to_one_with_boolean_cpk_spec.rb +46 -0
  115. data/spec/public/collection_spec.rb +69 -0
  116. data/spec/public/finalize_spec.rb +76 -0
  117. data/spec/public/model/hook_spec.rb +246 -0
  118. data/spec/public/model/property_spec.rb +88 -0
  119. data/spec/public/model/relationship_spec.rb +1040 -0
  120. data/spec/public/model_spec.rb +462 -0
  121. data/spec/public/property/binary_spec.rb +41 -0
  122. data/spec/public/property/boolean_spec.rb +22 -0
  123. data/spec/public/property/class_spec.rb +28 -0
  124. data/spec/public/property/date_spec.rb +22 -0
  125. data/spec/public/property/date_time_spec.rb +22 -0
  126. data/spec/public/property/decimal_spec.rb +23 -0
  127. data/spec/public/property/discriminator_spec.rb +135 -0
  128. data/spec/public/property/float_spec.rb +22 -0
  129. data/spec/public/property/integer_spec.rb +22 -0
  130. data/spec/public/property/object_spec.rb +107 -0
  131. data/spec/public/property/serial_spec.rb +22 -0
  132. data/spec/public/property/string_spec.rb +22 -0
  133. data/spec/public/property/text_spec.rb +63 -0
  134. data/spec/public/property/time_spec.rb +22 -0
  135. data/spec/public/property_spec.rb +341 -0
  136. data/spec/public/resource_spec.rb +288 -0
  137. data/spec/public/sel_spec.rb +53 -0
  138. data/spec/public/setup_spec.rb +145 -0
  139. data/spec/public/shared/association_collection_shared_spec.rb +309 -0
  140. data/spec/public/shared/collection_finder_shared_spec.rb +267 -0
  141. data/spec/public/shared/collection_shared_spec.rb +1667 -0
  142. data/spec/public/shared/finder_shared_spec.rb +1629 -0
  143. data/spec/rcov.opts +6 -0
  144. data/spec/semipublic/adapters/abstract_adapter_spec.rb +30 -0
  145. data/spec/semipublic/adapters/in_memory_adapter_spec.rb +13 -0
  146. data/spec/semipublic/associations/many_to_many_spec.rb +94 -0
  147. data/spec/semipublic/associations/many_to_one_spec.rb +63 -0
  148. data/spec/semipublic/associations/one_to_many_spec.rb +55 -0
  149. data/spec/semipublic/associations/one_to_one_spec.rb +53 -0
  150. data/spec/semipublic/associations/relationship_spec.rb +200 -0
  151. data/spec/semipublic/associations_spec.rb +177 -0
  152. data/spec/semipublic/collection_spec.rb +110 -0
  153. data/spec/semipublic/model_spec.rb +96 -0
  154. data/spec/semipublic/property/binary_spec.rb +13 -0
  155. data/spec/semipublic/property/boolean_spec.rb +47 -0
  156. data/spec/semipublic/property/class_spec.rb +33 -0
  157. data/spec/semipublic/property/date_spec.rb +43 -0
  158. data/spec/semipublic/property/date_time_spec.rb +46 -0
  159. data/spec/semipublic/property/decimal_spec.rb +83 -0
  160. data/spec/semipublic/property/discriminator_spec.rb +19 -0
  161. data/spec/semipublic/property/float_spec.rb +82 -0
  162. data/spec/semipublic/property/integer_spec.rb +82 -0
  163. data/spec/semipublic/property/lookup_spec.rb +29 -0
  164. data/spec/semipublic/property/serial_spec.rb +13 -0
  165. data/spec/semipublic/property/string_spec.rb +13 -0
  166. data/spec/semipublic/property/text_spec.rb +31 -0
  167. data/spec/semipublic/property/time_spec.rb +50 -0
  168. data/spec/semipublic/property_spec.rb +114 -0
  169. data/spec/semipublic/query/conditions/comparison_spec.rb +1501 -0
  170. data/spec/semipublic/query/conditions/operation_spec.rb +1294 -0
  171. data/spec/semipublic/query/path_spec.rb +471 -0
  172. data/spec/semipublic/query_spec.rb +3682 -0
  173. data/spec/semipublic/resource/state/clean_spec.rb +88 -0
  174. data/spec/semipublic/resource/state/deleted_spec.rb +78 -0
  175. data/spec/semipublic/resource/state/dirty_spec.rb +162 -0
  176. data/spec/semipublic/resource/state/immutable_spec.rb +105 -0
  177. data/spec/semipublic/resource/state/transient_spec.rb +162 -0
  178. data/spec/semipublic/resource/state_spec.rb +230 -0
  179. data/spec/semipublic/resource_spec.rb +23 -0
  180. data/spec/semipublic/shared/condition_shared_spec.rb +9 -0
  181. data/spec/semipublic/shared/resource_shared_spec.rb +199 -0
  182. data/spec/semipublic/shared/resource_state_shared_spec.rb +79 -0
  183. data/spec/semipublic/shared/subject_shared_spec.rb +79 -0
  184. data/spec/spec.opts +5 -0
  185. data/spec/spec_helper.rb +38 -0
  186. data/spec/support/core_ext/hash.rb +10 -0
  187. data/spec/support/core_ext/inheritable_attributes.rb +46 -0
  188. data/spec/support/properties/huge_integer.rb +17 -0
  189. data/spec/unit/array_spec.rb +23 -0
  190. data/spec/unit/blank_spec.rb +73 -0
  191. data/spec/unit/data_mapper/ordered_set/append_spec.rb +26 -0
  192. data/spec/unit/data_mapper/ordered_set/clear_spec.rb +24 -0
  193. data/spec/unit/data_mapper/ordered_set/delete_spec.rb +28 -0
  194. data/spec/unit/data_mapper/ordered_set/each_spec.rb +19 -0
  195. data/spec/unit/data_mapper/ordered_set/empty_spec.rb +20 -0
  196. data/spec/unit/data_mapper/ordered_set/entries_spec.rb +22 -0
  197. data/spec/unit/data_mapper/ordered_set/eql_spec.rb +51 -0
  198. data/spec/unit/data_mapper/ordered_set/equal_value_spec.rb +84 -0
  199. data/spec/unit/data_mapper/ordered_set/hash_spec.rb +12 -0
  200. data/spec/unit/data_mapper/ordered_set/include_spec.rb +23 -0
  201. data/spec/unit/data_mapper/ordered_set/index_spec.rb +28 -0
  202. data/spec/unit/data_mapper/ordered_set/initialize_spec.rb +32 -0
  203. data/spec/unit/data_mapper/ordered_set/merge_spec.rb +36 -0
  204. data/spec/unit/data_mapper/ordered_set/shared/append_spec.rb +24 -0
  205. data/spec/unit/data_mapper/ordered_set/shared/clear_spec.rb +9 -0
  206. data/spec/unit/data_mapper/ordered_set/shared/delete_spec.rb +25 -0
  207. data/spec/unit/data_mapper/ordered_set/shared/each_spec.rb +17 -0
  208. data/spec/unit/data_mapper/ordered_set/shared/empty_spec.rb +9 -0
  209. data/spec/unit/data_mapper/ordered_set/shared/entries_spec.rb +9 -0
  210. data/spec/unit/data_mapper/ordered_set/shared/include_spec.rb +9 -0
  211. data/spec/unit/data_mapper/ordered_set/shared/index_spec.rb +13 -0
  212. data/spec/unit/data_mapper/ordered_set/shared/initialize_spec.rb +28 -0
  213. data/spec/unit/data_mapper/ordered_set/shared/merge_spec.rb +28 -0
  214. data/spec/unit/data_mapper/ordered_set/shared/size_spec.rb +13 -0
  215. data/spec/unit/data_mapper/ordered_set/shared/to_ary_spec.rb +11 -0
  216. data/spec/unit/data_mapper/ordered_set/size_spec.rb +27 -0
  217. data/spec/unit/data_mapper/ordered_set/to_ary_spec.rb +23 -0
  218. data/spec/unit/data_mapper/subject_set/append_spec.rb +47 -0
  219. data/spec/unit/data_mapper/subject_set/clear_spec.rb +34 -0
  220. data/spec/unit/data_mapper/subject_set/delete_spec.rb +40 -0
  221. data/spec/unit/data_mapper/subject_set/each_spec.rb +30 -0
  222. data/spec/unit/data_mapper/subject_set/empty_spec.rb +31 -0
  223. data/spec/unit/data_mapper/subject_set/entries_spec.rb +31 -0
  224. data/spec/unit/data_mapper/subject_set/get_spec.rb +34 -0
  225. data/spec/unit/data_mapper/subject_set/include_spec.rb +32 -0
  226. data/spec/unit/data_mapper/subject_set/named_spec.rb +33 -0
  227. data/spec/unit/data_mapper/subject_set/shared/append_spec.rb +18 -0
  228. data/spec/unit/data_mapper/subject_set/shared/clear_spec.rb +9 -0
  229. data/spec/unit/data_mapper/subject_set/shared/delete_spec.rb +9 -0
  230. data/spec/unit/data_mapper/subject_set/shared/each_spec.rb +9 -0
  231. data/spec/unit/data_mapper/subject_set/shared/empty_spec.rb +9 -0
  232. data/spec/unit/data_mapper/subject_set/shared/entries_spec.rb +9 -0
  233. data/spec/unit/data_mapper/subject_set/shared/get_spec.rb +9 -0
  234. data/spec/unit/data_mapper/subject_set/shared/include_spec.rb +9 -0
  235. data/spec/unit/data_mapper/subject_set/shared/named_spec.rb +9 -0
  236. data/spec/unit/data_mapper/subject_set/shared/size_spec.rb +13 -0
  237. data/spec/unit/data_mapper/subject_set/shared/to_ary_spec.rb +9 -0
  238. data/spec/unit/data_mapper/subject_set/shared/values_at_spec.rb +44 -0
  239. data/spec/unit/data_mapper/subject_set/size_spec.rb +42 -0
  240. data/spec/unit/data_mapper/subject_set/to_ary_spec.rb +34 -0
  241. data/spec/unit/data_mapper/subject_set/values_at_spec.rb +57 -0
  242. data/spec/unit/hash_spec.rb +28 -0
  243. data/spec/unit/hook_spec.rb +1235 -0
  244. data/spec/unit/inflections_spec.rb +16 -0
  245. data/spec/unit/lazy_array_spec.rb +1949 -0
  246. data/spec/unit/mash_spec.rb +312 -0
  247. data/spec/unit/module_spec.rb +71 -0
  248. data/spec/unit/object_spec.rb +38 -0
  249. data/spec/unit/try_dup_spec.rb +46 -0
  250. data/tasks/ci.rake +1 -0
  251. data/tasks/spec.rake +38 -0
  252. data/tasks/yard.rake +9 -0
  253. data/tasks/yardstick.rake +19 -0
  254. metadata +365 -0
data/.autotest ADDED
@@ -0,0 +1,29 @@
1
+ Autotest.add_hook :initialize do |at|
2
+ %w[ .git log script tasks LICENSE README.rdoc ].each do |exception|
3
+ at.add_exception(exception)
4
+ end
5
+
6
+ at.clear_mappings
7
+
8
+ spec_folders = /(?:semi)?public/
9
+
10
+ # when a file is updated, make sure it's dependent public and semipublic specs pass
11
+ at.add_mapping %r{\Alib/dm\-core/(.+)\.rb\z} do |_,match|
12
+ at.files_matching %r{\Aspec/#{spec_folders}/#{match[1]}_spec\.rb\z}
13
+ end
14
+
15
+ # when the spec configuration changes make sure all specs pass
16
+ at.add_mapping %r{\Aspec/spec_helper\.rb\z} do
17
+ at.files_matching %r{\Aspec/.+_spec\.rb\z}
18
+ end
19
+
20
+ # when a spec is updated, make sure it passes
21
+ at.add_mapping %r{\Aspec/#{spec_folders}/(.+)_spec\.rb\z} do |filename,_|
22
+ filename
23
+ end
24
+
25
+ # when the collection shared spec is update, make sure all dependent specs pass
26
+ at.add_mapping %r{\Aspec/lib/collection_shared_spec\.rb\z} do
27
+ at.files_matching %r{\Aspec/#{spec_folders}/collection_spec\.rb\z}
28
+ end
29
+ end
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ --
4
+ README.rdoc
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,35 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## Rubinius
17
+ *.rbc
18
+
19
+ ## PROJECT::GENERAL
20
+ *.gem
21
+ coverage
22
+ rdoc
23
+ pkg
24
+ tmp
25
+ doc
26
+ log
27
+ .yardoc
28
+ measurements
29
+
30
+ ## BUNDLER
31
+ .bundle
32
+ Gemfile.*
33
+
34
+ ## PROJECT::SPECIFIC
35
+ spec/db/
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup rdoc --title 'DataMapper Documentation' --protected
data/Gemfile ADDED
@@ -0,0 +1,65 @@
1
+ require File.expand_path('../lib/dm-core/version', __FILE__)
2
+
3
+ require 'pathname'
4
+
5
+ source :rubygems
6
+
7
+ gemspec
8
+
9
+ gem 'virtus', '~> 0.5', :git => 'https://github.com/solnic/virtus'
10
+
11
+ SOURCE = ENV.fetch('SOURCE', :git).to_sym
12
+ REPO_POSTFIX = SOURCE == :path ? '' : '.git'
13
+ DATAMAPPER = SOURCE == :path ? Pathname(__FILE__).dirname.parent : 'https://github.com/datamapper'
14
+ DM_VERSION = "~> #{DataMapper::VERSION}"
15
+ DO_VERSION = '~> 0.10.6'
16
+ DM_DO_ADAPTERS = %w[ sqlite postgres mysql oracle sqlserver ]
17
+ CURRENT_BRANCH = ENV.fetch('GIT_BRANCH', 'master')
18
+
19
+ platforms :mri_18 do
20
+ group :quality do
21
+
22
+ gem 'rcov', '~> 0.9.10'
23
+ gem 'yard', '~> 0.7.2'
24
+ gem 'yardstick', '~> 0.4'
25
+
26
+ end
27
+ end
28
+
29
+ group :datamapper do
30
+
31
+ adapters = ENV['ADAPTERS'] || ENV['ADAPTER']
32
+ adapters = adapters.to_s.tr(',', ' ').split.uniq - %w[ in_memory ]
33
+
34
+ if (do_adapters = DM_DO_ADAPTERS & adapters).any?
35
+ do_options = {}
36
+ do_options[:git] = "#{DATAMAPPER}/do#{REPO_POSTFIX}" if ENV['DO_GIT'] == 'true'
37
+
38
+ gem 'data_objects', DO_VERSION, do_options.dup
39
+
40
+ do_adapters.each do |adapter|
41
+ adapter = 'sqlite3' if adapter == 'sqlite'
42
+ gem "do_#{adapter}", DO_VERSION, do_options.dup
43
+ end
44
+
45
+ gem 'dm-do-adapter', DM_VERSION,
46
+ SOURCE => "#{DATAMAPPER}/dm-do-adapter#{REPO_POSTFIX}",
47
+ :branch => CURRENT_BRANCH
48
+ end
49
+
50
+ adapters.each do |adapter|
51
+ gem "dm-#{adapter}-adapter", ENV.fetch('ADAPTER_VERSION', DM_VERSION),
52
+ SOURCE => "#{DATAMAPPER}/dm-#{adapter}-adapter#{REPO_POSTFIX}",
53
+ :branch => CURRENT_BRANCH
54
+ end
55
+
56
+ plugins = ENV['PLUGINS'] || ENV['PLUGIN']
57
+ plugins = plugins.to_s.tr(',', ' ').split.push('dm-migrations').uniq
58
+
59
+ plugins.each do |plugin|
60
+ gem plugin, DM_VERSION,
61
+ SOURCE => "#{DATAMAPPER}/#{plugin}#{REPO_POSTFIX}",
62
+ :branch => CURRENT_BRANCH
63
+ end
64
+
65
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Dan Kubb
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,269 @@
1
+ Why DataMapper?
2
+ ===============
3
+
4
+ Open Development
5
+ ----------------
6
+
7
+ DataMapper sports a very accessible code-base and a welcoming community.
8
+ Outside contributions and feedback are welcome and encouraged, especially
9
+ constructive criticism. Make your voice heard! [Submit an issue](https://github.com/datamapper/dm-core/issues),
10
+ speak up on our [mailing-list](http://groups.google.com/group/datamapper/),
11
+ chat with us on [irc](irc://irc.freenode.net/#datamapper), write a spec, get it
12
+ reviewed, ask for commit rights. It's as easy as that to become a contributor.
13
+
14
+ Identity Map
15
+ ------------
16
+
17
+ One row in the data-store should equal one object reference. Pretty simple idea.
18
+ Pretty profound impact. If you run the following code in ActiveRecord you'll
19
+ see all `false` results. Do the same in DataMapper and it's
20
+ `true` all the way down.
21
+
22
+ ``` ruby
23
+ repository do
24
+ @parent = Tree.first(:name => 'bob')
25
+
26
+ @parent.children.each do |child|
27
+ puts @parent.equal?(child.parent) # => true
28
+ end
29
+ end
30
+ ```
31
+
32
+ This makes DataMapper faster and allocate less resources to get things done.
33
+
34
+ Dirty Tracking
35
+ --------------
36
+
37
+ When you save a model back to your data-store, DataMapper will only write
38
+ the fields that actually changed. So it plays well with others. You can
39
+ use it in an Integration data-store without worrying that your application will
40
+ be a bad actor causing trouble for all of your other processes.
41
+
42
+ Eager Loading
43
+ -------------
44
+
45
+ Ready for something amazing? The following example executes only two queries
46
+ regardless of how many rows the inner and outer queries return.
47
+
48
+ ``` ruby
49
+ repository do
50
+ Zoo.all.each { |zoo| zoo.exhibits.to_a }
51
+ end
52
+ ```
53
+
54
+ Pretty impressive huh? The idea is that you aren't going to load a set of
55
+ objects and use only an association in just one of them. This should hold up
56
+ pretty well against a 99% rule. When you don't want it to work like this, just
57
+ load the item you want in it's own set. So the DataMapper thinks ahead. We
58
+ like to call it "performant by default". This feature single-handedly wipes
59
+ out the "N+1 Query Problem". No need to specify an `:include` option in
60
+ your finders.
61
+
62
+ Laziness Can Be A Virtue
63
+ ------------------------
64
+
65
+ Text fields are expensive in data-stores. They're generally stored in a
66
+ different place than the rest of your data. So instead of a fast sequential
67
+ read from your hard-drive, your data-store server has to hop around all over the
68
+ place to get what it needs. Since ActiveRecord returns everything by default,
69
+ adding a text field to a table slows everything down drastically, across the
70
+ board.
71
+
72
+ Not so with the DataMapper. Text fields are lazily loaded, meaning they
73
+ only load when you need them. If you want more control you can enable or
74
+ disable this feature for any field (not just text-fields) by passing a
75
+ `:lazy` option to your field mapping with a value of `true` or
76
+ `false`.
77
+
78
+ ``` ruby
79
+ class Animal
80
+ include DataMapper::Resource
81
+
82
+ property :name, String
83
+ property :description, Text, :lazy => false
84
+ end
85
+ ```
86
+
87
+ Plus, lazy-loading of Text fields happens automatically and intelligently when
88
+ working with associations. The following only issues 2 queries to load up all
89
+ of the notes fields on each animal:
90
+
91
+ ``` ruby
92
+ repository do
93
+ Animal.all.each { |animal| animal.description.to_a }
94
+ end
95
+ ```
96
+
97
+ Did you notice the `#to_a` call in the above example? That
98
+ was necessary because even DataMapper collections are lazy. If you don't
99
+ iterate over them, or in this case ask them to become Arrays, they won't
100
+ execute until you need them. We needed to call `#to_a` to force
101
+ the lazy load because without it, the above example would have only
102
+ executed one query. This extra bit of laziness can come in very handy,
103
+ for example:
104
+
105
+ ``` ruby
106
+ animals = Animal.all
107
+ description = 'foo'
108
+
109
+ animals.each do |animal|
110
+ animal.update(:description => description)
111
+ end
112
+ ```
113
+
114
+ In the above example, the Animals won't be retrieved until you actually
115
+ need them. This comes in handy in cases where you initialize the
116
+ collection before you know if you need it, like in a web app controller.
117
+
118
+ Collection Chaining
119
+ -------------------
120
+
121
+ DataMapper's lazy collections are also handy because you can get the
122
+ same effect as named scopes, without any special syntax, eg:
123
+
124
+ ``` ruby
125
+ class Animal
126
+ # ... setup ...
127
+
128
+ def self.mammals
129
+ all(:mammal => true)
130
+ end
131
+
132
+ def self.zoo(zoo)
133
+ all(:zoo => zoo)
134
+ end
135
+ end
136
+
137
+ zoo = Zoo.first(:name => 'Greater Vancouver Zoo')
138
+
139
+ Animal.mammals.zoo(zoo).to_a # => executes one query
140
+ ```
141
+
142
+ In the above example, we ask the Animal model for all the mammals,
143
+ and then all the animals in a specific zoo, and DataMapper will chain
144
+ the collection queries together and execute a single query to retrieve
145
+ the matching records. There's no special syntax, and no custom DSLs
146
+ to learn, it's just plain ruby all the way down.
147
+
148
+ You can even use this on association collections, eg:
149
+
150
+ ``` ruby
151
+ zoo.animals.mammals.to_a # => executes one query
152
+ ```
153
+
154
+ Custom Properties
155
+ -----------------
156
+
157
+ With DataMapper it is possible to create custom properties for your models.
158
+ Consider this example:
159
+
160
+ ``` ruby
161
+ module DataMapper
162
+ class Property
163
+ class Email < String
164
+ required true
165
+ format /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
166
+ end
167
+ end
168
+ end
169
+
170
+ class User
171
+ include DataMapper::Resource
172
+
173
+ property :id, Serial
174
+ property :email, Email
175
+ end
176
+ ```
177
+
178
+ This way there won't be a need to repeat same property options every time you
179
+ add an email to a model. In the example above we create an Email property which
180
+ is just a String with additional pre-configured options: `required` and
181
+ `format`. Please note that it is possible to override these options when
182
+ declaring a property, like this:
183
+
184
+ ``` ruby
185
+ class Member
186
+ include DataMapper::Resource
187
+
188
+ property :id, Serial
189
+ property :email, Email, :required => false
190
+ end
191
+ ```
192
+
193
+ Plays Well With Others
194
+ ----------------------
195
+
196
+ In ActiveRecord, all your fields are mapped, whether you want them or not.
197
+ This slows things down. In the DataMapper you define your mappings in your
198
+ model. So instead of an _ALTER TABLE ADD field_ in your data-store, you simply
199
+ add a `property :name, String` to your model. DRY. No schema.rb. No
200
+ migration files to conflict or die without reverting changes. Your model
201
+ drives the data-store, not the other way around.
202
+
203
+ Unless of course you want to map to a legacy data-store. Raise your hand if you
204
+ like seeing a method called `col2Name` on your model just because
205
+ that's what it's called in an old data-store you can't afford to change right
206
+ now? In DataMapper you control the mappings:
207
+
208
+ ``` ruby
209
+ class Fruit
210
+ include DataMapper::Resource
211
+
212
+ storage_names[:repo] = 'frt'
213
+
214
+ property :name, String, :field => 'col2Name'
215
+ end
216
+ ```
217
+
218
+ All Ruby, All The Time
219
+ ----------------------
220
+
221
+ It's great that ActiveRecord allows you to write SQL when you need to, but
222
+ should we have to so often?
223
+
224
+ DataMapper supports issuing your own query, but it also provides more helpers
225
+ and a unique hash-based condition syntax to cover more of the use-cases where
226
+ issuing your own SQL would have been the only way to go. For example, any
227
+ finder option that's non-standard is considered a condition. So you can write
228
+ `Zoo.all(:name => 'Dallas')` and DataMapper will look for zoos with the
229
+ name of 'Dallas'.
230
+
231
+ It's just a little thing, but it's so much nicer than writing
232
+ `Zoo.find(:all, :conditions => ['name = ?', 'Dallas'])`. What if you
233
+ need other comparisons though? Try these:
234
+
235
+ ``` ruby
236
+ # 'gt' means greater-than. We also do 'lt'.
237
+ Person.all(:age.gt => 30)
238
+
239
+ # 'gte' means greather-than-or-equal-to. We also do 'lte'.
240
+ Person.all(:age.gte => 30)
241
+
242
+ # 'not' allows you to match all people without the name "bob"
243
+ Person.all(:name.not => 'bob')
244
+
245
+ # If the value of a pair is an Array, we do an IN-clause for you.
246
+ Person.all(:name.like => 'S%', :id => [ 1, 2, 3, 4, 5 ])
247
+
248
+ # Does a NOT IN () clause for you.
249
+ Person.all(:name.not => [ 'bob', 'rick', 'steve' ])
250
+ ```
251
+
252
+ See? Fewer SQL fragments dirtying your Ruby code. And that's just a few of the
253
+ nice syntax tweaks DataMapper delivers out of the box...
254
+
255
+ Note on Patches/Pull Requests
256
+ -----------------------------
257
+
258
+ * Fork the project.
259
+ * Make your feature addition or bug fix.
260
+ * Add tests for it. This is important so I don't break it in a
261
+ future version unintentionally.
262
+ * Commit, do not mess with rakefile, version, or history.
263
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
264
+ * Send me a pull request. Bonus points for topic branches.
265
+
266
+ Copyright
267
+ ---------
268
+
269
+ Copyright (c) 2012 Dan Kubb. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ FileList['tasks/**/*.rake'].each { |task| import task }
data/dm-core.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/dm-core/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = [ "Jon Rose" ]
6
+ gem.email = [ "jonrose08@gmail.com" ]
7
+ gem.summary = "An Object/Relational Mapper for Ruby"
8
+ gem.description = "Faster, Better, Simpler."
9
+ gem.date = "2012-10-02"
10
+
11
+ gem.files = `git ls-files`.split("\n")
12
+ gem.test_files = `git ls-files -- {spec}/*`.split("\n")
13
+ gem.extra_rdoc_files = %w[LICENSE README.md]
14
+
15
+ gem.name = "ghost_dm-core"
16
+ gem.require_paths = [ "lib" ]
17
+ gem.version = DataMapper::VERSION
18
+
19
+ gem.add_runtime_dependency('addressable', '~> 2.2.6')
20
+ gem.add_runtime_dependency('virtus', '~> 0.5')
21
+
22
+ gem.add_development_dependency('rake', '~> 0.9.2')
23
+ gem.add_development_dependency('rspec', '~> 1.3.2')
24
+ end