├── .gitignore ├── .rspec ├── .rubocop.yml ├── .rubocop_todo.yml ├── .travis.yml ├── CHANGELOG.md ├── Gemfile ├── Guardfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── lib ├── rom-redis.rb └── rom │ ├── redis.rb │ └── redis │ ├── dataset.rb │ ├── gateway.rb │ ├── relation.rb │ └── version.rb ├── log └── .gitkeep ├── rakelib └── rubocop.rake ├── rom-redis.gemspec ├── spec ├── integration │ └── adapter_spec.rb ├── shared │ └── container.rb ├── spec_helper.rb ├── support │ └── user.rb └── unit │ ├── dataset_spec.rb │ ├── gateway_spec.rb │ └── relation_spec.rb └── stdout /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | *.bundle 11 | *.so 12 | *.o 13 | *.a 14 | mkmf.log 15 | log/*.log 16 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --order random 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | # Generated by `rubocop --auto-gen-config` 2 | inherit_from: .rubocop_todo.yml 3 | 4 | # Exclude temporary files 5 | AllCops: 6 | Exclude: 7 | - tmp/**/* 8 | 9 | # No need to handle LoadError in rake 10 | Lint/HandleExceptions: 11 | Exclude: 12 | - rakelib/*.rake 13 | 14 | # Documentation checked by Inch CI 15 | Style/Documentation: 16 | Enabled: false 17 | 18 | # Don't introduce semantic fail/raise distinction 19 | Style/SignalException: 20 | EnforcedStyle: only_raise 21 | 22 | # Allow rom-redis 23 | Style/FileName: 24 | Enabled: false 25 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by `rubocop --auto-gen-config` 2 | # on 2015-02-09 17:20:08 +0100 using RuboCop version 0.29.0. 3 | # The point is for the user to remove these configuration records 4 | # one by one as the offenses are removed from the code base. 5 | # Note that changes in the inspected code, or installation of new 6 | # versions of RuboCop, may require this file to be generated again. 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | sudo: false 3 | cache: bundler 4 | bundler_args: --without tools 5 | services: 6 | - redis-server 7 | script: "bundle exec rake spec" 8 | after_success: 9 | - '[ -d coverage ] && bundle exec codeclimate-test-reporter' 10 | rvm: 11 | - 2.4 12 | - 2.5 13 | - 2.6 14 | - jruby-9.2.7.0 15 | env: 16 | global: 17 | - CODECLIMATE_REPO_TOKEN=621087cd55965563c8deffef2b11eef3298a42dc5795686da994ea3ac86f7b13 18 | - JRUBY_OPTS='--dev -J-Xmx1024M' 19 | - COVERAGE='true' 20 | matrix: 21 | allow_failures: 22 | - rvm: ruby-head 23 | - rvm: jruby-head 24 | notifications: 25 | webhooks: 26 | urls: 27 | - https://webhooks.gitter.im/e/39e1225f489f38b0bd09 28 | on_success: change 29 | on_failure: always 30 | on_start: false 31 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## v0.0.1 to-be-released 2 | 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | group :test do 6 | gem 'rom', github: 'rom-rb/rom', branch: 'master' 7 | gem 'rspec', '~> 3.1' 8 | gem 'codeclimate-test-reporter', require: false 9 | end 10 | 11 | group :tools do 12 | gem 'guard' 13 | gem 'guard-rspec' 14 | gem 'guard-rubocop' 15 | gem 'rubocop', '~> 0.28' 16 | end 17 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | group :red_green_refactor, halt_on_fail: true do 2 | guard :rspec, cmd: 'rspec', all_on_start: true do 3 | # run all specs if Gemfile.lock is modified 4 | watch('Gemfile.lock') { 'spec' } 5 | 6 | # run all specs if any library code is modified 7 | watch(%r{\Alib/.+\.rb\z}) { 'spec' } 8 | 9 | # run all specs if supporting files are modified 10 | watch('spec/spec_helper.rb') { 'spec' } 11 | watch(%r{\Aspec/(?:lib|support|shared)/.+\.rb\z}) { 'spec' } 12 | 13 | # run a spec if it is modified 14 | watch(%r{\Aspec/(?:unit|integration)/.+_spec\.rb\z}) 15 | 16 | notification :tmux, display_message: true if ENV.key?('TMUX') 17 | end 18 | 19 | guard :rubocop do 20 | # run rubocop on modified file 21 | watch(%r{\Alib/.+\.rb\z}) 22 | watch(%r{\Aspec/.+\.rb\z}) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Ruby Object Mapper 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. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [gem]: https://rubygems.org/gems/rom-redis 2 | [travis]: https://travis-ci.org/rom-rb/rom-redis 3 | [gemnasium]: https://gemnasium.com/rom-rb/rom-redis 4 | [codeclimate]: https://codeclimate.com/github/rom-rb/rom-redis 5 | [inchpages]: http://inch-ci.org/github/rom-rb/rom-redis 6 | 7 | # ROM::Redis 8 | 9 | [![Gem Version](https://badge.fury.io/rb/rom-redis.svg)][gem] 10 | [![Build Status](https://travis-ci.org/rom-rb/rom-redis.svg?branch=master)][travis] 11 | [![Dependency Status](https://gemnasium.com/rom-rb/rom-redis.png)][gemnasium] 12 | [![Code Climate](https://codeclimate.com/github/rom-rb/rom-redis/badges/gpa.svg)][codeclimate] 13 | [![Test Coverage](https://codeclimate.com/github/rom-rb/rom-redis/badges/coverage.svg)][codeclimate] 14 | [![Inline docs](http://inch-ci.org/github/rom-rb/rom-redis.svg?branch=master)][inchpages] 15 | 16 | Redis suport for [Ruby Object Mapper](https://github.com/rom-rb/rom). 17 | 18 | ## License 19 | 20 | See `LICENSE` file. 21 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require 'rspec/core/rake_task' 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | task default: [:ci] 6 | 7 | desc 'Run CI tasks' 8 | task ci: [:spec] 9 | -------------------------------------------------------------------------------- /lib/rom-redis.rb: -------------------------------------------------------------------------------- 1 | require 'rom/redis' 2 | -------------------------------------------------------------------------------- /lib/rom/redis.rb: -------------------------------------------------------------------------------- 1 | require 'rom' 2 | require 'rom/redis/version' 3 | require 'rom/redis/relation' 4 | require 'rom/redis/gateway' 5 | 6 | ROM.register_adapter(:redis, ROM::Redis) 7 | -------------------------------------------------------------------------------- /lib/rom/redis/dataset.rb: -------------------------------------------------------------------------------- 1 | module ROM 2 | module Redis 3 | class Dataset 4 | attr_reader :connection, :commands 5 | 6 | def initialize(connection, commands = []) 7 | @connection = connection 8 | @commands = commands 9 | end 10 | 11 | def to_a 12 | view 13 | end 14 | 15 | def each(&block) 16 | view.each(&block) 17 | end 18 | 19 | def map(&block) 20 | view.map(&block) 21 | end 22 | 23 | def method_missing(command, *args) 24 | self.class.new(connection, commands.clone.push([command, args])) 25 | end 26 | 27 | private 28 | 29 | def view 30 | commands.map do |command, args| 31 | connection.send(command, *args) 32 | end 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/rom/redis/gateway.rb: -------------------------------------------------------------------------------- 1 | require 'redis' 2 | require 'redis/namespace' 3 | 4 | require 'rom/gateway' 5 | require 'rom/redis/dataset' 6 | 7 | module ROM 8 | module Redis 9 | class Gateway < ROM::Gateway 10 | adapter :redis 11 | 12 | attr_reader :datasets 13 | 14 | def initialize(options = {}) 15 | @connection = ::Redis.new(options) 16 | @datasets = {} 17 | end 18 | 19 | def [](name) 20 | datasets.fetch(name.to_s) 21 | end 22 | 23 | def dataset(name) 24 | datasets[name.to_s] = Dataset.new(namespace(name)) 25 | end 26 | 27 | def dataset?(name) 28 | datasets.key?(name.to_s) 29 | end 30 | 31 | private 32 | 33 | def namespace(name) 34 | ::Redis::Namespace.new(name.to_s, redis: @connection) 35 | end 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/rom/redis/relation.rb: -------------------------------------------------------------------------------- 1 | require 'redis/namespace' 2 | require 'rom/relation' 3 | 4 | module ROM 5 | module Redis 6 | class Relation < ROM::Relation 7 | adapter :redis 8 | 9 | forward(*::Redis::Namespace::COMMANDS.keys.map(&:to_sym)) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/rom/redis/version.rb: -------------------------------------------------------------------------------- 1 | module ROM 2 | module Redis 3 | VERSION = '0.2.2'.freeze 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /log/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rom-rb/rom-redis/97e276927fe6f1eae4f1336d2899760a63624a24/log/.gitkeep -------------------------------------------------------------------------------- /rakelib/rubocop.rake: -------------------------------------------------------------------------------- 1 | begin 2 | require 'rubocop/rake_task' 3 | 4 | Rake::Task[:default].enhance [:rubocop] 5 | 6 | RuboCop::RakeTask.new do |task| 7 | task.options << '--display-cop-names' 8 | end 9 | 10 | namespace :rubocop do 11 | desc 'Generate a configuration file acting as a TODO list.' 12 | task :auto_gen_config do 13 | exec 'bundle exec rubocop --auto-gen-config' 14 | end 15 | end 16 | 17 | rescue LoadError 18 | end 19 | -------------------------------------------------------------------------------- /rom-redis.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'rom/redis/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = 'rom-redis' 8 | spec.version = ROM::Redis::VERSION.dup 9 | spec.authors = ['Piotr Solnica'] 10 | spec.email = ['piotr.solnica@gmail.com'] 11 | spec.summary = 'Redis support for ROM' 12 | spec.description = spec.summary 13 | spec.homepage = 'http://rom-rb.org' 14 | spec.license = 'MIT' 15 | 16 | spec.files = `git ls-files -z`.split("\x0") 17 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 18 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 19 | spec.require_paths = ['lib'] 20 | 21 | spec.add_runtime_dependency 'redis', '~> 4.0' 22 | spec.add_runtime_dependency 'redis-namespace', '~> 1.6.0' 23 | spec.add_runtime_dependency 'rom', '~> 5.0' 24 | spec.add_runtime_dependency 'inflecto' 25 | 26 | spec.add_development_dependency 'bundler' 27 | spec.add_development_dependency 'rake', '~> 10.0' 28 | end 29 | -------------------------------------------------------------------------------- /spec/integration/adapter_spec.rb: -------------------------------------------------------------------------------- 1 | describe 'Adapter' do 2 | include_context 'container' 3 | 4 | before do 5 | configuration.relation(:users) do 6 | adapter :redis 7 | 8 | def by_id(id) 9 | hgetall(id) 10 | end 11 | end 12 | 13 | configuration.mappers do 14 | define(:users) do 15 | model User 16 | end 17 | end 18 | end 19 | 20 | it 'works' do 21 | rom.relations.users 22 | .hset(1, 'name', 'john doe') 23 | .hset(2, 'name', 'john snow') 24 | .to_a 25 | 26 | user = rom.relations[:users].by_id(1).map_with(:users).to_a.first 27 | 28 | expect(user).to be_a(User) 29 | expect(user.name).to eq('john doe') 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/shared/container.rb: -------------------------------------------------------------------------------- 1 | RSpec.shared_context 'container' do 2 | let(:container) { ROM.container(configuration) } 3 | let!(:configuration) { ROM::Configuration.new(:redis) } 4 | let(:gateway) { configuration.gateways[:default] } 5 | let(:rom) { container } 6 | end 7 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | if RUBY_ENGINE == 'ruby' && RUBY_VERSION >= '2.4.0' && ENV['CI'] == 'true' 4 | require 'simplecov' 5 | SimpleCov.start do 6 | add_filter '/spec/' 7 | end 8 | end 9 | 10 | require 'rom-redis' 11 | 12 | root = Pathname(__FILE__).dirname 13 | 14 | Dir[root.join('shared/*.rb').to_s].each { |f| require f } 15 | Dir[root.join('support/*.rb').to_s].each { |f| require f } 16 | 17 | RSpec.configure do |config| 18 | config.before do 19 | Redis.current.flushall 20 | end 21 | 22 | config.after do 23 | Redis.current.flushall 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/support/user.rb: -------------------------------------------------------------------------------- 1 | class User 2 | attr_reader :name 3 | 4 | def initialize(attrs) 5 | @name = attrs.fetch('name', nil) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/unit/dataset_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rom/lint/spec' 2 | 3 | describe ROM::Redis::Dataset do 4 | let(:conn) { ::Redis::Namespace.new(:test) } 5 | let(:dataset) { ROM::Redis::Dataset.new(conn).set(:a, 1).set(:b, 2).get(:a) } 6 | let(:data) { %w(OK OK 1) } 7 | 8 | it_behaves_like 'a rom enumerable dataset' 9 | end 10 | -------------------------------------------------------------------------------- /spec/unit/gateway_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rom/lint/spec' 2 | 3 | describe ROM::Redis::Gateway do 4 | let(:gateway) { ROM::Redis::Gateway } 5 | let(:uri) { Hash[] } 6 | let(:identifier) { :redis } 7 | 8 | it_behaves_like 'a rom gateway' 9 | end 10 | -------------------------------------------------------------------------------- /spec/unit/relation_spec.rb: -------------------------------------------------------------------------------- 1 | describe ROM::Redis::Relation do 2 | include_context 'container' 3 | 4 | subject { rom.relations[:users] } 5 | 6 | before do 7 | configuration.relation(:users) 8 | end 9 | 10 | it '#set' do 11 | expect(subject.set(:a, 1).to_a).to eq(['OK']) 12 | end 13 | 14 | it '#hset' do 15 | expect(subject.hset(:who, :is, :john).to_a).to eq([true]) 16 | end 17 | 18 | it '#hget' do 19 | subject.hset(:users, :john, :doe).to_a 20 | 21 | expect(subject.hgetall(:users).to_a).to eq([{ 'john' => 'doe' }]) 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /stdout: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rom-rb/rom-redis/97e276927fe6f1eae4f1336d2899760a63624a24/stdout --------------------------------------------------------------------------------