paquito 1.0.0 → 1.0.2
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/.github/workflows/release.yml +29 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +123 -47
- data/benchmark/active-record-unpack.rb +136 -0
- data/lib/paquito/active_record_coder.rb +11 -7
- data/lib/paquito/allow_nil.rb +2 -2
- data/lib/paquito/columns_digest_cache.rb +18 -0
- data/lib/paquito/types.rb +8 -7
- data/lib/paquito/version.rb +1 -1
- data/lib/paquito.rb +8 -0
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fad6ddfce955d4ca423ba42c1243336d1601d58488413c947603cc2ef9ce2547
|
|
4
|
+
data.tar.gz: f661e9eaf55c8ebec4fb5adc922ca504ee0905a8e4f4594af416097645752887
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8107813275f0223b3e11112f3e81219b66d491182d52950c570143e9eed633cf5111732fffd06b3fc125fb01719fc326a155b0ae25f26268cd9f38fe577eeed
|
|
7
|
+
data.tar.gz: 9ff759c8efcd363a868302316b564e982b6b53d7cc465b8ecc3efdfe634d2d38e48adcf216d7b31bbc56446f1bb2d71971625e681fffd60ff101d6ea29318577
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- v[0-9]+.[0-9]+.[0-9]+
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
release:
|
|
10
|
+
if: github.repository == 'Shopify/paquito'
|
|
11
|
+
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
id-token: write
|
|
17
|
+
|
|
18
|
+
environment: release
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v6
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
|
|
25
|
+
- uses: ruby/setup-ruby@v1
|
|
26
|
+
with:
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
|
|
29
|
+
- uses: rubygems/release-gem@v1
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
4.0.2
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
# 1.0.2
|
|
4
|
+
|
|
5
|
+
* Cache columns_digest so that its only computed once per record class. (#65)
|
|
6
|
+
* Use `recursive` for custom types. (#66)
|
|
7
|
+
|
|
8
|
+
# 1.0.1
|
|
9
|
+
|
|
10
|
+
* Avoid extra allocations in columns_digest. (#62)
|
|
11
|
+
|
|
1
12
|
# 1.0.0
|
|
2
13
|
|
|
3
14
|
Both changes in this release require applications to be fully updated to the latest patch version of the gem before
|
data/Gemfile.lock
CHANGED
|
@@ -1,83 +1,108 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
paquito (1.0.
|
|
4
|
+
paquito (1.0.2)
|
|
5
5
|
msgpack (>= 1.5.2)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
activemodel (
|
|
11
|
-
activesupport (=
|
|
12
|
-
activerecord (
|
|
13
|
-
activemodel (=
|
|
14
|
-
activesupport (=
|
|
10
|
+
activemodel (8.1.3)
|
|
11
|
+
activesupport (= 8.1.3)
|
|
12
|
+
activerecord (8.1.3)
|
|
13
|
+
activemodel (= 8.1.3)
|
|
14
|
+
activesupport (= 8.1.3)
|
|
15
15
|
timeout (>= 0.4.0)
|
|
16
|
-
activesupport (
|
|
16
|
+
activesupport (8.1.3)
|
|
17
17
|
base64
|
|
18
18
|
bigdecimal
|
|
19
19
|
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
20
20
|
connection_pool (>= 2.2.5)
|
|
21
21
|
drb
|
|
22
22
|
i18n (>= 1.6, < 2)
|
|
23
|
+
json
|
|
23
24
|
logger (>= 1.4.2)
|
|
24
25
|
minitest (>= 5.1)
|
|
25
26
|
securerandom (>= 0.3)
|
|
26
27
|
tzinfo (~> 2.0, >= 2.0.5)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
uri (>= 0.13.1)
|
|
29
|
+
ast (2.4.3)
|
|
30
|
+
base64 (0.3.0)
|
|
31
|
+
benchmark-ips (2.14.0)
|
|
32
|
+
bigdecimal (4.0.1)
|
|
33
|
+
byebug (13.0.0)
|
|
34
|
+
reline (>= 0.6.0)
|
|
35
|
+
concurrent-ruby (1.3.6)
|
|
36
|
+
connection_pool (3.0.2)
|
|
37
|
+
drb (2.2.3)
|
|
38
|
+
i18n (1.14.8)
|
|
36
39
|
concurrent-ruby (~> 1.0)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
io-console (0.8.2)
|
|
41
|
+
json (2.19.3)
|
|
42
|
+
language_server-protocol (3.17.0.5)
|
|
43
|
+
lint_roller (1.1.0)
|
|
44
|
+
logger (1.7.0)
|
|
45
|
+
minitest (5.27.0)
|
|
46
|
+
msgpack (1.8.0)
|
|
47
|
+
parallel (1.27.0)
|
|
48
|
+
parser (3.3.10.2)
|
|
45
49
|
ast (~> 2.4.1)
|
|
46
50
|
racc
|
|
47
|
-
|
|
51
|
+
prism (1.9.0)
|
|
52
|
+
racc (1.8.1)
|
|
48
53
|
rainbow (3.1.1)
|
|
49
|
-
rake (13.
|
|
50
|
-
regexp_parser (2.
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
rake (13.3.1)
|
|
55
|
+
regexp_parser (2.11.3)
|
|
56
|
+
reline (0.6.3)
|
|
57
|
+
io-console (~> 0.5)
|
|
58
|
+
rubocop (1.86.0)
|
|
53
59
|
json (~> 2.3)
|
|
54
|
-
language_server-protocol (
|
|
60
|
+
language_server-protocol (~> 3.17.0.2)
|
|
61
|
+
lint_roller (~> 1.1.0)
|
|
55
62
|
parallel (~> 1.10)
|
|
56
63
|
parser (>= 3.3.0.2)
|
|
57
64
|
rainbow (>= 2.2.2, < 4.0)
|
|
58
|
-
regexp_parser (>=
|
|
59
|
-
|
|
60
|
-
rubocop-ast (>= 1.31.1, < 2.0)
|
|
65
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
66
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
61
67
|
ruby-progressbar (~> 1.7)
|
|
62
|
-
unicode-display_width (>= 2.4.0, <
|
|
63
|
-
rubocop-ast (1.
|
|
64
|
-
parser (>= 3.3.
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
69
|
+
rubocop-ast (1.49.1)
|
|
70
|
+
parser (>= 3.3.7.2)
|
|
71
|
+
prism (~> 1.7)
|
|
72
|
+
rubocop-shopify (2.18.0)
|
|
73
|
+
rubocop (~> 1.62)
|
|
67
74
|
ruby-progressbar (1.13.0)
|
|
68
|
-
securerandom (0.
|
|
69
|
-
sorbet-runtime (0.
|
|
70
|
-
sqlite3 (2.
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
securerandom (0.4.1)
|
|
76
|
+
sorbet-runtime (0.6.13059)
|
|
77
|
+
sqlite3 (2.9.2-aarch64-linux-gnu)
|
|
78
|
+
sqlite3 (2.9.2-aarch64-linux-musl)
|
|
79
|
+
sqlite3 (2.9.2-arm-linux-gnu)
|
|
80
|
+
sqlite3 (2.9.2-arm-linux-musl)
|
|
81
|
+
sqlite3 (2.9.2-arm64-darwin)
|
|
82
|
+
sqlite3 (2.9.2-x86-linux-gnu)
|
|
83
|
+
sqlite3 (2.9.2-x86-linux-musl)
|
|
84
|
+
sqlite3 (2.9.2-x86_64-darwin)
|
|
85
|
+
sqlite3 (2.9.2-x86_64-linux-gnu)
|
|
86
|
+
sqlite3 (2.9.2-x86_64-linux-musl)
|
|
87
|
+
timeout (0.6.1)
|
|
73
88
|
tzinfo (2.0.6)
|
|
74
89
|
concurrent-ruby (~> 1.0)
|
|
75
|
-
unicode-display_width (2.
|
|
90
|
+
unicode-display_width (3.2.0)
|
|
91
|
+
unicode-emoji (~> 4.1)
|
|
92
|
+
unicode-emoji (4.2.0)
|
|
93
|
+
uri (1.1.1)
|
|
76
94
|
|
|
77
95
|
PLATFORMS
|
|
78
|
-
aarch64-linux
|
|
96
|
+
aarch64-linux-gnu
|
|
97
|
+
aarch64-linux-musl
|
|
98
|
+
arm-linux-gnu
|
|
99
|
+
arm-linux-musl
|
|
79
100
|
arm64-darwin
|
|
80
|
-
|
|
101
|
+
x86-linux-gnu
|
|
102
|
+
x86-linux-musl
|
|
103
|
+
x86_64-darwin
|
|
104
|
+
x86_64-linux-gnu
|
|
105
|
+
x86_64-linux-musl
|
|
81
106
|
|
|
82
107
|
DEPENDENCIES
|
|
83
108
|
activerecord (>= 7)
|
|
@@ -92,5 +117,56 @@ DEPENDENCIES
|
|
|
92
117
|
sorbet-runtime
|
|
93
118
|
sqlite3
|
|
94
119
|
|
|
120
|
+
CHECKSUMS
|
|
121
|
+
activemodel (8.1.3) sha256=90c05cbe4cef3649b8f79f13016191ea94c4525ce4a5c0fb7ef909c4b91c8219
|
|
122
|
+
activerecord (8.1.3) sha256=8003be7b2466ba0a2a670e603eeb0a61dd66058fccecfc49901e775260ac70ab
|
|
123
|
+
activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e
|
|
124
|
+
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
|
|
125
|
+
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
126
|
+
benchmark-ips (2.14.0) sha256=b72bc8a65d525d5906f8cd94270dccf73452ee3257a32b89fbd6684d3e8a9b1d
|
|
127
|
+
bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
|
|
128
|
+
byebug (13.0.0) sha256=d2263efe751941ca520fa29744b71972d39cbc41839496706f5d9b22e92ae05d
|
|
129
|
+
concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
|
|
130
|
+
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
|
|
131
|
+
drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373
|
|
132
|
+
i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
|
|
133
|
+
io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
|
|
134
|
+
json (2.19.3) sha256=289b0bb53052a1fa8c34ab33cc750b659ba14a5c45f3fcf4b18762dc67c78646
|
|
135
|
+
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
|
|
136
|
+
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
|
|
137
|
+
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
|
|
138
|
+
minitest (5.27.0) sha256=2d3b17f8a36fe7801c1adcffdbc38233b938eb0b4966e97a6739055a45fa77d5
|
|
139
|
+
msgpack (1.8.0) sha256=e64ce0212000d016809f5048b48eb3a65ffb169db22238fb4b72472fecb2d732
|
|
140
|
+
paquito (1.0.2)
|
|
141
|
+
parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
|
|
142
|
+
parser (3.3.10.2) sha256=6f60c84aa4bdcedb6d1a2434b738fe8a8136807b6adc8f7f53b97da9bc4e9357
|
|
143
|
+
prism (1.9.0) sha256=7b530c6a9f92c24300014919c9dcbc055bf4cdf51ec30aed099b06cd6674ef85
|
|
144
|
+
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
|
|
145
|
+
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
|
|
146
|
+
rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
|
|
147
|
+
regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
|
|
148
|
+
reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
|
|
149
|
+
rubocop (1.86.0) sha256=4ff1186fe16ebe9baff5e7aad66bb0ad4cabf5cdcd419f773146dbba2565d186
|
|
150
|
+
rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
|
|
151
|
+
rubocop-shopify (2.18.0) sha256=dafa25e5617ce4600ff86b1de3d5b78e43ab3d58cc5729df38e492b8e10294eb
|
|
152
|
+
ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
|
|
153
|
+
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
|
|
154
|
+
sorbet-runtime (0.6.13059) sha256=da7bb8daab144261e042b28e0e33f48af8229e1cb39b98c7836e5555f253cd3e
|
|
155
|
+
sqlite3 (2.9.2-aarch64-linux-gnu) sha256=eeb86db55645b85327ba75129e3614658d974bf4da8fdc87018a0d42c59f6e42
|
|
156
|
+
sqlite3 (2.9.2-aarch64-linux-musl) sha256=4feff91fb8c2b13688da34b5627c9d1ed9cedb3ee87a7114ec82209147f07a6d
|
|
157
|
+
sqlite3 (2.9.2-arm-linux-gnu) sha256=1ee2eb06b5301aaf5ce343a6e88d99ac932d95202d7b350f0e7b6d8d588580d7
|
|
158
|
+
sqlite3 (2.9.2-arm-linux-musl) sha256=8ca0de6aceede968de0394e22e95d549834c4d8e318f69a92a52f049878a0057
|
|
159
|
+
sqlite3 (2.9.2-arm64-darwin) sha256=d15bd9609a05f9d54930babe039585efc8cadd57517c15b64ec7dfa75158a5e9
|
|
160
|
+
sqlite3 (2.9.2-x86-linux-gnu) sha256=066bc904522f8a7072236a81237c03a4a1dfe070a25107e392de03d1e4ad0e6d
|
|
161
|
+
sqlite3 (2.9.2-x86-linux-musl) sha256=6503c76278f5e8629b12b6518ff43a9a4f6d9381de73f0b086c9fa1226db5ede
|
|
162
|
+
sqlite3 (2.9.2-x86_64-darwin) sha256=ed691b5021674d72582d03c5a38e89634b961902735fb6225273892805421d13
|
|
163
|
+
sqlite3 (2.9.2-x86_64-linux-gnu) sha256=dce83ffcb7e72f9f7aeb6e5404f15d277a45332fe18ccce8a8b3ed51e8d23aee
|
|
164
|
+
sqlite3 (2.9.2-x86_64-linux-musl) sha256=e8dd906a613f13b60f6d47ae9dda376384d9de1ab3f7e3f2fdf2fd18a871a2d7
|
|
165
|
+
timeout (0.6.1) sha256=78f57368a7e7bbadec56971f78a3f5ecbcfb59b7fcbb0a3ed6ddc08a5094accb
|
|
166
|
+
tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b
|
|
167
|
+
unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42
|
|
168
|
+
unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f
|
|
169
|
+
uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6
|
|
170
|
+
|
|
95
171
|
BUNDLED WITH
|
|
96
|
-
|
|
172
|
+
4.0.9
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "active_record"
|
|
6
|
+
require "active_support"
|
|
7
|
+
require "paquito"
|
|
8
|
+
require "benchmark/ips"
|
|
9
|
+
|
|
10
|
+
# Set up an in-memory SQLite database with a table that mirrors a typical
|
|
11
|
+
# Active Record model — 39 columns with a mix of types and many nils.
|
|
12
|
+
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
|
|
13
|
+
|
|
14
|
+
ActiveRecord::Schema.define do
|
|
15
|
+
create_table :records do |t|
|
|
16
|
+
t.string(:string1)
|
|
17
|
+
t.string(:string2)
|
|
18
|
+
t.text(:text1)
|
|
19
|
+
t.string(:string3)
|
|
20
|
+
t.string(:string4)
|
|
21
|
+
t.string(:string5)
|
|
22
|
+
t.string(:string6)
|
|
23
|
+
t.string(:string7)
|
|
24
|
+
t.string(:string8)
|
|
25
|
+
t.boolean(:boolean1)
|
|
26
|
+
t.integer(:integer1)
|
|
27
|
+
t.string(:string9)
|
|
28
|
+
t.string(:string10)
|
|
29
|
+
t.string(:string11)
|
|
30
|
+
t.float(:float1)
|
|
31
|
+
t.float(:float2)
|
|
32
|
+
t.string(:string12)
|
|
33
|
+
t.integer(:integer2)
|
|
34
|
+
t.string(:string13)
|
|
35
|
+
t.string(:string14)
|
|
36
|
+
t.integer(:integer3)
|
|
37
|
+
t.boolean(:boolean2)
|
|
38
|
+
t.boolean(:boolean3)
|
|
39
|
+
t.string(:string15)
|
|
40
|
+
t.string(:string16)
|
|
41
|
+
t.datetime(:datetime1)
|
|
42
|
+
t.string(:string17)
|
|
43
|
+
t.string(:string18)
|
|
44
|
+
t.string(:string19)
|
|
45
|
+
t.boolean(:boolean4)
|
|
46
|
+
t.string(:string20)
|
|
47
|
+
t.datetime(:created_at)
|
|
48
|
+
t.datetime(:updated_at)
|
|
49
|
+
t.string(:string21)
|
|
50
|
+
t.string(:string22)
|
|
51
|
+
t.integer(:integer4)
|
|
52
|
+
t.string(:string23)
|
|
53
|
+
t.integer(:integer5)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
class Record < ActiveRecord::Base
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
TEXT_BLOB = <<~TEXT
|
|
61
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
|
|
62
|
+
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
|
|
63
|
+
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
64
|
+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
|
|
65
|
+
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt
|
|
66
|
+
in culpa qui officia deserunt mollit anim id est laborum.
|
|
67
|
+
TEXT
|
|
68
|
+
|
|
69
|
+
now = Time.utc(2026, 3, 4, 18, 49, 17)
|
|
70
|
+
|
|
71
|
+
record = Record.create!(
|
|
72
|
+
string1: "short1",
|
|
73
|
+
string2: "medium_string@test",
|
|
74
|
+
text1: TEXT_BLOB,
|
|
75
|
+
string3: "medium.string.value",
|
|
76
|
+
string4: "medium12",
|
|
77
|
+
string5: "AB",
|
|
78
|
+
string6: "a medium string!",
|
|
79
|
+
string7: "ABC 123",
|
|
80
|
+
string8: "medstr01",
|
|
81
|
+
boolean1: nil,
|
|
82
|
+
integer1: 360283,
|
|
83
|
+
string9: nil,
|
|
84
|
+
string10: "5551234567",
|
|
85
|
+
string11: nil,
|
|
86
|
+
float1: nil,
|
|
87
|
+
float2: nil,
|
|
88
|
+
string12: "medium.string.value",
|
|
89
|
+
integer2: 1000001,
|
|
90
|
+
string13: "a_medium_string_val",
|
|
91
|
+
string14: "another_val",
|
|
92
|
+
integer3: 1,
|
|
93
|
+
boolean2: false,
|
|
94
|
+
boolean3: false,
|
|
95
|
+
string15: "en",
|
|
96
|
+
string16: "a" * 64,
|
|
97
|
+
datetime1: nil,
|
|
98
|
+
string17: "a_slightly_longer_string",
|
|
99
|
+
string18: nil,
|
|
100
|
+
string19: nil,
|
|
101
|
+
boolean4: false,
|
|
102
|
+
string20: nil,
|
|
103
|
+
created_at: now,
|
|
104
|
+
updated_at: now,
|
|
105
|
+
string21: nil,
|
|
106
|
+
string22: nil,
|
|
107
|
+
integer4: 1,
|
|
108
|
+
string23: nil,
|
|
109
|
+
integer5: 1,
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
codec = Paquito::CodecFactory.build([ActiveRecord::Base])
|
|
113
|
+
|
|
114
|
+
payload = codec.dump(record).freeze
|
|
115
|
+
|
|
116
|
+
# Sanity check
|
|
117
|
+
codec.load(payload).tap do |restored|
|
|
118
|
+
raise "Round-trip failed!" unless restored.attributes == record.attributes
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
stage = ENV.fetch("STAGE", "after")
|
|
122
|
+
|
|
123
|
+
puts "=== dump ==="
|
|
124
|
+
Benchmark.ips do |x|
|
|
125
|
+
x.save!("/tmp/paquito-bench-active-record-dump.json")
|
|
126
|
+
x.report("dump (#{stage})") { codec.dump(record) }
|
|
127
|
+
x.compare!(order: :baseline)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
puts
|
|
131
|
+
puts "=== load ==="
|
|
132
|
+
Benchmark.ips do |x|
|
|
133
|
+
x.save!("/tmp/paquito-bench-active-record-load.json")
|
|
134
|
+
x.report("load (#{stage})") { codec.load(payload) }
|
|
135
|
+
x.compare!(order: :baseline)
|
|
136
|
+
end
|
|
@@ -22,6 +22,15 @@ module Paquito
|
|
|
22
22
|
deserialize_associations(serialized_associations, instances)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def columns_digest(klass)
|
|
26
|
+
str = +""
|
|
27
|
+
klass.columns_hash.each do |name, column|
|
|
28
|
+
str << "," unless str.empty?
|
|
29
|
+
str << name << ":" << column.sql_type
|
|
30
|
+
end
|
|
31
|
+
::Digest::MD5.digest(str).unpack1("s")
|
|
32
|
+
end
|
|
33
|
+
|
|
25
34
|
private
|
|
26
35
|
|
|
27
36
|
# Records without associations, or which have already been visited before,
|
|
@@ -92,7 +101,7 @@ module Paquito
|
|
|
92
101
|
record.class.name,
|
|
93
102
|
attributes_for_database(record),
|
|
94
103
|
record.new_record?,
|
|
95
|
-
|
|
104
|
+
record.class.paquito_columns_digest,
|
|
96
105
|
]
|
|
97
106
|
end
|
|
98
107
|
|
|
@@ -109,7 +118,7 @@ module Paquito
|
|
|
109
118
|
raise ClassMissingError, "undefined class: #{class_name}"
|
|
110
119
|
end
|
|
111
120
|
|
|
112
|
-
if hash && (hash != (expected_digest =
|
|
121
|
+
if hash && (hash != (expected_digest = klass.paquito_columns_digest))
|
|
113
122
|
raise ColumnsDigestMismatch,
|
|
114
123
|
"\"#{hash}\" does not match the expected digest of \"#{expected_digest}\""
|
|
115
124
|
end
|
|
@@ -119,11 +128,6 @@ module Paquito
|
|
|
119
128
|
attributes = klass.attributes_builder.build_from_database(attributes_from_database, EMPTY_HASH)
|
|
120
129
|
klass.allocate.init_with_attributes(attributes, new_record)
|
|
121
130
|
end
|
|
122
|
-
|
|
123
|
-
def columns_digest(klass)
|
|
124
|
-
str = klass.columns_hash.map { |name, column| [name, column.sql_type].join(":") }.join(",")
|
|
125
|
-
::Digest::MD5.digest(str).unpack1("s")
|
|
126
|
-
end
|
|
127
131
|
end
|
|
128
132
|
|
|
129
133
|
class Error < ::Paquito::Error
|
data/lib/paquito/allow_nil.rb
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paquito
|
|
4
|
+
module ColumnsDigestCache
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
class_methods do
|
|
8
|
+
def reload_schema_from_cache(*)
|
|
9
|
+
super
|
|
10
|
+
@paquito_columns_digest = nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def paquito_columns_digest
|
|
14
|
+
@paquito_columns_digest ||= Paquito::ActiveRecordCoder.columns_digest(self)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/paquito/types.rb
CHANGED
|
@@ -405,13 +405,13 @@ module Paquito
|
|
|
405
405
|
factory.register_type(
|
|
406
406
|
127,
|
|
407
407
|
Object,
|
|
408
|
-
packer: ->(value) do
|
|
409
|
-
|
|
408
|
+
packer: ->(value, packer) do
|
|
409
|
+
as_pack = CustomTypesRegistry.packer(value)
|
|
410
410
|
class_name = value.class.to_s
|
|
411
|
-
|
|
411
|
+
packer.write([as_pack.call(value), class_name])
|
|
412
412
|
end,
|
|
413
|
-
unpacker: ->(
|
|
414
|
-
payload, class_name =
|
|
413
|
+
unpacker: ->(unpacker) do
|
|
414
|
+
payload, class_name = unpacker.read
|
|
415
415
|
|
|
416
416
|
begin
|
|
417
417
|
klass = Object.const_get(class_name)
|
|
@@ -419,9 +419,10 @@ module Paquito
|
|
|
419
419
|
raise ClassMissingError, "missing #{class_name} class"
|
|
420
420
|
end
|
|
421
421
|
|
|
422
|
-
|
|
423
|
-
|
|
422
|
+
from_pack = CustomTypesRegistry.unpacker(klass)
|
|
423
|
+
from_pack.call(payload)
|
|
424
424
|
end,
|
|
425
|
+
recursive: true,
|
|
425
426
|
)
|
|
426
427
|
end
|
|
427
428
|
|
data/lib/paquito/version.rb
CHANGED
data/lib/paquito.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: paquito
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jean Boussier
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: msgpack
|
|
@@ -34,6 +34,7 @@ files:
|
|
|
34
34
|
- ".devcontainer/devcontainer.json"
|
|
35
35
|
- ".github/workflows/ci.yml"
|
|
36
36
|
- ".github/workflows/cla.yml"
|
|
37
|
+
- ".github/workflows/release.yml"
|
|
37
38
|
- ".gitignore"
|
|
38
39
|
- ".rubocop.yml"
|
|
39
40
|
- ".ruby-version"
|
|
@@ -43,6 +44,7 @@ files:
|
|
|
43
44
|
- LICENSE.txt
|
|
44
45
|
- README.md
|
|
45
46
|
- Rakefile
|
|
47
|
+
- benchmark/active-record-unpack.rb
|
|
46
48
|
- benchmark/flat-entry-coder.rb
|
|
47
49
|
- benchmark/msgpack-pooling.rb
|
|
48
50
|
- benchmark/string-bypass.rb
|
|
@@ -58,6 +60,7 @@ files:
|
|
|
58
60
|
- lib/paquito/cache_entry_coder.rb
|
|
59
61
|
- lib/paquito/codec_factory.rb
|
|
60
62
|
- lib/paquito/coder_chain.rb
|
|
63
|
+
- lib/paquito/columns_digest_cache.rb
|
|
61
64
|
- lib/paquito/comment_prefix_version.rb
|
|
62
65
|
- lib/paquito/compressor.rb
|
|
63
66
|
- lib/paquito/conditional_compressor.rb
|
|
@@ -102,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
102
105
|
- !ruby/object:Gem::Version
|
|
103
106
|
version: '0'
|
|
104
107
|
requirements: []
|
|
105
|
-
rubygems_version:
|
|
108
|
+
rubygems_version: 4.0.10
|
|
106
109
|
specification_version: 4
|
|
107
110
|
summary: Framework for defining efficient and extendable serializers
|
|
108
111
|
test_files: []
|