Documentation is available at schema-defs.php
- <?php
- /* ******************************************************************** */
- /* CATALYST PHP Source Code */
- /* -------------------------------------------------------------------- */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to: */
- /* The Free Software Foundation, Inc., 59 Temple Place, Suite 330, */
- /* Boston, MA 02111-1307 USA */
- /* -------------------------------------------------------------------- */
- /* */
- /* Filename: schema-defs.php */
- /* Author: Paul Waite */
- /* Description: Definitions for managing DATABASE SCHEMAS */
- /* The schema class can be used to read in a database */
- /* table-by-table, or all at once. */
- /* */
- /* The main use of this class is to provide a means of */
- /* developing a child-class which reads a specific type */
- /* of database (eg. see pg-schema-defs.php). */
- /* */
- /* ******************************************************************** */
- /** @package database *//** Run getchema() in recusrive mode - follow foreign keys */
- ("ALL", "all");
- /** Run getschema() to get primary key(s) only */
- ("PRIMARY_KEY_ONLY", "p");
- /** Run getschema() to get only current table fields (no recursion) */
- ("FIELDS_ONLY", "f");
- // ----------------------------------------------------------------------
- /** Defines a virtual object which is used to denote something which
- * is a part of an existing database schema.
- * @package database
- */
- class SchemaObject {
- /** Reference to the schema object this belongs to */
- var $schema;
- /** Name of this schema object */
- var $name = "";
- // ....................................................................
- /** Constructor
- * Every schema object must belong to a schema. This is passed as the first
- * argument, as an object reference. It must also have a name, and this is
- * always passed as the second argument, a string.
- * @param reference $schema Reference to a schema object this object belongs to
- * @param string $name The name of this object
- */
- function SchemaObject($schema, $name) {
- $this->schema = $schema;
- $this->name = $name;
- }
- } // class SchemaObject
- // ----------------------------------------------------------------------
- /** Defines a database sequence.
- * @package database
- */
- class dbsequence extends SchemaObject {
- // ....................................................................
- function dbsequence(&$schema, $name) {
- $this->SchemaObject($schema, $name);
- }
- // ....................................................................
- /**
- * Acquires the schema from database metadata.
- * NB: Override this function to get schema info per DB type.
- */
- function getschema() { }
- // ....................................................................
- // Dump ascii description of this sequence to stdout.
- function dump() {
- $s = "Sequence $this->name";
- return "$s\n";
- }
- // ....................................................................
- // Return SQL required to create this sequence.
- function create() {
- $s .= "create sequence \"$this->name\"";
- $s .= ";\n";
- return $s;
- }
- // ....................................................................
- // Return SQL to drop this sequence.
- function drop() {
- $s .= "drop sequence $this->name;\n";
- return $s;
- }
- }
- // ----------------------------------------------------------------------
- /** Defines a database function (procedure).
- * @package database
- */
- class dbfunction extends SchemaObject {
- var $return_type = "";
- var $src = "";
- var $arg_types = array();
- var $language = "";
- // ....................................................................
- function dbfunction(&$schema, $name, $returns="", $src="", $args="", $lang="plpgsql") {
- $this->SchemaObject($schema, $name);
- $this->set($returns, $src, $args, $lang);
- }
- // ....................................................................
- /** Set the vars for this function */
- function set($returns="", $src="", $args="", $lang="plpgsql") {
- $this->return_type = $returns;
- $this->src = str_replace("'", "''", $src);
- if (is_array($args)) $this->arg_types = $args;
- $this->language = $lang;
- }
- // ....................................................................
- /**
- * Acquires the schema from database metadata.
- * NB: Override this function to get schema info per DB type.
- */
- function getschema() { }
- // ....................................................................
- /** Dump ascii description of this function to stdout. */
- function dump() {
- $s = "Function $this->name returns $this->returns language='$this->language'";
- return "$s\n";
- }
- // ....................................................................
- /** Return the types parameter list, including brackets. */
- function parameters() {
- $s = "";
- $s .= " (";
- if (count($this->arg_types) > 0) {
- foreach ($this->arg_types as $arg) {
- $s .= "$arg,";
- }
- $s = substr($s, 0, -1);
- }
- $s .= ")";
- return $s;
- }
- // ....................................................................
- // Return SQL required to create this function.
- function create() {
- $s .= "create function \"$this->name\"";
- $s .= $this->parameters();
- $s .= " returns $this->return_type";
- $s .= " as '$this->src'";
- $s .= " language $this->language";
- $s .= ";\n";
- return $s;
- }
- // ....................................................................
- // Return SQL to drop this function..
- function drop() {
- $s .= "drop function $this->name";
- $s .= $this->parameters();
- $s .= ";\n";
- return $s;
- }
- } // class dbfunction
- // ----------------------------------------------------------------------
- /** Defines a database index.
- * @package database
- */
- class dbindex extends SchemaObject {
- /** Name of table index is built on */
- var $tablename;
- /** Fieldnames in the index */
- var $fieldnames = array();
- /** True if index is for a primary key */
- var $primary = false;
- /** True if index is unique */
- var $unique = false;
- // ....................................................................
- function dbindex(&$schema, $name, $tablename="", $flds="", $primary=false, $unique=false) {
- $this->SchemaObject($schema, $name);
- $this->set($tablename, $flds, $primary, $unique);
- }
- // ....................................................................
- /** Set index variables. */
- function set($tablename="", $flds="", $primary=false, $unique=false) {
- $this->tablename = $tablename;
- if (is_array($flds)) $this->fieldnames = $flds;
- $this->primary = $primary;
- $this->unique = $unique;
- }
- // ....................................................................
- /**
- * Acquires the schema from database metadata.
- * NB: Override this function to get schema info per DB type.
- */
- function getschema() { }
- // ....................................................................
- /** Dump ascii description of this index to stdout. */
- function dump() {
- $bits = explode("create", $this->create());
- return str_replace(";", "", trim($bits[1])) . "\n";
- }
- // ....................................................................
- /** Return SQL required to create this index. */
- function create() {
- $s = "";
- $s .= "create";
- if ($this->unique) $s .= " unique";
- $s .= " index $this->name on " . $this->tablename;
- if ($this->access_method != "") {
- $s .= " using $this->access_method";
- }
- $s .= " (";
- if (count($this->fieldnames) > 0) {
- $flds = implode(",", $this->fieldnames);
- $s .= $flds;
- }
- $s .= ");\n";
- return $s;
- }
- // ....................................................................
- // Return SQL to drop this index.
- function drop() {
- $s = "drop index $this->name;\n";
- return $s;
- }
- } // class dbindex
- // ----------------------------------------------------------------------
- /** Defines a database constraint.
- * @package database
- */
- class dbconstraint extends SchemaObject {
- /** Type of constraint 'c' - check, 'p' - pk, 'f' - fk */
- var $type = "";
- /** Name of table constraint is applied to */
- var $tablename = "";
- /** Foreign key table name constraint refers to */
- var $fk_tablename = "";
- /** True if constraint is deferrable */
- var $deferrable = false;
- /** True if constraint is initially deferred */
- var $deferred = false;
- /** Array of table field names in constraint */
- var $fieldnames = array();
- /** Array of referenced foreign key fieldnames */
- var $fk_fieldnames = array();
- /** Action to take on update */
- var $update_action = "";
- /** Action to take on delete */
- var $delete_action = "";
- /** Match type for keys */
- var $match_type = "";
- /** Check constraint source */
- var $cksrc = "";
- // ....................................................................
- function dbconstraint(&$schema, $name, $type="p", $tablename="", $fktablename="", $flds="",
- $fkflds="", $updact="", $delact="", $match="", $cksrc="") {
- $this->SchemaObject($schema, $name);
- $this->set(
- $type,
- $tablename,
- $fktablename,
- $flds,
- $fkflds,
- $updact,
- $delact,
- $match,
- $cksrc
- );
- }
- // ....................................................................
- /** Set constraint variables. */
- function set(
- $type,
- $tablename="",
- $fktablename="",
- $flds="",
- $fkflds="",
- $updact="",
- $delact="",
- $match="",
- $cksrc="",
- $deferrable=false,
- $deferred=false
- ) {
- // The "!" implies 'leave as it is' ..
- if ($type != "!") $this->type = $type;
- if ($tablename != "!") $this->tablename = $tablename;
- if ($fktablename != "!") $this->fk_tablename = $fktablename;
- if (is_array($flds)) $this->fieldnames = $flds;
- if (is_array($fkflds)) $this->fk_fieldnames = $fkflds;
- if ($updact != "!") $this->update_action = $updact;
- if ($delact != "!") $this->delete_action = $delact;
- if ($match != "!") $this->match_type = $match;
- if ($cksrc != "!") $this->cksrc = $cksrc;
- if ($deferrable != "!") $this->deferrable = $deferrable;
- if ($deferred != "!") $this->deferred = $deferred;
- }
- // ....................................................................
- /**
- * Acquires the schema from database metadata.
- * NB: Override this function to get schema info per DB type.
- */
- function getschema() { }
- // ....................................................................
- /** Dump ascii description of this constraint to stdout. */
- function dump() {
- $bits = explode("add", $this->create());
- return str_replace(";", "", trim($bits[1])) . "\n";
- }
- // ....................................................................
- /** Return SQL required to create this as an inline table constraint */
- function create_inline() {
- return $this->create(false);
- }
- // ....................................................................
- /** Return SQL required to create this constraint outside the table */
- function create($outside_table=true) {
- $s = "";
- switch ($this->type) {
- // PRIMARY KEY CONSTRAINT
- case "p":
- if ($outside_table) {
- if ($this->tablename == "") return $s;
- $s .= "alter table " . $this->tablename . "\n";
- $s .= " add ";
- }
- $s .= "constraint $this->name primary key";
- $s .= $this->fields();
- break;
- // CHECK CONSTRAINT
- case "c":
- if ($outside_table) {
- if ($this->tablename == "") return $s;
- $s .= "alter table " . $this->tablename . "\n";
- $s .= " add ";
- }
- $s .= "constraint $this->name check $this->cksrc";
- break;
- // FOREIGN KEY CONSTRAINT
- case "f":
- if ($outside_table) {
- if ($this->tablename == "" || $this->fk_tablename == "") return $s;
- $s .= "alter table " . $this->tablename . "\n";
- $s .= " add ";
- }
- $s .= "constraint $this->name foreign key";
- $s .= $this->fields();
- $s .= " references " . $this->fk_tablename;
- $s .= $this->fk_fields();
- // MATCH TYPE
- switch ($this->match_type) {
- case "f":
- $s .= " match full";
- break;
- }
- // UPDATE ACTION
- if ($this->update_action != "") {
- $act = " on update";
- switch ($this->update_action) {
- case "a": $act .= " no action"; break;
- case "c": $act .= " cascade"; break;
- case "n": $act .= " set null"; break;
- case "r": $act .= " restrict"; break;
- case "d": $act .= " set default"; break;
- default: $act = "";
- }
- $s .= $act;
- }
- // DELETE ACTION
- if ($this->delete_action != "") {
- $act = " on delete";
- switch ($this->delete_action) {
- case "a": $act .= " no action"; break;
- case "c": $act .= " cascade"; break;
- case "n": $act .= " set null"; break;
- case "r": $act .= " restrict"; break;
- case "d": $act .= " set default"; break;
- default: $act = "";
- }
- $s .= $act;
- }
- // DEFERRABLE MODES
- if ($this->deferrable) {
- $s .= " deferrable";
- if ($this->deferred) {
- $s .= " initially deferred";
- }
- }
- break;
- }
- $s .= ";\n";
- return $s;
- }
- // ....................................................................
- // Unpacks the table fields array and returns '(field1,field2, ...)'..
- // These are the fields on the table the constraint is on.
- function fields() {
- $s .= "";
- if (count($this->fieldnames) > 0) {
- $s .= " (" . implode(",", $this->fieldnames) . ")";
- }
- return $s;
- }
- // ....................................................................
- // Unpacks the foreign key fields array and returns '(field1,field2, ...)'..
- // These are the fields on the table that the constraint references.
- function fk_fields() {
- $s .= "";
- if (count($this->fk_fieldnames) > 0) {
- $s .= " (" . implode(",", $this->fk_fieldnames) . ")";
- }
- return $s;
- }
- // ....................................................................
- // Return SQL to drop this constraint.
- function drop() {
- switch ($this->type) {
- case "p":
- case "f":
- case "c":
- $s .= "alter table " . $this->tablename . "\n";
- $s .= " drop constraint $this->name";
- $s .= " restrict;\n";
- break;
- }
- return $s;
- }
- // ....................................................................
- // Returns true if the given constraint matches this one in terms of
- // functionality. This allows you to identify constraints that are
- // the same apart from the naming.
- function matches($con) {
- if ($this->type != $con->type) return false;
- if ($this->tablename != $con->tablename) return false;
- if ($this->fk_tablename != $con->fk_tablename) return false;
- if ($this->deferrable != $con->deferrable) return false;
- if ($this->deferred != $con->deferred) return false;
- if ($this->fields() != $con->fields()) return false;
- if ($this->fk_fields() != $con->fk_fields()) return false;
- if ($this->update_action != $con->update_action) return false;
- if ($this->delete_action != $con->delete_action) return false;
- if ($this->match_type != $con->match_type) return false;
- if ($this->cksrc != $con->cksrc) return false;
- return true;
- }
- } // class dbconstraint
- // ----------------------------------------------------------------------
- /** Defines a database trigger.
- * @package database
- */
- class dbtrigger extends SchemaObject {
- /** When trigger fires. If true BEFORE, else AFTER event */
- var $before = true;
- /** If true, fire trigger on INSERT */
- var $oninsert = false;
- /** If true, fire trigger on DELETE */
- var $ondelete = false;
- /** If true, fire trigger on UPDATE */
- var $onupdate = false;
- /** If true, execute func for EACH ROW else EACH STATEMENT */
- var $eachrow = false;
- /** Name of table to apply trigger to */
- var $tablename;
- /** Name of function to call when triggered */
- var $funcname;
- /** Arguments to pass to the function */
- var $args = array();
- // ....................................................................
- function dbtrigger(
- &$schema,
- $name,
- $before=true,
- $oninsert=false,
- $ondelete=false,
- $onupdate=false,
- $eachrow=false,
- $tablename="",
- $funcname="",
- $args=""
- ) {
- $this->SchemaObject($schema, $name);
- $this->set($before, $oninsert, $ondelete, $onupdate, $eachrow, $tablename, $funcname, $args);
- }
- // ....................................................................
- /** Set the vars for this trigger */
- function set(
- $before=true,
- $oninsert=false,
- $ondelete=false,
- $onupdate=false,
- $eachrow=false,
- $tablename="",
- $funcname="",
- $args=""
- ) {
- $this->before = $before;
- $this->oninsert = $oninsert;
- $this->ondelete = $ondelete;
- $this->onupdate = $onupdate;
- $this->eachrow = $eachrow;
- $this->tablename = $tablename;
- $this->funcname = $funcname;
- if (is_array($args)) $this->args = $args;
- }
- // ....................................................................
- /**
- * Acquires the schema from database metadata.
- * NB: Override this function to get schema info per DB type.
- */
- function getschema() { }
- // ....................................................................
- /** Dump ascii description of this trigger to stdout. */
- function dump() {
- $s = "trigger $this->name on " . $this->tablename . " executing function " . $this->funcname . "()";
- return "$s\n";
- }
- // ....................................................................
- /** Return SQL required to create this trigger. */
- function create() {
- $s = "";
- $s .= "create";
- $s .= " trigger $this->name";
- if ($this->before) $s .= " before ";
- else $s .= " after ";
- $event = array();
- if ($this->oninsert) $event[] = "insert";
- if ($this->ondelete) $event[] = "delete";
- if ($this->onupdate) $event[] = "update";
- $s .= implode(" or ", $event);
- $s .= " on " . $this->tablename;
- if ($this->eachrow) $s .= " for each row";
- else $s = " for each statement";
- $s .= " execute procedure $this->funcname";
- $s .= " (";
- if (count($this->args) > 0) {
- $s .= implode(",", $this->args);
- }
- $s .= ");\n";
- return $s;
- }
- // ....................................................................
- // Return SQL to drop this trigger.
- function drop() {
- $s = "drop trigger $this->name on $this->tablename;\n";
- return $s;
- }
- } // class dbtrigger
- // ----------------------------------------------------------------------
- /** Class describing a database field of a table.
- * @package database
- */
- class dbfield extends SchemaObject {
- var $num = 0;
- var $type = "";
- var $defaultval = "";
- var $notnull = false;
- var $ispkey = false;
- var $constraints = array();
- // ....................................................................
- function dbfield(&$schema, $name, $num, $type, $defaultval="", $notnull=false, $ispkey=false) {
- $this->SchemaObject($schema, $name);
- $this->num = $num;
- $this->type = $type;
- $this->defaultval = $defaultval;
- $this->notnull = $notnull;
- $this->ispkey = $ispkey;
- }
- // ....................................................................
- /** Dump field description to stdout. */
- function dump() {
- $s = "$this->name $this->type";
- if ($this->defaultval != "") $s .= " DEFAULT $this->defaultval";
- if ($this->notnull) $s .= " NOT NULL";
- if ($this->ispkey) $s .= " (pk)";
- return "$s\n";
- }
- // ....................................................................
- /**
- * Return the generic type of the field. The generic types are as
- * follows:
- * text Fixed or varying length strings
- * numeric Integers, real numbers or money
- * datetime Times, dates date-times
- * logical Boolean or bit field (true/false)
- *
- * You should override this method to return the appropriate generic
- * field types from this list, for your database type.
- * NB: Override this function to get schema info per DB type.
- */
- function generic_type() {
- $gtype = "";
- $typematch = array(
- "text" => "char|varchar|character",
- "numeric" => "int|integer|float|real|dec|decimal",
- "datetime" => "datetime|date|time|timestamp",
- "logical" => "bit",
- "" => ".*"
- );
- foreach ($typematch as $gentype => $pattern) {
- if (preg_match("/$pattern/i", $this->type)) {
- $gtype = $gentype;
- break;
- }
- }
- return $gtype;
- }
- // ....................................................................
- /**
- * Return true if the field is of an integer class.
- * NB: Override this function to get schema info per DB type.
- */
- function is_integer_class() {
- $pattern = "int|integer";
- return preg_match("/$pattern/i", $this->type);
- }
- // ....................................................................
- /**
- * Return true if the field is of a 'serial' class. This is a pseudo
- * class of types which encapsulates integer fields which are able
- * to auto-increment themselves when records are inserted.
- * NB: Override this function to get schema info per DB type.
- */
- function is_serial_class() {
- $pattern = "db-specific type";
- return preg_match("/$pattern/i", $this->type);
- }
- // ....................................................................
- /**
- * Return SQL to create this field in a table. This represents a
- * portion of the CREATE TABLE script pertaining to this field and
- * it comprises field name, type, and constraints.
- * @return string SQL to create field inside a create table statement.
- */
- function create() {
- $s = "";
- $s .= " \"$this->name\" $this->type";
- if ($this->notnull) $s .= " not null";
- if ($this->defaultval != "") $s .= " default $this->defaultval";
- $s .= $this->create_constraints();
- return $s;
- }
- // ....................................................................
- /** Return SQL to create all constraints for this field..
- * @return string SQL to create all field constraints.
- */
- function create_constraints() {
- $s = "";
- foreach ($this->constraints as $con) {
- $s .= "\n" . $con->create_inline();
- }
- return $s;
- }
- // ....................................................................
- /** Return the SQL to drop this field. */
- function drop() {
- $s .= "drop column $this->name;";
- return $s;
- }
- // ....................................................................
- /** Return true if field constraints match those passed in.
- * @param object $field Field object to check matching constraints on
- * @return boolean True if $field's constraints match ours
- */
- function constraints_match($field) {
- $matched = true;
- if (count($this->constraints) != count($field->constraints)) {
- $matched = false;
- }
- else {
- foreach ($this->constraints as $con) {
- if (isset($field->constraints[$con->name])) {
- $fcon = $field->constraints[$con->name];
- if (!$fcon->matches($con)) {
- $matched = false;
- break;
- }
- }
- else {
- $matched = false;
- break;
- }
- } // foreach
- }
- return $matched;
- }
- } // class dbfield
- // ----------------------------------------------------------------------
- /** Class describing a database table.
- * @package database
- */
- class dbtable extends SchemaObject {
- /** Array of field attnum's which are primary keys in table */
- var $pkey = array();
- /** Array of field objects */
- var $fields = array();
- /** Array of constraints on this table */
- var $constraints = array();
- /** Array of indexes on this table */
- var $indexes = array();
- // ....................................................................
- /** Construct a table of given name and array of primary key fields.
- * @param string $name The name of the table
- * @param array $pkey The array of pkeys is actually a list of integers, each being
- * the enumerated order of the field which is part of the key.
- * @param integer $dbversion Optional database version information
- */
- function dbtable(&$schema, $name) {
- $this->SchemaObject($schema, $name);
- }
- // ....................................................................
- /**
- * Acquires the schema from database metadata.
- * NB: Override this function to get schema info per DB type.
- */
- function getschema() { }
- // ....................................................................
- /** Add a field to the table. */
- function addfield($field) {
- $this->fields[$field->name] = $field;
- }
- // ....................................................................
- /** Create a new field in the table with given parameters. */
- function newfield($name, $num, $type, $defaultval="", $notnull=false) {
- $ispkey = (in_array($num, $this->pkey));
- $this->fields[$name] = new dbfield($this->schema, $name, $num, $type, $defaultval, $notnull, $ispkey);
- } // newfield
- // ....................................................................
- /** Returns field object of given attnum (order number) */
- function getfieldbynum($num) {
- foreach ($this->fields as $field) {
- if ($field->num == $num) return $field;
- }
- return false;
- } // getfieldbynum
- // ....................................................................
- /** Returns field number of given field name */
- function getfieldnum($fieldname) {
- if (isset($this->fields[$fieldname])) {
- $field = $this->fields[$fieldname];
- return $field->num;
- }
- else return -1;
- }
- // ....................................................................
- /**
- * Returns a candidate label field name according to some fairly simple
- * heuristics. This would be a field suitable for displaying in a listbox
- * which is somewhat more informative than a keyfield. If nothing is
- * found then the key is used as fallback.
- * @param $pattern Extra pattern to use in matching likely fieldnames
- */
- function getlabelfield($pattern="") {
- $keyfields = $this->getkeyfieldnames();
- $patts = array();
- if ($pattern != "") {
- $patts[] = $pattern;
- }
- $patts[] = "name|title|desc|label";
- foreach ($patts as $patt) {
- foreach ($this->fields as $field) {
- if (!in_array($field->name, $keyfields)
- && preg_match("/$patt/i", $field->name)) {
- $labelfield = $field->name;
- $done = true;
- break;
- }
- }
- }
- // Fall back if necessary..
- if ($labelfield == "") {
- $labelfield = $keyfields[0];
- }
- return $labelfield;
- } // getlabelfield
- // ....................................................................
- /**
- * Returns a candidate ordering field name according to some fairly simple
- * heuristics. If nothing is found then a labelfield is used as fallback.
- * @param $pattern Extra pattern to use in matching likely fieldnames
- */
- function getorderfield($pattern="") {
- $keyfields = $this->getkeyfieldnames();
- $patts = array();
- if ($pattern != "") {
- $patts[] = $pattern;
- }
- $patts[] = "order";
- foreach ($patts as $patt) {
- foreach ($this->fields as $field) {
- if (!in_array($field->name, $keyfields)
- && preg_match("/$patt/i", $field->name)) {
- $orderfield = $field->name;
- $done = true;
- break;
- }
- }
- }
- // Fall back if necessary..
- if ($orderfield == "") {
- $orderfield = $this->getlabelfield();
- }
- return $orderfield;
- } // getorderfield
- // ....................................................................
- /** Returns field object of given name */
- function getfield($name) {
- return $this->fields[$name];
- } // getfield
- // ....................................................................
- /** Returns list of names of keyfields as array */
- function getkeyfieldnames() {
- $pks = array();
- foreach ($this->fields as $field) {
- if ($field->ispkey) {
- $pks[] = $field->name;
- }
- }
- return $pks;
- } // getkeyfieldnames
- // ....................................................................
- /** Returns list of names of non-keyfields as array */
- function getnonkeyfieldnames() {
- $npks = array();
- foreach ($this->fields as $field) {
- if (!$field->ispkey) {
- $npks[] = $field->name;
- }
- }
- return $npks;
- }
- // ....................................................................
- /** Dump the table description to stdout. */
- function dump() {
- $s = "\nTable: $this->name\n";
- foreach ($this->fields as $field) {
- $s .= $field->dump();
- }
- // Indexes..
- foreach ($this->indexes as $indexname => $index) {
- $s .= $index->dump();
- }
- // Constraints..
- foreach ($this->constraints as $conname => $con) {
- $s .= $con->dump();
- }
- return $s;
- }
- // ....................................................................
- /** Return the SQL which will create this table. */
- function create() {
- $s = "";
- // Table and fields..
- $s .= "create table $this->name (\n";
- foreach ($this->fields as $field) {
- $s .= $field->create() . ",\n";
- }
- $s = substr($s, 0, -2);
- $s .= "\n);\n";
- // Indexes..
- foreach ($this->indexes as $indexname => $index) {
- $s .= $index->create();
- }
- // Constraints..
- foreach ($this->constraints as $conname => $con) {
- $s .= $con->create_inline() . "\n";
- }
- return $s;
- }
- // ....................................................................
- /** Return SQL which will create a column in this table. The $column
- * passed in is actually a field object.
- */
- function addcolumn($column) {
- $s = "alter table \"$this->name\" add column";
- $s .= $column->create() . "\n";
- return $s;
- }
- // ....................................................................
- /** Return SQL to set the default for given field on this table. */
- function setdefault($column) {
- $defaultval = $column->defaultval;
- $s = "alter table \"$this->name\" alter column \"$column->name\"";
- if ($defaultval == "") {
- $s .= " drop default;\n";
- }
- else {
- if (!is_numeric($defaultval) && !strstr($defaultval, "nextval")) {
- $defaultval = "'" . escape_string($defaultval) . "'";
- }
- $s .= " set default $defaultval;\n";
- }
- return $s;
- }
- // ....................................................................
- /** Return SQL to set the NULL/NOT NULL constraint.. */
- function setnullconstraint($column) {
- $s = "alter table \"$this->name\" alter column \"$column->name\"";
- if ($column->notnull) $s .= " set not null;\n";
- else $s .= " drop not null;\n";
- return $s;
- }
- // ....................................................................
- /** Return SQL to drop a column from the table. The $column passed
- * is actually a field object.
- */
- function dropcolumn($column) {
- $s = "alter table \"$this->name\" ";
- $s .= $column->drop() . "\n";
- return $s;
- }
- // ....................................................................
- /** Return the SQL to drop this table. */
- function drop() {
- $s .= "drop table $this->name;\n";
- return $s;
- }
- } // class dbtable
- // ----------------------------------------------------------------------
- /**
- * Class describing a database schema. This object hold ALL the information
- * for the named database including tables, constraints, functions, triggers
- * and sequences. Methods are provided, however to allow you to obtain the
- * information for an individual table (@see getschema_table()), rather than
- * having to read in the whole schema. For all other info, you must use the
- * getschema() method to read all information in, then access it via the
- * arrays and methods provided.
- *
- * @package database
- */
- class schema extends SchemaObject {
- var $database_server = "Generic";
- var $database_version = 0;
- var $tables = array();
- var $sequences = array();
- var $constraints = array();
- var $indexes = array();
- var $functions = array();
- var $triggers = array();
- // ....................................................................
- /**
- * Create a schema (database) of given name. The name should be a
- * valid existing database name that is currently connected. It will
- * be selected to ensure the correct data is obtained.
- * @param string $name Name of this particular database
- * @param string $dbserver Database server, eg. 'Postgresql', or 'Oracle'
- */
- function schema($name, $dbserver="Generic") {
- $this->name = $name;
- $this->database_server = $dbserver;
- $this->getversion();
- }
- // ....................................................................
- /**
- * Acquire all of the schema details.
- * Override this method for your specific database type.
- */
- function getschema() {
- global $RESPONSE;
- if (isset($RESPONSE)) {
- $RESPONSE->select_database($this->name);
- }
- $this->gettables();
- $this->gettriggers();
- $this->getfunctions();
- $this->getsequences();
- } // get
- // ....................................................................
- /** Populates schema tables.
- * Override this method for your specific database type. */
- function gettables() { }
- // ....................................................................
- /** Populates schema triggers.
- * Override this method for your specific database type. */
- function gettriggers() { }
- // ....................................................................
- /** Populates schema sequences.
- * Override this method for your specific database type. */
- function getsequences() { }
- // ....................................................................
- /**
- * Acquire the schema details of a specific database table. This method
- * is provided to cater for the common requirement of acquiring details
- * for a specific table, without having to endure the overhead of reading
- * all of the database schema metadata to get it.
- * Override this method for your specific database type.
- * @param string $tablename Name of the table to acquire schema of
- */
- function getschema_table($tablename) {
- if (!isset($this->tables[$tablename])) {
- $table = new dbtable($this, $tablename, $this->database_version);
- $table->getschema();
- $this->addtable($table);
- }
- } // get
- // ....................................................................
- /**
- * Acquire the database version.
- * Override this method for your specific database type.
- */
- function getversion() {
- $this->database_version = 0;
- }
- // ....................................................................
- /** Set the database version */
- function set_dbversion($ver) {
- $this->database_version = $ver;
- }
- // ....................................................................
- /**
- * Return database capabilities. There are specific capabilities which
- * the diff code needs to query, and this method should be overridden
- * in the specific database module to answer those questions.
- */
- function capable_of($capability="") {
- switch ($capability) {
- // Supports the ALTER <tablename> DROP <colname> SQL
- // statement to remove table columns.
- case "alter_table_drop_column":
- $cando = false;
- break;
- // Supports functions or stored procedures.
- case "stored_procedures":
- $cando = false;
- break;
- // Can define check constraints on table columns.
- case "check_constraints":
- $cando = false;
- break;
- // Can define RI constraints between table/columns to
- // support foreign-keys.
- case "RI_constraints":
- $cando = false;
- break;
- // Supports indexes on table columns.
- case "indexes":
- $cando = false;
- break;
- // Unique indexes are auto-generated with unique constraints. Ie.
- // when a primary key constraint is added to a table a unique
- // index is automatically built for it.
- case "unique_index_with_constraint":
- $cando = false;
- break;
- // Supports triggers on table update, delete, insert.
- case "triggers":
- $cando = false;
- break;
- // Supports named sequences.
- case "named_sequences":
- $cando = false;
- break;
- default:
- $cando = false;
- }
- return $cando;
- }
- // ....................................................................
- /** Add a sequence to the schema information. */
- function addsequence($schemaobj) {
- $schemaobj->schema = $this;
- $this->sequences[$schemaobj->name] = $schemaobj;
- }
- // ....................................................................
- /** Add a table to the schema information. */
- function addtable($schemaobj) {
- $schemaobj->schema = $this;
- $this->tables[$schemaobj->name] = $schemaobj;
- }
- // ....................................................................
- /** Add a constraint to the schema information. */
- function addconstraint($schemaobj) {
- $schemaobj->schema = $this;
- $this->constraints[$schemaobj->name] = $schemaobj;
- }
- // ....................................................................
- /** Add a function to the schema information. */
- function addfunction($schemaobj) {
- $schemaobj->schema = $this;
- $this->functions[$schemaobj->name] = $schemaobj;
- }
- // ....................................................................
- /** Add a trigger to the schema information. */
- function addtrigger($schemaobj) {
- $schemaobj->schema = $this;
- $this->triggers[$schemaobj->name] = $schemaobj;
- }
- // ....................................................................
- /** Returns table object of given name */
- function gettable($name) {
- return $this->tables[$name];
- }
- // ....................................................................
- /** Returns constraint object of given name */
- function getconstraint($name) {
- $gotcon = false;
- if (isset($this->constraints[$name])) {
- $gotcon = $this->constraints[$name];
- }
- else {
- // Search tables next..
- foreach ($this->tables as $table) {
- if (isset($table->constraints[$name])) {
- $gotcon = $table->constraints[$name];
- break;
- }
- }
- }
- return $gotcon;
- }
- // ....................................................................
- /** Returns index object of given name */
- function getindex($name) {
- $gotidx = false;
- if (isset($this->indexes[$name])) {
- $gotidx = $this->indexes[$name];
- }
- else {
- // Search tables next..
- foreach ($this->tables as $table) {
- if (isset($table->indexes[$name])) {
- $gotidx = $table->indexes[$name];
- break;
- }
- }
- }
- return $gotidx;
- }
- // ....................................................................
- /** Returns function object of given name */
- function getfunction($name) {
- return $this->functions[$name];
- }
- // ....................................................................
- /** Returns trigger object of given name */
- function gettrigger($name) {
- return $this->triggers[$name];
- }
- // ....................................................................
- /** Returns seqeuence object of given name */
- function getsequence($name) {
- return $this->sequences[$name];
- }
- // ....................................................................
- /** Returns true if named constraint exists. */
- function constraint_exists($name) {
- return ($this->getconstraint($name) !== false);
- }
- // ....................................................................
- /** Returns true if named index exists. */
- function index_exists($name) {
- return ($this->getindex($name) !== false);
- }
- // ....................................................................
- /** Dump this entire schema description to stdout. */
- function dump() {
- $s = "Database: $this->name\n";
- $s .= "\nTables:\n";
- foreach ($this->tables as $table) {
- $s .= $table->dump();
- }
- $s .= "\nTriggers:\n";
- foreach ($this->triggers as $trigger) {
- $s .= $trigger->dump();
- }
- $s .= "\nFunctions:\n";
- foreach ($this->functions as $func) {
- $s .= $func->dump();
- }
- $s .= "\nSequences:\n";
- foreach ($this->sequences as $seq) {
- $s .= $seq->dump();
- }
- return $s;
- } // dump
- // ....................................................................
- /**
- * Produce the SQL required to morph the schema described in the passed
- * dbschema object $db, into the schema we have in this current object.
- * The resulting SQL is commented. This virtual function is database
- * specific.
- * @param object $schema The schema to morph into the current schema
- * @return string The SQL required to make passed-in schema same as current
- */
- function diff($schema) {
- return "";
- }
- } // class schema
- // ----------------------------------------------------------------------
- ?>
Documentation generated by phpDocumentor 1.3.0RC3