ricordami 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/TODO.md +2 -0
- data/lib/ricordami/can_be_queried.rb +4 -3
- data/lib/ricordami/is_retrievable.rb +2 -2
- data/lib/ricordami/unique_index.rb +1 -1
- data/lib/ricordami/unique_validator.rb +1 -1
- data/lib/ricordami/value_index.rb +1 -1
- data/lib/ricordami/version.rb +1 -1
- data/spec/ricordami/can_be_queried_spec.rb +10 -4
- data/spec/ricordami/has_attributes_spec.rb +3 -3
- data/spec/ricordami/has_indices_spec.rb +12 -12
- data/spec/ricordami/is_retrievable_spec.rb +2 -2
- data/spec/ricordami/unique_index_spec.rb +6 -6
- data/spec/ricordami/unique_validator_spec.rb +1 -1
- data/spec/ricordami/value_index_spec.rb +1 -1
- metadata +2 -2
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Changelog #
|
2
2
|
|
3
|
+
## 0.0.5 (March 14th, 2011) ##
|
4
|
+
|
5
|
+
- allow to have unique and value indices on the same column so we can
|
6
|
+
query fields that have a unique scoped index
|
7
|
+
|
3
8
|
## 0.0.4 (March 13th, 2011) ##
|
4
9
|
|
5
10
|
- add a scope option to validates_uniqueness_of validation macro
|
data/TODO.md
CHANGED
@@ -61,7 +61,7 @@ module Ricordami
|
|
61
61
|
private
|
62
62
|
|
63
63
|
def run_expressions(expressions)
|
64
|
-
key_all_ids = indices[:
|
64
|
+
key_all_ids = indices[:u_id].uidx_key_name
|
65
65
|
result_key = expressions.reduce(key_all_ids) do |key, expression|
|
66
66
|
type, conditions = expression
|
67
67
|
condition_keys = get_keys_for_each_condition(conditions)
|
@@ -74,8 +74,9 @@ module Ricordami
|
|
74
74
|
|
75
75
|
def get_keys_for_each_condition(conditions)
|
76
76
|
conditions.map do |field, value|
|
77
|
-
|
78
|
-
|
77
|
+
index_name = "v_#{field}".to_sym
|
78
|
+
index = indices[index_name]
|
79
|
+
raise MissingIndex.new("class: #{self}, attribute: #{index_name.inspect}") if index.nil?
|
79
80
|
index.key_name_for_value(value)
|
80
81
|
end
|
81
82
|
end
|
@@ -9,7 +9,7 @@ module Ricordami
|
|
9
9
|
def initialize(model, fields, options = {})
|
10
10
|
@model = model
|
11
11
|
@fields = normalize_array(fields)
|
12
|
-
@name = @fields.join("_").to_sym
|
12
|
+
@name = ("u_" + @fields.join("_")).to_sym
|
13
13
|
@need_get_by = options[:get_by] && @fields != [:id]
|
14
14
|
if options.has_key?(:scope)
|
15
15
|
@scope = normalize_array(options[:scope])
|
@@ -4,7 +4,7 @@ module Ricordami
|
|
4
4
|
class UniqueValidator < ActiveModel::EachValidator
|
5
5
|
def validate_each(record, attribute, value)
|
6
6
|
return true unless record.new_record? || record.send(:attribute_changed?, attribute)
|
7
|
-
index_name = attribute.to_sym
|
7
|
+
index_name = "u_#{attribute}".to_sym
|
8
8
|
index = record.class.indices[index_name]
|
9
9
|
if index.scope
|
10
10
|
scope_values = index.scope.map { |field| record.send(field) }
|
data/lib/ricordami/version.rb
CHANGED
@@ -10,7 +10,9 @@ describe Ricordami::CanBeQueried do
|
|
10
10
|
Customer.attribute :sex, :indexed => :value
|
11
11
|
Customer.attribute :name, :indexed => :value
|
12
12
|
Customer.attribute :kind, :indexed => :value
|
13
|
+
Customer.attribute :age, :indexed => :value
|
13
14
|
Customer.attribute :no_index
|
15
|
+
Customer.index :unique => :age, :scope => :kind
|
14
16
|
end
|
15
17
|
|
16
18
|
describe "building queries" do
|
@@ -71,10 +73,10 @@ describe Ricordami::CanBeQueried do
|
|
71
73
|
|
72
74
|
describe "running queries" do
|
73
75
|
before(:each) do
|
74
|
-
Customer.create(:name => "Zhanna", :sex => "F", :country => "Latvia", :kind => "human")
|
75
|
-
Customer.create(:name => "Mathieu", :sex => "M", :country => "France", :kind => "human")
|
76
|
-
Customer.create(:name => "Sophie", :sex => "F", :country => "USA", :kind => "human")
|
77
|
-
Customer.create(:name => "Brioche", :sex => "F", :country => "USA", :kind => "dog")
|
76
|
+
Customer.create(:name => "Zhanna", :sex => "F", :country => "Latvia", :kind => "human", :age => "29")
|
77
|
+
Customer.create(:name => "Mathieu", :sex => "M", :country => "France", :kind => "human", :age => "40")
|
78
|
+
Customer.create(:name => "Sophie", :sex => "F", :country => "USA", :kind => "human", :age => "1")
|
79
|
+
Customer.create(:name => "Brioche", :sex => "F", :country => "USA", :kind => "dog", :age => "3")
|
78
80
|
end
|
79
81
|
|
80
82
|
describe ":and" do
|
@@ -112,6 +114,10 @@ describe Ricordami::CanBeQueried do
|
|
112
114
|
it "doesn't require #all if another method call is chained" do
|
113
115
|
Customer.where(:country => "USA").and(:sex => "F").map(&:name).should =~ ["Sophie", "Brioche"]
|
114
116
|
end
|
117
|
+
|
118
|
+
it "can run a query on attributes with unique indices (if they also have a value index of course)" do
|
119
|
+
Customer.where(:country => "USA", :age => "1").map(&:name).should == ["Sophie"]
|
120
|
+
end
|
115
121
|
end
|
116
122
|
|
117
123
|
describe ":any" do
|
@@ -18,17 +18,17 @@ describe Ricordami::HasAttributes do
|
|
18
18
|
|
19
19
|
it "creates an index if :indexed is set" do
|
20
20
|
Boat.attribute :size, :indexed => :value
|
21
|
-
Boat.indices.should have_key(:
|
21
|
+
Boat.indices.should have_key(:v_size)
|
22
22
|
end
|
23
23
|
|
24
24
|
it "creates a unique index if :indexed is :unique" do
|
25
25
|
Boat.attribute :size, :indexed => :unique
|
26
|
-
Boat.indices[:
|
26
|
+
Boat.indices[:u_size].should be_a(Ricordami::UniqueIndex)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "creates a value index if :indexed is :value" do
|
30
30
|
Boat.attribute :size, :indexed => :value
|
31
|
-
Boat.indices[:
|
31
|
+
Boat.indices[:v_size].should be_a(Ricordami::ValueIndex)
|
32
32
|
end
|
33
33
|
|
34
34
|
it "replaces :initial value with a generator if it's a symbol" do
|
@@ -15,54 +15,54 @@ describe Ricordami::HasIndices do
|
|
15
15
|
describe "declaring a value index" do
|
16
16
|
it "can declare a value index with #index" do
|
17
17
|
index = Car.index :value => :model
|
18
|
-
Car.indices[:
|
19
|
-
Car.indices[:
|
18
|
+
Car.indices[:v_model].should be_a(Ricordami::ValueIndex)
|
19
|
+
Car.indices[:v_model].should == index
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
describe "declaring a unique index" do
|
24
24
|
it "can declare a unique index with #index" do
|
25
25
|
index = Car.index :unique => :model
|
26
|
-
Car.indices[:
|
27
|
-
Car.indices[:
|
26
|
+
Car.indices[:u_model].should be_a(Ricordami::UniqueIndex)
|
27
|
+
Car.indices[:u_model].should == index
|
28
28
|
end
|
29
29
|
|
30
30
|
it "can give a scope to a unique index with :scope option" do
|
31
31
|
Car.attribute :brand
|
32
32
|
index = Car.index :unique => :model, :scope => :brand
|
33
|
-
Car.indices[:
|
34
|
-
Car.indices[:
|
33
|
+
Car.indices[:u_model].scope.should == [:brand]
|
34
|
+
Car.indices[:u_model].fields.should == [:model, :brand]
|
35
35
|
end
|
36
36
|
|
37
37
|
it "discards the subsequent declarations if the same index is created more than once" do
|
38
38
|
Car.index :unique => :model, :get_by => true
|
39
|
-
Car.indices[:
|
39
|
+
Car.indices[:u_model].need_get_by.should be_true
|
40
40
|
Car.index :unique => :model, :get_by => false
|
41
|
-
Car.indices[:
|
41
|
+
Car.indices[:u_model].need_get_by.should be_true
|
42
42
|
end
|
43
43
|
|
44
44
|
it "saves the values of the unique attributes into the indices" do
|
45
45
|
Car.index :unique => :name
|
46
46
|
car = Car.new(:name => "Prius")
|
47
47
|
car.save
|
48
|
-
Car.indices[:
|
48
|
+
Car.indices[:u_name].all.should == ["Prius"]
|
49
49
|
end
|
50
50
|
|
51
51
|
it "replaces old values with new ones into the indices" do
|
52
52
|
Car.index :unique => :name
|
53
53
|
car = Car.new(:name => "Prius")
|
54
54
|
car.save
|
55
|
-
Car.indices[:
|
55
|
+
Car.indices[:u_name].all.should == ["Prius"]
|
56
56
|
car.name = "Rav4"
|
57
57
|
car.save
|
58
|
-
Car.indices[:
|
58
|
+
Car.indices[:u_name].all.should == ["Rav4"]
|
59
59
|
end
|
60
60
|
|
61
61
|
it "deletes the values of the unique attributes from the indices" do
|
62
62
|
Car.index :unique => :name
|
63
63
|
car = Car.create(:name => "Prius")
|
64
64
|
car.delete.should be_true
|
65
|
-
Car.indices[:
|
65
|
+
Car.indices[:u_name].all.should be_empty
|
66
66
|
end
|
67
67
|
|
68
68
|
it "adds a get_by_xxx method for each unique index xxx declared if :get_by is true" do
|
@@ -33,10 +33,10 @@ describe Ricordami::IsRetrievable do
|
|
33
33
|
Tenant.attribute :name
|
34
34
|
instance = Tenant.new(:id => "hi")
|
35
35
|
instance.save
|
36
|
-
Tenant.indices[:
|
36
|
+
Tenant.indices[:u_id].all.should == ["hi"]
|
37
37
|
instance.name = "john"
|
38
38
|
instance.save
|
39
|
-
Tenant.indices[:
|
39
|
+
Tenant.indices[:u_id].all.should == ["hi"]
|
40
40
|
end
|
41
41
|
|
42
42
|
it "returns all the instances with #all" do
|
@@ -13,7 +13,7 @@ describe Ricordami::UniqueIndex do
|
|
13
13
|
it "is initialized with a model, a name and the fields to be unique" do
|
14
14
|
@index.model.should == DataSource
|
15
15
|
@index.fields.should == [:id]
|
16
|
-
@index.name.should == :
|
16
|
+
@index.name.should == :u_id
|
17
17
|
end
|
18
18
|
|
19
19
|
it "can have a scope" do
|
@@ -23,7 +23,7 @@ describe Ricordami::UniqueIndex do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it "returns its internal index name with #uidx_key_name" do
|
26
|
-
@index.uidx_key_name.should == "DataSource:udx:
|
26
|
+
@index.uidx_key_name.should == "DataSource:udx:u_id"
|
27
27
|
end
|
28
28
|
|
29
29
|
it "returns its internal reference name with #ref_key_name" do
|
@@ -32,14 +32,14 @@ describe Ricordami::UniqueIndex do
|
|
32
32
|
|
33
33
|
it "adds a string to the index with #add" do
|
34
34
|
@index.add("ze-id", "allo")
|
35
|
-
Ricordami.redis.smembers("DataSource:udx:
|
35
|
+
Ricordami.redis.smembers("DataSource:udx:u_id").should == ["allo"]
|
36
36
|
end
|
37
37
|
|
38
38
|
it "also indices the hash index with #add if fields is not :id and :get_by is true" do
|
39
39
|
DataSource.attribute :domain
|
40
40
|
other = subject.new(DataSource, [:name, :domain], :get_by => true)
|
41
41
|
other.add("ze-id", ["jobs", "apple.com"])
|
42
|
-
Ricordami.redis.smembers("DataSource:udx:
|
42
|
+
Ricordami.redis.smembers("DataSource:udx:u_name_domain").should == ["jobs_-::-_apple.com"]
|
43
43
|
Ricordami.redis.hget("DataSource:hsh:name_domain_to_id", "jobs_-::-_apple.com").should == "ze-id"
|
44
44
|
end
|
45
45
|
|
@@ -68,12 +68,12 @@ describe Ricordami::UniqueIndex do
|
|
68
68
|
it "removes a string from the index with #rem" do
|
69
69
|
@index.add("ze-id", "allo")
|
70
70
|
@index.rem("ze-id", "allo")
|
71
|
-
Ricordami.redis.smembers("DataSource:udx:
|
71
|
+
Ricordami.redis.smembers("DataSource:udx:u_id").should == []
|
72
72
|
end
|
73
73
|
|
74
74
|
it "returns the redis command(s) to remove the value from the index when return_command is true" do
|
75
75
|
command = @index.rem("ze-id", "allo", true)
|
76
|
-
command.should == [[:srem, ["DataSource:udx:
|
76
|
+
command.should == [[:srem, ["DataSource:udx:u_id", "allo"]]]
|
77
77
|
end
|
78
78
|
|
79
79
|
it "returns the number of entries with #count" do
|
@@ -17,7 +17,7 @@ describe Ricordami::UniqueValidator do
|
|
17
17
|
|
18
18
|
it "#setup adds a unique index" do
|
19
19
|
validator.setup(Call)
|
20
|
-
Call.indices[:
|
20
|
+
Call.indices[:u_name].should be_a(Ricordami::UniqueIndex)
|
21
21
|
end
|
22
22
|
|
23
23
|
it "#validate_each adds an error if the value is already used" do
|
@@ -14,7 +14,7 @@ describe Ricordami::ValueIndex do
|
|
14
14
|
it "is initialized with a model, a name and a field" do
|
15
15
|
index.model.should == Friend
|
16
16
|
index.field.should == :first_name
|
17
|
-
index.name.should == :
|
17
|
+
index.name.should == :v_first_name
|
18
18
|
end
|
19
19
|
|
20
20
|
it "has a key name for each distinct value with #key_name_for_value" do
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ricordami
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0.
|
5
|
+
version: 0.0.5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mathieu Lajugie
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-15 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|