Guest User

Untitled

a guest
May 21st, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.20 KB | None | 0 0
  1. diff --git a/lib/dm-core.rb b/lib/dm-core.rb
  2. index 6165b18..070f903 100644
  3. --- a/lib/dm-core.rb
  4. +++ b/lib/dm-core.rb
  5. @@ -169,26 +169,19 @@ module DataMapper
  6. # @param [Symbol] args the name of a repository to act within or return, :default is default
  7. # @yield [Proc] (optional) block to execute within the context of the named repository
  8. # @demo spec/integration/repository_spec.rb
  9. - def self.repository(*args, &block) # :yields: current_context
  10. - if args.size > 1
  11. - raise ArgumentError, "Can only pass in one optional argument, but passed in #{args.size} arguments", caller
  12. - end
  13. -
  14. - if args.any? && !args.first.kind_of?(Symbol)
  15. - raise ArgumentError, "First optional argument must be a Symbol, but was #{args.first.inspect}", caller
  16. - end
  17. -
  18. - name = args.first
  19. -
  20. + def self.repository(name = nil) # :yields: current_context
  21. current_repository = if name
  22. + raise ArgumentError, "First optional argument must be a Symbol, but was #{args.first.inspect}" unless name.is_a?(Symbol)
  23. Repository.context.detect { |r| r.name == name } || Repository.new(name)
  24. else
  25. Repository.context.last || Repository.new(Repository.default_name)
  26. end
  27.  
  28. - return current_repository unless block_given?
  29. -
  30. - current_repository.scope(&block)
  31. + if block_given?
  32. + current_repository.scope { |*block_args| yield(*block_args) }
  33. + else
  34. + current_repository
  35. + end
  36. end
  37.  
  38. # A logger should always be present. Lets be consistent with DO
  39. diff --git a/lib/dm-core/adapters/data_objects_adapter.rb b/lib/dm-core/adapters/data_objects_adapter.rb
  40. index 4197732..6204aa6 100644
  41. --- a/lib/dm-core/adapters/data_objects_adapter.rb
  42. +++ b/lib/dm-core/adapters/data_objects_adapter.rb
  43. @@ -164,7 +164,7 @@ module DataMapper
  44. end
  45. end
  46.  
  47. - def with_connection(&block)
  48. + def with_connection
  49. connection = nil
  50. begin
  51. connection = create_connection
  52. @@ -177,7 +177,7 @@ module DataMapper
  53. end
  54. end
  55.  
  56. - def with_reader(statement, bind_values = [], &block)
  57. + def with_reader(statement, bind_values = [])
  58. with_connection do |connection|
  59. reader = nil
  60. begin
  61. diff --git a/lib/dm-core/adapters/postgres_adapter.rb b/lib/dm-core/adapters/postgres_adapter.rb
  62. index ed25893..1c8774e 100644
  63. --- a/lib/dm-core/adapters/postgres_adapter.rb
  64. +++ b/lib/dm-core/adapters/postgres_adapter.rb
  65. @@ -86,7 +86,7 @@ module DataMapper
  66. end
  67.  
  68. # TODO: move to dm-more/dm-migrations
  69. - def without_notices(&block)
  70. + def without_notices
  71. # execute the block with NOTICE messages disabled
  72. begin
  73. execute('SET client_min_messages = warning')
  74. diff --git a/lib/dm-core/associations/one_to_many.rb b/lib/dm-core/associations/one_to_many.rb
  75. index b079563..24d04ce 100644
  76. --- a/lib/dm-core/associations/one_to_many.rb
  77. +++ b/lib/dm-core/associations/one_to_many.rb
  78. @@ -132,7 +132,7 @@ module DataMapper
  79. orphan_resource(super)
  80. end
  81.  
  82. - def delete(resource, &block)
  83. + def delete(resource)
  84. assert_mutable
  85. orphan_resource(super)
  86. end
  87. diff --git a/lib/dm-core/associations/relationship.rb b/lib/dm-core/associations/relationship.rb
  88. index 3007f10..0e202ec 100644
  89. --- a/lib/dm-core/associations/relationship.rb
  90. +++ b/lib/dm-core/associations/relationship.rb
  91. @@ -157,14 +157,14 @@ module DataMapper
  92. end
  93.  
  94. # @api private
  95. - def with_repository(object = nil, &block)
  96. + def with_repository(object = nil)
  97. other_model = object.model == child_model ? parent_model : child_model if object.respond_to?(:model)
  98. other_model = object == child_model ? parent_model : child_model if object.kind_of?(DataMapper::Resource)
  99.  
  100. if other_model && other_model.repository == object.repository && object.repository.name != @repository_name
  101. - object.repository.scope(&block)
  102. + object.repository.scope { |block_args| yield(*block_args) }
  103. else
  104. - repository(@repository_name, &block)
  105. + repository(@repository_name) { |block_args| yield(*block_args) }
  106. end
  107. end
  108.  
  109. diff --git a/lib/dm-core/collection.rb b/lib/dm-core/collection.rb
  110. index a260ffe..7e09b3d 100644
  111. --- a/lib/dm-core/collection.rb
  112. +++ b/lib/dm-core/collection.rb
  113. @@ -295,7 +295,7 @@ module DataMapper
  114. # @see Array#delete
  115. #
  116. # @api public
  117. - def delete(resource, &block)
  118. + def delete(resource)
  119. orphan_resource(super)
  120. end
  121.  
  122. diff --git a/lib/dm-core/model.rb b/lib/dm-core/model.rb
  123. index a710297..e8e26c8 100644
  124. --- a/lib/dm-core/model.rb
  125. +++ b/lib/dm-core/model.rb
  126. @@ -102,13 +102,17 @@ module DataMapper
  127. # if given a block, otherwise the requested repository.
  128. #-
  129. # @api public
  130. - def repository(name = nil, &block)
  131. + def repository(name = nil)
  132. #
  133. # There has been a couple of different strategies here, but me (zond) and dkubb are at least
  134. # united in the concept of explicitness over implicitness. That is - the explicit wish of the
  135. # caller (+name+) should be given more priority than the implicit wish of the caller (Repository.context.last).
  136. #
  137. - DataMapper.repository(name || repository_name, &block)
  138. + if block_given?
  139. + DataMapper.repository(name || repository_name) { |*block_args| yield(*block_args) }
  140. + else
  141. + DataMapper.repository(name || repository_name)
  142. + end
  143. end
  144.  
  145. ##
  146. @@ -219,7 +223,8 @@ module DataMapper
  147. end
  148.  
  149. def default_order(repository_name = default_repository_name)
  150. - key(repository_name).map { |property| Query::Direction.new(property) }
  151. + @default_order ||= {}
  152. + @default_order[repository_name] ||= key(repository_name).map { |property| Query::Direction.new(property) }
  153. end
  154.  
  155. def get(*key)
  156. @@ -451,8 +456,8 @@ module DataMapper
  157. # @api public
  158. #
  159. # TODO: move to dm-more/dm-transactions
  160. - def transaction(&block)
  161. - DataMapper::Transaction.new(self, &block)
  162. + def transaction
  163. + DataMapper::Transaction.new(self) { |block_args| yield(*block_args) }
  164. end
  165. end # module Transaction
  166.  
  167. diff --git a/lib/dm-core/property.rb b/lib/dm-core/property.rb
  168. index de9213f..9f70504 100644
  169. --- a/lib/dm-core/property.rb
  170. +++ b/lib/dm-core/property.rb
  171. @@ -432,13 +432,6 @@ module DataMapper
  172. new_value = typecast(value)
  173. old_value = get!(resource)
  174.  
  175. - # skip setting the property if the new value is equal
  176. - # to the old value, and the old value was defined
  177. - # ---
  178. - # [YK] Why bother? Does this change the result at all?
  179. - # ---
  180. - # return if new_value == old_value && resource.attribute_loaded?(name)
  181. -
  182. set_original_value(resource, old_value)
  183.  
  184. set!(resource, new_value)
  185. diff --git a/lib/dm-core/property_set.rb b/lib/dm-core/property_set.rb
  186. index 40d75b6..629d4fc 100755
  187. --- a/lib/dm-core/property_set.rb
  188. +++ b/lib/dm-core/property_set.rb
  189. @@ -8,6 +8,7 @@ module DataMapper
  190. end
  191.  
  192. def []=(name, property)
  193. + @key, @defaults = nil
  194. if existing_property = detect { |p| p.name == name }
  195. property.hash
  196. @entries[@entries.index(existing_property)] = property
  197. @@ -22,10 +23,12 @@ module DataMapper
  198. end
  199.  
  200. def slice(*names)
  201. + @key, @defaults = nil
  202. @property_for.values_at(*names)
  203. end
  204.  
  205. def add(*properties)
  206. + @key, @defaults = nil
  207. @entries.push(*properties)
  208. properties.each { |property| property.hash }
  209. self
  210. @@ -47,11 +50,11 @@ module DataMapper
  211. end
  212.  
  213. def defaults
  214. - reject { |property| property.lazy? }
  215. + @defaults ||= reject { |property| property.lazy? }
  216. end
  217.  
  218. def key
  219. - select { |property| property.key? }
  220. + @key ||= select { |property| property.key? }
  221. end
  222.  
  223. def indexes
  224. @@ -132,6 +135,7 @@ module DataMapper
  225. end
  226.  
  227. def initialize_copy(orig)
  228. + @key, @defaults = nil
  229. @entries = orig.entries.dup
  230. @property_for = hash_for_property_for
  231. end
  232. diff --git a/lib/dm-core/query.rb b/lib/dm-core/query.rb
  233. index 81c2b32..3c48b88 100644
  234. --- a/lib/dm-core/query.rb
  235. +++ b/lib/dm-core/query.rb
  236. @@ -190,7 +190,7 @@ module DataMapper
  237. @includes = normalize_includes(@includes)
  238.  
  239. # treat all non-options as conditions
  240. - (options.keys - OPTIONS - OPTIONS.map { |option| option.to_s }).each do |k|
  241. + (options.keys - OPTIONS).each do |k|
  242. append_condition(k, options[k])
  243. end
  244.  
  245. @@ -218,53 +218,50 @@ module DataMapper
  246.  
  247. # validate the options
  248. def assert_valid_options(options)
  249. - # validate the reload option and unique option
  250. - ([ :reload, :unique ] & options.keys).each do |attribute|
  251. - if options[attribute] != true && options[attribute] != false
  252. - raise ArgumentError, "+options[:#{attribute}]+ must be true or false, but was #{options[attribute].inspect}", caller(2)
  253. - end
  254. - end
  255. -
  256. - # validate the offset and limit options
  257. - ([ :offset, :limit ] & options.keys).each do |attribute|
  258. - value = options[attribute]
  259. - assert_kind_of "options[:#{attribute}]", value, Integer
  260. - end
  261. -
  262. - if options.has_key?(:offset) && options[:offset] < 0
  263. - raise ArgumentError, "+options[:offset]+ must be greater than or equal to 0, but was #{options[:offset].inspect}", caller(2)
  264. - end
  265. -
  266. - if options.has_key?(:limit) && options[:limit] < 1
  267. - raise ArgumentError, "+options[:limit]+ must be greater than or equal to 1, but was #{options[:limit].inspect}", caller(2)
  268. - end
  269. + # [DB] This might look more ugly now, but it's 2x as fast as the old code
  270. + # [DB] This is one of the heavy spots for Query.new I found during profiling.
  271. + options.each_pair do |attribute, value|
  272. +
  273. + # validate the reload option and unique option
  274. + if [:reload, :unique].include? attribute
  275. + if value != true && value != false
  276. + raise ArgumentError, "+options[:#{attribute}]+ must be true or false, but was #{value.inspect}", caller(2)
  277. + end
  278.  
  279. - # validate the order, fields, links, includes and conditions options
  280. - ([ :order, :fields, :links, :includes ] & options.keys).each do |attribute|
  281. - value = options[attribute]
  282. - assert_kind_of "options[:#{attribute}]", value, Array
  283. + # validate the offset and limit options
  284. + elsif [:offset, :limit].include? attribute
  285. + assert_kind_of "options[:#{attribute}]", value, Integer
  286. + if attribute == :offset && value < 0
  287. + raise ArgumentError, "+options[:offset]+ must be greater than or equal to 0, but was #{value.inspect}", caller(2)
  288. + elsif attribute == :limit && value < 1
  289. + raise ArgumentError, "+options[:limit]+ must be greater than or equal to 1, but was #{options[:limit].inspect}", caller(2)
  290. + end
  291.  
  292. - if value.empty?
  293. - if attribute == :fields
  294. - if options[:unique] == false
  295. - raise ArgumentError, '+options[:fields]+ cannot be empty if +options[:unique] is false', caller(2)
  296. + # validate the :order, :fields, :links and :includes options
  297. + elsif [ :order, :fields, :links, :includes ].include? attribute
  298. + assert_kind_of "options[:#{attribute}]", value, Array
  299. +
  300. + if value.empty?
  301. + if attribute == :fields
  302. + if options[:unique] == false
  303. + raise ArgumentError, '+options[:fields]+ cannot be empty if +options[:unique] is false', caller(2)
  304. + end
  305. + elsif attribute == :order
  306. + if options[:fields] && options[:fields].any? { |p| !p.kind_of?(Operator) }
  307. + raise ArgumentError, '+options[:order]+ cannot be empty if +options[:fields] contains a non-operator', caller(2)
  308. + end
  309. + else
  310. + raise ArgumentError, "+options[:#{attribute}]+ cannot be empty", caller(2)
  311. end
  312. - elsif attribute == :order
  313. - if options[:fields] && options[:fields].any? { |p| !p.kind_of?(Operator) }
  314. - raise ArgumentError, '+options[:order]+ cannot be empty if +options[:fields] contains a non-operator', caller(2)
  315. - end
  316. - else
  317. - raise ArgumentError, "+options[:#{attribute}]+ cannot be empty", caller(2)
  318. end
  319. - end
  320. - end
  321.  
  322. - if options.has_key?(:conditions)
  323. - value = options[:conditions]
  324. - assert_kind_of 'options[:conditions]', value, Hash, Array
  325. + # validates the :conditions option
  326. + elsif :conditions == attribute
  327. + assert_kind_of 'options[:conditions]', value, Hash, Array
  328.  
  329. - if value.empty?
  330. - raise ArgumentError, '+options[:conditions]+ cannot be empty', caller(2)
  331. + if value.empty?
  332. + raise ArgumentError, '+options[:conditions]+ cannot be empty', caller(2)
  333. + end
  334. end
  335. end
  336. end
  337. diff --git a/lib/dm-core/repository.rb b/lib/dm-core/repository.rb
  338. index 2f0627f..85e9616 100755
  339. --- a/lib/dm-core/repository.rb
  340. +++ b/lib/dm-core/repository.rb
  341. @@ -33,11 +33,11 @@ module DataMapper
  342. end
  343.  
  344. def identity_map(model)
  345. - @identity_maps[model]
  346. + @identity_maps[model] ||= IdentityMap.new
  347. end
  348.  
  349. # TODO: spec this
  350. - def scope(&block)
  351. + def scope
  352. Repository.context << self
  353.  
  354. begin
  355. @@ -97,7 +97,7 @@ module DataMapper
  356. assert_kind_of 'name', name, Symbol
  357.  
  358. @name = name
  359. - @identity_maps = Hash.new { |h,model| h[model] = IdentityMap.new }
  360. + @identity_maps = {}
  361. end
  362.  
  363. # TODO: move to dm-more/dm-migrations
  364. diff --git a/lib/dm-core/resource.rb b/lib/dm-core/resource.rb
  365. index d011a60..308b9c3 100644
  366. --- a/lib/dm-core/resource.rb
  367. +++ b/lib/dm-core/resource.rb
  368. @@ -588,7 +588,7 @@ module DataMapper
  369. raise IncompleteResourceError, "#{model.name} must have a key."
  370. end
  371.  
  372. - class << self; @_valid_model = true; end
  373. + self.class.instance_variable_set("@_valid_model", true)
  374. end
  375.  
  376. # TODO document
  377. @@ -627,8 +627,8 @@ module DataMapper
  378. # @api public
  379. #
  380. # TODO: move to dm-more/dm-transactions
  381. - def transaction(&block)
  382. - model.transaction(&block)
  383. + def transaction
  384. + model.transaction { |*block_args| yield(*block_args) }
  385. end
  386. end # module Transaction
  387.  
  388. diff --git a/lib/dm-core/scope.rb b/lib/dm-core/scope.rb
  389. index 6c90cb9..646f51c 100644
  390. --- a/lib/dm-core/scope.rb
  391. +++ b/lib/dm-core/scope.rb
  392. @@ -17,13 +17,13 @@ module DataMapper
  393. protected
  394.  
  395. # @api semipublic
  396. - def with_scope(query, &block)
  397. + def with_scope(query)
  398. # merge the current scope with the passed in query
  399. - with_exclusive_scope(self.query ? self.query.merge(query) : query, &block)
  400. + with_exclusive_scope(self.query ? self.query.merge(query) : query) {|*block_args| yield(*block_args) }
  401. end
  402.  
  403. # @api semipublic
  404. - def with_exclusive_scope(query, &block)
  405. + def with_exclusive_scope(query)
  406. query = DataMapper::Query.new(repository, self, query) if query.kind_of?(Hash)
  407.  
  408. scope_stack << query
  409. diff --git a/lib/dm-core/support/kernel.rb b/lib/dm-core/support/kernel.rb
  410. index 33a6272..2fda366 100644
  411. --- a/lib/dm-core/support/kernel.rb
  412. +++ b/lib/dm-core/support/kernel.rb
  413. @@ -1,7 +1,11 @@
  414. module Kernel
  415. # Delegates to DataMapper::repository.
  416. # Will not overwrite if a method of the same name is pre-defined.
  417. - def repository(*args, &block)
  418. - DataMapper.repository(*args, &block)
  419. + def repository(*args)
  420. + if block_given?
  421. + DataMapper.repository(*args) { |*block_args| yield(*block_args) }
  422. + else
  423. + DataMapper.repository(*args)
  424. + end
  425. end
  426. end # module Kernel
  427. diff --git a/lib/dm-core/transaction.rb b/lib/dm-core/transaction.rb
  428. index 732466a..1329fb0 100644
  429. --- a/lib/dm-core/transaction.rb
  430. +++ b/lib/dm-core/transaction.rb
  431. @@ -13,12 +13,12 @@ module DataMapper
  432. # In fact, it just calls #link with the given arguments at the end of the
  433. # constructor.
  434. #
  435. - def initialize(*things, &block)
  436. + def initialize(*things)
  437. @transaction_primitives = {}
  438. @state = :none
  439. @adapters = {}
  440. link(*things)
  441. - commit(&block) if block_given?
  442. + commit { |*block_args| yield(*block_args) } if block_given?
  443. end
  444.  
  445. #
  446. @@ -39,7 +39,7 @@ module DataMapper
  447. # within this transaction. The transaction will begin and commit around
  448. # the block, and rollback if an exception is raised.
  449. #
  450. - def link(*things, &block)
  451. + def link(*things)
  452. raise "Illegal state for link: #{@state}" unless @state == :none
  453. things.each do |thing|
  454. if thing.is_a?(Array)
  455. @@ -56,7 +56,7 @@ module DataMapper
  456. raise "Unknown argument to #{self}#link: #{thing.inspect}"
  457. end
  458. end
  459. - return commit(&block) if block_given?
  460. + return commit { |*block_args| yield(*block_args) } if block_given?
  461. return self
  462. end
  463.  
  464. @@ -83,12 +83,12 @@ module DataMapper
  465. # If no block is given, it will simply commit any changes made since the
  466. # Transaction did #begin.
  467. #
  468. - def commit(&block)
  469. + def commit
  470. if block_given?
  471. raise "Illegal state for commit with block: #{@state}" unless @state == :none
  472. begin
  473. self.begin
  474. - rval = within(&block)
  475. + rval = within { |*block_args| yield(*block_args) }
  476. self.commit if @state == :begin
  477. return rval
  478. rescue Exception => e
  479. @@ -128,7 +128,7 @@ module DataMapper
  480. # adapter it is associated with, and it will ensures that it will pop the
  481. # Transaction away again after the block is finished.
  482. #
  483. - def within(&block)
  484. + def within
  485. raise "No block provided" unless block_given?
  486. raise "Illegal state for within: #{@state}" unless @state == :begin
  487. @adapters.each do |adapter, state|
  488. diff --git a/script/performance.rb b/script/performance.rb
  489. index acd2588..47536e5 100755
  490. --- a/script/performance.rb
  491. +++ b/script/performance.rb
  492. @@ -1,6 +1,7 @@
  493. #!/usr/bin/env ruby
  494.  
  495. require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core')
  496. +require File.join(File.dirname(__FILE__), '..', 'lib', 'dm-core', 'version')
  497.  
  498. require 'rubygems'
  499. require 'ftools'
  500. @@ -131,7 +132,7 @@ puts "Benchmarks will now run #{TIMES} times"
  501. RBench.run(TIMES) do
  502.  
  503. column :times
  504. - column :dm, :title => "DM 0.9.4"
  505. + column :dm, :title => "DM #{DataMapper::VERSION}"
  506. column :ar, :title => "AR 2.1"
  507. column :diff, :compare => [:dm,:ar]
  508.  
  509. @@ -183,6 +184,13 @@ RBench.run(TIMES) do
  510. ar { ARExhibit.create(create_exhibit) }
  511. end
  512.  
  513. + report "Resource#attributes" do
  514. + attrs_first = {:name => 'sam', :zoo_id => 1}
  515. + attrs_second = {:name => 'tom', :zoo_id => 1}
  516. + dm { e = Exhibit.new(attrs_first); e.attributes = attrs_second }
  517. + ar { e = ARExhibit.new(attrs_first); e.attributes = attrs_second }
  518. + end
  519. +
  520. report "Resource#update" do
  521. dm { e = Exhibit.get(1); e.name = 'bob'; e.save }
  522. ar { e = ARExhibit.find(1); e.name = 'bob'; e.save }
Add Comment
Please, Sign In to add comment