Annotation of embedaddon/sqlite3/tool/genfkey.README, revision 1.1.1.1

1.1       misho       1: 
                      2: OVERVIEW
                      3: 
                      4:   The SQLite library is capable of parsing SQL foreign key constraints 
                      5:   supplied as part of CREATE TABLE statements, but it does not actually 
                      6:   implement them. However, most of the features of foreign keys may be
                      7:   implemented using SQL triggers, which SQLite does support. This text
                      8:   file describes a feature of the SQLite shell tool (sqlite3) that
                      9:   extracts foreign key definitions from an existing SQLite database and
                     10:   creates the set of CREATE TRIGGER statements required to implement
                     11:   the foreign key constraints.
                     12: 
                     13: CAPABILITIES
                     14: 
                     15:   An SQL foreign key is a constraint that requires that each row in
                     16:   the "child" table corresponds to a row in the "parent" table. For
                     17:   example, the following schema:
                     18: 
                     19:     CREATE TABLE parent(a, b, c, PRIMARY KEY(a, b));
                     20:     CREATE TABLE child(d, e, f, FOREIGN KEY(d, e) REFERENCES parent(a, b));
                     21: 
                     22:   implies that for each row in table "child", there must be a row in
                     23:   "parent" for which the expression (child.d==parent.a AND child.e==parent.b) 
                     24:   is true. The columns in the parent table are required to be either the
                     25:   primary key columns or subject to a UNIQUE constraint. There is no such
                     26:   requirement for the columns of the child table.
                     27: 
                     28:   At this time, all foreign keys are implemented as if they were 
                     29:   "MATCH NONE", even if the declaration specified "MATCH PARTIAL" or 
                     30:   "MATCH FULL". "MATCH NONE" means that if any of the key columns in
                     31:   the child table are NULL, then there is no requirement for a corresponding
                     32:   row in the parent table. So, taking this into account, the expression that
                     33:   must be true for every row of the child table in the above example is
                     34:   actually:
                     35: 
                     36:       (child.d IS NULL) OR 
                     37:       (child.e IS NULL) OR 
                     38:       (child.d==parent.a AND child.e==parent.b)
                     39: 
                     40:   Attempting to insert or update a row in the child table so that the 
                     41:   affected row violates this constraint results in an exception being 
                     42:   thrown.
                     43: 
                     44:   The effect of attempting to delete or update a row in the parent table 
                     45:   so that the constraint becomes untrue for one or more rows in the child
                     46:   table depends on the "ON DELETE" or "ON UPDATE" actions specified as
                     47:   part of the foreign key definition, respectively. Three different actions
                     48:   are supported: "RESTRICT" (the default), "CASCADE" and "SET NULL". SQLite
                     49:   will also parse the "SET DEFAULT" action, but this is not implemented
                     50:   and "RESTRICT" is used instead.
                     51: 
                     52:     RESTRICT: Attempting to update or delete a row in the parent table so
                     53:               that the constraint becomes untrue for one or more rows in
                     54:               the child table is not allowed. An exception is thrown.
                     55: 
                     56:     CASCADE:  Instead of throwing an exception, all corresponding child table
                     57:               rows are either deleted (if the parent row is being deleted)
                     58:               or updated to match the new parent key values (if the parent 
                     59:               row is being updated).
                     60: 
                     61:     SET NULL: Instead of throwing an exception, the foreign key fields of
                     62:               all corresponding child table rows are set to NULL.
                     63: 
                     64: LIMITATIONS
                     65: 
                     66:   Apart from those limitiations described above:
                     67: 
                     68:     * Implicit mapping to composite primary keys is not supported. If
                     69:       a parent table has a composite primary key, then any child table
                     70:       that refers to it must explicitly map each column. For example, given
                     71:       the following definition of table "parent":
                     72: 
                     73:         CREATE TABLE parent(a, b, c, PRIMARY KEY(a, b));
                     74: 
                     75:       only the first of the following two definitions of table "child"
                     76:       is supported:
                     77: 
                     78:         CREATE TABLE child(d, e, f, FOREIGN KEY(d, e) REFERENCES parent(a, b));
                     79:         CREATE TABLE child(d, e, f, FOREIGN KEY(d, e) REFERENCES parent);
                     80: 
                     81:       An implicit reference to a composite primary key is detected as an
                     82:       error when the program is run (see below).
                     83: 
                     84:     * SQLite does not support recursive triggers, and therefore this program
                     85:       does not support recursive CASCADE or SET NULL foreign key 
                     86:       relationships. If the parent and the child tables of a CASCADE or
                     87:       SET NULL foreign key are the same table, the generated triggers will
                     88:       malfunction. This is also true if the recursive foreign key constraint
                     89:       is indirect (for example if table A references table B which references
                     90:       table A with a CASCADE or SET NULL foreign key constraint).
                     91: 
                     92:       Recursive CASCADE or SET NULL foreign key relationships are *not*
                     93:       detected as errors when the program is run. Buyer beware.
                     94: 
                     95: USAGE
                     96: 
                     97:   The functionality is accessed through an sqlite3 shell tool "dot-command":
                     98: 
                     99:     .genfkey ?--no-drop? ?--ignore-errors? ?--exec?
                    100: 
                    101:   When this command is run, it first checks the schema of the open SQLite
                    102:   database for foreign key related errors or inconsistencies. For example,
                    103:   a foreign key that refers to a parent table that does not exist, or
                    104:   a foreign key that refers to columns in a parent table that are not
                    105:   guaranteed to be unique. If such errors are found and the --ignore-errors
                    106:   option was not present, a message for each one is printed to stderr and
                    107:   no further processing takes place.
                    108: 
                    109:   If errors are found and the --ignore-errors option is passed, then
                    110:   no error messages are printed. No "CREATE TRIGGER" statements are generated
                    111:   for foriegn-key definitions that contained errors, they are silently
                    112:   ignored by subsequent processing.
                    113: 
                    114:   All triggers generated by this command have names that match the pattern
                    115:   "genfkey*". Unless the --no-drop option is specified, then the program
                    116:   also generates a "DROP TRIGGER" statement for each trigger that exists
                    117:   in the database with a name that matches this pattern. This allows the
                    118:   program to be used to upgrade a database schema for which foreign key
                    119:   triggers have already been installed (i.e. after new tables are created
                    120:   or existing tables dropped).
                    121: 
                    122:   Finally, a series of SQL trigger definitions (CREATE TRIGGER statements) 
                    123:   that implement the foreign key constraints found in the database schema are
                    124:   generated.
                    125: 
                    126:   If the --exec option was passed, then all generated SQL is immediately
                    127:   executed on the database. Otherwise, the generated SQL strings are output
                    128:   in the same way as the results of SELECT queries are. Normally, this means
                    129:   they will be printed to stdout, but this can be configured using other
                    130:   dot-commands (i.e. ".output").
                    131: 
                    132:   The simplest way to activate the foriegn key definitions in a database
                    133:   is simply to open it using the shell tool and enter the command 
                    134:   ".genfkey --exec":
                    135: 
                    136:     sqlite> .genfkey --exec
                    137: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>