json_schematize 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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