dm-adjust 0.9.11 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,7 @@
1
+ === 0.10.0 / 2009-10-15
2
+
3
+ * Updated to work with dm-core 0.10.0
4
+
1
5
  === 0.9.11 / 2009-03-29
2
6
 
3
7
  * No changes this version
@@ -1,13 +1,14 @@
1
- History.txt
1
+ History.rdoc
2
2
  LICENSE
3
3
  Manifest.txt
4
- README.txt
4
+ README.rdoc
5
5
  Rakefile
6
6
  TODO
7
7
  lib/dm-adjust.rb
8
8
  lib/dm-adjust/adapters/data_objects_adapter.rb
9
9
  lib/dm-adjust/collection.rb
10
10
  lib/dm-adjust/model.rb
11
+ lib/dm-adjust/query/conditions/comparison.rb
11
12
  lib/dm-adjust/repository.rb
12
13
  lib/dm-adjust/resource.rb
13
14
  lib/dm-adjust/version.rb
File without changes
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'pathname'
2
- require 'rubygems'
3
2
 
4
3
  ROOT = Pathname(__FILE__).dirname.expand_path
5
4
  JRUBY = RUBY_PLATFORM =~ /java/
@@ -14,10 +13,10 @@ GEM_NAME = 'dm-adjust'
14
13
  GEM_VERSION = DataMapper::Adjust::VERSION
15
14
  GEM_DEPENDENCIES = [['dm-core', GEM_VERSION]]
16
15
  GEM_CLEAN = %w[ log pkg coverage ]
17
- GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.txt LICENSE TODO History.txt ] }
16
+ GEM_EXTRAS = { :has_rdoc => true, :extra_rdoc_files => %w[ README.rdoc LICENSE TODO History.rdoc ] }
18
17
 
19
18
  PROJECT_NAME = 'datamapper'
20
- PROJECT_URL = "http://github.com/sam/dm-more/tree/master/#{GEM_NAME}"
19
+ PROJECT_URL = "http://github.com/datamapper/dm-more/tree/master/#{GEM_NAME}"
21
20
  PROJECT_DESCRIPTION = PROJECT_SUMMARY = 'DataMapper plugin providing methods to increment and decrement properties'
22
21
 
23
22
  [ ROOT, ROOT.parent ].each do |dir|
@@ -1,15 +1,7 @@
1
- require 'rubygems'
2
- require 'pathname'
3
-
4
- require Pathname(__FILE__).dirname + 'dm-adjust/version'
5
-
6
- gem 'dm-core', '0.9.11'
7
- require 'dm-core'
8
-
9
- dir = Pathname(__FILE__).dirname.expand_path / 'dm-adjust'
10
-
11
- require dir / 'collection'
12
- require dir / 'model'
13
- require dir / 'repository'
14
- require dir / 'resource'
15
- require dir / 'adapters' / 'data_objects_adapter'
1
+ require 'dm-adjust/adapters/data_objects_adapter'
2
+ require 'dm-adjust/collection'
3
+ require 'dm-adjust/model'
4
+ require 'dm-adjust/query/conditions/comparison'
5
+ require 'dm-adjust/repository'
6
+ require 'dm-adjust/resource'
7
+ require 'dm-adjust/version'
@@ -1,9 +1,24 @@
1
1
  module DataMapper
2
2
  module Adapters
3
- class DataObjectsAdapter
3
+ class DataObjectsAdapter < AbstractAdapter
4
4
  def adjust(attributes, query)
5
- statement = adjust_statement(attributes.keys, query)
6
- bind_values = attributes.values + query.bind_values
5
+ # TODO: if the query contains any links, a limit or an offset
6
+ # use a subselect to get the rows to be updated
7
+
8
+ properties = []
9
+ bind_values = []
10
+
11
+ # make the order of the properties consistent
12
+ query.model.properties(name).each do |property|
13
+ next unless attributes.key?(property)
14
+ properties << property
15
+ bind_values << attributes[property]
16
+ end
17
+
18
+ statement, conditions_bind_values = adjust_statement(properties, query)
19
+
20
+ bind_values.concat(conditions_bind_values)
21
+
7
22
  execute(statement, *bind_values)
8
23
  end
9
24
 
@@ -11,19 +26,17 @@ module DataMapper
11
26
  private
12
27
 
13
28
  def adjust_statement(properties, query)
14
- repository = query.repository
15
-
16
- statement = "UPDATE #{quote_table_name(query.model.storage_name(repository.name))}"
17
- statement << " SET #{set_adjustment_statement(repository, properties)}"
18
- statement << " WHERE #{conditions_statement(query)}" if query.conditions.any?
19
- statement
20
- rescue => e
21
- DataMapper.logger.error("QUERY INVALID: #{query.inspect} (#{e})")
22
- raise e
29
+ conditions_statement, bind_values = conditions_statement(query.conditions)
30
+
31
+ statement = "UPDATE #{quote_name(query.model.storage_name(name))}"
32
+ statement << " SET #{set_adjustment_statement(properties)}"
33
+ statement << " WHERE #{conditions_statement}" unless conditions_statement.blank?
34
+
35
+ return statement, bind_values
23
36
  end
24
37
 
25
- def set_adjustment_statement(repository, properties)
26
- properties.map { |p| [quote_column_name(p.field(repository.name))] * 2 * " = " + " + (?)" } * ", "
38
+ def set_adjustment_statement(properties)
39
+ properties.map { |p| "#{quote_name(p.field)} = #{quote_name(p.field)} + ?" }.join(', ')
27
40
  end
28
41
 
29
42
  end # module SQL
@@ -21,16 +21,23 @@ module DataMapper
21
21
 
22
22
  adjust_attributes = {}
23
23
 
24
- model.properties(repository.name).slice(*attributes.keys).each do |property|
24
+ model.properties(repository.name).values_at(*attributes.keys).each do |property|
25
25
  adjust_attributes[property] = attributes[property.name] if property
26
26
  end
27
27
 
28
- each { |r| attributes.each_pair{|a,v| r.attribute_set(a,r.send(a) + v) }; r.save } if loaded?
28
+ if loaded?
29
+ each { |r| attributes.each_pair { |a, v| r.attribute_set(a, r.send(a) + v) }; r.save }
30
+ return true
31
+ end
29
32
 
30
33
  # if none of the attributes that are adjusted is part of the collection-query
31
34
  # there is no need to load the collection (it will not change after adjustment)
32
35
  # if the query contains a raw sql-string, we cannot (truly) know, and must load.
33
- altered = query.conditions.detect{|c| adjust_attributes.include?(c[1]) || c[0] == :raw }
36
+ unless altered = query.raw?
37
+ query.conditions.each_node do |comparison|
38
+ altered = true
39
+ end
40
+ end
34
41
 
35
42
  identity_map = repository.identity_map(model)
36
43
  key_properties = model.key(repository.name)
@@ -44,21 +51,31 @@ module DataMapper
44
51
  end
45
52
  end
46
53
 
47
- repository.adjust(adjust_attributes,scoped_query)
54
+ repository.adjust(adjust_attributes, scoped_query({}))
48
55
 
49
56
  # Reload affected objects in identity-map. if collection was affected, dont use the scope.
50
- (altered ? model : self).all(reload_query).reload(:fields => attributes.keys) if reload_query && reload_query.any?
57
+ if reload_query && reload_query.any?
58
+ (altered ? model : self).all(reload_query).reload(:fields => attributes.keys)
59
+ end
51
60
 
52
61
  # if preload was set to false, and collection was affected by updates,
53
62
  # something is now officially borked. We'll try the best we can (still many cases this is borked for)
54
- query.conditions.each do |c|
55
- if adjustment = adjust_attributes[c[1]]
56
- case c[2]
57
- when Numeric then c[2] += adjustment
58
- when Range then c[2] = (c[2].first+adjustment)..(c[2].last+adjustment)
59
- end if adjustment = adjust_attributes[c[1]]
63
+ if altered
64
+ query.conditions.each_node do |comparison|
65
+ next unless adjustment = adjust_attributes[comparison.subject]
66
+
67
+ next unless key = [ comparison.subject, comparison.subject.name ].detect do |key|
68
+ query.options.key?(key)
69
+ end
70
+
71
+ value = case value = comparison.value
72
+ when Numeric then comparison.value + adjustment
73
+ when Range then (value.first + adjustment)..(value.last + adjustment)
74
+ end
75
+
76
+ query.update(key => value)
60
77
  end
61
- end if altered
78
+ end
62
79
 
63
80
  true
64
81
  end
@@ -0,0 +1,25 @@
1
+ module DataMapper
2
+ class Query
3
+ module Conditions
4
+ class AbstractOperation
5
+ def each_node
6
+ operands = self.operands.dup
7
+
8
+ while operand = operands.shift
9
+ if operand.respond_to?(:operands)
10
+ operands.concat(operand.operands)
11
+ else
12
+ yield operand
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ class AbstractComparison
19
+ # this is necessary to allow dm-adjust to change the conditions
20
+ # of the query in an existing collection
21
+ attr_accessor :value
22
+ end
23
+ end
24
+ end
25
+ end
@@ -9,11 +9,11 @@ module DataMapper
9
9
 
10
10
  adjust_attributes = {}
11
11
 
12
- model.properties(repository.name).slice(*attributes.keys).each do |property|
12
+ model.properties(repository.name).values_at(*attributes.keys).each do |property|
13
13
  adjust_attributes[property] = attributes[property.name] if property
14
14
  end
15
15
 
16
- repository.adapter.adjust(adjust_attributes, to_query)
16
+ repository.adapter.adjust(adjust_attributes, query)
17
17
 
18
18
  collection.reload(:fields => adjust_attributes.keys) if reload
19
19
 
@@ -1,5 +1,5 @@
1
1
  module DataMapper
2
2
  module Adjust
3
- VERSION = '0.9.11'
3
+ VERSION = '0.10.0'.freeze
4
4
  end
5
5
  end
@@ -1,14 +1,13 @@
1
- require 'pathname'
2
- require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
1
+ require 'spec_helper'
3
2
 
4
3
  if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
5
4
 
6
5
  class Person
7
6
  include DataMapper::Resource
8
- property :id, Integer, :serial => true
9
- property :name, String
7
+ property :id, Serial
8
+ property :name, String
10
9
  property :salary, Integer, :default => 20000
11
- property :age, Integer
10
+ property :age, Integer
12
11
  end
13
12
 
14
13
  describe 'Adjust' do
@@ -25,7 +24,7 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
25
24
 
26
25
  describe 'Model#adjust!' do
27
26
  it 'should adjust values' do
28
- repository(:default) do
27
+ DataMapper.repository(:default) do
29
28
  Person.adjust!({:salary => 1000},true)
30
29
  Person.all.each{|p| p.salary.should == 21000}
31
30
  end
@@ -34,7 +33,7 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
34
33
 
35
34
  describe 'Collection#adjust!' do
36
35
  it 'should adjust values' do
37
- repository(:default) do |repos|
36
+ DataMapper.repository(:default) do |repos|
38
37
  @oldies = Person.all(:age.gte => 40)
39
38
  @oldies.adjust!({:salary => 5000},true)
40
39
  @oldies.each{|p| p.salary.should == 25000}
@@ -48,17 +47,28 @@ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
48
47
  end
49
48
 
50
49
  it 'should load the query if conditions were adjusted' do
51
- repository(:default) do |repos|
50
+ DataMapper.repository(:default) do |repos|
52
51
  @specific = Person.all(:salary => 20000)
53
52
  @specific.adjust!({:salary => 5000},true)
54
- @specific.length.should == 6
53
+
54
+ # Both of these are seemingly equal
55
+ # puts @specific.query.inspect
56
+ # puts Person.all(:salary => 25000).query.inspect
57
+ #<DataMapper::Query @repository=:default @model=Person @fields=[#<Property:Person:id>, #<Property:Person:name>, #<Property:Person:salary>, #<Property:Person:age>] @links=[] @conditions=[[:eql, #<Property:Person:salary>, 25000]] @order=[#<DataMapper::Query::Direction #<Property:Person:id> asc>] @limit=nil @offset=0 @reload=false @unique=false>
58
+ #<DataMapper::Query @repository=:default @model=Person @fields=[#<Property:Person:id>, #<Property:Person:name>, #<Property:Person:salary>, #<Property:Person:age>] @links=[] @conditions=[[:eql, #<Property:Person:salary>, 25000]] @order=[#<DataMapper::Query::Direction #<Property:Person:id> asc>] @limit=nil @offset=0 @reload=false @unique=false>
59
+ # puts @specific.all.length # is 0
60
+ # puts Person.all(@specific.query.relative({})).length # 0
61
+ # puts Person.all(:salary => 25000).length # 6 !
62
+
63
+ Person.all(:salary => 25000).length.should == 6
64
+ @specific.all.length.should == 6
55
65
  end
56
66
  end
57
67
  end
58
68
 
59
69
  describe 'Resource#adjust' do
60
70
  it 'should adjust the value' do
61
- repository(:default) do |repos|
71
+ DataMapper.repository(:default) do |repos|
62
72
  p = Person.get(1)
63
73
  p.salary.should == 20000
64
74
  p.adjust!({:salary => 1000},true)
@@ -1 +1,2 @@
1
1
  --colour
2
+ --loadby random
@@ -1,7 +1,14 @@
1
- require 'pathname'
2
1
  require 'rubygems'
3
2
 
4
- require Pathname(__FILE__).dirname.expand_path.parent + 'lib/dm-adjust'
3
+ # Use local dm-core if running from a typical dev checkout.
4
+ lib = File.join('..', '..', 'dm-core', 'lib')
5
+ $LOAD_PATH.unshift(lib) if File.directory?(lib)
6
+ require 'dm-core'
7
+
8
+ # Support running specs with 'rake spec' and 'spec'
9
+ $LOAD_PATH.unshift('lib') unless $LOAD_PATH.include?('lib')
10
+
11
+ require 'dm-adjust'
5
12
 
6
13
  def load_driver(name, default_uri)
7
14
  return false if ENV['ADAPTER'] != name.to_s
@@ -9,7 +16,6 @@ def load_driver(name, default_uri)
9
16
  begin
10
17
  DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
11
18
  DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
12
- # DataObjects::Sqlite3.logger = DataObjects::Logger.new(Pathname(__FILE__).dirname+'dm.log',0)
13
19
  true
14
20
  rescue LoadError => e
15
21
  warn "Could not load do_#{name}: #{e}"
@@ -4,7 +4,7 @@ end
4
4
 
5
5
  desc "Install #{GEM_NAME} #{GEM_VERSION}"
6
6
  task :install => [ :package ] do
7
- sudo_gem "install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
7
+ sudo_gem "install pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources"
8
8
  end
9
9
 
10
10
  desc "Uninstall #{GEM_NAME} #{GEM_VERSION}"
@@ -1,6 +1,4 @@
1
1
  begin
2
- gem 'rspec', '~>1.2'
3
- require 'spec'
4
2
  require 'spec/rake/spectask'
5
3
 
6
4
  task :default => [ :spec ]
@@ -8,16 +6,18 @@ begin
8
6
  desc 'Run specifications'
9
7
  Spec::Rake::SpecTask.new(:spec) do |t|
10
8
  t.spec_opts << '--options' << 'spec/spec.opts' if File.exists?('spec/spec.opts')
11
- t.spec_files = Pathname.glob((ROOT + 'spec/**/*_spec.rb').to_s).map { |f| f.to_s }
9
+ t.libs << 'lib' << 'spec' # needed for CI rake spec task, duplicated in spec_helper
12
10
 
13
11
  begin
14
- gem 'rcov', '~>0.8'
12
+ require 'rcov'
15
13
  t.rcov = JRUBY ? false : (ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true)
16
14
  t.rcov_opts << '--exclude' << 'spec'
17
15
  t.rcov_opts << '--text-summary'
18
16
  t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
19
17
  rescue LoadError
20
18
  # rcov not installed
19
+ rescue SyntaxError
20
+ # rcov syntax invalid
21
21
  end
22
22
  end
23
23
  rescue LoadError
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-adjust
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.11
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sindre Aarsaether
@@ -9,19 +9,10 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-29 00:00:00 -07:00
12
+ date: 2009-09-16 00:00:00 -07:00
13
13
  default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: dm-core
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - "="
22
- - !ruby/object:Gem::Version
23
- version: 0.9.11
24
- version:
14
+ dependencies: []
15
+
25
16
  description: DataMapper plugin providing methods to increment and decrement properties
26
17
  email:
27
18
  - sindre [a] identu [d] no
@@ -30,21 +21,22 @@ executables: []
30
21
  extensions: []
31
22
 
32
23
  extra_rdoc_files:
33
- - README.txt
24
+ - README.rdoc
34
25
  - LICENSE
35
26
  - TODO
36
- - History.txt
27
+ - History.rdoc
37
28
  files:
38
- - History.txt
29
+ - History.rdoc
39
30
  - LICENSE
40
31
  - Manifest.txt
41
- - README.txt
32
+ - README.rdoc
42
33
  - Rakefile
43
34
  - TODO
44
35
  - lib/dm-adjust.rb
45
36
  - lib/dm-adjust/adapters/data_objects_adapter.rb
46
37
  - lib/dm-adjust/collection.rb
47
38
  - lib/dm-adjust/model.rb
39
+ - lib/dm-adjust/query/conditions/comparison.rb
48
40
  - lib/dm-adjust/repository.rb
49
41
  - lib/dm-adjust/resource.rb
50
42
  - lib/dm-adjust/version.rb
@@ -54,11 +46,13 @@ files:
54
46
  - tasks/install.rb
55
47
  - tasks/spec.rb
56
48
  has_rdoc: true
57
- homepage: http://github.com/sam/dm-more/tree/master/dm-adjust
49
+ homepage: http://github.com/datamapper/dm-more/tree/master/dm-adjust
50
+ licenses: []
51
+
58
52
  post_install_message:
59
53
  rdoc_options:
60
54
  - --main
61
- - README.txt
55
+ - README.rdoc
62
56
  require_paths:
63
57
  - lib
64
58
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -76,9 +70,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
70
  requirements: []
77
71
 
78
72
  rubyforge_project: datamapper
79
- rubygems_version: 1.3.1
73
+ rubygems_version: 1.3.5
80
74
  signing_key:
81
- specification_version: 2
75
+ specification_version: 3
82
76
  summary: DataMapper plugin providing methods to increment and decrement properties
83
77
  test_files: []
84
78