sjain-natural_key 0.0.1 → 0.1.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/CHANGELOG +8 -0
- data/{Manifest.txt → Manifest} +8 -9
- data/README.rdoc +12 -15
- data/Rakefile +12 -25
- data/VERSION.yml +4 -0
- data/lib/natural_key.rb +4 -3
- data/lib/natural_key/base.rb +38 -0
- data/natural_key.gemspec +32 -0
- data/test/lib/activerecord_test_case.rb +12 -14
- data/test/lib/activerecord_test_connector.rb +2 -1
- data/test/test_helper.rb +1 -1
- data/test/test_natural_key.rb +15 -4
- metadata +29 -42
- data/.gitignore +0 -1
- data/History.txt +0 -4
- data/PostInstall.txt +0 -7
- data/lib/natural_key/natural_key.rb +0 -37
data/CHANGELOG
ADDED
data/{Manifest.txt → Manifest}
RENAMED
@@ -1,14 +1,13 @@
|
|
1
|
-
|
2
|
-
History.txt
|
3
|
-
lib/natural_key/natural_key.rb
|
4
|
-
lib/natural_key.rb
|
5
|
-
Manifest.txt
|
6
|
-
PostInstall.txt
|
1
|
+
CHANGELOG
|
7
2
|
Rakefile
|
8
3
|
README.rdoc
|
9
|
-
|
4
|
+
Manifest
|
5
|
+
lib/natural_key/base.rb
|
6
|
+
lib/natural_key.rb
|
10
7
|
test/fixtures/schema.rb
|
11
|
-
test/lib/activerecord_test_case.rb
|
12
|
-
test/lib/activerecord_test_connector.rb
|
13
8
|
test/test_helper.rb
|
9
|
+
test/database.yml
|
14
10
|
test/test_natural_key.rb
|
11
|
+
test/lib/activerecord_test_connector.rb
|
12
|
+
test/lib/activerecord_test_case.rb
|
13
|
+
VERSION.yml
|
data/README.rdoc
CHANGED
@@ -6,34 +6,31 @@
|
|
6
6
|
|
7
7
|
This gem adds create_or_update functionality to ActiveRecord based on a user-defined natural-key.
|
8
8
|
|
9
|
-
== FEATURES/PROBLEMS:
|
10
|
-
|
11
|
-
* TODO
|
12
|
-
|
13
9
|
== SYNOPSIS:
|
14
10
|
|
15
|
-
|
16
|
-
# Table users(first_name varchar, last_name varchar, age integer, address string, salary integer)
|
17
|
-
#
|
18
|
-
class User < ActiveRecord::Base
|
19
|
-
natural_key :first_name, :last_name
|
20
|
-
end
|
11
|
+
Define natural key for your model as follows:
|
21
12
|
|
22
|
-
|
13
|
+
#
|
14
|
+
# Table users(first_name varchar, last_name varchar, age integer, address string, salary integer)
|
15
|
+
#
|
16
|
+
class User < ActiveRecord::Base
|
17
|
+
natural_key :first_name, :last_name
|
18
|
+
end
|
23
19
|
|
24
|
-
|
20
|
+
With this in place, a method 'create_or_update_by_natural_key' can be used to invoke create/update.
|
25
21
|
|
26
|
-
|
22
|
+
User.create_or_update_by_natural_key(:first_name => 'John', :last_name => "Smith", :age => 25, :address => "New York")
|
27
23
|
|
28
24
|
== INSTALL:
|
29
25
|
|
30
|
-
|
26
|
+
gem sources -a http://gems.github.com
|
27
|
+
gem install sjain-natural_key
|
31
28
|
|
32
29
|
== LICENSE:
|
33
30
|
|
34
31
|
(The MIT License)
|
35
32
|
|
36
|
-
Copyright (c) 2009
|
33
|
+
Copyright (c) 2009 Pathfinder Associates, LLC.
|
37
34
|
|
38
35
|
Permission is hereby granted, free of charge, to any person obtaining
|
39
36
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -1,28 +1,15 @@
|
|
1
|
-
|
2
|
-
require
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
require 'lib/natural_key'
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
p.
|
8
|
-
p.
|
9
|
-
p.
|
10
|
-
p.
|
11
|
-
# p.extra_deps = [
|
12
|
-
# ['activesupport','>= 2.0.2'],
|
13
|
-
# ]
|
14
|
-
p.extra_dev_deps = [
|
15
|
-
['newgem', ">= #{::Newgem::VERSION}"]
|
16
|
-
]
|
17
|
-
|
18
|
-
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
19
|
-
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
20
|
-
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
21
|
-
p.rsync_args = '-av --delete --ignore-errors'
|
6
|
+
Echoe.new('natural_key', NaturalKey::VERSION) do |p|
|
7
|
+
p.description = "ActiveRecord.create_or_update based on a user-defined natural-key"
|
8
|
+
p.url = "http://github.com/sjain/natural_key"
|
9
|
+
p.author = "Sharad Jain"
|
10
|
+
p.email = "shaanjain@gmail.com"
|
11
|
+
p.ignore_pattern = ["tmp/*", "script/*", "nbproject/**/*"]
|
12
|
+
p.development_dependencies = []
|
22
13
|
end
|
23
14
|
|
24
|
-
|
25
|
-
Dir['tasks/**/*.rake'].each { |t| load t }
|
26
|
-
|
27
|
-
# TODO - want other tests/tasks run by default? Add them to the list
|
28
|
-
# task :default => [:spec, :features]
|
15
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/VERSION.yml
ADDED
data/lib/natural_key.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
$:.unshift(File.dirname(__FILE__)) unless
|
2
2
|
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
3
|
|
4
|
-
require 'natural_key/natural_key'
|
5
|
-
|
6
4
|
module NaturalKey
|
7
|
-
|
5
|
+
version = YAML.load_file(File.dirname(__FILE__) + "/../VERSION.yml")
|
6
|
+
VERSION = "#{version[:major]}.#{version[:minor]}.#{version[:patch]}"
|
8
7
|
end
|
8
|
+
|
9
|
+
require 'natural_key/base'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'activerecord'
|
2
|
+
|
3
|
+
module NaturalKey
|
4
|
+
module Base
|
5
|
+
def natural_key(*key_attributes)
|
6
|
+
# TODO validate the supplied key_attributes are subset of all attributes
|
7
|
+
# TODO key_attributes should default to primary_key/surrogate_key (:id)
|
8
|
+
# TODO if natural_key is composed of non-primary-key, then it should not contain primary_key
|
9
|
+
raise "natural key attributes cannot be empty" if key_attributes.empty?
|
10
|
+
@@key_attributes = key_attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
# can't use method "create_or_update" since there is already a private method with that name
|
14
|
+
# in ActiveRecord::Base
|
15
|
+
# TODO The following method should only be made available when natural_key is called with proper
|
16
|
+
# attributes. (hint: use class_eval?)
|
17
|
+
def create_or_update_by_natural_key(options)
|
18
|
+
options.symbolize_keys!
|
19
|
+
#TODO options should contain all key_attributes, and their values should be non-nil
|
20
|
+
key_options = options.reject { |k,v| !@@key_attributes.include?(k) }
|
21
|
+
record = find(:first, :conditions => key_options)
|
22
|
+
if(record.nil?)
|
23
|
+
record = create(options)
|
24
|
+
else
|
25
|
+
record.update_attributes!(options)
|
26
|
+
end
|
27
|
+
record
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module ActiveRecord
|
33
|
+
class Base
|
34
|
+
class << self
|
35
|
+
include NaturalKey::Base
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/natural_key.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{natural_key}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Sharad Jain"]
|
9
|
+
s.date = %q{2009-08-08}
|
10
|
+
s.description = %q{ActiveRecord.create_or_update based on a user-defined natural-key}
|
11
|
+
s.email = %q{shaanjain@gmail.com}
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "README.rdoc", "lib/natural_key/base.rb", "lib/natural_key.rb"]
|
13
|
+
s.files = ["CHANGELOG", "Rakefile", "README.rdoc", "Manifest", "lib/natural_key/base.rb", "lib/natural_key.rb", "test/fixtures/schema.rb", "test/test_helper.rb", "test/database.yml", "test/test_natural_key.rb", "test/lib/activerecord_test_connector.rb", "test/lib/activerecord_test_case.rb", "VERSION.yml", "natural_key.gemspec"]
|
14
|
+
s.has_rdoc = true
|
15
|
+
s.homepage = %q{http://github.com/sjain/natural_key}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Natural_key", "--main", "README.rdoc"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{natural_key}
|
19
|
+
s.rubygems_version = %q{1.3.1}
|
20
|
+
s.summary = %q{ActiveRecord.create_or_update based on a user-defined natural-key}
|
21
|
+
s.test_files = ["test/test_helper.rb", "test/test_natural_key.rb"]
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 2
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
else
|
29
|
+
end
|
30
|
+
else
|
31
|
+
end
|
32
|
+
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'lib/activerecord_test_connector'
|
2
2
|
|
3
|
-
class ActiveRecordTestCase <
|
3
|
+
class ActiveRecordTestCase < ActiveRecord::TestCase
|
4
|
+
include ActiveRecord::TestFixtures
|
5
|
+
|
4
6
|
# Set our fixture path
|
5
7
|
if ActiveRecordTestConnector.able_to_connect
|
6
8
|
self.fixture_path = File.join(File.dirname(__FILE__), '..', 'fixtures')
|
@@ -15,22 +17,18 @@ class ActiveRecordTestCase < Test::Unit::TestCase
|
|
15
17
|
super if ActiveRecordTestConnector.connected
|
16
18
|
end
|
17
19
|
|
18
|
-
# Default so Test::Unit::TestCase doesn't complain
|
19
|
-
def test_truth
|
20
|
-
end
|
21
|
-
|
22
20
|
protected
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
def assert_queries(num = 1)
|
23
|
+
$query_count = 0
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
|
27
|
+
end
|
30
28
|
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def assert_no_queries(&block)
|
30
|
+
assert_queries(0, &block)
|
31
|
+
end
|
34
32
|
end
|
35
33
|
|
36
34
|
ActiveRecordTestConnector.setup
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rubygems'
|
1
2
|
require 'active_record'
|
2
3
|
require 'active_record/version'
|
3
4
|
require 'active_record/fixtures'
|
@@ -32,7 +33,7 @@ class ActiveRecordTestConnector
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def self.setup_connection
|
35
|
-
db = ENV['DB'].blank?? '
|
36
|
+
db = ENV['DB'].blank?? 'sqlite3' : ENV['DB']
|
36
37
|
|
37
38
|
configurations = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'database.yml'))
|
38
39
|
raise "no configuration for '#{db}'" unless configurations.key? db
|
data/test/test_helper.rb
CHANGED
@@ -4,7 +4,7 @@ require 'lib/activerecord_test_case'
|
|
4
4
|
require File.dirname(__FILE__) + '/../lib/natural_key'
|
5
5
|
|
6
6
|
# gem install redgreen for colored test output
|
7
|
-
begin require 'redgreen'; rescue LoadError; end
|
7
|
+
#begin require 'redgreen'; rescue LoadError; end
|
8
8
|
|
9
9
|
# The following is not required since we use active-record gem installed on the system
|
10
10
|
#require 'boot' unless defined?(ActiveRecord)
|
data/test/test_natural_key.rb
CHANGED
@@ -5,6 +5,13 @@ class User < ActiveRecord::Base
|
|
5
5
|
end
|
6
6
|
|
7
7
|
class TestNaturalKey < ActiveRecordTestCase
|
8
|
+
def test_create_by_natural_key
|
9
|
+
created_record = User.create(:first_name => 'John', :last_name => "Smith", :age => 21, :address => "Chicago")
|
10
|
+
updated_record = User.create_or_update_by_natural_key(:first_name => 'Different', :last_name => "Smith", :age => 25, :address => "New York")
|
11
|
+
assert_not_equal(created_record.id, updated_record.id)
|
12
|
+
assert_equal(25, updated_record.age)
|
13
|
+
assert_equal("New York", updated_record.address)
|
14
|
+
end
|
8
15
|
def test_update_by_natural_key
|
9
16
|
created_record = User.create(:first_name => 'John', :last_name => "Smith", :age => 21, :address => "Chicago")
|
10
17
|
updated_record = User.create_or_update_by_natural_key(:first_name => 'John', :last_name => "Smith", :age => 25, :address => "New York")
|
@@ -12,10 +19,14 @@ class TestNaturalKey < ActiveRecordTestCase
|
|
12
19
|
assert_equal(25, updated_record.age)
|
13
20
|
assert_equal("New York", updated_record.address)
|
14
21
|
end
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
22
|
+
def test_update_by_natural_key_when_keys_are_strings_instead_of_symbols
|
23
|
+
User.create(:first_name => 'Mary', :last_name => "Beth", :age => 21, :address => "Chicago")
|
24
|
+
john_smith = User.create(:first_name => 'John', :last_name => "Smith", :age => 21, :address => "Chicago")
|
25
|
+
updated_record = User.create_or_update_by_natural_key('first_name' => 'John',
|
26
|
+
'last_name' => "Smith",
|
27
|
+
'age' => 25,
|
28
|
+
'address' => "New York")
|
29
|
+
assert_equal(john_smith.id, updated_record.id)
|
19
30
|
assert_equal(25, updated_record.age)
|
20
31
|
assert_equal("New York", updated_record.address)
|
21
32
|
end
|
metadata
CHANGED
@@ -1,66 +1,53 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sjain-natural_key
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Sharad Jain
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-08-08 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
version_requirements: !ruby/object:Gem::Requirement
|
19
|
-
requirements:
|
20
|
-
- - ">="
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 1.2.3
|
23
|
-
version:
|
24
|
-
- !ruby/object:Gem::Dependency
|
25
|
-
name: hoe
|
26
|
-
version_requirement:
|
27
|
-
version_requirements: !ruby/object:Gem::Requirement
|
28
|
-
requirements:
|
29
|
-
- - ">="
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
version: 1.8.0
|
32
|
-
version:
|
33
|
-
description: This gem adds create_or_update functionality to ActiveRecord based on a user-defined natural-key.
|
34
|
-
email:
|
35
|
-
- info@pathf.com
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: ActiveRecord.create_or_update based on a user-defined natural-key
|
17
|
+
email: shaanjain@gmail.com
|
36
18
|
executables: []
|
37
19
|
|
38
20
|
extensions: []
|
39
21
|
|
40
22
|
extra_rdoc_files:
|
41
|
-
-
|
42
|
-
- Manifest.txt
|
43
|
-
- PostInstall.txt
|
23
|
+
- CHANGELOG
|
44
24
|
- README.rdoc
|
45
|
-
|
46
|
-
- .gitignore
|
47
|
-
- History.txt
|
48
|
-
- lib/natural_key/natural_key.rb
|
25
|
+
- lib/natural_key/base.rb
|
49
26
|
- lib/natural_key.rb
|
50
|
-
|
51
|
-
-
|
27
|
+
files:
|
28
|
+
- CHANGELOG
|
52
29
|
- Rakefile
|
53
30
|
- README.rdoc
|
54
|
-
-
|
31
|
+
- Manifest
|
32
|
+
- lib/natural_key/base.rb
|
33
|
+
- lib/natural_key.rb
|
55
34
|
- test/fixtures/schema.rb
|
56
|
-
- test/lib/activerecord_test_case.rb
|
57
|
-
- test/lib/activerecord_test_connector.rb
|
58
35
|
- test/test_helper.rb
|
36
|
+
- test/database.yml
|
59
37
|
- test/test_natural_key.rb
|
38
|
+
- test/lib/activerecord_test_connector.rb
|
39
|
+
- test/lib/activerecord_test_case.rb
|
40
|
+
- VERSION.yml
|
41
|
+
- natural_key.gemspec
|
60
42
|
has_rdoc: true
|
61
|
-
homepage: http://
|
62
|
-
|
43
|
+
homepage: http://github.com/sjain/natural_key
|
44
|
+
licenses:
|
45
|
+
post_install_message:
|
63
46
|
rdoc_options:
|
47
|
+
- --line-numbers
|
48
|
+
- --inline-source
|
49
|
+
- --title
|
50
|
+
- Natural_key
|
64
51
|
- --main
|
65
52
|
- README.rdoc
|
66
53
|
require_paths:
|
@@ -75,15 +62,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
62
|
requirements:
|
76
63
|
- - ">="
|
77
64
|
- !ruby/object:Gem::Version
|
78
|
-
version: "
|
65
|
+
version: "1.2"
|
79
66
|
version:
|
80
67
|
requirements: []
|
81
68
|
|
82
69
|
rubyforge_project: natural_key
|
83
|
-
rubygems_version: 1.
|
70
|
+
rubygems_version: 1.3.5
|
84
71
|
signing_key:
|
85
72
|
specification_version: 2
|
86
|
-
summary:
|
73
|
+
summary: ActiveRecord.create_or_update based on a user-defined natural-key
|
87
74
|
test_files:
|
88
75
|
- test/test_helper.rb
|
89
76
|
- test/test_natural_key.rb
|
data/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
pkg/*
|
data/History.txt
DELETED
data/PostInstall.txt
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
class Base
|
3
|
-
class << self
|
4
|
-
def natural_key(*key_attributes)
|
5
|
-
# TODO validate the supplied key_attributes are subset of all attributes
|
6
|
-
# TODO key_attributes should default to primary_key/surrogate_key (:id)
|
7
|
-
# TODO if natural_key is composed of non-primary-key, then it should not contain primary_key
|
8
|
-
raise "natural key attributes cannot be empty" if key_attributes.empty?
|
9
|
-
@@key_attributes = key_attributes
|
10
|
-
end
|
11
|
-
|
12
|
-
# can't use method "create_or_update" since there is already a private method with that name
|
13
|
-
# in ActiveRecord::Base
|
14
|
-
# TODO The following method should only be made available when natural_key is called with proper
|
15
|
-
# attributes. (hint: use class_eval?)
|
16
|
-
def create_or_update_by_natural_key(options)
|
17
|
-
#TODO options should contain all key_attributes, and their values should be non-nil
|
18
|
-
key_options = options.reject { |k,v| !@@key_attributes.include?(k) }
|
19
|
-
record = find(:first, :conditions => key_options)
|
20
|
-
if(record.nil?)
|
21
|
-
record = create(options)
|
22
|
-
else
|
23
|
-
record.update_attributes!(options)
|
24
|
-
end
|
25
|
-
record
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
#module NaturalKey
|
32
|
-
# def self.included other
|
33
|
-
# other.extend self
|
34
|
-
# end
|
35
|
-
#end
|
36
|
-
#
|
37
|
-
#ActiveRecord::Base.send :include, NaturalKey
|