db_memoize 0.2.3 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c30ad0bcaafd71d6b6e819e0d951561c0ccdee50
4
- data.tar.gz: 99803b69c67ad890ed66a2648c4cd414e3c0bc2d
2
+ SHA256:
3
+ metadata.gz: '095aec4c4352df19e1a55ee270414a18b240e6135733e5871d5f766dd6789077'
4
+ data.tar.gz: d9ee2695e76c0611f23aa3cfe7c8afa82ff09f04d5de1acf525d2570099b2428
5
5
  SHA512:
6
- metadata.gz: bde9f19880b5809dbf35daf2b1664223f9db45033d1cc297a3714c41afbbec98b0099b4e232566c0be1346e78dada3c92b27c607224f5480599efe91de7a644b
7
- data.tar.gz: 61aa061f01ba3df008f1b7be39f4e6510daf9f8e4dda38188b0c33deaace4c874cd60d426ea2cb3296ed4717f65635c5e4bdfa5ce9cb25cf47bd44042abaf020
6
+ metadata.gz: 50af7b39e3aed56fa829b940f4c0251c0d49fef89306a38f7f6aa69ab7c6dfecb677646869eb076c155f9fbc69abc9a6bba3d37ea57d4582b0a0465433d90a11
7
+ data.tar.gz: 97e18054c9914f961c97796650f47fff3aca4e74066f6dbe53b420633719bb7ec0f3f8354c7d2e19c11e93b864192894e538204b9bf57626fbeda427734af19c
data/.rubocop.yml CHANGED
@@ -3,21 +3,13 @@ AllCops:
3
3
  Include:
4
4
  - Rakefile
5
5
  - config.ru
6
+ - lib/**/*.rb
6
7
  Exclude:
7
8
  - Rakefile
8
9
  - bin/*
9
10
  - config.ru
10
11
  - config/**/*
11
- - db/**/*
12
- - doc/**/*
13
- - gems/**/*
14
- - gems/*/vendor/**/*
15
- - script/**/*
16
- - sh/**/*
17
- - spec/rails_helper.rb
18
- - spec/spec_helper.rb
19
12
  - vendor/**/*
20
- - spec/support/v20140601/requests_helper.rb
21
13
 
22
14
  Style/FrozenStringLiteralComment:
23
15
  Enabled: false
@@ -25,12 +17,6 @@ Style/FrozenStringLiteralComment:
25
17
  Metrics/LineLength:
26
18
  Max: 140
27
19
 
28
- Rails:
29
- Enabled: true
30
-
31
- Rails/HasAndBelongsToMany:
32
- Enabled: false
33
-
34
20
  Style/Documentation:
35
21
  Enabled: false
36
22
 
@@ -66,3 +52,9 @@ Metrics/MethodLength:
66
52
  # "Prefer !expression.nil? over expression != nil." no way!
67
53
  Style/NonNilCheck:
68
54
  Enabled: false
55
+
56
+ Style/SymbolArray:
57
+ Enabled: false
58
+
59
+ Lint/MissingCopEnableDirective:
60
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,8 +1,10 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.1
5
- before_install: gem install bundler -v 1.13.6
4
+ - 2.5.1
5
+ before_install: gem install bundler -v 1.16.4
6
+ addons:
7
+ postgresql: "9.6"
6
8
  script:
7
9
  - bundle exec rake db:test:create
8
10
  - bundle exec rspec
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Build Status](https://travis-ci.com/mediapeers/db_memoize.svg?branch=master)](https://travis-ci.com/mediapeers/db_memoize)
2
+
1
3
  # db_memoize
2
4
  library to cache (memoize) method return values in database
3
5
 
data/Rakefile CHANGED
@@ -1,11 +1,20 @@
1
- require "bundler/gem_tasks"
2
1
  require "rspec/core/rake_task"
3
2
 
4
3
  RSpec::Core::RakeTask.new(:spec)
5
4
 
6
- task "db:test:create" do
7
- Rake.sh "dropdb db_memoize_test || true"
8
- Rake.sh "createdb db_memoize_test"
5
+ task 'db:test:create' do
6
+ Rake.sh 'dropdb db_memoize_test -U postgres || true'
7
+ Rake.sh 'createdb db_memoize_test -U postgres'
9
8
  end
10
9
 
11
10
  task :default => %w(db:test:create spec)
11
+
12
+ desc "release a new development gem version"
13
+ task :release do
14
+ sh "scripts/release.rb"
15
+ end
16
+
17
+ desc "release a new stable gem version"
18
+ task "release:stable" do
19
+ sh "BRANCH=stable scripts/release.rb"
20
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.2
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
data/bin/rspec ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rspec-core", "rspec")
data/bin/rubocop ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rubocop", "rubocop")
data/db_memoize.gemspec CHANGED
@@ -1,11 +1,10 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'db_memoize/version'
5
4
 
6
5
  Gem::Specification.new do |spec|
7
6
  spec.name = "db_memoize"
8
- spec.version = DbMemoize::VERSION
7
+ spec.version = File.read("VERSION")
9
8
  spec.licenses = ['MIT']
10
9
  spec.authors = ["johannes-kostas goetzinger"]
11
10
  spec.email = ["goetzinger@mediapeers.com"]
@@ -21,20 +20,15 @@ Gem::Specification.new do |spec|
21
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
21
  spec.require_paths = ['lib']
23
22
 
23
+ spec.add_dependency 'simple-sql', '>= 0.4.20', '~> 0'
24
24
  spec.add_development_dependency 'railties', '~> 4.2'
25
- spec.add_development_dependency 'activerecord', '~> 4.2'
25
+ spec.add_development_dependency 'activerecord', '~> 4.2.10'
26
26
 
27
- spec.add_development_dependency 'rake', '~> 10.5'
28
- spec.add_development_dependency 'pg'
29
- spec.add_development_dependency 'rspec-rails', '~> 3.4'
30
- spec.add_development_dependency 'pry', '~> 0.10'
31
- spec.add_development_dependency 'pry-byebug', '~> 2.0'
32
- spec.add_development_dependency 'yard', '~> 0'
33
- spec.add_development_dependency 'simplecov', '~> 0.7.1'
34
- spec.add_development_dependency 'rubocop', '~> 0.37.2'
27
+ spec.add_development_dependency 'rake', '~> 12.0'
28
+ spec.add_development_dependency 'pg', '~> 0.20'
29
+ spec.add_development_dependency 'rspec', '~> 3.8'
30
+ spec.add_development_dependency 'simplecov', '~> 0.16'
31
+ spec.add_development_dependency 'rubocop', '~> 0.59.2'
35
32
  spec.add_development_dependency 'database_cleaner', '~> 1.5.3'
36
33
  spec.add_development_dependency 'factory_girl', '~> 4.7.0'
37
- spec.add_development_dependency 'ruby-progressbar', '~> 1.7'
38
- spec.add_development_dependency 'awesome_print'
39
- spec.add_development_dependency 'gem-release'
40
34
  end
data/lib/db_memoize.rb CHANGED
@@ -4,7 +4,6 @@ require 'digest'
4
4
  require 'benchmark'
5
5
 
6
6
  require 'db_memoize/version'
7
- require 'db_memoize/metal'
8
7
  require 'db_memoize/value'
9
8
  require 'db_memoize/helpers'
10
9
  require 'db_memoize/model'
@@ -16,17 +16,5 @@ module DbMemoize
16
16
  "DbMemoize <#{model.class.name}##{model.id}>##{method_name} - #{msg}"
17
17
  end
18
18
  end
19
-
20
- def calculate_arguments_hash(arguments)
21
- arguments.empty? ? nil : ::Digest::MD5.hexdigest(Marshal.dump(arguments))
22
- end
23
-
24
- def marshal(value)
25
- Marshal.dump(value)
26
- end
27
-
28
- def unmarshal(value)
29
- Marshal.load(value)
30
- end
31
19
  end
32
20
  end
@@ -13,6 +13,8 @@ module DbMemoize
13
13
 
14
14
  migration.add_index :memoized_values, [:entity_table_name, :entity_id]
15
15
  migrate_empty_arguments_support(migration)
16
+ drop_arguments_support(migration)
17
+ add_discrete_value_columns(migration)
16
18
  end
17
19
 
18
20
  def migrate_empty_arguments_support(migration)
@@ -23,7 +25,25 @@ module DbMemoize
23
25
 
24
26
  # add an index to be useful to look up entries where arguments_hash is NULL.
25
27
  # (which is the case for plain attributes of an object)
26
- migration.execute 'CREATE INDEX memoized_attributes_idx ON memoized_values((arguments_hash IS NULL))'
28
+ migration.execute 'CREATE INDEX IF NOT EXISTS memoized_attributes_idx ON memoized_values((arguments_hash IS NULL))'
29
+ end
30
+
31
+ def drop_arguments_support(migration)
32
+ migration.execute 'DROP INDEX IF EXISTS memoized_attributes_idx'
33
+ migration.execute 'ALTER TABLE memoized_values DROP COLUMN IF EXISTS arguments_hash'
34
+
35
+ migration.remove_index :memoized_values, [:entity_id, :entity_table_name]
36
+ migration.add_index :memoized_values, [:entity_id, :entity_table_name, :method_name], unique: true, name: 'memoized_attributes_idx2'
37
+ end
38
+
39
+ def add_discrete_value_columns(migration)
40
+ migration.execute 'ALTER TABLE memoized_values ADD COLUMN IF NOT EXISTS val_string varchar'
41
+ migration.execute 'ALTER TABLE memoized_values ADD COLUMN IF NOT EXISTS val_integer bigint'
42
+ migration.execute 'ALTER TABLE memoized_values ADD COLUMN IF NOT EXISTS val_float double precision'
43
+ migration.execute 'ALTER TABLE memoized_values ADD COLUMN IF NOT EXISTS val_time timestamp without time zone'
44
+ migration.execute 'ALTER TABLE memoized_values ADD COLUMN IF NOT EXISTS val_boolean boolean'
45
+ migration.execute 'ALTER TABLE memoized_values ADD COLUMN IF NOT EXISTS val_object jsonb'
46
+ migration.execute 'ALTER TABLE memoized_values ADD COLUMN IF NOT EXISTS val_nil boolean'
27
47
  end
28
48
  end
29
49
  end
@@ -1,23 +1,23 @@
1
+ require 'simple-sql'
2
+
1
3
  module DbMemoize
2
4
  module Model
3
5
  extend ActiveSupport::Concern
4
6
 
5
- def memoized_value(method_name, args)
6
- if changed? || !persisted?
7
- return send("#{method_name}_without_memoize", *args)
8
- end
7
+ def memoized_value(method_name)
8
+ memoizable = !changed? && persisted?
9
+ return send("#{method_name}_without_memoize") unless memoizable
9
10
 
10
11
  value = nil
11
- args_hash = Helpers.calculate_arguments_hash(args)
12
- cached_value = find_memoized_value(method_name, args_hash)
12
+ cached_value = find_memoized_value(method_name)
13
13
 
14
14
  if cached_value
15
- value = Helpers.unmarshal(cached_value.value)
15
+ value = cached_value.value
16
16
  Helpers.log(self, method_name, 'cache hit')
17
17
  else
18
18
  time = ::Benchmark.realtime do
19
- value = send("#{method_name}_without_memoize", *args)
20
- create_memoized_value(method_name, args_hash, value)
19
+ value = send("#{method_name}_without_memoize")
20
+ create_memoized_value(method_name, value)
21
21
  end
22
22
  Helpers.log(self, method_name, "cache miss. took #{Kernel.format '%.2f msecs', time * 1_000}")
23
23
  end
@@ -37,33 +37,28 @@ module DbMemoize
37
37
  # product.memoize_values full_title: "my full title",
38
38
  # autocomplete_info: "my autocomplete_info"
39
39
  #
40
- def memoize_values(values, *args)
41
- # [TODO] - when creating many memoized values: should we even support arguments here?
42
- args_hash = Helpers.calculate_arguments_hash(args)
43
-
40
+ # This sets the "full_title" and "autocomplete_info" values of the product.
41
+ #
42
+ def memoize_values(values)
44
43
  values.each do |name, value|
45
- create_memoized_value(name, args_hash, value)
44
+ create_memoized_value(name, value)
46
45
  end
47
46
  end
48
47
 
49
48
  private
50
49
 
51
- def create_memoized_value(method_name, arguments_hash, value)
52
- ::DbMemoize::Value.metal.create! entity_table_name: self.class.table_name,
53
- entity_id: id,
54
- method_name: method_name.to_s,
55
- arguments_hash: arguments_hash,
56
- value: Helpers.marshal(value)
57
-
58
- @association_cache.delete :memoized_values
50
+ def create_memoized_value(method_name, value)
51
+ self.class.transaction do
52
+ ::DbMemoize::Value.fast_create self.class.table_name, id, method_name, value
53
+ @association_cache.delete :memoized_values
54
+ end
59
55
  end
60
56
 
61
- def find_memoized_value(method_name, args_hash)
57
+ def find_memoized_value(method_name)
62
58
  method_name = method_name.to_s
63
59
 
64
60
  memoized_values.detect do |rec|
65
- rec.method_name == method_name &&
66
- rec.arguments_hash == args_hash
61
+ rec.method_name == method_name
67
62
  end
68
63
  end
69
64
 
@@ -93,19 +88,13 @@ module DbMemoize
93
88
  DbMemoize::Value.where(conditions).delete_all_ordered
94
89
  end
95
90
 
96
- def memoize_values(records_or_ids, values, *args)
97
- # [TODO] - when creating many memoized values: should we even support arguments here?
91
+ def memoize_values(records_or_ids, values)
98
92
  transaction do
99
- ids = Helpers.find_ids(records_or_ids)
100
- arguments_hash = Helpers.calculate_arguments_hash(args)
93
+ ids = Helpers.find_ids(records_or_ids)
101
94
 
102
95
  ids.each do |id|
103
96
  values.each do |method_name, value|
104
- ::DbMemoize::Value.metal.create! entity_table_name: table_name,
105
- entity_id: id,
106
- method_name: method_name.to_s,
107
- arguments_hash: arguments_hash,
108
- value: Helpers.marshal(value)
97
+ ::DbMemoize::Value.fast_create table_name, id, method_name, value
109
98
  end
110
99
  end
111
100
  end
@@ -113,14 +102,16 @@ module DbMemoize
113
102
 
114
103
  private
115
104
 
105
+ # rubocop:disable Style/EmptyBlockParameter
116
106
  def create_memoized_alias_method(method_name)
117
- define_method "#{method_name}_with_memoize" do |*args|
118
- memoized_value(method_name, args)
107
+ define_method "#{method_name}_with_memoize" do ||
108
+ memoized_value(method_name)
119
109
  end
120
110
 
121
111
  alias_method_chain method_name, :memoize
122
112
  end
123
113
 
114
+ # rubocop:disable Style/GuardClause
124
115
  def create_memoized_values_association
125
116
  unless reflect_on_association(:memoized_values)
126
117
  conditions = { entity_table_name: table_name }
@@ -1,15 +1,39 @@
1
+ # rubocop:disable Metrics/CyclomaticComplexity
2
+
3
+ require 'simple-sql'
4
+ require 'json'
5
+
1
6
  module DbMemoize
2
7
  class Value < ActiveRecord::Base
3
8
  self.table_name = 'memoized_values'
4
9
 
5
- include DbMemoize::Metal
10
+ SQL = ::Simple::SQL
11
+
12
+ def value=(value)
13
+ self.val_integer = self.val_float = self.val_string = self.val_boolean = self.val_time = nil
14
+
15
+ case value
16
+ when String then self.val_string = value
17
+ when Integer then self.val_integer = value
18
+ when Float then self.val_float = value
19
+ when Time then self.val_time = value
20
+ when false then self.val_boolean = value
21
+ when true then self.val_boolean = value
22
+ when nil then :nop
23
+ end
24
+ end
25
+
26
+ def value
27
+ # Note: val_boolean should come last.
28
+ val_string || val_integer || val_float || val_time || val_object || val_boolean
29
+ end
6
30
 
7
31
  def self.delete_all_ordered
8
32
  relation = self
9
33
  relation = all unless is_a?(ActiveRecord::Relation)
10
34
 
11
35
  sql = relation.select(:ctid).to_sql
12
- connection.execute <<-SQL
36
+ SQL.ask <<-SQL
13
37
  DO $$DECLARE c record;
14
38
  BEGIN
15
39
  FOR c IN #{sql} ORDER BY ctid LOOP
@@ -18,5 +42,36 @@ module DbMemoize
18
42
  END$$;
19
43
  SQL
20
44
  end
45
+
46
+ def self.fast_create(entity_table_name, id, method_name, value)
47
+ method_name = method_name.to_s
48
+
49
+ # clear out old entry (if any). This makes sure that any existing value
50
+ # is cleared out properly.
51
+ SQL.ask "DELETE FROM #{table_name} WHERE(entity_table_name, entity_id, method_name) = ($1, $2, $3)",
52
+ entity_table_name, id, method_name
53
+
54
+ dest_column = case value
55
+ when String then :val_string
56
+ when Integer then :val_integer
57
+ when Float then :val_float
58
+ when Time then :val_time
59
+ when false then :val_boolean
60
+ when nil then :val_nil
61
+ when Hash then :val_object
62
+ when Array then :val_object
63
+ else
64
+ raise "Unsupported value of type #{value.class.name}: #{value.inspect}"
65
+ end
66
+
67
+ value = JSON.generate(value) if dest_column == :val_object
68
+ sql = <<~SQL.freeze
69
+ INSERT INTO #{table_name}
70
+ (entity_table_name, entity_id, method_name, #{dest_column}, created_at)
71
+ VALUES($1,$2,$3,$4,NOW())
72
+ SQL
73
+
74
+ SQL.ask sql, entity_table_name, id, method_name, value
75
+ end
21
76
  end
22
77
  end
@@ -1,3 +1,24 @@
1
1
  module DbMemoize
2
- VERSION = '0.2.3'.freeze
2
+ module GemHelper
3
+ module_function
4
+
5
+ def version(name)
6
+ spec = Gem.loaded_specs[name]
7
+ version = spec.version.to_s
8
+ version += '+unreleased' if unreleased?(spec)
9
+ version
10
+ end
11
+
12
+ private
13
+
14
+ def unreleased?(spec)
15
+ return false unless defined?(Bundler::Source::Gemspec)
16
+ return true if spec.source.is_a?(::Bundler::Source::Gemspec)
17
+ return true if spec.source.is_a?(::Bundler::Source::Path)
18
+
19
+ false
20
+ end
21
+ end
22
+
23
+ VERSION = GemHelper.version 'db_memoize'
3
24
  end
data/scripts/release ADDED
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ $0.rb "$@"
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # -- helpers ------------------------------------------------------------------
4
+
5
+ def sys(cmd)
6
+ STDERR.puts "> #{cmd}"
7
+ system cmd
8
+ return true if $?.success?
9
+
10
+ STDERR.puts "> #{cmd} returned with exitstatus #{$?.exitstatus}"
11
+ $?.success?
12
+ end
13
+
14
+ def sys!(cmd, error: nil)
15
+ return true if sys(cmd)
16
+ STDERR.puts error if error
17
+ exit 1
18
+ end
19
+
20
+ def die!(msg)
21
+ STDERR.puts msg
22
+ exit 1
23
+ end
24
+
25
+ ROOT = File.expand_path("#{File.dirname(__FILE__)}/..")
26
+
27
+ GEMSPEC = Dir.glob("*.gemspec").first || die!("Missing gemspec file.")
28
+
29
+ # -- Version reading and bumping ----------------------------------------------
30
+
31
+ module Version
32
+ extend self
33
+
34
+ VERSION_FILE = "#{Dir.getwd}/VERSION"
35
+
36
+ def read_version
37
+ version = File.exist?(VERSION_FILE) ? File.read(VERSION_FILE) : "0.0.1"
38
+ version.chomp!
39
+ raise "Invalid version number in #{VERSION_FILE}" unless version =~ /^\d+\.\d+\.\d+$/
40
+ version
41
+ end
42
+
43
+ def auto_version_bump
44
+ old_version_number = read_version
45
+ old = old_version_number.split('.')
46
+
47
+ current = old[0..-2] << old[-1].next
48
+ current.join('.')
49
+ end
50
+
51
+ def bump_version
52
+ next_version = ENV["VERSION"] || auto_version_bump
53
+ File.open(VERSION_FILE, "w") { |io| io.write next_version }
54
+ end
55
+ end
56
+
57
+ # -- check, bump, release a new gem version -----------------------------------
58
+
59
+ Dir.chdir ROOT
60
+ $BASE_BRANCH = ENV['BRANCH'] || 'master'
61
+
62
+ # ENV["BUNDLE_GEMFILE"] = "#{Dir.getwd}/Gemfile"
63
+ # sys! "bundle install"
64
+
65
+ sys! "git diff --exit-code > /dev/null", error: 'There are unstaged changes in your working directory'
66
+ sys! "git diff --cached --exit-code > /dev/null", error: 'There are staged but uncommitted changes'
67
+
68
+ sys! "git checkout #{$BASE_BRANCH}"
69
+ sys! "git pull"
70
+
71
+ Version.bump_version
72
+ version = Version.read_version
73
+
74
+ sys! "git add VERSION"
75
+ sys! "git commit -m \"bump gem to v#{version}\""
76
+ sys! "git tag -a v#{version} -m \"Tag #{version}\""
77
+
78
+ sys! "gem build #{GEMSPEC}"
79
+
80
+ sys! "git push origin #{$BASE_BRANCH}"
81
+ sys! 'git push --tags --force'
82
+
83
+ # sys! "bundle exec fury push #{Dir.glob('*.gem').first} --as mediapeers"
84
+ sys! "gem push #{Dir.glob('*.gem').first}"
85
+
86
+ sys! "mkdir -p pkg"
87
+ sys! "mv *.gem pkg"
88
+
89
+ STDERR.puts <<-MSG
90
+ ================================================================================
91
+ Thank you for releasing a new gem version. You made my day.
92
+ ================================================================================
93
+ MSG
metadata CHANGED
@@ -1,31 +1,37 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: db_memoize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - johannes-kostas goetzinger
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-30 00:00:00.000000000 Z
11
+ date: 2018-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: railties
14
+ name: simple-sql
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.4.20
17
20
  - - "~>"
18
21
  - !ruby/object:Gem::Version
19
- version: '4.2'
20
- type: :development
22
+ version: '0'
23
+ type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.4.20
24
30
  - - "~>"
25
31
  - !ruby/object:Gem::Version
26
- version: '4.2'
32
+ version: '0'
27
33
  - !ruby/object:Gem::Dependency
28
- name: activerecord
34
+ name: railties
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
@@ -39,117 +45,89 @@ dependencies:
39
45
  - !ruby/object:Gem::Version
40
46
  version: '4.2'
41
47
  - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '10.5'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '10.5'
55
- - !ruby/object:Gem::Dependency
56
- name: pg
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec-rails
48
+ name: activerecord
71
49
  requirement: !ruby/object:Gem::Requirement
72
50
  requirements:
73
51
  - - "~>"
74
52
  - !ruby/object:Gem::Version
75
- version: '3.4'
53
+ version: 4.2.10
76
54
  type: :development
77
55
  prerelease: false
78
56
  version_requirements: !ruby/object:Gem::Requirement
79
57
  requirements:
80
58
  - - "~>"
81
59
  - !ruby/object:Gem::Version
82
- version: '3.4'
60
+ version: 4.2.10
83
61
  - !ruby/object:Gem::Dependency
84
- name: pry
62
+ name: rake
85
63
  requirement: !ruby/object:Gem::Requirement
86
64
  requirements:
87
65
  - - "~>"
88
66
  - !ruby/object:Gem::Version
89
- version: '0.10'
67
+ version: '12.0'
90
68
  type: :development
91
69
  prerelease: false
92
70
  version_requirements: !ruby/object:Gem::Requirement
93
71
  requirements:
94
72
  - - "~>"
95
73
  - !ruby/object:Gem::Version
96
- version: '0.10'
74
+ version: '12.0'
97
75
  - !ruby/object:Gem::Dependency
98
- name: pry-byebug
76
+ name: pg
99
77
  requirement: !ruby/object:Gem::Requirement
100
78
  requirements:
101
79
  - - "~>"
102
80
  - !ruby/object:Gem::Version
103
- version: '2.0'
81
+ version: '0.20'
104
82
  type: :development
105
83
  prerelease: false
106
84
  version_requirements: !ruby/object:Gem::Requirement
107
85
  requirements:
108
86
  - - "~>"
109
87
  - !ruby/object:Gem::Version
110
- version: '2.0'
88
+ version: '0.20'
111
89
  - !ruby/object:Gem::Dependency
112
- name: yard
90
+ name: rspec
113
91
  requirement: !ruby/object:Gem::Requirement
114
92
  requirements:
115
93
  - - "~>"
116
94
  - !ruby/object:Gem::Version
117
- version: '0'
95
+ version: '3.8'
118
96
  type: :development
119
97
  prerelease: false
120
98
  version_requirements: !ruby/object:Gem::Requirement
121
99
  requirements:
122
100
  - - "~>"
123
101
  - !ruby/object:Gem::Version
124
- version: '0'
102
+ version: '3.8'
125
103
  - !ruby/object:Gem::Dependency
126
104
  name: simplecov
127
105
  requirement: !ruby/object:Gem::Requirement
128
106
  requirements:
129
107
  - - "~>"
130
108
  - !ruby/object:Gem::Version
131
- version: 0.7.1
109
+ version: '0.16'
132
110
  type: :development
133
111
  prerelease: false
134
112
  version_requirements: !ruby/object:Gem::Requirement
135
113
  requirements:
136
114
  - - "~>"
137
115
  - !ruby/object:Gem::Version
138
- version: 0.7.1
116
+ version: '0.16'
139
117
  - !ruby/object:Gem::Dependency
140
118
  name: rubocop
141
119
  requirement: !ruby/object:Gem::Requirement
142
120
  requirements:
143
121
  - - "~>"
144
122
  - !ruby/object:Gem::Version
145
- version: 0.37.2
123
+ version: 0.59.2
146
124
  type: :development
147
125
  prerelease: false
148
126
  version_requirements: !ruby/object:Gem::Requirement
149
127
  requirements:
150
128
  - - "~>"
151
129
  - !ruby/object:Gem::Version
152
- version: 0.37.2
130
+ version: 0.59.2
153
131
  - !ruby/object:Gem::Dependency
154
132
  name: database_cleaner
155
133
  requirement: !ruby/object:Gem::Requirement
@@ -178,48 +156,6 @@ dependencies:
178
156
  - - "~>"
179
157
  - !ruby/object:Gem::Version
180
158
  version: 4.7.0
181
- - !ruby/object:Gem::Dependency
182
- name: ruby-progressbar
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: '1.7'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: '1.7'
195
- - !ruby/object:Gem::Dependency
196
- name: awesome_print
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - ">="
200
- - !ruby/object:Gem::Version
201
- version: '0'
202
- type: :development
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - ">="
207
- - !ruby/object:Gem::Version
208
- version: '0'
209
- - !ruby/object:Gem::Dependency
210
- name: gem-release
211
- requirement: !ruby/object:Gem::Requirement
212
- requirements:
213
- - - ">="
214
- - !ruby/object:Gem::Version
215
- version: '0'
216
- type: :development
217
- prerelease: false
218
- version_requirements: !ruby/object:Gem::Requirement
219
- requirements:
220
- - - ">="
221
- - !ruby/object:Gem::Version
222
- version: '0'
223
159
  description: library to cache (memoize) method return values in database
224
160
  email:
225
161
  - goetzinger@mediapeers.com
@@ -235,12 +171,15 @@ files:
235
171
  - LICENSE
236
172
  - README.md
237
173
  - Rakefile
174
+ - VERSION
238
175
  - bin/console
176
+ - bin/rake
177
+ - bin/rspec
178
+ - bin/rubocop
239
179
  - bin/setup
240
180
  - db_memoize.gemspec
241
181
  - lib/db_memoize.rb
242
182
  - lib/db_memoize/helpers.rb
243
- - lib/db_memoize/metal.rb
244
183
  - lib/db_memoize/migrations.rb
245
184
  - lib/db_memoize/model.rb
246
185
  - lib/db_memoize/railtie.rb
@@ -249,6 +188,8 @@ files:
249
188
  - lib/tasks/clear.rake
250
189
  - lib/tasks/warmup.rake
251
190
  - log/.keep
191
+ - scripts/release
192
+ - scripts/release.rb
252
193
  homepage: https://github.com/mediapeers/db_memoize
253
194
  licenses:
254
195
  - MIT
@@ -269,7 +210,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
269
210
  version: '0'
270
211
  requirements: []
271
212
  rubyforge_project:
272
- rubygems_version: 2.5.1
213
+ rubygems_version: 2.7.7
273
214
  signing_key:
274
215
  specification_version: 4
275
216
  summary: library to cache (memoize) method return values in database
@@ -1,127 +0,0 @@
1
- module DbMemoize
2
- module Metal
3
- def self.included(base)
4
- base.extend ClassMethods
5
- # base.metal # initialize the metal adapter
6
- end
7
-
8
- module ClassMethods
9
- def metal
10
- @metal ||= Adapter.new(self)
11
- end
12
- end
13
-
14
- class Adapter
15
- class PkInfo
16
- attr_reader :column, :type
17
-
18
- def initialize(base_klass)
19
- @column = base_klass.primary_key
20
- @type = @column && base_klass.columns_hash.fetch(@column).type
21
- end
22
- end
23
-
24
- def initialize(base_klass)
25
- @base_klass = base_klass
26
- @query_cache = {}
27
- end
28
-
29
- private
30
-
31
- # setup primary key information. This is necessary to allow the create! method
32
- # to return the primary key of a newly created entry.
33
- def primary_key
34
- @primary_key ||= PkInfo.new(@base_klass)
35
- end
36
-
37
- def table_name
38
- @base_klass.table_name
39
- end
40
-
41
- def raw_connection
42
- @base_klass.connection.raw_connection # do not memoize me!
43
- end
44
-
45
- def column?(column_name)
46
- @base_klass.columns_hash.key?(column_name)
47
- end
48
-
49
- class Inserter
50
- def initialize(sql:, bytea_indices:)
51
- @sql = sql
52
- @bytea_indices = bytea_indices
53
- end
54
-
55
- def exec(raw_connection:, values:)
56
- @bytea_indices.each do |bytea_index|
57
- value = values[bytea_index]
58
- values[bytea_index] = PGconn.escape_bytea(value) if value
59
- end
60
-
61
- raw_connection.exec_params(@sql, values)
62
- end
63
- end
64
-
65
- # returns an Inserter
66
- def inserter(field_names)
67
- @query_cache[field_names] ||= _inserter(field_names)
68
- end
69
-
70
- DATABASE_IDENTIFIER_REGEX = /\A\w+\z/
71
-
72
- def check_database_identifiers!(*strings)
73
- strings.each do |s|
74
- next if DATABASE_IDENTIFIER_REGEX =~ s
75
- raise ArgumentError, "Invalid database identifier: #{s.inspect}"
76
- end
77
- end
78
-
79
- def _inserter(field_names)
80
- check_database_identifiers! table_name, *field_names
81
-
82
- placeholders = 0.upto(field_names.count - 1).map { |idx| "$#{idx + 1}" }
83
-
84
- if column?('created_at')
85
- field_names << 'created_at'
86
- placeholders << 'current_timestamp'
87
- end
88
-
89
- if column?('updated_at')
90
- field_names << 'updated_at'
91
- placeholders << 'current_timestamp'
92
- end
93
-
94
- sql = "INSERT INTO #{table_name} (#{field_names.join(',')}) VALUES(#{placeholders.join(',')})"
95
- sql += " RETURNING #{primary_key.column}" if primary_key.column
96
-
97
- columns_hash = @base_klass.columns_hash
98
- bytea_indices = []
99
- field_names.each_with_index { |column, idx|
100
- next unless :binary == columns_hash.fetch(column).type
101
- bytea_indices << idx
102
- }
103
-
104
- Inserter.new sql: sql, bytea_indices: bytea_indices
105
- end
106
-
107
- public
108
-
109
- def create!(record)
110
- keys, values = record.to_a.transpose
111
- keys = keys.map(&:to_s)
112
-
113
- result = inserter(keys).exec(raw_connection: raw_connection, values: values)
114
-
115
- # if we don't have an ID column then the sql does not return any value. The result
116
- # object would be this: #<PG::Result status=PGRES_COMMAND_OK ntuples=0 nfields=0 cmd_tuples=1>
117
- # we just return nil in that case; otherwise we return the first entry of the first result row
118
- # which would be the stringified id.
119
- first_row = result.each_row.first
120
- return nil unless first_row
121
-
122
- id = first_row.first
123
- primary_key.type == :integer ? Integer(id) : id
124
- end
125
- end
126
- end
127
- end