Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements #5

Merged
merged 6 commits into from
May 25, 2017
Merged
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
6 changes: 6 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ Style/StructInheritance:

Metrics/ModuleLength:
Enabled: false

Metrics/BlockLength:
Enabled: false

Security/YAMLLoad:
Enabled: false
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruby-2.2.2
2.4.1
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ services:
- redis-server
language: ruby
rvm:
- 2.2.0
- 2.4.1
- jruby-1.7.18
- rbx-2.5.0
- 2.2.4
- 2.3.0
- 2.4.0
- jruby-9.1.9.0
env:
global:
secure: LrTz0Pq2ibNZuKDhdzcrvEUSNxUpPopEq9aJeCxy3UpV0v4vpHBtWV0S6zofvf98g/RkZ6cGI1u+0H578dHgE6pWTo+iR8LAwqPKofrFIWRkeo+M77Vs5swahb3mQyPOcig1hfVWDm25MsojePYm70eBIcBU55NWImtdePXfiU0=
4 changes: 3 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'rake'
gem 'rspec'

platform :mri do
gem 'codeclimate-test-reporter', require: nil
gem 'cane'
gem 'codeclimate-test-reporter', require: nil
gem 'rubocop', require: false
gem 'simplecov', require: false
end
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

ActiveModel + Redis with the aim to mimic ActiveRecord where possible.

## Requirements

Modis supports CRuby 2.2.2+ and jRuby 9k+

## Installation

Add this line to your application's Gemfile:
Expand Down
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require "rake"
require "bundler/gem_tasks"
require "rspec/core/rake_task"
Expand Down
8 changes: 5 additions & 3 deletions benchmark/bench.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'stackprof'
require 'benchmark'

Expand Down Expand Up @@ -40,14 +42,14 @@ def _run

private

def with_profile(name, &blk)
def with_profile(name)
if ENV['PROFILE']
mode = :wall
out = "tmp/stackprof-#{mode}-#{name}.dump"
@profiles << out
StackProf.run(mode: mode, out: out, &blk)
StackProf.run(mode: mode, out: out, &Proc.new)
else
blk.call
yield
end
end

Expand Down
4 changes: 3 additions & 1 deletion benchmark/find.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

$LOAD_PATH.unshift('benchmark')
require 'bench'

Expand All @@ -16,7 +18,7 @@ class User
attribute :flag, :boolean
attribute :array, :array
attribute :hash, :hash
attribute :string_or_hash, [:string, :hash]
attribute :string_or_hash, %i[string hash]

index :name
end
Expand Down
4 changes: 3 additions & 1 deletion benchmark/persistence.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

$LOAD_PATH.unshift('benchmark')
require 'bench'

Expand All @@ -16,7 +18,7 @@ class User
attribute :flag, :boolean
attribute :array, :array
attribute :hash, :hash
attribute :string_or_hash, [:string, :hash]
attribute :string_or_hash, %i[string hash]

index :name
end
Expand Down
3 changes: 2 additions & 1 deletion lib/modis.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# frozen_string_literal: true

require 'redis'
require 'connection_pool'
require 'active_model'
require 'active_support/all'
require 'yaml'
require 'msgpack'

require 'modis/version'
Expand Down
2 changes: 2 additions & 0 deletions lib/modis/attribute.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Modis
module Attribute
TYPES = { string: [String],
Expand Down
2 changes: 2 additions & 0 deletions lib/modis/configuration.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Modis
def self.configure
yield config
Expand Down
2 changes: 2 additions & 0 deletions lib/modis/errors.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Modis
class ModisError < StandardError; end
class RecordNotSaved < ModisError; end
Expand Down
4 changes: 3 additions & 1 deletion lib/modis/finder.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Modis
module Finder
def self.included(base)
Expand Down Expand Up @@ -61,7 +63,7 @@ def records_to_models(records)

def model_for(attributes)
cls = model_class(attributes)
return unless self == cls || cls < self
return unless cls == self || cls < self
cls.new(attributes, new_record: false)
end

Expand Down
2 changes: 2 additions & 0 deletions lib/modis/index.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Modis
module Index
def self.included(base)
Expand Down
4 changes: 3 additions & 1 deletion lib/modis/model.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Modis
module Model
def self.included(base)
Expand Down Expand Up @@ -42,6 +44,6 @@ def initialize(record = nil, options = {})
def ==(other)
super || other.instance_of?(self.class) && id.present? && other.id == id
end
alias_method :eql?, :==
alias eql? ==
end
end
30 changes: 10 additions & 20 deletions lib/modis/persistence.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# frozen_string_literal: true

module Modis
module Persistence
def self.included(base)
base.extend ClassMethods
base.instance_eval do
class << self
attr_reader :sti_child
alias_method :sti_child?, :sti_child
alias sti_child? sti_child
end
end
end
Expand Down Expand Up @@ -71,28 +73,15 @@ def create!(attrs)
model
end

YAML_MARKER = '---'.freeze
def deserialize(record)
values = record.values
values = MessagePack.unpack(msgpack_array_header(values.size) + values.join)
keys = record.keys
values.each_with_index { |v, i| record[keys[i]] = v }
record
rescue MessagePack::MalformedFormatError
found_yaml = false

record.each do |k, v|
if v.start_with?(YAML_MARKER)
found_yaml = true
record[k] = YAML.load(v)
else
record[k] = MessagePack.unpack(v)
end
end

if found_yaml
id = record['id']
STDERR.puts "#{self}(id: #{id}) contains attributes serialized as YAML. As of Modis 1.4.0, YAML is no longer used as the serialization format. To improve performance loading this record, you can force the record to new serialization format (MessagePack) with: #{self}.find(#{id}).save!(yaml_sucks: true)"
record[k] = MessagePack.unpack(v)
end

record
Expand Down Expand Up @@ -177,7 +166,7 @@ def coerce_for_persistence(value)

def create_or_update(args = {})
validate(args)
future = persist(args[:yaml_sucks])
future = persist

if future && (future == :unchanged || future.value == 'OK')
reset_changes
Expand All @@ -194,7 +183,8 @@ def validate(args)
raise Modis::RecordInvalid, errors.full_messages.join(', ')
end

def persist(persist_all)
# rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
def persist
future = nil
set_id if new_record?
callback = new_record? ? :create : :update
Expand All @@ -203,7 +193,7 @@ def persist(persist_all)
run_callbacks :save do
run_callbacks callback do
redis.pipelined do
attrs = coerced_attributes(persist_all)
attrs = coerced_attributes
key = self.class.sti_child? ? self.class.sti_base_key_for(id) : self.class.key_for(id)
future = attrs.any? ? redis.hmset(key, attrs) : :unchanged

Expand All @@ -222,10 +212,10 @@ def persist(persist_all)
future
end

def coerced_attributes(persist_all)
def coerced_attributes
attrs = []

if new_record? || persist_all
if new_record?
attributes.each do |k, v|
if (self.class.attributes[k][:default] || nil) != v
attrs << k << coerce_for_persistence(v)
Expand Down
2 changes: 2 additions & 0 deletions lib/modis/transaction.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Modis
module Transaction
def self.included(base)
Expand Down
2 changes: 2 additions & 0 deletions lib/modis/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Modis
VERSION = '1.4.1'
end
6 changes: 4 additions & 2 deletions lib/tasks/quality.rake
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

begin
if ENV['TRAVIS']
namespace :spec do
Expand All @@ -16,7 +18,7 @@ begin
end

namespace :spec do
task cane: %w(spec cane_quality)
task cane: %w[spec cane_quality]
end
end
rescue LoadError
Expand All @@ -37,5 +39,5 @@ rescue LoadError
end

namespace :spec do
task quality: %w(cane rubocop)
task quality: %w[cane rubocop]
end
4 changes: 2 additions & 2 deletions modis.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Gem::Specification.new do |gem|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.require_paths = ["lib"]

gem.add_runtime_dependency 'activemodel', '>= 3.0', '< 5.0'
gem.add_runtime_dependency 'activesupport', '>= 3.0', '< 5.0'
gem.add_runtime_dependency 'activemodel', '>= 3.0'
gem.add_runtime_dependency 'activesupport', '>= 3.0'
gem.add_runtime_dependency 'redis', '>= 3.0'
gem.add_runtime_dependency 'hiredis', '>= 0.5'
gem.add_runtime_dependency 'connection_pool', '>= 2'
Expand Down
4 changes: 3 additions & 1 deletion spec/attribute_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'spec_helper'

module AttributeSpec
Expand All @@ -11,7 +13,7 @@ class MockModel
attribute :flag, :boolean
attribute :array, :array
attribute :hash, :hash
attribute :string_or_hash, [:string, :hash]
attribute :string_or_hash, %i[string hash]
end
end

Expand Down
2 changes: 2 additions & 0 deletions spec/errors_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'spec_helper'

module ErrorsSpec
Expand Down
6 changes: 4 additions & 2 deletions spec/finder_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'spec_helper'

module FindersSpec
Expand Down Expand Up @@ -142,10 +144,10 @@ class Worker < Producer

it 'inherits attributes from the parent' do
producer = FindersSpec::Producer.create!(name: 'Kyle', consumed: true)
expect(producer.attributes.keys.sort).to eq(%w(age child_default id name parent_default type))
expect(producer.attributes.keys.sort).to eq(%w[age child_default id name parent_default type])

worker = FindersSpec::Worker.create!(name: 'Max')
expect(worker.attributes.keys.sort).to eq(%w(age child_default id name parent_default type))
expect(worker.attributes.keys.sort).to eq(%w[age child_default id name parent_default type])
end

it 'inherits default attribute values from the parent' do
Expand Down
2 changes: 2 additions & 0 deletions spec/index_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'spec_helper'

module IndexSpec
Expand Down
24 changes: 2 additions & 22 deletions spec/persistence_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'spec_helper'

module PersistenceSpec
Expand Down Expand Up @@ -294,26 +296,4 @@ def test_before_save
expect(model.update_attributes(name: nil)).to be false
end
end

describe 'YAML backward compatability' do
it 'loads a YAML serialized value' do
Modis.with_connection do |redis|
model.save!
key = model.class.key_for(model.id)
record = redis.hgetall(key)
record['age'] = YAML.dump(30)
redis.hmset(key, *record.to_a)
record = redis.hgetall(key)

expect(record['age']).to eq("--- 30\n...\n")

model.reload
expect(model.age).to eq(30)

model.save!(yaml_sucks: true)
record = redis.hgetall(key)
expect(record['age']).to eq("\x1E")
end
end
end
end
2 changes: 2 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

unless ENV['TRAVIS']
begin
require './spec/support/simplecov_helper'
Expand Down
Loading