universalid 0.1.2 → 0.1.4

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +387 -1087
  3. data/Rakefile +16 -2
  4. data/config/default.yml +1 -1
  5. data/config/example.yml +2 -2
  6. data/lib/universalid/encoder.rb +21 -0
  7. data/lib/universalid/extensions/active_record/base_message_pack_type.rb +15 -0
  8. data/lib/universalid/extensions/active_record/base_packer.rb +170 -0
  9. data/lib/universalid/extensions/active_record/base_unpacker.rb +61 -0
  10. data/lib/universalid/extensions/active_record/relation_message_pack_type.rb +20 -0
  11. data/lib/universalid/extensions/active_support/time_with_zone_message_pack_type.rb +18 -0
  12. data/lib/universalid/extensions/global_id/global_id_model.rb +28 -0
  13. data/lib/universalid/extensions/global_id/global_id_uid_extension.rb +43 -0
  14. data/lib/universalid/extensions/global_id/message_pack_type.rb +16 -0
  15. data/lib/universalid/extensions/signed_global_id/message_pack_type.rb +12 -0
  16. data/lib/{universal_id → universalid}/message_pack_types/ruby/composites/open_struct.rb +2 -0
  17. data/lib/universalid/message_pack_types/ruby/scalars/bigdecimal.rb +10 -0
  18. data/lib/{universal_id → universalid}/message_pack_types/ruby/scalars/date.rb +2 -0
  19. data/lib/{universal_id → universalid}/message_pack_types/ruby/scalars/date_time.rb +2 -0
  20. data/lib/{universal_id → universalid}/message_pack_types.rb +3 -5
  21. data/lib/universalid/packer.rb +19 -0
  22. data/lib/{universal_id → universalid}/prepack_database_options.rb +4 -4
  23. data/lib/{universal_id → universalid}/prepack_options.rb +2 -12
  24. data/lib/{universal_id → universalid}/prepacker.rb +3 -3
  25. data/lib/{universal_id → universalid}/refinements/open_struct_refinement.rb +2 -0
  26. data/lib/universalid/refinements.rb +3 -0
  27. data/lib/{universal_id → universalid}/settings.rb +3 -2
  28. data/lib/{universal_id → universalid}/version.rb +1 -1
  29. data/lib/universalid.rb +28 -1
  30. data/lib/uri/uid.rb +17 -7
  31. metadata +128 -50
  32. data/lib/universal_id/contrib/active_record/base_message_pack_type.rb +0 -11
  33. data/lib/universal_id/contrib/active_record/base_packer.rb +0 -130
  34. data/lib/universal_id/contrib/active_record/base_unpacker.rb +0 -50
  35. data/lib/universal_id/contrib/active_record/relation_message_pack_type.rb +0 -16
  36. data/lib/universal_id/contrib/active_record.rb +0 -4
  37. data/lib/universal_id/contrib/active_support/time_with_zone_message_pack_type.rb +0 -14
  38. data/lib/universal_id/contrib/active_support.rb +0 -3
  39. data/lib/universal_id/contrib/global_id/global_id_model.rb +0 -24
  40. data/lib/universal_id/contrib/global_id/global_id_uid_extension.rb +0 -36
  41. data/lib/universal_id/contrib/global_id/message_pack_type.rb +0 -15
  42. data/lib/universal_id/contrib/global_id.rb +0 -3
  43. data/lib/universal_id/contrib/rails.rb +0 -6
  44. data/lib/universal_id/contrib/signed_global_id/message_pack_type.rb +0 -8
  45. data/lib/universal_id/contrib/signed_global_id.rb +0 -3
  46. data/lib/universal_id/encoder.rb +0 -27
  47. data/lib/universal_id/refinements.rb +0 -8
  48. data/lib/universal_id.rb +0 -29
  49. /data/lib/{universal_id → universalid}/message_pack_factory.rb +0 -0
  50. /data/lib/{universal_id → universalid}/message_pack_types/ruby/composites/module.rb +0 -0
  51. /data/lib/{universal_id → universalid}/message_pack_types/ruby/composites/set.rb +0 -0
  52. /data/lib/{universal_id → universalid}/message_pack_types/ruby/composites/struct.rb +0 -0
  53. /data/lib/{universal_id → universalid}/message_pack_types/ruby/scalars/complex.rb +0 -0
  54. /data/lib/{universal_id → universalid}/message_pack_types/ruby/scalars/range.rb +0 -0
  55. /data/lib/{universal_id → universalid}/message_pack_types/ruby/scalars/rational.rb +0 -0
  56. /data/lib/{universal_id → universalid}/message_pack_types/ruby/scalars/regexp.rb +0 -0
  57. /data/lib/{universal_id → universalid}/message_pack_types/uri/uid/type.rb +0 -0
  58. /data/lib/{universal_id → universalid}/refinements/array_refinement.rb +0 -0
  59. /data/lib/{universal_id → universalid}/refinements/hash_refinement.rb +0 -0
  60. /data/lib/{universal_id → universalid}/refinements/set_refinement.rb +0 -0
data/lib/universalid.rb CHANGED
@@ -1,3 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "universal_id"
3
+ require "active_support/all"
4
+ require "zeitwerk"
5
+
6
+ module UniversalID
7
+ module Extensions; end
8
+
9
+ class << self
10
+ attr_writer :logger
11
+
12
+ def logger
13
+ @logger ||= defined?(Rails) ? Rails.logger : Logger.new(File::NULL)
14
+ end
15
+ end
16
+ end
17
+
18
+ Zeitwerk::Loader.for_gem(warn_on_extra_files: false).tap do |loader|
19
+ loader.inflector = Zeitwerk::GemInflector.new(__dir__)
20
+ loader.ignore "#{__dir__}/universalid/**/*message_pack_type*"
21
+ loader.ignore "#{__dir__}/universalid/extensions"
22
+ loader.inflector.inflect("universalid" => "UniversalID")
23
+ loader.inflector.inflect("uri" => "URI")
24
+ loader.inflector.inflect("uid" => "UID")
25
+ loader.inflector.inflect("version" => "VERSION")
26
+ loader.setup
27
+ loader.eager_load
28
+ end
29
+
30
+ UniversalID::Settings.instance # initialize settings
data/lib/uri/uid.rb CHANGED
@@ -1,12 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "uri"
4
+
3
5
  unless defined?(::URI::UID) || ::URI.scheme_list.include?("UID")
4
6
 
5
7
  module URI
6
8
  class UID < ::URI::Generic
7
9
  VERSION = UniversalID::VERSION
8
10
  SCHEME = "uid"
9
- HOST = "universal-id"
11
+ HOST = "universalid"
10
12
 
11
13
  class << self
12
14
  def encoder
@@ -18,8 +20,13 @@ unless defined?(::URI::UID) || ::URI.scheme_list.include?("UID")
18
20
  end
19
21
 
20
22
  def parse(value)
21
- components = ::URI.split(value.to_s)
22
- new(*components)
23
+ return nil if value.nil?
24
+ return value if value.is_a?(self)
25
+
26
+ value = value.to_s
27
+ return nil if value.strip.empty?
28
+
29
+ new(*::URI.split(value))
23
30
  end
24
31
 
25
32
  def build_string(payload, object = nil)
@@ -87,10 +94,13 @@ unless defined?(::URI::UID) || ::URI.scheme_list.include?("UID")
87
94
  end
88
95
  end
89
96
 
90
- alias_method :fingerprint, :fragment
97
+ def payload
98
+ path[1..]
99
+ end
91
100
 
92
- def payload(truncate: false)
93
- (truncate && path.length > 80) ? "#{path[1..77]}..." : path[1..]
101
+ def fingerprint(decode: false)
102
+ return decode_fingerprint if decode
103
+ fragment
94
104
  end
95
105
 
96
106
  def valid?
@@ -116,7 +126,7 @@ unless defined?(::URI::UID) || ::URI.scheme_list.include?("UID")
116
126
  end
117
127
 
118
128
  def inspect
119
- "#<URI::UID scheme=#{scheme}, host=#{host}, payload=#{payload truncate: true}>"
129
+ "#<URI::UID payload=#{payload.truncate 40}, fingerprint=#{fingerprint.truncate 40}>"
120
130
  end
121
131
 
122
132
  private
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: universalid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nate Hopkins (hopsoft)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-17 00:00:00.000000000 Z
11
+ date: 2024-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.1'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: brotli
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,20 @@ dependencies:
24
38
  - - ">="
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: config
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: msgpack
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -39,19 +67,33 @@ dependencies:
39
67
  - !ruby/object:Gem::Version
40
68
  version: '1.7'
41
69
  - !ruby/object:Gem::Dependency
42
- name: config
70
+ name: zeitwerk
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - ">="
46
74
  - !ruby/object:Gem::Version
47
- version: '5.0'
75
+ version: '2.6'
48
76
  type: :runtime
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - ">="
53
81
  - !ruby/object:Gem::Version
54
- version: '5.0'
82
+ version: '2.6'
83
+ - !ruby/object:Gem::Dependency
84
+ name: actionview
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
55
97
  - !ruby/object:Gem::Dependency
56
98
  name: activerecord
57
99
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +108,20 @@ dependencies:
66
108
  - - ">="
67
109
  - !ruby/object:Gem::Version
68
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
69
125
  - !ruby/object:Gem::Dependency
70
126
  name: awesome_print
71
127
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +164,20 @@ dependencies:
108
164
  - - ">="
109
165
  - !ruby/object:Gem::Version
110
166
  version: '1.1'
167
+ - !ruby/object:Gem::Dependency
168
+ name: jbuilder
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
111
181
  - !ruby/object:Gem::Dependency
112
182
  name: magic_frozen_string_literal
113
183
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +220,20 @@ dependencies:
150
220
  - - ">="
151
221
  - !ruby/object:Gem::Version
152
222
  version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: oj
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
153
237
  - !ruby/object:Gem::Dependency
154
238
  name: pry-byebug
155
239
  requirement: !ruby/object:Gem::Requirement
@@ -249,10 +333,8 @@ dependencies:
249
333
  - !ruby/object:Gem::Version
250
334
  version: '1.32'
251
335
  description: |
252
- Universal ID is a Ruby library that specializes in the serialization of Ruby objects to URL-safe strings,
253
- employing MessagePack and Brotli for optimized encoding. It facilitates efficient data transfer and state
254
- management across various computing processes. Designed to seamlessly integrate with Ruby applications,
255
- it does not rely on Rails-specific dependencies, making it adaptable for diverse Ruby projects.
336
+ Universal ID opens the flood gates with a deluge of profoundly powerful
337
+ yet easily implemented new use-cases for your apps and scripts.
256
338
  email:
257
339
  - natehop@gmail.com
258
340
  executables: []
@@ -263,46 +345,42 @@ files:
263
345
  - Rakefile
264
346
  - config/default.yml
265
347
  - config/example.yml
266
- - lib/universal_id.rb
267
- - lib/universal_id/contrib/active_record.rb
268
- - lib/universal_id/contrib/active_record/base_message_pack_type.rb
269
- - lib/universal_id/contrib/active_record/base_packer.rb
270
- - lib/universal_id/contrib/active_record/base_unpacker.rb
271
- - lib/universal_id/contrib/active_record/relation_message_pack_type.rb
272
- - lib/universal_id/contrib/active_support.rb
273
- - lib/universal_id/contrib/active_support/time_with_zone_message_pack_type.rb
274
- - lib/universal_id/contrib/global_id.rb
275
- - lib/universal_id/contrib/global_id/global_id_model.rb
276
- - lib/universal_id/contrib/global_id/global_id_uid_extension.rb
277
- - lib/universal_id/contrib/global_id/message_pack_type.rb
278
- - lib/universal_id/contrib/rails.rb
279
- - lib/universal_id/contrib/signed_global_id.rb
280
- - lib/universal_id/contrib/signed_global_id/message_pack_type.rb
281
- - lib/universal_id/encoder.rb
282
- - lib/universal_id/message_pack_factory.rb
283
- - lib/universal_id/message_pack_types.rb
284
- - lib/universal_id/message_pack_types/ruby/composites/module.rb
285
- - lib/universal_id/message_pack_types/ruby/composites/open_struct.rb
286
- - lib/universal_id/message_pack_types/ruby/composites/set.rb
287
- - lib/universal_id/message_pack_types/ruby/composites/struct.rb
288
- - lib/universal_id/message_pack_types/ruby/scalars/complex.rb
289
- - lib/universal_id/message_pack_types/ruby/scalars/date.rb
290
- - lib/universal_id/message_pack_types/ruby/scalars/date_time.rb
291
- - lib/universal_id/message_pack_types/ruby/scalars/range.rb
292
- - lib/universal_id/message_pack_types/ruby/scalars/rational.rb
293
- - lib/universal_id/message_pack_types/ruby/scalars/regexp.rb
294
- - lib/universal_id/message_pack_types/uri/uid/type.rb
295
- - lib/universal_id/prepack_database_options.rb
296
- - lib/universal_id/prepack_options.rb
297
- - lib/universal_id/prepacker.rb
298
- - lib/universal_id/refinements.rb
299
- - lib/universal_id/refinements/array_refinement.rb
300
- - lib/universal_id/refinements/hash_refinement.rb
301
- - lib/universal_id/refinements/open_struct_refinement.rb
302
- - lib/universal_id/refinements/set_refinement.rb
303
- - lib/universal_id/settings.rb
304
- - lib/universal_id/version.rb
305
348
  - lib/universalid.rb
349
+ - lib/universalid/encoder.rb
350
+ - lib/universalid/extensions/active_record/base_message_pack_type.rb
351
+ - lib/universalid/extensions/active_record/base_packer.rb
352
+ - lib/universalid/extensions/active_record/base_unpacker.rb
353
+ - lib/universalid/extensions/active_record/relation_message_pack_type.rb
354
+ - lib/universalid/extensions/active_support/time_with_zone_message_pack_type.rb
355
+ - lib/universalid/extensions/global_id/global_id_model.rb
356
+ - lib/universalid/extensions/global_id/global_id_uid_extension.rb
357
+ - lib/universalid/extensions/global_id/message_pack_type.rb
358
+ - lib/universalid/extensions/signed_global_id/message_pack_type.rb
359
+ - lib/universalid/message_pack_factory.rb
360
+ - lib/universalid/message_pack_types.rb
361
+ - lib/universalid/message_pack_types/ruby/composites/module.rb
362
+ - lib/universalid/message_pack_types/ruby/composites/open_struct.rb
363
+ - lib/universalid/message_pack_types/ruby/composites/set.rb
364
+ - lib/universalid/message_pack_types/ruby/composites/struct.rb
365
+ - lib/universalid/message_pack_types/ruby/scalars/bigdecimal.rb
366
+ - lib/universalid/message_pack_types/ruby/scalars/complex.rb
367
+ - lib/universalid/message_pack_types/ruby/scalars/date.rb
368
+ - lib/universalid/message_pack_types/ruby/scalars/date_time.rb
369
+ - lib/universalid/message_pack_types/ruby/scalars/range.rb
370
+ - lib/universalid/message_pack_types/ruby/scalars/rational.rb
371
+ - lib/universalid/message_pack_types/ruby/scalars/regexp.rb
372
+ - lib/universalid/message_pack_types/uri/uid/type.rb
373
+ - lib/universalid/packer.rb
374
+ - lib/universalid/prepack_database_options.rb
375
+ - lib/universalid/prepack_options.rb
376
+ - lib/universalid/prepacker.rb
377
+ - lib/universalid/refinements.rb
378
+ - lib/universalid/refinements/array_refinement.rb
379
+ - lib/universalid/refinements/hash_refinement.rb
380
+ - lib/universalid/refinements/open_struct_refinement.rb
381
+ - lib/universalid/refinements/set_refinement.rb
382
+ - lib/universalid/settings.rb
383
+ - lib/universalid/version.rb
306
384
  - lib/uri/uid.rb
307
385
  homepage: https://github.com/hopsoft/universalid
308
386
  licenses:
@@ -326,8 +404,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
326
404
  - !ruby/object:Gem::Version
327
405
  version: '0'
328
406
  requirements: []
329
- rubygems_version: 3.4.15
407
+ rubygems_version: 3.2.32
330
408
  signing_key:
331
409
  specification_version: 4
332
- summary: URL-Safe String Serialization for any Ruby Object
410
+ summary: Fast, recursive, and URL-Safe serialization for any Ruby object.
333
411
  test_files: []
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "base_packer"
4
- require_relative "base_unpacker"
5
-
6
- UniversalID::MessagePackFactory.register(
7
- type: ActiveRecord::Base,
8
- recreate_pool: false,
9
- packer: ->(obj, packer) { UniversalID::Contrib::ActiveRecordBasePacker.new(obj).pack_with packer },
10
- unpacker: ->(unpacker) { UniversalID::Contrib::ActiveRecordBaseUnpacker.unpack_with unpacker }
11
- )
@@ -1,130 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class UniversalID::Contrib::ActiveRecordBasePacker
4
- using UniversalID::Refinements::HashRefinement
5
-
6
- # TODO: implement support for has_one
7
- # ActiveRecord::Reflection::HasOneReflection
8
- #
9
- # TODO: implement support for has_and_belongs_to_many
10
- # ActiveRecord::Reflection::HasAndBelongsToManyReflection
11
- #
12
- HAS_MANY_ASSOCIATIONS = [
13
- ActiveRecord::Reflection::HasManyReflection
14
- ]
15
-
16
- DESCENDANTS_KEY = "uid:descendants"
17
-
18
- attr_reader :record
19
-
20
- def initialize(record)
21
- @record = record
22
- end
23
-
24
- def pack_with(packer)
25
- packer.write record.class.name
26
- packer.write packable_attributes
27
- end
28
-
29
- def prepack_options
30
- options = record.instance_variable_get(:@_uid_prepack_options)
31
- options = UniversalID::PrepackOptions.new unless options.is_a?(UniversalID::PrepackOptions)
32
- options
33
- end
34
-
35
- def prepack_database_options
36
- prepack_options.database_options
37
- end
38
-
39
- private
40
-
41
- def packable_attributes
42
- return record.attributes.slice(record.class.primary_key) if id_only?(prepack_database_options)
43
-
44
- hash = record.attributes
45
- reject_keys! hash if prepack_database_options.exclude_keys?
46
- reject_timestamps! hash if prepack_database_options.exclude_timestamps?
47
- reject_unsaved_changes! hash if prepack_database_options.exclude_unsaved_changes?
48
- add_descendants! hash if include_descendants?
49
-
50
- hash.prepack prepack_options
51
- end
52
-
53
- # helpers ..................................................................................................
54
- def id_only?(prepack_database_options)
55
- return false if record.new_record?
56
- return false if prepack_database_options.include_descendants?
57
- prepack_database_options.exclude_unsaved_changes?
58
- end
59
-
60
- def include_descendants?
61
- return false unless prepack_database_options.include_descendants?
62
-
63
- max_depth = prepack_database_options.descendant_depth.to_i
64
- record_depth = record.instance_variable_get(:@_uid_depth).to_i
65
- record_depth < max_depth
66
- end
67
-
68
- # attribute mutators .......................................................................................
69
-
70
- def reject_keys!(hash)
71
- hash.delete record.class.primary_key
72
- foreign_key_column_names.each { |key| hash.delete key }
73
- end
74
-
75
- def reject_timestamps!(hash)
76
- timestamp_column_names.each { |key| hash.delete key }
77
- end
78
-
79
- def reject_unsaved_changes!(hash)
80
- record.changes_to_save.each do |key, (original_value, _)|
81
- hash[key] = original_value
82
- end
83
- end
84
-
85
- def add_descendants!(hash)
86
- hash[DESCENDANTS_KEY] ||= {}
87
-
88
- loaded_has_many_relations_by_name.each do |name, relation|
89
- descendants = relation.map do |descendant|
90
- descendant.instance_variable_set(:@_uid_depth, prepack_database_options.current_depth + 1)
91
- UniversalID::Encoder.encode descendant, prepack_options
92
- ensure
93
- prepack_database_options.decrement_current_depth!
94
- descendant.remove_instance_variable :@_uid_depth
95
- end
96
- hash[DESCENDANTS_KEY][name] = descendants
97
- end
98
-
99
- prepack_database_options.increment_current_depth!
100
- end
101
-
102
- # active record helpers ....................................................................................
103
-
104
- def timestamp_column_names
105
- record.class.all_timestamp_attributes_in_model
106
- end
107
-
108
- def foreign_key_column_names
109
- record.class.reflections
110
- .each_with_object([]) do |(name, reflection), memo|
111
- memo << reflection.foreign_key if reflection.macro == :belongs_to
112
- end
113
- end
114
-
115
- def associations
116
- record.class.reflect_on_all_associations
117
- end
118
-
119
- def has_many_associations
120
- associations.select { |a| HAS_MANY_ASSOCIATIONS.include? a.class }
121
- end
122
-
123
- def loaded_has_many_relations_by_name
124
- has_many_associations.each_with_object({}) do |association, memo|
125
- relation = record.public_send(association.name)
126
- next unless relation.loaded?
127
- memo[association.name] = relation
128
- end
129
- end
130
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class UniversalID::Contrib::ActiveRecordBaseUnpacker
4
- class << self
5
- def unpack_with(unpacker)
6
- class_name = unpacker.read
7
- attributes = unpacker.read || {}
8
- create_instance class_name, attributes
9
- end
10
-
11
- private
12
-
13
- def create_instance(class_name, attributes)
14
- klass = Object.const_get(class_name) if Object.const_defined?(class_name)
15
- return nil unless klass
16
-
17
- record = if attributes[klass.primary_key]
18
- klass.find_by(klass.primary_key => attributes[klass.primary_key])
19
- else
20
- klass.new
21
- end
22
-
23
- assign_attributes record, attributes
24
- assign_descendants record, attributes
25
-
26
- record
27
- end
28
-
29
- def assign_attributes(record, attributes)
30
- attributes.each do |key, value|
31
- record.public_send "#{key}=", value if record.respond_to? "#{key}="
32
- end
33
- end
34
-
35
- def assign_descendants(record, attributes)
36
- descendants = attributes[UniversalID::Contrib::ActiveRecordBasePacker::DESCENDANTS_KEY] || {}
37
- descendants.each do |name, list|
38
- next unless record.respond_to?(name) && record.respond_to?("#{name}=")
39
-
40
- models = list.map { |encoded| UniversalID::Encoder.decode encoded }
41
- models.compact!
42
- next unless models.any?
43
-
44
- # NOTE: ActiveRecord is smart enough to not re-create or re-add
45
- # existing records for has_many associations
46
- record.public_send "#{name}=", models
47
- end
48
- end
49
- end
50
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # TODO: Revisit ActiveRecord::Relation serialization strategy,
4
- # and attempt to optimize without falling back to Marshal.dump/load
5
- UniversalID::MessagePackFactory.register(
6
- type: ActiveRecord::Relation,
7
- recreate_pool: false,
8
- packer: ->(obj, packer) do
9
- # NOTE: packing a relation will reset the loaded state and internal cache of the relation
10
- # this ensures minimal payload size
11
- obj = obj.dup # clear internal cached state (loaded results, etc.)
12
- obj.reset # dup should clear any internal caching, but we call reset just in case
13
- packer.write Marshal.dump(obj)
14
- end,
15
- unpacker: ->(unpacker) { Marshal.load unpacker.read }
16
- )
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "active_record/base_message_pack_type"
4
- require_relative "active_record/relation_message_pack_type"
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- UniversalID::MessagePackFactory.register(
4
- type: ActiveSupport::TimeWithZone,
5
- packer: ->(obj, packer) do
6
- packer.write obj.iso8601(9)
7
- packer.write obj.zone
8
- end,
9
- unpacker: ->(unpacker) do
10
- time = Time.parse(unpacker.read)
11
- zone = unpacker.read
12
- ActiveSupport::TimeWithZone.new time, ActiveSupport::TimeZone[zone]
13
- end
14
- )
@@ -1,3 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "active_support/time_with_zone_message_pack_type"
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class UniversalID::Contrib::GlobalIDModel
4
- include GlobalID::Identification
5
-
6
- def self.find(value)
7
- new value
8
- end
9
-
10
- attr_reader :id, :uid
11
-
12
- def initialize(universal_id)
13
- @uid = case universal_id
14
- when URI::UID then universal_id
15
- when String
16
- case universal_id
17
- when /\A#{URI::UID::SCHEME}/o then URI::UID.parse(universal_id)
18
- else URI::UID.parse(URI::UID.build_string(universal_id, self))
19
- end
20
- end
21
-
22
- @id = @uid&.payload
23
- end
24
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module UniversalID::Contrib::GlobalIDUIDExtension
4
- extend Forwardable
5
-
6
- def self.included(mixer)
7
- mixer.extend ClassMethods
8
- end
9
-
10
- # Adds all GlobalID::Identification methods
11
- def_delegators(:to_global_id_model, *GlobalID::Identification.instance_methods(false))
12
-
13
- # Returns a UniversalID::Contrib::GlobalIDModel instance
14
- # which implements the GlobalID::Identification interface/protocol
15
- def to_global_id_model
16
- UniversalID::Contrib::GlobalIDModel.new self
17
- end
18
-
19
- module ClassMethods
20
- def from_global_id_record(gid_record)
21
- gid_record&.find&.uid
22
- end
23
-
24
- def from_global_id(gid, options = {})
25
- from_global_id_record GlobalID.parse(gid, options)
26
- end
27
-
28
- alias_method :from_gid, :from_global_id
29
-
30
- def from_signed_global_id(sgid, options = {})
31
- from_global_id_record SignedGlobalID.parse(sgid, options)
32
- end
33
-
34
- alias_method :from_sgid, :from_signed_global_id
35
- end
36
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module UniversalID::Contrib::GlobalID; end
4
-
5
- require_relative "global_id_model"
6
- require_relative "global_id_uid_extension"
7
-
8
- URI::UID.include UniversalID::Contrib::GlobalIDUIDExtension
9
-
10
- UniversalID::MessagePackFactory.register(
11
- type: GlobalID,
12
- recreate_pool: false,
13
- packer: ->(obj, packer) { packer.write obj.to_param },
14
- unpacker: ->(unpacker) { GlobalID.parse unpacker.read }
15
- )
@@ -1,3 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "global_id/message_pack_type"
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "active_record" if defined? ActiveRecord
4
- require_relative "active_support" if defined? ActiveSupport
5
- require_relative "global_id" if defined? GlobalID
6
- require_relative "signed_global_id" if defined? SignedGlobalID
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- UniversalID::MessagePackFactory.register(
4
- type: SignedGlobalID,
5
- recreate_pool: false,
6
- packer: ->(obj, packer) { packer.write obj.to_param },
7
- unpacker: ->(unpacker) { SignedGlobalID.parse unpacker.read }
8
- )