ricordami 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|