ricordami 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -10,6 +10,8 @@
10
10
 
11
11
  - add support for booleans and datetimes
12
12
  - add support for native types (list, hash, set, sorted set)
13
+ - add better exception descriptions (i.e.: missing value index when
14
+ querying, etc...)
13
15
 
14
16
  ## Maybe ##
15
17
 
@@ -61,7 +61,7 @@ module Ricordami
61
61
  private
62
62
 
63
63
  def run_expressions(expressions)
64
- key_all_ids = indices[:id].uidx_key_name
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
- index = indices[field]
78
- raise MissingIndex.new("class: #{self}, attribute: #{field.inspect}") if index.nil?
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
@@ -23,12 +23,12 @@ module Ricordami
23
23
  alias :[] :get
24
24
 
25
25
  def all(expressions = nil)
26
- ids = indices[:id].all
26
+ ids = indices[:u_id].all
27
27
  ids.map { |id| get(id) }
28
28
  end
29
29
 
30
30
  def count
31
- indices[:id].count
31
+ indices[:u_id].count
32
32
  end
33
33
  end
34
34
  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) }
@@ -7,7 +7,7 @@ module Ricordami
7
7
  def initialize(model, field)
8
8
  @model = model
9
9
  @field = field.to_sym
10
- @name = @field
10
+ @name = "v_#{@field}".to_sym
11
11
  end
12
12
 
13
13
  def key_name_for_value(value)
@@ -1,3 +1,3 @@
1
1
  module Ricordami
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -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(:size)
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[:size].should be_a(Ricordami::UniqueIndex)
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[:size].should be_a(Ricordami::ValueIndex)
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[:model].should be_a(Ricordami::ValueIndex)
19
- Car.indices[:model].should == index
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[:model].should be_a(Ricordami::UniqueIndex)
27
- Car.indices[:model].should == index
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[:model].scope.should == [:brand]
34
- Car.indices[:model].fields.should == [:model, :brand]
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[:model].need_get_by.should be_true
39
+ Car.indices[:u_model].need_get_by.should be_true
40
40
  Car.index :unique => :model, :get_by => false
41
- Car.indices[:model].need_get_by.should be_true
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[:name].all.should == ["Prius"]
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[:name].all.should == ["Prius"]
55
+ Car.indices[:u_name].all.should == ["Prius"]
56
56
  car.name = "Rav4"
57
57
  car.save
58
- Car.indices[:name].all.should == ["Rav4"]
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[:name].all.should be_empty
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[:id].all.should == ["hi"]
36
+ Tenant.indices[:u_id].all.should == ["hi"]
37
37
  instance.name = "john"
38
38
  instance.save
39
- Tenant.indices[:id].all.should == ["hi"]
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 == :id
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:id"
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:id").should == ["allo"]
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:name_domain").should == ["jobs_-::-_apple.com"]
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:id").should == []
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:id", "allo"]]]
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[:name].should be_a(Ricordami::UniqueIndex)
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 == :first_name
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.4
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-12 23:00:00 -08:00
13
+ date: 2011-03-15 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency