# for Emacs: -*- mode: org; mode: flyspell; fill-column: 79 -*-

# We will be importing several models and metamodels (UML, user model1, user
# model2,...). We want a way to find out all elements that belong to each

| TABLE      | models                  | model           |       | The models that were imported in the database |
| id         | AUTOINCREMENT           | PK              |       |                                               |
| xmi        | TEXT                    | NOT NULL, INDEX |       |                                               |
| name       | TEXT                    | NOT NULL        |       |                                               |
| super      | FK elements(superClass) |                 |       | Model element to use to find superclasses     |
| is_profile | BOOLEAN                 | NOT NULL        | false |                                               |
| nsPrefix   | TEXT                    |                 |       | for xmi export                                |
| nsUri      | TEXT                    |                 |       | for xmi export                                |

# The various elements present in a model (classes, properties,
# associations,...)
#
# The name of the element is stored directly in this table, for efficiency. It
# would be more logical to store it in the attributes table as all other
# attributes, so that for instance we do not need to hard-code that
# ownedAttributes contains "name". But since this is such a special attribute
# we would need hard-coding in some places anyway.
#
#   Employee.get ("name")   reads the Models.name column in the database.
#   Class.get ("name")      also reads the column
#
# Some attributes are stored differently depending on whether we are
# manipulating the model or the metamodel. Some MOF attributes are represented
# as explicit columns in the tables. So for instance:
#
#   Employee_head.get ("upper")    # reads in the Attributes table (model level)
#   Class_isAbstract.get ("upper") # uses Properties.upper column (metamodel)
#
# As a result, we need some hard coding in the code to return all owned
# attributes of elements, also depending on the level:
#
#   Employee.get ("ownedAttribute") # reads the Properties table (model level)
#   Class.get ("ownedAttribute") # reads Properties, and adds name, upper...
#      This is the metamodel level, and "ownedAttribute" is the one defined in
#      MOF.

| TABLE       | elements               | db_element      |       | Stores all elements in models and metamodels                                                 |
| id          | AUTOINCREMENT          | PK              |       |                                                                                              |
| xmi         | TEXT                   | NOT NULL, INDEX |       | the unique identifier of the model element in form 'model's xmi:id':'element's xmi:id'       |
| name        | TEXT                   | INDEX           |       | the name of the element                                                                      |
| is_abstract | BOOLEAN                | NOT NULL        | false | makes sense only for MOF metaclasses, use standard properties otherwise                      |
| meta        | FK elements(instances) | NOT NULL        |       | meta-class. This will have a temporary incorrect value when loading the ecore:EClass element |
| from_model  | FK models(elements)    | NOT NULL        |       | The model to which this element belongs                                                      |

# CONSTRAINT: lower <= upper

| ABSTRACT TABLE | multiplicity |          |       |                                                       |
| lower          | INTEGER      | NOT NULL |     1 | Lower bound for multiplicity                          |
| upper          | INTEGER      | NOT NULL |     1 | Upper bound for multiplicity (-1 for infinite) |
| ordered        | BOOLEAN      | NOT NULL | false | Whether this property is ordered                      |
| is_unique      | BOOLEAN      | NOT NULL | false | Whether values of this property must be unique        |

# The properties that are valid for an element. This table deals with the
# properties that have a primitiveType type. If they have a type defined as
# another element in the model, use the Associations table.
#
# There can be several rows with the same Element (for instance "name" applies
# to properties and classes in MOF). So we need a separate id.
#
# Their default values are stored in the Default_Values table. The multiplicity
# information in this table applies to general property itself (for instance
# "ownedAttribute" in UML is 0..*), but each of the properties should have its
# own "lower", "upper",... attributes (like "Employee.computers" is 1..2)
# stored in the Attributes table.
#
#  +---------------+                         +-----------+
#  | Property      |--meta-----------values--| Attribute |
#  |  multiplicity |   1                *    |  value    |
#  +---------------+                         |  order_by |
#      | 1       | *                         +-----------+
#  as_property   properties                       | *
#      |         |                              attributes
#    element     owner                            |
#      | 1       | 1                              |
#     +-------------+                             |
#     | Element     |--owner----------------------+
#     +-------------+    1
#
# CONSTRAINT: a single property with isID=True for a model
# CONSTRAINT: if the property is an enum, value must be in the literals table

| TABLE (multiplicity) | properties               | property        |       | Valid properties for elements in models                                            |
| id                   | AUTOINCREMENT            | PK              |       |                                                                                    |
| xmi                  | TEXT                     | NOT NULL, INDEX |       |                                                                                    |
| element              | FK elements(as_property) | NOT NULL        |       | The element that represents this property, and to which attributes can be attached |
| owner                | FK elements(properties)  | NOT NULL        |       | Element to which the attribute belongs                                             |
| read_only            | BOOLEAN                  | NOT NULL        | false | Whether this property is read only                                                 |
| derived              | BOOLEAN                  | NOT NULL        | false | Whether this is a derived property                                                 |
| is_id                | BOOLEAN                  | NOT NULL        | false | Whether this attribute represents a unique ID                                      |

# Use a separate table to store default values, since in some models or
# metamodels the default values could be tuples, and thus in SQL we need a
# separate able (one-to-many relationships)

| TABLE    | default_values         | default_value |   |                                                                                                     |
| id       | AUTOINCREMENT          | PK            |   |                                                                                                     |
| property | FK properties(default) | NOT NULL      |   | The value for which we are specifying the default value                                             |
| order_by | INTEGER                | NOT NULL      | 1 | For ordered lists of values                                                                         |
| value    | TEXT                   | NOT NULL      |   | The default value of the property. There could be several rows if the cardinality is greater than 1 |

# There could be multiple lines for the same owner, in case the cardinality is
# greater than 1
# CONSTRAINT: if the property is an enum, value must be in the literals table

| TABLE    | attributes              | attribute |   | Actual values of properties in models                                            |
| id       | AUTOINCREMENT           | PK        |   |                                                                                  |
| owner    | FK elements(attributes) | NOT NULL  |   |                                                                                  |
| meta     | FK properties(values)   | NOT NULL  |   |                                                                                  |
| order_by | INTEGER                 | NOT NULL  | 1 | For ordered lists of values                                                      |
| value    | TEXT                    |           |   | Always scalar or string. If you need to associate two models, use a Link instead |

# This table describes valid associations between elements of the metamodel.
# It is not used for the models themselves, which instead provide instances of
# these associations known as links.
# For instance, this table will describe that a Class owns some Properties.
# This table will not accept n-ary associations between elements of the
# metamodels, but this is not a case we want to handle anyway (not needed for
# UML)
# Separating Associations and Association_Ends allow symmetric handling of
# "opposite" ends of an association: this relationship is implicit, and always
# goes both directions since the ends are defined as part of the association
# itself.

| TABLE | associations                    | association     |    | Valid associations between elements in models                             |
| id    | AUTOINCREMENT                   | PK              |    |                                                                           |
| label | FK elements(as_association)     | NULL            | -1 | Label of the association (for GUI representation, mostly)                 |
| xmi   | TEXT                            | NOT NULL, INDEX |    |                                                                           |
| end1  | FK association_ends(assoc_end1) | NOT NULL        |    | The end that describes the property of the source element (name : Target) |
| end2  | FK association_ends(assoc_end2) | NOT NULL        |    | The end that describes the property of the target element (name : Source) |

| TABLE (multiplicity) | association_ends    | association_end |       | Each end of an metamodel association                                                                   |
| id                   | AUTOINCREMENT       | PK              |       |                                                                                                        |
| xmi                  | TEXT                | NOT NULL, INDEX |       |                                                                                                        |
| kind                 | FK elements()       | NOT NULL        |       | The metaclass for this end                                                                             |
| element              | FK elements(as_end) |                 |       | The element that gives the name of the association end. Null if not navigable and multiplicity is 1..1 |
| read_only            | BOOLEAN             | NOT NULL        | false | Whether this association is read only                                                                  |
| derived              | BOOLEAN             | NOT NULL        | false | Whether this is a derived association                                                                  |
| containment          | BOOLEAN             | NOT NULL        | false | Whether element owns the other end of the association                                                  |

| TABLE    | links                      | link     |   | instances of associations |
| id       | AUTOINCREMENT              | PK       |   |                           |
| meta     | FK associations(instances) | NOT NULL |   |                           |
| end1     | FK elements(links_from)    | NOT NULL |   |                           |
| end2     | FK elements(links_to)      | NOT NULL |   |                           |
| order_by | INTEGER                    | NOT NULL | 1 |                           |

| TABLE | literals              | literal  |   | Possible values for enumerations        |
| id    | AUTOINCREMENT         | PK       |   |                                         |
| enum  | FK elements(literals) | NOT NULL |   | enumeration for which this is a literal |
| value | TEXT                  | NOT NULL |   |                                         |

| TABLE      | stereotype_applications | stereotype_application |   |   |
| id         | AUTOINCREMENT           | PK                     |   |   |
| element    | FK elements()           | NOT NULL               |   |   |
| stereotype | FK elements()           | NOT NULL               |   |   |

# @sogilis
# table to test MONEY type
| TABLE   | operations    | operation | | |
| id      | AUTOINCREMENT | PK        | | |
| account | INTEGER       | NOT NULL  | | |
| amount  | MONEY         | NOT NULL  | | |
