nobrainer 0.40.0 → 0.42.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 +4 -4
- data/CHANGELOG.md +20 -1
- data/lib/no_brainer/criteria/where.rb +35 -2
- data/lib/no_brainer/document/store.rb +304 -0
- data/lib/no_brainer/document.rb +1 -1
- data/lib/no_brainer/query_runner/table_on_demand.rb +7 -6
- data/lib/nobrainer.rb +4 -0
- metadata +12 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69052877b8fd9f2684f63a0bc7a917812fd771f793d55e7f5182149fc1346643
|
4
|
+
data.tar.gz: 33dbe632e862a31bb4ac95ab8015834947bd1207df3bbdfb921b742274d06517
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 102682b8e844b1fd574b3d29f386923bb4dfaee33e88e7da6c5615b4901d20023267cbd4e698bec34a94b77718ca04f251f8aebdfd8f74ef5837c637931dd206
|
7
|
+
data.tar.gz: 3cb7abcc47fd15d71abac788e7c5844229d30f532c01000d177d7c5b718848b48d2150cda32a1725ed7d0b68adbb775f4461805d9c2f4768104ba1320eb95d52
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
|
10
|
+
## [0.42.0] - 2022-06-15
|
11
|
+
### Added
|
12
|
+
- Add support for partial compound index queries
|
13
|
+
|
14
|
+
## [0.41.1] - 2022-03-21
|
15
|
+
### Fixed
|
16
|
+
- Removing table_config duplicates after a runtime exception (caspiano)
|
17
|
+
|
18
|
+
## [0.41.0] - 2021-10-17
|
19
|
+
### Added
|
20
|
+
- ActiveRecord `store_accessor` helper method
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
- gemspec dependencies on activemodel and activesupport
|
24
|
+
|
9
25
|
## [0.40.0] - 2021-10-16
|
10
26
|
### Fixed
|
11
27
|
- Ruby 3 compatibility
|
@@ -108,7 +124,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
108
124
|
- Locks: bug fix: allow small timeouts in lock()
|
109
125
|
- Fix reentrant lock counter on steals
|
110
126
|
|
111
|
-
[Unreleased]: https://github.com/nobrainerorm/nobrainer/compare/v0.
|
127
|
+
[Unreleased]: https://github.com/nobrainerorm/nobrainer/compare/v0.42.0...HEAD
|
128
|
+
[0.41.1]: https://github.com/nobrainerorm/nobrainer/compare/v0.41.1...v0.42.0
|
129
|
+
[0.41.1]: https://github.com/nobrainerorm/nobrainer/compare/v0.41.0...v0.41.1
|
130
|
+
[0.41.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.40.0...v0.41.0
|
112
131
|
[0.40.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.36.0...v0.40.0
|
113
132
|
[0.36.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.35.0...v0.36.0
|
114
133
|
[0.35.0]: https://github.com/nobrainerorm/nobrainer/compare/v0.34.1...v0.35.0
|
@@ -399,12 +399,45 @@ module NoBrainer::Criteria::Where
|
|
399
399
|
get_usable_indexes(:kind => :compound, :geo => false, :multi => false).each do |index|
|
400
400
|
indexed_clauses = index.what.map { |field| clauses[[field]] }
|
401
401
|
next unless indexed_clauses.all? { |c| c.try(:compatible_with_index?, index) }
|
402
|
-
|
403
402
|
return IndexStrategy.new(self, ast, indexed_clauses, index, :get_all, [indexed_clauses.map(&:value)])
|
404
403
|
end
|
405
404
|
return nil
|
406
405
|
end
|
407
406
|
|
407
|
+
def find_strategy_compound_partial
|
408
|
+
clauses = get_candidate_clauses(:eq, :between).map { |c| [c.key_path, c] }.to_h
|
409
|
+
return nil unless clauses.present?
|
410
|
+
|
411
|
+
get_usable_indexes(:kind => :compound, :geo => false, :multi => false).each do |index|
|
412
|
+
indexed_clauses = index.what.map { |field| clauses[[field]] }
|
413
|
+
partial_clauses = indexed_clauses.compact
|
414
|
+
pad = indexed_clauses.length - partial_clauses.length
|
415
|
+
if partial_clauses.any? && partial_clauses.all? { |c| c.try(:compatible_with_index?, index) }
|
416
|
+
# can only use partial compound index if:
|
417
|
+
# * index contains all clause fields
|
418
|
+
next unless (clauses.values & partial_clauses) == clauses.values
|
419
|
+
# * all clause fields come first in the indexed clauses (unused indexed fields are at the end)
|
420
|
+
next unless indexed_clauses.last(pad).all?(&:nil?)
|
421
|
+
# * all clause fields are :eq, except the last (which may be :between)
|
422
|
+
next unless partial_clauses[0..-2].all? { |c| c.op == :eq }
|
423
|
+
|
424
|
+
# use range query to cover unused index fields
|
425
|
+
left_bound = partial_clauses.map(&:value)
|
426
|
+
right_bound = partial_clauses.map(&:value)
|
427
|
+
if (clause = partial_clauses[-1]).op == :between
|
428
|
+
left_bound[-1] = clause.value.min
|
429
|
+
right_bound[-1] = clause.value.max
|
430
|
+
end
|
431
|
+
if pad > 0
|
432
|
+
left_bound.append *Array.new(pad, RethinkDB::RQL.new.minval)
|
433
|
+
right_bound.append *Array.new(pad, RethinkDB::RQL.new.maxval)
|
434
|
+
end
|
435
|
+
return IndexStrategy.new(self, ast, partial_clauses, index, :between, [left_bound, right_bound], :left_bound => :closed, :right_bound => :closed)
|
436
|
+
end
|
437
|
+
end
|
438
|
+
nil
|
439
|
+
end
|
440
|
+
|
408
441
|
def find_strategy_hidden_between
|
409
442
|
clauses = get_candidate_clauses(:gt, :ge, :lt, :le).group_by(&:key_path)
|
410
443
|
return nil unless clauses.present?
|
@@ -454,7 +487,7 @@ module NoBrainer::Criteria::Where
|
|
454
487
|
def find_strategy
|
455
488
|
return nil unless ast.try(:clauses).present? && !criteria.without_index?
|
456
489
|
case ast.op
|
457
|
-
when :and then find_strategy_compound || find_strategy_canonical || find_strategy_hidden_between
|
490
|
+
when :and then find_strategy_compound || find_strategy_compound_partial || find_strategy_canonical || find_strategy_hidden_between
|
458
491
|
when :or then find_strategy_union
|
459
492
|
end
|
460
493
|
end
|
@@ -0,0 +1,304 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
4
|
+
|
5
|
+
module NoBrainer
|
6
|
+
module Document
|
7
|
+
# Store gives you a way for storing hashes in a single field with accessors
|
8
|
+
# to the Hash keys.
|
9
|
+
# It is a portage of the ActiveRecord::Store which make gems using it
|
10
|
+
# compatible with NoBrainer.
|
11
|
+
#
|
12
|
+
# You can then declare accessors to this store that are then accessible just
|
13
|
+
# like any other attribute of the model. This is very helpful for easily
|
14
|
+
# exposing store keys to a form or elsewhere that's already built around
|
15
|
+
# just accessing attributes on the model.
|
16
|
+
#
|
17
|
+
# Every accessor comes with dirty tracking methods (+key_changed?+,
|
18
|
+
# +key_was+ and +key_change+).
|
19
|
+
#
|
20
|
+
# You can set custom coder to encode/decode your serialized attributes
|
21
|
+
# to/from different formats.
|
22
|
+
# JSON, YAML, Marshal are supported out of the box.
|
23
|
+
# Generally it can be any wrapper that provides +load+ and +dump+.
|
24
|
+
#
|
25
|
+
# NOTE: The {.store}[rdoc-ref:rdoc-ref:ClassMethods#store] method is here
|
26
|
+
# for compatibility reason, but you should use
|
27
|
+
# {.store_accessor}[rdoc-ref:ClassMethods#store_accessor] instead
|
28
|
+
# to generate the accessor methods.
|
29
|
+
# Be aware that these columns use a string keyed hash and do not allow
|
30
|
+
# access using a symbol.
|
31
|
+
#
|
32
|
+
# NOTE: The default validations with the exception of +uniqueness+ will work.
|
33
|
+
#
|
34
|
+
# Examples:
|
35
|
+
#
|
36
|
+
# class User
|
37
|
+
# include NoBrainer::Document
|
38
|
+
#
|
39
|
+
# store :settings, accessors: [ :color, :homepage ], coder: JSON
|
40
|
+
# store :parent, accessors: [ :name ], coder: JSON, prefix: true
|
41
|
+
# store :spouse, accessors: [ :name ], coder: JSON, prefix: :partner
|
42
|
+
# store :settings, accessors: [ :two_factor_auth ], suffix: true
|
43
|
+
# store :settings, accessors: [ :login_retry ], suffix: :config
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# u = User.new(color: 'black', homepage: '37signals.com',
|
47
|
+
# parent_name: 'Mary', partner_name: 'Lily')
|
48
|
+
# u.color # Accessor stored attribute
|
49
|
+
# u.parent_name # Accessor stored attribute with prefix
|
50
|
+
# u.partner_name # Accessor stored attribute with custom prefix
|
51
|
+
# u.two_factor_auth_settings # Accessor stored attribute with suffix
|
52
|
+
# u.login_retry_config # Accessor stored attribute with custom suffix
|
53
|
+
# u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
|
54
|
+
#
|
55
|
+
# # There is no difference between strings and symbols for accessing
|
56
|
+
# # custom attributes
|
57
|
+
# u.settings[:country] # => 'Denmark'
|
58
|
+
# u.settings['country'] # => 'Denmark'
|
59
|
+
#
|
60
|
+
# # Dirty tracking
|
61
|
+
# u.color = 'green'
|
62
|
+
# u.color_changed? # => true
|
63
|
+
# u.color_was # => 'black'
|
64
|
+
# u.color_change # => ['black', 'red']
|
65
|
+
#
|
66
|
+
# # Add additional accessors to an existing store through store_accessor
|
67
|
+
# class SuperUser < User
|
68
|
+
# store_accessor :settings, :privileges, :servants
|
69
|
+
# store_accessor :parent, :birthday, prefix: true
|
70
|
+
# store_accessor :settings, :secret_question, suffix: :config
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# The stored attribute names can be retrieved using
|
74
|
+
# {.stored_attributes}[rdoc-ref:rdoc-ref:ClassMethods#stored_attributes].
|
75
|
+
#
|
76
|
+
# User.stored_attributes[:settings]
|
77
|
+
# #=> [:color, :homepage, :two_factor_auth, :login_retry]
|
78
|
+
#
|
79
|
+
# == Overwriting default accessors
|
80
|
+
#
|
81
|
+
# All stored values are automatically available through accessors on
|
82
|
+
# the NoBrainer Document object, but sometimes you want to specialize
|
83
|
+
# this behavior. This can be done by overwriting the default accessors
|
84
|
+
# (using the same name as the attribute) and calling <tt>super</tt>
|
85
|
+
# to actually change things.
|
86
|
+
#
|
87
|
+
# class Song
|
88
|
+
# include NoBrainer::Document
|
89
|
+
#
|
90
|
+
# # Uses a stored integer to hold the volume adjustment of the song
|
91
|
+
# store :settings, accessors: [:volume_adjustment]
|
92
|
+
#
|
93
|
+
# def volume_adjustment=(decibels)
|
94
|
+
# super(decibels.to_i)
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# def volume_adjustment
|
98
|
+
# super.to_i
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
module Store
|
102
|
+
extend ActiveSupport::Concern
|
103
|
+
|
104
|
+
included do
|
105
|
+
class << self
|
106
|
+
attr_accessor :local_stored_attributes
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
module ClassMethods
|
111
|
+
def store(store_attribute, options = {})
|
112
|
+
store_accessor(store_attribute, options[:accessors], **options.slice(:prefix, :suffix)) if options.has_key? :accessors
|
113
|
+
end
|
114
|
+
|
115
|
+
def store_accessor(store_attribute, *keys, prefix: nil, suffix: nil)
|
116
|
+
keys = keys.flatten
|
117
|
+
|
118
|
+
accessor_prefix =
|
119
|
+
case prefix
|
120
|
+
when String, Symbol
|
121
|
+
"#{prefix}_"
|
122
|
+
when TrueClass
|
123
|
+
"#{store_attribute}_"
|
124
|
+
else
|
125
|
+
""
|
126
|
+
end
|
127
|
+
accessor_suffix =
|
128
|
+
case suffix
|
129
|
+
when String, Symbol
|
130
|
+
"_#{suffix}"
|
131
|
+
when TrueClass
|
132
|
+
"_#{store_attribute}"
|
133
|
+
else
|
134
|
+
""
|
135
|
+
end
|
136
|
+
|
137
|
+
field store_attribute, type: Hash, default: {} unless has_field?(store_attribute)
|
138
|
+
|
139
|
+
define_method("#{store_attribute}=") do |value|
|
140
|
+
super(value) if value.is_a?(Hash) || value.nil?
|
141
|
+
end
|
142
|
+
|
143
|
+
_store_accessors_module.module_eval do
|
144
|
+
keys.each do |key|
|
145
|
+
accessor_key = "#{accessor_prefix}#{key}#{accessor_suffix}"
|
146
|
+
|
147
|
+
define_method("#{accessor_key}=") do |value|
|
148
|
+
write_store_attribute(store_attribute, key, value)
|
149
|
+
end
|
150
|
+
|
151
|
+
define_method(accessor_key) do
|
152
|
+
read_store_attribute(store_attribute, key)
|
153
|
+
end
|
154
|
+
|
155
|
+
define_method("#{accessor_key}_changed?") do
|
156
|
+
return false unless __send__("#{store_attribute}_changed?")
|
157
|
+
prev_store, new_store = changes[store_attribute]
|
158
|
+
if NoBrainer.rails4?
|
159
|
+
(prev_store && prev_store[key.to_s]) != (new_store && new_store[key.to_s])
|
160
|
+
else
|
161
|
+
(prev_store && prev_store.dig(key)) != (new_store && new_store.dig(key))
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
define_method("#{accessor_key}_change") do
|
166
|
+
return unless __send__("#{store_attribute}_changed?")
|
167
|
+
prev_store, new_store = changes[store_attribute]
|
168
|
+
if NoBrainer.rails4?
|
169
|
+
[(prev_store && prev_store[key.to_s]), (new_store && new_store[key.to_s])]
|
170
|
+
else
|
171
|
+
[(prev_store && prev_store.dig(key)), (new_store && new_store.dig(key))]
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
define_method("#{accessor_key}_was") do
|
176
|
+
return unless __send__("#{store_attribute}_changed?")
|
177
|
+
prev_store, _new_store = changes[store_attribute]
|
178
|
+
if NoBrainer.rails4?
|
179
|
+
(prev_store && prev_store[key.to_s])
|
180
|
+
else
|
181
|
+
(prev_store && prev_store.dig(key))
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# NoBrainer doesn't have `attribute_will_change!` so those methods
|
186
|
+
# can't be implemented yet.
|
187
|
+
# See https://github.com/NoBrainerORM/nobrainer/pull/190
|
188
|
+
#
|
189
|
+
# define_method("saved_change_to_#{accessor_key}?") do
|
190
|
+
# return false unless __send__("saved_change_to_#{store_attribute}?")
|
191
|
+
# prev_store, new_store = __send__("saved_change_to_#{store_attribute}")
|
192
|
+
# prev_store&.dig(key) != new_store&.dig(key)
|
193
|
+
# end
|
194
|
+
|
195
|
+
# define_method("saved_change_to_#{accessor_key}") do
|
196
|
+
# return unless __send__("saved_change_to_#{store_attribute}?")
|
197
|
+
# prev_store, new_store = __send__("saved_change_to_#{store_attribute}")
|
198
|
+
# [prev_store&.dig(key), new_store&.dig(key)]
|
199
|
+
# end
|
200
|
+
|
201
|
+
# define_method("#{accessor_key}_before_last_save") do
|
202
|
+
# return unless __send__("saved_change_to_#{store_attribute}?")
|
203
|
+
# prev_store, _new_store = __send__("saved_change_to_#{store_attribute}")
|
204
|
+
# prev_store&.dig(key)
|
205
|
+
# end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
# assign new store attribute and create new hash to ensure that each class in the hierarchy
|
210
|
+
# has its own hash of stored attributes.
|
211
|
+
self.local_stored_attributes ||= {}
|
212
|
+
self.local_stored_attributes[store_attribute] ||= []
|
213
|
+
self.local_stored_attributes[store_attribute] |= keys
|
214
|
+
end
|
215
|
+
|
216
|
+
def _store_accessors_module # :nodoc:
|
217
|
+
@_store_accessors_module ||= begin
|
218
|
+
mod = Module.new
|
219
|
+
include mod
|
220
|
+
mod
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def stored_attributes
|
225
|
+
parent = superclass.respond_to?(:stored_attributes) ? superclass.stored_attributes : {}
|
226
|
+
if local_stored_attributes
|
227
|
+
parent.merge!(local_stored_attributes) { |k, a, b| a | b }
|
228
|
+
end
|
229
|
+
parent
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
private
|
234
|
+
|
235
|
+
def read_store_attribute(store_attribute, key) # :doc:
|
236
|
+
StringKeyedHashAccessor.read(self, store_attribute, key)
|
237
|
+
end
|
238
|
+
|
239
|
+
def write_store_attribute(store_attribute, key, value) # :doc:
|
240
|
+
StringKeyedHashAccessor.write(self, store_attribute, key, value)
|
241
|
+
end
|
242
|
+
|
243
|
+
class HashAccessor # :nodoc:
|
244
|
+
def self.read(object, attribute, key)
|
245
|
+
prepare(object, attribute)
|
246
|
+
object.public_send(attribute)[key]
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.write(object, attribute, key, value)
|
250
|
+
prepare(object, attribute)
|
251
|
+
if value != read(object, attribute, key)
|
252
|
+
# "#{attribute}_will_change!" is not implemented in NoBrainer. See issue #190
|
253
|
+
# object.public_send :"#{attribute}_will_change!"
|
254
|
+
object.public_send(attribute)[key] = value
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def self.prepare(object, attribute)
|
259
|
+
object.public_send :"#{attribute}=", {} unless object.send(attribute)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
class StringKeyedHashAccessor < HashAccessor # :nodoc:
|
264
|
+
def self.read(object, attribute, key)
|
265
|
+
super object, attribute, key.to_s
|
266
|
+
end
|
267
|
+
|
268
|
+
def self.write(object, attribute, key, value)
|
269
|
+
super object, attribute, key.to_s, value
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
class IndifferentCoder # :nodoc:
|
274
|
+
def initialize(attr_name, coder_or_class_name)
|
275
|
+
@coder =
|
276
|
+
if coder_or_class_name.respond_to?(:load) && coder_or_class_name.respond_to?(:dump)
|
277
|
+
coder_or_class_name
|
278
|
+
else
|
279
|
+
NoBrainer::Document::Coders::YAMLColumn.new(attr_name, coder_or_class_name || Object)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
def dump(obj)
|
284
|
+
@coder.dump self.class.as_indifferent_hash(obj)
|
285
|
+
end
|
286
|
+
|
287
|
+
def load(yaml)
|
288
|
+
self.class.as_indifferent_hash(@coder.load(yaml || ""))
|
289
|
+
end
|
290
|
+
|
291
|
+
def self.as_indifferent_hash(obj)
|
292
|
+
case obj
|
293
|
+
when ActiveSupport::HashWithIndifferentAccess
|
294
|
+
obj
|
295
|
+
when Hash
|
296
|
+
obj.with_indifferent_access
|
297
|
+
else
|
298
|
+
ActiveSupport::HashWithIndifferentAccess.new
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
data/lib/no_brainer/document.rb
CHANGED
@@ -7,7 +7,7 @@ module NoBrainer::Document
|
|
7
7
|
autoload_and_include :Core, :TableConfig, :InjectionLayer, :Attributes, :Readonly,
|
8
8
|
:Persistance, :Callbacks, :Validation, :Types, :Dirty, :PrimaryKey,
|
9
9
|
:Association, :Serialization, :Criteria, :Polymorphic, :Index, :Aliases,
|
10
|
-
:MissingAttributes, :LazyFetch, :AtomicOps, :VirtualAttributes
|
10
|
+
:MissingAttributes, :LazyFetch, :AtomicOps, :VirtualAttributes, :Store
|
11
11
|
|
12
12
|
autoload :DynamicAttributes, :Timestamps
|
13
13
|
|
@@ -29,9 +29,13 @@ class NoBrainer::QueryRunner::TableOnDemand < NoBrainer::QueryRunner::Middleware
|
|
29
29
|
env[:last_auto_create_table] = [db_name, table_name]
|
30
30
|
|
31
31
|
create_options = model.table_create_options
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
begin
|
33
|
+
NoBrainer.run(:db => db_name) do |r|
|
34
|
+
r.table_create(table_name, create_options.reject { |k,_| k.in? [:name, :write_acks] })
|
35
|
+
end
|
36
|
+
rescue RuntimeError => e
|
37
|
+
# We might have raced with another table create
|
38
|
+
raise unless e.message =~ /Table `#{db_name}\.#{table_name}` already exists/
|
35
39
|
end
|
36
40
|
|
37
41
|
# Prevent duplicate table errors on a cluster.
|
@@ -49,8 +53,5 @@ class NoBrainer::QueryRunner::TableOnDemand < NoBrainer::QueryRunner::Middleware
|
|
49
53
|
r.table(table_name).config().update(:write_acks => create_options[:write_acks])
|
50
54
|
end
|
51
55
|
end
|
52
|
-
rescue RuntimeError => e
|
53
|
-
# We might have raced with another table create
|
54
|
-
raise unless e.message =~ /Table `#{db_name}\.#{table_name}` already exists/
|
55
56
|
end
|
56
57
|
end
|
data/lib/nobrainer.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nobrainer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.42.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicolas Viennot
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 4.1.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '8'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: 4.1.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '8'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
version: 4.1.0
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '8'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
version: 4.1.0
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
52
|
+
version: '8'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: middleware
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -168,6 +168,7 @@ files:
|
|
168
168
|
- lib/no_brainer/document/primary_key/generator.rb
|
169
169
|
- lib/no_brainer/document/readonly.rb
|
170
170
|
- lib/no_brainer/document/serialization.rb
|
171
|
+
- lib/no_brainer/document/store.rb
|
171
172
|
- lib/no_brainer/document/table_config.rb
|
172
173
|
- lib/no_brainer/document/table_config/synchronizer.rb
|
173
174
|
- lib/no_brainer/document/timestamps.rb
|
@@ -241,7 +242,11 @@ files:
|
|
241
242
|
homepage: http://nobrainer.io
|
242
243
|
licenses:
|
243
244
|
- LGPL-3.0-only
|
244
|
-
metadata:
|
245
|
+
metadata:
|
246
|
+
allowed_push_host: https://rubygems.org
|
247
|
+
homepage_uri: http://nobrainer.io
|
248
|
+
source_code_uri: https://github.com/NoBrainerORM/nobrainer
|
249
|
+
changelog_uri: https://github.com/NoBrainerORM/nobrainer/blob/master/CHANGELOG.md
|
245
250
|
post_install_message:
|
246
251
|
rdoc_options: []
|
247
252
|
require_paths:
|