diff --git a/.rubocop.yml b/.rubocop.yml index 745e154..932c41e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -35,3 +35,9 @@ Style/StructInheritance: Metrics/ModuleLength: Enabled: false + +Metrics/BlockLength: + Enabled: false + +Security/YAMLLoad: + Enabled: false diff --git a/.ruby-version b/.ruby-version index 94b04ed..005119b 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -ruby-2.2.2 +2.4.1 diff --git a/.travis.yml b/.travis.yml index 11e48a2..3844f2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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= diff --git a/Gemfile b/Gemfile index bd3fa6b..3466afb 100644 --- a/Gemfile +++ b/Gemfile @@ -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 diff --git a/README.md b/README.md index 707e779..567c0b2 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/Rakefile b/Rakefile index 058c233..d860faa 100644 --- a/Rakefile +++ b/Rakefile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "rake" require "bundler/gem_tasks" require "rspec/core/rake_task" diff --git a/benchmark/bench.rb b/benchmark/bench.rb index bbb5fec..523de06 100644 --- a/benchmark/bench.rb +++ b/benchmark/bench.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'stackprof' require 'benchmark' @@ -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 diff --git a/benchmark/find.rb b/benchmark/find.rb index 97d6cf8..57193e9 100755 --- a/benchmark/find.rb +++ b/benchmark/find.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + $LOAD_PATH.unshift('benchmark') require 'bench' @@ -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 diff --git a/benchmark/persistence.rb b/benchmark/persistence.rb index f9d88a3..9484af4 100644 --- a/benchmark/persistence.rb +++ b/benchmark/persistence.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + $LOAD_PATH.unshift('benchmark') require 'bench' @@ -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 diff --git a/lib/modis.rb b/lib/modis.rb index f7f750e..50a0660 100644 --- a/lib/modis.rb +++ b/lib/modis.rb @@ -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' diff --git a/lib/modis/attribute.rb b/lib/modis/attribute.rb index bd2025e..98e8aed 100644 --- a/lib/modis/attribute.rb +++ b/lib/modis/attribute.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis module Attribute TYPES = { string: [String], diff --git a/lib/modis/configuration.rb b/lib/modis/configuration.rb index 170abd7..c7933c7 100644 --- a/lib/modis/configuration.rb +++ b/lib/modis/configuration.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis def self.configure yield config diff --git a/lib/modis/errors.rb b/lib/modis/errors.rb index 6937466..c3d82a2 100644 --- a/lib/modis/errors.rb +++ b/lib/modis/errors.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis class ModisError < StandardError; end class RecordNotSaved < ModisError; end diff --git a/lib/modis/finder.rb b/lib/modis/finder.rb index dead104..48068a2 100644 --- a/lib/modis/finder.rb +++ b/lib/modis/finder.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis module Finder def self.included(base) @@ -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 diff --git a/lib/modis/index.rb b/lib/modis/index.rb index 0af55f9..c397056 100644 --- a/lib/modis/index.rb +++ b/lib/modis/index.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis module Index def self.included(base) diff --git a/lib/modis/model.rb b/lib/modis/model.rb index d46c448..790bf76 100644 --- a/lib/modis/model.rb +++ b/lib/modis/model.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis module Model def self.included(base) @@ -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 diff --git a/lib/modis/persistence.rb b/lib/modis/persistence.rb index f39071e..52b6086 100644 --- a/lib/modis/persistence.rb +++ b/lib/modis/persistence.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis module Persistence def self.included(base) @@ -5,7 +7,7 @@ def self.included(base) base.instance_eval do class << self attr_reader :sti_child - alias_method :sti_child?, :sti_child + alias sti_child? sti_child end end end @@ -71,7 +73,6 @@ def create!(attrs) model end - YAML_MARKER = '---'.freeze def deserialize(record) values = record.values values = MessagePack.unpack(msgpack_array_header(values.size) + values.join) @@ -79,20 +80,8 @@ def deserialize(record) 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 @@ -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 @@ -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 @@ -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 @@ -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) diff --git a/lib/modis/transaction.rb b/lib/modis/transaction.rb index 461edfe..f3f3849 100644 --- a/lib/modis/transaction.rb +++ b/lib/modis/transaction.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis module Transaction def self.included(base) diff --git a/lib/modis/version.rb b/lib/modis/version.rb index aafb787..ebac909 100644 --- a/lib/modis/version.rb +++ b/lib/modis/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Modis VERSION = '1.4.1' end diff --git a/lib/tasks/quality.rake b/lib/tasks/quality.rake index af33081..a23c571 100644 --- a/lib/tasks/quality.rake +++ b/lib/tasks/quality.rake @@ -1,3 +1,5 @@ +# frozen_string_literal: true + begin if ENV['TRAVIS'] namespace :spec do @@ -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 @@ -37,5 +39,5 @@ rescue LoadError end namespace :spec do - task quality: %w(cane rubocop) + task quality: %w[cane rubocop] end diff --git a/modis.gemspec b/modis.gemspec index 013ba32..78fa09e 100644 --- a/modis.gemspec +++ b/modis.gemspec @@ -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' diff --git a/spec/attribute_spec.rb b/spec/attribute_spec.rb index abbe775..bebc6c2 100644 --- a/spec/attribute_spec.rb +++ b/spec/attribute_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module AttributeSpec @@ -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 diff --git a/spec/errors_spec.rb b/spec/errors_spec.rb index c3d67f4..2449598 100644 --- a/spec/errors_spec.rb +++ b/spec/errors_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module ErrorsSpec diff --git a/spec/finder_spec.rb b/spec/finder_spec.rb index c9e9784..49ad86a 100644 --- a/spec/finder_spec.rb +++ b/spec/finder_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module FindersSpec @@ -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 diff --git a/spec/index_spec.rb b/spec/index_spec.rb index 08d6003..51d98a0 100644 --- a/spec/index_spec.rb +++ b/spec/index_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module IndexSpec diff --git a/spec/persistence_spec.rb b/spec/persistence_spec.rb index c193a78..a196c72 100644 --- a/spec/persistence_spec.rb +++ b/spec/persistence_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module PersistenceSpec @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d50ef65..dc979b3 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + unless ENV['TRAVIS'] begin require './spec/support/simplecov_helper' diff --git a/spec/support/simplecov_helper.rb b/spec/support/simplecov_helper.rb index 029427a..c1288c9 100644 --- a/spec/support/simplecov_helper.rb +++ b/spec/support/simplecov_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'simplecov' require './spec/support/simplecov_quality_formatter' @@ -17,7 +19,7 @@ def start_simple_cov(name) end end - formatter SimpleCov::Formatter::MultiFormatter[*formatters] + formatter SimpleCov::Formatter::MultiFormatter.new(*formatters) end end end diff --git a/spec/support/simplecov_quality_formatter.rb b/spec/support/simplecov_quality_formatter.rb index 65bdd1d..97b6ff0 100644 --- a/spec/support/simplecov_quality_formatter.rb +++ b/spec/support/simplecov_quality_formatter.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module SimpleCov module Formatter class QualityFormatter diff --git a/spec/transaction_spec.rb b/spec/transaction_spec.rb index eef78ce..420c24a 100644 --- a/spec/transaction_spec.rb +++ b/spec/transaction_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' module TransactionSpec diff --git a/spec/validations_spec.rb b/spec/validations_spec.rb index 5010ff0..e6dadd5 100644 --- a/spec/validations_spec.rb +++ b/spec/validations_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'spec_helper' describe 'validations' do