Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,14 @@ rake test

## Setting up a connection to the redis server

If you are using Rails you should initialize redis and set up global $redis variable in *config/initializers/redis.rb* file:

And now you can point RedisOrm to any redis you want, for example:
(if you got the global redis variable already set somewhere in initializers/redis.rb)
```ruby
RedisOrm.redis = $redis
```
otherwise you can easily point anywhere you want like you are use to, e.g.:
```ruby
require 'redis'
$redis = Redis.new(:host => 'localhost', :port => 6379)
RedisOrm.redis = Redis.new(host: 'localhost', port: 6379, db: '9')
```

## Defining a model and specifing properties
Expand Down Expand Up @@ -546,22 +549,22 @@ Though I'm a big fan of the Test::Unit all tests are based on RSpec. And the onl
RSpec.configure do |config|
config.before(:all) do
path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/redis.conf"
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
RedisOrm.redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
RedisOrm.redis = Redis.new(:host => 'localhost', :path => path_to_socket)
end

config.before(:each) do
$redis.flushall if $redis
RedisOrm.redis.flushall if RedisOrm.redis
end

config.after(:each) do
$redis.flushall if $redis
RedisOrm.redis.flushall if RedisOrm.redis
end

config.after(:all) do
Process.kill 9, $redis_pid.to_i if $redis_pid
Process.kill 9, RedisOrm.redis_pid.to_i if RedisOrm.redis_pid
end
end
```
Expand Down
10 changes: 5 additions & 5 deletions benchmarks/sortable_benchmark.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ class SortableUser < RedisOrm::Base
end

path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/../test/redis.conf"
$redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
RedisOrm.redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
begin
$redis = Redis.new(:host => 'localhost', :path => path_to_socket)
RedisOrm.redis = Redis.new(:host => 'localhost', :path => path_to_socket)
rescue => e
puts 'Unable to create connection to the redis server: ' + e.message.inspect
Process.kill 9, $redis_pid.to_i if $redis_pid
Process.kill 9, RedisOrm.redis_pid.to_i if RedisOrm.redis_pid
end

n = 100
Expand All @@ -41,5 +41,5 @@ class SortableUser < RedisOrm::Base
x.report("finding users w/ sortable attrs:") { SortableUser.find(:all, :limit => 5, :offset => 10, :order => [:name, :asc]) }
end

$redis.flushall if $redis
Process.kill 9, $redis_pid.to_i if $redis_pid
RedisOrm.redis.flushall if RedisOrm.redis
Process.kill 9, RedisOrm.redis_pid.to_i if RedisOrm.redis_pid
16 changes: 16 additions & 0 deletions lib/redis_orm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,19 @@ def human
end

require File.join(File.dirname(File.expand_path(__FILE__)), 'redis_orm', 'redis_orm')

module RedisOrm
extend self

attr_accessor :redis, :redis_pid
@@redis = Redis.new

def self.redis=(redis)
@@redis = redis
end

def self.redis
@@redis
end

end
30 changes: 15 additions & 15 deletions lib/redis_orm/associations/belongs_to.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ def belongs_to(foreign_model, options = {})

define_method foreign_model_name do
if options[:polymorphic]
model_type = $redis.get("#{model_name}:#{id}:#{foreign_model_name}_type")
model_type = RedisOrm.redis.get("#{model_name}:#{id}:#{foreign_model_name}_type")
if model_type
model_type.to_s.camelize.constantize.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}_id")
model_type.to_s.camelize.constantize.find(RedisOrm.redis.get "#{model_name}:#{@id}:#{foreign_model_name}_id")
end
else
# find model even if it's in some module
full_model_scope = RedisOrm::Base.descendants.detect{|desc| desc.to_s.split('::').include?(foreign_model.to_s.camelize) }
if full_model_scope
full_model_scope.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
full_model_scope.find(RedisOrm.redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
else
foreign_model.to_s.camelize.constantize.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
foreign_model.to_s.camelize.constantize.find(RedisOrm.redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
end
end
end
Expand All @@ -47,13 +47,13 @@ def belongs_to(foreign_model, options = {})
full_model_scope = RedisOrm::Base.descendants.detect{|desc| desc.to_s.split('::').include?(foreign_model.to_s.camelize) }

if options[:polymorphic]
$redis.set("#{model_name}:#{id}:#{foreign_model_name}_type", assoc_with_record.model_name)
$redis.set("#{model_name}:#{id}:#{foreign_model_name}_id", assoc_with_record.id)
RedisOrm.redis.set("#{model_name}:#{id}:#{foreign_model_name}_type", assoc_with_record.model_name)
RedisOrm.redis.set("#{model_name}:#{id}:#{foreign_model_name}_id", assoc_with_record.id)
else
if assoc_with_record.nil?
$redis.del("#{model_name}:#{id}:#{foreign_model_name}")
RedisOrm.redis.del("#{model_name}:#{id}:#{foreign_model_name}")
elsif [foreign_model.to_s, full_model_scope.model_name].include?(assoc_with_record.model_name)
$redis.set("#{model_name}:#{id}:#{foreign_model_name}", assoc_with_record.id)
RedisOrm.redis.set("#{model_name}:#{id}:#{foreign_model_name}", assoc_with_record.id)
else
raise TypeMismatchError
end
Expand All @@ -67,9 +67,9 @@ def belongs_to(foreign_model, options = {})
prepared_index.downcase! if index[:options][:case_insensitive]

if index[:options][:unique]
$redis.del(prepared_index, id)
RedisOrm.redis.del(prepared_index, id)
else
$redis.zrem(prepared_index, id)
RedisOrm.redis.zrem(prepared_index, id)
end
end

Expand All @@ -81,21 +81,21 @@ def belongs_to(foreign_model, options = {})
prepared_index.downcase! if index[:options][:case_insensitive]

if index[:options][:unique]
$redis.set(prepared_index, id)
RedisOrm.redis.set(prepared_index, id)
else
$redis.zadd(prepared_index, Time.now.to_f, id)
RedisOrm.redis.zadd(prepared_index, Time.now.to_f, id)
end
end

# we should have an option to delete created earlier associasion (like 'node.owner = nil')
if assoc_with_record.nil?
# remove old assoc
$redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc
RedisOrm.redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc
else
# check whether *assoc_with_record* object has *has_many* declaration and TODO it states *self.model_name* in plural and there is no record yet from the *assoc_with_record*'s side (in order not to provoke recursion)
if class_associations[assoc_with_record.model_name].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym} && !$redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
if class_associations[assoc_with_record.model_name].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym} && !RedisOrm.redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
# remove old assoc
$redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc
RedisOrm.redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", self.id) if old_assoc
assoc_with_record.send(model_name.pluralize.to_sym).send(:"<<", self)

# check whether *assoc_with_record* object has *has_one* declaration and TODO it states *self.model_name* and there is no record yet from the *assoc_with_record*'s side (in order not to provoke recursion)
Expand Down
14 changes: 7 additions & 7 deletions lib/redis_orm/associations/has_many.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,21 @@ def has_many(foreign_models, options = {})

old_records.each do |record|
if has_many_assoc
$redis.zrem "#{record.model_name}:#{record.id}:#{model_name.pluralize}", id
RedisOrm.redis.zrem "#{record.model_name}:#{record.id}:#{model_name.pluralize}", id
elsif has_one_or_belongs_to_assoc
$redis.del "#{record.model_name}:#{record.id}:#{model_name}"
RedisOrm.redis.del "#{record.model_name}:#{record.id}:#{model_name}"
end
end
end

# clear old assocs from this model side
$redis.zremrangebyscore "#{model_name}:#{id}:#{foreign_models}", 0, Time.now.to_f
RedisOrm.redis.zremrangebyscore "#{model_name}:#{id}:#{foreign_models}", 0, Time.now.to_f
end

records.to_a.each do |record|
# we use here *foreign_models_name* not *record.model_name.pluralize* because of the :as option
key = "#{model_name}:#{id}:#{foreign_models_name}"
$redis.zadd(key, Time.now.to_f, record.id)
RedisOrm.redis.zadd(key, Time.now.to_f, record.id)
set_expire_on_reference_key(key)

record.get_indices.each do |index|
Expand All @@ -52,10 +52,10 @@ def has_many(foreign_models, options = {})
# article.comments = [comment1, comment2]
# iterate through the array of comments and create backlink
# check whether *record* object has *has_many* declaration and it states *self.model_name* in plural
if assoc = class_associations[record.model_name].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym} #&& !$redis.zrank("#{record.model_name}:#{record.id}:#{model_name.pluralize}", id)#record.model_name.to_s.camelize.constantize.find(id).nil?
if assoc = class_associations[record.model_name].detect{|h| h[:type] == :has_many && h[:foreign_models] == model_name.pluralize.to_sym} #&& !RedisOrm.redis.zrank("#{record.model_name}:#{record.id}:#{model_name.pluralize}", id)#record.model_name.to_s.camelize.constantize.find(id).nil?
assoc_foreign_models_name = assoc[:options][:as] ? assoc[:options][:as] : model_name.pluralize
key = "#{record.model_name}:#{record.id}:#{assoc_foreign_models_name}"
$redis.zadd(key, Time.now.to_f, id) if !$redis.zrank(key, id)
RedisOrm.redis.zadd(key, Time.now.to_f, id) if !RedisOrm.redis.zrank(key, id)
set_expire_on_reference_key(key)
end

Expand All @@ -64,7 +64,7 @@ def has_many(foreign_models, options = {})
foreign_model_name = assoc[:options][:as] ? assoc[:options][:as] : model_name
key = "#{record.model_name}:#{record.id}:#{foreign_model_name}"
# overwrite assoc anyway so we don't need to check record.send(model_name.to_sym).nil? here
$redis.set(key, id)
RedisOrm.redis.set(key, id)
set_expire_on_reference_key(key)
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/redis_orm/associations/has_many_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ def save_index_for_associated_record(index, record, inception)
prepared_index.downcase! if index[:options][:case_insensitive]

if index[:options][:unique]
$redis.set(prepared_index, record.id)
RedisOrm.redis.set(prepared_index, record.id)
else
$redis.zadd(prepared_index, Time.now.to_f, record.id)
RedisOrm.redis.zadd(prepared_index, Time.now.to_f, record.id)
end
end
end
Expand Down
22 changes: 11 additions & 11 deletions lib/redis_orm/associations/has_many_proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def receiver_instance
end

def fetch
@records = @foreign_models.to_s.singularize.camelize.constantize.find($redis.zrevrangebyscore __key__, Time.now.to_f, 0)
@records = @foreign_models.to_s.singularize.camelize.constantize.find(RedisOrm.redis.zrevrangebyscore __key__, Time.now.to_f, 0)
@fetched = true
end

Expand All @@ -35,7 +35,7 @@ def to_a
# user.avatars << Avatar.find(23) => user:1:avatars => [23]
def <<(new_records)
new_records.to_a.each do |record|
$redis.zadd(__key__, Time.now.to_f, record.id)
RedisOrm.redis.zadd(__key__, Time.now.to_f, record.id)

receiver_instance.set_expire_on_reference_key(__key__)

Expand All @@ -58,8 +58,8 @@ def <<(new_records)

reference_key = "#{record.model_name}:#{record.id}:#{pluralized_reciever_model_name}"

if !$redis.zrank(reference_key, @reciever_id)
$redis.zadd(reference_key, Time.now.to_f, @reciever_id)
if !RedisOrm.redis.zrank(reference_key, @reciever_id)
RedisOrm.redis.zadd(reference_key, Time.now.to_f, @reciever_id)
receiver_instance.set_expire_on_reference_key(reference_key)
end
# check whether *record* object has *has_one* declaration and TODO it states *self.model_name* and there is no record yet from the *record*'s side (in order not to provoke recursion)
Expand All @@ -71,7 +71,7 @@ def <<(new_records)
end
if record.send(reciever_model_name).nil?
key = "#{record.model_name}:#{record.id}:#{reciever_model_name}"
$redis.set(key, @reciever_id)
RedisOrm.redis.set(key, @reciever_id)
receiver_instance.set_expire_on_reference_key(key)
end
end
Expand Down Expand Up @@ -107,13 +107,13 @@ def all(options = {})
# to DRY things up I use here check for index but *else* branch also imply that the index might have be used
# since *prepared_index* vary whether options[:conditions] are present or not
if index && index[:options][:unique]
id = $redis.get prepared_index
id = RedisOrm.redis.get prepared_index
@records << @foreign_models.to_s.singularize.camelize.constantize.find(id)
else
ids = if options[:order].to_s == 'desc'
$redis.zrevrangebyscore(prepared_index, Time.now.to_f, 0, :limit => limit)
RedisOrm.redis.zrevrangebyscore(prepared_index, Time.now.to_f, 0, :limit => limit)
else
$redis.zrangebyscore(prepared_index, 0, Time.now.to_f, :limit => limit)
RedisOrm.redis.zrangebyscore(prepared_index, 0, Time.now.to_f, :limit => limit)
end
@records += @foreign_models.to_s.singularize.camelize.constantize.find(ids)
end
Expand All @@ -127,7 +127,7 @@ def all(options = {})

def find(token = nil, options = {})
if token.is_a?(String) || token.is_a?(Integer)
record_id = $redis.zrank(__key__, token.to_i)
record_id = RedisOrm.redis.zrank(__key__, token.to_i)
if record_id
@fetched = true
@records = @foreign_models.to_s.singularize.camelize.constantize.find(token)
Expand All @@ -145,11 +145,11 @@ def find(token = nil, options = {})
end

def delete(id)
$redis.zrem(__key__, id.to_i)
RedisOrm.redis.zrem(__key__, id.to_i)
end

def count
$redis.zcard __key__
RedisOrm.redis.zcard __key__
end

def method_missing(method_name, *args, &block)
Expand Down
20 changes: 10 additions & 10 deletions lib/redis_orm/associations/has_one.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def has_one(foreign_model, options = {})
end

define_method foreign_model_name do
foreign_model.to_s.camelize.constantize.find($redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
foreign_model.to_s.camelize.constantize.find(RedisOrm.redis.get "#{model_name}:#{@id}:#{foreign_model_name}")
end

# profile = Profile.create :title => 'test'
Expand All @@ -31,9 +31,9 @@ def has_one(foreign_model, options = {})

reference_key = "#{model_name}:#{id}:#{foreign_model_name}"
if assoc_with_record.nil?
$redis.del(reference_key)
RedisOrm.redis.del(reference_key)
elsif assoc_with_record.model_name == foreign_model.to_s
$redis.set(reference_key, assoc_with_record.id)
RedisOrm.redis.set(reference_key, assoc_with_record.id)
set_expire_on_reference_key(reference_key)
else
raise TypeMismatchError
Expand All @@ -47,9 +47,9 @@ def has_one(foreign_model, options = {})
prepared_index.downcase! if index[:options][:case_insensitive]

if index[:options][:unique]
$redis.del(prepared_index, id)
RedisOrm.redis.del(prepared_index, id)
else
$redis.zrem(prepared_index, id)
RedisOrm.redis.zrem(prepared_index, id)
end
end

Expand All @@ -61,24 +61,24 @@ def has_one(foreign_model, options = {})
prepared_index.downcase! if index[:options][:case_insensitive]

if index[:options][:unique]
$redis.set(prepared_index, id)
RedisOrm.redis.set(prepared_index, id)
else
$redis.zadd(prepared_index, Time.now.to_f, id)
RedisOrm.redis.zadd(prepared_index, Time.now.to_f, id)
end
end

if !options[:as]
if assoc_with_record.nil?
# remove old assoc
$redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", id) if old_assoc
RedisOrm.redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", id) if old_assoc
else
# check whether *assoc_with_record* object has *belongs_to* declaration and TODO it states *self.model_name* and there is no record yet from the *assoc_with_record*'s side (in order not to provoke recursion)
if class_associations[assoc_with_record.model_name].detect{|h| [:belongs_to, :has_one].include?(h[:type]) && h[:foreign_model] == model_name.to_sym} && assoc_with_record.send(model_name.to_sym).nil?
# old association is being rewritten here automatically so we don't have to worry about it
assoc_with_record.send("#{model_name}=", self)
elsif class_associations[assoc_with_record.model_name].detect{|h| :has_many == h[:type] && h[:foreign_models] == model_name.to_s.pluralize.to_sym} && !$redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
elsif class_associations[assoc_with_record.model_name].detect{|h| :has_many == h[:type] && h[:foreign_models] == model_name.to_s.pluralize.to_sym} && !RedisOrm.redis.zrank("#{assoc_with_record.model_name}:#{assoc_with_record.id}:#{model_name.pluralize}", self.id)
# remove old assoc
$redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", id) if old_assoc
RedisOrm.redis.zrem("#{old_assoc.model_name}:#{old_assoc.id}:#{model_name.to_s.pluralize}", id) if old_assoc
# create/add new ones
assoc_with_record.send(model_name.pluralize.to_sym).send(:"<<", self)
end
Expand Down
Loading