-- ------------------------------------------------------------------------------
-- $Author: vantanas $
-- $Date: 2020-04-13 05:24:53 -0400 (Mon, 13 Apr 2020) $ 
-- $Revision: 6617 $
-- $URL: svn://saulius-grazulis.lt/restful/tags/v0.15.2/sql/metatables/metatables_0.2.0.sql $
-- ------------------------------------------------------------------------------

-- The metatables describe fields (columns) in other tables of other
-- databases; they provide information that is not evident from the
-- SQL schema. The RestfulDB Web wrapper will consult these tables to
-- figure out how to generate forms or represent certain fields.

-- == CHANGELOG ==
--
-- metatables.sql (0.2.0)
--  * Added:
--    - the 'foruser' option of 'description'.'display';
--    - the 'data' option of 'description'.'coltype';
--    - the 'cdatetime' option of 'description'.'coltype'.
--  * Changed:
--    - the data type of the 'description'.'coltype' column
--      from 'VARCHAR(8)' to 'VARCHAR(9)';
--    - the data type of the 'description'.'dbname',
--      'description'.'dtable' and 'description'.'dbcolumn'
--      columns from 'VARCHAR(255)' to 'VARCHAR(128)'.
--  * Removed:
--    - the 'document_group' table.
-- metatables.sql (0.1.1)
--  * Added:
--    - the 'display' column in the 'description' table;
--    - the 'db_users' table
--  * Deprecated:
--    - the 'document_group' table.
-- metatables.sql (0.1.0)
--  * Initial release.
--

-- Semantic version number of the metadatabase schema

create table version (
       `id` integer primary key,
       `release_date` text,    -- release date of the schema version
       `number` text not null, -- semantic version number of the schema
       `schema_url` text       -- URL of the current schema
);

insert into version ( `id`, `release_date`, `number`, `schema_url` )
values ( '1', '2020-04-09', '0.2.0',
'svn+ssh://saulius-grazulis.lt/home/saulius/svn-repositories/restfuldb/trunk/sql/metatables/metatables_0.2.0.sql' );

-- Regular expressions are used to impose stricter requirements on
-- field values:

create table validation_regex (
       id integer primary key,
       regex text
);

-- 'coltype' value meanings:

-- id: *internal* database primary key; used for table
--     connections. SHOULD NOT be published externally; MAY change during
--     database life cycle.

-- fk: foreign key; points to the 'id' of another table; MUST NOT be
--     published externally; MAY change during database life
--     cycle. Subject to FOREIGN KEY constraints.

-- extkey: external unique key identifying a record (aka "business
--     key"; e.g. SOLSA ID of a sample or COD ID of a structure). MAY
--     be published externally; MAY be used for generating stable URIs
--     for record access. MUST NOT change during the database life
--     cycle. Assigned by external processes (such as sample
--     registration or record deposition).

-- uuid: globally unique record identifier; must be constrained to
--     uniqueness in the table. MAY be published externally; MAY be
--     used for generating stable URIs for record access. Assigned by
--     internal database management processes (such as record
--     insertion scripts). MAY change during the database life cycle,
--     but this means that the resource identified by the previous
--     UUID vanishes.

-- resource: a stable external identifier to an external database
--     (e.g. DOI, PDB ID, COD ID). Can be used for constructing of
--     stable URIs to external and internal resources.

-- url: An URL (URI) pointing to an external resource. MAY be used to
--      generate external references (anchors).

-- image: This column contains an image; its SQL type should be BLOB.

-- file: This column contains a file contents; its SQL type should be
--       BLOB. File contents should be handles correctly by default
--       BLOB treatment, but we may wish to mark this coltype
--       explicitly.

-- cssclass: the described column contains a CSS class that should be
--      assigned to another columns (X)HTML representation; the target
--      column name is specified in the 'fk_target' field of the
--      'description' table.

-- mimetype: the described column contains a MIME type of another
--      column; the target column name is specified in the 'fk_target'
--      field of the 'description' table.

-- format: the described column contains a format designator of
--      another column; the target column name is specified in the
--      'fk_target' field of the 'description' table. The format is
--      supposed to be application-specific, but it can be used to
--      mark files that do not have their MIME types registered or to
--      distinguish different file formats with the same MIME type
--      (e.g. different encodings of the hyperspectral image raster,
--      where the raster itself will have mime type
--      'application/octet-stream').

-- dbrev: the described column is a reference (foreign key) to a
--        special revision table; a new revision record MUST be
--        created with each insert, delete or update (preferably
--        automatically).

-- cdate: current (change) date; such dates will be suggested to be
--        the data entry date in 'new record' forms.

-- ctime: current (change) time; such dates will be suggested to be
--        the data entry time in 'new record' forms.

-- cdatetime: current (change) datetime; such dates will be suggested to
--            be the data entry datetime in 'new record' forms.

-- markdown: the column contains text in Markdown syntax and should be
--           properly displayed.

-- md5: the described column contains the md5 checksum of another
--      column; the target column name is specified in the 'fk_target'
--      field of the 'description' table.

-- filename: The file name that was uploaded to another ('file')
--           column; the 'fk_target' field of the 'description' table
--           specifies what column it is.

-- imguri: The column is a (stable!) URI of an external image that
--         should be displayed in-line (using <img href=""/>)

-- data: A regular column. This setting supersedes all guesswork that
--       could be applied to detect the type of the column from its name.

-- FIXME(S.G.): The following column descriptors are not yet
--              implemented but are planned for the future:

-- sha1: the described column contains the sha1 checksum of another
--       column; the target column name is specified in the 'fk_target'
--       field of the 'description' table.

-- sha256: the described column contains the sha256 checksum of another
--         column; the target column name is specified in the 'fk_target'
--         field of the 'description' table.

-- sha512: the described column contains the sha512 checksum of another
--         column; the target column name is specified in the 'fk_target'
--         field of the 'description' table.

-- script: The column value is a parameter of a generic script that
--         renders its value on a HTML page. (A.V.: sounds
--         dangerous...). Values must be sanitised properly!
--         (S.G.).

create table description (
       id integer primary key, -- coltype 'id' -- self-describing :)
       dbname varchar(128),
       dbtable varchar(128),
       dbcolumn varchar(128),
       -- coltype enum( 'id', 'fk', 'extkey', 'url', 'resource',
       -- 'uuid', 'image', 'file', 'cssclass', 'mimetype', 'format',
       -- 'dbrev', 'cdate', 'ctime', 'cdatetime', 'markdown', 'md5',
       -- 'filename', 'imguri', 'data' ),
       coltype varchar(9),
       fk_target integer,
       -- relation enum('1','N'),
       relation char(1),
       -- visualisation enum('table','card','none'),
       visualisation char(5),
       validation_regex_id integer,
       -- display enum('always','notnull','never','foruser'),
       display char(7),
       constraint coltype unique (dbname,dbtable,dbcolumn,coltype),
       foreign key (fk_target) references description(id),
       foreign key (validation_regex_id) references validation_regex(id)
);

create table altname (
       id integer primary key,
       column_id integer,
       altname text,
       language char(5),
       foreign key (column_id) references description(id)
);

-- The `enumeration` table contains value suggestions for enumerator
-- columns:

create table enumeration (
       id integer primary key,
       column_id integer,
       `option` text,
       foreign key (column_id) references description(id)
);

-- For the 'resource' and possibly for the 'uuid' and 'extkey'
-- columns, the `resolver` table can contain base URLs that can be
-- used to convert resource values (IDs) to Web URI references. Simple
-- concatenation is supposed to be used:

-- For example: A database `proteins` table `structures` contains column `pdbid`
-- which is described as `resource`:

-- restfuldb.description contains:
-- +----+----------+-----------+----------+----------+
-- | id | dbname   | dbtable   | dbcolumn | coltype  |
-- +----+----------+-----------+----------+----------+
-- | 12 | proteins | structure | pdbid    | resource |
-- +----+----------+-----------+----------+----------+

-- restfuldb.resolver contains:
-- +----+-----------+------------+----------------------------+
-- | id | column_id | is_primary | baseurl                    |
-- +----+-----------+------------+----------------------------+
-- |  4 |        12 |          1 | https://www.pdb.org/files/ |
-- +----+-----------+------------+----------------------------+

-- restfuldb.suffix contains:
-- +----+-------------+------------+--------+
-- | id | resolver_id | is_primary | suffix |
-- +----+-------------+------------+--------+
-- |  4 |           4 |          1 | .cif   |
-- +----+-------------+------------+--------+

-- proteins.structure contains
-- +----+-------+
-- | id | pdbid |
-- +----+-------+
-- | 56 |  1knv |
-- +----+-------+

-- The following URI can then be constructed:
-- https://www.pdb.org/pdb/files/1knv.cif

-- 'is_primary = 1' means that this column is intended to be selected
-- by default.

create table resolver (
       id integer primary key,
       column_id integer,
       is_primary integer,
       baseurl text,
       foreign key (column_id) references description(id)
);

create table suffix (
       id integer primary key,
       resolver_id integer,
       is_primary integer,
       suffix text,
       foreign key (resolver_id) references resolver(id)
);

create table format (
       id integer primary key,
       column_id integer,
       is_primary integer,
       -- format enum('png','jpeg','xml','cif','json','jmol-cif','jmol-sdf')
       format varchar(20),
       foreign key (column_id) references description(id)
);

-- Evaluators can be used to produce default values for the specified
-- database columns:

create table evaluator (
       id integer primary key,
       column_id integer,
       evaluator text,
       arguments text, -- list of arguments that are used for this
                       -- evaluator (proglang specific)
       proglang text,  -- programming language for this `evaluator`
       foreign key (column_id) references description(id)
);

-- Foreign key format defines the way table records are displayed in
-- foreign key references in other tables. Format strings must be
-- compatible with Perl module Text::sprintfn.

create table fk_format (
       id integer primary key,
       dbname varchar(255),
       dbtable varchar(255),
       format text,
       constraint dbtable unique (dbname,dbtable)
);

-- Suggestion ranges for columns with suggested values.

create table numbers (
       id integer primary key,
       column_id integer not null, -- column with suggested value
       `range` varchar(12) not null,
       user varchar(255) not null, -- name of the user associated with
                                   -- the range
       foreign key (column_id) references description(id)
);

-- Database users table can be used as alternative step for user 
-- authorization SQL database.

create table db_users (
    id integer primary key,
    db_username varchar(255) not null,  -- Database username
    username_hash varchar(64) not null, -- SHA256 hexadecimal string of
                                        -- the authenticated username 
                                        -- under Apache server
    unique (username_hash)
);
