Open joneubank opened 3 years ago
@joneubank is ther ea plan to transfer this repository/move this into arranger? If so, may want ot transition this ticket.
I have a working prototype in a branch on this repo that I plan to complete to match this spec. Makes most sense at this point to complete this work and then discuss how Overture wants to adopt the tool. I don't think we've made a decision about this being published as a standalone or packaged with Arranger Components or both...
SQON and SQONMixer
Proposal for Synthetic SQON Management Library
SQON Builder API Updates
The SQON portion of the library has been refactored to no longer follow the builder pattern. This has been published as sqon-builder version 2.0.0 . Updates to this portion of the API are available in the README .
Of note, we simplified some of the terminology of the two operator types that combine into a SQON. These operators are now known as
Combinations
andFilters
. SQONs supportand
,or
, andnot
combinations, andin
,gt
,lt
filters.The SQON class was also given a
toString()
method as a convenience to serialize the data into a string. This is just a convenience wrapper aroundJSON.stringify(sqon)
. Any SQON can be passed directly into an http request library (axios
orfetch
for example) without the need to.build()
it anymore.SQONMixer
The task being accomplished by "SyntheticSQONs" can be summarized as maintaining a list of reference SQONs and other combinations of these references, and then in the future being able to resolve those references into a SQON usable in a query.
To simplify terminology and separate the functionality of the SQON Builder library from the existing Arranger implementation, we're proposing the introduction of a
SQONMixer
that will perform these tasks.Basic Use Case
The basic usage of this object would be adding multiple
SQON
s, then using theSQONMixer
to combine them, and finally resolve the combined entry into a newSQON
.The value of the
combinedSqon
would be:Similar to a SQON, the mixer can combine SQONs and References via
and
,or
, andnot
combinations.The output of the mixer operations is a SQONMixerEntry, and these same combinations and resolution can be performed on these entries. For example:
Other Important Functions (Modifying Existing Entries)
Removing an Entry
Removing an entry from the SQONMixer will remove that entry from the list of content in the mixer, and will loop through all other entries to remove references to it. Nothing is returned from this method. The Mixer Entry object will not be modified but it will no longer be usable within the mixer.
Updating Combination
Changes the
op
value, combination operation, at the root of the SQON referenced in the entry.Circular References
See next section pertaining to loops.
Updating SQON Content
At time of writing there isn't a clean and understandable scheme for modifying parts of an existing SQON, but updates are still required to make this system useful.
In place of modifying individual clauses of a SQON's content, it is instead proposed that the SQON held within a SQONMixer Entry can be wholely replaced.
To replace an entry's content with a new SQON that references other SQONMixer Entries from this mixer, you can create the content with the
.combine()
method:Finally, from a SQONMixer Entry, entities can be added or removed from the current content list:
Concerning Circular References (Loops)
Modifying an existing entry by adding another entry to it can create a loop. This will happen if the first entry is in the list of references of the one being added. To prevent this, all additions to existing entries will check for reference loops before executing, and if there is an issue an error will be thrown instead of updating the entry.
To accomplish this, each entry maintains a list of the IDs of the other entries it references in the property
.references
. To get the complete list of Mixer Entries that are required to resolve this entry, you can use the method.allReferences()
. Finally, these tools are used by the method.hasLoops(entries: SQONMixerEntries[])
which can be called form the mixer or from any entry.API Arguments
All SQONMixer functions that accept SQONMixerEntry objects as arguments can alternately be given the entry ID as a string. The function will handle both in the same way.
For example:
mixer.resolve(entry.id)
ormixer.resolve(entry)
are both valid.Other APIs where this is useful are
.remove
, and.get
, and in any of the entries for the combination methods.and
,.or
, and.not
Serialization
It is necessary for the SQONMixer to be serializable, so that it can be stored somewhere as a string and then reloaded in the future.
To accomplish this, SQONMixer instances have a
.serialize()
method that will output the mixer as a string, including all contained SQONs and references. References to SQONs which are maintained in JS memory as references will instead be serialized with their string ID.The SQONMixer class has a static method
.parse(serializedMixer)
that will read in a serialized mixer from string and provide a functioning SQONMixer instance as output. All the entries are available from the mixer via the.content
preroperty, which stores all entries as an object with the keys being the entry IDs:Here,
entries
would have a value like (output from first example in this doc):