From bc37721bebac4f4eb5f55e2ff508aacd7074f5f9 Mon Sep 17 00:00:00 2001 From: Brock Freeman Date: Tue, 28 Feb 2017 15:46:59 -0800 Subject: [PATCH] bug fix for exec: "php-fpm": executable file not found in $PATH --- Caddyfile | 12 +- Dockerfile | 3 + phpLiteAdmin_README.md | 24 +- phpliteadmin.php | 768 ++++++++++++++++++++++++++--------------- 4 files changed, 518 insertions(+), 289 deletions(-) mode change 100644 => 100755 phpLiteAdmin_README.md mode change 100644 => 100755 phpliteadmin.php diff --git a/Caddyfile b/Caddyfile index 540d199..16b764b 100644 --- a/Caddyfile +++ b/Caddyfile @@ -1,3 +1,9 @@ -localhost:2015 -fastcgi / 127.0.0.1:9000 php # php variant only -startup php-fpm # php variant only +0.0.0.0 + +fastcgi / 127.0.0.1:9000 php + +startup php-fpm7 + +log stdout + +errors stdout \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e73529f..8712e53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,9 @@ # using https://hub.docker.com/r/abiosoft/caddy/ FROM abiosoft/caddy:php +# essential php libs to run phpLiteAdmin +RUN apk add --no-cache php7-pdo_sqlite + # load Caddyfile ADD Caddyfile /etc/Caddyfile diff --git a/phpLiteAdmin_README.md b/phpLiteAdmin_README.md old mode 100644 new mode 100755 index 52bec7b..fe9a030 --- a/phpLiteAdmin_README.md +++ b/phpLiteAdmin_README.md @@ -1,5 +1,9 @@ # phpLiteAdmin +Website: http://www.phpliteadmin.org/ + +Bitbucket: https://bitbucket.org/phpliteadmin/public/ + ## What is phpLiteAdmin? phpLiteAdmin is a web-based SQLite database admin tool written in PHP with @@ -9,6 +13,12 @@ that is dropped into a directory on a server and then visited in a browser. There is no installation required. The available operations, feature set, interface, and user experience is comparable to that of phpMyAdmin. +## News + +**13.12.2016: Just released phpLiteAdmin 1.9.7! [Download now](https://bitbucket.org/phpliteadmin/public/downloads/phpLiteAdmin_v1-9-7.zip)** + +**05.07.2015: Just released phpLiteAdmin 1.9.6! [Download now](https://bitbucket.org/phpliteadmin/public/downloads/phpLiteAdmin_v1-9-6.zip)** + ## Features - Lightweight - consists of a single 200KB source file for portability @@ -36,11 +46,11 @@ interface, and user experience is comparable to that of phpMyAdmin. ## Demo A live demo of phpLiteAdmin can be found here: -http://demo.phpliteadmin.christosoft.de/ +http://demo.phpliteadmin.org/ ## Requirements -- a server with PHP >= 5.2.0 installed +- a server with PHP >= 5.2.4 installed - at least one PHP SQLite library extension installed and enabled: PDO, SQLite3, or SQLiteDatabase @@ -49,14 +59,10 @@ and enabled by default so no custom action is necessary. ## Download -The files in the source repositories are for development. - -You can find the latest stable single-file version here: -https://bitbucket.org/phpliteadmin/public/wiki/DownloadLinks - -The latest single-file version of the development version can be found here: -https://phpliteadmin.christosoft.de/phpliteadmin.zip +The files in the source repositories are meant for development, not for use in production. +You can find the latest downloads here: +http://www.phpliteadmin.org/download/ ## Installation diff --git a/phpliteadmin.php b/phpliteadmin.php old mode 100644 new mode 100755 index 9e80187..aa84cc0 --- a/phpliteadmin.php +++ b/phpliteadmin.php @@ -1,9 +1,9 @@ "Add Transaction to Exported SQL File", "help8_x" => "During the process for exporting to an SQL file, you may choose to wrap the queries around a TRANSACTION so that if an error occurs at any time during the importation process using the exported file, the database can be reverted to its previous state, preventing partially updated data from populating the database.", "help9" => "Add Comments to Exported SQL File", - "help9_x" => "During the process for exporting to an SQL file, you may choose to include comments that explain each step of the process so that a human can better understand what is happening." + "help9_x" => "During the process for exporting to an SQL file, you may choose to include comments that explain each step of the process so that a human can better understand what is happening.", + "help10" => "Partial Indexes", + "help10_x" => "Partial indexes are indexes over a subset of the rows of a table specified by a WHERE clause. Note this requires at least SQLite 3.8.0 and database files with partial indexes won't be readable or writable by older versions. See the SQLite documentation." ); @@ -415,25 +417,27 @@ $lang = array( // load optional configuration file $config_filename = './phpliteadmin.config.php'; -if (is_readable($config_filename)) { +if (is_readable($config_filename)) +{ include_once $config_filename; } //constants 1 define("PROJECT", "phpLiteAdmin"); -define("VERSION", "1.9.6"); +define("VERSION", "1.9.7.1"); define("PAGE", basename(__FILE__)); define("FORCETYPE", false); //force the extension that will be used (set to false in almost all circumstances except debugging) define("SYSTEMPASSWORD", $password); // Makes things easier. -define('PROJECT_URL','https://bitbucket.org/phpliteadmin/public'); -define('DONATE_URL','http://phpliteadmin.christosoft.de/donate.php'); -define('VERSION_CHECK_URL','https://phpliteadmin.christosoft.de/current_version.php'); +define('PROJECT_URL','http://www.phpliteadmin.org/'); +define('DONATE_URL','http://www.phpliteadmin.org/donate/'); +define('VERSION_CHECK_URL','https://www.phpliteadmin.org/current_version.php'); define('PROJECT_BUGTRACKER_LINK','https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open'); define('PROJECT_INSTALL_LINK','https://bitbucket.org/phpliteadmin/public/wiki/Installation'); // Resource output (css and javascript files) // we get out of the main code as soon as possible, without inizializing the session -if (isset($_GET['resource'])) { +if (isset($_GET['resource'])) +{ Resources::output($_GET['resource']); exit(); } @@ -441,6 +445,37 @@ if (isset($_GET['resource'])) { // don't mess with this - required for the login session ini_set('session.cookie_httponly', '1'); session_start(); +// generate CSRF token +if (empty($_SESSION['token'])) +{ + if (function_exists('mcrypt_create_iv')) + { + $_SESSION['token'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); + } else { + $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32)); + } +} +$token = $_SESSION['token']; +$token_html = ''; + +// checking CSRF token +if($_SERVER['REQUEST_METHOD'] === 'POST' || isset($_GET['download'])) // all POST forms need tokens! downloads are protected as well +{ + if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['token'])) + $check_token=$_POST['token']; + elseif($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['token'])) + $check_token=$_GET['token']; + + if (!isset($check_token)) + { + die("CSRF token missing"); + } + elseif ((function_exists('hash_equals') && !hash_equals($_SESSION['token'], $check_token)) || + (!function_exists('hash_equals') && $_SESSION['token']!==$check_token) ) // yes, timing attacks might be possible here. update your php ;) + { + die("CSRF token is wrong - please try to login again"); + } +} if($debug==true) { @@ -608,7 +643,7 @@ function deQuoteSQL($s) function subString($str) { global $charsNum; - if($charsNum > 10 && !$_SESSION[COOKIENAME.'fulltexts'] && strlen($str)>$charsNum) + if($charsNum > 10 && (!isset($_SESSION[COOKIENAME.'fulltexts']) || !$_SESSION[COOKIENAME.'fulltexts']) && strlen($str)>$charsNum) { $str = substr($str, 0, $charsNum).'...'; } @@ -697,6 +732,10 @@ if ($auth->isAuthorized()) $tdata = array(); $tdata['name'] = $dbname; $tdata['path'] = $directory.DIRECTORY_SEPARATOR.$dbpath; + if(isset($_POST['new_dbtype'])) + $tdata['type'] = $_POST['new_dbtype']; + else + $tdata['type'] = 3; $td = new Database($tdata); $td->query("VACUUM"); } else @@ -766,10 +805,18 @@ if ($auth->isAuthorized()) for($i=0; $i sprintf($lang['help1_x'], PROJECT, PROJECT, PROJECT), $lang['help2'] => $lang['help2_x'], $lang['help3'] => $lang['help3_x'], $lang['help4'] => $lang['help4_x'], $lang['help5'] => $lang['help5_x'], $lang['help6'] => $lang['help6_x'], - $lang['help7'] => $lang['help7_x'], $lang['help8'] => $lang['help8_x'], $lang['help9'] => $lang['help9_x'] + $lang['help7'] => $lang['help7_x'], $lang['help8'] => $lang['help8_x'], $lang['help9'] => $lang['help9_x'], $lang['help10'] => $lang['help10_x'] ); ?> @@ -1004,6 +1051,7 @@ if(!$auth->isAuthorized()) if ($auth->isFailedLogin()) echo "".$lang['passwd_incorrect']."

"; echo "
"; + echo $token_html; echo $lang['passwd'].":
"; echo "

"; echo ""; @@ -1048,7 +1096,16 @@ else // the database array is empty, offer to create a new database } echo "
".$lang['db_create'].""; echo ""; - echo " "; + echo $token_html; + echo " "; + if(class_exists('SQLiteDatabase') && (class_exists('SQLite3') || class_exists('PDO'))) + { + echo ""; + } + echo ""; echo ""; echo "
"; } @@ -1246,20 +1303,12 @@ if(isset($_GET['action']) && isset($_GET['confirm'])) $all_default = true; for($j=0; $j
";
-								var_dump($_POST);
-								echo "

"; - } - $value = $_POST[$i.":".$fields[$j]]; - } + $value = $_POST[$i.":".$j]; else $value = ""; if($value===$result[$j]['dflt_value']) @@ -1272,7 +1321,7 @@ if(isset($_GET['action']) && isset($_GET['confirm'])) $type = $result[$j]['type']; $typeAffinity = get_type_affinity($type); - $function = $_POST["function_".$i."_".$fields[$j]]; + $function = $_POST["function_".$i."_".$j]; if($function!="") $query_vals .= $function."("; if(($typeAffinity=="TEXT" || $typeAffinity=="NONE") && !$null) @@ -1348,13 +1397,12 @@ if(isset($_GET['action']) && isset($_GET['confirm'])) $all_default = true; for($j=0; $jquote_id($target_table)." SET "; for($j=0; $jquote_id($fields[$j])."="; if($function!="") $query .= $function."("; if($null) $query .= "NULL"; else - $query .= $db->quote($_POST[$field_index][$i]); + $query .= $db->quote($_POST[$j][$i]); if($function!="") $query .= ")"; $query .= ", "; @@ -1461,10 +1508,16 @@ if(isset($_GET['action']) && isset($_GET['confirm'])) } if($db->getVersion()==3 && ($_POST[$i.'_defaultoption']=='defined' || $_POST[$i.'_defaultoption']=='none' || $_POST[$i.'_defaultoption']=='NULL') - // Sqlite3 cannot add columns with default values that are not constant, so use AlterTable-workaround - && !isset($_POST[$i.'_primarykey'])) // sqlite3 cannot add primary key columns + // Sqlite3 cannot add columns with default values that are not constant + && !isset($_POST[$i.'_primarykey']) + // sqlite3 cannot add primary key columns + && (!isset($_POST[$i.'_notnull']) || $_POST[$i.'_defaultoption']!='none') + // SQLite3 cannot add NOT NULL columns without DEFAULT even if the table is empty + ) + // use SQLITE3 ALTER TABLE ADD COLUMN $result = $db->query($query, true); else + // use ALTER TABLE workaround $result = $db->query($query, false); if($result===false) $error = true; @@ -1580,6 +1633,8 @@ if(isset($_GET['action']) && isset($_GET['confirm'])) $str .= ", ".$db->quote_id($_POST[$i.'_field']).$_POST[$i.'_order']; } $str .= ")"; + if(isset($_POST['where']) && $_POST['where']!='') + $str.=" WHERE ".$_POST['where']; $query = $str; $result = $db->query($query); if($result===false) @@ -1607,44 +1662,15 @@ echo "".$lang['proj_site'].""; echo ""; //- HTML: database list -echo "
".$lang['db_ch'].""; -if(sizeof($databases)<10) //if there aren't a lot of databases, just show them as a list of links instead of drop down menu -{ - $i=0; - foreach($databases as $database) - { - $i++; - echo '[' . ($database['readable'] ? 'r':' ' ) . ($database['writable'] && $database['writable_dir'] ? 'w':' ' ) . '] '; - if($database == $_SESSION[COOKIENAME.'currentDB']) - echo "".htmlencode($database['name'])." ()"; - else - echo "".htmlencode($database['name'])." ()"; - if($i"; - } -} -else //there are a lot of databases - show a drop down menu -{ - echo "
"; - echo " "; - echo ""; - echo "
"; -} -echo "
"; +$db->print_db_list(); echo "
"; echo "".htmlencode($currentDB['name']).""; +$name = $currentDB['name']; +if(strlen($name)>25) + $name = "...".substr($name, strlen($name)-22, 22); +echo ">".htmlencode($name).""; echo ""; //- HTML: table list @@ -1672,13 +1698,23 @@ if($directory!==false && is_writable($directory)) { echo "
".$lang['db_create']." ".helpLink($lang['help2']).""; echo "
"; - echo " "; + echo $token_html; + echo ""; + if(class_exists('SQLiteDatabase') && (class_exists('SQLite3') || class_exists('PDO'))) + { + echo ""; + } + echo ""; echo "
"; echo "
"; } echo "
"; echo "
"; +echo $token_html; echo ""; echo "
"; echo "
"; @@ -1698,7 +1734,7 @@ if(isset($_GET['confirm'])) echo "
"; echo "
"; if(isset($error) && $error) //an error occured during the action, so show an error message - echo $lang['err'].": ".$db->getError()."
".$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK; + echo $lang['err'].": ".htmlencode($db->getError())."
".$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK; else //action was performed successfully - show success message echo $completed; echo "
"; @@ -1841,6 +1877,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $num = intval($_POST['tablefields']); $name = $_POST['tablename']; echo "
"; + echo $token_html; echo ""; echo ""; echo ""; @@ -1901,7 +1938,6 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //- Perform SQL query on table (=table_sql) case "table_sql": - $isSelect = false; if(isset($_POST['query']) && $_POST['query']!="") { $delimiter = $_POST['delimiter']; @@ -1922,37 +1958,18 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) if(str_replace(" ", "", str_replace("\n", "", str_replace("\r", "", $query[$i])))!="") //make sure this query is not an empty string { $queryTimer = new MicroTimer(); - $result = $db->selectArray($query[$i], "assoc"); - $queryTimer->stop(); + $table_result = $db->query($query[$i]); echo "
"; - echo ""; - - if($result !== NULL) + echo "".htmlencode($query[$i]).""; + if($table_result === NULL || $table_result === false) { - - if(sizeof($result)>0 || $db->getAffectedRows()==0) - { - printf($lang['show_rows'], sizeof($result)); - } - if($db->getAffectedRows()>0 || sizeof($result)==0) - { - echo $db->getAffectedRows()." ".$lang['rows_aff']." "; - } - printf($lang['query_time'], $queryTimer); - echo "
"; - } - else - { - echo $lang['err'].": ".$db->getError()."
"; + echo "
".$lang['err'].": ".htmlencode($db->getError())."
"; } - - echo "".htmlencode($query[$i]).""; echo "
"; - if(sizeof($result)>0) + if($row = $db->fetch($table_result, 'assoc')) { - $headers = array_keys($result[0]); - + $headers = array_keys($row); echo "
"; echo ""; for($j=0; $j"; } echo ""; - for($j=0; $jfetch($table_result, 'assoc'); $rowCount++) { - $tdWithClass = ""; for($z=0; $zNULL"; else - echo htmlencode(subString($result[$j][$headers[$z]])); + echo htmlencode(subString($row[$headers[$z]])); echo ""; } echo ""; } + $queryTimer->stop(); echo "
"; + $tdWithClass = ""; echo "


"; + + + if($table_result !== NULL && $table_result !== false) + { + echo "
"; + if($rowCount>0 || $db->getAffectedRows()==0) + { + printf($lang['show_rows'], $rowCount); + } + if($db->getAffectedRows()>0 || $rowCount==0) + { + echo $db->getAffectedRows()." ".$lang['rows_aff']." "; + } + printf($lang['query_time'], $queryTimer); + echo "
"; + } + + } } } @@ -1993,11 +2030,12 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo "
"; echo "".sprintf($lang['run_sql'],htmlencode($db->getName())).""; echo ""; + echo $token_html; if(isset($_SESSION['query_history']) && sizeof($_SESSION['query_history'])>0) { echo "".$lang['recent_queries']."

"; } echo "
"; @@ -2025,6 +2063,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //- Empty table (=table_empty) case "table_empty": echo ""; + echo $token_html; echo ""; echo "
"; echo sprintf($lang['ques_empty'], htmlencode($target_table))."

"; @@ -2036,6 +2075,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //- Drop table (=table_drop) case "table_drop": echo ""; + echo $token_html; echo ""; echo "
"; echo sprintf($lang['ques_drop'], htmlencode($target_table))."

"; @@ -2047,6 +2087,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //- Drop view (=view_drop) case "view_drop": echo ""; + echo $token_html; echo ""; echo "
"; echo sprintf($lang['ques_drop_view'], htmlencode($target_table))."

"; @@ -2058,6 +2099,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //- Export table (=table_export) case "table_export": echo ""; + echo $token_html; echo "
".$lang['export'].""; echo ""; echo ""; @@ -2097,7 +2139,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo " "; echo "
"; echo ""; - echo "
".sprintf($lang['backup_hint'], "".$lang["backup_hint_linktext"]."")."
"; + echo "
".sprintf($lang['backup_hint'], "".$lang["backup_hint_linktext"]."")."
"; break; //- Import table (=table_import) @@ -2108,10 +2150,11 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) if($importSuccess===true) echo $lang['import_suc']; else - echo $lang['err'].': '.$importSuccess; + echo $lang['err'].': '.htmlencode($importSuccess); echo "

"; } echo "
"; + echo $token_html; echo "
".$lang['import_into']." ".htmlencode($target_table).""; echo ""; echo "
"; @@ -2149,6 +2192,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //- Rename table (=table_rename) case "table_rename": echo ""; + echo $token_html; echo ""; printf($lang['rename_tbl'], htmlencode($target_table)); echo " "; @@ -2171,18 +2215,33 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $field_index = str_replace(" ","_",$field); $operator = $_POST[$field_index.":operator"]; $value = $_POST[$field_index]; - if($value!="" || $operator=="!= ''" || $operator=="= ''") + if($value!="" || $operator=="!= ''" || $operator=="= ''" || $operator == 'IS NULL' || $operator == 'IS NOT NULL') { - if($operator=="= ''" || $operator=="!= ''") + if($operator=="= ''" || $operator=="!= ''" || $operator == 'IS NULL' || $operator == 'IS NOT NULL') $arr[$j] = $db->quote_id($field)." ".$operator; - else{ if($operator == "LIKE%"){ $operator = "LIKE"; if(!preg_match('/(^%)|(%$)/', $value)) $value = '%'.$value.'%'; + $searchValues[$field] = array($value); + $value_quoted = $db->quote($value); } - $searchValues[$field] = $value; - $arr[$j] = $db->quote_id($field)." ".$operator." ".$db->quote($value); + elseif($operator == 'IN' || $operator == 'NOT IN') + { + $value = trim($value, '() '); + $values = explode(',',$value); + $values = array_map('trim', $values, array_fill(0,count($values),' \'"')); + if($operator == 'IN') + $searchValues[$field] = $values; + $values = array_map(array($db, 'quote'), $values); + $value_quoted = '(' .implode(', ', $values) . ')'; + } + else + { + $searchValues[$field] = array($value); + $value_quoted = $db->quote($value); + } + $arr[$j] = $db->quote_id($field)." ".$operator." ".$value_quoted; } $j++; } @@ -2223,7 +2282,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) } else { - echo $lang['err'].": ".$db->getError().".
".$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK.'
'; + echo $lang['err'].": ".htmlencode($db->getError()).".
".$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK.'
'; } echo "".htmlencode($query_disp).""; echo "

"; @@ -2284,12 +2343,15 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) { echo $tdWithClass; $fldResult = $arr[$j][$headers[$z]]; - if(isset($searchValues[$headers[$z]])) + if(isset($searchValues[$headers[$z]]) && is_array($searchValues[$headers[$z]])) { - $foundVal = str_replace('%', '', $searchValues[$headers[$z]]); - $fldResult = str_ireplace($foundVal, '[fnd]'.$foundVal.'[/fnd]', $fldResult); - // we replace with [fnd] first because we need to htmlencode _afterwards_ without breaking the found-markers - // htmlencoing _before_ would mean we might highlight stuff inside of htmlcode thus breaking it + foreach($searchValues[$headers[$z]] as $searchValue) + { + $foundVal = str_replace('%', '', $searchValue); + $fldResult = str_ireplace($foundVal, '[fnd]'.$foundVal.'[/fnd]', $fldResult); + // we replace with [fnd] first because we need to htmlencode _afterwards_ without breaking the found-markers + // htmlencoing _before_ would mean we might highlight stuff inside of htmlcode thus breaking it + } } echo str_replace(array('[fnd]', '[/fnd]'), array('', ''), htmlencode($fldResult)); echo ""; @@ -2307,6 +2369,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $result = $db->selectArray($query); echo ""; + echo $token_html; echo ""; echo ""; @@ -2352,6 +2415,10 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo ""; echo ""; echo ""; + echo ""; + echo ""; + echo ""; + echo ""; echo ""; echo ""; echo $tdWithClassLeft; @@ -2380,7 +2447,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $_POST['startRow'] = 0; if(isset($_POST['numRows'])) - $_SESSION[COOKIENAME.'numRows'] = $_POST['numRows']; + $_SESSION[COOKIENAME.'numRows'] = intval($_POST['numRows']); if(!isset($_SESSION[COOKIENAME.'numRows'])) $_SESSION[COOKIENAME.'numRows'] = $rowsNum; @@ -2414,6 +2481,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) { echo "
"; echo ""; + echo $token_html; echo ""; echo " "; echo " "; @@ -2421,6 +2489,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo "
"; echo "
"; echo ""; + echo $token_html; echo ""; echo " "; echo " "; @@ -2431,6 +2500,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //show certain number buttons echo "
"; echo ""; + echo $token_html; echo " "; echo " "; echo $lang['rows_records']; @@ -2460,6 +2530,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) { echo "
"; echo ""; + echo $token_html; echo ""; echo " "; echo " "; @@ -2467,6 +2538,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo "
"; echo "
"; echo ""; + echo $token_html; echo ""; echo " "; echo " "; @@ -2506,6 +2578,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) } $query .= " FROM ".$db->quote_id($target_table); $queryDisp = "SELECT * FROM ".$db->quote_id($target_table); + $queryCount = "SELECT MIN(COUNT(*),".$numRows.") AS count FROM ".$db->quote_id($target_table); $queryAdd = ""; if(isset($_SESSION[COOKIENAME.'sortRows'])) $queryAdd .= " ORDER BY ".$db->quote_id($_SESSION[COOKIENAME.'sortRows']); @@ -2514,15 +2587,20 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $queryAdd .= " LIMIT ".$startRow.", ".$numRows; $query .= $queryAdd; $queryDisp .= $queryAdd; - $queryTimer = new MicroTimer(); - $arr = $db->selectArray($query); - $queryTimer->stop(); + + $resultRows = $db->select($queryCount); + $resultRows = $resultRows['count']; //- Show results - if(sizeof($arr)>0) + if($resultRows>0) { + $queryTimer = new MicroTimer(); + $table_result = $db->query($query); + $queryTimer->stop(); + + echo "
"; - echo "".$lang['showing_rows']." ".$startRow." - ".($startRow + sizeof($arr)-1).", ".$lang['total'].": ".$rowCount." "; + echo "".$lang['showing_rows']." ".$startRow." - ".($startRow + $resultRows-1).", ".$lang['total'].": ".$rowCount." "; printf($lang['query_time'], $queryTimer); echo "
"; echo "".htmlencode($queryDisp).""; @@ -2541,6 +2619,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) if(!isset($_SESSION[COOKIENAME.'viewtype']) || $_SESSION[COOKIENAME.'viewtype']=="table") { echo ""; + echo $token_html; echo "
"; echo ""; if($target_table_type == 'table') @@ -2567,19 +2646,19 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) } echo ""; - for($i=0; $ifetch($table_result); $i++) { // -g-> $pk will always be the last columns in each row of the array because we are doing "SELECT *, PK_1, typeof(PK_1), PK2, typeof(PK_2), ... FROM ..." $pk_arr = array(); - for($col = $pkFirstCol; array_key_exists($col, $arr[$i]); $col=$col+2) + for($col = $pkFirstCol; array_key_exists($col, $row); $col=$col+2) { // in $col we have the type and in $col-1 the value - if($arr[$i][$col]=='integer' || $arr[$i][$col]=='real') + if($row[$col]=='integer' || $row[$col]=='real') // json encode as int or float, not string - $pk_arr[] = $arr[$i][$col-1]+0; + $pk_arr[] = $row[$col-1]+0; else // encode as json string - $pk_arr[] = $arr[$i][$col-1]; + $pk_arr[] = $row[$col-1]; } $pk = json_encode($pk_arr); $tdWithClass = ""; } echo ""; @@ -2700,19 +2779,19 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) data.addColumn('number', ''); data.addRows([ fetch($table_result); $i++) { - $label = str_replace("'", "", htmlencode($arr[$i][$_SESSION[COOKIENAME.$target_table.'chartlabels']])); - $value = htmlencode($arr[$i][$_SESSION[COOKIENAME.$target_table.'chartvalues']]); + $label = str_replace("'", "", htmlencode($row[$_SESSION[COOKIENAME.$target_table.'chartlabels']])); + $value = htmlencode($row[$_SESSION[COOKIENAME.$target_table.'chartvalues']]); if($value==NULL || $value=="") $value = 0; echo "['".$label."', ".$value."]"; - if($i1000) $height = 1000; else if($height<300) @@ -2746,6 +2825,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) Chart Settings"; echo ""; + echo $token_html; echo $lang['chart_type'].": "; for($i=1; $i<=40; $i++) @@ -2820,6 +2901,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; $result = $db->selectArray($query); echo ""; + echo $token_html; if(isset($_POST['num'])) $num = $_POST['num']; else @@ -2841,7 +2923,6 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) for($i=0; $i"; echo ""; echo $tdWithClassLeft; - echo $field_html; + echo htmlencode($field); echo ""; echo $tdWithClassLeft; echo htmlencode($type); echo ""; echo $tdWithClassLeft; - echo ""; echo ""; foreach (array_merge($sqlite_functions, $custom_functions) as $f) { echo ""; @@ -2868,9 +2949,9 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) if($result[$i]['notnull']==0) { if($result[$i]['dflt_value']==="NULL") - echo ""; + echo ""; else - echo ""; + echo ""; } echo ""; echo $tdWithClassLeft; @@ -2880,9 +2961,9 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $dflt_value = htmlencode(deQuoteSQL($result[$i]['dflt_value'])); if($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") - echo ""; + echo ""; else - echo ""; + echo ""; echo ""; echo ""; } @@ -2922,6 +3003,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) if((isset($_POST['type']) && $_POST['type']=="edit") || (isset($_GET['type']) && $_GET['type']=="edit")) //edit { echo ""; + echo $token_html; $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; $result = $db->selectArray($query); @@ -2964,7 +3046,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo htmlencode($type); echo ""; echo $tdWithClassLeft; - echo ""; echo ""; foreach (array_merge($sqlite_functions, $custom_functions) as $f) { echo ""; @@ -2975,16 +3057,16 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) if($result[$i][3]==0) { if($value===NULL) - echo ""; + echo ""; else - echo ""; + echo ""; } echo ""; echo $tdWithClassLeft; if($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") - echo ""; + echo ""; else - echo ""; + echo ""; echo ""; echo ""; } @@ -3004,6 +3086,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) else //delete { echo ""; + echo $token_html; echo "
"; printf($lang['ques_del_rows'], htmlencode($str), htmlencode($target_table)); echo "

"; @@ -3022,6 +3105,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $result = $db->selectArray($query); echo ""; + echo $token_html; echo "
"; @@ -2605,12 +2684,12 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo $tdWithClass; else echo $tdWithClassLeft; - if($arr[$i][$j]==="") + if($row[$j]==="") echo " "; - elseif($arr[$i][$j]===NULL) + elseif($row[$j]===NULL) echo "NULL"; else - echo htmlencode(subString($arr[$i][$j])); + echo htmlencode(subString($row[$j])); echo "
"; echo ""; if($target_table_type == 'table') @@ -3115,6 +3199,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) { echo "
"; echo ""; + echo $token_html; echo ""; echo $lang['add']." ".$lang['tbl_end']." "; echo ""; @@ -3130,7 +3215,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo "".htmlencode($master[0]['sql']).""; echo ""; echo "
"; - if($target_table_type == 'view') + if($target_table_type != 'view') { echo "


"; //$query = "SELECT * FROM sqlite_master WHERE type='index' AND tbl_name='".$target_table."'"; @@ -3224,6 +3309,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) } echo "
"; + echo $token_html; echo ""; echo "
"; echo $lang['create_index2']." ".$lang['cols']." "; @@ -3231,6 +3317,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) echo ""; echo "
"; + echo $token_html; echo ""; echo "
"; echo $lang['create_trigger2']." "; @@ -3251,6 +3338,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $num = intval($_POST['tablefields']); $name = $_POST['tablename']; echo ""; + echo $token_html; echo ""; echo ""; echo "
"; @@ -3333,7 +3421,8 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $str .= ", ".$pks[$i]; $pkVal .= ":".$pks[$i]; } - echo ""; + echo ""; + echo $token_html; echo "
"; printf($lang['ques_'.$_REQUEST['action2']], htmlencode($str), htmlencode($target_table)); echo "

"; @@ -3372,6 +3461,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) $name = $target_table; echo ""; + echo $token_html; echo ""; echo ""; echo "
"; @@ -3439,6 +3529,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //- Delete index (=index_delete) case "index_delete": echo ""; + echo $token_html; echo "
"; echo sprintf($lang['ques_del_index'], htmlencode($_GET['pk']))."

"; echo " "; @@ -3450,6 +3541,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) //- Delete trigger (=trigger_delete) case "trigger_delete": echo ""; + echo $token_html; echo "
"; echo sprintf($lang['ques_del_trigger'], htmlencode($_GET['pk']))."

"; echo " "; @@ -3466,6 +3558,7 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) else { echo ""; + echo $token_html; echo $lang['trigger_name'].":

"; echo "
".$lang['db_event'].""; echo $lang['before']."/".$lang['after'].": "; @@ -3507,17 +3600,20 @@ if(isset($_GET['action']) && !isset($_GET['confirm'])) else { echo ""; + echo $token_html; $num = intval($_POST['numcolumns']); $query = "PRAGMA table_info(".$db->quote_id($_POST['tablename']).")"; $result = $db->selectArray($query); echo "
".$lang['define_index'].""; - echo $lang['index_name'].":
"; - echo $lang['dup_val'].": "; - echo "
"; + echo ""; + echo "
"; + if(version_compare($db->getSQLiteVersion(),'3.8.0')>=0) + echo " ".helpLink($lang['help10']); echo "
"; echo "
"; echo "
".$lang['define_in_col'].""; @@ -3607,10 +3703,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is if($view=="structure") { //- Database structure, shows all the tables (=structure) - $query = "SELECT sqlite_version() AS sqlite_version"; - $queryVersion = $db->select($query); - $realVersion = $queryVersion['sqlite_version']; - + if(isset($dbexists)) { echo "
"; @@ -3645,7 +3738,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is echo "".$lang['db_path'].": ".htmlencode($db->getPath())."
"; echo "".$lang['db_size'].": ".$db->getSize()." KB
"; echo "".$lang['db_mod'].": ".$db->getDate()."
"; - echo "".$lang['sqlite_v'].": ".$realVersion."
"; + echo "".$lang['sqlite_v'].": ".$db->getSQLiteVersion()."
"; echo "".$lang['sqlite_ext']." ".helpLink($lang['help1']).": ".$db->getType()."
"; echo "".$lang['php_v'].": ".phpversion()."
"; echo "".PROJECT." ".$lang["ver"].": ".VERSION; @@ -3766,7 +3859,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is { echo "
"; echo $tdWithClassLeft; - echo "View"; + echo $lang['view']; echo ""; echo $tdWithClassLeft; echo "".htmlencode($result[$i]['name']).""; @@ -3819,6 +3912,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is echo "
"; echo "".$lang['create_tbl_db']." '".htmlencode($db->getName())."'"; echo ""; + echo $token_html; echo $lang['name'].": "; echo $lang['fld_num'].": "; echo ""; @@ -3828,6 +3922,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is echo "
"; echo "".$lang['create_view']." '".htmlencode($db->getName())."'"; echo ""; + echo $token_html; echo $lang['name'].": "; echo $lang['sel_state']." ".helpLink($lang['help4']).": "; echo ""; @@ -3837,7 +3932,6 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is else if($view=="sql") { //- Database SQL editor (=sql) - $isSelect = false; if(isset($_POST['query']) && $_POST['query']!="") { $delimiter = $_POST['delimiter']; @@ -3858,36 +3952,18 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is if(str_replace(" ", "", str_replace("\n", "", str_replace("\r", "", $query[$i])))!="") //make sure this query is not an empty string { $queryTimer = new MicroTimer(); - $result = $db->selectArray($query[$i], "assoc"); - $queryTimer->stop(); + $table_result = $db->query($query[$i]); echo "
"; - echo ""; - - if($result !== NULL) + echo "".htmlencode($query[$i]).""; + if($table_result === NULL || $table_result === false) { - - if(sizeof($result)>0 || $db->getAffectedRows()==0) - { - printf($lang['show_rows'], sizeof($result)); - } - if($db->getAffectedRows()>0 || sizeof($result)==0) - { - echo $db->getAffectedRows()." ".$lang['rows_aff']." "; - } - printf($lang['query_time'], $queryTimer); - echo "
"; + echo "
".$lang['err'].": ".htmlencode($db->getError())."
"; } - else - { - echo $lang['err'].": ".$db->getError()."

"; - } - echo "".htmlencode($query[$i]).""; echo "
"; - if(sizeof($result)>0) + if($row = $db->fetch($table_result, 'assoc')) { - $headers = array_keys($result[0]); - + $headers = array_keys($row); echo "
"; echo ""; for($j=0; $j"; } echo ""; - for($j=0; $jfetch($table_result, 'assoc'); $rowCount++) { - $tdWithClass = ""; for($z=0; $zNULL"; else - echo htmlencode(subString($result[$j][$headers[$z]])); + echo htmlencode(subString($row[$headers[$z]])); echo ""; } echo ""; } + $queryTimer->stop(); echo "
"; + $tdWithClass = ""; echo "


"; + + + if($table_result !== NULL && $table_result !== false) + { + echo "
"; + if($rowCount>0 || $db->getAffectedRows()==0) + { + printf($lang['show_rows'], $rowCount); + } + if($db->getAffectedRows()>0 || $rowCount==0) + { + echo $db->getAffectedRows()." ".$lang['rows_aff']." "; + } + printf($lang['query_time'], $queryTimer); + echo "
"; + } + + } - } + } } } else @@ -3928,12 +4024,13 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is echo "
"; echo "".sprintf($lang['run_sql'],htmlencode($db->getName())).""; echo ""; + echo $token_html; if(isset($_SESSION['query_history']) && sizeof($_SESSION['query_history'])>0) { echo "".$lang['recent_queries']."

"; } @@ -3955,6 +4052,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is echo "

"; } echo ""; + echo $token_html; printf($lang['vac_desc'],htmlencode($db->getName())); echo "

"; echo ""; @@ -3964,6 +4062,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is { //- Export view (=export) echo ""; + echo $token_html; echo "
".$lang['export'].""; echo " "; echo "
"; echo ""; - echo "
".sprintf($lang['backup_hint'], "".$lang["backup_hint_linktext"]."")."
"; + echo "
".sprintf($lang['backup_hint'], "".$lang["backup_hint_linktext"]."")."
"; } else if($view=="import") { @@ -4028,6 +4127,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is } echo "
"; + echo $token_html; echo "
".$lang['import'].""; echo ""; echo "
"; @@ -4101,6 +4201,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is echo "

"; } echo ""; + echo $token_html; echo ""; echo $lang['db_rename']." '".htmlencode($db->getPath())."' ".$lang['to']." "; echo ""; @@ -4109,6 +4210,7 @@ if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (is { //- Delete database confirmation (=delete) echo "
"; + echo $token_html; echo "
"; echo sprintf($lang['ques_del_db'],htmlencode($db->getPath()))."

"; echo ""; @@ -4256,6 +4358,7 @@ class Database echo "
"; printf($lang['db_not_writeable'], htmlencode($this->data["path"]), htmlencode(dirname($this->data["path"]))); echo ""; + echo ''; echo ""; echo ""; echo "

"; @@ -4266,21 +4369,21 @@ class Database switch(true) { - case (FORCETYPE=="PDO" || ((FORCETYPE==false || $ver!=-1) && class_exists("PDO") && ($ver==-1 || $ver==3))): + case ((!isset($data['type']) || $data['type']!=2) && (FORCETYPE=="PDO" || (FORCETYPE==false && class_exists("PDO") && ($ver==-1 || $ver==3)))): $this->db = new PDO("sqlite:".$this->data['path']); if($this->db!=NULL) { $this->type = "PDO"; break; } - case (FORCETYPE=="SQLite3" || ((FORCETYPE==false || $ver!=-1) && class_exists("SQLite3") && ($ver==-1 || $ver==3))): + case ((!isset($data['type']) || $data['type']!=2) && (FORCETYPE=="SQLite3" || (FORCETYPE==false && class_exists("SQLite3") && ($ver==-1 || $ver==3)))): $this->db = new SQLite3($this->data['path']); if($this->db!=NULL) { $this->type = "SQLite3"; break; } - case (FORCETYPE=="SQLiteDatabase" || ((FORCETYPE==false || $ver!=-1) && class_exists("SQLiteDatabase") && ($ver==-1 || $ver==2))): + case (FORCETYPE=="SQLiteDatabase" || (FORCETYPE==false && class_exists("SQLiteDatabase") && ($ver==-1 || $ver==2))): $this->db = new SQLiteDatabase($this->data['path']); if($this->db!=NULL) { @@ -4291,6 +4394,7 @@ class Database $this->showError(); exit(); } + $this->query("PRAGMA foreign_keys = ON"); } catch(Exception $e) { @@ -4368,8 +4472,54 @@ class Database else echo $lang['report_issue'].' '.PROJECT_BUGTRACKER_LINK.'.'; } - echo "
See ".PROJECT_INSTALL_LINK." for help."; - echo "

"; + echo "

See ".PROJECT_INSTALL_LINK." for help.

"; + + $this->print_db_list(); + + echo "
"; + } + + // print the list of databases + public function print_db_list() + { + global $databases, $lang; + echo "
".$lang['db_ch'].""; + if(sizeof($databases)<10) //if there aren't a lot of databases, just show them as a list of links instead of drop down menu + { + $i=0; + foreach($databases as $database) + { + $i++; + $name = $database['name']; + if(strlen($name)>25) + $name = "...".substr($name, strlen($name)-22, 22); + echo '[' . ($database['readable'] ? 'r':' ' ) . ($database['writable'] && $database['writable_dir'] ? 'w':' ' ) . '] '; + if($database == $_SESSION[COOKIENAME.'currentDB']) + echo "".htmlencode($name)."  [↓]"; + else + echo "".htmlencode($name)."  [↓]"; + if($i"; + } + } + else //there are a lot of databases - show a drop down menu + { + echo "
"; + echo ''; + echo " "; + echo ""; + echo "
"; + } + echo "
"; } public function __destruct() @@ -4383,6 +4533,13 @@ class Database { return $this->type; } + + // get the version of the SQLite library + public function getSQLiteVersion() + { + $queryVersion = $this->select("SELECT sqlite_version() AS sqlite_version"); + return $queryVersion['sqlite_version']; + } //get the name of the database public function getName() @@ -4500,7 +4657,7 @@ class Database } $tablename = str_replace('""','"',$matches[1]); $alterdefs = $matches[2]; - if($debug) echo "ALTER TABLE QUERY=(".htmlencode($query)."), tablename=($tablename), alterdefs=($alterdefs)
"; + if($debug) echo "ALTER TABLE QUERY=(".htmlencode($query)."), tablename=($tablename), alterdefs=($alterdefs)
"; $result = $this->alterTable($tablename, $alterdefs); } else //this query is normal - proceed as normal @@ -4611,6 +4768,46 @@ class Database return $result->fetchAll($mode); } } + + //returns an array of the next row in $result + public function fetch($result, $mode="both") + { + //make sure the result is valid + if($result=== false || $result===NULL) + return NULL; // error + if(!is_object($result)) // no rows returned + return array(); + if($this->type=="PDO") + { + if($mode=="assoc") + $mode = PDO::FETCH_ASSOC; + else if($mode=="num") + $mode = PDO::FETCH_NUM; + else + $mode = PDO::FETCH_BOTH; + return $result->fetch($mode); + } + else if($this->type=="SQLite3") + { + if($mode=="assoc") + $mode = SQLITE3_ASSOC; + else if($mode=="num") + $mode = SQLITE3_NUM; + else + $mode = SQLITE3_BOTH; + return $result->fetchArray($mode); + } + else if($this->type=="SQLiteDatabase") + { + if($mode=="assoc") + $mode = SQLITE_ASSOC; + else if($mode=="num") + $mode = SQLITE_NUM; + else + $mode = SQLITE_BOTH; + return $result->fetch($mode); + } + } // SQlite supports multiple ways of surrounding names in quotes: @@ -4624,10 +4821,18 @@ class Database if($notAllowedName!==false && $preg_quote) $notAllowedName = preg_quote($notAllowedName,"/"); // use possesive quantifiers to save memory - $nameSingle = ($notAllowedName!==false?"(?!".$notAllowedName."')":"")."(?:[^']$name+|'')$name+"; - $nameDouble = ($notAllowedName!==false?"(?!".$notAllowedName."\")":"")."(?:[^\"]$name+|\"\")$name+"; - $nameBacktick = ($notAllowedName!==false?"(?!".$notAllowedName."`)":"")."(?:[^`]$name+|``)$name+"; - $nameSquare = ($notAllowedName!==false?"(?!".$notAllowedName."\])":"")."(?:[^\]]$name+|\]\])$name+"; + // (There is a bug in PCRE starting in 8.13 and fixed in PCRE 8.36 + // why we can't use posesive quantifiers - See issue #310). + if(version_compare(strstr(constant('PCRE_VERSION'), ' ', true), '8.36', '>=') || + version_compare(strstr(constant('PCRE_VERSION'), ' ', true), '8.12', '<=')) + $posessive='+'; + else + $posessive=''; + + $nameSingle = ($notAllowedName!==false?"(?!".$notAllowedName."')":"")."(?:[^']$name+|'')$name".$posessive; + $nameDouble = ($notAllowedName!==false?"(?!".$notAllowedName."\")":"")."(?:[^\"]$name+|\"\")$name".$posessive; + $nameBacktick = ($notAllowedName!==false?"(?!".$notAllowedName."`)":"")."(?:[^`]$name+|``)$name".$posessive; + $nameSquare = ($notAllowedName!==false?"(?!".$notAllowedName."\])":"")."(?:[^\]]$name+|\]\])$name".$posessive; $nameNo = ($notAllowedName!==false?"(?!".$notAllowedName."\s)":"")."[^".$notAllowedCharsIfNone."]$name"; } else @@ -4660,7 +4865,8 @@ class Database case PREG_BACKTRACK_LIMIT_ERROR: return 'Backtrack limit was exhausted!'; case PREG_RECURSION_LIMIT_ERROR: return 'Recursion limit was exhausted!'; case PREG_BAD_UTF8_ERROR: return 'Bad UTF8 error!'; - case PREG_BAD_UTF8_ERROR: return 'Bad UTF8 offset error!'; + // PREG_BAD_UTF8_OFFSET_ERROR is introduced in PHP 5.3.0, which is not yet required by PLA, so we use its value 5 instead so long + case 5: return 'Bad UTF8 offset error!'; default: return 'Unknown Error'; } } @@ -4673,7 +4879,7 @@ class Database global $debug, $lang; $this->alterError=""; $errormsg = sprintf($lang['alter_failed'],htmlencode($table)).' - '; - if($debug) echo "ALTER TABLE: table=($table), alterdefs=($alterdefs)
"; + if($debug) echo "ALTER TABLE: table=($table), alterdefs=($alterdefs), PCRE version=(".PCRE_VERSION.")

"; if($alterdefs != '') { $recreateQueries = array(); @@ -4681,7 +4887,7 @@ class Database if(sizeof($resultArr)<1) { $this->alterError = $errormsg . sprintf($lang['tbl_inexistent'], htmlencode($table)); - if($debug) echo "ERROR: unknown table
"; + if($debug) echo "ERROR: unknown table

"; return false; } for($i=0; $i"; + if($debug) echo "recreate=(".$row['sql'].";)
"; } } else @@ -4703,15 +4909,15 @@ class Database $origsql = $row['sql']; $preg_remove_create_table = "/^\s*+CREATE\s++TABLE\s++".$this->sqlite_surroundings_preg($table)."\s*+(\(.*+)$/is"; $origsql_no_create = preg_replace($preg_remove_create_table, '$1', $origsql, 1); - if($debug) echo "origsql=($origsql)
preg_remove_create_table=($preg_remove_create_table)
"; + if($debug) echo "origsql=($origsql)
preg_remove_create_table=($preg_remove_create_table)
"; if($origsql_no_create == $origsql) { $this->alterError = $errormsg . $lang['alter_tbl_name_not_replacable']; if($debug) echo "ERROR: could not get rid of CREATE TABLE
"; return false; } - $createtemptableSQL = "CREATE TEMPORARY TABLE ".$this->quote($tmpname)." ".$origsql_no_create; - if($debug) echo "createtemptableSQL=($createtemptableSQL)
"; + $createtemptableSQL = "CREATE TABLE ".$this->quote($tmpname)." ".$origsql_no_create; + if($debug) echo "createtemptableSQL=($createtemptableSQL)
"; $createindexsql = array(); $preg_alter_part = "/(?:DROP(?! PRIMARY KEY)|ADD(?! PRIMARY KEY)|CHANGE|RENAME TO|ADD PRIMARY KEY|DROP PRIMARY KEY)" // the ALTER command ."(?:" @@ -4720,7 +4926,7 @@ class Database ."\s+".$this->sqlite_surroundings_preg("+",false,",'\"\[`") // column names and stuff like this .")*/i"; if($debug) - echo "preg_alter_part=(".$preg_alter_part.")
"; + echo "preg_alter_part=(".$preg_alter_part.")
"; preg_match_all($preg_alter_part,$alterdefs,$matches); $defs = $matches[0]; @@ -4750,12 +4956,12 @@ class Database if(count($defs)<1) { $this->alterError = $errormsg . $lang['alter_no_def']; - if($debug) echo "ERROR: defs<1
"; + if($debug) echo "ERROR: defs<1

"; return false; } foreach($defs as $def) { - if($debug) echo "def=$def
"; + if($debug) echo "
def=$def
"; $preg_parse_def = "/^(DROP(?! PRIMARY KEY)|ADD(?! PRIMARY KEY)|CHANGE|RENAME TO|ADD PRIMARY KEY|DROP PRIMARY KEY)" // $matches[1]: command ."(?:" // this is either @@ -4775,18 +4981,18 @@ class Database ")" ."?\s*$" .")?\s*$/i"; // in case of DROP PRIMARY KEY, there is nothing after the command - if($debug) echo "preg_parse_def=$preg_parse_def
"; + if($debug) echo "preg_parse_def=$preg_parse_def
"; $parse_def = preg_match($preg_parse_def,$def,$matches); if($parse_def===false) { $this->alterError = $errormsg . $lang['alter_parse_failed']; - if($debug) echo "ERROR: !parse_def
"; + if($debug) echo "ERROR: !parse_def

"; return false; } if(!isset($matches[1])) { $this->alterError = $errormsg . $lang['alter_action_not_recognized']; - if($debug) echo "ERROR: !isset(matches[1])
"; + if($debug) echo "ERROR: !isset(matches[1])

"; return false; } $action = strtolower($matches[1]); @@ -4803,7 +5009,7 @@ class Database $column_escaped = str_replace("'","''",$column); - if($debug) echo "action=($action), column=($column), column_escaped=($column_escaped)
"; + if($debug) echo "action=($action), column=($column), column_escaped=($column_escaped)
"; /* we build a regex that devides the CREATE TABLE statement parts: Part example Group Explanation @@ -4812,11 +5018,11 @@ class Database 3. 'colX' ..., (with colX being the column to change/drop) 4. 'colX+1' ..., ..., 'colK') $5 (with colX+1-colK being columns after the column to change/drop) */ - $preg_create_table = "\s*+(CREATE\s++TEMPORARY\s++TABLE\s++".preg_quote($this->quote($tmpname),"/")."\s*+\()"; // This is group $1 (keep unchanged) + $preg_create_table = "\s*+(CREATE\s++TABLE\s++".preg_quote($this->quote($tmpname),"/")."\s*+\()"; // This is group $1 (keep unchanged) $preg_column_definiton = "\s*+".$this->sqlite_surroundings_preg("+",true," '\"\[`,",$column)."(?:\s*+".$this->sqlite_surroundings_preg("*",false,"'\",`\[ ").")++"; // catches a complete column definition, even if it is // 'column' TEXT NOT NULL DEFAULT 'we have a comma, here and a double ''quote!' // this definition does NOT match columns with the column name $column - if($debug) echo "preg_column_definition=(".$preg_column_definiton.")
"; + if($debug) echo "preg_column_definition=(".$preg_column_definiton.")
"; $preg_columns_before = // columns before the one changed/dropped (keep) "(?:". "(". // group $2. Keep this one unchanged! @@ -4827,7 +5033,7 @@ class Database ")". // end of group $2 ",\s*+" // the last comma of the last column before the column to change. Do not keep it! .")?"; // there might be no columns before - if($debug) echo "preg_columns_before=(".$preg_columns_before.")
"; + if($debug) echo "preg_columns_before=(".$preg_columns_before.")
"; $preg_columns_after = "(,\s*(.+))?"; // the columns after the column to drop. This is group $3 (drop) or $4(change) (keep!) // we could remove the comma using $6 instead of $5, but then we might have no comma at all. // Keeping it leaves a problem if we drop the first column, so we fix that case in another regex. @@ -4850,9 +5056,9 @@ class Database $preg_error = $this->getPregError(); if($debug) { - echo $createtesttableSQL."
"; - echo $newSQL."
"; - echo $preg_pattern_add."
"; + echo $createtesttableSQL."

"; + echo $newSQL."

"; + echo $preg_pattern_add."

"; } if($newSQL==$createtesttableSQL) // pattern did not match, so column adding did not succed { @@ -4880,14 +5086,14 @@ class Database $preg_error = $this->getPregError(); // remove comma at the beginning if the first column is changed // probably somebody is able to put this into the first regex (using lookahead probably). - $newSQL = preg_replace("/^\s*(CREATE\s+TEMPORARY\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); + $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); if($debug) { - echo "preg_column_to_change=(".$preg_column_to_change.")
"; - echo $createtesttableSQL."
"; - echo $newSQL."
"; + echo "preg_column_to_change=(".$preg_column_to_change.")

"; + echo $createtesttableSQL."

"; + echo $newSQL."

"; - echo $preg_pattern_change."
"; + echo $preg_pattern_change."

"; } if($newSQL==$createtesttableSQL || $newSQL=="") // pattern did not match, so column removal did not succed { @@ -4906,12 +5112,12 @@ class Database $preg_error = $this->getPregError(); // remove comma at the beginning if the first column is removed // probably somebody is able to put this into the first regex (using lookahead probably). - $newSQL = preg_replace("/^\s*(CREATE\s+TEMPORARY\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); + $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); if($debug) { - echo $createtesttableSQL."
"; - echo $newSQL."
"; - echo $preg_pattern_drop."
"; + echo $createtesttableSQL."

"; + echo $newSQL."

"; + echo $preg_pattern_drop."

"; } if($newSQL==$createtesttableSQL || $newSQL=="") // pattern did not match, so column removal did not succed { @@ -4966,14 +5172,14 @@ class Database $newSQL = preg_replace($preg_pattern_change, '$1$2,$3$4$5$6)', $createtesttableSQL); // remove comma at the beginning if the first column is changed // probably somebody is able to put this into the first regex (using lookahead probably). - $newSQL = preg_replace("/^\s*(CREATE\s+TEMPORARY\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); + $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); if($debug) { - echo "preg_column_to_change=(".$preg_column_to_change.")
"; - echo $createtesttableSQL."
"; - echo $newSQL."
"; + echo "preg_column_to_change=(".$preg_column_to_change.")

"; + echo $createtesttableSQL."

"; + echo $newSQL."

"; - echo $preg_pattern_change."
"; + echo $preg_pattern_change."

"; } if($newSQL!=$createtesttableSQL && $newSQL!="") // pattern did match, so PRIMARY KEY constraint removed :) { @@ -4993,14 +5199,14 @@ class Database break; default: - if($debug) echo 'ERROR: unknown alter operation!
'; + if($debug) echo 'ERROR: unknown alter operation!

'; $this->alterError = $errormsg . $lang['alter_unknown_operation']; return false; } } $droptempsql = 'DROP TABLE '.$this->quote_id($tmpname); - $createnewtableSQL = "CREATE TABLE ".$this->quote($table_new)." ".preg_replace("/^\s*CREATE\s+TEMPORARY\s+TABLE\s+'?".str_replace("'","''",preg_quote($tmpname,"/"))."'?\s+(.*)$/is", '$1', $createtesttableSQL, 1); + $createnewtableSQL = "CREATE TABLE ".$this->quote($table_new)." ".preg_replace("/^\s*CREATE\s+TABLE\s+'?".str_replace("'","''",preg_quote($tmpname,"/"))."'?\s+(.*)$/is", '$1', $createtesttableSQL, 1); $newcolumns = ''; $oldcolumns = ''; @@ -5032,7 +5238,7 @@ class Database { if(!isset($newcols[$indexInfo['name']])) { - if($debug) echo 'Not recreating the following index:
'.htmlencode($recreate_query['sql']).'
'; + if($debug) echo 'Not recreating the following index:

'.htmlencode($recreate_query['sql']).'

'; // Index on a column that was dropped. Skip recreation. continue 2; } @@ -5057,7 +5263,7 @@ class Database else { // the CREATE INDEX regex did not match. this normally should not happen - if($debug) echo 'ERROR: CREATE INDEX regex did not match!?
'; + if($debug) echo 'ERROR: CREATE INDEX regex did not match!?

'; // just try to recreate the index originally (will fail most likely) $alter_transaction .= $recreate_query['sql'].';'; } @@ -5068,7 +5274,7 @@ class Database $alter_transaction .= $recreate_query['sql'].';'; break; default: - if($debug) echo 'ERROR: Unknown type '.htmlencode($recreate_query['type']).'
'; + if($debug) echo 'ERROR: Unknown type '.htmlencode($recreate_query['type']).'

'; $alter_transaction .= $recreate_query['sql'].';'; } } @@ -5218,7 +5424,7 @@ class Database if($field_enclosed=="") $field_enclosed='"'; // PHP requires escaper defined if($field_escaped=="") $field_escaped='\\'; - while(!feof($csv_handle)) + while($csv_handle!==false && !feof($csv_handle)) { $csv_data = fgetcsv($csv_handle, 0, $field_terminate, $field_enclosed, $field_escaped); if($csv_data[0] != NULL || count($csv_data)>1) @@ -5254,19 +5460,24 @@ class Database } } } - $csv_insert .= "COMMIT;"; - fclose($csv_handle); - $import = $this->multiQuery($csv_insert); - if(!$import) - return $this->getError(); + if($csv_handle === false) + return "Error reading CSV file"; else - return true; + { + $csv_insert .= "COMMIT;"; + fclose($csv_handle); + $import = $this->multiQuery($csv_insert); + if(!$import) + return $this->getError(); + else + return true; + } } //export csv public function export_csv($tables, $field_terminate, $field_enclosed, $field_escaped, $null, $crlf, $fields_in_first_row) { - $field_enclosed = $field_enclosed; + @set_time_limit(-1); $query = "SELECT * FROM sqlite_master WHERE type='table' or type='view' ORDER BY type DESC"; $result = $this->selectArray($query); for($i=0; $iquote_id($result[$i]['tbl_name']); - $arr = $this->selectArray($query, "assoc"); - for($z=0; $zquery($query); + $firstRow=true; + while($row = $this->fetch($table_result, "assoc")) { + if(!$firstRow) + echo "\r\n"; + else + $firstRow=false; + for($y=0; $yquote_id($result[$i]['name']).";\r\n"; + echo "DROP ".strtoupper($result[$i]['type'])." IF EXISTS ".$this->quote_id($result[$i]['name']).";\r\n"; } if($structure) { @@ -5383,38 +5599,36 @@ class Database if($data && $result[$i]['type']=="table") { $query = "SELECT * FROM ".$this->quote_id($result[$i]['tbl_name']); - $arr = $this->selectArray($query, "assoc"); + $table_result = $this->query($query, "assoc"); if($comments) { + $numRows = $this->numRows($result[$i]['tbl_name']); echo "\r\n----\r\n"; - echo "-- ".$lang['data_dump']." ".$result[$i]['tbl_name'].", ".sprintf($lang['total_rows'], sizeof($arr))."\r\n"; + echo "-- ".$lang['data_dump']." ".$result[$i]['tbl_name'].", ".sprintf($lang['total_rows'], $numRows)."\r\n"; echo "----\r\n"; } $query = "PRAGMA table_info(".$this->quote_id($result[$i]['tbl_name']).")"; $temp = $this->selectArray($query); $cols = array(); $cols_quoted = array(); - $vals = array(); for($z=0; $zquote_id($temp[$z][1]); } - for($z=0; $zfetch($table_result)) { + $vals = array(); for($y=0; $yquote($arr[$z][$cols[$y]]); + $vals[$cols[$y]] = $this->quote($row[$cols[$y]]); } + echo "INSERT INTO ".$this->quote_id($result[$i]['tbl_name'])." (".implode(",", $cols_quoted).") VALUES (".implode(",", $vals).");\r\n"; } - for($j=0; $jquote_id($result[$i]['tbl_name'])." (".implode(",", $cols_quoted).") VALUES (".implode(",", $vals[$j]).");\r\n"; } } } @@ -5531,7 +5745,7 @@ class Resources { // returns data from internal resources, available in single-file mode function getInternalResource($res) { - $resources = array('resources/phpliteadmin.css'=>array(0=>0,1=>3954,),'resources/phpliteadmin.js'=>array(0=>3954,1=>4178,),'resources/favicon.ico'=>array(0=>8132,1=>1448,),); + $resources = array('resources/phpliteadmin.css'=>array(0=>0,1=>4047,),'resources/phpliteadmin.js'=>array(0=>4047,1=>4169,),'resources/favicon.ico'=>array(0=>8216,1=>1448,),); if (isset($resources[$res]) && $f = fopen(__FILE__, 'r')) { fseek($f, __COMPILER_HALT_OFFSET__ + $resources[$res][0]); @@ -5543,7 +5757,7 @@ function getInternalResource($res) { } // resources embedded below, do not edit! -__halt_compiler() ?>body{margin:0px;padding:0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#000;background-color:#e0ebf6;overflow:auto}.body_tbl td{padding:9px 2px 9px 9px}.left_td{width:100px}a{color:#03F;text-decoration:none;cursor:pointer}a:hover{color:#06F}hr{height:1px;border:0;color:#bbb;background-color:#bbb;width:100%}h1{margin:0px;padding:5px;font-size:24px;background-color:#f3cece;text-align:center;color:#000;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}#headerlinks{text-align:center;margin-bottom:10px;padding:5px 15px;border-color:#03F;border-width:1px;border-style:solid;border-left-style:none;border-right-style:none;font-size:12px;background-color:#e0ebf6;font-weight:bold}h1 #version{color:#000;font-size:16px}h1 #logo{color:#000}h2{margin:0px;padding:0px;font-size:14px;margin-bottom:20px}input,select,textarea{font-family:Arial,Helvetica,sans-serif;background-color:#eaeaea;color:#03F;border-color:#03F;border-style:solid;border-width:1px;margin:5px;border-radius:5px;-moz-border-radius:5px;padding:3px}input.btn{cursor:pointer}input.btn:hover{background-color:#ccc}fieldset{padding:15px;border-color:#03F;border-width:1px;border-style:solid;border-radius:5px;-moz-border-radius:5px;background-color:#f9f9f9}#container{padding:10px}#leftNav{min-width:250px;padding:0px;border-color:#03F;border-width:1px;border-style:solid;background-color:#FFF;padding-bottom:15px;border-radius:5px;-moz-border-radius:5px}.viewTable tr td{padding:1px}#loginBox{width:500px;margin-left:auto;margin-right:auto;margin-top:50px;border-color:#03F;border-width:1px;border-style:solid;background-color:#FFF;border-radius:5px;-moz-border-radius:5px}#main{border-color:#03F;border-width:1px;border-style:solid;padding:15px;background-color:#FFF;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top-right-radius:5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px;-moz-border-radius-topright:5px}.td1{background-color:#f9e3e3;text-align:right;font-size:12px;padding-left:10px;padding-right:10px}.td2{background-color:#f3cece;text-align:right;font-size:12px;padding-left:10px;padding-right:10px}.tdheader{border-color:#03F;border-width:1px;border-style:solid;font-weight:bold;font-size:12px;padding-left:10px;padding-right:10px;background-color:#e0ebf6;border-radius:5px;-moz-border-radius:5px}.confirm{border-color:#03F;border-width:1px;border-style:dashed;padding:15px;background-color:#e0ebf6}.tab{display:block;padding:5px;padding-right:8px;padding-left:8px;border-color:#03F;border-width:1px;border-style:solid;margin-right:5px;float:left;border-bottom-style:none;position:relative;top:1px;padding-bottom:4px;background-color:#eaeaea;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}.tab_pressed{display:block;padding:5px;padding-right:8px;padding-left:8px;border-color:#03F;border-width:1px;border-style:solid;margin-right:5px;float:left;border-bottom-style:none;position:relative;top:1px;background-color:#FFF;cursor:default;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}.helpq{font-size:11px;font-weight:normal}#help_container{padding:0px;font-size:12px;margin-left:auto;margin-right:auto;background-color:#fff}.help_outer{background-color:#FFF;padding:0px;height:300px;position:relative}.help_list{padding:10px;height:auto}.headd{font-size:14px;font-weight:bold;display:block;padding:10px;background-color:#e0ebf6;border-color:#03F;border-width:1px;border-style:solid;border-left-style:none;border-right-style:none}.help_inner{padding:10px}.help_top{display:block;position:absolute;right:10px;bottom:10px}.warning,.delete,.empty,.drop,.delete_db{color:red}.sidebar_table{font-size:11px}.active_table,.active_db{text-decoration:underline}.null{color:#888}.found{background:#FF0;text-decoration:none} +__halt_compiler() ?>body{margin:0px;padding:0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#000;background-color:#e0ebf6;overflow:auto}.body_tbl td{padding:9px 2px 9px 9px}.left_td{width:100px}a{color:#03F;text-decoration:none;cursor:pointer}a:hover{color:#06F}hr{height:1px;border:0;color:#bbb;background-color:#bbb;width:100%}h1{margin:0px;padding:5px;font-size:24px;background-color:#f3cece;text-align:center;color:#000;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}#headerlinks{text-align:center;margin-bottom:10px;padding:5px 15px;border-color:#03F;border-width:1px;border-style:solid;border-left-style:none;border-right-style:none;font-size:12px;background-color:#e0ebf6;font-weight:bold}h1 #version{color:#000;font-size:16px}h1 #logo{color:#000}h2{margin:0px;padding:0px;font-size:14px;margin-bottom:20px}input,select,textarea{font-family:Arial,Helvetica,sans-serif;background-color:#eaeaea;color:#03F;border-color:#03F;border-style:solid;border-width:1px;margin:5px;border-radius:5px;-moz-border-radius:5px;padding:3px}input.btn{cursor:pointer}input.btn:hover{background-color:#ccc}fieldset label{min-width:200px;display:block;float:left}fieldset{padding:15px;border-color:#03F;border-width:1px;border-style:solid;border-radius:5px;-moz-border-radius:5px;background-color:#f9f9f9}#container{padding:10px}#leftNav{min-width:250px;padding:0px;border-color:#03F;border-width:1px;border-style:solid;background-color:#FFF;padding-bottom:15px;border-radius:5px;-moz-border-radius:5px}.databaseList select{max-width:200px}.viewTable tr td{padding:1px}#loginBox{width:500px;margin-left:auto;margin-right:auto;margin-top:50px;border-color:#03F;border-width:1px;border-style:solid;background-color:#FFF;border-radius:5px;-moz-border-radius:5px}#main{border-color:#03F;border-width:1px;border-style:solid;padding:15px;background-color:#FFF;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top-right-radius:5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px;-moz-border-radius-topright:5px}.td1{background-color:#f9e3e3;text-align:right;font-size:12px;padding-left:10px;padding-right:10px}.td2{background-color:#f3cece;text-align:right;font-size:12px;padding-left:10px;padding-right:10px}.tdheader{border-color:#03F;border-width:1px;border-style:solid;font-weight:bold;font-size:12px;padding-left:10px;padding-right:10px;background-color:#e0ebf6;border-radius:5px;-moz-border-radius:5px}.confirm{border-color:#03F;border-width:1px;border-style:dashed;padding:15px;background-color:#e0ebf6}.tab{display:block;padding:5px;padding-right:8px;padding-left:8px;border-color:#03F;border-width:1px;border-style:solid;margin-right:5px;float:left;border-bottom-style:none;position:relative;top:1px;padding-bottom:4px;background-color:#eaeaea;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}.tab_pressed{display:block;padding:5px;padding-right:8px;padding-left:8px;border-color:#03F;border-width:1px;border-style:solid;margin-right:5px;float:left;border-bottom-style:none;position:relative;top:1px;background-color:#FFF;cursor:default;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}.helpq{font-size:11px;font-weight:normal}#help_container{padding:0px;font-size:12px;margin-left:auto;margin-right:auto;background-color:#fff}.help_outer{background-color:#FFF;padding:0px;height:300px;position:relative}.help_list{padding:10px;height:auto}.headd{font-size:14px;font-weight:bold;display:block;padding:10px;background-color:#e0ebf6;border-color:#03F;border-width:1px;border-style:solid;border-left-style:none;border-right-style:none}.help_inner{padding:10px}.help_top{display:block;position:absolute;right:10px;bottom:10px}.warning,.delete,.empty,.drop,.delete_db{color:red}.sidebar_table{font-size:11px}.active_table,.active_db{text-decoration:underline}.null{color:#888}.found{background:#FF0;text-decoration:none} function initAutoincrement() {var i=0;while(document.getElementById('i'+i+'_autoincrement')!=undefined) {document.getElementById('i'+i+'_autoincrement').disabled=true;i++;}} @@ -5568,7 +5782,7 @@ function changeIgnore(area,e,u) document.getElementById(e).checked=false;if(document.getElementById(u)!=undefined) document.getElementById(u).checked=false;}} function moveFields() -{var fields=document.getElementById("fieldcontainer");var selected=new Array();for(var i=0;i