# DataElements

All information in the DataStore repository is stored in the form of DataElements. DataElements are objects that have attributes and may contain other DataElements. The attributes of a DataElement are stored as an array of strings. A particular attribute is retrieved by calling `getAttribute(`attribute index`)`. A particular attribute is set by calling `setAttribute(`attribute index`,` attribute value`)`. The attribute indices that can be used are as follows:

Attribute | Description
`A_TYPE` | Attribute indicating the type of object. The type can be used to indicate the type of an instance of data, a descriptor, a relationship or a commnad.
`A_NAME` | Attribute indicating the name of object.
`A_VALUE` | Attribute indicating the more information about that object
`A_SOURCE` | Attribute indicating source information about an object, if applicable
`A_REF_TYPE` | Attribute indicating whether the object is a normal object ("value"), a spirit ("spirit"), or a reference to another DataElement ("reference"). In the DataStore, a reference to another DataElement is represented with a DataElement. For more information on spirit elements, see Memory Management in DataStore
`A_ID` | The unique ID of a DataElement.

Rather than representing different types of objects as different classes, the type attribute of a DataElement indicates its type. There are two general categories of DataElements. There are schema elements, descriptors, and instances of those schema elements, instances.

## Descriptors

A descriptor is a DataElement that describes some type of object. The `A_TYPE` attribute of a descriptor indicates what type of descriptor it is. The `A_NAME` attribute of a descriptor identifies the type that the descriptor describes.

A descriptor may be of one of the following types:

`T_OBJECT_DESCRIPTOR` | Describes a type of object
`T_RELATION_DESCRIPTOR` | Describes a type of relationship that may exist between two DataElements.
`T_COMMAND_DESCRIPTOR` | Describes a type of command

### Object Descriptors

Object descriptors describe the different types of data that can be represented in the DataStore repository. Object descriptors can describe types of object instances as well as other types of object descriptors. Each object descriptor is related to other object, relationship and command descriptors.

### Relation Descriptors

Relation descriptors describe the different types of relationships that can be represented in the DataStore repository. Relation descriptors describe types of relationships between object instances, object descriptors, command instances and command descriptors.

### Command Descriptors

Command descriptors describe the different types of commands that can be executed on an object in the DataStore repository. In the DataStore schema, object descriptors are related to command descriptors to indicate that an object instance of a certain type can have the described command run on it. Command descriptors are always contained by the object descriptors they are associated with. The `A_SOURCE` attribute of a command descriptor indicates which miner(s) may execute an instance of such a command.

These three types of objects are used to define the DataStore schema. Instances of relation descriptors are used to define relationships between descriptors in the schema.

## Instances

An instance object is a DataElement that is an instance of a descriptor. An instance may either by an object, a relation or a command. An instance uses its descriptor's `A_NAME` attribute as its `A_TYPE` attribute.

### Objects

Objects are instances of object descriptors. Objects are used to the represent the external or internal entities that are being interacted with. An instance object can be related in a certain way to another type of instance object if its object descriptor has the same kind of relationship to the other object's object descriptor. An instance object may be associated with a particular command if its object descriptor is associated with the command descriptor for that command.

### Relations

Relations are instances of relation descriptors. A relation is really a typed reference to another object. Relations may exist from one object to another if the schema indicates that the object descriptor for the first object may have a relationship of that type to the other object's descriptor. Relations are used to describe the relationship between two instances, the relationship between two descriptors and the relationship between an instance and a descriptor. A relation is able to reference another element by storing the other element's `A_ID` attribute in its `A_SOURCE` attribute. If a relation object needs to be dereferenced, it uses this attribute to query the DataStore for the object being referenced.

A relation is typically represented by having an instance object DataElement contain a relation DataElement. There are two types of relationships between elements that are implicit. These are the contains and the parent of relationships. If an element is directly contained within another element, the relationship between those two elements is implied to be contains/parent of relationships.

### Commands

Commands are instances of command descriptors. A command is always associated with an instance object such that the command is to be performed on that object. The object associated with a command is referred to as the subject of the command. Only a command that has a command descriptor that is related to the object descriptor of the subject may be constructed. A command object is constructed when the DataStore method `command()` is called. The command is created with a reference to the subject, an optional set of arguments, also instance objects, and a status object instance, used to indicate the state of the command. The tree of elements for a command is communicated, via the DataStore comm layer, to the appropriate miner(s), where it is interpreted and executed.

The structure of a command looks like the following:

- Command
  - subject - a reference to the instance that this command applies to
  - arg 1 - an optional argument represented as a DataElement
  - ...
  - arg n - an optional argument represented as a DataElement
  - status - element that represents the current status of a command

As an example, suppose the DataStore is being used for browsing a filesystem. The filesystem entities and how to interact with the filesystem needs to be defined in the schema. The following descriptors could be used to describe this.

- Object Descriptors
  - "generic file object" - describes a generic file system object
  - "file" - describes a file object
  - "folder" - describes a folder object
- Relation Descriptors
  - "contains" - represents the containment relationship between two objects
  - "abstracts" - represents a derives relationship between two object descriptors
  - "abstracted by" - represents an inherits relationship between two object descriptors
- Command Descriptors
  - "query" - a command to list the contents of a folder
  - "rename" - a command to rename a file or folder
  - "delete" - a command to delete a file or folder
  - "create" - a command to create a new file or folder from an existing folder

Now that all the required descriptors are defined, relations between descriptors are needed. Note that the symbol "->" implies a "contains" relationship and "IO()" implies an instance of a specified descriptor.

- "generic file object"
  - ->"rename"
  - ->"delete"
  - ->IO("abstracts")->"folder"
  - ->IO("abstracts")->"file"
- "folder"
  - ->"create"
  - ->"query"
  - ->IO("abstracted by")->"generic file object"
  - ->IO("contains")->"generic file object"
- "file"
  - ->IO("abstracted by")->"generic file object"

DataStore schemas are created by the DataStore miners. Each tool contributes it's own schema to the DataStore schema, referencing descriptors of other schemas, such that one tool can contribute to another tool. All the command descriptors that are contributed by a miner are expected to be handled by the contributing miner. Whenever a miner creates a new command descriptor, the `A_SOURCE` attribute indicates to the DataStore that an instance of that command should be routed to that miner when it's issued.

See the section, Miners to find out how miners contribute schemas and execute commands.