ycl eav, by 
PYK, is an entity-attribute-value system for Tcl, built upon 
sqlite, that features a Tcl-ish interface and query capabilities, traces for maintaining constraints on data and reacting in other ways to record updates, and the ability to traverse logical 
hierarchies in the data.
 Description  edit
In an entity-attribute-value system, structure that might otherwise be found in the database schema is in the data instead.  
ycl eav provides the features needed to store data in this fashion and to use it as if it were structured into a more traditional relational schema.
An entity-attribute value system easily accomodates hierarchical data such as that represented by 
XML documents.  Nodes in logical hierarchies within a dataset can be discovered using 
eav find.  See below for more information.
As a rule, 
eav routines process records in the order they were entered.  This makes it possible to view a snapshot of the data by limiting results to records that preceded some particular record.
 Documentation  edit
- The source code 
- Includes documentation in prose.
 Creating an Eav  edit
eav myeav filename /path/to/some/file
If no filename is provided, the database is created in memory
eav myeav
 Creating Entities  edit
To create a new entity, assign one or more attributes and provide the 
empty string as the entity identifier:
set hydrogen [myeav set {} name hydrogen protons 1]
set oxygen [myeav set {} name oxygen protons 8 phase gas]
set sodium [myeav set {} name sodium protons 11 phase solid] Removing Entities  edit
To remove an entity:
myeav unset $oxygen
 Copying Entities  edit
To copy an entity:
myeav set {} {*}[myeav get $oxygen] Adding Attributes  edit
To set an additional attribute on an entity:
myeav set $hydrogen phase gas
To add multiple records for an attribute, use 
insert instead of 
setset water [myeav set {} component $hydrogen]
$water insert component $oxygen Removing Attributes  edit
To unset all records of 
$oxygen where the attribute is "protons":
myeav unset $oxygen protons
 Modifying Attribute Values  edit
To change the value of the last record for some attribute:
myeav set $entity $attribute $value
To increment by 3 the value of the last record for some attribute:
myeav incr $entity $attribute 3 
 Retrieving Values  edit
To retrieve the value of an attribute, use 
setmyeav set $hydrogen component
To retrieve a dictionary of selected values of a entity:
myeav get $hydrogen protons phase
To check if an attribute exists for some entity:
myeav exists $hydrogen phase
If an entity has multiple values for an attribute, only the last value is returned.
To retrieve a list of selected values for an attribute:
myeav list $hydrogen protons phase
 Ensuring Such an Entity  edit
To ensure that an entity having a certain profile (set of attributes and associated values) exists:
set nitrogen [myeav ensure name nitrogen protons 7]
 Nested Dictionaries  edit
dset, 
dget, and 
dexists make it possible to process 
eav records as 
nested dictionaries:
set Cronus [myeav set {} name Cronus]
set Apollo [myeav set {} name Apollo]
myeav dset [list $Cronus sons Zeus sons] Apollo $Apollo
puts [myeav dset [list $Cronus sons Zeus sons Apollo] name] Finding Entities  edit
The first argument to 
find is a list of attributes to include in the results, and the remaining arguments are operators and their arguments.  Each operator consumes a certain number of arguments, and any subsequent argument is another operator.  If all operations are true for some entity, it is included in the result set.
To find the entity identifiers for all entities that have a "phase" attribute:
myeav find {} exists phase To retrieve a dictionary, keyed by identifier, of all entities that have a "phase" attribute:
myeav find * exists phase 
To retrieve only the "protons" and "phase" attributes of such entities:
myeav find {protons phase} exists phase exists protonsBut since any attribute mentioned in the first argument implies an "exists" requirement, the previous command is equivalent to:
myeav find {protons phase}To find entities that have at least 3 protons:
myeav find {} > protons 3To find the names of entities that have at least 3 protons and a phase of "solid":
myeav find name > protons 3 == phase solid
To find entities that are missing some attribute:
myeav find name > protons 3 is missing phase
To limit results to those that were inserted prior to some record, use the 
id operator:
myeav find {} id < $id Finding Members of Logical Hierarchies  edit
To find members of logical hierarchies of entities, use the 
descend operator, which takes the name of an entity to build the hierarchy on, and either an 
== or an 
entity operation that selects the entry points into the hierarchy, as well as provides the criteria for selecting children of the current node in the hierarchy.  For example with an eav instance named 
organization:
organization find {} descend boss entity == $myboss To use a set of criteria instead of an entity to specifiy the entry point(s) into the hierarchy:
organization find {} descend boss name == Neo  The eval operator  edit
find features an 
eval operator that functions just like the one in the Tcli interface to 
sqlite:
organization find {} entity == $myboss descend boss eval record {
    puts [array get $record]
} Ordering Results  edit
find usually processes data in the order of insertion.  To change this order, use the 
order operation:
myeav find {} order valueunion takes a list of arguments that might be passed to 
find, and wraps them up into a single database query.  for operators that only make sense when given once, the last occurrence is used.
Example:
myeav union {* protons > 3} {* missing phase eval record {
    puts [array get record]
}}Both write and unset actions can be traced.  A trace can specify an attribute, an entity, or both.  This results in four kinds of traces:
- Any attribute of any entity.
- Any attribute of a particular entity.
- A particular attribute of any entity.
- A particular attribute of a particular entity.
All traces that match fire, with more general matches firing first.  To set a trace:
myeav trace write $id $attribute_name $cmdPrefix
The command prefix has the following signature:
operation entity attribute value
$operation is one of 
write or 
unset.