6 changed files with 0 additions and 3834 deletions
-
385lib/MDB2/Driver/Datatype/sqlite3.php
-
136lib/MDB2/Driver/Function/sqlite3.php
-
1362lib/MDB2/Driver/Manager/sqlite3.php
-
33lib/MDB2/Driver/Native/sqlite3.php
-
586lib/MDB2/Driver/Reverse/sqlite3.php
-
1332lib/MDB2/Driver/sqlite3.php
@ -1,385 +0,0 @@ |
|||
<?php |
|||
/** |
|||
* ownCloud |
|||
* |
|||
* @author Robin Appelman |
|||
* @copyright 2011 Robin Appelman icewind1991@gmail.com |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public |
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
require_once 'MDB2/Driver/Datatype/Common.php'; |
|||
|
|||
/** |
|||
* MDB2 SQLite driver |
|||
* |
|||
* @package MDB2 |
|||
* @category Database |
|||
* @author Lukas Smith <smith@pooteeweet.org> |
|||
*/ |
|||
class MDB2_Driver_Datatype_sqlite3 extends MDB2_Driver_Datatype_Common |
|||
{ |
|||
// {{{ _getCollationFieldDeclaration()
|
|||
|
|||
/** |
|||
* Obtain DBMS specific SQL code portion needed to set the COLLATION |
|||
* of a field declaration to be used in statements like CREATE TABLE. |
|||
* |
|||
* @param string $collation name of the collation |
|||
* |
|||
* @return string DBMS specific SQL code portion needed to set the COLLATION |
|||
* of a field declaration. |
|||
*/ |
|||
function _getCollationFieldDeclaration($collation) |
|||
{ |
|||
return 'COLLATE '.$collation; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ getTypeDeclaration()
|
|||
|
|||
/** |
|||
* Obtain DBMS specific SQL code portion needed to declare an text type |
|||
* field to be used in statements like CREATE TABLE. |
|||
* |
|||
* @param array $field associative array with the name of the properties |
|||
* of the field being declared as array indexes. Currently, the types |
|||
* of supported field properties are as follows: |
|||
* |
|||
* length |
|||
* Integer value that determines the maximum length of the text |
|||
* field. If this argument is missing the field should be |
|||
* declared to have the longest length allowed by the DBMS. |
|||
* |
|||
* default |
|||
* Text value to be used as default for this field. |
|||
* |
|||
* notnull |
|||
* Boolean flag that indicates whether this field is constrained |
|||
* to not be set to null. |
|||
* @return string DBMS specific SQL code portion that should be used to |
|||
* declare the specified field. |
|||
* @access public |
|||
*/ |
|||
function getTypeDeclaration($field) |
|||
{ |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
switch ($field['type']) { |
|||
case 'text': |
|||
$length = !empty($field['length']) |
|||
? $field['length'] : false; |
|||
$fixed = !empty($field['fixed']) ? $field['fixed'] : false; |
|||
return $fixed ? ($length ? 'CHAR('.$length.')' : 'CHAR('.$db->options['default_text_field_length'].')') |
|||
: ($length ? 'VARCHAR('.$length.')' : 'TEXT'); |
|||
case 'clob': |
|||
if (!empty($field['length'])) { |
|||
$length = $field['length']; |
|||
if ($length <= 255) { |
|||
return 'TINYTEXT'; |
|||
} elseif ($length <= 65532) { |
|||
return 'TEXT'; |
|||
} elseif ($length <= 16777215) { |
|||
return 'MEDIUMTEXT'; |
|||
} |
|||
} |
|||
return 'LONGTEXT'; |
|||
case 'blob': |
|||
if (!empty($field['length'])) { |
|||
$length = $field['length']; |
|||
if ($length <= 255) { |
|||
return 'TINYBLOB'; |
|||
} elseif ($length <= 65532) { |
|||
return 'BLOB'; |
|||
} elseif ($length <= 16777215) { |
|||
return 'MEDIUMBLOB'; |
|||
} |
|||
} |
|||
return 'LONGBLOB'; |
|||
case 'integer': |
|||
if (!empty($field['length'])) { |
|||
$length = $field['length']; |
|||
if ($length <= 2) { |
|||
return 'SMALLINT'; |
|||
} elseif ($length == 3 || $length == 4) { |
|||
return 'INTEGER'; |
|||
} elseif ($length > 4) { |
|||
return 'BIGINT'; |
|||
} |
|||
} |
|||
return 'INTEGER'; |
|||
case 'boolean': |
|||
return 'BOOLEAN'; |
|||
case 'date': |
|||
return 'DATE'; |
|||
case 'time': |
|||
return 'TIME'; |
|||
case 'timestamp': |
|||
return 'DATETIME'; |
|||
case 'float': |
|||
return 'DOUBLE'.($db->options['fixed_float'] ? '('. |
|||
($db->options['fixed_float']+2).','.$db->options['fixed_float'].')' : ''); |
|||
case 'decimal': |
|||
$length = !empty($field['length']) ? $field['length'] : 18; |
|||
$scale = !empty($field['scale']) ? $field['scale'] : $db->options['decimal_places']; |
|||
return 'DECIMAL('.$length.','.$scale.')'; |
|||
} |
|||
return ''; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ _getIntegerDeclaration()
|
|||
|
|||
/** |
|||
* Obtain DBMS specific SQL code portion needed to declare an integer type |
|||
* field to be used in statements like CREATE TABLE. |
|||
* |
|||
* @param string $name name the field to be declared. |
|||
* @param string $field associative array with the name of the properties |
|||
* of the field being declared as array indexes. |
|||
* Currently, the types of supported field |
|||
* properties are as follows: |
|||
* |
|||
* unsigned |
|||
* Boolean flag that indicates whether the field |
|||
* should be declared as unsigned integer if |
|||
* possible. |
|||
* |
|||
* default |
|||
* Integer value to be used as default for this |
|||
* field. |
|||
* |
|||
* notnull |
|||
* Boolean flag that indicates whether this field is |
|||
* constrained to not be set to null. |
|||
* @return string DBMS specific SQL code portion that should be used to |
|||
* declare the specified field. |
|||
* @access protected |
|||
*/ |
|||
function _getIntegerDeclaration($name, $field) |
|||
{ |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
$default = $autoinc = ''; |
|||
if (!empty($field['autoincrement'])) { |
|||
$autoinc = ' PRIMARY KEY AUTOINCREMENT'; |
|||
} elseif (array_key_exists('default', $field)) { |
|||
if ($field['default'] === '') { |
|||
$field['default'] = empty($field['notnull']) ? null : 0; |
|||
} |
|||
$default = ' DEFAULT '.$this->quote($field['default'], 'integer'); |
|||
} |
|||
|
|||
$notnull = empty($field['notnull']) ? '' : ' NOT NULL'; |
|||
$unsigned = empty($field['unsigned']) ? '' : ' UNSIGNED'; |
|||
$name = $db->quoteIdentifier($name, true); |
|||
if($autoinc) { |
|||
return $name.' '.$this->getTypeDeclaration($field).$autoinc; |
|||
}else{ |
|||
return $name.' '.$this->getTypeDeclaration($field).$unsigned.$default.$notnull.$autoinc; |
|||
} |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ matchPattern()
|
|||
|
|||
/** |
|||
* build a pattern matching string |
|||
* |
|||
* @access public |
|||
* |
|||
* @param array $pattern even keys are strings, odd are patterns (% and _) |
|||
* @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future) |
|||
* @param string $field optional field name that is being matched against |
|||
* (might be required when emulating ILIKE) |
|||
* |
|||
* @return string SQL pattern |
|||
*/ |
|||
function matchPattern($pattern, $operator = null, $field = null) |
|||
{ |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
$match = ''; |
|||
if (!is_null($operator)) { |
|||
$field = is_null($field) ? '' : $field.' '; |
|||
$operator = strtoupper($operator); |
|||
switch ($operator) { |
|||
// case insensitive
|
|||
case 'ILIKE': |
|||
$match = $field.'LIKE '; |
|||
break; |
|||
// case sensitive
|
|||
case 'LIKE': |
|||
$match = $field.'LIKE '; |
|||
break; |
|||
default: |
|||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, |
|||
'not a supported operator type:'. $operator, __FUNCTION__); |
|||
} |
|||
} |
|||
$match.= "'"; |
|||
foreach ($pattern as $key => $value) { |
|||
if ($key % 2) { |
|||
$match.= $value; |
|||
} else { |
|||
$match.= $db->escapePattern($db->escape($value)); |
|||
} |
|||
} |
|||
$match.= "'"; |
|||
$match.= $this->patternEscapeString(); |
|||
return $match; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ _mapNativeDatatype()
|
|||
|
|||
/** |
|||
* Maps a native array description of a field to a MDB2 datatype and length |
|||
* |
|||
* @param array $field native field description |
|||
* @return array containing the various possible types, length, sign, fixed |
|||
* @access public |
|||
*/ |
|||
function _mapNativeDatatype($field) |
|||
{ |
|||
$db_type = strtolower($field['type']); |
|||
$length = !empty($field['length']) ? $field['length'] : null; |
|||
$unsigned = !empty($field['unsigned']) ? $field['unsigned'] : null; |
|||
$fixed = null; |
|||
$type = array(); |
|||
switch ($db_type) { |
|||
case 'boolean': |
|||
$type[] = 'boolean'; |
|||
break; |
|||
case 'tinyint': |
|||
$type[] = 'integer'; |
|||
$type[] = 'boolean'; |
|||
if (preg_match('/^(is|has)/', $field['name'])) { |
|||
$type = array_reverse($type); |
|||
} |
|||
$unsigned = preg_match('/ unsigned/i', $field['type']); |
|||
$length = 1; |
|||
break; |
|||
case 'smallint': |
|||
$type[] = 'integer'; |
|||
$unsigned = preg_match('/ unsigned/i', $field['type']); |
|||
$length = 2; |
|||
break; |
|||
case 'mediumint': |
|||
$type[] = 'integer'; |
|||
$unsigned = preg_match('/ unsigned/i', $field['type']); |
|||
$length = 3; |
|||
break; |
|||
case 'int': |
|||
case 'integer': |
|||
case 'serial': |
|||
$type[] = 'integer'; |
|||
$unsigned = preg_match('/ unsigned/i', $field['type']); |
|||
$length = 4; |
|||
break; |
|||
case 'bigint': |
|||
case 'bigserial': |
|||
$type[] = 'integer'; |
|||
$unsigned = preg_match('/ unsigned/i', $field['type']); |
|||
$length = 8; |
|||
break; |
|||
case 'clob': |
|||
$type[] = 'clob'; |
|||
$fixed = false; |
|||
break; |
|||
case 'tinytext': |
|||
case 'mediumtext': |
|||
case 'longtext': |
|||
case 'text': |
|||
case 'varchar': |
|||
case 'varchar2': |
|||
$fixed = false; |
|||
case 'char': |
|||
$type[] = 'text'; |
|||
if ($length == '1') { |
|||
$type[] = 'boolean'; |
|||
if (preg_match('/^(is|has)/', $field['name'])) { |
|||
$type = array_reverse($type); |
|||
} |
|||
} elseif (strstr($db_type, 'text')) { |
|||
$type[] = 'clob'; |
|||
$type = array_reverse($type); |
|||
} |
|||
if ($fixed !== false) { |
|||
$fixed = true; |
|||
} |
|||
break; |
|||
case 'date': |
|||
$type[] = 'date'; |
|||
$length = null; |
|||
break; |
|||
case 'datetime': |
|||
case 'timestamp': |
|||
$type[] = 'timestamp'; |
|||
$length = null; |
|||
break; |
|||
case 'time': |
|||
$type[] = 'time'; |
|||
$length = null; |
|||
break; |
|||
case 'float': |
|||
case 'double': |
|||
case 'real': |
|||
$type[] = 'float'; |
|||
break; |
|||
case 'decimal': |
|||
case 'numeric': |
|||
$type[] = 'decimal'; |
|||
$length = $length.','.$field['decimal']; |
|||
break; |
|||
case 'tinyblob': |
|||
case 'mediumblob': |
|||
case 'longblob': |
|||
case 'blob': |
|||
$type[] = 'blob'; |
|||
$length = null; |
|||
break; |
|||
case 'year': |
|||
$type[] = 'integer'; |
|||
$type[] = 'date'; |
|||
$length = null; |
|||
break; |
|||
default: |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, |
|||
'unknown database attribute type: '.$db_type, __FUNCTION__); |
|||
} |
|||
|
|||
if ((int)$length <= 0) { |
|||
$length = null; |
|||
} |
|||
|
|||
return array($type, $length, $unsigned, $fixed); |
|||
} |
|||
|
|||
// }}}
|
|||
} |
|||
@ -1,136 +0,0 @@ |
|||
<?php |
|||
/** |
|||
* ownCloud |
|||
* |
|||
* @author Robin Appelman |
|||
* @copyright 2011 Robin Appelman icewind1991@gmail.com |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public |
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
require_once 'MDB2/Driver/Function/Common.php'; |
|||
|
|||
/** |
|||
* MDB2 SQLite driver for the function modules |
|||
* |
|||
* @package MDB2 |
|||
* @category Database |
|||
* @author Lukas Smith <smith@pooteeweet.org> |
|||
*/ |
|||
class MDB2_Driver_Function_sqlite3 extends MDB2_Driver_Function_Common |
|||
{ |
|||
// {{{ constructor
|
|||
|
|||
/** |
|||
* Constructor |
|||
*/ |
|||
function __construct($db_index) |
|||
{ |
|||
parent::__construct($db_index); |
|||
// create all sorts of UDFs
|
|||
} |
|||
|
|||
// {{{ now()
|
|||
|
|||
/** |
|||
* Return string to call a variable with the current timestamp inside an SQL statement |
|||
* There are three special variables for current date and time. |
|||
* |
|||
* @return string to call a variable with the current timestamp |
|||
* @access public |
|||
*/ |
|||
function now($type = 'timestamp') |
|||
{ |
|||
switch ($type) { |
|||
case 'time': |
|||
return 'CURRENT_TIME'; |
|||
case 'date': |
|||
return 'CURRENT_DATE'; |
|||
case 'timestamp': |
|||
default: |
|||
return 'CURRENT_TIMESTAMP'; |
|||
} |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ unixtimestamp()
|
|||
|
|||
/** |
|||
* return string to call a function to get the unix timestamp from a iso timestamp |
|||
* |
|||
* @param string $expression |
|||
* |
|||
* @return string to call a variable with the timestamp |
|||
* @access public |
|||
*/ |
|||
function unixtimestamp($expression) |
|||
{ |
|||
return 'strftime("%s",'. $expression.', "utc")'; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ substring()
|
|||
|
|||
/** |
|||
* return string to call a function to get a substring inside an SQL statement |
|||
* |
|||
* @return string to call a function to get a substring |
|||
* @access public |
|||
*/ |
|||
function substring($value, $position = 1, $length = null) |
|||
{ |
|||
if (!is_null($length)) { |
|||
return "substr($value, $position, $length)"; |
|||
} |
|||
return "substr($value, $position, length($value))"; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ random()
|
|||
|
|||
/** |
|||
* return string to call a function to get random value inside an SQL statement |
|||
* |
|||
* @return return string to generate float between 0 and 1 |
|||
* @access public |
|||
*/ |
|||
function random() |
|||
{ |
|||
return '((RANDOM()+2147483648)/4294967296)'; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ replace()
|
|||
|
|||
/** |
|||
* return string to call a function to get a replacement inside an SQL statement. |
|||
* |
|||
* @return string to call a function to get a replace |
|||
* @access public |
|||
*/ |
|||
function replace($str, $from_str, $to_str) |
|||
{ |
|||
$db =& $this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
$error =& $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, |
|||
'method not implemented', __FUNCTION__); |
|||
return $error; |
|||
} |
|||
|
|||
// }}}
|
|||
} |
|||
1362
lib/MDB2/Driver/Manager/sqlite3.php
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,33 +0,0 @@ |
|||
<?php |
|||
/** |
|||
* ownCloud |
|||
* |
|||
* @author Robin Appelman |
|||
* @copyright 2011 Robin Appelman icewind1991@gmail.com |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public |
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
require_once 'MDB2/Driver/Native/Common.php'; |
|||
|
|||
/** |
|||
* MDB2 SQLite driver for the native module |
|||
* |
|||
* @package MDB2 |
|||
* @category Database |
|||
* @author Lukas Smith <smith@pooteeweet.org> |
|||
*/ |
|||
class MDB2_Driver_Native_sqlite extends MDB2_Driver_Native_Common |
|||
{ |
|||
} |
|||
@ -1,586 +0,0 @@ |
|||
<?php |
|||
/** |
|||
* ownCloud |
|||
* |
|||
* @author Robin Appelman |
|||
* @copyright 2011 Robin Appelman icewind1991@gmail.com |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public |
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
require_once 'MDB2/Driver/Reverse/Common.php'; |
|||
|
|||
/** |
|||
* MDB2 SQlite driver for the schema reverse engineering module |
|||
* |
|||
* @package MDB2 |
|||
* @category Database |
|||
* @author Lukas Smith <smith@pooteeweet.org> |
|||
*/ |
|||
class MDB2_Driver_Reverse_sqlite3 extends MDB2_Driver_Reverse_Common |
|||
{ |
|||
/** |
|||
* Remove SQL comments from the field definition |
|||
* |
|||
* @access private |
|||
*/ |
|||
function _removeComments($sql) { |
|||
$lines = explode("\n", $sql); |
|||
foreach ($lines as $k => $line) { |
|||
$pieces = explode('--', $line); |
|||
if (count($pieces) > 1 && (substr_count($pieces[0], '\'') % 2) == 0) { |
|||
$lines[$k] = substr($line, 0, strpos($line, '--')); |
|||
} |
|||
} |
|||
return implode("\n", $lines); |
|||
} |
|||
|
|||
/** |
|||
* |
|||
*/ |
|||
function _getTableColumns($sql) |
|||
{ |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
$start_pos = strpos($sql, '('); |
|||
$end_pos = strrpos($sql, ')'); |
|||
$column_def = substr($sql, $start_pos+1, $end_pos-$start_pos-1); |
|||
// replace the decimal length-places-separator with a colon
|
|||
$column_def = preg_replace('/(\d),(\d)/', '\1:\2', $column_def); |
|||
$column_def = $this->_removeComments($column_def); |
|||
$column_sql = explode(',', $column_def); |
|||
$columns = array(); |
|||
$count = count($column_sql); |
|||
if ($count == 0) { |
|||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, |
|||
'unexpected empty table column definition list', __FUNCTION__); |
|||
} |
|||
$regexp = '/^\s*([^\s]+) +(CHAR|VARCHAR|VARCHAR2|TEXT|BOOLEAN|SMALLINT|INT|INTEGER|DECIMAL|BIGINT|DOUBLE|FLOAT|DATETIME|DATE|TIME|LONGTEXT|LONGBLOB)( ?\(([1-9][0-9]*)(:([1-9][0-9]*))?\))?( NULL| NOT NULL)?( UNSIGNED)?( NULL| NOT NULL)?( PRIMARY KEY)?( AUTOINCREMENT)?( DEFAULT (\'[^\']*\'|[^ ]+))?( NULL| NOT NULL)?( PRIMARY KEY)?(\s*\-\-.*)?$/i'; |
|||
$regexp2 = '/^\s*([^ ]+) +(PRIMARY|UNIQUE|CHECK)$/i'; |
|||
for ($i=0, $j=0; $i<$count; ++$i) { |
|||
if (!preg_match($regexp, trim($column_sql[$i]), $matches)) { |
|||
if (!preg_match($regexp2, trim($column_sql[$i]))) { |
|||
continue; |
|||
} |
|||
return $db->raiseError(MDB2_ERROR_UNSUPPORTED, null, null, |
|||
'unexpected table column SQL definition: "'.$column_sql[$i].'"', __FUNCTION__); |
|||
} |
|||
$columns[$j]['name'] = trim($matches[1], implode('', $db->identifier_quoting)); |
|||
$columns[$j]['type'] = strtolower($matches[2]); |
|||
if (isset($matches[4]) && strlen($matches[4])) { |
|||
$columns[$j]['length'] = $matches[4]; |
|||
} |
|||
if (isset($matches[6]) && strlen($matches[6])) { |
|||
$columns[$j]['decimal'] = $matches[6]; |
|||
} |
|||
if (isset($matches[8]) && strlen($matches[8])) { |
|||
$columns[$j]['unsigned'] = true; |
|||
} |
|||
if (isset($matches[10]) && strlen($matches[10])) { |
|||
$columns[$j]['autoincrement'] = true; |
|||
$columns[$j]['notnull']=true; |
|||
} |
|||
if (isset($matches[10]) && strlen($matches[10])) { |
|||
$columns[$j]['autoincrement'] = true; |
|||
$columns[$j]['notnull']=true; |
|||
} |
|||
if (isset($matches[13]) && strlen($matches[13])) { |
|||
$default = $matches[13]; |
|||
if (strlen($default) && $default[0]=="'") { |
|||
$default = str_replace("''", "'", substr($default, 1, strlen($default)-2)); |
|||
} |
|||
if ($default === 'NULL') { |
|||
$default = null; |
|||
} |
|||
$columns[$j]['default'] = $default; |
|||
} |
|||
if (isset($matches[7]) && strlen($matches[7])) { |
|||
$columns[$j]['notnull'] = ($matches[7] === ' NOT NULL'); |
|||
} else if (isset($matches[9]) && strlen($matches[9])) { |
|||
$columns[$j]['notnull'] = ($matches[9] === ' NOT NULL'); |
|||
} else if (isset($matches[14]) && strlen($matches[14])) { |
|||
$columns[$j]['notnull'] = ($matches[14] === ' NOT NULL'); |
|||
} |
|||
++$j; |
|||
} |
|||
return $columns; |
|||
} |
|||
|
|||
// {{{ getTableFieldDefinition()
|
|||
|
|||
/** |
|||
* Get the stucture of a field into an array |
|||
* |
|||
* @param string $table_name name of table that should be used in method |
|||
* @param string $field_name name of field that should be used in method |
|||
* @return mixed data array on success, a MDB2 error on failure. |
|||
* The returned array contains an array for each field definition, |
|||
* with (some of) these indices: |
|||
* [notnull] [nativetype] [length] [fixed] [default] [type] [mdb2type] |
|||
* @access public |
|||
*/ |
|||
function getTableFieldDefinition($table_name, $field_name) |
|||
{ |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
list($schema, $table) = $this->splitTableSchema($table_name); |
|||
|
|||
$result = $db->loadModule('Datatype', null, true); |
|||
if (PEAR::isError($result)) { |
|||
return $result; |
|||
} |
|||
$query = "SELECT sql FROM sqlite_master WHERE type='table' AND "; |
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text'); |
|||
} else { |
|||
$query.= 'name='.$db->quote($table, 'text'); |
|||
} |
|||
$sql = $db->queryOne($query); |
|||
if (PEAR::isError($sql)) { |
|||
return $sql; |
|||
} |
|||
$columns = $this->_getTableColumns($sql); |
|||
foreach ($columns as $column) { |
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
if ($db->options['field_case'] == CASE_LOWER) { |
|||
$column['name'] = strtolower($column['name']); |
|||
} else { |
|||
$column['name'] = strtoupper($column['name']); |
|||
} |
|||
} else { |
|||
$column = array_change_key_case($column, $db->options['field_case']); |
|||
} |
|||
if ($field_name == $column['name']) { |
|||
$mapped_datatype = $db->datatype->mapNativeDatatype($column); |
|||
if (PEAR::isError($mapped_datatype)) { |
|||
return $mapped_datatype; |
|||
} |
|||
list($types, $length, $unsigned, $fixed) = $mapped_datatype; |
|||
$notnull = false; |
|||
if (!empty($column['notnull'])) { |
|||
$notnull = $column['notnull']; |
|||
} |
|||
$default = false; |
|||
if (array_key_exists('default', $column)) { |
|||
$default = $column['default']; |
|||
if (is_null($default) && $notnull) { |
|||
$default = ''; |
|||
} |
|||
} |
|||
$autoincrement = false; |
|||
if (!empty($column['autoincrement'])) { |
|||
$autoincrement = true; |
|||
} |
|||
|
|||
$definition[0] = array( |
|||
'notnull' => $notnull, |
|||
'nativetype' => preg_replace('/^([a-z]+)[^a-z].*/i', '\\1', $column['type']) |
|||
); |
|||
if (!is_null($length)) { |
|||
$definition[0]['length'] = $length; |
|||
} |
|||
if (!is_null($unsigned)) { |
|||
$definition[0]['unsigned'] = $unsigned; |
|||
} |
|||
if (!is_null($fixed)) { |
|||
$definition[0]['fixed'] = $fixed; |
|||
} |
|||
if ($default !== false) { |
|||
$definition[0]['default'] = $default; |
|||
} |
|||
if ($autoincrement !== false) { |
|||
$definition[0]['autoincrement'] = $autoincrement; |
|||
} |
|||
foreach ($types as $key => $type) { |
|||
$definition[$key] = $definition[0]; |
|||
if ($type == 'clob' || $type == 'blob') { |
|||
unset($definition[$key]['default']); |
|||
} |
|||
$definition[$key]['type'] = $type; |
|||
$definition[$key]['mdb2type'] = $type; |
|||
} |
|||
return $definition; |
|||
} |
|||
} |
|||
|
|||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, |
|||
'it was not specified an existing table column', __FUNCTION__); |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ getTableIndexDefinition()
|
|||
|
|||
/** |
|||
* Get the stucture of an index into an array |
|||
* |
|||
* @param string $table_name name of table that should be used in method |
|||
* @param string $index_name name of index that should be used in method |
|||
* @return mixed data array on success, a MDB2 error on failure |
|||
* @access public |
|||
*/ |
|||
function getTableIndexDefinition($table_name, $index_name) |
|||
{ |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
list($schema, $table) = $this->splitTableSchema($table_name); |
|||
|
|||
$query = "SELECT sql FROM sqlite_master WHERE type='index' AND "; |
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$query.= 'LOWER(name)=%s AND LOWER(tbl_name)=' . $db->quote(strtolower($table), 'text'); |
|||
} else { |
|||
$query.= 'name=%s AND tbl_name=' . $db->quote($table, 'text'); |
|||
} |
|||
$query.= ' AND sql NOT NULL ORDER BY name'; |
|||
$index_name_mdb2 = $db->getIndexName($index_name); |
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$qry = sprintf($query, $db->quote(strtolower($index_name_mdb2), 'text')); |
|||
} else { |
|||
$qry = sprintf($query, $db->quote($index_name_mdb2, 'text')); |
|||
} |
|||
$sql = $db->queryOne($qry, 'text'); |
|||
if (PEAR::isError($sql) || empty($sql)) { |
|||
// fallback to the given $index_name, without transformation
|
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$qry = sprintf($query, $db->quote(strtolower($index_name), 'text')); |
|||
} else { |
|||
$qry = sprintf($query, $db->quote($index_name, 'text')); |
|||
} |
|||
$sql = $db->queryOne($qry, 'text'); |
|||
} |
|||
if (PEAR::isError($sql)) { |
|||
return $sql; |
|||
} |
|||
if (!$sql) { |
|||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, |
|||
'it was not specified an existing table index', __FUNCTION__); |
|||
} |
|||
|
|||
$sql = strtolower($sql); |
|||
$start_pos = strpos($sql, '('); |
|||
$end_pos = strrpos($sql, ')'); |
|||
$column_names = substr($sql, $start_pos+1, $end_pos-$start_pos-1); |
|||
$column_names = explode(',', $column_names); |
|||
|
|||
if (preg_match("/^create unique/", $sql)) { |
|||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, |
|||
'it was not specified an existing table index', __FUNCTION__); |
|||
} |
|||
|
|||
$definition = array(); |
|||
$count = count($column_names); |
|||
for ($i=0; $i<$count; ++$i) { |
|||
$column_name = strtok($column_names[$i], ' '); |
|||
$collation = strtok(' '); |
|||
$definition['fields'][$column_name] = array( |
|||
'position' => $i+1 |
|||
); |
|||
if (!empty($collation)) { |
|||
$definition['fields'][$column_name]['sorting'] = |
|||
($collation=='ASC' ? 'ascending' : 'descending'); |
|||
} |
|||
} |
|||
|
|||
if (empty($definition['fields'])) { |
|||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, |
|||
'it was not specified an existing table index', __FUNCTION__); |
|||
} |
|||
return $definition; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ getTableConstraintDefinition()
|
|||
|
|||
/** |
|||
* Get the stucture of a constraint into an array |
|||
* |
|||
* @param string $table_name name of table that should be used in method |
|||
* @param string $constraint_name name of constraint that should be used in method |
|||
* @return mixed data array on success, a MDB2 error on failure |
|||
* @access public |
|||
*/ |
|||
function getTableConstraintDefinition($table_name, $constraint_name) |
|||
{ |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
list($schema, $table) = $this->splitTableSchema($table_name); |
|||
|
|||
$query = "SELECT sql FROM sqlite_master WHERE type='index' AND "; |
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$query.= 'LOWER(name)=%s AND LOWER(tbl_name)=' . $db->quote(strtolower($table), 'text'); |
|||
} else { |
|||
$query.= 'name=%s AND tbl_name=' . $db->quote($table, 'text'); |
|||
} |
|||
$query.= ' AND sql NOT NULL ORDER BY name'; |
|||
$constraint_name_mdb2 = $db->getIndexName($constraint_name); |
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$qry = sprintf($query, $db->quote(strtolower($constraint_name_mdb2), 'text')); |
|||
} else { |
|||
$qry = sprintf($query, $db->quote($constraint_name_mdb2, 'text')); |
|||
} |
|||
$sql = $db->queryOne($qry, 'text'); |
|||
if (PEAR::isError($sql) || empty($sql)) { |
|||
// fallback to the given $index_name, without transformation
|
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$qry = sprintf($query, $db->quote(strtolower($constraint_name), 'text')); |
|||
} else { |
|||
$qry = sprintf($query, $db->quote($constraint_name, 'text')); |
|||
} |
|||
$sql = $db->queryOne($qry, 'text'); |
|||
} |
|||
if (PEAR::isError($sql)) { |
|||
return $sql; |
|||
} |
|||
//default values, eventually overridden
|
|||
$definition = array( |
|||
'primary' => false, |
|||
'unique' => false, |
|||
'foreign' => false, |
|||
'check' => false, |
|||
'fields' => array(), |
|||
'references' => array( |
|||
'table' => '', |
|||
'fields' => array(), |
|||
), |
|||
'onupdate' => '', |
|||
'ondelete' => '', |
|||
'match' => '', |
|||
'deferrable' => false, |
|||
'initiallydeferred' => false, |
|||
); |
|||
if (!$sql) { |
|||
$query = "SELECT sql FROM sqlite_master WHERE type='table' AND "; |
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$query.= 'LOWER(name)='.$db->quote(strtolower($table), 'text'); |
|||
} else { |
|||
$query.= 'name='.$db->quote($table, 'text'); |
|||
} |
|||
$query.= " AND sql NOT NULL ORDER BY name"; |
|||
$sql = $db->queryOne($query, 'text'); |
|||
if (PEAR::isError($sql)) { |
|||
return $sql; |
|||
} |
|||
if ($constraint_name == 'primary') { |
|||
// search in table definition for PRIMARY KEYs
|
|||
if (preg_match("/\bPRIMARY\s+KEY\b\s*\(([^)]+)/i", $sql, $tmp)) { |
|||
$definition['primary'] = true; |
|||
$definition['fields'] = array(); |
|||
$column_names = explode(',', $tmp[1]); |
|||
$colpos = 1; |
|||
foreach ($column_names as $column_name) { |
|||
$definition['fields'][trim($column_name)] = array( |
|||
'position' => $colpos++ |
|||
); |
|||
} |
|||
return $definition; |
|||
} |
|||
if (preg_match("/\"([^\"]+)\"[^\,\"]+\bPRIMARY\s+KEY\b[^\,\)]*/i", $sql, $tmp)) { |
|||
$definition['primary'] = true; |
|||
$definition['fields'] = array(); |
|||
$column_names = explode(',', $tmp[1]); |
|||
$colpos = 1; |
|||
foreach ($column_names as $column_name) { |
|||
$definition['fields'][trim($column_name)] = array( |
|||
'position' => $colpos++ |
|||
); |
|||
} |
|||
return $definition; |
|||
} |
|||
} else { |
|||
// search in table definition for FOREIGN KEYs
|
|||
$pattern = "/\bCONSTRAINT\b\s+%s\s+
|
|||
\bFOREIGN\s+KEY\b\s*\(([^\)]+)\)\s* |
|||
\bREFERENCES\b\s+([^\s]+)\s*\(([^\)]+)\)\s* |
|||
(?:\bMATCH\s*([^\s]+))?\s* |
|||
(?:\bON\s+UPDATE\s+([^\s,\)]+))?\s* |
|||
(?:\bON\s+DELETE\s+([^\s,\)]+))?\s* |
|||
/imsx";
|
|||
$found_fk = false; |
|||
if (preg_match(sprintf($pattern, $constraint_name_mdb2), $sql, $tmp)) { |
|||
$found_fk = true; |
|||
} elseif (preg_match(sprintf($pattern, $constraint_name), $sql, $tmp)) { |
|||
$found_fk = true; |
|||
} |
|||
if ($found_fk) { |
|||
$definition['foreign'] = true; |
|||
$definition['match'] = 'SIMPLE'; |
|||
$definition['onupdate'] = 'NO ACTION'; |
|||
$definition['ondelete'] = 'NO ACTION'; |
|||
$definition['references']['table'] = $tmp[2]; |
|||
$column_names = explode(',', $tmp[1]); |
|||
$colpos = 1; |
|||
foreach ($column_names as $column_name) { |
|||
$definition['fields'][trim($column_name)] = array( |
|||
'position' => $colpos++ |
|||
); |
|||
} |
|||
$referenced_cols = explode(',', $tmp[3]); |
|||
$colpos = 1; |
|||
foreach ($referenced_cols as $column_name) { |
|||
$definition['references']['fields'][trim($column_name)] = array( |
|||
'position' => $colpos++ |
|||
); |
|||
} |
|||
if (isset($tmp[4])) { |
|||
$definition['match'] = $tmp[4]; |
|||
} |
|||
if (isset($tmp[5])) { |
|||
$definition['onupdate'] = $tmp[5]; |
|||
} |
|||
if (isset($tmp[6])) { |
|||
$definition['ondelete'] = $tmp[6]; |
|||
} |
|||
return $definition; |
|||
} |
|||
} |
|||
$sql = false; |
|||
} |
|||
if (!$sql) { |
|||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, |
|||
$constraint_name . ' is not an existing table constraint', __FUNCTION__); |
|||
} |
|||
|
|||
$sql = strtolower($sql); |
|||
$start_pos = strpos($sql, '('); |
|||
$end_pos = strrpos($sql, ')'); |
|||
$column_names = substr($sql, $start_pos+1, $end_pos-$start_pos-1); |
|||
$column_names = explode(',', $column_names); |
|||
|
|||
if (!preg_match("/^create unique/", $sql)) { |
|||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, |
|||
$constraint_name . ' is not an existing table constraint', __FUNCTION__); |
|||
} |
|||
|
|||
$definition['unique'] = true; |
|||
$count = count($column_names); |
|||
for ($i=0; $i<$count; ++$i) { |
|||
$column_name = strtok($column_names[$i], " "); |
|||
$collation = strtok(" "); |
|||
$definition['fields'][$column_name] = array( |
|||
'position' => $i+1 |
|||
); |
|||
if (!empty($collation)) { |
|||
$definition['fields'][$column_name]['sorting'] = |
|||
($collation=='ASC' ? 'ascending' : 'descending'); |
|||
} |
|||
} |
|||
|
|||
if (empty($definition['fields'])) { |
|||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, |
|||
$constraint_name . ' is not an existing table constraint', __FUNCTION__); |
|||
} |
|||
return $definition; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ getTriggerDefinition()
|
|||
|
|||
/** |
|||
* Get the structure of a trigger into an array |
|||
* |
|||
* EXPERIMENTAL |
|||
* |
|||
* WARNING: this function is experimental and may change the returned value |
|||
* at any time until labelled as non-experimental |
|||
* |
|||
* @param string $trigger name of trigger that should be used in method |
|||
* @return mixed data array on success, a MDB2 error on failure |
|||
* @access public |
|||
*/ |
|||
function getTriggerDefinition($trigger) |
|||
{ |
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
$query = "SELECT name as trigger_name,
|
|||
tbl_name AS table_name, |
|||
sql AS trigger_body, |
|||
NULL AS trigger_type, |
|||
NULL AS trigger_event, |
|||
NULL AS trigger_comment, |
|||
1 AS trigger_enabled |
|||
FROM sqlite_master |
|||
WHERE type='trigger'";
|
|||
if ($db->options['portability'] & MDB2_PORTABILITY_FIX_CASE) { |
|||
$query.= ' AND LOWER(name)='.$db->quote(strtolower($trigger), 'text'); |
|||
} else { |
|||
$query.= ' AND name='.$db->quote($trigger, 'text'); |
|||
} |
|||
$types = array( |
|||
'trigger_name' => 'text', |
|||
'table_name' => 'text', |
|||
'trigger_body' => 'text', |
|||
'trigger_type' => 'text', |
|||
'trigger_event' => 'text', |
|||
'trigger_comment' => 'text', |
|||
'trigger_enabled' => 'boolean', |
|||
); |
|||
$def = $db->queryRow($query, $types, MDB2_FETCHMODE_ASSOC); |
|||
if (PEAR::isError($def)) { |
|||
return $def; |
|||
} |
|||
if (empty($def)) { |
|||
return $db->raiseError(MDB2_ERROR_NOT_FOUND, null, null, |
|||
'it was not specified an existing trigger', __FUNCTION__); |
|||
} |
|||
if (preg_match("/^create\s+(?:temp|temporary)?trigger\s+(?:if\s+not\s+exists\s+)?.*(before|after)?\s+(insert|update|delete)/Uims", $def['trigger_body'], $tmp)) { |
|||
$def['trigger_type'] = strtoupper($tmp[1]); |
|||
$def['trigger_event'] = strtoupper($tmp[2]); |
|||
} |
|||
return $def; |
|||
} |
|||
|
|||
// }}}
|
|||
// {{{ tableInfo()
|
|||
|
|||
/** |
|||
* Returns information about a table |
|||
* |
|||
* @param string $result a string containing the name of a table |
|||
* @param int $mode a valid tableInfo mode |
|||
* |
|||
* @return array an associative array with the information requested. |
|||
* A MDB2_Error object on failure. |
|||
* |
|||
* @see MDB2_Driver_Common::tableInfo() |
|||
* @since Method available since Release 1.7.0 |
|||
*/ |
|||
function tableInfo($result, $mode = null) |
|||
{ |
|||
if (is_string($result)) { |
|||
return parent::tableInfo($result, $mode); |
|||
} |
|||
|
|||
$db =$this->getDBInstance(); |
|||
if (PEAR::isError($db)) { |
|||
return $db; |
|||
} |
|||
|
|||
return $db->raiseError(MDB2_ERROR_NOT_CAPABLE, null, null, |
|||
'This DBMS can not obtain tableInfo from result sets', __FUNCTION__); |
|||
} |
|||
} |
|||
1332
lib/MDB2/Driver/sqlite3.php
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save
Reference in new issue