From 22a658ac3ab20363d80b0aa76429ddf2fa59deda Mon Sep 17 00:00:00 2001 From: kjmtsh Date: Wed, 29 Jan 2014 09:35:06 +0000 Subject: [PATCH] Fixed some bugs and revised the documentations git-svn-id: https://plugins.svn.wordpress.org/sqlite-integration/trunk@847560 b8457f37-d9ea-0310-8a92-e5e31aec5664 --- db.php | 35 ++- functions-5-2.php | 371 +++++++++++++++++++++++--- functions.php | 410 ++++++++++++++++++++++++----- install.php | 9 +- js/sqlite.js | 9 +- languages/sqlite-integration-ja.po | 132 +--------- pdodb.class.php | 90 +++++-- pdoengine.class.php | 353 +++++++++++++++++++++---- query.class.php | 270 ++++++++++++++----- query_alter.class.php | 94 ++++++- query_create.class.php | 153 +++++++---- readme-ja.txt | 148 +++++------ readme.txt | 153 +++++------ schema.php | 15 +- sqlite-integration.php | 50 ++-- styles/blue.css | 4 + styles/coffee.css | 4 + styles/ectoplasm.css | 4 + styles/light.css | 4 + styles/midnight.css | 4 + styles/ocean.css | 4 + styles/style.css | 5 +- styles/sunrise.css | 4 + utilities/database_maintenance.php | 51 +++- utilities/documentation.php | 70 +---- utilities/patch.php | 37 ++- utilities/utility.php | 131 +++++++-- 27 files changed, 1865 insertions(+), 749 deletions(-) diff --git a/db.php b/db.php index 371243a..d38a3ba 100644 --- a/db.php +++ b/db.php @@ -1,11 +1,12 @@ * define('USE_MYSQL', true); + * */ if (defined('USE_MYSQL') && USE_MYSQL === true) return; @@ -35,7 +38,7 @@ function pdo_log_error($message, $data = null) { WordPress › Error - +

WordPress

@@ -60,13 +63,17 @@ if (!extension_loaded('pdo_sqlite')) { pdo_log_error('PDO Driver for SQLite is missing.', 'Your PHP installtion appears not to have the right PDO drivers loaded. These are required for this version of WordPress and the type of database you have specified.'); } -/** +/* * Notice: * Your scripts have the permission to create directories or files on your server. * If you write in your wp-config.php like below, we take these definitions. * define('DB_DIR', '/full_path_to_the_database_directory/'); * define('DB_FILE', 'database_file_name'); */ + +/* + * PDODIR is SQLite Integration installed directory. + */ if (defined('WP_PLUGIN_DIR')) { define('PDODIR', WP_PLUGIN_DIR . '/sqlite-integration/'); } else { @@ -76,7 +83,10 @@ if (defined('WP_PLUGIN_DIR')) { define('PDODIR', ABSPATH . 'wp-content/plugins/sqlite-integration/'); } } - +/* + * FQDBDIR is a directory where the sqlite database file is placed. + * If DB_DIR is defined, it is used as FQDBDIR. + */ if (defined('DB_DIR')) { if (substr(DB_DIR, -1, 1) != '/') { define('FQDBDIR', DB_DIR . '/'); @@ -90,13 +100,18 @@ if (defined('DB_DIR')) { define('FQDBDIR', ABSPATH . 'wp-content/database/'); } } - +/* + * FQDB is a database file name. If DB_FILE is defined, it is used + * as FQDB. + */ if ( defined('DB_FILE' )) { define('FQDB', FQDBDIR . DB_FILE); } else { define('FQDB', FQDBDIR . '.ht.sqlite'); } - +/* + * UDF_FILE is a file that contains user defined functions. + */ if (version_compare(PHP_VERSION, '5.3', '<')) { define('UDF_FILE', PDODIR . 'functions-5-2.php'); } elseif (version_compare(PHP_VERSION, '5.3', '>=')) { diff --git a/functions-5-2.php b/functions-5-2.php index 934b57b..5e2fe84 100644 --- a/functions-5-2.php +++ b/functions-5-2.php @@ -1,23 +1,48 @@ + * new PDOSQLiteUDFS(ref_to_pdo_obj); + * + * + * This automatically enables ref_to_pdo_obj to replace the function in the SQL statement + * to the ones defined here. */ class PDOSQLiteUDFS { + /** + * Constructor + * + * Initialize the user defined functions to the PDO object with PDO::sqliteCreateFunction(). + * + * @param reference to PDO object $pdo + */ public function __construct(&$pdo){ foreach ($this->functions as $f=>$t) { $pdo->sqliteCreateFunction($f, array($this, $t)); } } - + /** + * Array to associate MySQL function to the substituted one. + * + * @var associative array + */ private $functions = array( 'month' => 'month', 'year' => 'year', @@ -41,7 +66,6 @@ class PDOSQLiteUDFS { 'subdate' => 'date_sub', 'localtime' => 'now', 'localtimestamp' => 'now', - //'date'=>'date', 'isnull' => 'isnull', 'if' => '_if', 'regexpp' => 'regexp', @@ -49,6 +73,7 @@ class PDOSQLiteUDFS { 'field' => 'field', 'log' => 'log', 'least' => 'least', + 'greatest' => 'greatest', 'get_lock' => 'get_lock', 'release_lock' => 'release_lock', 'ucase' => 'ucase', @@ -59,34 +84,86 @@ class PDOSQLiteUDFS { 'locate' => 'locate', 'version' => 'version' ); - + /** + * Method to extract the month value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the month between 1 and 12. + */ public function month($field){ $t = strtotime($field); return date('n', $t); } + /** + * Method to extract the year value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the year. + */ public function year($field){ $t = strtotime($field); return date('Y', $t); } + /** + * Method to extract the day value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the day of the month from 1 and 31. + */ public function day($field){ $t = strtotime($field); return date('j', $t); } + /** + * Method to return the unix timestamp. + * + * Used without an argument, it returns PHP time() function (total seconds passed + * from '1970-01-01 00:00:00' GMT). Used with the argument, it changes the value + * to the timestamp. + * + * @param string representing the date formated as '0000-00-00 00:00:00'. + * @return number of unsigned integer + */ public function unix_timestamp($field = null){ return is_null($field) ? time() : strtotime($field); } + /** + * Method to emulate MySQL SECOND() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number of unsigned integer + */ public function second($field){ $t = strtotime($field); return intval( date("s", $t) ); } + /** + * Method to emulate MySQL MINUTE() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number of unsigned integer + */ public function minute($field){ $t = strtotime($field); return intval(date("i", $t)); } + /** + * Method to emulate MySQL HOUR() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number + */ public function hour($time){ list($hours, $minutes, $seconds) = explode(":", $time); return intval($hours); } + /** + * Method to emulate MySQL FROM_UNIXTIME() function. + * + * @param integer of unix timestamp + * @param string to indicate the way of formatting(optional) + * @return string formatted as '0000-00-00 00:00:00'. + */ public function from_unixtime($field, $format=null){ // $field is a timestamp //convert to ISO time @@ -95,25 +172,75 @@ class PDOSQLiteUDFS { return is_null($format) ? $date : $self->dateformat($date, $format); } + /** + * Method to emulate MySQL NOW() function. + * + * @return string representing current time formatted as '0000-00-00 00:00:00'. + */ public function now(){ return date("Y-m-d H:i:s"); } + /** + * Method to emulate MySQL CURDATE() function. + * + * @return string representing current time formatted as '0000-00-00'. + */ public function curdate() { return date("Y-m-d"); } + /** + * Method to emulate MySQL CHAR_LENGTH() function. + * + * @param string + * @return unsigned integer for the length of the argument. + */ public function char_length($field){ return strlen($field); } + /** + * Method to emulate MySQL MD5() function. + * + * @param string + * @return string of the md5 hash value of the argument. + */ public function md5($field){ return md5($field); } + /** + * Method to emulate MySQL RAND() function. + * + * SQLite does have a random generator, but it is called RANDOM() and returns random + * number between -9223372036854775808 and +9223372036854775807. So we substitute it + * with PHP random generator. + * + * This function uses mt_rand() which is four times faster than rand() and returns + * the random number between 0 and 1. + * + * @return unsigned integer + */ public function rand(){ - return rand(0,1); + return mt_rand(0,1); } + /** + * Method to emulate MySQL SUBSTRING() function. + * + * This function rewrites the function name to SQLite compatible substr(). + * + * @param string $text + * @param integer $pos representing the start point. + * @param integer $len representing the length of the substring(optional). + * @return string + */ public function substring($text, $pos, $len=null){ - if (is_null($len)) return substr($text, $pos-1); - else return substr($text, $pos-1, $len); + return "substr($text, $pos, $len)"; } + /** + * Method to emulate MySQL DATEFORMAT() function. + * + * @param string date formatted as '0000-00-00' or datetime as '0000-00-00 00:00:00'. + * @param string $format + * @return string formatted according to $format + */ public function dateformat($date, $format){ $mysql_php_dateformats = array ( '%a' => 'D', '%b' => 'M', '%c' => 'n', '%D' => 'jS', '%d' => 'd', '%e' => 'j', '%H' => 'H', '%h' => 'h', '%I' => 'h', '%i' => 'i', '%j' => 'z', '%k' => 'G', '%l' => 'g', '%M' => 'F', '%m' => 'm', '%p' => 'A', '%r' => 'h:i:s A', '%S' => 's', '%s' => 's', '%T' => 'H:i:s', '%U' => 'W', '%u' => 'W', '%V' => 'W', '%v' => 'W', '%W' => 'l', '%w' => 'w', '%X' => 'Y', '%x' => 'o', '%Y' => 'Y', '%y' => 'y', ); $t = strtotime($date); @@ -121,6 +248,17 @@ class PDOSQLiteUDFS { $output = date($format, $t); return $output; } + /** + * Method to emulate MySQL DATE_ADD() function. + * + * This function adds the time value of $interval expression to $date. + * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). + * It is calculated in the private function deriveInterval(). + * + * @param string $date representing the start date. + * @param string $interval representing the expression of the time to add. + * @return string date formated as '0000-00-00 00:00:00'. + */ public function date_add($date, $interval) { $interval = $this->deriveInterval($interval); switch (strtolower($date)) { @@ -141,6 +279,17 @@ class PDOSQLiteUDFS { } return $returnval; } + /** + * Method to emulate MySQL DATE_SUB() function. + * + * This function substracts the time value of $interval expression from $date. + * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). + * It is calculated in the private function deriveInterval(). + * + * @param string $date representing the start date. + * @param string $interval representing the expression of the time to substract. + * @return string date formated as '0000-00-00 00:00:00'. + */ public function date_sub($date, $interval) { $interval = $this->deriveInterval($interval); switch (strtolower($date)) { @@ -161,7 +310,13 @@ class PDOSQLiteUDFS { } return $returnval; } - + /** + * Method to calculate the interval time between two dates value. + * + * @access private + * @param string $interval white space separated expression. + * @return string representing the time to add or substract. + */ private function deriveInterval($interval){ $interval = trim(substr(trim($interval), 8)); $parts = explode(' ', $interval); @@ -252,25 +407,60 @@ class PDOSQLiteUDFS { return false; } } - + /** + * Method to emulate MySQL DATE() function. + * + * @param string $date formatted as unix time. + * @return string formatted as '0000-00-00'. + */ public function date($date){ return date("Y-m-d", strtotime($date)); } - + /** + * Method to emulate MySQL ISNULL() function. + * + * This function returns true if the argument is null, and true if not. + * + * @param various types $field + * @return boolean + */ public function isnull($field){ return is_null($field); } - + /** + * Method to emulate MySQL IF() function. + * + * As 'IF' is a reserved word for PHP, function name must be changed. + * + * @param unknonw $expression the statement to be evaluated as true or false. + * @param unknown $true statement or value returned if $expression is true. + * @param unknown $false statement or value returned if $expression is false. + * @return unknown + */ public function _if($expression, $true, $false){ return ($expression == true) ? $true : $false; } - + /** + * Method to emulate MySQL REGEXP() function. + * + * @param string $field haystack + * @param string $pattern: regular expression to match. + * @return integer 1 if matched, 0 if not matched. + */ public function regexp($field, $pattern){ $pattern = str_replace('/', '\/', $pattern); $pattern = "/" . $pattern ."/i"; return preg_match ($pattern, $field); } - + /** + * Method to emulate MySQL CONCAT() function. + * + * SQLite does have CONCAT() function, but it has a different syntax from MySQL. + * So this function must be manipulated here. + * + * @param string + * @return NULL if the argument is null | string conatenated if the argument is given. + */ public function concat() { $returnValue = ""; $argsNum = func_num_args(); @@ -283,20 +473,48 @@ class PDOSQLiteUDFS { } return $returnValue; } - + /** + * Method to emulate MySQL FIELD() function. + * + * This function gets the list argument and compares the first item to all the others. + * If the same value is found, it returns the position of that value. If not, it + * returns 0. + * + * @param variable number of string, integer or double + * @return unsigned integer + */ public function field() { $numArgs = func_num_args(); if ($numArgs < 2 or is_null(func_get_arg(0))) { - return null; + return 0; } $arr = func_get_args(); $searchString = strtolower(array_shift($arr)); for ($i = 0; $i < $numArgs-1; $i++) { if ($searchString === strtolower($arr[$i])) return $i + 1; } - return null; + return 0; } - + /** + * Method to emulate MySQL LOG() function. + * + * Used with one argument, it returns the natural logarithm of X. + * + * LOG(X) + * + * Used with two arguments, it returns the natural logarithm of X base B. + * + * LOG(B, X) + * + * In this case, it returns the value of log(X) / log(B). + * + * Used without an argument, it returns false. This returned value will be + * rewritten to 0, because SQLite doesn't understand true/false value. + * + * @param integer representing the base of the logarithm, which is optional. + * @param double value to turn into logarithm. + * @return double | NULL + */ public function log() { $numArgs = func_num_args(); if ($numArgs == 1) { @@ -307,18 +525,36 @@ class PDOSQLiteUDFS { $arg2 = func_get_arg(1); return log($arg1)/log($arg2); } else { - return false; + return null; } } - - public function least() { - $arr = func_get_args(); - return min($arr); - } - /** - * These two functions are meaningless in SQLite - * So we return meaningless statement and do nothing + * Method to emulate MySQL LEAST() function. + * + * This function rewrites the function name to SQLite compatible function name. + * + * @return mixed + */ + public function least() { + $arg_list = func_get_args(); + return "min($arg_list)"; + } + /** + * Method to emulate MySQL GREATEST() function. + * + * This function rewrites the function name to SQLite compatible function name. + * + * @return mixed + */ + public function greatest() { + $arg_list = func_get_args(); + return "max($arg_list)"; + } + /** + * Method to dummy out MySQL GET_LOCK() function. + * + * This function is meaningless in SQLite, so we do nothing. + * * @param string $name * @param integer $timeout * @return string @@ -326,39 +562,75 @@ class PDOSQLiteUDFS { public function get_lock($name, $timeout) { return '1=1'; } + /** + * Method to dummy out MySQL RELEASE_LOCK() function. + * + * This function is meaningless in SQLite, so we do nothing. + * + * @param string $name + * @return string + */ public function release_lock($name) { return '1=1'; } - /** - * MySQL aliases for upper and lower functions - * @param unknown $string - * @return string + * Method to emulate MySQL UCASE() function. + * + * This is MySQL alias for upper() function. This function rewrites it + * to SQLite compatible name upper(). + * + * @param string + * @return string SQLite compatible function name. */ public function ucase($string) { return "upper($string)"; } + /** + * Method to emulate MySQL LCASE() function. + * + * This is MySQL alias for lower() function. This function rewrites it + * to SQLite compatible name lower(). + * + * @param string + * @return string SQLite compatible function name. + */ public function lcase($string) { return "lower($string)"; } - /** - * MySQL aliases for INET_NTOA and INET_ATON functions - * @param unsigned integer, string respectively - * @return string, unsigned integer respectively + * Method to emulate MySQL INET_NTOA() function. + * + * This function gets 4 or 8 bytes integer and turn it into the network address. + * + * @param unsigned long integer + * @return string */ public function inet_ntoa($num) { return long2ip($num); } + /** + * Method to emulate MySQL INET_ATON() function. + * + * This function gets the network address and turns it into integer. + * + * @param string + * @return unsigned long integer + */ public function inet_aton($addr) { $int_data = ip2long($addr); $unsigned_int_data = sprintf('%u', $address); return $unsigned_int_data; } - /** - * MySQL aliase for DATEDIFF function - * @param string, string + * Method to emulate MySQL DATEDIFF() function. + * + * This function compares two dates value and returns the difference. + * + * PHP 5.3.2 has a serious bug in DateTime::diff(). So if users' PHP is that version, + * we don't use that function. See https://bugs.php.net/bug.php?id=51184. + * + * @param string start + * @param string end * @return string */ public function datediff($start, $end) { @@ -368,7 +640,16 @@ class PDOSQLiteUDFS { return $interval; } /** - * emulates MySQL LOCATE() function + * Method to emulate MySQL LOCATE() function. + * + * This function returns the position if $substr is found in $str. If not, + * it returns 0. If mbstring extension is loaded, mb_strpos() function is + * used. + * + * @param string needle + * @param string haystack + * @param integer position + * @return integer */ public function locate($substr, $str, $pos = 0) { if (!extension_loaded('mbstring')) { @@ -386,7 +667,13 @@ class PDOSQLiteUDFS { } } /** + * Method to return MySQL version. * + * This function only returns WordPress $required_mysql_version, because it is + * meaningless for SQLite database. + * + * @param none + * @return string representing the version number */ public function version() { global $required_mysql_version; diff --git a/functions.php b/functions.php index e97e373..58d8445 100644 --- a/functions.php +++ b/functions.php @@ -1,23 +1,50 @@ + * new PDOSQLiteUDFS(ref_to_pdo_obj); + * + * + * This automatically enables ref_to_pdo_obj to replace the function in the SQL statement + * to the ones defined here. */ class PDOSQLiteUDFS { + /** + * The class constructor + * + * Initializes the use defined functions to PDO object with PDO::sqliteCreateFunction(). + * + * @param reference to PDO object $pdo + */ public function __construct(&$pdo){ foreach ($this->functions as $f=>$t) { $pdo->sqliteCreateFunction($f, array($this, $t)); } } - + /** + * array to define MySQL function => function defined with PHP. + * + * Replaced functions must be public. + * + * @var associative array + */ private $functions = array( 'month' => 'month', 'year' => 'year', @@ -41,7 +68,6 @@ class PDOSQLiteUDFS { 'subdate' => 'date_sub', 'localtime' => 'now', 'localtimestamp' => 'now', - //'date'=>'date', 'isnull' => 'isnull', 'if' => '_if', 'regexpp' => 'regexp', @@ -49,7 +75,7 @@ class PDOSQLiteUDFS { 'field' => 'field', 'log' => 'log', 'least' => 'least', - 'replace' => 'replace', + 'greatest' => 'greatest', 'get_lock' => 'get_lock', 'release_lock' => 'release_lock', 'ucase' => 'ucase', @@ -60,108 +86,238 @@ class PDOSQLiteUDFS { 'locate' => 'locate', 'version' => 'version' ); - + /** + * Method to extract the month value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the month between 1 and 12. + */ public function month($field){ $t = strtotime($field); return date('n', $t); } + /** + * Method to extract the year value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the year. + */ public function year($field){ $t = strtotime($field); return date('Y', $t); } + /** + * Method to extract the day value from the date. + * + * @param string representing the date formated as 0000-00-00. + * @return string representing the number of the day of the month from 1 and 31. + */ public function day($field){ $t = strtotime($field); return date('j', $t); } + /** + * Method to return the unix timestamp. + * + * Used without an argument, it returns PHP time() function (total seconds passed + * from '1970-01-01 00:00:00' GMT). Used with the argument, it changes the value + * to the timestamp. + * + * @param string representing the date formated as '0000-00-00 00:00:00'. + * @return number of unsigned integer + */ public function unix_timestamp($field = null){ return is_null($field) ? time() : strtotime($field); } + /** + * Method to emulate MySQL SECOND() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number of unsigned integer + */ public function second($field){ $t = strtotime($field); return intval( date("s", $t) ); } + /** + * Method to emulate MySQL MINUTE() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number of unsigned integer + */ public function minute($field){ $t = strtotime($field); return intval(date("i", $t)); } + /** + * Method to emulate MySQL HOUR() function. + * + * @param string representing the time formated as '00:00:00'. + * @return number + */ public function hour($time){ list($hours, $minutes, $seconds) = explode(":", $time); return intval($hours); } + /** + * Method to emulate MySQL FROM_UNIXTIME() function. + * + * @param integer of unix timestamp + * @param string to indicate the way of formatting(optional) + * @return string formatted as '0000-00-00 00:00:00'. + */ public function from_unixtime($field, $format=null){ // $field is a timestamp //convert to ISO time $date = date("Y-m-d H:i:s", $field); //now submit to dateformat - return is_null($format) ? $date : $self->dateformat($date, $format); } + /** + * Method to emulate MySQL NOW() function. + * + * @return string representing current time formatted as '0000-00-00 00:00:00'. + */ public function now(){ return date("Y-m-d H:i:s"); } + /** + * Method to emulate MySQL CURDATE() function. + * + * @return string representing current time formatted as '0000-00-00'. + */ public function curdate() { return date("Y-m-d"); } + /** + * Method to emulate MySQL CHAR_LENGTH() function. + * + * @param string + * @return unsigned integer for the length of the argument. + */ public function char_length($field){ return strlen($field); } + /** + * Method to emulate MySQL MD5() function. + * + * @param string + * @return string of the md5 hash value of the argument. + */ public function md5($field){ return md5($field); } + /** + * Method to emulate MySQL RAND() function. + * + * SQLite does have a random generator, but it is called RANDOM() and returns random + * number between -9223372036854775808 and +9223372036854775807. So we substitute it + * with PHP random generator. + * + * This function uses mt_rand() which is four times faster than rand() and returns + * the random number between 0 and 1. + * + * @return unsigned integer + */ public function rand(){ - return rand(0,1); + return mt_rand(0, 1); } + /** + * Method to emulate MySQL SUBSTRING() function. + * + * This function rewrites the function name to SQLite compatible substr(). + * + * @param string $text + * @param integer $pos representing the start point. + * @param integer $len representing the length of the substring(optional). + * @return string + */ public function substring($text, $pos, $len=null){ - if (is_null($len)) return substr($text, $pos-1); - else return substr($text, $pos-1, $len); + return "substr($text, $pos, $len)"; } + /** + * Method to emulate MySQL DATEFORMAT() function. + * + * @param string date formatted as '0000-00-00' or datetime as '0000-00-00 00:00:00'. + * @param string $format + * @return string formatted according to $format + */ public function dateformat($date, $format){ $mysql_php_dateformats = array ( '%a' => 'D', '%b' => 'M', '%c' => 'n', '%D' => 'jS', '%d' => 'd', '%e' => 'j', '%H' => 'H', '%h' => 'h', '%I' => 'h', '%i' => 'i', '%j' => 'z', '%k' => 'G', '%l' => 'g', '%M' => 'F', '%m' => 'm', '%p' => 'A', '%r' => 'h:i:s A', '%S' => 's', '%s' => 's', '%T' => 'H:i:s', '%U' => 'W', '%u' => 'W', '%V' => 'W', '%v' => 'W', '%W' => 'l', '%w' => 'w', '%X' => 'Y', '%x' => 'o', '%Y' => 'Y', '%y' => 'y', ); - $t = strtotime($date); + $t = strtotime($date); $format = strtr($format, $mysql_php_dateformats); $output = date($format, $t); return $output; } + /** + * Method to emulate MySQL DATE_ADD() function. + * + * This function adds the time value of $interval expression to $date. + * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). + * It is calculated in the private function deriveInterval(). + * + * @param string $date representing the start date. + * @param string $interval representing the expression of the time to add. + * @return string date formated as '0000-00-00 00:00:00'. + */ public function date_add($date, $interval) { $interval = $this->deriveInterval($interval); switch (strtolower($date)) { case "curdate()": - $objDate = new Datetime($this->curdate()); + $objDate = new Datetime($this->curdate()); $objDate->add(new DateInterval($interval)); $returnval = $objDate->format("Y-m-d"); break; case "now()": - $objDate = new Datetime($this->now()); + $objDate = new Datetime($this->now()); $objDate->add(new DateInterval($interval)); $returnval = $objDate->format("Y-m-d H:i:s"); break; default: - $objDate = new Datetime($date); + $objDate = new Datetime($date); $objDate->add(new DateInterval($interval)); $returnval = $objDate->format("Y-m-d H:i:s"); } return $returnval; } + /** + * Method to emulate MySQL DATE_SUB() function. + * + * This function substracts the time value of $interval expression from $date. + * $interval is a single quoted strings rewritten by SQLiteQueryDriver::rewrite_query(). + * It is calculated in the private function deriveInterval(). + * + * @param string $date representing the start date. + * @param string $interval representing the expression of the time to substract. + * @return string date formated as '0000-00-00 00:00:00'. + */ public function date_sub($date, $interval) { $interval = $this->deriveInterval($interval); switch (strtolower($date)) { case "curdate()": - $objDate = new Datetime($this->curdate()); + $objDate = new Datetime($this->curdate()); $objDate->sub(new DateInterval($interval)); $returnval = $objDate->format("Y-m-d"); break; case "now()": - $objDate = new Datetime($this->now()); + $objDate = new Datetime($this->now()); $objDate->sub(new DateInterval($interval)); $returnval = $objDate->format("Y-m-d H:i:s"); break; default: - $objDate = new Datetime($date); + $objDate = new Datetime($date); $objDate->sub(new DateInterval($interval)); $returnval = $objDate->format("Y-m-d H:i:s"); } return $returnval; } + /** + * Method to calculate the interval time between two dates value. + * + * @access private + * @param string $interval white space separated expression. + * @return string representing the time to add or substract. + */ private function deriveInterval($interval) { $interval = trim(substr(trim($interval), 8)); $parts = explode(' ', $interval); @@ -202,7 +358,7 @@ class PDOSQLiteUDFS { return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M'; break; case "day_hour": - $days = intval($_parts[0]); + $days = intval($_parts[0]); $hours = intval($_parts[1]); return 'P' . $days . 'D' . 'T' . $hours . 'H'; break; @@ -212,28 +368,63 @@ class PDOSQLiteUDFS { break; } } - + /** + * Method to emulate MySQL DATE() function. + * + * @param string $date formatted as unix time. + * @return string formatted as '0000-00-00'. + */ public function date($date){ return date("Y-m-d", strtotime($date)); } - + /** + * Method to emulate MySQL ISNULL() function. + * + * This function returns true if the argument is null, and true if not. + * + * @param various types $field + * @return boolean + */ public function isnull($field){ return is_null($field); } - + /** + * Method to emulate MySQL IF() function. + * + * As 'IF' is a reserved word for PHP, function name must be changed. + * + * @param unknonw $expression the statement to be evaluated as true or false. + * @param unknown $true statement or value returned if $expression is true. + * @param unknown $false statement or value returned if $expression is false. + * @return unknown + */ public function _if($expression, $true, $false){ return ($expression == true) ? $true : $false; } - + /** + * Method to emulate MySQL REGEXP() function. + * + * @param string $field haystack + * @param string $pattern: regular expression to match. + * @return integer 1 if matched, 0 if not matched. + */ public function regexp($field, $pattern){ $pattern = str_replace('/', '\/', $pattern); $pattern = "/" . $pattern ."/i"; return preg_match ($pattern, $field); } - + /** + * Method to emulate MySQL CONCAT() function. + * + * SQLite does have CONCAT() function, but it has a different syntax from MySQL. + * So this function must be manipulated here. + * + * @param string + * @return NULL if the argument is null | string conatenated if the argument is given. + */ public function concat() { $returnValue = ""; - $argsNum = func_num_args(); + $argsNum = func_num_args(); $argsList = func_get_args(); for ($i = 0; $i < $argsNum; $i++) { if (is_null($argsList[$i])) { @@ -243,20 +434,51 @@ class PDOSQLiteUDFS { } return $returnValue; } - + /** + * Method to emulate MySQL FIELD() function. + * + * This function gets the list argument and compares the first item to all the others. + * If the same value is found, it returns the position of that value. If not, it + * returns 0. + * + * @param variable number of string, integer or double + * @return unsigned integer + */ public function field() { $numArgs = func_num_args(); if ($numArgs < 2 or is_null(func_get_arg(0))) { - return null; + return 0; + } else { + $arg_list = func_get_args(); } - $arr = func_get_args(); - $searchString = strtolower(array_shift($arr)); + $searchString = array_shift($arg_list); for ($i = 0; $i < $numArgs-1; $i++) { - if ($searchString === strtolower($arr[$i])) return $i + 1; + if ($searchString === strtolower($arg_list[$i])) { + return $i + 1; + } } - return null; + return 0; } - + /** + * Method to emulate MySQL LOG() function. + * + * Used with one argument, it returns the natural logarithm of X. + * + * LOG(X) + * + * Used with two arguments, it returns the natural logarithm of X base B. + * + * LOG(B, X) + * + * In this case, it returns the value of log(X) / log(B). + * + * Used without an argument, it returns false. This returned value will be + * rewritten to 0, because SQLite doesn't understand true/false value. + * + * @param integer representing the base of the logarithm, which is optional. + * @param double value to turn into logarithm. + * @return double | NULL + */ public function log() { $numArgs = func_num_args(); if ($numArgs == 1) { @@ -267,22 +489,36 @@ class PDOSQLiteUDFS { $arg2 = func_get_arg(1); return log($arg1)/log($arg2); } else { - return false; + return null; } } - + /** + * Method to emulate MySQL LEAST() function. + * + * This function rewrites the function name to SQLite compatible function name. + * + * @return mixed + */ public function least() { - $arr = func_get_args(); - return min($arr); + $arg_list = func_get_args(); + return "min($arg_list)"; } - - public function replace($haystack, $needle, $replace) { - return str_replace($needle, $replace, $haystack); - } - /** - * These two functions are meaningless in SQLite - * So we return meaningless statement and do nothing + * Method to emulate MySQL GREATEST() function. + * + * This function rewrites the function name to SQLite compatible function name. + * + * @return mixed + */ + public function greatest() { + $arg_list = func_get_args(); + return "max($arg_list)"; + } + /** + * Method to dummy out MySQL GET_LOCK() function. + * + * This function is meaningless in SQLite, so we do nothing. + * * @param string $name * @param integer $timeout * @return string @@ -290,30 +526,61 @@ class PDOSQLiteUDFS { public function get_lock($name, $timeout) { return '1=1'; } + /** + * Method to dummy out MySQL RELEASE_LOCK() function. + * + * This function is meaningless in SQLite, so we do nothing. + * + * @param string $name + * @return string + */ public function release_lock($name) { return '1=1'; } - /** - * MySQL aliases for upper and lower functions - * @param $string - * @return string + * Method to emulate MySQL UCASE() function. + * + * This is MySQL alias for upper() function. This function rewrites it + * to SQLite compatible name upper(). + * + * @param string + * @return string SQLite compatible function name. */ public function ucase($string) { return "upper($string)"; } + /** + * Method to emulate MySQL LCASE() function. + * + * + * This is MySQL alias for lower() function. This function rewrites it + * to SQLite compatible name lower(). + * + * @param string + * @return string SQLite compatible function name. + */ public function lcase($string) { return "lower($string)"; } - /** - * MySQL aliases for INET_NTOA and INET_ATON functions - * @param unsigned integer, string respectively - * @return string, unsigned integer respectively + * Method to emulate MySQL INET_NTOA() function. + * + * This function gets 4 or 8 bytes integer and turn it into the network address. + * + * @param unsigned long integer + * @return string */ public function inet_ntoa($num) { return long2ip($num); } + /** + * Method to emulate MySQL INET_ATON() function. + * + * This function gets the network address and turns it into integer. + * + * @param string + * @return unsigned long integer + */ public function inet_aton($addr) { $int_data = ip2long($addr); $unsigned_int_data = sprintf('%u', $address); @@ -321,28 +588,41 @@ class PDOSQLiteUDFS { } /** - * MySQL aliase for DATEDIFF function - * @param string, string + * Method to emulate MySQL DATEDIFF() function. + * + * This function compares two dates value and returns the difference. + * + * PHP 5.3.2 has a serious bug in DateTime::diff(). So if users' PHP is that version, + * we don't use that function. See https://bugs.php.net/bug.php?id=51184. + * + * @param string start + * @param string end * @return string */ public function datediff($start, $end) { - /* PHP 5.3.2 has a serious bug in DateTime::diff() - * see https://bugs.php.net/bug.php?id=51184 - */ if (version_compare(PHP_VERSION, '5.3.2', '==')) { $start_date = strtotime($start); $end_date = strtotime($end); - $interval = floor(($start_date - $end_date)/(3600*24)); + $interval = floor(($start_date - $end_date)/(3600*24)); return $interval; } else { $start_date = new DateTime($start); - $end_date = new DateTime($end); - $interval = $end_date->diff($start_date, false); + $end_date = new DateTime($end); + $interval = $end_date->diff($start_date, false); return $interval->format('%r%a'); } } /** - * emulates MySQL LOCATE() function + * Method to emulate MySQL LOCATE() function. + * + * This function returns the position if $substr is found in $str. If not, + * it returns 0. If mbstring extension is loaded, mb_strpos() function is + * used. + * + * @param string needle + * @param string haystack + * @param integer position + * @return integer */ public function locate($substr, $str, $pos = 0) { if (!extension_loaded('mbstring')) { @@ -360,7 +640,13 @@ class PDOSQLiteUDFS { } } /** + * Method to return MySQL version. * + * This function only returns WordPress $required_mysql_version, because it is + * meaningless for SQLite database. + * + * @param none + * @return string representing the version number */ public function version() { global $required_mysql_version; diff --git a/install.php b/install.php index bc88f85..4648d02 100644 --- a/install.php +++ b/install.php @@ -1,17 +1,20 @@ " "PDO for WordPressの後継です。PDO for WordPressはWordPressでSQLiteを使えるようにする" "ものでしたが、もうメンテナンスされていないようで、古くなってしまいました。SQLite Integrationは、その基本的な" -"考えと枠組みを使って、新たな機能を追加し、最新のWordPress(3.8)で動作するように" +"考えと枠組みを使って、新たな機能を追加し、最新のWordPress(3.8.1)で動作するように" "したものです。" #: utilities/documentation.php:43 @@ -243,7 +243,7 @@ msgstr "" "が扱えないものもあります。だから..." #: utilities/documentation.php:68 -msgid "There are some plugins that you can't use in any way.
" +msgid "There are some plugins that you can't use. No way around.
" msgstr "どうしても使えないプラグインがあります。" #: utilities/documentation.php:69 @@ -266,7 +266,7 @@ msgstr "" msgid "" "Some plugins do work fine if you rewrite MySQL functions. I made some patch " "files and Patch Utility. See also the Plugin Page for " +"\"http://dogwood.skr.jp/wordpress/sqlite-integration\">SQLite Integration page for " "more details." msgstr "" "MySQLの関数を書き換えると動作するプラグインがあります。いくつかはパッチファイルと、" @@ -349,9 +349,7 @@ msgstr "" #: utilities/documentation.php:104 #, php-format msgid "" -"Most of the plugins will work fine with this plugin. But there are some that " -"you need to rewrite some codes in them, and there are others that you can't " -"use with this plugin. This is the list of the problematic plugins (far from " +"This is the list of the problematic plugins (far from " "complete). You can see informations about your installed plugins in the System Info page. To see more details, please " "visit the My recommendation is not to use caching plugins. " -"Even so, if you want a caching plugin, you could try WP Super Cache, which " -"doesn't use db.php file. But no warranty, try at your own risk." -msgstr "" -"これらのプラグインがdb.phpファイルを上書きすると、SQLite Integrationは動作しなくなります。" -"私のお勧めは、キャッシュ・プラグインを使わないというものです。" -"それでも、どうしても使いたいということであれば、WP Super Cacheのようなものなら試せるかもしれません。db.phpを使わない" -"からです。でも、保証はありません。ご自分の責任でお試しください。" - -#: utilities/documentation.php:148 -msgid "I have not tested none of those caching plugins." -msgstr "私はこれらのキャッシュ・プラグインをテストしていません。" - -#: utilities/documentation.php:150 -msgid "MySQL specific functions" -msgstr "MySQL用の関数" - -#: utilities/documentation.php:152 -msgid "" -"Some plugins don't use WordPress database functions such as dbDelta(), and " -"use PHP native MySQL functions when they create and manage tables in the " -"database. But PHP doesn't permit redefining of the native functions (at " -"least, under ordinary server setting). So SQLite Integration can't intercept " -"and rewrite those functions." -msgstr "" -"プラグインの中にはデータベースにアクセスするのに、WordPressが提供するdbDelta()のような関数を使わず、" -"PHPのmysqlドライバの提供する関数を使って、テーブルを作ったり、操作したりするものがあります。PHPは組み込み" -"の関数を再定義することを許しません(少なくとも通常のサーバ設定では)。だから、SQLite Integrationは" -"それらをインターセプトして、書き換えることができません。" - -#: utilities/documentation.php:155 -msgid "For example, you can see these codes in Google XML Sitemaps." -msgstr "たとえば、Google XML Sitemapsにはこのようなコードがあります。" - -#: utilities/documentation.php:161 -msgid "or in Camera Slideshow" -msgstr "あるいは、Camera Slideshowには、こんな部分があります。" - -#: utilities/documentation.php:167 -msgid "" -"Such functions as mysql_get_server_info() or mysql_query() are from the " -"MySQL driver of PHP. Not only some plugins but WordPress uses them, but " -"SQLite Integration has no way to rewrite or redefine them. If the plugin you " -"want to use has those functions in it, it won't work or give the error " -"messages." -msgstr "" -"mysql_get_server_info()やmysql_query()といった関数は、PHPのドライバが提供するものです。" -"でも、SQLite Integrationはこれらを書き換えたり、再定義したりすることができません。もし、あなたが" -"使いたいプラグインがこれらの関数を使っていたら、うまく動かないか、エラー・メッセージが出るでしょう。" - -#: utilities/documentation.php:170 -msgid "" -"So, you have to rewrite them for SQLite Integration can execute. The two " -"example above can be rewritten like this:" -msgstr "" -"だから、これらの関数は手動で書き換えなければ、SQLite Integrationで実行できません。上の2つの" -"例は、次のように書き換えればうまくいきます。" - -#: utilities/documentation.php:179 -msgid "" -"As for those functions in WordPress, I overrode the WordPress functions " -"themselves that contains such MySQL functions as mysql_query() or " -"mysql_real_escape_string()." -msgstr "" -"WordPressで使われているこれらの関数については、mysql_query()やmysql_real_escape_string()" -"といった関数を含むWordPress関数をオーバーライドしています。" - -#: utilities/documentation.php:181 -msgid "FULLTEXT index" -msgstr "FULLTEXTインデックス" - -#: utilities/documentation.php:183 -msgid "" -"Some plugins use FULLTEXT index of MySQL. Of course SQLite does have the " -"functionality named "full-text search". But it is not correlated " -"with that of MySQL. In fact it is not an "index" and requires " -"another new table for that. And it has a different syntax. So you can't use " -"the plugins which uses FULLTEXT index" -msgstr "" -"プラグインの中には、MySQLのFULLTEXTインデックスを使うものがあります。もちろん、SQLiteにも、"" -"full-text search"という機能があります。でも、これはMySQLのものとは違います。、実際は" -"インデックスではなく、新たなテーブルを作らなければならないものです。構文も異なります。だから、FULLTEXT" -"インデックスを使うプラグインは使うことができません。" - -#: utilities/documentation.php:186 -msgid "" -"If your language is not written by separating words with spaces, e.g. " -"Japanese, Chinese or Thai, neither FULLTEXT index nor full-text search work " -"effectively. Even if your language is space-separating-words one, you don't " -"have to be disappointed. Whatever languages you use, you can use WordPress Related Posts or Related Posts or others. They are working fine " -"with SQLite Integration!" -msgstr "" -"あなたの言語が、日本語や中国語やタイ語のように、スペースで単語を区切らない言語の場合、FULLTEXT" -"インデックスもfull-text searchも有効に働きません。あなたの言語が分かち書きをするものだとしても、" -"がっかりする必要はありません。WordPress Related PostsRelated Postsのうようなプラグインを" -"使うことができます。これらは、SQLite Integrationでちゃんと動作します。" - #: utilities/patch.php:55 msgid "Patch command is not found" msgstr "パッチコマンドがありません" diff --git a/pdodb.class.php b/pdodb.class.php index bb3e6a1..465d5ed 100644 --- a/pdodb.class.php +++ b/pdodb.class.php @@ -1,7 +1,10 @@ db_connect(); } - + /** + * Desctructor + * + * This overrides wpdb::__destruct(), but does nothing but return true. + * + * @see wpdb::__destruct() + */ function __destruct() { return true; } /** - * dummy out the MySQL function + * Method to set character set for the database. + * + * This overrides wpdb::set_charset(), only to dummy out the MySQL function. + * * @see wpdb::set_charset() */ function set_charset($dbh, $charset = null, $collate = null) { @@ -59,7 +78,10 @@ class PDODB extends wpdb { $collate = $this->collate; } /** - * dummy out the MySQL function + * Method to select the database connection. + * + * This overrides wpdb::select(), only to dummy out the MySQL function. + * * @see wpdb::select() */ function select($db, $dbh = null) { @@ -70,7 +92,10 @@ class PDODB extends wpdb { } /** - * overrides wpdb::_real_escape(), which uses mysql_real_escape_string(). + * Method to escape characters. + * + * This overrides wpdb::_real_escape() to avoid using mysql_real_escape_string(). + * * @see wpdb::_real_escape() */ function _real_escape($string) { @@ -78,7 +103,10 @@ class PDODB extends wpdb { } /** - * overrides wpdb::print_error() + * Method to put out the error message. + * + * This overrides wpdb::print_error(), for we can't use the parent class method. + * * @see wpdb::print_error() */ function print_error($str = '') { @@ -112,7 +140,7 @@ class PDODB extends wpdb { if (defined('DIEONDBERROR')) wp_die($msg); } else { - $str = htmlspecialchars($str, ENT_QUOTES); + $str = htmlspecialchars($str, ENT_QUOTES); $query = htmlspecialchars($this->last_query, ENT_QUOTES); print "
@@ -123,7 +151,10 @@ class PDODB extends wpdb { } /** - * overrides wpdb::db_connect() + * Method to do the database connection. + * + * This overrides wpdb::db_connect() to avoid using MySQL function. + * * @see wpdb::db_connect() */ function db_connect() { @@ -143,7 +174,11 @@ class PDODB extends wpdb { } /** - * overrides wpdb::query() + * Method to execute the query. + * + * This overrides wpdb::query(). In fact, this method does all the database + * access jobs. + * * @see wpdb::query() */ function query($query) { @@ -188,14 +223,16 @@ class PDODB extends wpdb { $return_val = $this->rows_affected; } else { $this->last_result = $this->dbh->get_query_results(); - $this->num_rows = $this->dbh->get_num_rows(); - $return_val = $this->num_rows; + $this->num_rows = $this->dbh->get_num_rows(); + $return_val = $this->num_rows; } return $return_val; } - /** - * overrides wpdb::load_col_info(), which uses a mysql function. + * Method to set the class variable $col_info. + * + * This overrides wpdb::load_col_info(), which uses a mysql function. + * * @see wpdb::load_col_info() */ function load_col_info() { @@ -205,8 +242,11 @@ class PDODB extends wpdb { } /** - * overrides wpdb::has_cap() - * We don't support collation, group_concat, set_charset + * Method to return what the database can do. + * + * This overrides wpdb::has_cap() to avoid using MySQL functions. + * SQLite supports subqueries, but not support collation, group_concat and set_charset. + * * @see wpdb::has_cap() */ function has_cap($db_cap) { @@ -222,8 +262,12 @@ class PDODB extends wpdb { } } /** - * overrides wpdb::db_version() - * Returns mysql version number but it means nothing for SQLite. + * Method to return database version number. + * + * This overrides wpdb::db_version() to avoid using MySQL function. + * It returns mysql version number, but it means nothing for SQLite. + * So it return the required mysql version. + * * @see wpdb::db_version() */ function db_version() { @@ -232,7 +276,7 @@ class PDODB extends wpdb { } } -/** +/* * Initialize $wpdb with PDODB class */ if (!isset($wpdb)) { diff --git a/pdoengine.class.php b/pdoengine.class.php index 0044fbe..fd574b4 100644 --- a/pdoengine.class.php +++ b/pdoengine.class.php @@ -1,53 +1,154 @@ init(); } + /** + * Destructor + * + * @return boolean + */ function __destruct() { $this->pdo = null; return true; } /** - * Function to initialize database - * checks if there's a database directory and database file, creates the tables, - * and binds the user defined function to the pdo object + * Function to initialize database. + * + * It checks if there's a database directory and database file, creates the tables, + * and binds the user defined function to the pdo object. + * * @return boolean */ private function init() { @@ -105,8 +206,9 @@ class PDOEngine extends PDO { } /** - * Make database direcotry and .htaccess file - * executed once while installation process + * This function makes database direcotry and .htaccess file. + * + * It is executed only once when the installation begins. */ private function prepare_directory() { global $wpdb; @@ -140,13 +242,20 @@ class PDOEngine extends PDO { return true; } /** - * Make database file itself and WordPress tables - * executed once while installation process + * function to call install() function which overrides WordPress install(). + * + * This function is executed only once during the installation process. */ private function make_sqlite_tables() { require_once PDODIR . 'install.php'; } - + /** + * Function to execute query(). + * + * @param $query full SQL statement string + * @return mixed according to the query type + * @see PDO::query() + */ public function query($query) { $this->flush(); @@ -158,9 +267,17 @@ class PDOEngine extends PDO { } switch (strtolower($this->query_type)) { case 'foundrows': - $this->results = $this->found_rows_result; - $this->num_rows = count($this->results); - $this->found_rows_result = null; + $_column = array('FOUND_ROWS()' => ''); + $column = array(); + if (!is_null($this->found_rows_result)) { + $this->num_rows = count($this->found_rows_result); + foreach ($this->found_rows_result[0] as $key => $value) { + $_column['FOUND_ROWS()'] = $value; + } + $column[] = new ObjectArray($_column); + $this->results = $column; + $this->found_rows_result = null; + } break; case 'insert': if ($this->can_insert_multiple_rows) { @@ -206,30 +323,63 @@ class PDOEngine extends PDO { break; } if (defined('PDO_DEBUG') && PDO_DEBUG === true) { - file_put_contents(FQDBDIR . 'debug.txt', $this->get_debug_info(), FLIE_APPEND); + file_put_contents(FQDBDIR . 'debug.txt', $this->get_debug_info(), FILE_APPEND); } return $this->return_value; } - + /** + * Function to return inserted row id. + * + * @return unsigned integer + */ public function get_insert_id() { return $this->last_insert_id; } + /** + * Function to return the number of rows affected. + * + * @return unsigned integer + */ public function get_affected_rows() { return $this->affected_rows; } + /** + * Function to return the queried column names. + * + * @return string + */ public function get_columns() { return $this->column_names; } + /** + * Function to return the queried result data. + * + * @return mixed + */ public function get_query_results() { return $this->results; } + /** + * Function to return the number of rows from the queried result. + * + * @return unsigned integer + */ public function get_num_rows() { return $this->num_rows; } + /** + * Function to return the queried results according to the query types. + * + * @return mixed + */ public function get_return_value() { return $this->return_value; } - + /** + * Function to return error messages. + * + * @return string + */ public function get_error_message(){ if (count($this->error_messages) === 0){ $this->is_error = false; @@ -257,15 +407,21 @@ class PDOEngine extends PDO { return $output; } - + /** + * Function to return information about query string for debugging. + * + * @return string + */ private function get_debug_info(){ $output = ''; foreach ($this->queries as $q){ - $output .= $q ."\r\n"; + $output .= $q ."\n"; } return $output; } - + /** + * Function to clear previous data. + */ private function flush(){ $this->rewritten_query = ''; $this->query_type = ''; @@ -282,7 +438,15 @@ class PDOEngine extends PDO { $this->queries = array(); $this->param_num = 0; } - + /** + * Function to include the apropreate class files. + * + * It is not a good habit to change the include files programatically. + * Needs to be fixed some other way. + * + * @param string $query_type + * @return object reference to apropreate driver + */ private function prepare_engine($query_type = null) { if (stripos($query_type, 'create') !== false) { require_once PDODIR . 'query_create.class.php'; @@ -296,7 +460,11 @@ class PDOEngine extends PDO { } return $engine; } - + /** + * Function to create a PDO statement object from the query string. + * + * @return PDOStatement + */ private function prepare_query(){ $this->queries[] = 'Prepare: ' . $this->prepared_query; $reason = 0; @@ -317,12 +485,21 @@ class PDOEngine extends PDO { } return $statement; } - + /** + * Function to execute PDO statement object. + * + * This function executes query and sets the variables to give back to WordPress. + * The variables are class fields. So if success, no return value. If failure, it + * returns void and stops. + * + * @param object $statement of PDO statement + * @return boolean + */ private function execute_query($statement) { $reason = 0; $message = ''; if (!is_object($statement)) - return; + return false; if (count($this->extracted_variables) > 0) { $this->queries[] = 'Executing: ' . var_export($this->extracted_variables, true); do { @@ -413,11 +590,18 @@ class PDOEngine extends PDO { break; } } - + /** + * Function to extract field data to an array and prepare the query statement. + * + * If original SQL statement is CREATE query, this function do nothing and return + * true. This returned value is not used. + * + * @return boolean + */ private function extract_variables() { if ($this->query_type == 'create') { $this->prepared_query = $this->rewritten_query; - return; + return true; } //long queries can really kill this @@ -440,7 +624,12 @@ class PDOEngine extends PDO { $this->queries[]= 'With Placeholders: ' . $query; $this->prepared_query = $query; } - + /** + * Call back function to replace field data with PDO parameter. + * + * @param string $matches + * @return string + */ private function replace_variables_with_placeholders($matches) { //remove the wordpress escaping mechanism $param = stripslashes($matches[0]); @@ -464,8 +653,11 @@ class PDOEngine extends PDO { } /** - * takes the query string ,determines the type and returns the type string - * if the query is the type PDO for Wordpress can't executes, returns false + * Function to determine which query type the argument is. + * + * It takes the query string ,determines the type and returns the type string. + * If the query is the type that SQLite Integration can't executes, returns false. + * * @param string $query * @return boolean|string */ @@ -499,8 +691,11 @@ class PDOEngine extends PDO { } /** - * SQLite version 3.7.11 began support multiple rows insert with values + * Function to execute INSERT query for SQLite version 3.7.11 or later. + * + * SQLite version 3.7.11 began to support multiple rows insert with values * clause. This is for that version or later. + * * @param string $query */ private function execute_insert_query_new($query) { @@ -512,7 +707,11 @@ class PDOEngine extends PDO { $this->execute_query($statement); } /** - * executes the INSERT query for SQLite version 3.7.10 or lesser + * Function to execute INSERT query for SQLite version 3.7.10 or lesser. + * + * It executes the INSERT query for SQLite version 3.7.10 or lesser. It is + * necessary to rewrite multiple row values. + * * @param string $query */ private function execute_insert_query($query) { @@ -566,7 +765,10 @@ class PDOEngine extends PDO { } /** - * helper function for execute_insert_query() + * Function to help rewriting multiple row values insert query. + * + * It splits the values clause into an array to execute separately. + * * @param string $values * @return array */ @@ -605,7 +807,8 @@ class PDOEngine extends PDO { } /** - * function to execute CREATE query + * Function to execute CREATE query. + * * @param string * @return boolean */ @@ -640,9 +843,9 @@ class PDOEngine extends PDO { } return true; } - /** - * function to execute ALTER TABLE query + * Function to execute ALTER TABLE query. + * * @param string * @return boolean */ @@ -693,10 +896,10 @@ class PDOEngine extends PDO { } /** - * function to execute SHOW VARIABLES query + * Function to execute SHOW VARIABLES query * - * This query is meaningless for SQLite. This function returns null data and - * avoid the error message. + * This query is meaningless for SQLite. This function returns null data with some + * exceptions and only avoids the error message. * * @param string * @return ObjectArray @@ -720,7 +923,11 @@ class PDOEngine extends PDO { $this->return_value = $this->num_rows; return true; } - + /** + * Function to format the queried data to that of MySQL. + * + * @param string $engine + */ private function process_results($engine) { if (in_array($this->query_type, array('describe', 'desc', 'showcolumns'))) { $this->convert_to_columns_object(); @@ -732,7 +939,17 @@ class PDOEngine extends PDO { $this->results = $this->_results; } } - + /** + * Function to format the error messages and put out to the file. + * + * When $wpdb::suppress_errors is set to true or $wpdb::show_errors is set to false, + * the error messages are ignored. + * + * @param string $line where the error occurred. + * @param string $function to indicate the function name where the error occurred. + * @param string $message + * @return boolean + */ private function set_error ($line, $function, $message){ global $wpdb; $this->errors[] = array("line"=>$line, "function"=>$function); @@ -742,9 +959,13 @@ class PDOEngine extends PDO { if (!$wpdb->show_errors) return false; file_put_contents (FQDBDIR .'debug.txt', "Line $line, Function: $function, Message: $message \n", FILE_APPEND); } - /** - * method that takes the associative array of query results and creates a numeric array of anonymous objects + * Function to change the queried data to PHP object format. + * + * It takes the associative array of query results and creates a numeric + * array of anonymous objects + * + * @access private */ private function convert_to_object(){ $_results = array(); @@ -757,11 +978,13 @@ class PDOEngine extends PDO { } $this->results = $_results; } - /** - * method to rewrite pragma results to mysql compatible array + * Function to convert the SHOW COLUMNS query data to an object. + * + * It rewrites pragma results to mysql compatible array * when query_type is describe, we use sqlite pragma function. - * see pdo_sqlite_driver.php + * + * @access private */ private function convert_to_columns_object() { $_results = array(); @@ -788,8 +1011,12 @@ class PDOEngine extends PDO { $this->results = $_results; } /** - * rewrites the result of SHOW INDEX to the Object compatible with MySQL + * Function to convert SHOW INDEX query data to PHP object. + * + * It rewrites the result of SHOW INDEX to the Object compatible with MySQL * added the WHERE clause manipulation (ver 1.3.1) + * + * @access private */ private function convert_to_index_object() { $_results = array(); @@ -873,7 +1100,11 @@ class PDOEngine extends PDO { } $this->results = $_results; } - + /** + * Function to the CHECK query data to an object. + * + * @access private + */ private function convert_result_check_or_analyze() { $results = array(); if ($this->query_type == 'check') { @@ -895,9 +1126,12 @@ class PDOEngine extends PDO { $this->results = $_results; } /** - * function to get SQLite library version - * this is used for checking if SQLite can execute multiple rows insert + * Function to check SQLite library version. + * + * This is used for checking if SQLite can execute multiple rows insert. + * * @return version number string or 0 + * @access private */ private function get_sqlite_version() { try { @@ -910,8 +1144,10 @@ class PDOEngine extends PDO { } } /** - * function call to PDO::beginTransaction() + * Function to call PDO::beginTransaction(). + * * @see PDO::beginTransaction() + * @return boolean */ public function beginTransaction() { if ($this->has_active_transaction) { @@ -922,7 +1158,8 @@ class PDOEngine extends PDO { } } /** - * function call to PDO::commit() + * Function to call PDO::commit(). + * * @see PDO::commit() */ public function commit() { @@ -930,7 +1167,8 @@ class PDOEngine extends PDO { $this->has_active_transaction = false; } /** - * function call to PDO::rollBack() + * Function to call PDO::rollBack(). + * * @see PDO::rollBack() */ public function rollBack() { @@ -939,6 +1177,11 @@ class PDOEngine extends PDO { } } +/** + * Class to change queried data to PHP object. + * + * @author kjm + */ class ObjectArray { function __construct($data = null,&$node= null) { foreach ($data as $key => $value) { diff --git a/query.class.php b/query.class.php index 959738e..cd2899f 100644 --- a/query.class.php +++ b/query.class.php @@ -1,21 +1,33 @@ _rewrite_between(); break; case 'insert': - $this->_strip_backticks(); + $this->_safe_strip_backticks(); $this->_execute_duplicate_key_update(); $this->_rewrite_insert_ignore(); $this->_rewrite_regexp(); $this->_fix_date_quoting(); break; case 'update': - $this->_strip_backticks(); + $this->_safe_strip_backticks(); $this->_rewrite_update_ignore(); // $this->_rewrite_date_sub(); $this->_rewrite_limit_usage(); @@ -81,7 +93,7 @@ class PDOSQLiteDriver { $this->_delete_workaround(); break; case 'replace': - $this->_strip_backticks(); + $this->_safe_strip_backticks(); $this->_rewrite_date_sub(); $this->_rewrite_regexp(); break; @@ -102,7 +114,9 @@ class PDOSQLiteDriver { } /** - * method to dummy the SHOW TABLES query + * method to handle SHOW TABLES query. + * + * @access private */ private function _handle_show_query(){ $table_name = ''; @@ -117,28 +131,62 @@ class PDOSQLiteDriver { } $this->_query = "SELECT name FROM sqlite_master WHERE type='table'" . $suffix . ' ORDER BY name DESC'; } - /** - * method to strip all column qualifiers (backticks) from a query + * Method to strip all column qualifiers (backticks) from a query. + * + * All the back quotes in the query string are removed automatically. + * So it must not be used when INSERT, UPDATE or REPLACE query is executed. + * + * @access private */ private function _strip_backticks(){ $this->_query = str_replace('`', '', $this->_query); } - /** - * method to emulate the SQL_CALC_FOUND_ROWS placeholder for mysql + * Method to strip all column qualifiers (backticks) from a query except post data. + * + * All the back quotes execpt user data to be inserted are revomved automatically. + * This method must be used when INSERT, UPDATE or REPLACE query is executed. + * + * @access private + */ + private function _safe_strip_backticks() { + $query_string = ''; + $tokens = preg_split("/(''|')/s", $this->_query, -1, PREG_SPLIT_DELIM_CAPTURE); + $literal = false; + $query_string = ''; + foreach ($tokens as $token) { + if ($token == "'") { + if ($literal) { + $literal = false; + } else { + $literal = true; + } + } else { + if ($literal === false && strpos($token, '`') !== false) { + $token = str_replace('`', '', $token); + } + } + $query_string .= $token; + } + $this->_query = $query_string; + } + /** + * Method to emulate the SQL_CALC_FOUND_ROWS placeholder for MySQL. * - * this is a kind of tricky play. + * This is a kind of tricky play. * 1. remove SQL_CALC_FOUND_ROWS option, and give it to the pdo engine * 2. make another $wpdb instance, and execute SELECT COUNT(*) query - * 3. give the returned value to the original instance variable + * 3. give the returned value to the original instance variable without LIMIT * - * when SQL statement contains GROUP BY option, SELECT COUNT query doesn't + * When SQL statement contains GROUP BY option, SELECT COUNT query doesn't * go well. So we remove the GROUP BY, which means the returned value may * be a approximate one. * - * this kind of statement is required for WordPress to calculate the paging. + * This kind of statement is required for WordPress to calculate the paging. * see also WP_Query class in wp-includes/query.php + * + * @access private */ private function _handle_sql_count(){ if (stripos($this->_query, 'SELECT SQL_CALC_FOUND_ROWS') !== false){ @@ -153,38 +201,46 @@ class PDOSQLiteDriver { $_wpdb = new PDODB(); $result = $_wpdb->query($unlimited_query); $wpdb->dbh->found_rows_result = $_wpdb->last_result; + $_wpdb = null; } } - /** - * transforms a select query to a select count(*) + * Call back method to change SELECT query to SELECT COUNT(). + * + * revised for version 1.5.1 * * @param string $query the query to be transformed - * @return string the transformed query + * @return string the transformed query + * @access private */ private function __transform_to_count($query){ - $pattern = '/^\\s*SELECT\\s*(DISTINCT|)?.*?FROM\b/imsx'; + $pattern = '/^\\s*SELECT\\s*(DISTINCT|)?.*?FROM\b/isx'; $_query = preg_replace($pattern, 'SELECT \\1 COUNT(*) FROM ', $query); return $_query; } - /** - * rewrites the insert ignore phrase for sqlite + * Method to rewrite INSERT IGNORE to INSERT OR IGNORE. + * + * @access private */ private function _rewrite_insert_ignore(){ $this->_query = str_ireplace('INSERT IGNORE', 'INSERT OR IGNORE ', $this->_query); } - /** - * rewrites the update ignore phrase for sqlite + * Method to rewrite UPDATE IGNORE to UPDATE OR IGNORE. + * + * @access private */ private function _rewrite_update_ignore(){ $this->_query = str_ireplace('UPDATE IGNORE', 'UPDATE OR IGNORE ', $this->_query); } - - /** - * rewrites the date_add function for udf to manipulate + * Method to rewrite DATE_ADD() function. + * + * DATE_ADD has a parameter PHP function can't parse, so we quote the list and + * pass it to the user defined function. + * + * @access private */ private function _rewrite_date_add(){ //(date,interval expression unit) @@ -194,9 +250,13 @@ class PDOSQLiteDriver { $this->_query = preg_replace($pattern, " date_add($matches[1], $expression) ", $this->_query); } } - /** - * rewrite the data_sub function for udf to manipulate + * Method to rewrite DATE_SUB() function. + * + * DATE_SUB has a parameter PHP function can't parse, so we quote the list and + * pass it to the user defined function. + * + * @access private */ private function _rewrite_date_sub(){ //(date,interval expression unit) @@ -206,21 +266,28 @@ class PDOSQLiteDriver { $this->_query = preg_replace($pattern, " date_sub($matches[1], $expression) ", $this->_query); } } - /** - * handles the create query - * this function won't be used... See PDOEngine class + * Method to handle CREATE query. + * + * If the query is CREATE query, it will be passed to the query_create.class.php. + * So this method can't be used. It's here for safety. + * + * @access private */ private function _handle_create_query(){ - require_once PDODIR.'query_create.class.php'; + require_once PDODIR . 'query_create.class.php'; $engine = new CreateQuery(); $this->_query = $engine->rewrite_query($this->_query); $engine = null; } /** - * handles the ALTER query - * this function won't be used... See PDOEngine class + * Method to handle ALTER query. + * + * If the query is ALTER query, it will be passed ot the query_alter.class.php. + * So this method can't be used. It is here for safety. + * + * @access private */ private function _handle_alter_query(){ require_once PDODIR . 'query_alter.class.php'; @@ -230,8 +297,12 @@ class PDOSQLiteDriver { } /** - * handles DESCRIBE or DESC query - * this is required in the WordPress install process + * Method to handle DESCRIBE or DESC query. + * + * DESCRIBE is required for WordPress installation process. DESC is + * an alias for DESCRIBE, but it is not used in core WordPress. + * + * @access private */ private function _handle_describe_query(){ // $this->_query = "select 1=1"; @@ -241,12 +312,16 @@ class PDOSQLiteDriver { $this->_query = "PRAGMA table_info($tablename)"; } } - /** + * Method to remove LIMIT clause from DELETE or UPDATE query. + * * The author of the original 'PDO for WordPress' says update method of wpdb * insists on adding LIMIT. But the newest version of WordPress doesn't do that. * Nevertheless some plugins use DELETE with LIMIT, UPDATE with LIMIT. - * We need to exclude sub query's LIMIT. + * We need to exclude sub query's LIMIT. And if SQLite is compiled with + * ENABLE_UPDATE_DELETE_LIMIT option, we don't remove it. + * + * @access private */ private function _rewrite_limit_usage(){ $_wpdb = new PDODB(); @@ -259,29 +334,47 @@ class PDOSQLiteDriver { } } /** + * Method to remove ORDER BY clause from DELETE or UPDATE query. + * * SQLite compiled without SQLITE_ENABLE_UPDATE_DELETE_LIMIT option can't * execute UPDATE with ORDER BY, DELETE with GROUP BY. * We need to exclude sub query's GROUP BY. + * + * @access private */ private function _rewrite_order_by_usage() { + $_wpdb = new PDODB(); + $options = $_wpdb->get_results('PRAGMA compile_options'); + foreach ($options as $opt) { + if (stripos($opt->compile_option, 'ENABLE_UPDATE_DELETE_LIMIT') !== false) return; + } if (stripos($this->_query, '(select') === false) { $this->_query = preg_replace('/\\s*ORDER\\s*BY\\s*.*$/i', '', $this->_query); } } - + /** + * Method to handle TRUNCATE query. + * + * @access private + */ private function _handle_truncate_query(){ $pattern = '/TRUNCATE TABLE (.*)/im'; $this->_query = preg_replace($pattern, 'DELETE FROM $1', $this->_query); } /** - * rewrites use of Optimize queries in mysql for sqlite. - * table name is ignored. + * Method to handle OPTIMIZE query. + * + * Original query has the table names, but they are simply ignored. + * Table names are meaningless in SQLite. + * + * @access private */ private function _rewrite_optimize(){ $this->_query ="VACUUM"; } - /** + * Method to rewrite day. + * * Jusitn Adie says: some wp UI interfaces (notably the post interface) * badly composes the day part of the date leading to problems in sqlite * sort ordering etc. @@ -289,59 +382,79 @@ class PDOSQLiteDriver { * I don't understand that... * * @return void + * @access private */ private function _rewrite_badly_formed_dates(){ $pattern = '/([12]\d{3,}-\d{2}-)(\d )/ims'; $this->_query = preg_replace($pattern, '${1}0$2', $this->_query); } - /** - * function to remove unsupported index hinting from mysql queries + * Method to remove INDEX HINT. * - * @return void + * @return void + * @access private */ private function _delete_index_hints(){ $pattern = '/\\s*(use|ignore|force)\\s+index\\s*\(.*?\)/i'; $this->_query = preg_replace($pattern, '', $this->_query); } - /** - * Fix the date string and quote. This is required for the calendar widget. + * Method to fix the date string and quoting. * - * where month(fieldname)=08 becomes month(fieldname)='8' - * where month(fieldname)='08' becomes month(fieldname)='8' + * This is required for the calendar widget. + * + * WHERE month(fieldname)=08 is converted to month(fieldname)='8' + * WHERE month(fieldname)='08' is converted to month(fieldname)='8' * * I use preg_replace_callback instead of 'e' option because of security reason. * cf. PHP manual (regular expression) * * @return void + * @access private */ private function _fix_date_quoting() { $pattern = '/(month|year|second|day|minute|hour|dayofmonth)\\s*\((.*?)\)\\s*=\\s*["\']?(\d{1,4})[\'"]?\\s*/im'; $this->_query = preg_replace_callback($pattern, array($this, '__fix_date_quoting'), $this->_query); } + /** + * Call back method to rewrite date string. + * + * @param string $match + * @return string + * @access private + */ private function __fix_date_quoting($match) { $fixed_val = "{$match[1]}({$match[2]})='" . intval($match[3]) . "' "; return $fixed_val; } - + /** + * Method to rewrite REGEXP() function. + * + * This method changes function name to regexpp() and pass it to the user defined + * function. + * + * @access private + */ private function _rewrite_regexp(){ $pattern = '/\s([^\s]*)\s*regexp\s*(\'.*?\')/im'; $this->_query = preg_replace($pattern, ' regexpp(\1, \2)', $this->_query); } - /** - * rewrites boolean to numeral - * SQLite doesn't support true/false type + * Method to rewrite boolean to number. + * + * SQLite doesn't support true/false type, so we need to convert them to 1/0. + * + * @access private */ private function _rewrite_boolean() { $query = str_ireplace('TRUE', "1", $this->_query); $query = str_ireplace('FALSE', "0", $query); $this->_query = $query; } - /** - * method to execute SHOW COLUMNS query + * Method to handl SHOW COLUMN query. + * + * @access private */ private function _handle_show_columns_query() { $pattern_like = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?\\s*LIKE\\s*(.*)?/i'; @@ -357,10 +470,12 @@ class PDOSQLiteDriver { $this->_query = $query_string; } } - /** - * method to execute SHOW INDEX query + * Method to handle SHOW INDEX query. + * * Moved the WHERE clause manipulation to pdoengin.class.php (ver 1.3.1) + * + * @access private */ private function _handle_show_index() { $pattern = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?/im'; @@ -370,13 +485,14 @@ class PDOSQLiteDriver { $this->_query = "SELECT * FROM sqlite_master WHERE tbl_name='$table_name'"; } } - /** - * function to rewrite ON DUPLICATE KEY UPDATE statement - * I use SELECT query and check if INSERT is allowed or not - * Rewriting procedure looks like a detour, but I've got another way. + * Method to handle ON DUPLICATE KEY UPDATE statement. + * + * First we use SELECT query and check if INSERT is allowed or not. + * Rewriting procedure looks like a detour, but I've got no other way. * * @return void + * @access private */ private function _execute_duplicate_key_update() { $update = false; @@ -509,7 +625,14 @@ class PDOSQLiteDriver { // $this->_query = $replace_query; // } } - + /** + * Method to rewrite BETWEEN A AND B clause. + * + * This clause is the same form as natural language, so we have to check if it is + * in the data or SQL statement. + * + * @access private + */ private function _rewrite_between() { $pattern = '/\\s*(\\w+)?\\s*BETWEEN\\s*([^\\s]*)?\\s*AND\\s*([^\\s]*)?\\s*/ims'; if (preg_match($pattern, $this->_query, $match)) { @@ -517,11 +640,11 @@ class PDOSQLiteDriver { $min_value = trim($match[2]); $max_value = trim($match[3]); $max_value = rtrim($max_value); - $tokens = preg_split("/(''|'|,|)/s", $this->_query, -1, PREG_SPLIT_DELIM_CAPTURE); + $tokens = preg_split("/(''|')/s", $this->_query, -1, PREG_SPLIT_DELIM_CAPTURE); $literal = false; $rewriting = false; foreach ($tokens as $token) { - if (strpos($token, "'") !== false) { + if ($token == "'") { if ($literal) { $literal = false; } else { @@ -541,10 +664,15 @@ class PDOSQLiteDriver { } } /** - * workaround function to avoid DELETE with JOIN + * Method to avoid DELETE with JOIN statement. + * * wp-admin/includes/upgrade.php contains 'DELETE ... JOIN' statement. * This query can't be replaced with regular expression or udf, so we - * replace all the statement with another. + * replace all the statement with another. But this query was used in + * the very old version of WordPress when it was upgraded. So we won't + * have no chance that this method should be used. + * + * @access private */ private function _delete_workaround() { global $wpdb; @@ -556,7 +684,13 @@ class PDOSQLiteDriver { } } /** + * Method to suppress errors. * + * When the query string is the one that this class can't manipulate, + * the query string is replaced with the one that always returns true + * and does nothing. + * + * @access private */ private function _return_true() { $this->_query = 'SELECT 1=1'; diff --git a/query_alter.class.php b/query_alter.class.php index 38d5d44..c784651 100644 --- a/query_alter.class.php +++ b/query_alter.class.php @@ -1,13 +1,26 @@ _query; } - + /** + * Function to analyze ALTER TABLE command and sets the data to an array. + * + * @param string $command + * @return boolean|array + * @access private + */ private function command_tokenizer($command) { $tokens = array(); if (preg_match('/^(ADD|DROP|RENAME|MODIFY|CHANGE|ALTER)\\s*(\\w+)?\\s*(\\w+(\(.+\)|))?\\s*/ims', $command, $match)) { @@ -204,7 +223,15 @@ class AlterQuery { return $tokens; } } - + /** + * Function to split multiple commands into an array and return it. + * + * This function is deprecated. + * + * @access private + * @param unknown $command + * @return multitype:string unknown Ambigous + */ private function split_multiple($command) { $out = true; $command_array = array(); @@ -245,7 +272,13 @@ class AlterQuery { } return $command_array; } - + /** + * Function to handle single command. + * + * @access private + * @param array of string $queries + * @return string + */ private function handle_single_command($queries) { $tokenized_query = $queries; if (stripos($tokenized_query['command'], 'add column') !== false) { @@ -263,7 +296,13 @@ class AlterQuery { } return $query; } - + /** + * Function to handle ADD PRIMARY KEY. + * + * @access private + * @param array of string $queries + * @return array of string + */ private function handle_add_primary_key($queries) { $tokenized_query = $queries; $tbl_name = $tokenized_query['table_name']; @@ -287,7 +326,13 @@ class AlterQuery { } return $query; } - + /** + * Function to handle DROP PRIMARY KEY. + * + * @access private + * @param array of string $queries + * @return array of string + */ private function handle_drop_primary_key($queries) { $tokenized_query = $queries; $temp_table = 'temp_'.$tokenized_query['table_name']; @@ -315,7 +360,13 @@ class AlterQuery { } return $query; } - + /** + * Function to handle MODIFY COLUMN. + * + * @access private + * @param array of string $queries + * @return string|array of string + */ private function handle_modify_command($queries) { $tokenized_query = $queries; $temp_table = 'temp_'.$tokenized_query['table_name']; @@ -347,7 +398,13 @@ class AlterQuery { } return $query; } - + /** + * Function to handle CHANGE COLUMN. + * + * @access private + * @param array of string $queries + * @return string|array of string + */ private function handle_change_command($queries) { $col_check = false; $old_fields = ''; @@ -401,7 +458,13 @@ class AlterQuery { } return $query; } - + /** + * Function to handle ALTER COLUMN. + * + * @access private + * @param array of string $queries + * @return string|array of string + */ private function handle_alter_command($queries) { $tokenized_query = $queries; $temp_table = 'temp_'.$tokenized_query['table_name']; @@ -461,7 +524,9 @@ class AlterQuery { return $query; } /** - * Change the field definition to SQLite compatible data type. + * Function to change the field definition to SQLite compatible data type. + * + * @access private * @param string $col_name * @param string $col_def * @return string @@ -488,7 +553,12 @@ class AlterQuery { } return $def_string; } - + /** + * Variable to store the data definition table. + * + * @access private + * @var associative array + */ private $array_types = array( 'bit' => 'INTEGER', 'bool' => 'INTEGER', 'boolean' => 'INTEGER', 'tinyint' => 'INTEGER', diff --git a/query_create.class.php b/query_create.class.php index 13bdc2a..0ef200f 100644 --- a/query_create.class.php +++ b/query_create.class.php @@ -1,12 +1,14 @@ _query = $query; $this->_errors [] = ''; if (preg_match('/^CREATE\\s*(UNIQUE|FULLTEXT|)\\s*INDEX/ims', $this->_query, $match)) { + // we manipulate CREATE INDEX query in PDOEngine.class.php + // FULLTEXT index creation is simply ignored. if (isset($match[1]) && stripos($match[1], 'fulltext') !== false) { return 'SELECT 1=1'; } else { return $this->_query; } } elseif (preg_match('/^CREATE\\s*(TEMP|TEMPORARY|)\\s*TRIGGER\\s*/im', $this->_query)) { + // if WordPress comes to use foreign key constraint, trigger will be needed. + // we don't use it for now. return $this->_query; } $this->get_table_name(); @@ -50,11 +57,12 @@ class CreateQuery{ return $this->post_process(); } - /** - * Method for getting the table name from the create query. - * taken from PDO for WordPress - * we don't need 'IF NOT EXISTS', so we changed the pattern. + * Method to get table name from the query string. + * + * IF NOT EXISTS is removed for the easy regular expression usage. + * It will be added at the end of the process. + * @access private */ private function get_table_name(){ // $pattern = '/^\\s*CREATE\\s*(TEMP|TEMPORARY)?\\s*TABLE\\s*(IF NOT EXISTS)?\\s*([^\(]*)/imsx'; @@ -63,9 +71,10 @@ class CreateQuery{ $this->table_name = trim($matches[1]); } } - /** - * Method for changing the field type to SQLite compatible type. + * Method to change the MySQL field types to SQLite compatible types. + * + * @access private */ private function rewrite_field_types(){ $array_types = array ( @@ -95,33 +104,43 @@ class CreateQuery{ } } } - /** - * Method for stripping the comments from the SQL statement + * Method for stripping the comments from the SQL statement. + * + * @access private */ private function rewrite_comments(){ $this->_query = preg_replace("/# --------------------------------------------------------/","-- ******************************************************",$this->_query); $this->_query = preg_replace("/#/","--",$this->_query); } - /** - * Method for stripping the engine and other stuffs + * Method for stripping the engine and other stuffs. + * + * TYPE, ENGINE and AUTO_INCREMENT are removed here. + * @access private */ private function rewrite_engine_info(){ $this->_query = preg_replace("/\\s*(TYPE|ENGINE)\\s*=\\s*.*(?_query); $this->_query = preg_replace("/ AUTO_INCREMENT\\s*=\\s*[0-9]*/ims",'',$this->_query); } - /** - * Method for stripping unsigned + * Method for stripping unsigned. + * + * UNSIGNED INT(EGER) is converted to INTEGER here. + * + * @access private */ private function rewrite_unsigned(){ $this->_query = preg_replace('/\\bunsigned\\b/ims', ' ', $this->_query); } - /** - * Method for rewriting auto_increment - * if the field type is 'integer primary key', it is automatically autoincremented + * Method for rewriting primary key auto_increment. + * + * If the field type is 'INTEGER PRIMARY KEY', it is automatically autoincremented + * by SQLite. There's a little difference between PRIMARY KEY and AUTOINCREMENT, so + * we may well convert to PRIMARY KEY only. + * + * @access private */ private function rewrite_autoincrement(){ $this->_query = preg_replace('/\\bauto_increment\\s*primary\\s*key\\s*(,)?/ims', ' PRIMARY KEY AUTOINCREMENT \\1', $this->_query, -1, $count); @@ -130,9 +149,10 @@ class CreateQuery{ $this->has_primary_key = true; } } - /** - * Method for rewriting primary key + * Method for rewriting primary key. + * + * @access private */ private function rewrite_primary_key(){ if ($this->has_primary_key) { @@ -142,17 +162,19 @@ class CreateQuery{ $this->_query = preg_replace('/\\bprimary\\s*key\\s*.*?\\s*(\(.*?\))/im', 'PRIMARY KEY \\1', $this->_query); } } - /** - * Method for rewriting unique key + * Method for rewriting unique key. + * + * @access private */ private function rewrite_unique_key(){ $this->_query = preg_replace_callback('/\\bunique key\\b([^\(]*)(\([^\)]*\))/ims', array($this, '_rewrite_unique_key'), $this->_query); } - /** - * Callback method for rewrite_unique_key + * Callback method for rewrite_unique_key. + * * @param array $matches an array of matches from the Regex + * @access private */ private function _rewrite_unique_key($matches){ $index_name = trim($matches[1]); @@ -174,46 +196,53 @@ class CreateQuery{ $this->index_queries[] = "CREATE UNIQUE INDEX $index_name ON " . $tbl_name .$col_name; return ''; } - /** - * Method for handling ENUM fields - * SQLite doesn't support enum, so we change it to check constraint + * Method for handling ENUM fields. + * + * SQLite doesn't support enum, so we change it to check constraint. + * + * @access private */ private function rewrite_enum(){ $pattern = '/(,|\))([^,]*)enum\((.*?)\)([^,\)]*)/ims'; $this->_query = preg_replace_callback($pattern, array($this, '_rewrite_enum'), $this->_query); } - /** - * Method for the callback function rewrite_enum and rewrite_set + * Call back method for rewrite_enum() and rewrite_set(). + * + * @access private */ private function _rewrite_enum($matches){ $output = $matches[1] . ' ' . $matches[2]. ' TEXT '. $matches[4].' CHECK ('.$matches[2].' IN ('.$matches[3].')) '; return $output; } - /** - * Method for rewriting usage of set - * whilst not identical to enum, they are similar and sqlite does not - * support either. + * Method for rewriting usage of set. + * + * It is similar but not identical to enum. SQLite does not support either. + * + * @access private */ private function rewrite_set(){ $pattern = '/\b(\w)*\bset\\s*\((.*?)\)\\s*(.*?)(,)*/ims'; $this->_query = preg_replace_callback($pattern, array($this, '_rewrite_enum'), $this->_query); } - /** - * Method for rewriting usage of key to create an index - * sqlite cannot create non-unique indices as part of the create query - * so we need to create an index by hand and append it to the create query + * Method for rewriting usage of key to create an index. + * + * SQLite cannot create non-unique indices as part of the create query, + * so we need to create an index by hand and append it to the create query. + * + * @access private */ private function rewrite_key(){ $this->_query = preg_replace_callback('/,\\s*(KEY|INDEX)\\s*(\\w+)?\\s*(\(.*(?_query); } - /** - * Callback method for rewrite_key + * Callback method for rewrite_key. + * * @param array $matches an array of matches from the Regex + * @access private */ private function _rewrite_key($matches){ $index_name = trim($matches[2]); @@ -237,13 +266,24 @@ class CreateQuery{ $this->index_queries[] = 'CREATE INDEX '. $index_name . ' ON ' . $tbl_name . $col_name ; return ''; } + /** + * Call back method to remove unnecessary string. + * + * This method is deprecated. + * + * @param string $match + * @return string whose length is zero + * @access private + */ private function _remove_length($match) { return ''; } /** - * Method to assemble the main query and index queries into an array - * to be returned to the base class - * @return array + * Method to assemble the main query and index queries into an array. + * + * It return the array of the queries to be executed separately. + * @return array + * @access private */ private function post_process(){ $mainquery = $this->_query; @@ -260,10 +300,12 @@ class CreateQuery{ return $return_val; } /** - * Method to add IF NOT EXISTS to query defs - * sometimes, if upgrade.php is being called, wordpress seems to want to run - * new create queries. this stops the query from throwing an error and halting - * output + * Method to add IF NOT EXISTS to query string. + * + * This adds IF NOT EXISTS to every query string, which prevent the exception + * from being thrown. + * + * @access private */ private function add_if_not_exists(){ $pattern_table = '/^\\s*CREATE\\s*(TEMP|TEMPORARY)?\\s*TABLE\\s*(IF NOT EXISTS)?\\s*/ims'; @@ -273,9 +315,10 @@ class CreateQuery{ $this->index_queries[$i] = preg_replace($pattern_index, 'CREATE $1 INDEX IF NOT EXISTS ', $this->index_queries[$i]); } } - /** - * Method to strip back ticks + * Method to strip back ticks. + * + * @access private */ private function strip_backticks(){ $this->_query = str_replace('`', '', $this->_query); @@ -283,9 +326,13 @@ class CreateQuery{ $query = str_replace('`', '', $query); } } - /** - * Method to remove the character set information from within mysql queries + * Method to remove the character set information from within mysql queries. + * + * This removes DEFAULT CHAR(ACTER) SET and COLLATE, which is meaningless for + * SQLite. + * + * @access private */ private function rewrite_character_set(){ $pattern_charset = '/\\b(default\\s*character\\s*set|default\\s*charset|character\\s*set)\\s*(?text_domain; @@ -360,7 +394,13 @@ class DatabaseMaintenance { return $results; } } - + /** + * Method to create a back up file of the database. + * + * It returns true if success, false if failure. + * + * @return boolean + */ private function maintenance_backup() { $result = array(); $database_file = FQDB; @@ -390,7 +430,10 @@ class DatabaseMaintenance { } return $result; } - + /** + * Method to display the maintenance page on the admin panel. + * + */ function show_maintenance_page() { global $utils, $wpdb; $domain = $utils->text_domain; diff --git a/utilities/documentation.php b/utilities/documentation.php index 8d4afce..339a80c 100644 --- a/utilities/documentation.php +++ b/utilities/documentation.php @@ -1,15 +1,22 @@ text_domain; if (is_multisite() && !current_user_can('manage_network_options')) { @@ -30,7 +37,7 @@ class SQLiteIntegrationDocument {

- Plugin Page.', $domain);?> + SQLite Integration page.', $domain);?>

@@ -38,7 +45,7 @@ class SQLiteIntegrationDocument {

- PDO for WordPress, which enabled WordPress to use SQLite for its database. But PDO for WordPress doesn\'t seem to be maintained any more only to be outdated. SQLite Integration makes use of the basic ideas and framework of PDO for WordPress, adds some new features and updates it to be able to work with the newest version of WordPress(3.8).', $domain); ?> + PDO for WordPress, which enabled WordPress to use SQLite for its database. But PDO for WordPress doesn\'t seem to be maintained any more only to be outdated. SQLite Integration makes use of the basic ideas and framework of PDO for WordPress, adds some new features and updates it to be able to work with the newest version of WordPress(3.8.1).', $domain); ?>

SQLite Web Page says — SQLite is a "software library that implements selfcontained, serverless, zero-configuration, transactional SQL database engine". It is "a good choice for small to medium size websites". It\'s small and portable, and you don\'t need any database server system.', $domain); ?> @@ -66,7 +73,7 @@ class SQLiteIntegrationDocument {

    -
  1. ', $domain);?> +
  2. ', $domain);?>
  3. ', $domain);?> Patch Utility. See also the Plugin Page for more details.', $domain), $utils->show_parent());?>
  4. @@ -102,7 +109,7 @@ class SQLiteIntegrationDocument {

    - System Info page. To see more details, please visit the Plugin Page.', $domain), $utils->show_parent());?> + System Info page. To see more details, please visit the Plugin Page.', $domain), $utils->show_parent());?>

    @@ -137,56 +144,7 @@ class SQLiteIntegrationDocument {
    - -

    -

    - -

    -

    - My recommendation is not to use caching plugins. Even so, if you want a caching plugin, you could try WP Super Cache, which doesn\'t use db.php file. But no warranty, try at your own risk.', $domain);?> -

    -

    - -

    -

    -

    - -

    -

    - -

    -
    -$postRes = mysql_query($sql,$wpdb->dbh);
    -
    -

    - -

    -
    -if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') ) {
    -
    -

    - -

    -

    - -

    -
    -$postRes = $wpdb->query($sql);
    -
    -
    -if ( version_compare($wpdb->db_version(), '4.1.0', '>=') ) {
    -
    -

    - -

    -

    -

    - -

    -

    - WordPress Related Posts or Related Posts or others. They are working fine with SQLite Integration!', $domain);?> -

    -
+
* sys_info['WordPress'] => WordPress Version * sys_info['PHP'] => PHP Version + * + * * @return array + * @access private */ private function get_system_info() { global $wp_version; @@ -62,8 +87,12 @@ class SQLiteIntegrationUtils { return $sys_info; } /** - * function to return various database information - * @return assoc array + * Method to get database information from the database and returns its data. + * + * Returned value is an associative array. + * + * @return array + * @access private */ private function get_database_status() { global $wpdb; @@ -93,10 +122,16 @@ class SQLiteIntegrationUtils { return $status; } /** - * function to return associative array + * Method to get table information and returns its data. + * + * Returned value is an associative array like: + * * array( table name => array( index name ( column name ))) + * * for each table in the database + * * @return array + * @access private */ private function get_tables_info() { global $wpdb; @@ -116,8 +151,12 @@ class SQLiteIntegrationUtils { return $table_info; } /** - * function to return the autoincremented values of each table + * Method to get the autoincremented values of each table and returns it. + * + * The data is from sqlite_sequence table. + * * @return assoc array name => sequence, or false + * @access private */ private function get_sequence() { global $wpdb; @@ -133,9 +172,12 @@ class SQLiteIntegrationUtils { } } /** - * function to return contents of 'wp-content/db.php' file - * if the file is not existent, returns false. + * Method to show the contents of 'wp-content/db.php' file. + * + * If this file is not existent, shows message and returns false. + * * @return string|boolean + * @access private */ private function show_db_php() { if (defined('WP_CONTENT_DIR')) { @@ -156,9 +198,11 @@ class SQLiteIntegrationUtils { } } /** - * function to get the textarea contents and write into db.php file + * Method to get the textarea content and write it to db.php file. + * * @param string $contents * @return boolean + * @access private */ private function save_db_php($contents) { if (defined('WP_CONTENT_DIR')) { @@ -181,9 +225,13 @@ class SQLiteIntegrationUtils { return true; } /** - * function to optimize database file - * only to give vacuum command to SQLite + * Method to optimize SQLite database. + * + * This only gives VACUUM command to SQLite database. This query is rewritten in + * the query.class.php file. + * * @return boolean + * @access private */ private function optimize_db() { global $wpdb; @@ -191,8 +239,10 @@ class SQLiteIntegrationUtils { return $result; } /** - * function to get SQLite database file size + * Method to get SQLite database file size. + * * @return string + * @access private */ private function get_database_size() { $db_file = FQDB; @@ -203,9 +253,11 @@ class SQLiteIntegrationUtils { } } /** - * function to format file size to unit byte + * Method to format the file size number to the unit byte. + * * @param integer $size * @return string + * @access private */ private function convert_to_formatted_number($size) { $unim = array('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'); @@ -218,7 +270,10 @@ class SQLiteIntegrationUtils { } /** - * function to echo plugins info table component + * Method to echo plugins info table component. + * + * @return nothing returned. + * @access private */ private function show_plugins_info() { $domain = $this->text_domain; @@ -279,9 +334,11 @@ class SQLiteIntegrationUtils { } /** - * function to return output of phpinfo() as an array - * See PHP Manual + * Method to return output of phpinfo() as an array. + * + * @See PHP Manual * @return array + * @access private */ private function parse_php_modules() { ob_start(); @@ -313,9 +370,11 @@ class SQLiteIntegrationUtils { return $modules; } /** - * function to echo PHP module info + * Method to echo PHP module info. + * * @param string $module_name * @param string $setting_name + * @access private */ private function get_module_setting($module_name, $setting_name) { $module_info = $this->parse_php_modules(); @@ -330,7 +389,10 @@ class SQLiteIntegrationUtils { } /** - * function to parse FQDBDIR and return backup database files + * Method to parse FQDBDIR and return backup database files. + * + * @return nothing returned. + * @access private */ private function get_backup_files() { $db_name = basename(FQDB); @@ -348,7 +410,10 @@ class SQLiteIntegrationUtils { } /** - * function to create backup file + * Method to create backup database file. + * + * @return string array + * @access private */ private function backup_db() { $result = array(); @@ -379,7 +444,12 @@ class SQLiteIntegrationUtils { } return $result; } - + /** + * Method to delete backup database file(s). + * + * @return boolean|string + * @access private + */ private function delete_backup_db() { global $utils; $domain = $utils->text_domain; @@ -401,7 +471,10 @@ class SQLiteIntegrationUtils { } return $results; } - + /** + * Method to show Welcome page. + * + */ function welcome() { $domain = $this->text_domain; if (isset($_GET['page']) && $_GET['page'] == 'sqlite-integration') :?> @@ -446,12 +519,11 @@ class SQLiteIntegrationUtils { - text_domain; @@ -638,7 +710,8 @@ class SQLiteIntegrationUtils { } /** - * function to show Setting File page + * Method to show Setting File page. + * */ function edit_db_file() { $domain = $this->text_domain;