sequel-packer 0.5.0 → 1.0.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 +5 -0
- data/README.md +107 -30
- data/lib/sequel/packer/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3668368d8bc70c9c48aed2d48180c46caf75749eec556e4625e134534f65760
|
4
|
+
data.tar.gz: bcd3643f407dd675b80b5b76719ee6906b0892d8b437b0415712c81e271bdba1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 979da0d59439adbb1065cdd0a07977b7a9192842d2df8cf753ccfac306b26b92361a340536d4125c31901f7ad2d064eb4dc563ba246c8f667c7b7af2ee9937e1
|
7
|
+
data.tar.gz: 8e8ed34ddc5e6059253454772fe7f089e9bb662eebd4ec1d44c7d2d0699cd6cc9800d347fa1d9a82aa3dfd16606df3e7a062e6a62ec4f08e7aed72f4c6c4aab0
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Sequel::Packer
|
2
2
|
|
3
|
-
`Sequel::Packer` is a Ruby
|
4
|
-
ORM
|
3
|
+
`Sequel::Packer` is a Ruby serialization library to be used with the [Sequel
|
4
|
+
ORM](https://github.com/jeremyevans/sequel) with the following qualities:
|
5
5
|
|
6
6
|
* **Declarative:** Define the shape of your serialized data with a simple,
|
7
7
|
straightforward DSL.
|
@@ -18,33 +18,6 @@ ORM offering the following features:
|
|
18
18
|
and nested associations it needs to eager load in order to avoid any N+1 query
|
19
19
|
issues.
|
20
20
|
|
21
|
-
- [Example](#example)
|
22
|
-
- [Getting Started](#getting-started)
|
23
|
-
- [Installation](#installation)
|
24
|
-
- [Example Schema](#example-schema)
|
25
|
-
- [Basic Fields](#basic-fields)
|
26
|
-
- [Packing Associations by Nesting Packers](#packing-associations-by-nesting-packers)
|
27
|
-
- [Traits](#traits)
|
28
|
-
- [API Reference](#api-reference)
|
29
|
-
- [Using a Packer](#using-a-packer)
|
30
|
-
- [Defining a Packer](#defining-a-packer)
|
31
|
-
- [`self.model(sequel_model_class)`](#selfmodelsequel_model_class)
|
32
|
-
- [`self.field(column_name)` (or `self.field(method_name)`)](#selffieldcolumn_name-or-selffieldmethod_name)
|
33
|
-
- [`self.field(key, &block)`](#selffieldkey-block)
|
34
|
-
- [`self.field(association, subpacker, *traits)`](#selffieldassociation-subpacker-traits)
|
35
|
-
- [`self.field(&block)`](#selffieldblock)
|
36
|
-
- [`self.trait(trait_name, &block)`](#selftraittrait_name-block)
|
37
|
-
- [`self.eager(*associations)`](#selfeagerassociations)
|
38
|
-
- [`self.set_association_packer(association, subpacker, *traits)`](#selfset_association_packerassociation-subpacker-traits)
|
39
|
-
- [`self.pack_association(association, models)`](#selfpack_associationassociation-models)
|
40
|
-
- [`self.precompute(&block)`](#selfprecomputeblock)
|
41
|
-
- [Context](#context)
|
42
|
-
- [`self.with_context(&block)`](#selfwith_contextblock)
|
43
|
-
- [Contributing](#contributing)
|
44
|
-
- [Development](#development)
|
45
|
-
- [Releases](#releases)
|
46
|
-
- [License](#license)
|
47
|
-
|
48
21
|
## Example
|
49
22
|
|
50
23
|
`Sequel::Packer` uses your existing `Sequel::Model` declarations and leverages
|
@@ -88,7 +61,7 @@ end
|
|
88
61
|
|
89
62
|
Once defined, Packers are easy to use; just call `.pack` and pass in a Sequel
|
90
63
|
dataset, an array of models, or a single model, and get back Ruby hashes.
|
91
|
-
|
64
|
+
From there you can simply call `to_json` on the result!
|
92
65
|
|
93
66
|
```ruby
|
94
67
|
UserPacker.pack(User.dataset)
|
@@ -118,6 +91,41 @@ UserPacker.pack(User[1], :posts)
|
|
118
91
|
}
|
119
92
|
```
|
120
93
|
|
94
|
+
## Contents
|
95
|
+
|
96
|
+
- [Example](#example)
|
97
|
+
- [Getting Started](#getting-started)
|
98
|
+
- [Installation](#installation)
|
99
|
+
- [Example Schema](#example-schema)
|
100
|
+
- [Basic Fields](#basic-fields)
|
101
|
+
- [Packing Associations by Nesting Packers](#packing-associations-by-nesting-packers)
|
102
|
+
- [Traits](#traits)
|
103
|
+
- [API Reference](#api-reference)
|
104
|
+
- [Using a Packer](#using-a-packer)
|
105
|
+
- [Defining a Packer](#defining-a-packer)
|
106
|
+
- [`self.model(sequel_model_class)`](#selfmodelsequel_model_class)
|
107
|
+
- [`self.field(column_name)` (or `self.field(method_name)`)](#selffieldcolumn_name-or-selffieldmethod_name)
|
108
|
+
- [`self.field(key, &block)`](#selffieldkey-block)
|
109
|
+
- [`self.field(association, subpacker, *traits)`](#selffieldassociation-subpacker-traits)
|
110
|
+
- [`self.field(&block)`](#selffieldblock)
|
111
|
+
- [`self.trait(trait_name, &block)`](#selftraittrait_name-block)
|
112
|
+
- [`self.eager(*associations)`](#selfeagerassociations)
|
113
|
+
- [`self.set_association_packer(association, subpacker, *traits)`](#selfset_association_packerassociation-subpacker-traits)
|
114
|
+
- [`self.pack_association(association, models)`](#selfpack_associationassociation-models)
|
115
|
+
- [`self.precompute(&block)`](#selfprecomputeblock)
|
116
|
+
- [Context](#context)
|
117
|
+
- [`self.with_context(&block)`](#selfwith_contextblock)
|
118
|
+
- [Potential Future Functionality](#potential-future-functionality)
|
119
|
+
- [Automatically Generated Type Declarations](#automatically-generated-type-declarations)
|
120
|
+
- [Lifecycle Hooks](#lifecycle-hooks)
|
121
|
+
- [Less Data Fetching](#less-data-fetching)
|
122
|
+
- [Other Enhancements](#other-enhancements)
|
123
|
+
- [Contributing](#contributing)
|
124
|
+
- [Development](#development)
|
125
|
+
- [Releases](#releases)
|
126
|
+
- [Attribution](#attribution)
|
127
|
+
- [License](#license)
|
128
|
+
|
121
129
|
## Getting Started
|
122
130
|
|
123
131
|
This section will explain the basic use of `Sequel::Packer`. Check out the [API
|
@@ -782,6 +790,68 @@ UserPacker.pack(User.dataset, comment_traits: [:num_likes])
|
|
782
790
|
=> [{comments: [{id: 7, likes: 53}, ...]}]
|
783
791
|
```
|
784
792
|
|
793
|
+
## Potential Future Functionality
|
794
|
+
|
795
|
+
The 1.0.0 version of the Packer library is flexible to support many use cases.
|
796
|
+
That said, of course there are ways to improve it! There are three main
|
797
|
+
improvements I can imagine adding:
|
798
|
+
|
799
|
+
### Automatically Generated Type Declarations
|
800
|
+
|
801
|
+
It would be fairly easy to add generate type definitions by adding arguments to
|
802
|
+
`field`. Packers could produce [TypeScript
|
803
|
+
interface](https://www.typescriptlang.org/docs/handbook/interfaces.html)
|
804
|
+
declarations, and adding a simple build step to a CI pipeline could enforce type
|
805
|
+
safety across the frontend and backend. Or they could produce
|
806
|
+
[OpenAPI](http://spec.openapis.org/oas/v3.0.3) specifications, which could then
|
807
|
+
be used to automatically generate clients using something like
|
808
|
+
[Swagger](https://swagger.io/).
|
809
|
+
|
810
|
+
### Lifecycle Hooks
|
811
|
+
|
812
|
+
It should be fairly easy to extend the Packer library using standard Ruby
|
813
|
+
features like subclassing, mixins, via `include`, or even monkey-patching. It
|
814
|
+
may be beneficial to have explicit hooks for common operations however, like
|
815
|
+
`before_fetch`, or `around_pack`. It's more likely that these hooks are needed
|
816
|
+
for logging and tracing capabilities, than for actual functionality, so I'd
|
817
|
+
like to see some real-world usage before committing to a specific style of
|
818
|
+
integration.
|
819
|
+
|
820
|
+
### Less Data Fetching
|
821
|
+
|
822
|
+
Sequel by default fetches every column in a table, but a Packer knows (roughly)
|
823
|
+
what data is going to be used so it could only select the columns neede for
|
824
|
+
actual serialization, and limit how much data is actually fetched from the
|
825
|
+
database. I haven't done any benchmarking on this, so I'm not sure how much of
|
826
|
+
a benefit could be gained by this, but it would be interesting!
|
827
|
+
|
828
|
+
This could work roughly as follows:
|
829
|
+
|
830
|
+
* Start by fetching all columns that appear in simple `field(:column_name)`
|
831
|
+
declarations
|
832
|
+
* Add any columns need to fetch nested associations, or to re-asscociate fetched
|
833
|
+
records with their "parent" models, using the `left_key` and `right_key`
|
834
|
+
fields of the `AssociationReflections`
|
835
|
+
* Add a `column(*columns)` DSL method to explicitly fetch additional columns
|
836
|
+
|
837
|
+
### Other Enhancements
|
838
|
+
|
839
|
+
Here are some other potential enhancements, though these are less fleshed out.
|
840
|
+
|
841
|
+
* Support not including a key in a hash if the associated value is nil, to
|
842
|
+
reduce size of outputted data.
|
843
|
+
* Support different casing of the outputted hashes, i.e., `snake_case` vs.
|
844
|
+
`camelCase`.
|
845
|
+
* Explicitly support different output formats, rather than just plain Ruby
|
846
|
+
hashes, such as [Protocol
|
847
|
+
Buffers](https://developers.google.com/protocol-buffers) or [Cap'n
|
848
|
+
Proto](https://capnproto.org/).
|
849
|
+
* When using nested `precompute` blocks, the Packer has to flatten the
|
850
|
+
associations of a model, which may be expensive, but has not been benchmarked.
|
851
|
+
These flattened arrays already exist internally in Sequel when the eager
|
852
|
+
loading occurs, but those aren't exposed. The code in Sequel could be
|
853
|
+
re-implemented as part of the library to avoid re-constructing those arrays.
|
854
|
+
|
785
855
|
## Contributing
|
786
856
|
|
787
857
|
Bug reports and pull requests are welcome on GitHub at
|
@@ -801,6 +871,13 @@ run `rake release`, which which will create a git tag for the version, push git
|
|
801
871
|
commits and tags, and push the `.gem` file to
|
802
872
|
[rubygems.org](https://rubygems.org).
|
803
873
|
|
874
|
+
## Attribution
|
875
|
+
|
876
|
+
[Karthik Viswanathan](https://github.com/karthikv) designed the original API
|
877
|
+
of the Packer library while at [Affinity](https://www.affinity.co/). This
|
878
|
+
library is a ground up rewrite which defines a very similar API, but shares no
|
879
|
+
code with the original implementation.
|
880
|
+
|
804
881
|
## License
|
805
882
|
|
806
883
|
The gem is available as open source under the terms of the
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-packer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Julius Martinez
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|