-- ------------------------------------------------------------------------------
-- $Author: saulius $
-- $Date: 2022-04-10 12:45:31 -0400 (Sun, 10 Apr 2022) $ 
-- $Revision: 7611 $
-- $URL: svn://saulius-grazulis.lt/restful/tags/v0.16.0/sql/metatables/metatables_0.2.5.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.5)
--  * Added:
--    - columns 'name', 'description' and 'explanation' to 'table_description'
--      table.
-- metatables.sql (0.2.4)
--  * Added:
--    - The 'fmttable' column to the 'fk_format' table to specify a table from
--      which foreign key representation data should be taken according to the
--      'format' description.
-- metatables.sql (0.2.3)
--  * Added:
--    - support for 'sha1', 'sha256' and 'sha512' column types.
--  * Changed:
--    - the 'numbers'.'range' column is now text (to accommodate long suggestions).
-- metatables.sql (0.2.2)
--  * Added:
--    - the 'table_description' table;
--    - the 'printf_format' column in the 'description' table.
-- metatables.sql (0.2.1)
--  * Added:
--    - the 'measurement_unit' table;
--    - the 'measurement_unit_id' column in the 'description' table.
--  * Changed:
--    - the 'numbers'.'user' column to allow NULL values.
-- 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'.'dbtable' 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', '2022-04-08', '0.2.5',
'svn+ssh://saulius-grazulis.lt/home/saulius/svn-repositories/restfuldb/trunk/sql/metatables/metatables_0.2.5.sql' );

create table `table_description` (
       `id` integer primary key,
       `dbname` varchar(128),
       `dbtable` varchar(128),
       `name` text,
       `description` text,
       `explanation` text,
       `is_read_only` integer,
       constraint `UQ_table_description_dbtable` unique (dbname,dbtable)
);

create table `measurement_unit` (
       `id` integer primary key,
       `name` text,
       `symbol` text
);

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

-- Regular expressions MUST NOT contain string start or end anchors
-- (trailing '^' and leading '$'), as the regular expression is assumed
-- to match the whole input (metasymbols added automatically).

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.

-- 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.

-- 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:

-- 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),
       measurement_unit_id integer,
       printf_format varchar(1024),
       constraint coltype unique (dbname,dbtable,dbcolumn,coltype),
       foreign key (fk_target) references description(id),
       foreign key (validation_regex_id) references validation_regex(id),
       foreign key (measurement_unit_id) references measurement_unit(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),
       fmttable varchar(255),
-- The 'fmttable' column describes an additional table from which
-- information to be displayed under the `format` description will be
-- taken. This additional table is usually supposed to be a database
-- view, denormalised as a rule, so that additional information useful
-- for the user can be picked form these views and displayed alongside
-- or instead of the unique IDs to make rows addressed by foreign keys
-- easier to recognise. The format specified in the `format` column
-- refers to the columns in this table (view) if the 'fmttable' is
-- present. Otherwise it refers to columns in the FK target table
-- itself.
--
-- For this method to work, several restrictions are placed on tables
-- (views) that are specified as 'fmttable' values. The number of rows
-- in the 'fmttable' table MUST be the same as in the original table
-- to which the foreign key references. Also, the column to which the
-- foreign key references MUST have the same name and MUST have the
-- same values as the original table column. These requirements can be
-- satisfied by using, say, 'CREATE VIEW fk_target_view AS SELECT
-- original_fk_target.*, additional_fk_information.* FROM
-- original_fk_target LEFT JOIN additional_fk_information USING(`id`)'
-- and define 'fmttable="fk_target_view"'.
--
-- The 'fmttable' value can be specified in the 'fmttable' attribute
-- of the <FKRepresentation> XML element when describing relational
-- databases according to the
-- "http://crystallography.net/xml/schema/restfuldb-metadata" schema
-- as of version 0.1.0-rc.8.
       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` text not null,
       user varchar(255), -- name of the user associated with the
                          -- range, NULL values mark ranges common to
                          -- all users
       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)
);
