Comments (3)
You're correct that we haven't added binary attributes yet, that's an item on our backlog. If you can expand a bit on your use of binary attributes (though I can understand if you can't), would be happy to consider that as well when implementing them.
The type_cast
methods are taking possible inputs and turning them into a single representative type, while the serialization step just focuses on differences between that type and DB representation (for example, where Date(Time) attributes are backed by strings).
I'm open to feedback on cases where this implementation falls short or creates issues, our primary source for the marshaler logic was our previous SDK major version.
from aws-sdk-ruby-record.
Sure. I want an attribute that can take a String with encoding ASCII-8BIT and store its value, roughly no matter how long it is. I'm going to provide the symbol for that attribute to a DSL which then sets and gets from it; I have little control over that DSL, and am only lucky that it is encoding the string as ASCII-8BIT consistently. In this particular case, it's going to represent a per-instance encryption key which will then be used to serialize & deserialize other attributes in the same model.
That attribute value needs to be preserved as-is, of course. One approach: type_cast
changes String to encode64
strings; serialize
puts them out as-is. But now when I read a value back, I get double encodes and no place to decode. Clearly the wrong answer.
Second approach: type_cast
requires a different type for encoding (say class BinaryString < String
). Now I can vaguely make it work; type_cast
runs decode64
on Strings and doesn't touch BinaryString
s, and serialize
runs the encode64
on BinaryStrings. But this has two problems:
bar = BinaryString.new('bar') ; model.foo = bar; model.foo == bar
is false sincetype_cast
is called by the getter (so model.foo will rundecode64
on 'bar').- I have to know to cast the value in my assignment.
Working approach: add another layer of accessors (foo=
and its foo
). The setter wraps the value in BinaryString
and then calls the setter generated by attr
(say binary_foo=
). The binary_foo
accessors work like in the second approach; the foo
getter just delegates to the binary_foo
getter.
Now foo=
and foo
work symmetrically
wack = Example.new(hash_key_field: 'x')
wack.foo = 'blah'
assert(wack.foo == 'blah') # => true
wack.save(force: true)
amole = Example.find(hash_key_field: 'x')
assert(amole.foo == 'blah') # => true
assert(wack.foo == amole.foo) # => true
But I'm copying and force_encoding strings, and even then we're only getting dirty tracking because I'm eager (and encode as soon as the assignment is made).
Probable next approach if I can take the time to reopen the code: write the case statements in terms of the encoding instead of the value's class. That breaks the pattern established by Aws::Record::Marshaler subclasses, but might allow removal of the second layer of accessors.
Other ORMs like Active::Record and DataMapper just re-use the pattern from Ruby's Marshal module: two conceptually decoupled methods called #dump
and #load
. The only assumption is that random_marshaller.load(random_marshaller.dump(x)) == x
(and even that's a bit loose; it wouldn't be unusual for a symbol to be turned to a string). The attribute handling just lets x
be whatever value it was before it was assigned.
Thanks for your attention.
from aws-sdk-ruby-record.
I had a rough draft of binary types that appeared to work for basic cases, I'll take a look at your use case once we pull this up. Definitely happy to prioritize a PR review as well.
from aws-sdk-ruby-record.
Related Issues (20)
- Seahorse::Client::NetworkingError (SSL_connect returned=1 errno=0 state=error: wrong version number) HOT 6
- The '#find' command doesn't properly populate database_attribute_name if symbolized HOT 1
- Wrong documentation for assign_attributes HOT 1
- Query yielding heterogeneous results HOT 9
- Capacity used for iterating through a query's results HOT 2
- Is it possible to override table name? HOT 1
- Support DynamoDB Encryption feature HOT 4
- Support increment! and decrement! for atomic counters? HOT 2
- FrozenError When Building Query HOT 1
- Numeric type casting of attributes nested in maps HOT 7
- Support for creating cross-region replication?
- Support for BatchGetItem HOT 5
- Serialize to JSON HOT 1
- No All / Scan Operation? HOT 3
- Support for custom Update expressions HOT 2
- Configuration with a Single Table HOT 3
- Nested List Attributes & Type Casting HOT 2
- List of classes HOT 1
- How to query against local or global index? HOT 1
- "limit" on scan HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aws-sdk-ruby-record.