ricordami 0.0.1
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.md +13 -0
- data/ISSUES.md +0 -0
- data/MIT-LICENSE +21 -0
- data/README.md +454 -0
- data/TODO.md +21 -0
- data/examples/calls.rb +64 -0
- data/examples/singers.rb +42 -0
- data/lib/ricordami/attribute.rb +52 -0
- data/lib/ricordami/can_be_queried.rb +133 -0
- data/lib/ricordami/can_be_validated.rb +27 -0
- data/lib/ricordami/can_have_relationships.rb +152 -0
- data/lib/ricordami/configuration.rb +39 -0
- data/lib/ricordami/connection.rb +22 -0
- data/lib/ricordami/exceptions.rb +14 -0
- data/lib/ricordami/has_attributes.rb +159 -0
- data/lib/ricordami/has_indices.rb +105 -0
- data/lib/ricordami/is_lockable.rb +52 -0
- data/lib/ricordami/is_persisted.rb +123 -0
- data/lib/ricordami/is_retrievable.rb +35 -0
- data/lib/ricordami/key_namer.rb +63 -0
- data/lib/ricordami/model.rb +29 -0
- data/lib/ricordami/query.rb +68 -0
- data/lib/ricordami/relationship.rb +40 -0
- data/lib/ricordami/unique_index.rb +59 -0
- data/lib/ricordami/unique_validator.rb +21 -0
- data/lib/ricordami/value_index.rb +26 -0
- data/lib/ricordami/version.rb +3 -0
- data/lib/ricordami.rb +26 -0
- data/spec/acceptance/manage_relationships_spec.rb +42 -0
- data/spec/acceptance/model_with_validation_spec.rb +78 -0
- data/spec/acceptance/query_model_spec.rb +93 -0
- data/spec/acceptance_helper.rb +2 -0
- data/spec/ricordami/attribute_spec.rb +113 -0
- data/spec/ricordami/can_be_queried_spec.rb +254 -0
- data/spec/ricordami/can_be_validated_spec.rb +115 -0
- data/spec/ricordami/can_have_relationships_spec.rb +255 -0
- data/spec/ricordami/configuration_spec.rb +45 -0
- data/spec/ricordami/connection_spec.rb +25 -0
- data/spec/ricordami/exceptions_spec.rb +43 -0
- data/spec/ricordami/has_attributes_spec.rb +266 -0
- data/spec/ricordami/has_indices_spec.rb +73 -0
- data/spec/ricordami/is_lockable_spec.rb +45 -0
- data/spec/ricordami/is_persisted_spec.rb +186 -0
- data/spec/ricordami/is_retrievable_spec.rb +55 -0
- data/spec/ricordami/key_namer_spec.rb +56 -0
- data/spec/ricordami/model_spec.rb +65 -0
- data/spec/ricordami/query_spec.rb +156 -0
- data/spec/ricordami/relationship_spec.rb +123 -0
- data/spec/ricordami/unique_index_spec.rb +87 -0
- data/spec/ricordami/unique_validator_spec.rb +41 -0
- data/spec/ricordami/value_index_spec.rb +40 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/constants.rb +43 -0
- data/spec/support/db_manager.rb +18 -0
- data/test/bin/data_loader.rb +107 -0
- data/test/data/domains.txt +462 -0
- data/test/data/first_names.txt +1220 -0
- data/test/data/last_names.txt +1028 -0
- data/test/data/people_100_000.csv.bz2 +0 -0
- data/test/data/people_10_000.csv.bz2 +0 -0
- data/test/data/people_1_000_000.csv.bz2 +0 -0
- metadata +258 -0
@@ -0,0 +1,123 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "ricordami/relationship"
|
3
|
+
|
4
|
+
describe Ricordami::Relationship do
|
5
|
+
def valid_options
|
6
|
+
{:other => :blih, :self => :blah}
|
7
|
+
end
|
8
|
+
uses_constants("Stuff")
|
9
|
+
subject { Ricordami::Relationship }
|
10
|
+
|
11
|
+
describe "using most options" do
|
12
|
+
subject do
|
13
|
+
Ricordami::Relationship.new(:references_many, :other => :stuffs,
|
14
|
+
:as => :things, :self => :person,
|
15
|
+
:alias => :owner, :dependent => :delete)
|
16
|
+
end
|
17
|
+
|
18
|
+
it("has a type") { subject.type.should == :references_many }
|
19
|
+
|
20
|
+
it("has a name") { subject.name.should == :things }
|
21
|
+
|
22
|
+
it("has an object kind") { subject.object_kind.should == :stuff }
|
23
|
+
|
24
|
+
it("returns the object class") { subject.object_class.should == Stuff }
|
25
|
+
|
26
|
+
it("has a self kind") { subject.self_kind.should == :person }
|
27
|
+
|
28
|
+
it("has an alias") { subject.alias.should == :owner }
|
29
|
+
|
30
|
+
it("has a referrer id") { subject.referrer_id.should == "owner_id" }
|
31
|
+
|
32
|
+
it("has a dependent attribute") { subject.dependent.should == :delete }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "other cases" do
|
36
|
+
it "can specify an optional dependent option" do
|
37
|
+
relationship = subject.new(:references_many, valid_options.merge(:dependent => :delete))
|
38
|
+
relationship.dependent.should == :delete
|
39
|
+
end
|
40
|
+
|
41
|
+
it "deducts the object kind from the other parameter" do
|
42
|
+
relationship = subject.new(:references_many, valid_options.merge(:other => :stuffs))
|
43
|
+
relationship.name.should == :stuffs
|
44
|
+
relationship.object_kind.should == :stuff
|
45
|
+
end
|
46
|
+
|
47
|
+
it "can specify an optional as option that is the relationship name" do
|
48
|
+
relationship = subject.new(:references_many, valid_options.merge(:other => :stuffs, :as => :things))
|
49
|
+
relationship.name.should == :things
|
50
|
+
relationship.object_kind.should == :stuff
|
51
|
+
end
|
52
|
+
|
53
|
+
it "deducts the referrer id from the other or as parameter for a referenced_in relationship" do
|
54
|
+
relationship = subject.new(:referenced_in, :self => :ingredient, :other => :cook)
|
55
|
+
relationship.referrer_id.should == "cook_id"
|
56
|
+
relationship = subject.new(:referenced_in, :self => :ingredient, :other => :cook, :as => :chef)
|
57
|
+
relationship.referrer_id.should == "chef_id"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "deducts the referrer id from the self or alias parameter for a references_many relationship" do
|
61
|
+
relationship = subject.new(:references_many, :self => :cook, :other => :ingredients)
|
62
|
+
relationship.referrer_id.should == "cook_id"
|
63
|
+
relationship = subject.new(:references_many, :self => :cook, :alias => :chef, :other => :ingredients, :as => :stuff)
|
64
|
+
relationship.referrer_id.should == "chef_id"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "deducts the referrer id from the self or alias parameter for a references_one relationship" do
|
68
|
+
relationship = subject.new(:references_one, :self => :cook, :other => :hat)
|
69
|
+
relationship.referrer_id.should == "cook_id"
|
70
|
+
relationship = subject.new(:references_one, :self => :cook, :alias => :chef, :other => :hat, :as => :toque)
|
71
|
+
relationship.referrer_id.should == "chef_id"
|
72
|
+
end
|
73
|
+
|
74
|
+
it "can specify an optional alias that is the relationship name for the other party" do
|
75
|
+
relationship = subject.new(:references_many, valid_options.merge(:self => :person, :alias => :owners))
|
76
|
+
relationship.alias.should == :owners
|
77
|
+
relationship.self_kind.should == :person
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "error cases" do
|
82
|
+
it "raises an error if all the mandatory parameters are not present" do
|
83
|
+
[{}, {:other => :blah}, {:self => :blih}].each do |options|
|
84
|
+
lambda {
|
85
|
+
subject.new(:references_many, options)
|
86
|
+
}.should raise_error(Ricordami::MissingMandatoryArgs)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "doesn't raise an error if all mandatory parameters are present" do
|
91
|
+
lambda {
|
92
|
+
subject.new(:referenced_in, :other => :blah, :self => :blih)
|
93
|
+
}.should_not raise_error
|
94
|
+
end
|
95
|
+
|
96
|
+
it "raises an error if the type is not supported" do
|
97
|
+
lambda { subject.new(:references_many, valid_options) }.should_not raise_error
|
98
|
+
lambda { subject.new(:referenced_in, valid_options) }.should_not raise_error
|
99
|
+
lambda { subject.new(:references_one, valid_options) }.should_not raise_error
|
100
|
+
lambda {
|
101
|
+
subject.new(:blah, valid_options)
|
102
|
+
}.should raise_error(Ricordami::TypeNotSupported)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "raises an error if dependent is set but not equal to :nullify or :delete" do
|
106
|
+
lambda {
|
107
|
+
subject.new(:references_many, valid_options.merge(:dependent => :nullify))
|
108
|
+
}.should_not raise_error
|
109
|
+
lambda {
|
110
|
+
subject.new(:references_many, valid_options.merge(:dependent => :delete))
|
111
|
+
}.should_not raise_error
|
112
|
+
lambda {
|
113
|
+
subject.new(:references_many, valid_options.merge(:dependent => :what))
|
114
|
+
}.should raise_error(Ricordami::OptionValueInvalid)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "raises an error if an option is not supported" do
|
118
|
+
lambda {
|
119
|
+
subject.new(:references_many, valid_options.merge(:not_supported => :blah))
|
120
|
+
}.should raise_error(ArgumentError)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Ricordami::UniqueIndex do
|
4
|
+
subject { Ricordami::UniqueIndex }
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
create_constant("DataSource")
|
8
|
+
DataSource.attribute :name
|
9
|
+
@index = subject.new(DataSource, :id)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "is initialized with a model, a name and the fields to be unique" do
|
13
|
+
@index.model.should == DataSource
|
14
|
+
@index.fields.should == [:id]
|
15
|
+
@index.name.should == :id
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns its internal index name with #uidx_key_name" do
|
19
|
+
@index.uidx_key_name.should == "DataSource:udx:id"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns its internal reference name with #ref_key_name" do
|
23
|
+
@index.ref_key_name.should == "DataSource:hsh:id_to_id"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "adds a string to the index with #add" do
|
27
|
+
@index.add("ze-id", "allo")
|
28
|
+
Ricordami.driver.smembers("DataSource:udx:id").should == ["allo"]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "also indices the hash index with #add if fields is not :id and :get_by is true" do
|
32
|
+
DataSource.attribute :domain
|
33
|
+
other = subject.new(DataSource, [:name, :domain], :get_by => true)
|
34
|
+
other.add("ze-id", ["jobs", "apple.com"])
|
35
|
+
Ricordami.driver.smembers("DataSource:udx:name_domain").should == ["jobs_-::-_apple.com"]
|
36
|
+
Ricordami.driver.hget("DataSource:hsh:name_domain_to_id", "jobs_-::-_apple.com").should == "ze-id"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "doesn't index the has index with #add if :get_by is false or fields is :id" do
|
40
|
+
one = subject.new(DataSource, :name)
|
41
|
+
one.add("ze-id", "jobs")
|
42
|
+
Ricordami.driver.hexists("DataSource:hsh:name_to_id", "jobs").should be_false
|
43
|
+
two = subject.new(DataSource, :id, :get_by => true)
|
44
|
+
two.add("ze-id", "ze-id")
|
45
|
+
Ricordami.driver.hexists("DataSource:hsh:id_to_id", "ze-id").should be_false
|
46
|
+
three = subject.new(DataSource, :name, :get_by => true)
|
47
|
+
three.add("ze-id", "jobs")
|
48
|
+
Ricordami.driver.hexists("DataSource:hsh:name_to_id", "jobs").should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns the id from values with #id_for_values if :get_by is true" do
|
52
|
+
DataSource.attribute :domain
|
53
|
+
two_fields = subject.new(DataSource, [:name, :domain], :get_by => true)
|
54
|
+
two_fields.add("ze-id", ["jobs", "apple.com"])
|
55
|
+
two_fields.id_for_values("jobs", "apple.com").should == "ze-id"
|
56
|
+
one_field = subject.new(DataSource, :name, :get_by => true)
|
57
|
+
one_field.add("ze-id", "jobs")
|
58
|
+
one_field.id_for_values("jobs").should == "ze-id"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "removes a string from the index with #rem" do
|
62
|
+
@index.add("ze-id", "allo")
|
63
|
+
@index.rem("ze-id", "allo")
|
64
|
+
Ricordami.driver.smembers("DataSource:udx:id").should == []
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns the redis command(s) to remove the value from the index when return_command is true" do
|
68
|
+
command = @index.rem("ze-id", "allo", true)
|
69
|
+
command.should == [[:srem, ["DataSource:udx:id", "allo"]]]
|
70
|
+
end
|
71
|
+
|
72
|
+
it "returns the number of entries with #count" do
|
73
|
+
5.times { |i| @index.add("ze-id", i.to_s) }
|
74
|
+
@index.count.should == 5
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns all the strings from the index with #all" do
|
78
|
+
%w(allo la terre).each { |v| @index.add("ze-id", v) }
|
79
|
+
@index.all.should =~ ["allo", "la", "terre"]
|
80
|
+
end
|
81
|
+
|
82
|
+
it "returns if a string already exists with #include?" do
|
83
|
+
%w(allo la terre).each { |v| @index.add("ze-id", v) }
|
84
|
+
@index.should include("terre")
|
85
|
+
@index.should_not include("earth")
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "ricordami/can_be_validated"
|
3
|
+
|
4
|
+
describe Ricordami::UniqueValidator do
|
5
|
+
uses_constants("Call")
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Call.send(:include, Ricordami::CanBeValidated)
|
9
|
+
Call.attribute :name
|
10
|
+
end
|
11
|
+
let(:record) { Call.new(:name => "sophie") }
|
12
|
+
let(:validator) { Ricordami::UniqueValidator.new(:attributes => [:name]) }
|
13
|
+
|
14
|
+
it "is an active model EachValidator" do
|
15
|
+
validator.is_a?(ActiveModel::EachValidator)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "#setup adds a unique index" do
|
19
|
+
validator.setup(Call)
|
20
|
+
Call.indices[:name].should be_a(Ricordami::UniqueIndex)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "#validate_each adds an error if the value is already used" do
|
24
|
+
validator.setup(Call)
|
25
|
+
record.save
|
26
|
+
|
27
|
+
sophie = Call.new(:name => "sophie")
|
28
|
+
validator.validate_each(sophie, :name, record.name)
|
29
|
+
sophie.should have(1).error
|
30
|
+
sophie.errors[:name].should == ["is already used"]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "accepts an option :message to change the error message" do
|
34
|
+
validator = Ricordami::UniqueValidator.new(:attributes => [:name], :message => "come on, man!")
|
35
|
+
validator.setup(Call)
|
36
|
+
record.save
|
37
|
+
sophie = Call.new(:name => "sophie")
|
38
|
+
validator.validate_each(sophie, :name, record.name)
|
39
|
+
sophie.errors[:name].should == ["come on, man!"]
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "ricordami/value_index"
|
3
|
+
|
4
|
+
describe Ricordami::ValueIndex do
|
5
|
+
subject { Ricordami::ValueIndex }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
create_constant("Friend")
|
9
|
+
Friend.attribute :first_name
|
10
|
+
@index = subject.new(Friend, :first_name)
|
11
|
+
end
|
12
|
+
let(:index) { @index }
|
13
|
+
|
14
|
+
it "is initialized with a model, a name and a field" do
|
15
|
+
index.model.should == Friend
|
16
|
+
index.field.should == :first_name
|
17
|
+
index.name.should == :first_name
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has a key name for each distinct value with #key_name_for_value" do
|
21
|
+
index.key_name_for_value("VALUE").should == "Friend:idx:first_name:VkFMVUU="
|
22
|
+
end
|
23
|
+
|
24
|
+
it "adds the id to the index value with #add" do
|
25
|
+
index.add("3", "VALUE")
|
26
|
+
Ricordami.driver.smembers("Friend:idx:first_name:VkFMVUU=").should == ["3"]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "removes the id from the index value with #rem" do
|
30
|
+
index.add("1", "VALUE")
|
31
|
+
index.add("2", "VALUE")
|
32
|
+
index.rem("1", "VALUE")
|
33
|
+
Ricordami.driver.smembers("Friend:idx:first_name:VkFMVUU=").should == ["2"]
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns the redis command to remove the value from the index when return_command is true" do
|
37
|
+
commands = index.rem("1", "VALUE", true)
|
38
|
+
commands.should == [[:srem, ["Friend:idx:first_name:VkFMVUU=", "1"]]]
|
39
|
+
end
|
40
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
spec_dir = Pathname.new(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift spec_dir
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "bundler"
|
6
|
+
|
7
|
+
Bundler.setup :default, :test
|
8
|
+
ENV['RACK_ENV'] ||= "test"
|
9
|
+
|
10
|
+
require "rspec"
|
11
|
+
require "support/constants"
|
12
|
+
require "support/db_manager"
|
13
|
+
require "awesome_print"
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.include Support::Constants
|
17
|
+
config.include Support::DbManager
|
18
|
+
config.before(:each) do
|
19
|
+
Ricordami.configure do |config|
|
20
|
+
config.from_hash(:redis_host => "127.0.0.1",
|
21
|
+
:redis_port => 6379,
|
22
|
+
:redis_db => 7,
|
23
|
+
:thread_safe => true)
|
24
|
+
end
|
25
|
+
Ricordami.driver.flushdb
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
require spec_dir + "../lib/ricordami"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# copied from toystore gem (https://github.com/newtoy/toystore/raw/master/spec/support/constants.rb)
|
2
|
+
# and a bit updated for ricordami
|
3
|
+
|
4
|
+
module Support
|
5
|
+
module Constants
|
6
|
+
def self.included(base)
|
7
|
+
base.extend(ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def uses_constants(*constants)
|
12
|
+
before { create_constants(*constants) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_constants(*constants)
|
17
|
+
constants.each { |constant| create_constant(constant) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove_constants(*constants)
|
21
|
+
constants.each { |constant| remove_constant(constant) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_constant(constant)
|
25
|
+
remove_constant(constant)
|
26
|
+
Object.const_set(constant, Model(constant))
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove_constant(constant)
|
30
|
+
Object.send(:remove_const, constant) if Object.const_defined?(constant)
|
31
|
+
end
|
32
|
+
|
33
|
+
def Model(name=nil)
|
34
|
+
Class.new.tap do |model|
|
35
|
+
model.class_eval """
|
36
|
+
def self.name; '#{name}' end
|
37
|
+
def self.to_s; '#{name}' end
|
38
|
+
""" if name
|
39
|
+
model.send(:include, Ricordami::Model)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Support
|
2
|
+
module DbManager
|
3
|
+
def switch_db_to_error
|
4
|
+
@_db_mode_error = true
|
5
|
+
error = Object.new
|
6
|
+
def error.method_missing(meth, *args, &blk)
|
7
|
+
raise Errno::ECONNREFUSED
|
8
|
+
end
|
9
|
+
Ricordami.instance_eval { @driver = error }
|
10
|
+
end
|
11
|
+
|
12
|
+
def switch_db_to_ok
|
13
|
+
return unless @_db_mode_error
|
14
|
+
Ricordami.instance_eval { @driver = nil }
|
15
|
+
@_db_mode_error = false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup :default, :development
|
6
|
+
|
7
|
+
require "thor"
|
8
|
+
require "thor/actions"
|
9
|
+
require "csv"
|
10
|
+
require "redis"
|
11
|
+
|
12
|
+
class DataLoader < Thor
|
13
|
+
include Thor::Actions
|
14
|
+
|
15
|
+
add_runtime_options!
|
16
|
+
check_unknown_options!
|
17
|
+
|
18
|
+
desc "generate_people FILE_NAME", "Generate a CSV file of random people"
|
19
|
+
method_option :number, :aliases => "-n", :default => 1_000, :type => :numeric, :desc => "number of people to generate"
|
20
|
+
|
21
|
+
def generate_people(file_name)
|
22
|
+
d = load_data
|
23
|
+
CSV.open(file_name, "w") do |csv|
|
24
|
+
csv << %w(first_name last_name email age)
|
25
|
+
options[:number].times do
|
26
|
+
f, l = get_first_name(d), get_last_name(d)
|
27
|
+
csv << [f, l, get_email(d, f, l), get_age]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
puts "File #{file_name} generated with #{options[:number]} people."
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "load_people FILE_NAME", "Load a people file into Redis"
|
34
|
+
method_option :db, :aliases => "-d", :default => 1, :type => :numeric, :desc => "database number"
|
35
|
+
|
36
|
+
def load_people(file_name)
|
37
|
+
r = Redis.new
|
38
|
+
r.select(options[:db])
|
39
|
+
r.flushdb
|
40
|
+
key_ids = "global:people:ids"
|
41
|
+
key_att = "people:"
|
42
|
+
key_seq = "global:seq_id"
|
43
|
+
i = 0
|
44
|
+
CSV.foreach(file_name, :headers => :first_row) do |row|
|
45
|
+
id = r.incr(key_seq)
|
46
|
+
r.multi
|
47
|
+
r.hmset("#{key_att}#{id}", *row.to_a.flatten)
|
48
|
+
r.sadd(key_ids, id)
|
49
|
+
r.exec
|
50
|
+
i += 1
|
51
|
+
if i == 100
|
52
|
+
putc "."
|
53
|
+
i = 0
|
54
|
+
end
|
55
|
+
end
|
56
|
+
puts
|
57
|
+
puts "Db loaded."
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def load_data
|
63
|
+
data_dir = File.expand_path("../../data", __FILE__)
|
64
|
+
{
|
65
|
+
:first => read_entries(File.join(data_dir, "first_names.txt")),
|
66
|
+
:last => read_entries(File.join(data_dir, "last_names.txt")),
|
67
|
+
:domains => read_entries(File.join(data_dir, "domains.txt"))
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
def read_entries(path)
|
72
|
+
[].tap do |entries|
|
73
|
+
File.open(path, "r") do |f|
|
74
|
+
f.each_line { |line| entries.push(line.chomp.downcase.capitalize) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_first_name(d)
|
80
|
+
d[:first].sample(rand(12) == 3 ? 2 : 1).join(" ")
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_last_name(d)
|
84
|
+
d[:last].sample
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_email(d, f, l)
|
88
|
+
one = f[0..(rand(2) - 2)].downcase
|
89
|
+
dot = rand(2) == 0 ? "" : "."
|
90
|
+
two = l.split.join("-").downcase
|
91
|
+
"#{one}#{dot}#{two}@#{d[:domains].sample}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_age
|
95
|
+
18 + rand(50)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
require "rubygems" if RUBY_VERSION[0..2].to_f < 1.9
|
100
|
+
|
101
|
+
begin
|
102
|
+
DataLoader.start
|
103
|
+
rescue Exception => ex
|
104
|
+
STDERR.puts "#{File.basename(__FILE__)}: #{ex}"
|
105
|
+
raise
|
106
|
+
end
|
107
|
+
|