json_schematize 0.6.0 → 0.7.0

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
2
  SHA256:
3
- metadata.gz: 7db5a295c8de919a0eb55d2894094d8c5c97f932b0955495c31ed762e84133f8
4
- data.tar.gz: a8dc99a3affdf8027d9ec4bde5e689e84b18d1571ba126e54cb806d484ad8fb2
3
+ metadata.gz: 332c8451a65d8d3ef3c738e6a06d54407e62d479f6d0f015aa348c01c8c70f03
4
+ data.tar.gz: 534ae0f9dd57ee349c99fa75305370241470afb99ca0273afe98d9b206a9eb57
5
5
  SHA512:
6
- metadata.gz: 4de0766c2fb072d96908c1cb66e7611c79db5635cfc046b51d90ad40a8d732d0fe086e62e1b243b0813d90b48e9607198c854624544e2e05b7bbd8a59dd7fb2b
7
- data.tar.gz: ce9fa6fdda05e251c7ec45cbff00a22f7aba3ce28f31820f682da05676584defdf491540d5cddd17e26697d572665081781430be7dcaa87723d7466f975f2560
6
+ metadata.gz: ce9ed85a4db89c977231290127487fde0d703ac527009173d28d0d10a1ced80a43d1febcb8cc3e4dff3b64bd80dc20c2817dd14fe301c478d3169342799f1187
7
+ data.tar.gz: 6eca9b7c49801e97d1393157c8c49a42ffafcb26bcdc103974329c2222ce3f804a496038f1cf8041836170ac251b3e9f977727f99d4bd11edad6de47931b76de
data/.circleci/config.yml CHANGED
@@ -1,202 +1,29 @@
1
1
  version: 2.1
2
2
 
3
- # Declare the orbs that we'll use in our config.
4
- # read more about orbs: https://circleci.com/docs/2.0/using-orbs/
5
3
  orbs:
6
4
  ruby: circleci/ruby@1.0
5
+ node: circleci/node@2
6
+ cst: cst/framework@1
7
7
 
8
- common_envs: &common_envs
9
- environment:
10
- APP_BUNDLER_VERSION: "2.3.8"
11
- REDIS_URL: "redis://127.0.0.1"
12
-
13
- executors:
14
- gem:
15
- parameters:
16
- ruby-version:
17
- default: "3.0.0"
18
- type: string
19
- docker:
20
- - image: cimg/ruby:<< parameters.ruby-version >>
21
- - image: circleci/redis:6.0
22
-
23
- <<: *common_envs
24
-
25
- commands:
26
- bundler-preamble:
27
- description: "Install ruby and the Gemfile dependencies"
28
- parameters:
29
- ruby-version:
30
- type: string
31
- default: "3"
32
- description: "Ruby Gem version"
33
- key-name:
34
- type: string
35
- default: ""
36
- description: Custom name to add to the cache key
37
- cache-breaker:
38
- type: string
39
- default: "0"
40
- description: "Cache breaker to force new cache instantiation"
41
- keep-lock-file:
42
- type: boolean
43
- default: false
44
- description: "Retain lock file when bit is set to true. Otherwise generate a new one specific for this build"
45
- steps:
46
- - checkout
47
- - attach_workspace:
48
- at: workspace
49
- - unless:
50
- condition:
51
- equal: [ true, << parameters.keep-lock-file >> ]
52
- steps:
53
- - run:
54
- name: Remove Gemfile.lock
55
- command: rm Gemfile.lock
56
- - restore_cache:
57
- key: bundle-<< parameters.ruby-version >>-<< parameters.key-name >>-{{ checksum "Gemfile" }}-<< parameters.cache-breaker >>
58
- - ruby/install-deps:
59
- path: vendor/bundle
60
- with-cache: false
61
- - run:
62
- name: "Update dependencies"
63
- command: bundle update
64
- - save_cache:
65
- key: bundle-<< parameters.ruby-version >>-<< parameters.key-name >>-{{ checksum "Gemfile" }}-<< parameters.cache-breaker >>
66
- paths:
67
- - vendor/bundle
68
-
69
- jobs:
70
- publish-rubygems:
71
- executor: gem
72
- steps:
73
- - bundler-preamble:
74
- keep-lock-file: true
75
- - run:
76
- name: Publish to Ruby Gems
77
- command: |
78
- if [ -z "$GEM_HOST_API_KEY" ]; then
79
- echo 'Environment variable GEM_HOST_API_KEY is not present'
80
- exit 1
81
- fi
82
- gem_output=$(gem build json_schematize.gemspec)
83
- VERSION=$(printf "$gem_output" | awk '/Version: / {print $2}')
84
- FILE=$(printf "$gem_output" | awk '/File: / {print $2}')
85
-
86
- gem push ${FILE}
87
-
88
- publish-github:
89
- executor: gem
90
- steps:
91
- - bundler-preamble:
92
- keep-lock-file: true
93
- - run:
94
- name: 'Get Go'
95
- command: |
96
- sudo apt-get update -qq
97
- sudo apt-get -y --no-install-recommends install golang-go
98
- - run:
99
- name: 'Set Git stats'
100
- command: |
101
- git config user.name $GITHUB_USER
102
- git config user.email $GITHUB_EMAIL
103
- - run:
104
- name: Publish Git Release
105
- command: |
106
- curl -sSL https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_linux_amd64.tar.gz | tar xz -f - -C . ghr_v0.13.0_linux_amd64/ghr
107
- mv ghr_v0.13.0_linux_amd64/ghr .
108
- rm -rf ghr_v0.13.0_linux_amd64
109
- chmod 0755 ghr
110
-
111
- if [ -z "$GITHUB_TOKEN" ]; then
112
- echo 'Environment variable GITHUB_TOKEN is not present'
113
- exit 1
114
- fi
115
-
116
- if [ -z "$GITHUB_USER" ]; then
117
- echo 'Environment variable GITHUB_USER is not present'
118
- exit 1
119
- fi
120
-
121
- if [ $(git tag -l "$VERSION") ]; then
122
- echo "Pre existing version $VERSION, not tagging."
123
- exit 0
124
- fi
125
-
126
- gem_output=$(gem build json_schematize.gemspec)
127
- VERSION=$(printf "$gem_output" | awk '/Version: / {print $2}')
128
- FILE=$GEM_PATH$(printf "$gem_output" | awk '/File: / {print $2}')
129
-
130
- git tag -a $VERSION -m "$VERSION"
131
-
132
- SHA=$(git rev-parse HEAD)
133
- ./ghr -soft -t ${GITHUB_TOKEN} -u ${GITHUB_USER} -r json_schematize -c ${SHA} ${VERSION} ${FILE}
134
-
135
- test:
136
- parameters:
137
- ruby-version:
138
- default: "3.0.0"
139
- type: string
140
- description: "Ruby version to test against"
141
- executor:
142
- name: gem
143
- ruby-version: << parameters.ruby-version >>
144
- steps:
145
- - bundler-preamble:
146
- ruby-version: "<< parameters.ruby-version >>"
147
- - run:
148
- name: Setup Climate Control test-reporter
149
- command: |
150
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
151
- chmod +x ./cc-test-reporter
152
- - run:
153
- name: Waiting for Redis to be ready
154
- command: |
155
- for i in `seq 1 10`;
156
- do
157
- nc -z localhost 6379 && echo Success && exit 0
158
- echo -n .
159
- sleep 1
160
- done
161
- echo Failed waiting for Redis to be available && exit 1
162
- - run:
163
- name: Run and Report tests
164
- command: |
165
- ./cc-test-reporter before-build
166
- SIMPLE_COV_RUN=true bundle exec rspec --format RspecJunitFormatter --out test-results/rspec/rspec.xml --format progress --color
167
- - when:
168
- condition:
169
- equal:
170
- [
171
- required-test-ruby2.7.5,
172
- required-test-ruby<< parameters.ruby-version >>,
173
- ]
174
- steps:
175
- - run:
176
- name: Report CodeClimate Coverage
177
- command: ./cc-test-reporter after-build --coverage-input-type simplecov
178
8
  workflows:
179
9
  version: 2
180
10
  yeet-le-jobs:
181
11
  jobs:
182
- - test:
12
+ - cst/enforce-gem-version-bump
13
+ - cst/rspec-ruby:
14
+ rspec-system-args: "SIMPLE_COV_RUN=true"
15
+ cc-report-collect-ruby: "2.7.5"
183
16
  matrix:
184
17
  parameters:
185
18
  ruby-version: ["2.7.5" , "3.0.0", "3.0.3"]
186
19
  alias: required-matrix-tests
187
- name: required-test-ruby<< matrix.ruby-version >>
188
- - publish-github:
189
- requires:
190
- - required-matrix-tests
191
- filters:
192
- branches:
193
- only:
194
- - main
195
- - publish-rubygems:
20
+ name: test-ruby<< matrix.ruby-version >>
21
+ - cst/publish-gem:
22
+ publish-git: true
23
+ publish-default-gem: true
196
24
  requires:
197
25
  - required-matrix-tests
198
26
  filters:
199
27
  branches:
200
28
  only:
201
29
  - main
202
-
data/Gemfile CHANGED
@@ -4,7 +4,7 @@ source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
6
 
7
- gem 'redis'
7
+ gem 'activesupport'
8
8
  gem 'faker'
9
9
  gem 'pry'
10
10
  gem 'rspec', '~> 3.0'
data/Gemfile.lock CHANGED
@@ -1,14 +1,19 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- json_schematize (0.6.0)
4
+ json_schematize (0.7.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ activesupport (7.0.2.4)
10
+ concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ i18n (>= 1.6, < 2)
12
+ minitest (>= 5.1)
13
+ tzinfo (~> 2.0)
9
14
  byebug (11.1.3)
10
15
  coderay (1.1.3)
11
- concurrent-ruby (1.1.10)
16
+ concurrent-ruby (1.1.9)
12
17
  diff-lcs (1.5.0)
13
18
  docile (1.4.0)
14
19
  faker (2.20.0)
@@ -16,6 +21,7 @@ GEM
16
21
  i18n (1.10.0)
17
22
  concurrent-ruby (~> 1.0)
18
23
  method_source (1.0.0)
24
+ minitest (5.15.0)
19
25
  pry (0.13.1)
20
26
  coderay (~> 1.1)
21
27
  method_source (~> 1.0)
@@ -23,7 +29,6 @@ GEM
23
29
  byebug (~> 11.0)
24
30
  pry (~> 0.13.0)
25
31
  rake (12.3.3)
26
- redis (4.6.0)
27
32
  rspec (3.11.0)
28
33
  rspec-core (~> 3.11.0)
29
34
  rspec-expectations (~> 3.11.0)
@@ -33,7 +38,7 @@ GEM
33
38
  rspec-expectations (3.11.0)
34
39
  diff-lcs (>= 1.2.0, < 2.0)
35
40
  rspec-support (~> 3.11.0)
36
- rspec-mocks (3.11.1)
41
+ rspec-mocks (3.11.0)
37
42
  diff-lcs (>= 1.2.0, < 2.0)
38
43
  rspec-support (~> 3.11.0)
39
44
  rspec-support (3.11.0)
@@ -45,17 +50,19 @@ GEM
45
50
  simplecov_json_formatter (~> 0.1)
46
51
  simplecov-html (0.12.3)
47
52
  simplecov_json_formatter (0.1.4)
53
+ tzinfo (2.0.4)
54
+ concurrent-ruby (~> 1.0)
48
55
 
49
56
  PLATFORMS
50
57
  x86_64-linux
51
58
 
52
59
  DEPENDENCIES
60
+ activesupport
53
61
  faker
54
62
  json_schematize!
55
63
  pry
56
64
  pry-byebug
57
65
  rake (~> 12.0)
58
- redis
59
66
  rspec (~> 3.0)
60
67
  rspec_junit_formatter
61
68
  simplecov
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Matt Taylor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/docker-compose.yml CHANGED
@@ -10,13 +10,6 @@ services:
10
10
  - .:/gem
11
11
  - ..:/local
12
12
  - bundle-cache:/usr/local/bundle:delegated
13
- environment:
14
- REDIS_URL: redis://redis
15
- links:
16
- - redis
17
- redis:
18
- image: redis
19
- expose:
20
- - 6379
13
+
21
14
  volumes:
22
15
  bundle-cache:
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class JsonSchematize::Base
4
- def self.acceptable_types
5
- raise NoMethodError, "Expected acceptable_values to be defined in parent class"
3
+ module JsonSchematize
4
+ class Base
5
+ def self.acceptable_types
6
+ raise NoMethodError, "Expected acceptable_values to be defined in parent class"
7
+ end
6
8
  end
7
9
  end
@@ -2,18 +2,20 @@
2
2
 
3
3
  require "json_schematize/base"
4
4
 
5
- class JsonSchematize::Boolean < JsonSchematize::Base
6
- FALSE_VALUES = ["false", "f", "0", false]
7
- TRUE_VALUES = ["true", "t", "1", true]
5
+ module JsonSchematize
6
+ class Boolean < JsonSchematize::Base
7
+ FALSE_VALUES = ["false", "f", "0", false]
8
+ TRUE_VALUES = ["true", "t", "1", true]
8
9
 
9
- def self.new(val)
10
- return false if FALSE_VALUES.include?(val)
11
- return true if TRUE_VALUES.include?(val)
10
+ def self.new(val)
11
+ return false if FALSE_VALUES.include?(val)
12
+ return true if TRUE_VALUES.include?(val)
12
13
 
13
- raise JsonSchematize::UndefinedBoolean, "#{val} is not a valid #{self.class}"
14
- end
14
+ raise JsonSchematize::UndefinedBoolean, "#{val} is not a valid #{self.class}"
15
+ end
15
16
 
16
- def self.acceptable_types
17
- [TrueClass, FalseClass]
17
+ def self.acceptable_types
18
+ [TrueClass, FalseClass]
19
+ end
18
20
  end
19
21
  end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JsonSchematize::Cache::ClassMethods
4
+ module Client
5
+
6
+ def __deserialize_keys__(key_hash_bytes)
7
+ return [{}, 0] if key_hash_bytes.nil?
8
+
9
+ min_expire = Time.now.to_i
10
+ key_hash = Marshal.load(key_hash_bytes)
11
+ keys_removed = 0
12
+ key_hash.each do |key, expire|
13
+ next if expire.to_i > min_expire
14
+
15
+ key_hash.delete(key)
16
+ keys_removed += 1
17
+ end
18
+
19
+ [key_hash, keys_removed]
20
+ rescue StandardError => e
21
+ ::Kernel.warn("Yikes!! Failed to parse. Returning empty. #{e.message}")
22
+ [{}, 0]
23
+ end
24
+
25
+ def __update_record_keeper__!(expire:, cache_key:, delete_key: false)
26
+ record_of_truth = cached_keys(with_expire: true)
27
+ if delete_key
28
+ record_of_truth.delete(cache_key)
29
+ else
30
+ record_of_truth[cache_key] = expire
31
+ end
32
+ serialized_string = Marshal.dump(record_of_truth)
33
+
34
+ cache_client.write(cache_namespace, serialized_string)
35
+ end
36
+
37
+ def __delete_record__!(key)
38
+ __update_record_keeper__!(expire: nil, cache_key: key, delete_key: true)
39
+ end
40
+
41
+ def cached_keys(with_expire: false, count_removed: false)
42
+ raw_string = cache_client.read(cache_namespace)
43
+ key_hash, keys_removed = __deserialize_keys__(raw_string)
44
+ return key_hash if with_expire
45
+ return keys_removed if count_removed
46
+
47
+ key_hash.keys
48
+ end
49
+
50
+ def cached_items(key_includes: nil)
51
+ clear_unscored_items! if rand > cache_configuration[:stochastic_cache_bust]
52
+
53
+ cached_keys.map do |key|
54
+ if key_includes
55
+ next unless key.include?(key_includes)
56
+ end
57
+
58
+ serialized_string = cache_client.read(key)
59
+ Marshal.load(serialized_string)
60
+ end.compact
61
+ end
62
+
63
+ def clear_cache!
64
+ cache_client.delete_multi(([cache_namespace] + cached_keys))
65
+ end
66
+
67
+ def clear_unscored_items!
68
+ cached_keys(count_removed: true)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JsonSchematize::Cache::ClassMethods
4
+ module Configuration
5
+ def cache_options(key: nil, cache_client: nil, cache_namespace: nil, ttl: nil, update_on_change: nil, stochastic_cache_bust: nil)
6
+ cache_configuration[:key] = key if key
7
+ cache_configuration[:ttl] = ttl if ttl
8
+ cache_configuration[:stochastic_cache_bust] = stochastic_cache_bust if stochastic_cache_bust
9
+ cache_configuration[:update_on_change] = update_on_change if update_on_change
10
+ cache_namespace = cache_configuration[:cache_namespace] = cache_namespace if cache_namespace
11
+
12
+ self.cache_client = cache_configuration[:cache_client] = cache_client if cache_client
13
+ end
14
+
15
+ def cache_namespace
16
+ cache_configuration[:cache_namespace] ||= "jss:#{self.name.downcase}"
17
+ end
18
+
19
+ def cache_namespace=(namespace)
20
+ cache_configuration[:cache_namespace] = namespace
21
+ end
22
+
23
+ def cache_configuration
24
+ @cache_configuration ||= begin
25
+ {
26
+ cache_client: JsonSchematize.configuration.cache_client,
27
+ cache_namespace: JsonSchematize.configuration.cache_namespace,
28
+ key: JsonSchematize.configuration.cache_key,
29
+ stochastic_cache_bust: JsonSchematize.configuration.cache_stochastic_bust,
30
+ ttl: JsonSchematize.configuration.cache_ttl,
31
+ update_on_change: JsonSchematize.configuration.cache_update_on_change,
32
+ }
33
+ end
34
+ end
35
+
36
+ def cache_client=(client)
37
+ cache_configuration[:cache_client] = client
38
+ end
39
+
40
+ def cache_client
41
+ cache_configuration[:cache_client].is_a?(Proc) ? cache_configuration[:cache_client].call : cache_configuration[:cache_client]
42
+ end
43
+ end
44
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JsonSchematize
2
4
  module Cache
3
5
  module InstanceMethods
@@ -12,16 +14,17 @@ module JsonSchematize
12
14
 
13
15
  def __update_cache_item__(with_delete: true)
14
16
  __clear_entry__! if with_delete # needs to get done first in the event the cache_key changes
15
- client = self.class.redis_client
17
+ client = self.class.cache_client
16
18
  ttl = self.class.cache_configuration[:ttl].to_i
17
19
  score = Time.now.to_i + ttl
18
- client.zadd(__cache_namespace__, score, __cache_key__)
19
- client.set(__cache_key__, Marshal.dump(self), ex: ttl)
20
+ self.class.__update_record_keeper__!(expire: score, cache_key: __cache_key__)
21
+
22
+ client.write(__cache_key__, Marshal.dump(self), expires_in: ttl)
20
23
  end
21
24
 
22
25
  def __clear_entry__!
23
- self.class.redis_client.zrem(__cache_namespace__, __cache_key__)
24
- self.class.redis_client.unlink(__cache_key__)
26
+ self.class.cache_client.delete(__cache_key__)
27
+ self.class.__delete_record__!(__cache_key__)
25
28
  end
26
29
 
27
30
  def __cache_key__
@@ -1,15 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "json_schematize/cache/instance_methods"
4
- require "json_schematize/cache/class_methods"
4
+ require "json_schematize/cache/class_methods/client"
5
+ require "json_schematize/cache/class_methods/configuration"
5
6
 
6
7
  module JsonSchematize
7
8
  module Cache
8
- def self.included(base)
9
- raise StandardError, "Yikes! JsonSchematize::Cache Needs Redis to work. Include it as a gem" unless defined?(Redis)
9
+ module ClassMethods; end
10
10
 
11
+ def self.included(base)
11
12
  base.include(JsonSchematize::Cache::InstanceMethods)
12
- base.extend(JsonSchematize::Cache::ClassMethods)
13
+ base.extend(JsonSchematize::Cache::ClassMethods::Client)
14
+ base.extend(JsonSchematize::Cache::ClassMethods::Configuration)
13
15
  end
14
16
  end
15
17
  end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JsonSchematize
4
+ class Configuration
5
+ DEFAULT_ONE_MIN = 60 * 60
6
+ DEFAULT_ONE_HOUR = DEFAULT_ONE_MIN * 60
7
+ DEFAULT_ONE_DAY = DEFAULT_ONE_HOUR * 24
8
+ DEFAULT_CACHE_OPTIONS = {
9
+ cache_client: nil,
10
+ cache_key: ->(val, _custom_key) { val.hash },
11
+ cache_namespace: nil,
12
+ cache_stochastic_bust: 0.8,
13
+ cache_ttl: DEFAULT_ONE_DAY,
14
+ cache_update_on_change: true,
15
+ }
16
+
17
+ attr_accessor *DEFAULT_CACHE_OPTIONS.keys
18
+
19
+ def initialize
20
+ @cache_client = DEFAULT_CACHE_OPTIONS[:cache_client]
21
+ @cache_key = DEFAULT_CACHE_OPTIONS[:cache_key]
22
+ @cache_namespace = DEFAULT_CACHE_OPTIONS[:cache_namespace]
23
+ @cache_stochastic_bust = DEFAULT_CACHE_OPTIONS[:cache_stochastic_bust]
24
+ @cache_ttl = DEFAULT_CACHE_OPTIONS[:cache_ttl]
25
+ @cache_update_on_change = DEFAULT_CACHE_OPTIONS[:cache_update_on_change]
26
+ end
27
+
28
+ def cache_hash
29
+ DEFAULT_CACHE_OPTIONS.map do |key, value|
30
+ val = public_send(key)
31
+ [key, val]
32
+ end.to_h
33
+ end
34
+
35
+ def cache_key=(value)
36
+ if value.is_a? Proc
37
+ @key = value
38
+ return @key
39
+ end
40
+
41
+ assign = _assign_msg_("cache_key", "->(val, cusom_key) { val.hash }", "Default proc to assign cache key")
42
+ msg = "cache_key must be a proc. \n#{assign}"
43
+ raise JsonSchematize::ConfigError, msg
44
+ end
45
+
46
+ def cache_client=(client)
47
+ min_required = [:read, :write, :delete_multi, :read_multi]
48
+ min_required.each do |meth|
49
+ next if client.methods.include?(meth)
50
+
51
+ assign = _assign_msg_("cache_client", "_initialized_client_", "Preferably an ActiveSupport::Cache::Store supported client")
52
+ msg = "Passed in client does not accept minimum values. #{min_required} are required methods \n#{assign}"
53
+ raise JsonSchematize::ConfigError, msg
54
+ end
55
+
56
+
57
+ @cache_client = client
58
+ end
59
+
60
+ def cache_client
61
+ return @cache_client unless @cache_client.nil?
62
+
63
+ begin
64
+ Kernel.require 'active_support'
65
+ rescue LoadError
66
+ assign = _assign_msg_("cache_client", "ActiveSupport::Cache::MemoryStore.new", "A ActiveSupport::Cache::Store supported client")
67
+ msg = "Default client missing. Attempted to use 'active_support/cache' but not loaded. \n#{assign}"
68
+ raise JsonSchematize::ConfigError, msg
69
+ end
70
+
71
+ @cache_client = ActiveSupport::Cache::MemoryStore.new
72
+ @cache_client
73
+ end
74
+
75
+ private
76
+
77
+ def _assign_msg_(key, assignment, comment)
78
+ config = " config.#{key} = #{assignment} # #{comment}"
79
+ "\n\n# Initializer for json_schematize\n" \
80
+ "JsonSchematize.configure do |config|\n" \
81
+ "#{config}\n" \
82
+ "end\n\n"
83
+ end
84
+ end
85
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JsonSchematize
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.0"
5
5
  end
@@ -1,13 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "json_schematize/version"
4
+
3
5
  require "json_schematize/base"
4
6
  require "json_schematize/boolean"
5
- require "json_schematize/generator"
7
+ require "json_schematize/configuration"
6
8
  require "json_schematize/empty_value"
9
+ require "json_schematize/generator"
7
10
  require "json_schematize/version"
8
11
 
9
12
  module JsonSchematize
10
13
  class Error < StandardError; end
14
+ class ConfigError < StandardError; end
11
15
  class FieldError < Error; end
12
16
  class InvalidField < Error; end
13
17
  class InvalidFieldByValidator < InvalidField; end
@@ -16,4 +20,22 @@ module JsonSchematize
16
20
 
17
21
  ## Customized class errors
18
22
  class UndefinedBoolean < Error; end
23
+
24
+ def self.configure
25
+ yield configuration if block_given?
26
+ end
27
+
28
+ def self.configuration
29
+ @configuration ||= JsonSchematize::Configuration.new
30
+ end
31
+
32
+ def self.configuration=(object)
33
+ raise ConfigError, "Expected configuration to be a JsonSchematize::Configuration" unless object.is_a?(JsonSchematize::Configuration)
34
+
35
+ @configuration = object
36
+ end
37
+
38
+ def self.cache_client
39
+ configuration.cache_client
40
+ end
19
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json_schematize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Taylor
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-02 00:00:00.000000000 Z
11
+ date: 2022-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry-byebug
@@ -82,6 +82,7 @@ files:
82
82
  - Dockerfile
83
83
  - Gemfile
84
84
  - Gemfile.lock
85
+ - LICENSE
85
86
  - Makefile
86
87
  - README.md
87
88
  - bin/console
@@ -91,8 +92,10 @@ files:
91
92
  - lib/json_schematize/base.rb
92
93
  - lib/json_schematize/boolean.rb
93
94
  - lib/json_schematize/cache.rb
94
- - lib/json_schematize/cache/class_methods.rb
95
+ - lib/json_schematize/cache/class_methods/client.rb
96
+ - lib/json_schematize/cache/class_methods/configuration.rb
95
97
  - lib/json_schematize/cache/instance_methods.rb
98
+ - lib/json_schematize/configuration.rb
96
99
  - lib/json_schematize/empty_value.rb
97
100
  - lib/json_schematize/field.rb
98
101
  - lib/json_schematize/field_transformations.rb
@@ -121,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
124
  - !ruby/object:Gem::Version
122
125
  version: '0'
123
126
  requirements: []
124
- rubygems_version: 3.2.3
127
+ rubygems_version: 3.3.11
125
128
  signing_key:
126
129
  specification_version: 4
127
130
  summary: This gem gives you the ability to turn API results into a standardized schema's
@@ -1,81 +0,0 @@
1
- module JsonSchematize
2
- module Cache
3
- module ClassMethods
4
- DEFAULT_ONE_MIN = 60 * 60
5
- DEFAULT_ONE_HOUR = DEFAULT_ONE_MIN * 60
6
- DEFAULT_ONE_DAY = DEFAULT_ONE_HOUR * 24
7
- DEFAULT_URL = ENV["CACHE_LAYER_REDIS_URL"] || ENV["REDIS_URL"]
8
- DEFAULTS = {
9
- redis_url: DEFAULT_URL,
10
- ttl: DEFAULT_ONE_DAY,
11
- key: ->(val, _custom_key) { val.hash },
12
- update_on_change: true,
13
- redis_client: ->() { ::Redis.new(url: DEFAULT_URL) },
14
- stochastic_cache_bust: 0.8,
15
- }
16
-
17
- def cache_options(key: nil, redis_url: nil, redis_client: nil, cache_namespace: nil, ttl: nil, update_on_change: nil, stochastic_cache_bust: nil)
18
- cache_configuration[:key] = key if key
19
- cache_configuration[:ttl] = ttl if ttl
20
- cache_configuration[:stochastic_cache_bust] = stochastic_cache_bust if stochastic_cache_bust
21
- cache_configuration[:update_on_change] = update_on_change if update_on_change
22
- cache_namespace = cache_configuration[:cache_namespace] = cache_namespace if cache_namespace
23
-
24
- self.redis_client = cache_configuration[:redis_client] = redis_client if redis_client
25
- self.redis_url = cache_configuration[:redis_url] = redis_url if redis_url
26
- end
27
-
28
- def cache_namespace
29
- cache_configuration[:cache_namespace] ||= "jss:#{self.name.downcase}"
30
- end
31
-
32
- def cache_namespace=(namespace)
33
- cache_configuration[:cache_namespace] = namespace
34
- end
35
-
36
- def cache_configuration
37
- @cache_configuration ||= DEFAULTS.clone
38
- end
39
-
40
- def redis_client=(client)
41
- cache_configuration[:redis_client] = client
42
- end
43
-
44
- def redis_url=(url)
45
- cache_configuration[:redis_url] = url
46
- cache_configuration[:redis_client] = ::Redis.new(url: url)
47
- end
48
-
49
- def redis_client
50
- cache_configuration[:redis_client].is_a?(Proc) ? cache_configuration[:redis_client].call : cache_configuration[:redis_client]
51
- end
52
-
53
- def cached_keys
54
- max_length = Time.now.to_i + cache_configuration[:ttl].to_i + 10
55
- redis_client.zrangebyscore(cache_namespace, Time.now.to_i, "+inf")
56
- end
57
-
58
- def cached_items(key_includes: nil)
59
- clear_unscored_items! if rand > cache_configuration[:stochastic_cache_bust]
60
-
61
- cached_keys.map do |key|
62
- if key_includes
63
- next unless key.include?(key_includes)
64
- end
65
-
66
- serialized_string = redis_client.get(key)
67
- Marshal.load(serialized_string)
68
- end
69
- end
70
-
71
- def clear_cache!
72
- redis_client.unlink(*cached_keys) if cached_keys.length > 0
73
- redis_client.unlink(cache_namespace)
74
- end
75
-
76
- def clear_unscored_items!
77
- redis_client.zremrangebyscore(cache_namespace, "-inf", Time.now.to_i)
78
- end
79
- end
80
- end
81
- end