Object store — ``selkie.store`` =============================== JSONDisk - unit is the file. Directories are created incidentally. An Object is either a Dict or a List. It represents the contents of a JSONDisk at a finer grain. An Object may be attached to a file, or an element inside of a file, or a directory. It may also be unattached. An Object has a ``_contents`` member that contains the current contents of what is on disk. If ``_contents`` is None, the Object is unattached. which An ``Object`` is a dict-like JSON object that is backed by a JSONDisk, and a ``Store`` maps pathnames to Objects. To clarify, let us define some terms: **Dict-like object** An object that has an ``items()`` method. **List-like object** An object that has an ``__iter__()`` method, but is not dict-like. **JSON object** None, a boolean, int, float, or string, or a dict-like or list-like object consisting of JSON objects. **Backing** A directory, file, or part of a file that provides the persistent content of an Object. **Key** A member of an Object that contributes an item to ``items()``. **Basic key** A key that has a direct backing. The value of the key is set when the Object is instantiated, and setting the value causes the backing to be rewritten. **Defined key** A key that is not basic. Its value is computed from the values of basic keys, and setting its value sets the values of basic keys. An Object is instantiated from a directory, file, or part of a file, known as its **backing**. Object classes are never instantiated by the user, but are always obtained by reading from a store. Instantiating the object from its backing sets certain keys, which are distinguished as **basic keys**. Setting the value of a basic key causes **Defined keys** are also permitted. Their values are determined by the values of basic keys, and setting them provides construction from JSON and rendering to JSON. It is intended for use with a ``Store``, which is a specialization of JSONDisk (see :py:mod:`selkie.disk`) that provides a store of persistent objects. Distinguish directory objects or file objects from meta-objects. The backing of a meta-object is just a part of a file; typically a listing. A file object is immediately loaded in entirety, but the members of a directory object are only loaded on demand. The members of a directory object are files or subdirectories. We distinguish between *instantiation* and *loading*. Loading involves reading something from disk. We rely on schemas to know what the contents of a directory are (or rather, should be). Directory listings are never taken. Loading consists exclusively of the loading of individual files. A **directory object** is backed by a directory. Directories are never loaded. The first time a key is accessed, the value of that key (and only that key) is instantiated. The key's value (which must be a directory object or file object) is only instantiated, not loaded. A **file object** is backed by a file. Nothing is loaded when the file object is instantiated. The file is loaded the first time any key is accessed. A **partial-file object** is an object that cannot be independently read or written. Its contents exist in entirety when it is instantiated. It has a pointer to the file object that contains it. If the partial-file object is modified, it instructs the containing file to save itself. Objects wrap plain lists and dicts produced by ``read_kvi()``. A subclass defines ``__schema__``, which determines the basic keys. A defined key is added for each method whose name begins ``get_``. Object provides ``__getattr__()``, etc., ``__getitem__()`` etc., and ``GET()`` etc. As a JSON object, an Object is equal to its contents (which is what the JSONDisk reads in).