Skip to content

Commit

Permalink
Adding initial documentation, and some initial spikes to speed up rec…
Browse files Browse the repository at this point in the history
…ords_for
  • Loading branch information
whoahbot committed May 22, 2009
1 parent 487e337 commit 0361ca9
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 3 deletions.
6 changes: 5 additions & 1 deletion README.textile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ h1. DM-Redis

This is an experimental datamapper adapter for the <a href="http://code.google.com/p/redis/wiki/README">Redis</a> key-value database.

Please be aware that this is very alpha quality software! It is not recommended for production use. Oh, and it will be _slow_ for large sets of data until I'm finished refactoring, which sort of defeats the purpose, wouldn't you say?
Please be aware that this is very alpha quality software! It is not recommended for production use.

h1. TODO

Currently, the records_for(query) method returns a set of hashes of all of the

h1. Install

Expand Down
92 changes: 90 additions & 2 deletions lib/redis_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ module Adapters
Extlib::Inflection.word 'redis'

class RedisAdapter < AbstractAdapter
##
# Used by DataMapper to put records into the redis data-store: "INSERT" in SQL-speak.
# It takes an array of the resources (model instances) to be saved. Resources
# each have a key that can be used to quickly look them up later without
# searching.
#
# @param [Enumerable(Resource)] resources
# The set of resources (model instances)
#
# @api semipublic
def create(resources)
resources.each do |resource|
initialize_identity_field(resource, @redis.incr("#{resource.model}:#{redis_key_for(resource.model)}:serial"))
Expand All @@ -14,6 +24,18 @@ def create(resources)
update_attributes(resources)
end

##
# Looks up one record or a collection of records from the data-store:
# "SELECT" in SQL.
#
# @param [Query] query
# The query to be used to seach for the resources
#
# @return [Array]
# An Array of Hashes containing the key-value pairs for
# each record
#
# @api semipublic
def read(query)
records = records_for(query).each do |record|
query.fields.each do |property|
Expand All @@ -24,11 +46,34 @@ def read(query)
query.filter_records(records)
end

##
# Used by DataMapper to update the attributes on existing records in the redis
# data-store: "UPDATE" in SQL-speak. It takes a hash of the attributes
# to update with, as well as a collection object that specifies which resources
# should be updated.
#
# @param [Hash] attributes
# A set of key-value pairs of the attributes to update the resources with.
# @param [DataMapper::Collection] collection
# The query that should be used to find the resource(s) to update.
#
# @api semipublic
def update(attributes, collection)
attributes = attributes_as_fields(attributes)
read(collection.query).each { |r| r.update(attributes) }
end

##
# Destroys all the records matching the given query. "DELETE" in SQL.
#
# @param [DataMapper::Collection] collection
# The query used to locate the resources to be deleted.
#
# @return [Array]
# An Array of Hashes containing the key-value pairs for
# each record
#
# @api semipublic
def delete(collection)
collection.query.filter_records(records_for(collection.query)).each do |record|
collection.query.model.properties.each do |p|
Expand All @@ -40,10 +85,28 @@ def delete(collection)

private

##
# Creates a string representation for the keys in a given model
#
# @param [DataMapper::Model] model
# The query used to locate the resources to be deleted.
#
# @return [Array]
# An Array of Hashes containing the key-value pairs for
# each record
#
# @api private
def redis_key_for(model)
model.key.collect {|k| k.name}.join(":")
end

##
# Saves each key value pair to the redis data store
#
# @param [Array] resources
# An array of resources to save
#
# @api private
def update_attributes(resources)
resources.each do |resource|
resource.attributes.each do |property, value|
Expand All @@ -52,12 +115,37 @@ def update_attributes(resources)
end
end

##
# Retrieves all of the records for a particular model
#
# @param [DataMapper::Query] query
# The query used to locate the resources
#
# @return [Array]
# An array of hashes of all of the records for a particular model
#
# @api private
def records_for(query)
@redis.set_members("#{query.model}:#{redis_key_for(query.model)}:all").inject(Set.new) do |s, val|
s << {"#{redis_key_for(query.model)}" => val.to_i}
set = @redis.set_members("#{query.model}:#{redis_key_for(query.model)}:all")
arr = Array.new(set.size)
set.each_with_index do |val, i|
arr[i] = {"#{redis_key_for(query.model)}" => val.to_i}
end

arr
end

##
# Make a new instance of the adapter. The @redis ivar is the 'data-store'
# for this adapter.
#
# @param [String, Symbol] name
# The name of the Repository using this adapter.
# @param [String, Hash] uri_or_options
# The connection uri string, or a hash of options to set up
# the adapter
#
# @api semipublic
def initialize(name, uri_or_options)
super
@redis = Redis.new(@options)
Expand Down

0 comments on commit 0361ca9

Please sign in to comment.