dm-optlock 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,5 +5,10 @@
5
5
 
6
6
  == 0.1.2 2008-10-01
7
7
 
8
- * 1 minor enhancement:
8
+ * 1 major enhancement:
9
9
  * Added class method 'set_locking_column'
10
+
11
+ == 0.1.3 2009-01-10
12
+
13
+ * 1 major enhancement:
14
+ * replaced 'set_locking_column' by 'add_locking_column'
@@ -1,14 +1,12 @@
1
1
  History.txt
2
2
  Manifest.txt
3
+ README.rdoc
3
4
  Rakefile
4
- config/hoe.rb
5
- config/requirements.rb
6
5
  lib/dm-optlock.rb
7
- lib/dm-optlock/version.rb
8
- setup.rb
9
- tasks/deployment.rake
10
- tasks/environment.rake
11
- tasks/spec.rake
6
+ script/console
7
+ script/destroy
8
+ script/generate
9
+ spec/dm-optlock_spec.rb
12
10
  spec/spec.opts
13
11
  spec/spec_helper.rb
14
- spec/integration/optlock_spec.rb
12
+ tasks/rspec.rake
@@ -0,0 +1,48 @@
1
+ = dm-optlock
2
+
3
+ * FIX (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2009 FIXME full name
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,4 +1,21 @@
1
- require 'config/requirements'
2
- require 'config/hoe' # setup Hoe + all gem configuration
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/dm-optlock'
3
3
 
4
- Dir['tasks/**/*.rake'].each { |rake| load rake }
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('dm-optlock', DataMapper::DmOptlock::VERSION) do |p|
7
+ p.developer('FIXME full name', 'FIXME email')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.rubyforge_name = p.name # TODO this is default value
10
+ p.extra_deps = [
11
+ ['dm-core','>= 0.9.5'],
12
+ ]
13
+
14
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
15
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
16
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
17
+ p.rsync_args = '-av --delete --ignore-errors'
18
+ end
19
+
20
+ require 'newgem/tasks' # load /tasks/*.rake
21
+ Dir['tasks/**/*.rake'].each { |t| load t }
@@ -1,19 +1,19 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
1
4
  require 'rubygems'
2
-
3
- gem 'dm-core', '=0.9.5'
5
+ gem 'dm-core', '>=0.9.5'
4
6
  require 'dm-core'
5
7
 
6
8
  module DataMapper
7
- # Raised when the row represented by the object which is to be saved was updated in meantime.
8
9
  class StaleObjectError < StandardError
9
10
  end
10
11
 
11
- # Enables optimistic row locking in DM.
12
- module OptLock
12
+ module DmOptlock
13
+ VERSION = '0.1.3'
13
14
  DEFAULT_LOCKING_COLUMN = :lock_version
14
15
 
15
- # hmm...
16
- def self.included(base)
16
+ def self.included(base) #:nodoc:
17
17
  base.extend ClassMethods
18
18
  base.before :save, :check_lock_version
19
19
  end
@@ -21,33 +21,37 @@ module DataMapper
21
21
  private
22
22
  # Checks if the row has been changed since being loaded from the database.
23
23
  def check_lock_version
24
- if self.respond_to?(self.class.locking_column.to_s) && !self.new_record? && self.dirty?
25
- id = self.id
26
- id = self.original_values[:id] if self.original_values.include?(:id)
27
- if self.original_values.include?(self.class.locking_column) || self.class.first(:id => id, self.class.locking_column => self.attributes[self.class.locking_column]).nil?
24
+ if !new_record? && dirty? && respond_to?(self.class.locking_column.to_s)
25
+ if original_values.include?(:id)
26
+ row = self.class.get(original_values[:id])
27
+ else
28
+ row = self.class.get(id)
29
+ end
30
+ if !row.nil? && row.attribute_get(self.class.locking_column) != attribute_get(self.class.locking_column)
31
+ attributes = original_values
28
32
  raise DataMapper::StaleObjectError
29
33
  else
30
- self.attributes = {self.class.locking_column => self.attributes[self.class.locking_column] + 1}
34
+ attribute_set(self.class.locking_column, attribute_get(self.class.locking_column) + 1)
31
35
  end
32
36
  end
33
37
  end
34
38
 
35
39
  module ClassMethods
36
-
37
40
  @@lock_column = nil
38
41
 
39
42
  # Set the column to use for optimistic locking. Defaults to lock_version.
40
- def set_locking_column(name = nil)
43
+ def add_locking_column(name = DEFAULT_LOCKING_COLUMN, options = {})
44
+ options.merge!({:default => 0, :writer => :protected})
41
45
  @@lock_column = name
46
+ property name, Integer, options
42
47
  end
43
48
 
44
49
  # The version column used for optimistic locking. Defaults to lock_version.
45
50
  def locking_column
46
- return DEFAULT_LOCKING_COLUMN unless @@lock_column
47
51
  return @@lock_column
48
52
  end
49
53
  end
50
54
  end
51
-
52
- Resource::append_inclusions OptLock
55
+
56
+ Resource::append_inclusions DmOptlock
53
57
  end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/dm-optlock.rb'}"
9
+ puts "Loading dm-optlock gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,71 @@
1
+ #:nodoc:
2
+ require 'pathname'
3
+ require Pathname(__FILE__).dirname.expand_path + 'spec_helper'
4
+
5
+ if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
6
+ describe 'DataMapper::DmOptlock' do
7
+ before :all do
8
+ class Thing
9
+ include DataMapper::Resource
10
+ property :id, Integer, :serial => true
11
+ property :name, String
12
+
13
+ add_locking_column :row_version
14
+
15
+ auto_migrate!(:default)
16
+ end
17
+ end
18
+
19
+ after do
20
+ repository(:default).adapter.execute('DELETE from things');
21
+ end
22
+
23
+ it "shouldn't save second" do
24
+ t = Thing.new(:name => "Banana")
25
+ t.save
26
+ tA = Thing.first
27
+ tB = Thing.first
28
+ tA.name = 'Apple'
29
+ tB.name = 'Pineapple'
30
+ tA.save.should be_true
31
+ lambda { tB.save.should }.should raise_error(DataMapper::StaleObjectError)
32
+ end
33
+
34
+ it "should increment lock version" do
35
+ t = Thing.new(:name => "Dollar")
36
+ t.save
37
+ t.row_version.should equal(0)
38
+ t.name = "Euro"
39
+ t.save
40
+ t.row_version.should equal(1)
41
+ end
42
+
43
+ it "should be aware of ID changes" do
44
+ t = Thing.new(:name => "abc")
45
+ t.save
46
+ tA = Thing.first
47
+ tB = Thing.first
48
+ tA.name = 'Apple'
49
+ tB.id = 122
50
+ tA.save.should be_true
51
+ lambda { tB.save.should }.should raise_error(DataMapper::StaleObjectError)
52
+ end
53
+
54
+ it "'s version column should be not nullable, have default 0 and a protected writer" do
55
+ class Foo
56
+ include DataMapper::Resource
57
+ property :id, Integer, :serial => true
58
+
59
+ add_locking_column :foo_version, :default => 1, :nullable => false
60
+
61
+ auto_migrate!(:default)
62
+ end
63
+
64
+ col = Foo.properties[:foo_version]
65
+ col.nullable?.should be_false
66
+ col.default.should be(0)
67
+ col.writer_visibility.should equal(:protected)
68
+ end
69
+
70
+ end
71
+ end
@@ -1,2 +1 @@
1
- --format specdoc
2
- --colour
1
+ --colour
@@ -1,8 +1,14 @@
1
- require 'rubygems'
2
- gem 'rspec', '>=1.1.3'
3
- require 'spec'
4
- require 'pathname'
5
- require Pathname(__FILE__).dirname.parent.expand_path + 'lib/dm-optlock'
1
+ #:nodoc:
2
+ begin
3
+ require 'spec'
4
+ rescue LoadError
5
+ require 'rubygems'
6
+ gem 'rspec'
7
+ require 'spec'
8
+ end
9
+
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+ require 'dm-optlock'
6
12
 
7
13
  def load_driver(name, default_uri)
8
14
  return false if ENV['ADAPTER'] != name.to_s
@@ -10,7 +16,7 @@ def load_driver(name, default_uri)
10
16
  lib = "do_#{name}"
11
17
 
12
18
  begin
13
- gem lib, '=0.9.5'
19
+ gem lib, '>=0.9.5'
14
20
  require lib
15
21
  DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
16
22
  DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dm-optlock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
- - Martin Vielsmaier
7
+ - FIXME full name
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-10-02 00:00:00 +02:00
12
+ date: 2009-01-10 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,11 +30,11 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 1.7.0
33
+ version: 1.8.0
34
34
  version:
35
- description: Optimistic locking for Datamapper
35
+ description: FIX (describe your package)
36
36
  email:
37
- - martin.vielsmaier@gmail.com
37
+ - FIXME email
38
38
  executables: []
39
39
 
40
40
  extensions: []
@@ -42,27 +42,26 @@ extensions: []
42
42
  extra_rdoc_files:
43
43
  - History.txt
44
44
  - Manifest.txt
45
+ - README.rdoc
45
46
  files:
46
47
  - History.txt
47
48
  - Manifest.txt
49
+ - README.rdoc
48
50
  - Rakefile
49
- - config/hoe.rb
50
- - config/requirements.rb
51
51
  - lib/dm-optlock.rb
52
- - lib/dm-optlock/version.rb
53
- - setup.rb
54
- - tasks/deployment.rake
55
- - tasks/environment.rake
56
- - tasks/spec.rake
52
+ - script/console
53
+ - script/destroy
54
+ - script/generate
55
+ - spec/dm-optlock_spec.rb
57
56
  - spec/spec.opts
58
57
  - spec/spec_helper.rb
59
- - spec/integration/optlock_spec.rb
58
+ - tasks/rspec.rake
60
59
  has_rdoc: true
61
- homepage: http://moserei.de/?p=27
62
- post_install_message: ""
60
+ homepage: FIX (url)
61
+ post_install_message:
63
62
  rdoc_options:
64
63
  - --main
65
- - README.txt
64
+ - README.rdoc
66
65
  require_paths:
67
66
  - lib
68
67
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -80,9 +79,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
79
  requirements: []
81
80
 
82
81
  rubyforge_project: dm-optlock
83
- rubygems_version: 1.2.0
82
+ rubygems_version: 1.3.1
84
83
  signing_key:
85
84
  specification_version: 2
86
- summary: Optimistic locking for Datamapper
85
+ summary: FIX (describe your package)
87
86
  test_files: []
88
87
 
@@ -1,73 +0,0 @@
1
- require 'dm-optlock/version'
2
-
3
- AUTHOR = 'Martin Vielsmaier' # can also be an array of Authors
4
- EMAIL = "martin.vielsmaier@gmail.com"
5
- DESCRIPTION = "Optimistic locking for Datamapper"
6
- GEM_NAME = 'dm-optlock' # what ppl will type to install your gem
7
- RUBYFORGE_PROJECT = 'dm-optlock' # The unix name for your project
8
- HOMEPATH = "http://moserei.de/?p=27"
9
- DOWNLOAD_PATH = "http://moserei.de/?p=27"
10
- EXTRA_DEPENDENCIES = [
11
- ['dm-core', '>= 0.9.5']
12
- ] # An array of rubygem dependencies [name, version]
13
-
14
- @config_file = "~/.rubyforge/user-config.yml"
15
- @config = nil
16
- RUBYFORGE_USERNAME = "unknown"
17
- def rubyforge_username
18
- unless @config
19
- begin
20
- @config = YAML.load(File.read(File.expand_path(@config_file)))
21
- rescue
22
- puts <<-EOS
23
- ERROR: No rubyforge config file found: #{@config_file}
24
- Run 'rubyforge setup' to prepare your env for access to Rubyforge
25
- - See http://newgem.rubyforge.org/rubyforge.html for more details
26
- EOS
27
- exit
28
- end
29
- end
30
- RUBYFORGE_USERNAME.replace @config["username"]
31
- end
32
-
33
-
34
- REV = nil
35
- # UNCOMMENT IF REQUIRED:
36
- # REV = YAML.load(`svn info`)['Revision']
37
- VERS = DataMapper::OptLock::VERSION::STRING + (REV ? ".#{REV}" : "")
38
- RDOC_OPTS = ['--quiet', '--title', 'dm-optlock documentation',
39
- "--opname", "index.html",
40
- "--line-numbers",
41
- "--main", "README",
42
- "--inline-source"]
43
-
44
- class Hoe
45
- def extra_deps
46
- @extra_deps.reject! { |x| Array(x).first == 'hoe' }
47
- @extra_deps
48
- end
49
- end
50
-
51
- # Generate all the Rake tasks
52
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
53
- $hoe = Hoe.new(GEM_NAME, VERS) do |p|
54
- p.developer(AUTHOR, EMAIL)
55
- p.description = DESCRIPTION
56
- p.summary = DESCRIPTION
57
- p.url = HOMEPATH
58
- p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
59
- p.test_globs = ["test/**/test_*.rb"]
60
- p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
61
-
62
- # == Optional
63
- p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
64
- p.extra_deps = EXTRA_DEPENDENCIES
65
-
66
- #p.spec_extras = {} # A hash of extra values to set in the gemspec.
67
- end
68
-
69
- CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
70
- PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
71
- $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
72
- $hoe.rsync_args = '-av --delete --ignore-errors'
73
- $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""