In the process of reviewing the Ada Gems, I was amazed by this feature:
Who knew about this one? (Honestly ^^)
In the process of reviewing the Ada Gems, I was amazed by this feature:
Who knew about this one? (Honestly ^^)
I did not know it, though I worked on persistency a lot.
However there are issues with that:
I really like the Ada gems series for things just like this. I hope they never take the archive down as it is a really valuable resource.
I did.
I used it to implement configuration for a bit of custom logging. — Basically a store of Pascal-style strings (256-bytes: 1 length byte, followed by the string data), plus the integral data.
I don’t know that I agree; for many things, yes… but for small things with very few parameters?
I mean, you’re using Shared_Passive
, which means that you should be able to hook it into a DSA program easily. (Though, TBF, I think the LRM stance on DSA programs are that it’s implementation-defined; which makes sense: incorporating a truly portable RPC/data-communication protocol would be (a) constraining all DSA programs to those protocols, and (b) would entail incorporation-by-reference to something that would likely be ASN.1 or something of similar capability.)
This is perhaps the place that current Ada disappoints the most: it’s rather obvious that the original (Ada83) design was done with the idea of being able to incorporate self-referential datastructures like the aforementioned, when “compiler/language technology caught up”, such that you could make lists/graphs/links. (Actually, I suspect that the access
type was always meant to be key: that the Cursor
-type in the Ada.Containers.*
packages should be access types, discriminated by the container.)
Honestly, at that point what would be useful is a common Ada+PL/SQL runtime, with the runtime containing a full database-engine.
That is why pragma does not scale. You need a primitive operations implementing storing/restoring, just like stream attributes that do same thing for serialization.
Recursive types simply do not work. The ugly truth is that you need forward and backward links, strong and weak references. For example, I frequently implement graphs that share subgraphs for performance reasons. When a subgraph is updated by one client it is cloned when referenced by other clients.
No, it is just a wrong design. The implementation must support whatever user-provided persistency layer rather than forcing certain engine.
Consider cases when some updates happen in situ rather than the whole thing is stored/restored. You might have gigabytes of persistent objects.
No, you don’t.
(Off the top of my head, using this for extremely simple config.)
Package Example_Config with Shared_Private is
Type Pascal_String is private;
Procedure Set( Value : String; Object : in out Pascal_String )
with Pre => Value'Length in 0..255;
Procedure Get( Object : Pascal_String ) return String;
Login : Constant Pascal_String;
Password : Constant Pascal_String;
Port : Constant Integer;
Private
Subtype Byte is Interfaces.Unsigned_8;
Type Internal_String_Data is Array(Byte range <>) of Character;
Type Internal_String( Length : Byte ) is Record
Data : Internal_String_Data( 1..Length );
End record with Size => 8*256;
Type Pascal_String is null record with Size => 8*256;
-- And all the conversion routines.
-- We set these with a config routine, they stay until re-configured or deleted.
Login : Constant Pascal_String:= (0, (others => ASCII.NUL));
Password : Constant Pascal_String:= (0, (others => ASCII.NUL));
Port : Constant Integer:= 0;
End Example_Config;
In-situ is a non-issue.
SQL’s the PSM (Persistent Storage Module) —colloquially “PL/SQL”— is more about triggers, stored procedures, etc, and SQL is about providing query to database/storage. There’s nothing preventing the “database” from being a single file, an external-link/-object, or anything else… indeed, Part 9 of the SQL standard is “Management of External Data”.
The word “extremely” is the key here. You can start with versioning config versions, language support and types other than string. Even primitive init-file engines are capable of more.
You missed the point. When dealing with persistency there are two choices: #1 to restore the object update the proxy and store it back or #2 to update the object directly in the store.
In your example consider updating the password without restoring login and conversely restoring all user authentication, updating and storing it back.
P.S. The bottom up way of thinking and designing is poor engineering which will inevitably hit you back once faced real life.
Yes; that’s exactly the point.
I think you misunderstand: the logging-system only needed the login/password to access internal (literally a local server) e-mail; throwing the config in shared-passive (not quite “in the exe
”; as it’s a flat-file that is generated w/ the defaults if it doesn’t exist), and was the perfect choice for something that needed minimal config. (i.e. an INI
or XML
file would have been overkill.)
I did. I saw the gem many years ago, and used it to keep track of a sequence number in a communication process. The protocol wants the telegrams order by sequence num, which increases by 1 for each tgm. To make the other side happy I saved the sequence num on disk through this pragma, so I did not need to serialize it myself. It is read upon restart which was the point.
That protocol was later changed to accept 0 as a restart marker.
I also customized the storage format. at firs it was just 4 integers (32 bit num) but I made it human readable.
It is still running on that site.