ricordami 0.0.4 → 0.0.5

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.
@@ -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