redis-record 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/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in redis_record.gemspec
4
+ gemspec
5
+
6
+ gem 'guard'
7
+ gem 'rb-inotify' if RUBY_PLATFORM.downcase.include?("linux")
8
+ gem 'rb-fsevent' if RUBY_PLATFORM.downcase.include?("darwin")
9
+ gem 'guard-bundler'
10
+ gem 'guard-rspec'
11
+ gem 'rspec'
data/Guardfile ADDED
@@ -0,0 +1,14 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
10
+
11
+ guard 'bundler' do
12
+ watch('Gemfile')
13
+ watch(/^.+\.gemspec/)
14
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Subhash Chandra
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # RedisRecord
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'redis_record'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install redis_record
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ require 'redis_record'
@@ -0,0 +1,29 @@
1
+ require 'active_attr'
2
+ require 'active_support'
3
+ require 'redis'
4
+
5
+ class RedisRecord
6
+
7
+ Dir[File.expand_path("../redis_record/**/*.rb", __FILE__)].each {|f| require f}
8
+
9
+ include ActiveAttr::Model
10
+ include DataTypes
11
+ include Base
12
+ include Sorting
13
+ include Filters
14
+
15
+ @@REDIS = nil
16
+
17
+ def self.REDIS
18
+ @@REDIS
19
+ end
20
+ def self.REDIS=(client)
21
+ @@REDIS = client
22
+ end
23
+
24
+ class_attribute :defined_sorts, :defined_filters
25
+ self.defined_sorts = {id: nil}
26
+ self.defined_filters = {}
27
+
28
+ ActiveSupport.run_load_hooks :redis_record, self
29
+ end
@@ -0,0 +1,43 @@
1
+ module RedisRecord::Base
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ extend ActiveSupport::Callbacks
6
+
7
+ define_callbacks :save
8
+ define_callbacks :destroy
9
+ attr_accessor :persisted
10
+ attr_accessor :original_attributes
11
+ end
12
+
13
+ def save
14
+ success = nil
15
+ RedisRecord.REDIS.multi do
16
+ run_callbacks :save do
17
+ success = RedisRecord.REDIS.mapped_hmset(key, attributes)
18
+ end
19
+ end
20
+ self.persisted = (success.value == "OK")
21
+ end
22
+ alias save! save
23
+
24
+ def destroy
25
+ success = nil
26
+ RedisRecord.REDIS.multi do
27
+ run_callbacks :destroy do
28
+ success = RedisRecord.REDIS.del key
29
+ end
30
+ end
31
+ success.value == 1 ? self : nil
32
+ end
33
+ alias destroy! destroy
34
+
35
+ def update_attributes(attrs)
36
+ assign_attributes attrs
37
+ save
38
+ end
39
+
40
+ def key
41
+ self.class.key(id)
42
+ end
43
+ end
@@ -0,0 +1,61 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+
3
+ module RedisRecord::Base
4
+ module ClassMethods
5
+
6
+ def scoped(*args)
7
+ RedisScope.new self, *args
8
+ end
9
+
10
+ delegate :filter, :sort, :min, :max, :limit, :offset, :to => :scoped
11
+ delegate :all, :each, :map, :count, :first, :last, :to => :scoped
12
+
13
+ def create(*args)
14
+ new(*args).save
15
+ end
16
+
17
+ def find(id)
18
+ find_by_key key id
19
+ end
20
+
21
+
22
+ def find_or_initialize_by_id(id)
23
+ find(id) || self.new(:id => id)
24
+ end
25
+
26
+ def create_filter(name, &block)
27
+ self.defined_filters = self.defined_filters.merge name.to_sym => block
28
+ end
29
+
30
+ def sortable(name, &block)
31
+ self.defined_sorts = self.defined_sorts.merge name.to_sym => block
32
+ end
33
+
34
+ def values_for_filter(name)
35
+ RedisRecord.REDIS.zrange filter_key('_Values', name), 0, -1
36
+ end
37
+
38
+ def meta_key(attr)
39
+ ['Meta', model_name, attr].join ':'
40
+ end
41
+
42
+ def filter_key(name, value)
43
+ meta_key "Filter:#{name}:#{value}"
44
+ end
45
+
46
+ def key(id)
47
+ [model_name, id].join ':'
48
+ end
49
+
50
+ private
51
+ def find_by_key(key)
52
+ attributes = RedisRecord.REDIS.mapped_hmget(key, *attribute_names)
53
+ attributes['id'] && self.new(attributes).tap { |r|
54
+ r.persisted = true
55
+ r.original_attributes = attributes
56
+ }
57
+ end
58
+
59
+ end
60
+ end
61
+
@@ -0,0 +1,25 @@
1
+ module RedisRecord::DataTypes
2
+ extend ActiveSupport::Concern
3
+ module ClassMethods
4
+ def create_initializer(type, klass, defaults = {})
5
+ define_singleton_method(type) do | *list, opts |
6
+ unless opts.is_a? Hash
7
+ list << opts
8
+ opts = {}
9
+ end
10
+ opts[:type] ||= klass
11
+
12
+ list.each do |attr|
13
+ attribute attr, defaults.merge(opts)
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ included do
20
+ [ :integer, :string, :date ].each { |klass| create_initializer klass, klass.to_s.classify.constantize }
21
+ create_initializer(:boolean, ActiveAttr::Typecasting::Boolean) # TODO: Ugly hack
22
+ create_initializer(:datetime, DateTime)
23
+ create_initializer(:decimal, BigDecimal)
24
+ end
25
+ end
@@ -0,0 +1,33 @@
1
+ module RedisRecord::Filters
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ set_callback :save, :after, :add_to_filter_lists
6
+ set_callback :save, :before, :remove_from_filter_lists
7
+ set_callback :destroy, :before, :remove_from_filter_lists
8
+ end
9
+
10
+ protected
11
+ def filter_key(name, block)
12
+ value = block ? block.call(self) : self.send(name)
13
+ RedisRecord.REDIS.zincrby self.class.filter_key('_Values', name), 1, value
14
+ self.class.filter_key(name, value)
15
+ end
16
+
17
+ private
18
+ def remove_from_filter_lists
19
+ return unless original_attributes
20
+
21
+ old_dog = self.class.new(original_attributes)
22
+ defined_filters.each do |name, block|
23
+ RedisRecord.REDIS.srem old_dog.filter_key(name, block), id
24
+ end
25
+ end
26
+
27
+ def add_to_filter_lists
28
+ defined_filters.each do |name, block|
29
+ RedisRecord.REDIS.sadd filter_key(name, block), id
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,104 @@
1
+ class RedisScope
2
+ DEFAULT_OPTIONS = {
3
+ offset: 0,
4
+ filters: [],
5
+ sort: :id,
6
+ min: '-inf',
7
+ max: '+inf'
8
+ }
9
+
10
+ def initialize(model, opts = {})
11
+ @model = model
12
+ @options = DEFAULT_OPTIONS.merge opts
13
+ end
14
+
15
+ # Modifiers
16
+ # always returns self
17
+
18
+ def filter(name, value=true)
19
+ raise NameError, ":#{name} isn't in the defined filters" unless @model.defined_filters.include? name
20
+ new_filters = @options[:filters] + [[name, value]]
21
+
22
+ chain_scope filters: new_filters
23
+ end
24
+
25
+ def sort(attr)
26
+ chain_scope sort: attr
27
+ end
28
+
29
+ def min(value)
30
+ chain_scope min: value
31
+ end
32
+
33
+ def max(value)
34
+ chain_scope max: value
35
+ end
36
+
37
+ def limit(n)
38
+ chain_scope limit: n
39
+ end
40
+
41
+ def offset(n)
42
+ chain_scope offset: n
43
+ end
44
+
45
+ # Executors
46
+ def count
47
+ apply_filters
48
+ total_records = RedisRecord.REDIS.zcard temp_key
49
+
50
+ remaining_records = total_records - @options[:offset]
51
+
52
+ if @options[:limit] and @options[:limit] < remaining_records
53
+ @options[:limit]
54
+ else
55
+ remaining_records
56
+ end
57
+ end
58
+
59
+ def all
60
+ ids.map {|id| @model.find id}
61
+ end
62
+ delegate :each, :map, to: :all
63
+ delegate :as_json, to: :all
64
+
65
+ def first
66
+ limit(1).all[0]
67
+ end
68
+
69
+ def last
70
+ offset(@options[:offset] + count - 1).limit(1).all[0]
71
+ end
72
+
73
+ private
74
+ def chain_scope(opts = {})
75
+ self.class.new @model, @options.merge(opts)
76
+ end
77
+
78
+ def ids
79
+ apply_filters
80
+ RedisRecord.REDIS.zrangebyscore temp_key, @options[:min], @options[:max], limit: [@options[:offset], @options[:limit] || -1]
81
+ end
82
+
83
+ def apply_filters
84
+ filter_keys = @options[:filters].map do |name, value|
85
+ if value.is_a? Array
86
+ values = value
87
+ union_key = @model.filter_key "_Union:#{name}", values.join('_')
88
+ value_keys = values.map {|value| @model.filter_key name, value}
89
+ RedisRecord.REDIS.zunionstore union_key, value_keys
90
+ union_key
91
+ else
92
+ @model.filter_key name, value
93
+ end
94
+ end
95
+ key_sets = [@model.meta_key(@options[:sort])] + filter_keys
96
+ weights = [1] + [0] * @options[:filters].count
97
+ RedisRecord.REDIS.zinterstore temp_key, key_sets, weights: weights
98
+ end
99
+
100
+ def temp_key
101
+ @temp_key ||= @model.meta_key("_Temp:Filtered")
102
+ end
103
+
104
+ end
@@ -0,0 +1,30 @@
1
+ module RedisRecord::Sorting
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ set_callback :destroy, :after, :remove_from_sort_lists
6
+ set_callback :save, :after, :add_to_sort_lists
7
+ end
8
+
9
+ protected
10
+ def add_to_sort_lists
11
+ defined_sorts.each do |name, block|
12
+ score = 0
13
+ if block
14
+ if block.respond_to? :call
15
+ score = block.call self
16
+ else
17
+ score = self.send block
18
+ end
19
+ end
20
+ RedisRecord.REDIS.zadd self.class.meta_key(name), score, id
21
+ end
22
+ end
23
+
24
+ def remove_from_sort_lists
25
+ defined_sorts.each do |name, _|
26
+ RedisRecord.REDIS.zrem self.class.meta_key(name), id
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,3 @@
1
+ class RedisRecord
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/redis_record/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Subhash Chandra"]
6
+ gem.email = ["TMaYaD@LoonyB.in"]
7
+ gem.description = %q{Active model interface for redis}
8
+ gem.summary = %q{Active record like interface for redis without adding bloat}
9
+ gem.homepage = "http://github.com/loonybin/redis_record"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "redis-record"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = RedisRecord::VERSION
17
+
18
+ gem.add_runtime_dependency 'active_attr'
19
+ gem.add_runtime_dependency 'activesupport'
20
+ gem.add_runtime_dependency 'redis'
21
+ end
@@ -0,0 +1,26 @@
1
+ class Domain < RedisRecord
2
+ attr_accessible :id
3
+ attr_accessible :hidden, :liked
4
+
5
+ string :id # name
6
+ boolean :hidden, :default => false
7
+ boolean :liked, :default => false
8
+
9
+ create_filter :numbers do |domain|
10
+ !!domain.id.match(/[0-9]/)
11
+ end
12
+ create_filter :hyphenated do |domain|
13
+ !!domain.id.match(/-/)
14
+ end
15
+ create_filter :tld do |domain|
16
+ domain.id.split('.').last
17
+ end
18
+
19
+ create_filter :hidden
20
+ create_filter :liked
21
+
22
+ sortable :length do |domain|
23
+ domain.id.length
24
+ end
25
+
26
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/domain'
3
+
4
+ describe Domain do
5
+ before(:each) do
6
+ (0..4).each { |i| Domain.create id: "#{i}.com", status: 'Pre-release' }
7
+ end
8
+
9
+ it "should return all the records" do
10
+ Domain.count.should eq 5
11
+ Domain.all.map(&:id).should eq %w[0.com 1.com 2.com 3.com 4.com]
12
+ end
13
+
14
+ it "should return only 'limit' number of records" do
15
+ Domain.limit(2).all.map(&:id).should eq %w[0.com 1.com]
16
+ end
17
+
18
+ it "should return only records starting from 'offset'" do
19
+ Domain.offset(3).all.map(&:id).should eq %w[3.com 4.com]
20
+ end
21
+
22
+ it "should return only 'limit' records starting from 'offset'" do
23
+ Domain.offset(2).limit(2).all.map(&:id).should eq %w[2.com 3.com]
24
+
25
+ # in any order
26
+ Domain.limit(2).offset(2).all.map(&:id).should eq %w[2.com 3.com]
27
+ end
28
+
29
+ it "should not return more records than existing" do
30
+ Domain.offset(3).limit(3).all.map(&:id).should eq %w[3.com 4.com]
31
+ end
32
+
33
+ it "should not display hidden records" do
34
+ Domain.first.update_attributes hidden: true
35
+
36
+ Domain.filter(:hidden, false).count.should eq 4
37
+ Domain.filter(:hidden, false).all.map(&:id).should eq %w[1.com 2.com 3.com 4.com]
38
+ end
39
+
40
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/domain'
3
+
4
+ describe Domain do
5
+ context "with filters" do
6
+ before(:each) do
7
+ ('a'..'b').each { |i| Domain.create id: "#{i}.com", status: 'Pre-release' }
8
+ ('5'..'6').each { |i| Domain.create id: "#{i}-.net", status: 'Pre-release' }
9
+ ('a'..'b').each { |i| Domain.create id: "#{i}.org", status: 'Pre-release' }
10
+ end
11
+
12
+ it "shouldn't allow undefined filters" do
13
+ expect{Domain.filter(:blah)}.to raise_error NameError
14
+ end
15
+
16
+ it "should return only records with the given filter applied" do
17
+ Domain.filter(:numbers).all.map(&:id).should eq %w[5-.net 6-.net]
18
+ end
19
+
20
+ it "should return only records matching all the filters" do
21
+ Domain.filter(:numbers).filter(:hyphenated).all.map(&:id).should eq %w[5-.net 6-.net]
22
+ end
23
+
24
+ it "should list out all the available values for a given filter" do
25
+ Domain.values_for_filter(:tld).should eq %w[com net org]
26
+ end
27
+
28
+ it "should return records with the filter matching a custom value" do
29
+ Domain.filter(:tld, 'net').map(&:id).should eq %w[5-.net 6-.net]
30
+ end
31
+
32
+ it "should return records with the filter matching any of the custom values" do
33
+ Domain.filter(:tld, ['net', 'org']).map(&:id).should eq %w[5-.net 6-.net a.org b.org]
34
+ end
35
+
36
+ it "should sort and select records even when filters are applied" do
37
+ (1..4).each {|i| Domain.create id: ('a' * i), status: 'Pre-release'}
38
+ Domain.filter(:numbers, false).sort(:length).min(2).max(4).map(&:id).should eq %w[aa aaa aaaa]
39
+ end
40
+
41
+ it "should allow defining filters on attributes without block" do
42
+ Domain.first.update_attributes hidden: true
43
+
44
+ Domain.filter(:hidden, false).count.should eq 5
45
+ Domain.filter(:hidden, false).all.map(&:id).should eq %w[6-.net a.com a.org b.com b.org]
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/domain'
3
+
4
+ describe Domain do
5
+ context 'with sorting' do
6
+ before(:each) do
7
+ (1..4).each {|i| Domain.create id: ('a' * i), status: 'Pre-release'}
8
+ end
9
+
10
+ it "should sort by given attribute" do
11
+ Domain.sort(:length).map(&:id).should eq %w[a aa aaa aaaa]
12
+ end
13
+
14
+ it "should filter for min and max on the sort" do
15
+ Domain.sort(:length).min(3).map(&:id).should eq %w[aaa aaaa]
16
+ Domain.sort(:length).max(4).map(&:id).should eq %w[a aa aaa aaaa]
17
+ Domain.sort(:length).min(2).max(4).map(&:id).should eq %w[aa aaa aaaa]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/domain'
3
+
4
+ describe Domain do
5
+ before(:each) do
6
+ (0..4).each { |i| Domain.create id: "#{i}.com" }
7
+ end
8
+
9
+ it "should return all the records" do
10
+ Domain.count.should eq 5
11
+ Domain.all.map(&:id).should eq %w[0.com 1.com 2.com 3.com 4.com]
12
+ end
13
+
14
+ it "should return only 'limit' number of records" do
15
+ Domain.limit(2).all.map(&:id).should eq %w[0.com 1.com]
16
+ end
17
+
18
+ it "should return only records starting from 'offset'" do
19
+ Domain.offset(3).all.map(&:id).should eq %w[3.com 4.com]
20
+ end
21
+
22
+ it "should return only 'limit' records starting from 'offset'" do
23
+ Domain.offset(2).limit(2).all.map(&:id).should eq %w[2.com 3.com]
24
+
25
+ # in any order
26
+ Domain.limit(2).offset(2).all.map(&:id).should eq %w[2.com 3.com]
27
+ end
28
+
29
+ it "should not return more records than existing" do
30
+ Domain.offset(3).limit(3).all.map(&:id).should eq %w[3.com 4.com]
31
+ end
32
+
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'redis_record'
2
+ RedisRecord.REDIS ||= Redis.new db: 2
3
+
4
+ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
5
+
6
+ RSpec.configure do |config|
7
+ config.treat_symbols_as_metadata_keys_with_true_values = true
8
+ config.run_all_when_everything_filtered = true
9
+ config.filter_run :focus
10
+
11
+ # Run specs in random order to surface order dependencies. If you find an
12
+ # order dependency and want to debug it, you can fix the order by providing
13
+ # the seed, which is printed after each run.
14
+ # --seed 1234
15
+ config.order = 'random'
16
+ end
@@ -0,0 +1,5 @@
1
+ RSpec.configure do |c|
2
+ c.before(:each) do |example|
3
+ RedisRecord.REDIS.flushdb
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redis-record
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Subhash Chandra
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: active_attr
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: redis
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: Active model interface for redis
63
+ email:
64
+ - TMaYaD@LoonyB.in
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - .rspec
71
+ - Gemfile
72
+ - Guardfile
73
+ - LICENSE
74
+ - README.md
75
+ - Rakefile
76
+ - lib/redis-record.rb
77
+ - lib/redis_record.rb
78
+ - lib/redis_record/base.rb
79
+ - lib/redis_record/base/class_methods.rb
80
+ - lib/redis_record/data_types.rb
81
+ - lib/redis_record/filters.rb
82
+ - lib/redis_record/redis_scope.rb
83
+ - lib/redis_record/sorting.rb
84
+ - lib/redis_record/version.rb
85
+ - redis-record.gemspec
86
+ - spec/fixtures/domain.rb
87
+ - spec/lib/domain_spec.rb
88
+ - spec/lib/redis_record/filters_spec.rb
89
+ - spec/lib/redis_record/sorting_spec.rb
90
+ - spec/lib/redis_record_spec.rb
91
+ - spec/spec_helper.rb
92
+ - spec/support/redis.rb
93
+ homepage: http://github.com/loonybin/redis_record
94
+ licenses: []
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 1.8.23
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: Active record like interface for redis without adding bloat
117
+ test_files:
118
+ - spec/fixtures/domain.rb
119
+ - spec/lib/domain_spec.rb
120
+ - spec/lib/redis_record/filters_spec.rb
121
+ - spec/lib/redis_record/sorting_spec.rb
122
+ - spec/lib/redis_record_spec.rb
123
+ - spec/spec_helper.rb
124
+ - spec/support/redis.rb