lib/ohm.rb in ohm-1.0.0.rc1 vs lib/ohm.rb in ohm-1.0.0.rc2
- old
+ new
@@ -18,11 +18,11 @@
#
# Solution: you need to save your model first.
#
# IndexNotFound:
#
- # Comment.find(foo: "Bar") # => Error
+ # Comment.find(:foo => "Bar") # => Error
#
# Solution: add an index with `Comment.index :foo`.
#
# UniqueIndexViolation:
#
@@ -101,12 +101,12 @@
# Stores the connection options for the Redis instance.
#
# Examples:
#
- # Ohm.connect(port: 6380, db: 1, host: "10.0.1.1")
- # Ohm.connect(url: "redis://10.0.1.1:6380/1")
+ # Ohm.connect(:port => 6380, :db => 1, :host => "10.0.1.1")
+ # Ohm.connect(:url => "redis://10.0.1.1:6380/1")
#
# All of the options are simply passed on to `Redis.connect`.
#
def self.connect(options = {})
conn.start(options)
@@ -152,20 +152,20 @@
#
# class User < Ohm::Model
# attribute :name
# end
#
- # User.all.sort_by(:name, order: "ALPHA")
- # User.all.sort_by(:name, order: "ALPHA DESC")
- # User.all.sort_by(:name, order: "ALPHA DESC", limit: [0, 10])
+ # User.all.sort_by(:name, :order => "ALPHA")
+ # User.all.sort_by(:name, :order => "ALPHA DESC")
+ # User.all.sort_by(:name, :order => "ALPHA DESC", :limit => [0, 10])
#
# Note: This is slower compared to just doing `sort`, specifically
# because Redis has to read each individual hash in order to sort
# them.
#
def sort_by(att, options = {})
- sort(options.merge(by: namespace["*->%s" % att]))
+ sort(options.merge(:by => namespace["*->%s" % att]))
end
# Allows you to sort your models using their IDs. This is much
# faster than `sort_by`. If you simply want to get records in
# ascending or descending order, then this is the best method to
@@ -175,20 +175,20 @@
#
# class User < Ohm::Model
# attribute :name
# end
#
- # User.create(name: "John")
- # User.create(name: "Jane")
+ # User.create(:name => "John")
+ # User.create(:name => "Jane")
#
# User.all.sort.map(&:id) == ["1", "2"]
# # => true
#
- # User.all.sort(order: "ASC").map(&:id) == ["1", "2"]
+ # User.all.sort(:order => "ASC").map(&:id) == ["1", "2"]
# # => true
#
- # User.all.sort(order: "DESC").map(&:id) == ["2", "1"]
+ # User.all.sort(:order => "DESC").map(&:id) == ["2", "1"]
# # => true
#
def sort(options = {})
if options.has_key?(:get)
options[:get] = namespace["*->%s" % options[:get]]
@@ -223,18 +223,18 @@
# first element.
#
# Example:
#
# User.all.first ==
- # User.all.sort(limit: [0, 1]).first
+ # User.all.sort(:limit => [0, 1]).first
#
- # User.all.first(by: :name, "ALPHA") ==
- # User.all.sort_by(:name, order: "ALPHA", limit: [0, 1]).first
+ # User.all.first(:by => :name, "ALPHA") ==
+ # User.all.sort_by(:name, :order => "ALPHA", :limit => [0, 1]).first
#
def first(options = {})
opts = options.dup
- opts.merge!(limit: [0, 1])
+ opts.merge!(:limit => [0, 1])
if opts[:by]
sort_by(opts.delete(:by), opts).first
else
sort(opts).first
@@ -268,15 +268,19 @@
def fetch(ids)
arr = model.db.pipelined do
ids.each { |id| model.db.hgetall(namespace[id]) }
end
- return [] if arr.nil?
+ res = []
- arr.map.with_index do |atts, idx|
- model.new(Hash[*atts].update(id: ids[idx]))
+ return res if arr.nil?
+
+ arr.each_with_index do |atts, idx|
+ res << model.new(Hash[*atts].update(:id => ids[idx]))
end
+
+ res
end
end
class List < Struct.new(:key, :namespace, :model)
include Enumerable
@@ -394,27 +398,31 @@
def fetch(ids)
arr = model.db.pipelined do
ids.each { |id| model.db.hgetall(namespace[id]) }
end
- return [] if arr.nil?
+ res = []
- arr.map.with_index do |atts, idx|
- model.new(Hash[*atts].update(id: ids[idx]))
+ return res if arr.nil?
+
+ arr.each_with_index do |atts, idx|
+ res << model.new(Hash[*atts].update(:id => ids[idx]))
end
+
+ res
end
end
class Set < Struct.new(:key, :namespace, :model)
include Collection
# Chain new fiters on an existing set.
#
# Example:
#
- # set = User.find(name: "John")
- # set.find(age: 30)
+ # set = User.find(:name => "John")
+ # set.find(:age => 30)
#
def find(dict)
keys = model.filters(dict)
keys.push(key)
@@ -423,29 +431,29 @@
# Reduce the set using any number of filters.
#
# Example:
#
- # set = User.find(name: "John")
- # set.except(country: "US")
+ # set = User.find(:name => "John")
+ # set.except(:country => "US")
#
# # You can also do it in one line.
- # User.find(name: "John").except(country: "US")
+ # User.find(:name => "John").except(:country => "US")
#
def except(dict)
MultiSet.new([key], namespace, model).except(dict)
end
# Do a union to the existing set using any number of filters.
#
# Example:
#
- # set = User.find(name: "John")
- # set.union(name: "Jane")
+ # set = User.find(:name => "John")
+ # set.union(:name => "Jane")
#
# # You can also do it in one line.
- # User.find(name: "John").union(name: "Jane")
+ # User.find(:name => "John").union(:name => "Jane")
#
def union(dict)
MultiSet.new([key], namespace, model).union(dict)
end
@@ -517,25 +525,25 @@
# Example:
#
# User.all.kind_of?(Ohm::Set)
# # => true
#
- # User.find(name: "John").kind_of?(Ohm::Set)
+ # User.find(:name => "John").kind_of?(Ohm::Set)
# # => true
#
- # User.find(name: "John", age: 30).kind_of?(Ohm::MultiSet)
+ # User.find(:name => "John", :age => 30).kind_of?(Ohm::MultiSet)
# # => true
#
class MultiSet < Struct.new(:keys, :namespace, :model)
include Collection
# Chain new fiters on an existing set.
#
# Example:
#
- # set = User.find(name: "John", age: 30)
- # set.find(status: 'pending')
+ # set = User.find(:name => "John", :age => 30)
+ # set.find(:status => 'pending')
#
def find(dict)
keys = model.filters(dict)
keys.push(*self.keys)
@@ -544,15 +552,15 @@
# Reduce the set using any number of filters.
#
# Example:
#
- # set = User.find(name: "John")
- # set.except(country: "US")
+ # set = User.find(:name => "John")
+ # set.except(:country => "US")
#
# # You can also do it in one line.
- # User.find(name: "John").except(country: "US")
+ # User.find(:name => "John").except(:country => "US")
#
def except(dict)
sdiff.push(*model.filters(dict)).uniq!
return self
@@ -560,15 +568,15 @@
# Do a union to the existing set using any number of filters.
#
# Example:
#
- # set = User.find(name: "John")
- # set.union(name: "Jane")
+ # set = User.find(:name => "John")
+ # set.union(:name => "Jane")
#
# # You can also do it in one line.
- # User.find(name: "John").union(name: "Jane")
+ # User.find(:name => "John").union(:name => "Jane")
#
def union(dict)
sunion.push(*model.filters(dict)).uniq!
return self
@@ -582,11 +590,11 @@
def sdiff
@sdiff ||= []
end
def execute
- key = namespace[:temp][SecureRandom.uuid]
+ key = namespace[:temp][SecureRandom.hex(32)]
key.sinterstore(*keys)
key.sdiffstore(key, *sdiff) if sdiff.any?
key.sunionstore(key, *sunion) if sunion.any?
begin
@@ -613,11 +621,11 @@
# counter :points
#
# set :posts, :Post
# end
#
- # u = User.create(name: "John", email: "foo@bar.com")
+ # u = User.create(:name => "John", :email => "foo@bar.com")
# u.incr :points
# u.posts.add(Post.create)
#
# When you execute `User.create(...)`, you run the following Redis
# commands:
@@ -694,11 +702,11 @@
# u = User.create
# u == User[u.id]
# # => true
#
def self.[](id)
- new(id: id).load! if id && exists?(id)
+ new(:id => id).load! if id && exists?(id)
end
# Retrieve a set of models given an array of IDs.
#
# Example:
@@ -726,11 +734,11 @@
#
# class User < Ohm::Model
# unique :email
# end
#
- # u = User.create(email: "foo@bar.com")
+ # u = User.create(:email => "foo@bar.com")
# u == User.with(:email, "foo@bar.com")
# # => true
#
def self.with(att, val)
id = key[:uniques][att].hget(val)
@@ -760,21 +768,21 @@
# def tag
# ["ruby", "python"]
# end
# end
#
- # u = User.create(name: "John", status: "pending", email: "foo@me.com")
- # User.find(provider: "me", name: "John", status: "pending").include?(u)
+ # u = User.create(:name => "John", :status => "pending", :email => "foo@me.com")
+ # User.find(:provider => "me", :name => "John", :status => "pending").include?(u)
# # => true
#
- # User.find(tag: "ruby").include?(u)
+ # User.find(:tag => "ruby").include?(u)
# # => true
#
- # User.find(tag: "python").include?(u)
+ # User.find(:tag => "python").include?(u)
# # => true
#
- # User.find(tag: ["ruby", "python"]).include?(u)
+ # User.find(:tag => ["ruby", "python"]).include?(u)
# # => true
#
def self.find(dict)
keys = filters(dict)
@@ -869,11 +877,11 @@
#
# # is the same as
#
# class User < Ohm::Model
# def posts
- # Post.find(user_id: self.id)
+ # Post.find(:user_id => self.id)
# end
# end
#
def self.collection(name, model, reference = to_reference)
define_method name do
@@ -1022,11 +1030,11 @@
#
# class User < Ohm::Model
# attribute :name
# end
#
- # u = User.create(name: "John")
+ # u = User.create(:name => "John")
# u.key.hget(:name)
# # => John
#
# For more details see
# http://github.com/soveran/nest
@@ -1037,11 +1045,11 @@
# Initialize a model using a dictionary of attributes.
#
# Example:
#
- # u = User.new(name: "John")
+ # u = User.new(:name => "John")
#
def initialize(atts = {})
@attributes = {}
@_memo = {}
update_attributes(atts)
@@ -1088,11 +1096,11 @@
# the most recent value of the attribute and not rely on locally
# cached value.
#
# Example:
#
- # User.create(name: "A")
+ # User.create(:name => "A")
#
# Session 1 | Session 2
# --------------|------------------------
# u = User[1] | u = User[1]
# u.name = "B" |
@@ -1158,27 +1166,27 @@
#
# class User < Ohm::Model
# attribute :name
# end
#
- # u = User.create(name: "John")
+ # u = User.create(:name => "John")
# u.to_hash
- # # => { id: "1" }
+ # # => { :id => "1" }
#
# In order to add additional attributes, you can override `to_hash`:
#
# class User < Ohm::Model
# attribute :name
#
# def to_hash
- # super.merge(name: name)
+ # super.merge(:name => name)
# end
# end
#
- # u = User.create(name: "John")
+ # u = User.create(:name => "John")
# u.to_hash
- # # => { id: "1", name: "John" }
+ # # => { :id => "1", :name => "John" }
#
def to_hash
attrs = {}
attrs[:id] = id unless new?
attrs[:errors] = errors if errors.any?
@@ -1200,14 +1208,14 @@
# def validate
# assert_present :name
# end
# end
#
- # User.new(name: nil).save
+ # User.new(:name => nil).save
# # => nil
#
- # u = User.new(name: "John").save
+ # u = User.new(:name => "John").save
# u.kind_of?(User)
# # => true
#
def save(&block)
return if not valid?
@@ -1215,38 +1223,46 @@
end
# Saves the model without checking for validity. Refer to
# `Model#save` for more details.
def save!
- transaction do |t|
+ t = __save__
+ yield t if block_given?
+ t.commit(db)
+
+ return self
+ end
+
+ def __save__
+ Transaction.new do |t|
t.watch(*_unique_keys)
t.watch(key) if not new?
t.before do
_initialize_id if new?
end
- t.read do |store|
+ existing = nil
+ uniques = nil
+ indices = nil
+
+ t.read do
_verify_uniques
- store.existing = key.hgetall
- store.uniques = _read_index_type(:uniques)
- store.indices = _read_index_type(:indices)
+ existing = key.hgetall
+ uniques = _read_index_type(:uniques)
+ indices = _read_index_type(:indices)
end
- t.write do |store|
+ t.write do
model.key[:all].sadd(id)
- _delete_uniques(store.existing)
- _delete_indices(store.existing)
+ _delete_uniques(existing)
+ _delete_indices(existing)
_save
- _save_indices(store.indices)
- _save_uniques(store.uniques)
+ _save_indices(indices)
+ _save_uniques(uniques)
end
-
- yield t if block_given?
end
-
- return self
end
# Delete the model, including all the following keys:
#
# - <Model>:<id>
@@ -1256,16 +1272,16 @@
# If the model has uniques or indices, they're also cleaned up.
#
def delete
transaction do |t|
t.read do |store|
- store.existing = key.hgetall
+ store[:existing] = key.hgetall
end
t.write do |store|
- _delete_uniques(store.existing)
- _delete_indices(store.existing)
+ _delete_uniques(store[:existing])
+ _delete_indices(store[:existing])
model.collections.each { |e| key[e].del }
model.key[:all].srem(id)
key[:counters].del
key.del
end
@@ -1276,16 +1292,16 @@
# Update the model attributes and call save.
#
# Example:
#
- # User[1].update(name: "John")
+ # User[1].update(:name => "John")
#
# # It's the same as:
#
# u = User[1]
- # u.update_attributes(name: "John")
+ # u.update_attributes(:name => "John")
# u.save
#
def update(attributes)
update_attributes(attributes)
save
@@ -1374,11 +1390,11 @@
end
def _save
catch :empty do
key.del
- key.hmset(*_skip_empty(attributes).flatten)
+ key.hmset(*_skip_empty(attributes).to_a.flatten)
end
end
def _verify_uniques
if att = _detect_duplicate
@@ -1451,13 +1467,15 @@
def run(script, options)
keys = options[:keys]
argv = options[:argv]
+ params = keys + argv
+
begin
- redis.evalsha(sha(script), keys.size, *keys, *argv)
+ redis.evalsha(sha(script), keys.size, *params)
rescue RuntimeError
- redis.eval(script, keys.size, *keys, *argv)
+ redis.eval(script, keys.size, *params)
end
end
private
def read(file)