/scalr-2/tags/scalr-2.0.0/app/src/Lib/Data/DB/adodb_lite/adodbSQL_drivers/mysql/mysql_meta_module.inc
PHP | 623 lines | 438 code | 72 blank | 113 comment | 74 complexity | e360fd7b5efcf84681e73fdc9ad613f4 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, GPL-3.0
- <?php
- /**
- * ADOdb Lite Meta Module for Mysql
- *
- * Portions of the Meta Coding came from ADOdb
- */
-
- /*
- (c) 2000-2005 John Lim (jlim@natsoft.com.my). All rights reserved.
- Released under both BSD license and Lesser GPL library license.
- Whenever there is any discrepancy between the two licenses,
- the BSD license will take precedence. See License.txt.
- */
-
- eval('class mysql_meta_EXTENDER extends '. $last_module . '_ADOConnection { }');
-
- class mysql_meta_ADOConnection extends mysql_meta_EXTENDER
- {
- var $metaTablesSQL = "SHOW TABLES";
- var $metaColumnsSQL = "SHOW COLUMNS FROM %s";
-
- function MetaError($err=false)
- {
- include_once(ADODB_DIR."/adodb-error.inc.php");
- if ($err === false)
- $err = $this->ErrorNo();
-
- return adodb_error($this->dataProvider,$this->databaseType,$err);
- }
-
- function MetaErrorMsg($errno)
- {
- include_once(ADODB_DIR."/adodb-error.inc.php");
- return adodb_errormsg($errno);
- }
-
- /**
- * @returns an array with the primary key columns in it.
- */
- function MetaPrimaryKeys($table, $owner=false)
- {
- // owner not used in base class - see oci8
- $p = array();
- $objs =& $this->MetaColumns($table);
- if ($objs) {
- foreach($objs as $v) {
- if (!empty($v->primary_key))
- $p[] = $v->name;
- }
- }
- if (sizeof($p))
- return $p;
- if (function_exists('ADODB_VIEW_PRIMARYKEYS'))
- return ADODB_VIEW_PRIMARYKEYS($this->databaseType, $this->database, $table, $owner);
- return false;
- }
-
- /**
- * @returns assoc array where keys are tables, and values are foreign keys
- */
- function MetaForeignKeys( $table, $owner = FALSE, $upper = FALSE, $associative = FALSE )
- {
- if ( !empty($owner) ) {
- $table = "$owner.$table";
- }
- $a_create_table = $this->getRow(sprintf('SHOW CREATE TABLE %s', $table));
- if ($associative) $create_sql = $a_create_table["Create Table"];
- else $create_sql = $a_create_table[1];
-
- $matches = array();
-
- if (!preg_match_all("/FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)/", $create_sql, $matches)) return false;
- $foreign_keys = array();
- $num_keys = count($matches[0]);
- for ( $i = 0; $i < $num_keys; $i ++ ) {
- $my_field = explode('`, `', $matches[1][$i]);
- $ref_table = $matches[2][$i];
- $ref_field = explode('`, `', $matches[3][$i]);
-
- if ( $upper ) {
- $ref_table = strtoupper($ref_table);
- }
-
- $foreign_keys[$ref_table] = array();
- $num_fields = count($my_field);
- for ( $j = 0; $j < $num_fields; $j ++ ) {
- if ( $associative ) {
- $foreign_keys[$ref_table][$ref_field[$j]] = $my_field[$j];
- } else {
- $foreign_keys[$ref_table][] = "{$my_field[$j]}={$ref_field[$j]}";
- }
- }
- }
-
- return $foreign_keys;
- }
-
- // not the fastest implementation - quick and dirty - jlim
- // for best performance, use the actual $rs->MetaType().
- function MetaType($t,$len=-1,$fieldobj=false)
- {
- if (empty($this->_metars)) {
- $rsclass = $this->last_module_name . "_ResultSet";
- $this->_metars =& new $rsclass(false,$this->fetchMode);
- }
-
- return $this->_metars->MetaType($t,$len,$fieldobj);
- }
-
- /**
- * return the databases that the driver can connect to.
- * Some databases will return an empty array.
- *
- * @return an array of database names.
- */
- function &MetaDatabases()
- {
- $qid = mysql_list_dbs($this->connectionId);
- $arr = array();
- $i = 0;
- $max = mysql_num_rows($qid);
- while ($i < $max) {
- $db = mysql_tablename($qid,$i);
- if ($db != 'mysql') $arr[] = $db;
- $i += 1;
- }
- return $arr;
- }
-
- /**
- * @param ttype can either be 'VIEW' or 'TABLE' or false.
- * If false, both views and tables are returned.
- * "VIEW" returns only views
- * "TABLE" returns only tables
- * @param showSchema returns the schema/user with the table name, eg. USER.TABLE
- * @param mask is the input mask - only supported by oci8 and postgresql
- *
- * @return array of tables for current database.
- */
- function &MetaTables($ttype=false,$showSchema=false,$mask=false)
- {
- $save = $this->metaTablesSQL;
- if ($showSchema && is_string($showSchema)) {
- $this->metaTablesSQL .= " from $showSchema";
- }
-
- if ($mask) {
- $mask = $this->qstr($mask);
- $this->metaTablesSQL .= " like $mask";
- }
- $ret =& $this->_MetaTables($ttype,$showSchema);
-
- $this->metaTablesSQL = $save;
- return $ret;
- }
-
- function &_MetaTables($ttype=false,$showSchema=false,$mask=false)
- {
- global $ADODB_FETCH_MODE;
-
- $false = false;
- if ($mask) {
- return $false;
- }
- if ($this->metaTablesSQL) {
- $save = $ADODB_FETCH_MODE;
- $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-
- if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
-
- $rs = $this->Execute($this->metaTablesSQL);
- if (isset($savem)) $this->SetFetchMode($savem);
- $ADODB_FETCH_MODE = $save;
-
- if ($rs === false) return $false;
- $arr =& $rs->GetArray();
- $arr2 = array();
-
- if ($hast = ($ttype && isset($arr[0][1]))) {
- $showt = strncmp($ttype,'T',1);
- }
-
- for ($i=0; $i < sizeof($arr); $i++) {
- if ($hast) {
- if ($showt == 0) {
- if (strncmp($arr[$i][1],'T',1) == 0) $arr2[] = trim($arr[$i][0]);
- } else {
- if (strncmp($arr[$i][1],'V',1) == 0) $arr2[] = trim($arr[$i][0]);
- }
- } else
- $arr2[] = trim($arr[$i][0]);
- }
- $rs->Close();
- return $arr2;
- }
- return $false;
- }
-
- function _findschema(&$table,&$schema)
- {
- if (!$schema && ($at = strpos($table,'.')) !== false) {
- $schema = substr($table,0,$at);
- $table = substr($table,$at+1);
- }
- }
-
- /**
- * List columns in a database as an array of ADOFieldObjects.
- * See top of file for definition of object.
- *
- * @param $table table name to query
- * @param $normalize makes table name case-insensitive (required by some databases)
- * @schema is optional database schema to use - not supported by all databases.
- *
- * @return array of ADOFieldObjects for current table.
- */
- function MetaColumns($table)
- {
- $this->_findschema($table,$schema);
- if ($schema) {
- $dbName = $this->database;
- $this->connection->SelectDB($schema);
- }
- global $ADODB_FETCH_MODE;
- $save = $ADODB_FETCH_MODE;
- $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
-
- if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
- $rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
-
- if ($schema) {
- $this->SelectDB($dbName);
- }
-
- if (isset($savem)) $this->SetFetchMode($savem);
- $ADODB_FETCH_MODE = $save;
- if (!is_object($rs)) {
- $false = false;
- return $false;
- }
-
- $retarr = array();
- while (!$rs->EOF){
- $fld = new ADOFieldObject();
- $fld->name = $rs->fields[0];
- $type = $rs->fields[1];
-
- // split type into type(length):
- $fld->scale = null;
- if (preg_match("/^(.+)\((\d+),(\d+)/", $type, $query_array)) {
- $fld->type = $query_array[1];
- $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
- $fld->scale = is_numeric($query_array[3]) ? $query_array[3] : -1;
- } elseif (preg_match("/^(.+)\((\d+)/", $type, $query_array)) {
- $fld->type = $query_array[1];
- $fld->max_length = is_numeric($query_array[2]) ? $query_array[2] : -1;
- } elseif (preg_match("/^(enum)\((.*)\)$/i", $type, $query_array)) {
- $fld->type = $query_array[1];
- $arr = explode(",",$query_array[2]);
- $fld->enums = $arr;
- $zlen = max(array_map("strlen",$arr)) - 2; // PHP >= 4.0.6
- $fld->max_length = ($zlen > 0) ? $zlen : 1;
- } else {
- $fld->type = $type;
- $fld->max_length = -1;
- }
- $fld->not_null = ($rs->fields[2] != 'YES');
- $fld->primary_key = ($rs->fields[3] == 'PRI');
- $fld->auto_increment = (strpos($rs->fields[5], 'auto_increment') !== false);
- $fld->binary = (strpos($type,'blob') !== false);
- $fld->unsigned = (strpos($type,'unsigned') !== false);
-
- if (!$fld->binary) {
- $d = $rs->fields[4];
- if ($d != '' && $d != 'NULL') {
- $fld->has_default = true;
- $fld->default_value = $d;
- } else {
- $fld->has_default = false;
- }
- }
-
- if ($save == ADODB_FETCH_NUM) {
- $retarr[] = $fld;
- } else {
- $retarr[strtoupper($fld->name)] = $fld;
- }
- $rs->MoveNext();
- }
-
- $rs->Close();
- return $retarr;
- }
-
- /**
- * List indexes on a table as an array.
- * @param table table name to query
- * @param primary true to only show primary keys. Not actually used for most databases
- *
- * @return array of indexes on current table. Each element represents an index, and is itself an associative array.
-
- Array (
- [name_of_index] => Array
- (
- [unique] => true or false
- [columns] => Array
- (
- [0] => firstname
- [1] => lastname
- )
- )
- */
- function MetaIndexes ($table, $primary = FALSE, $owner=false)
- {
- // save old fetch mode
- global $ADODB_FETCH_MODE;
-
- $false = false;
- $save = $ADODB_FETCH_MODE;
- $ADODB_FETCH_MODE = ADODB_FETCH_NUM;
- if ($this->fetchMode !== FALSE) {
- $savem = $this->SetFetchMode(FALSE);
- }
-
- // get index details
- $rs =& $this->Execute(sprintf('SHOW INDEX FROM %s',$table));
-
- // restore fetchmode
- if (isset($savem)) {
- $this->SetFetchMode($savem);
- }
- $ADODB_FETCH_MODE = $save;
-
- if (!is_object($rs)) {
- return $false;
- }
-
- $indexes = array ();
-
- // parse index data into array
- while (!$rs->EOF)
- {
- if ($primary == FALSE AND $rs->fields[2] == 'PRIMARY') {
- $rs->MoveNext();
- continue;
- }
-
- if (!isset($indexes[$rs->fields[2]])) {
- $indexes[$rs->fields[2]] = array(
- 'unique' => ($rs->fields[1] == 0),
- 'columns' => array()
- );
- }
-
- $indexes[$rs->fields[2]]['columns'][$rs->fields[3] - 1] = $rs->fields[4];
-
- $rs->MoveNext();
- }
-
- // sort columns by order in the index
- foreach ( array_keys ($indexes) as $index )
- {
- ksort ($indexes[$index]['columns']);
- }
-
- return $indexes;
- }
-
- /**
- * List columns names in a table as an array.
- * @param table table name to query
- *
- * @return array of column names for current table.
- */
- function &MetaColumnNames($table, $numIndexes=false)
- {
- $objarr =& $this->MetaColumns($table);
- if (!is_array($objarr)) {
- $false = false;
- return $false;
- }
- $arr = array();
- if ($numIndexes) {
- $i = 0;
- foreach($objarr as $v) $arr[$i++] = $v->name;
- } else
- foreach($objarr as $v) $arr[strtoupper($v->name)] = $v->name;
-
- return $arr;
- }
-
- function MetaTransaction($mode,$db)
- {
- $mode = strtoupper($mode);
- $mode = str_replace('ISOLATION LEVEL ','',$mode);
-
- switch($mode) {
-
- case 'READ UNCOMMITTED':
- switch($db) {
- case 'oci8':
- case 'oracle':
- return 'ISOLATION LEVEL READ COMMITTED';
- default:
- return 'ISOLATION LEVEL READ UNCOMMITTED';
- }
- break;
-
- case 'READ COMMITTED':
- return 'ISOLATION LEVEL READ COMMITTED';
- break;
-
- case 'REPEATABLE READ':
- switch($db) {
- case 'oci8':
- case 'oracle':
- return 'ISOLATION LEVEL SERIALIZABLE';
- default:
- return 'ISOLATION LEVEL REPEATABLE READ';
- }
- break;
-
- case 'SERIALIZABLE':
- return 'ISOLATION LEVEL SERIALIZABLE';
- break;
-
- default:
- return $mode;
- }
- }
-
- }
-
- eval('class mysql_meta_resultset_EXTENDER extends '. $last_module . '_ResultSet { }');
-
- class mysql_meta_ResultSet extends mysql_meta_resultset_EXTENDER
- {
- /**
- * Get the metatype of the column. This is used for formatting. This is because
- * many databases use different names for the same type, so we transform the original
- * type to our standardised version which uses 1 character codes:
- *
- * @param t is the type passed in. Normally is ADOFieldObject->type.
- * @param len is the maximum length of that field. This is because we treat character
- * fields bigger than a certain size as a 'B' (blob).
- * @param fieldobj is the field object returned by the database driver. Can hold
- * additional info (eg. primary_key for mysql).
- *
- * @return the general type of the data:
- * C for character < 250 chars
- * X for teXt (>= 250 chars)
- * B for Binary
- * N for numeric or floating point
- * D for date
- * T for timestamp
- * L for logical/Boolean
- * I for integer
- * R for autoincrement counter/integer
- *
- *
- */
- function MetaType($t,$len=-1,$fieldobj=false)
- {
- if (is_object($t)) {
- $fieldobj = $t;
- $t = $fieldobj->type;
- $len = $fieldobj->max_length;
- }
-
- $len = -1; // mysql max_length is not accurate
- switch (strtoupper($t)) {
- case 'STRING':
- case 'CHAR':
- case 'VARCHAR':
- case 'TINYBLOB':
- case 'TINYTEXT':
- case 'ENUM':
- case 'SET':
- if ($len <= $this->blobSize) return 'C';
-
- case 'TEXT':
- case 'LONGTEXT':
- case 'MEDIUMTEXT':
- return 'X';
-
- // php_mysql extension always returns 'blob' even if 'text'
- // so we have to check whether binary...
- case 'IMAGE':
- case 'LONGBLOB':
- case 'BLOB':
- case 'MEDIUMBLOB':
- return !empty($fieldobj->binary) ? 'B' : 'X';
-
- case 'YEAR':
- case 'DATE': return 'D';
-
- case 'TIME':
- case 'DATETIME':
- case 'TIMESTAMP': return 'T';
-
- case 'INT':
- case 'INTEGER':
- case 'BIGINT':
- case 'TINYINT':
- case 'MEDIUMINT':
- case 'SMALLINT':
-
- if (!empty($fieldobj->primary_key)) return 'R';
- else return 'I';
-
- default:
- static $typeMap = array(
- 'VARCHAR' => 'C',
- 'VARCHAR2' => 'C',
- 'CHAR' => 'C',
- 'C' => 'C',
- 'STRING' => 'C',
- 'NCHAR' => 'C',
- 'NVARCHAR' => 'C',
- 'VARYING' => 'C',
- 'BPCHAR' => 'C',
- 'CHARACTER' => 'C',
- 'INTERVAL' => 'C', # Postgres
- 'MACADDR' => 'C', # postgres
- ##
- 'LONGCHAR' => 'X',
- 'TEXT' => 'X',
- 'NTEXT' => 'X',
- 'M' => 'X',
- 'X' => 'X',
- 'CLOB' => 'X',
- 'NCLOB' => 'X',
- 'LVARCHAR' => 'X',
- ##
- 'BLOB' => 'B',
- 'IMAGE' => 'B',
- 'BINARY' => 'B',
- 'VARBINARY' => 'B',
- 'LONGBINARY' => 'B',
- 'B' => 'B',
- ##
- 'YEAR' => 'D', // mysql
- 'DATE' => 'D',
- 'D' => 'D',
- ##
- 'UNIQUEIDENTIFIER' => 'C', # MS SQL Server
- ##
- 'TIME' => 'T',
- 'TIMESTAMP' => 'T',
- 'DATETIME' => 'T',
- 'TIMESTAMPTZ' => 'T',
- 'T' => 'T',
- 'TIMESTAMP WITHOUT TIME ZONE' => 'T', // postgresql
- ##
- 'BOOL' => 'L',
- 'BOOLEAN' => 'L',
- 'BIT' => 'L',
- 'L' => 'L',
- ##
- 'COUNTER' => 'R',
- 'R' => 'R',
- 'SERIAL' => 'R', // ifx
- 'INT IDENTITY' => 'R',
- ##
- 'INT' => 'I',
- 'INT2' => 'I',
- 'INT4' => 'I',
- 'INT8' => 'I',
- 'INTEGER' => 'I',
- 'INTEGER UNSIGNED' => 'I',
- 'SHORT' => 'I',
- 'TINYINT' => 'I',
- 'SMALLINT' => 'I',
- 'I' => 'I',
- ##
- 'LONG' => 'N', // interbase is numeric, oci8 is blob
- 'BIGINT' => 'N', // this is bigger than PHP 32-bit integers
- 'DECIMAL' => 'N',
- 'DEC' => 'N',
- 'REAL' => 'N',
- 'DOUBLE' => 'N',
- 'DOUBLE PRECISION' => 'N',
- 'SMALLFLOAT' => 'N',
- 'FLOAT' => 'N',
- 'NUMBER' => 'N',
- 'NUM' => 'N',
- 'NUMERIC' => 'N',
- 'MONEY' => 'N',
-
- ## informix 9.2
- 'SQLINT' => 'I',
- 'SQLSERIAL' => 'I',
- 'SQLSMINT' => 'I',
- 'SQLSMFLOAT' => 'N',
- 'SQLFLOAT' => 'N',
- 'SQLMONEY' => 'N',
- 'SQLDECIMAL' => 'N',
- 'SQLDATE' => 'D',
- 'SQLVCHAR' => 'C',
- 'SQLCHAR' => 'C',
- 'SQLDTIME' => 'T',
- 'SQLINTERVAL' => 'N',
- 'SQLBYTES' => 'B',
- 'SQLTEXT' => 'X',
- ## informix 10
- "SQLINT8" => 'I8',
- "SQLSERIAL8" => 'I8',
- "SQLNCHAR" => 'C',
- "SQLNVCHAR" => 'C',
- "SQLLVARCHAR" => 'X',
- "SQLBOOL" => 'L'
- );
-
- $tmap = false;
- $t = strtoupper($t);
- $tmap = (isset($typeMap[$t])) ? $typeMap[$t] : 'N';
- return $tmap;
- }
- }
-
- }
-
- ?>