wheel (GitLab)
wheel (GHA via
nightly.link
)
We have moved to https://codeberg.org/KOLANICH-libs/urm.py, grab new versions there.
Under the disguise of "better security" Micro$oft-owned GitHub has discriminated users of 1FA passwords while having commercial interest in success and wide adoption of FIDO 1FA specifications and Windows Hello implementation which it promotes as a replacement for passwords. It will result in dire consequencies and is competely inacceptable, read why.
If you don't want to participate in harming yourself, it is recommended to follow the lead and migrate somewhere away of GitHub and Micro$oft. Here is the list of alternatives and rationales to do it. If they delete the discussion, there are certain well-known places where you can get a copy of it. Read why you should also leave GitHub.
Unrelational mapper.
Sometimes you need to store some data somewhen and lazily retrieve as class fields and we don't want to write lot of boilerplate code and maintain this piece of shit. Object-relational mappers solve this problem by mapping classes to database tables, objects - to rows, object hierarchy to public and foreign keys.
But sometimes we don't need to store the data in relational databases. We need to store data in entities like files, archives, remote servers using REST/GraphQL API, etc. So we generalize a bit.
This stuff utilizes my other library transformerz
of composable 2-way transformations.
It is strongly recommended to read the tutorial before using the lib. tutorial.ipynb
We tie stored entities not to objects, but properties in classes. Entities are stored in underlying key-value storage.
- When we first time access a property in the class, it is loaded into a cache and then returned.
- subsequent accesses return the stuff from the cache.
- we can
save
the stuff from the cache to the storage explicitly. - to create a storage from scratch, we put the data into a cache and then
save
it.
Then we heavily abstrage the stuff.
A key
is a tuple
of strings and numbers. It is an unique identifier of a piece of data. It is decoupled from the actual storage implementation. We address data by keys.
To define the way we are going to store data we need to answer to the following "orthogonal" questions:
- WHERE are we going to store it?
Saver
object is an answer.Mapper.saver
answers the question. - WHAT is the mapping between our internal
key
s andkey
s in the storage of this piece of data? Akey
is an answer.Mapper.key
answers this question.
For cold storage we need to answer an additional question:
- HOW are we going to serialize the data?
transformerz.Transformer
object is an answer.ColdMapper.serializer
answers this question.
So Mapper
object answers the questions related to storage of values.
To create a bidirectional mapping between class properties, we need to answer the following questions:
- What pattern of access to the data should be optimized for?
FieldStrategy
subclasses are the answers.ColdStrategy
optimizes for frequent rather cheap accesses to volatile data.- Requires to know how we STORE the data.
ColdMapper
object is an answer.FieldStrategy.cold
answers this question.
- Requires to know how we STORE the data.
CachedStrategy
optimizes for frequent rather expensive accesses to not very volatile data.- Additionally requires to know how we CACHE the data?
HotMapper
object is an answer.FieldStrategy.hot
answers this question.
- Additionally requires to know how we CACHE the data?
- How do we create our internal
key
s?Field
subclasses contain the answers.