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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa3f2c4a293512f8a86e4acaf01c77e0554a42eb5f8847a6c33bfe8bff03330b
4
- data.tar.gz: 8abeec112ff65793ced679bbf1f7aa370c9f3f6f08bdb63b1d5adb7cfc259833
3
+ metadata.gz: b3668368d8bc70c9c48aed2d48180c46caf75749eec556e4625e134534f65760
4
+ data.tar.gz: bcd3643f407dd675b80b5b76719ee6906b0892d8b437b0415712c81e271bdba1
5
5
  SHA512:
6
- metadata.gz: ea64c4d227fd832b232d2833ccae7948208c012cd2b890f44bed919af86c6f828dbfd28de0d925fed3e218f96837b409251bc6f9ea7e8d0ff7802da63d21313f
7
- data.tar.gz: 93bd50aee1d410b117ee2c2993d85dc6c53bae5e5204b6be37d413ab160f92a120725cb6cfc6f6c00744a9c12ff1b8db30aea7f8c0593fc9a7fb3831cca258c0
6
+ metadata.gz: 979da0d59439adbb1065cdd0a07977b7a9192842d2df8cf753ccfac306b26b92361a340536d4125c31901f7ad2d064eb4dc563ba246c8f667c7b7af2ee9937e1
7
+ data.tar.gz: 8e8ed34ddc5e6059253454772fe7f089e9bb662eebd4ec1d44c7d2d0699cd6cc9800d347fa1d9a82aa3dfd16606df3e7a062e6a62ec4f08e7aed72f4c6c4aab0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ### 1.0.0 (2020-05-18)
2
+
3
+ * Version 1.0.0 release! No changes since 0.5.0 except some small changes to the
4
+ README.
5
+
1
6
  ### 0.5.0 (2020-05-17)
2
7
 
3
8
  * Add `**context` argument to `#pack` method, exposed as `@context` in blocks
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Sequel::Packer
2
2
 
3
- `Sequel::Packer` is a Ruby JSON serialization library to be used with the Sequel
4
- ORM offering the following features:
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
- Simply call `to_json` on the result!
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
@@ -1,5 +1,5 @@
1
1
  module Sequel
2
2
  class Packer
3
- VERSION = "0.5.0"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
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.5.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-18 00:00:00.000000000 Z
11
+ date: 2020-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel