diff --git a/db.php b/db.php
index 3724300..4c665c2 100644
--- a/db.php
+++ b/db.php
@@ -1,16 +1,39 @@
+ * define('USE_MYSQL', true);
+ *
+ *
+ * If you want to use SQLite, the line below will do. Or simply removing the line will
+ * be enough.
+ *
+ *
+ * define('USE_MYSQL', false);
+ *
+ */
+if (defined('USE_MYSQL') && USE_MYSQL) return;
+
+function pdo_log_error($message, $data = null) {
if (strpos($_SERVER['SCRIPT_NAME'], 'wp-admin') !== false) {
$admin_dir = '';
@@ -24,7 +47,7 @@ function pdo_log_erro($message, $data = null) {
+ * 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 +529,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 +566,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 +644,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')) {
@@ -385,5 +670,46 @@ class PDOSQLiteUDFS {
}
}
}
+ /**
+ * Method to return GMT date in the string format.
+ *
+ * @param none
+ * @return string formatted GMT date 'dddd-mm-dd'
+ */
+ public function utc_date() {
+ return gmdate('Y-m-d', time());
+ }
+ /**
+ * Method to return GMT time in the string format.
+ *
+ * @param none
+ * @return string formatted GMT time '00:00:00'
+ */
+ public function utc_time() {
+ return gmdate('H:i:s', time());
+ }
+ /**
+ * Method to return GMT time stamp in the string format.
+ *
+ * @param none
+ * @return string formatted GMT timestamp 'yyyy-mm-dd 00:00:00'
+ */
+ public function utc_timestamp() {
+ return gmdate('Y-m-d H:i:s', time());
+ }
+ /**
+ * Method to return MySQL version.
+ *
+ * This function only returns the current newest version number of MySQL,
+ * because it is meaningless for SQLite database.
+ *
+ * @param none
+ * @return string representing the version number: major_version.minor_version
+ */
+ public function version() {
+// global $required_mysql_version;
+// return $required_mysql_version;
+ return '5.5';
+ }
}
?>
\ No newline at end of file
diff --git a/functions.php b/functions.php
index 8cb715c..7dd6247 100644
--- a/functions.php
+++ b/functions.php
@@ -1,24 +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',
@@ -42,7 +68,6 @@ class PDOSQLiteUDFS {
'subdate' => 'date_sub',
'localtime' => 'now',
'localtimestamp' => 'now',
- //'date'=>'date',
'isnull' => 'isnull',
'if' => '_if',
'regexpp' => 'regexp',
@@ -50,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',
@@ -58,110 +83,245 @@ class PDOSQLiteUDFS {
'inet_ntoa' => 'inet_ntoa',
'inet_aton' => 'inet_aton',
'datediff' => 'datediff',
- 'locate' => 'locate'
+ 'locate' => 'locate',
+ 'utc_date' => 'utc_date',
+ 'utc_time' => 'utc_time',
+ 'utc_timestamp' => 'utc_timestamp',
+ '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(),
+ * which can manipulate UTF-8 characters.
+ *
+ * @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 +362,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 +372,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 +438,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 +493,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 +530,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 +592,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')) {
@@ -359,5 +643,46 @@ class PDOSQLiteUDFS {
}
}
}
+ /**
+ * Method to return GMT date in the string format.
+ *
+ * @param none
+ * @return string formatted GMT date 'dddd-mm-dd'
+ */
+ public function utc_date() {
+ return gmdate('Y-m-d', time());
+ }
+ /**
+ * Method to return GMT time in the string format.
+ *
+ * @param none
+ * @return string formatted GMT time '00:00:00'
+ */
+ public function utc_time() {
+ return gmdate('H:i:s', time());
+ }
+ /**
+ * Method to return GMT time stamp in the string format.
+ *
+ * @param none
+ * @return string formatted GMT timestamp 'yyyy-mm-dd 00:00:00'
+ */
+ public function utc_timestamp() {
+ return gmdate('Y-m-d H:i:s', time());
+ }
+ /**
+ * Method to return MySQL version.
+ *
+ * This function only returns the current newest version number of MySQL,
+ * because it is meaningless for SQLite database.
+ *
+ * @param none
+ * @return string representing the version number: major_version.minor_version
+ */
+ public function version() {
+// global $required_mysql_version;
+// return $required_mysql_version;
+ return '5.5';
+ }
}
?>
\ No newline at end of file
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..29d690a
--- /dev/null
+++ b/index.php
@@ -0,0 +1,2 @@
+'; + echo $server_message; + echo '
'; + } + return array('url' => $guessurl, 'user_id' => $user_id, 'password' => $user_password, 'password_message' => $message); } ?> \ No newline at end of file diff --git a/js/index.php b/js/index.php new file mode 100644 index 0000000..29d690a --- /dev/null +++ b/js/index.php @@ -0,0 +1,2 @@ +') diff --git a/js/sqlite.min.js b/js/sqlite.min.js new file mode 100644 index 0000000..a27987e --- /dev/null +++ b/js/sqlite.min.js @@ -0,0 +1 @@ +jQuery(document).ready(function($){function stripe(arg){$(arg).find("tr.alt").removeClass("alt");var $args=arg+" tbody";$($args).each(function(){$(this).children(":visible").has("td").filter(function(index){return 1==index%2}).addClass("alt")})}var $table=null,$headers=null;null!=document.getElementById("sqlite-table")?($table=$("#sqlite-table"),$headers=$table.find("thead th").slice(0,2)):null!=document.getElementById("plugins-table")?($table=$("#plugins-table"),$headers=$table.find("thead th").slice(0)):null!=document.getElementById("patch-files")?($table=$("#patch-files"),$headers=$table.find("thead th").slice(1)):null!=document.getElementById("backup-files")&&($table=$("#backup-files"),$headers=$table.find("thead th").slice(1)),$headers.wrapInner('').addClass("sort");var rows=$table.find("tbody > tr").get();$headers.bind("click",function(event){event.preventDefault();var $header=$(this),sortKey=$header.data("sort").key,sortDirection=1;$header.hasClass("sorted-asc")&&(sortDirection=-1),rows.sort(function(a,b){var keyA=$(a).data("table")[sortKey],keyB=$(b).data("table")[sortKey];return keyB>keyA?-sortDirection:keyA>keyB?sortDirection:0}),$headers.removeClass("sorted-asc sortd-desc"),$headers.addClass(1==sortDirection?"sorted-asc":"sorted-desc"),$.each(rows,function(index,row){$table.children("tbody").append(row)}),stripe("#plugins-table"),stripe("#sqlite-table"),stripe("#patch-files")}),stripe("#plugins-table"),stripe("#sys-info"),stripe("#sqlite-table"),stripe("#status"),stripe("#patch-files")}),jQuery(document).ready(function($){function stripe(arg){$(arg).find("tr.alt").removeClass("alt");var $args=arg+" tbody";$($args).each(function(){$(this).children(":visible").has("td").filter(function(index){return 1==index%2}).addClass("alt")})}var $table=$("#plugins-info"),$headers=$table.find("thead th").slice(0);$headers.wrapInner('').addClass("sort");var rows=$table.find("tbody > tr").get();$headers.bind("click",function(event){event.preventDefault();var $header=$(this),sortKey=$header.data("sort").key,sortDirection=1;$header.hasClass("sorted-asc")&&(sortDirection=-1),rows.sort(function(a,b){var keyA=$(a).data("table")[sortKey],keyB=$(b).data("table")[sortKey];return keyB>keyA?-sortDirection:keyA>keyB?sortDirection:0}),$headers.removeClass("sorted-asc sortd-desc"),$headers.addClass(1==sortDirection?"sorted-asc":"sorted-desc"),$.each(rows,function(index,row){$table.children("tbody").append(row)}),stripe("#plugins-info")}),stripe("#plugins-info")}); \ No newline at end of file diff --git a/languages/index.php b/languages/index.php new file mode 100644 index 0000000..29d690a --- /dev/null +++ b/languages/index.php @@ -0,0 +1,2 @@ +, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: sqlite-integration\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-02-06 01:39+0900\n" +"PO-Revision-Date: 2014-05-07 20:49-0300\n" +"Last-Translator: Pablo LagunaWe have been unable to "
+"connect to the specified database.
The error message received was %s"
+msgstr ""
+"
No pudimos "
+"conectar con la base de datos especificada.
El mensaje de error "
+"recibido fue %s"
+
+#: pdoengine.class.php:291
+#, php-format
+msgid ""
+"
Sorry, we cannot determine the type of query " +"that is requested.
The query is %s
" +msgstr "" +"Disculpe, no pudimos determinar el tipo " +"de query que es requerido.
La query es %s
" + +#: utility.php:294 utility.php:296 documentation.php:134 +msgid "Needs Patch" +msgstr "Parche requerido" + +#: utility.php:300 documentation.php:136 +msgid "Probably No" +msgstr "Probablemente no" + +#: utility.php:303 +msgid "Probably Yes" +msgstr "Probablemente sí" + +#: utility.php:306 documentation.php:138 +msgid "No" +msgstr "No" + +#: utility.php:310 +msgid "Checked*" +msgstr "Revisado*" + +#: utility.php:312 +msgid "Checked" +msgstr "Revisado" + +#: utility.php:316 utility.php:322 +msgid "Not Checked" +msgstr "No revisado" + +#: utility.php:327 +msgid "Sitewide Active" +msgstr "Activo en todo el sitio" + +#: utility.php:330 +msgid "Active" +msgstr "Activo" + +#: utility.php:333 +msgid "Inactive" +msgstr "Inactivo" + +#: utility.php:434 utility.php:444 +msgid " was created." +msgstr "fue creado." + +#: utility.php:436 utility.php:446 +msgid " was not created." +msgstr "no fue creado." + +#: utility.php:472 +#, php-format +msgid "File %s was deleted." +msgstr "El fichero %s fue eliminado." + +#: utility.php:474 +msgid "Error! File was not deleted." +msgstr "Error. El fichero no fue eliminado." + +#: utility.php:534 +msgid "Welcome to SQLite Integration" +msgstr "Bienvenido a SQLite Integration" + +#: utility.php:536 +msgid "Thank you for using SQLite Integration plugin!" +msgstr "¡Gracias por utilizar el plugin SQLite Integration!" + +#: utility.php:539 +msgid "" +"You read this message, which means you have succeeded in installing " +"WordPress with this plugin SQLite Integration. Congratulations and enjoy " +"your Blogging!" +msgstr "" +"Si lee este mensaje, significa que tuvo éxito al instalar WordPress con el " +"plugin SQLite Integration. ¡Felicidades y disfrute publicando!" + +#: utility.php:542 +msgid "" +"You don't have to set any special settings. In fact there are no other " +"settings. You can write articles or pages and customize you WordPress in an " +"ordinary way. You want to install your plugins? All right, go ahead. But " +"some of them may be incompatible with this. Please read more information " +"about this plugin and your SQLite database below." +msgstr "" +"No tiene que establecer ninguna configuración especial. De hecho no hay " +"otras configuraciones. Puede escribir entradas o páginas y personalizar su " +"WordPress con normalidad. ¿Desea instalar plugins? Sin problema, hágalo. " +"Quizás algunos sean incompatibles. Por favor, lea más información de este " +"plugin y su base de datos SQLite a continuación." + +#: utility.php:544 +msgid "" +"Deactivation makes this documents and utilities disappear from the " +"dashboard, but it doesn't affect the functionality of the SQLite " +"Integration. when uninstalled, it will remove wp-content/uploads/patches " +"directory (if exists) and wp-content/db.php file altogether." +msgstr "" +"La desactivación hará desaparecer de su tablero estos documentos y " +"utilidades, pero no afectará al funcionamiento de SQLite Integration. Cuando " +"desinstale, se eliminará el directorio wp-content/uploads/patches (si " +"existe) y también el fichero wp-content/db.php." + +#: utility.php:547 +msgid "Title" +msgstr "Título" + +#: utility.php:548 +msgid "Contents" +msgstr "Contenidos" + +#: utility.php:552 utility.php:590 utility.php:867 +#: database_maintenance.php:453 documentation.php:30 documentation.php:38 +#: patch.php:296 +msgid "Documentation" +msgstr "Documentación" + +#: utility.php:553 +msgid "You can read documentation about this plugin and plugin compatibility." +msgstr "" +"Puede leer documentación sobre este plugin y la compatibilidad de plugins." + +#: utility.php:556 utility.php:591 utility.php:868 +#: database_maintenance.php:454 documentation.php:31 patch.php:297 +msgid "System Info" +msgstr "Información del sistema" + +#: utility.php:557 +msgid "You can see database and system information." +msgstr "Puede ver información de la base de datos y del sistema." + +#: utility.php:560 utility.php:592 utility.php:869 +#: database_maintenance.php:455 documentation.php:32 patch.php:298 +msgid "Miscellaneous" +msgstr "Herramientas" + +#: utility.php:561 +msgid "" +"You can see the error log and edit db.php file (if necessary) and optimize " +"your database." +msgstr "" +"Puede ver el registro de errores y editar el fichero db.php (si lo necesita) " +"y optimizar su base de datos." + +#: utility.php:564 utility.php:593 utility.php:870 +#: database_maintenance.php:456 documentation.php:33 patch.php:299 +msgid "Patch Utility" +msgstr "Parches" + +#: utility.php:565 +msgid "You can upload patch files and apply them to the incompatible plugins." +msgstr "Puede subir subir parches y aplicarlos a los plugins incompatibles." + +#: utility.php:568 utility.php:594 utility.php:871 +#: database_maintenance.php:457 documentation.php:34 patch.php:300 +msgid "Maintenance" +msgstr "Mantenimiento" + +#: utility.php:569 +msgid "You can check your database and fix it if needed." +msgstr "Puede revisar su base de datos y repararla si lo necesita." + +#: utility.php:583 utility.php:585 utility.php:774 utility.php:776 +#: database_maintenance.php:446 database_maintenance.php:448 +#: documentation.php:23 documentation.php:25 patch.php:236 patch.php:238 +msgid "You are not allowed to access this page!" +msgstr "No tiene permiso para acceder a esta página." + +#: utility.php:598 +msgid "System Information" +msgstr "Información del sistema" + +#: utility.php:599 +msgid "PHP Informations" +msgstr "Información PHP" + +#: utility.php:604 utility.php:640 +msgid "Items" +msgstr "Elementos" + +#: utility.php:605 +msgid "Description" +msgstr "Descripción" + +#: utility.php:610 +msgid "WordPress Version" +msgstr "Versión de WordPress" + +#: utility.php:614 +msgid "PHP Version" +msgstr "Versión de PHP" + +#: utility.php:618 +msgid "PDO Support" +msgstr "Soporte de PDO" + +#: utility.php:622 +msgid "PDO Drivers" +msgstr "Drivers de PDO" + +#: utility.php:626 +msgid "PDO Driver for SQLite 3.x" +msgstr "Drivers de PDO para SQLite 3.x" + +#: utility.php:630 +msgid "SQLite Library Version" +msgstr "Versión de la librería de SQLite" + +#: utility.php:636 +msgid "Your Database Status" +msgstr "Estado de su base de datos" + +#: utility.php:641 +msgid "Status" +msgstr "Estado" + +#: utility.php:647 +msgid "Database Size" +msgstr "Tamaño de la base de datos" + +#: utility.php:651 +msgid "Page Size" +msgstr "Tamaño de la página" + +#: utility.php:655 +msgid "Total Number of Pages" +msgstr "Número total de páginas" + +#: utility.php:659 +msgid "Unused Page" +msgstr "Páginas no usadas" + +#: utility.php:663 +msgid "Integrity Check" +msgstr "Integridad" + +#: utility.php:667 +msgid "Encoding" +msgstr "Codificación" + +#: utility.php:671 +msgid "Collations" +msgstr "Clasificaciones" + +#: utility.php:683 +msgid "Compile Options" +msgstr "Opciones de compilado" + +#: utility.php:697 +msgid "Database Tables and Indexes" +msgstr "Tablas e indexados de la base de datos" + +#: utility.php:699 +msgid "" +"Table names in brown are required by WordPress, and those in blue are " +"created by some plugins. The table sqlite_sequence is not a WordPress table " +"but a table required by SQLite to store the current autoincremented value of " +"each table, which is displayed in the parenthesis after the table names. You " +"can't manipulate the tables or indexes here. Please use SQLite utilities (e." +"g. SQLiteManager)." +msgstr "" +"Los nombres de tabla en marrón son requeridos por WordPress, y los azules " +"son creados por otros plugins. La tabla sqlite_sequence no es una tabla de " +"WordPress pero es requerida por SQLite para almacenar el actual valor " +"autoincrementado de cada tabla, el cual es indicado en el paréntesis después " +"de los nombres de tabla. No puede manipular las tablas o indexados aquí. Por " +"favor utilice utilidades SQLite (por ejemplo SQLiteManager)." + +#: utility.php:704 +msgid "Table Name" +msgstr "Nombre de la tabla" + +#: utility.php:705 +msgid "System/User" +msgstr "Sistema/usuario" + +#: utility.php:706 +msgid "Index ( Column )" +msgstr "Indexado ( Columna )" + +#: utility.php:744 +msgid "Plugin Info" +msgstr "Información del plugin" + +#: utility.php:746 +msgid "This table shows plugins you have installed and their compatibility." +msgstr "" +"Esta tabla muestra los plugins que tiene instalados y su compatibilidad." + +#: utility.php:751 +msgid "Installed Plugins" +msgstr "Plugins instalados" + +#: utility.php:752 +msgid "Active/Inactive" +msgstr "Activo/Inactivo" + +#: utility.php:753 +msgid "Compatible" +msgstr "Compatible" + +#: utility.php:761 +msgid "" +"\"Checked*\" with an asterisk is from the users' information. I didn't check " +"myself yet. If you found any malfunctioning, please let me know." +msgstr "" +"\"Revisado*\" con un asterisco es desde la información de los usuarios. No " +"ha sido revisado oficialmente aún. Si encuentra cualquier mal " +"funcionamiento, por favor, repórtelo." + +#: utility.php:781 +msgid "Log cleared" +msgstr "Registro limpiado" + +#: utility.php:784 +msgid "Log not cleared" +msgstr "Registro no limpiado" + +#: utility.php:796 +msgid "db.php was saved" +msgstr "db.php fue guardado" + +#: utility.php:799 +msgid "Error! db.php couldn't be saved" +msgstr "Error: db.php no pudo ser guardado" + +#: utility.php:810 +#, php-format +msgid "" +"Optimization finished. Before optimization: %1$s, After optimization: %2$s." +msgstr "" +"Optimización finalizada. Antes de la optimización: %1$s, después: %2$s." + +#: utility.php:813 +msgid "Optimization failed" +msgstr "Optimización fallida" + +#: utility.php:821 +msgid "Couldn't find your database file." +msgstr "No se pudo encontrar su fichero de base de datos." + +#: utility.php:833 +msgid "Please select backup file(s)." +msgstr "Por favor, seleccione el/los fichero(s) de respaldo." + +#: utility.php:842 +msgid "Error! Please remove file(s) manyally." +msgstr "Error: Por favor elimine el/los fichero(s) manualmente." + +#: utility.php:853 +msgid "Please select backup file." +msgstr "Por favor selecciones fichero de respaldo." + +#: utility.php:856 +msgid "Please select one file at a time." +msgstr "Por favor selecciones un fichero cada vez." + +#: utility.php:875 +msgid "Database Optimization, Error Log, Init File" +msgstr "Optimización de la base de datos, registro de errores, fichero inicial" + +#: utility.php:876 +msgid "Optimize You Database" +msgstr "Optimice su base de datos" + +#: utility.php:878 +msgid "" +"This button sends "vacuum" command to your SQLite database. That " +"command reclaims space after data has been deleted." +msgstr "" +"Este botón envía el comando "vacuum" a tu base de datos SQLite. " +"Este comando recupera el espacio que queda después de que se hayan eliminado " +"datos." + +#: utility.php:886 +msgid "Optimize" +msgstr "Optimizar" + +#: utility.php:886 +msgid "" +"Are you sure to optimize your database?\\n\\nClick [Cancel] to stop, [OK] to " +"continue." +msgstr "" +"¿Seguro que desea optimizar su base de datos?\\n\\nHaga clic en [Cancelar] " +"para detener, o en [OK] para continuar." + +#: utility.php:889 +msgid "Create or Delete backup file(s)" +msgstr "Crear o eliminar fichero(s) de respaldo" + +#: utility.php:891 +msgid "" +"Click the backup button below if you want to create a current snapshot of " +"your database file. The backup file is named ‘DB_FILE_NAME.yyyymmdd." +"zip’ if PHP zip extension is loaded or ‘DB_FILE_NAME.yyyymmdd." +"back’ if not loaded, and is put in the same directory that the " +"database is in." +msgstr "" +"Haga clic en el siguiente botón si desea crear una imagen de su fichero de " +"base de datos. El fichero de respaldo es nombrado ‘" +"NOMBRE_DE_LA_BASE_DE_DATOS.aaaammdd.zip’ si la extensión zip de PHP " +"está cargada o ‘NOMBRE_DE_LA_BASE_DE_DATOS.aaaammdd.back’ si no " +"lo está, y es guardado en el mismo directorio en el que está la base de " +"datos." + +#: utility.php:894 +msgid "" +"If you want to delete the file(s), check the file name and click the Delete " +"button. You can check multiple files." +msgstr "" +"Si desea eliminar el/los fichero(s), marque el nombre del fichero y haga " +"clic en el botón Eliminar. Puede marcar múltiples ficheros." + +#: utility.php:897 +msgid "" +"If you want to download a file, check the file name and click the Download " +"button. Please check one file at a time." +msgstr "" +"Si desea descargar un fichero, márquelo y haga clic en el botón Descargar. " +"Por favor, marque un sólo fichero a la vez." + +#: utility.php:908 +msgid "Delete/Download" +msgstr "Eliminar/descargar" + +#: utility.php:909 +msgid "Backup Files" +msgstr "Respaldar ficheros" + +#: utility.php:924 +msgid "Backup" +msgstr "Respaldar" + +#: utility.php:924 +msgid "" +"Are you sure to make a backup file?\\n\\nClick [Cancel] to stop, [OK] to " +"continue." +msgstr "" +"¿Seguro que desea crear un fichero de respaldo?\\n\\nHaga clic en [Cancelar] " +"para detener, o en [OK] para continuar." + +#: utility.php:925 patch.php:399 +msgid "Delete file" +msgstr "Eliminar fichero" + +#: utility.php:925 +msgid "" +"Are you sure to delete backup file(s)?\\n\\nClick [Cancel] to stop, [OK] to " +"continue." +msgstr "" +"¿Seguro que desea eliminar el/los fichero(s) de respaldo?\\n\\nHaga clic en " +"[Cancelar] para detener, o en [OK] para continuar." + +#: utility.php:926 +msgid "Download" +msgstr "Descargar" + +#: utility.php:926 +msgid "" +"Are you sure to download backup file?\\n\\nClick [Cancel] to stop, [OK] to " +"continue." +msgstr "" +"¿Seguro \tque desea descargar el fichero de respaldo?\\n\\nHaga clic en " +"[Cancelar] para detener, o en [OK] para continuar." + +#: utility.php:929 +msgid "SQLite Integration Error Log" +msgstr "Registro de errores de SQLite Integration" + +#: utility.php:931 +msgid "" +"This is the contents of SQLite Integration error log file(default: wp-" +"content/database/debug.txt). If you want to clear this file, click the Clear " +"Log button." +msgstr "" +"Esto es el contenido del fichero de registro de errores de SQLite " +"Integration (predeterminado: wp-content/database/debug.txt). Si desea " +"limpiar este fichero, haga clic en el botón Limpiar registro." + +#: utility.php:941 +msgid "No error messages are found" +msgstr "No se han encontrado mensajes de error" + +#: utility.php:949 +msgid "Clear Log" +msgstr "Limpiar registro" + +#: utility.php:949 +msgid "" +"Are you sure to clear Log?\\n\\nClick [Cancel] to stop, [OK] to continue." +msgstr "" +"¿Seguro que desea limpiar el registro?\\n\\nHaga clic en [Cancelar] para " +"detener, o en [OK] para continuar." + +#: utility.php:953 +msgid "Edit Initial File (wp-content/db.php)" +msgstr "Editar fichero inicial (wp-content/db.php)" + +#: utility.php:955 +msgid "" +"When you go "Plugins » Edit Plugin" page, you can edit " +"plugin source file. But you can't see this file there because it is not in " +"the plugin directory. If you need to edit this file, you can edit here. This " +"settings may cause problems. If you don't understand " +"well, please don't edit this file." +msgstr "" +"Cuando usted va a la página "Plugins » Editar", puede editar " +"el código del fichero del plugin. Pero no puede ver este fichero porque no " +"está en el directorio del plugin. Si necesita editar este fichero, puede " +"hacerlo aquí. Estos ajustes pueden causar problemas. Si no está seguro, por favor absténgase de editar este fichero." + +#: utility.php:965 +msgid "Save" +msgstr "Guardar" + +#: utility.php:965 +msgid "" +"Are you sure to save this file?\\n\\nClick [Cancel] to stop, [OK] to " +"continue." +msgstr "" +"¿Seguro que desea guardar este fichero?\\n\\nHaga clic en [Cancelar] para " +"detener, o en [OK] para continuar." + +#: utility.php:1049 +msgid "Update db.php" +msgstr "Actualizar db.php" + +#: utility.php:1050 +msgid "Replace the old db.php with the new one." +msgstr "Reemplaza el viejo db.php con el nuevo." + +#: utility.php:1056 +msgid "Update" +msgstr "Actualizar" + +#: utility.php:1056 +msgid "" +"Are you sure to update this file?\n" +"\n" +"Click [Cancel] to stop, [OK] to continue." +msgstr "" +"¿Seguro que desea actualizar este fichero?\\n\\nHaga clic en [Cancelar] para " +"detener, o en [OK] para continuar." + +#: database_maintenance.php:344 +msgid "Can't create backup file." +msgstr "No se puede crear el fichero de respaldo." + +#: database_maintenance.php:363 +msgid "Failed: " +msgstr "Fallo:" + +#: database_maintenance.php:368 database_maintenance.php:561 +msgid "Your database is OK. You don't have to restore it." +msgstr "Su base de datos está bien. No necesita restaurarla." + +#: database_maintenance.php:372 +msgid "Your database restoration is successfully finished!" +msgstr "La restauración de su base de datos finalizó correctamente." + +#: database_maintenance.php:391 +msgid "Table name is not selected." +msgstr "El nombre de la tabla no está seleccionado." + +#: database_maintenance.php:394 +msgid "There's no such table." +msgstr "No existe dicha tabla." + +#: database_maintenance.php:461 +msgid "Database Maintenace" +msgstr "Mantenimiento de la base de datos" + +#: database_maintenance.php:462 +msgid "Important Notice" +msgstr "Aviso importante" + +#: database_maintenance.php:464 +msgid "" +"When you installed WordPress 3.5.x with SQLite Integration and upgraded to " +"3.6, your database might not function as expected." +msgstr "" +"Si instaló WordPress 3.5.x con SQLite Integration y actualizó a 3.6, su base " +"de datos podría no funcionar como esperaba." + +#: database_maintenance.php:465 +msgid "" +"This page provide you the database sanity check utility and the restore " +"utility." +msgstr "" +"Esta página le provee la utilidad de revisión del estado de su base de datos " +"y la utilidad de restauración." + +#: database_maintenance.php:468 +msgid "" +"Click \"Sanity Check\" button first, and see if you need to fix database or " +"not. If needed, click \"Fix Database\" button. Afterward you may go to " +"Miscellaneous page and optimize database (this is not required)." +msgstr "" +"Haga clic en el botón \"Revisar estado\" primero, y vea si necesita reparar " +"la base de datos o no. Si es necesario, haga clic en el botón \"Reparar base " +"de datos\". Después de esto, puede ir a la página Herramientas y optimizar " +"la base de datos (esto no es requerido)." + +#: database_maintenance.php:471 +msgid "" +"Fix Database procedure will create a database backup file each time the " +"button clicked. The backup file is named with \"maintenance-backup\", so you " +"can remove it if you don't need it. Please go to Miscellaneous page and " +"check if there is one." +msgstr "" +"Al reparar la base de datos se creará un fichero de respaldo que será " +"llamado \"maintenance-backup\", luego usted puede eliminarlo si no lo " +"necesita. Por favor, vaya a la página Herramientas y revíselo." + +#: database_maintenance.php:474 +msgid "" +"If you installed WordPress 3.6 (not upgraded), you don't have to restore the " +"database." +msgstr "" +"Si usted instaló WordPress 3.6 (no actualizó), no tiene que restaurar la " +"base de datos." + +#: database_maintenance.php:483 +msgid "Sanity Check" +msgstr "Revisar estado" + +#: database_maintenance.php:483 +msgid "" +"Are you sure to check the database? This will take some time.\\n\\nClick " +"[Cancel] to stop, [OK] to continue." +msgstr "" +"¿Seguro que desea revisar el estado de la base de datos? Esto llevará algún " +"tiempo.\\n\\nHaga clic en [Cancelar] para detener, o en [OK] para continuar." + +#: database_maintenance.php:484 +msgid "Fix database" +msgstr "Reparar base de datos" + +#: database_maintenance.php:484 +msgid "" +"Are you sure to do fix the database? This will take some time.\\n\\nClick " +"[Cancel] to stop, [OK] to continue." +msgstr "" +"¿Seguro que desea reparar la base de datos? Esto tomará algún tiempo.\\n" +"\\nHaga clic en [Cancelar] para detener, o en [OK] para continuar." + +#: database_maintenance.php:488 +msgid "Columns Information" +msgstr "Información de columnas" + +#: database_maintenance.php:490 +msgid "" +"Select a table name and click \"Display Columns\" button, and you'll see the " +"column property of that table. This information is for debug use." +msgstr "" +"Seleccione un nombre de tabla y haga clic en el botón \"Mostrar columnas\", " +"y usted verá la columna de propiedades de esa tabla. Esta información es " +"para uso de depuración." + +#: database_maintenance.php:501 +msgid "Table Name: " +msgstr "Nombre de la tabla:" + +#: database_maintenance.php:507 +msgid "Display Columns" +msgstr "Mostrar columnas" + +#: database_maintenance.php:507 +msgid "" +"Display columns in the selected table.\\n\\nClick [Cancel] to stop, [OK] to " +"continue." +msgstr "" +"Mostrar columnas en la tabla seleccionada.\\n\\nHaga clic en [Cancelar] para " +"detener, o en [OK] para continuar." + +#: database_maintenance.php:517 database_maintenance.php:519 +#: database_maintenance.php:543 database_maintenance.php:545 +#: database_maintenance.php:571 database_maintenance.php:573 patch.php:243 +#: patch.php:245 patch.php:265 patch.php:267 patch.php:287 patch.php:289 +msgid "You are not allowed to do this operation!" +msgstr "No tiene permitido hacer esta operación." + +#: database_maintenance.php:523 database_maintenance.php:533 +msgid "Results" +msgstr "Resultados" + +#: database_maintenance.php:549 database_maintenance.php:560 +msgid "Checked Results" +msgstr "Resultados de la revisión" + +#: database_maintenance.php:554 +msgid " needs restoring." +msgstr " necesita restauración." + +#: database_maintenance.php:577 +#, php-format +msgid "Columns In %s" +msgstr "Columnas %s" + +#: database_maintenance.php:578 +msgid "Column" +msgstr "Columna" + +#: database_maintenance.php:579 +msgid "Type" +msgstr "Tipo" + +#: database_maintenance.php:580 +msgid "Null" +msgstr "Nulo" + +#: database_maintenance.php:581 +msgid "Default" +msgstr "Predeterminado" + +#: database_maintenance.php:598 +msgid "Columns Info" +msgstr "Información de columnas" + +#: documentation.php:40 +msgid "" +"This is a brief documentation about this plugin. For more details, see also " +"the SQLite " +"Integration page." +msgstr "" +"Esta es una breve documentación sobre este plugin. Para más detalle, vea " +"también la página de SQLite Integration." + +#: documentation.php:43 +msgid "" +"Please don't forget: WordPress DOES NOT OFFICIALLY SUPPORT any database " +"other than MySQL. So if you ask about this plugin in the Forum, it's not " +"unlikely that you won't get no answers at all." +msgstr "" +"Por favor, no olvide: WordPress NO SOPORTA OFICIALMENTE ninguna base de " +"datos que no sea MySQL. Así que si usted pregunta acerca de este plugin en " +"el Foro, probablemente no obtenga respuesta." + +#: documentation.php:46 +msgid "Features" +msgstr "Características" + +#: documentation.php:48 +msgid "" +"This plugin is a successor to 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)." +msgstr "" +"Este plugin es un sucesor de PDO for WordPress, el cual habilitaba WordPress " +"para el uso de SQLite para su base de datos. Pero PDO for WordPress parece " +"que no va a tener más mantenimiento. SQLite Integration hace uso de las " +"ideas básicas y framework de PDO for WordPress, añade algunas " +"características nuevas y lo actualiza para hacerlo trabajar con la versión " +"más reciente de WordPress." + +#: documentation.php:51 +msgid "" +"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." +msgstr "" +"La página web de SQLite dice: SQLite " +"es una "biblioteca de software que implementa el motor de bases de " +"datos SQL autocontenido, sin servidor, de configuración cero y " +"transaccional". Esto es "una buena opción para sitios web pequeños " +"y medianos". Es pequeño y potable, y no necesita ningún sistema de " +"servidor de base de datos." + +#: documentation.php:54 +msgid "" +"Unfortunately enough, WordPress only supports MySQL. Consequently it doesn't " +"provide any APIs for SQLite. So if you want to create a website using " +"WordPress without a database server, you've got to write a kind of wrapper " +"program yourself to use SQLite. This is the way SQLite Integration goes." +msgstr "" +"Desgraciadamente, WordPress sólo soporta MySQL. En consecuencia no provee " +"ninguna API para SQLite. Por lo que si busca crear un sitio web usando " +"WordPress sin un servidor de base de datos, tiene que escribir una especie " +"de programa envoltorio usted mismo para usar SQLite. Esto es los que SQLite " +"Integration le ofrece." + +#: documentation.php:57 +msgid "SQLite Integration does the work as follows:" +msgstr "SQLite Integration hace tareas como las siguientes:" + +#: documentation.php:60 +msgid "Intercepts SQL statement for MySQL from WordPress" +msgstr "Intercepta enunciados SQL para MySQL de WordPress" + +#: documentation.php:61 +msgid "Rewrites it as SQLite can execute" +msgstr "Los reescribe para que los pueda ejecutar SQLite" + +#: documentation.php:62 +msgid "Gives it to SQLite" +msgstr "Se los da a SQLite" + +#: documentation.php:63 +msgid "Gets the results from SQLite" +msgstr "Obtiene los resultados de SQLite" + +#: documentation.php:64 +msgid "Format the results as MySQL returns, if necessary" +msgstr "Formatea los resultados como MySQL, si es necesario" + +#: documentation.php:65 +msgid "Gives back the results to WordPress" +msgstr "Devuelve los resultados a WordPress" + +#: documentation.php:68 +msgid "" +"WordPress doesn't know what has happened in the background and will be happy " +"with it." +msgstr "" +"WordPress no sabe qué está pasando en la parte trasera y estará bien así." + +#: documentation.php:71 +msgid "Limitations" +msgstr "Limitaciones" + +#: documentation.php:73 +msgid "" +"SQLite Integration uses SQLite, so the limitations of SQLite is, as it is, " +"those of SQLite Integration. MySQL is far from a simple SQL engine and has " +"many extended features and functionalities. WordPress uses some of them. " +"Among those are some SQLite doesn't implement. For those features that " +"WordPress uses, I made them work with SQLite Integration. But for others " +"that some plugins are using, SQLite Integration can't manipulate. So..." +msgstr "" +"SQLite Integration usa SQLite, por lo que las limitaciones de SQLite son a " +"su vez las de SQLite Integration. MySQL está lejos de un motor SQL simple y " +"tiene muchas características y funcionalidades extendidas, y WordPress usa " +"alguna de ellas, es decir, SQLite no implementa algunas características que " +"tiene MySQL y que WordPress usa. Algunas de estas características, SQLite " +"las consigue hacer funcionar. Pero para otras que algunos plugins están " +"usando, SQLite no puede conseguirlo. Así es que..." + +#: documentation.php:76 +msgid "There are some plugins that you can't use. No way around.We have been unable to "
"connect to the specified database.
The error message received was %s"
msgstr ""
-"
データベースに接続できませんでした。
エラーメッセージは、%sです。"
+"
データベースに接続できません。
エラーメッセージは、%s"
-#: pdoengine.class.php:80 pdoengine.class.php:96 schema.php:26
+#: pdoengine.class.php:82 pdoengine.class.php:98
msgid "Database connection error!
"
msgstr "データベース接続エラー!
"
-#: pdoengine.class.php:81 pdoengine.class.php:97 schema.php:27 schema.php:81
+#: pdoengine.class.php:83 pdoengine.class.php:99
+#, php-format
msgid "Error message is: %s"
-msgstr "エラーメッセージは: "
+msgstr "エラーメッセージ: %s"
-#: pdoengine.class.php:115
-msgid ""
-"Unable to create the required directory! Please check your server settings."
-msgstr ""
-"必要なディレクトリが作成できませんでした。サーバ設定を確認してください。"
-
-#: pdoengine.class.php:120 pdoengine.class.php:126
-msgid ""
-"Unable to create a file in the directory! Please check your server settings."
-msgstr ""
-"ディレクトリにファイルを作成できませんでした。サーバ設定を確認してください。"
-
-#: pdoengine.class.php:148
+#: pdoengine.class.php:156
#, php-format
msgid ""
"
Sorry, we cannot determine the type of query " "that is requested.
The query is %s
" msgstr "" -"申し訳ありません、要求されたクエリのタイプを決定できません。
クエリは%s" -"です。
" +"申し訳ありません。要求されたクエリのタイプを判別できませんでした。
" +"クエリ: %s
" -#: pdoengine.class.php:294 +#: pdoengine.class.php:315 #, php-format msgid "Problem preparing the PDO SQL Statement. Error was: %s" -msgstr "SQLステートメントの準備中に問題。エラーは: %s" +msgstr "PDO SQLステートメントを準備中に問題がありました。エラー: %s" -#: pdoengine.class.php:327 +#: pdoengine.class.php:372 #, php-format msgid "Error while executing query! Error message was: %s" -msgstr "クエリの実行中にエラー! エラーメッセージは: %s" +msgstr "クエリを実行中にエラーが発生しました。エラーメッセージ: %s" -#: pdoengine.class.php:381 +#: pdoengine.class.php:426 msgid "The query is too big to parse properly" -msgstr "クエリが長すぎて解析できません" +msgstr "クエリが長すぎてちゃんと解析できません" -#: pdoengine.class.php:583 +#: pdoengine.class.php:635 #, php-format msgid "Problem in creating table or index. Error was: %s" -msgstr "テーブルまたはインデックスを作成中に問題発生。エラーは: %s" +msgstr "テーブルかインデックスを作るときに問題がありました。エラー: %s" -#: pdoengine.class.php:626 +#: pdoengine.class.php:678 #, php-format msgid "Problem in executing alter query. Error was: %s" -msgstr "ALTERクエリを実行中に問題発生。エラーは: %s" - -#: schema.php:80 -#, php-format -msgid "" -"Error occured while creating tables or indexes...We have been unable to "
"connect to the specified database.
The error message received was %s"
msgstr ""
-#: pdoengine.class.php:80 pdoengine.class.php:96 schema.php:26
-msgid "Database connection error!
"
-msgstr ""
-
-#: pdoengine.class.php:81 pdoengine.class.php:97 schema.php:27 schema.php:81
-msgid "Error message is: %s"
-msgstr ""
-
-#: pdoengine.class.php:115
-msgid ""
-"Unable to create the required directory! Please check your server settings."
-msgstr ""
-
-#: pdoengine.class.php:120 pdoengine.class.php:126
-msgid ""
-"Unable to create a file in the directory! Please check your server settings."
-msgstr ""
-
-#: pdoengine.class.php:148
+#: pdoengine.class.php:291
#, php-format
msgid ""
"
Sorry, we cannot determine the type of query " "that is requested.
The query is %s
" msgstr "" -#: pdoengine.class.php:294 -#, php-format -msgid "Problem preparing the PDO SQL Statement. Error was: %s" -msgstr "" - -#: pdoengine.class.php:327 -#, php-format -msgid "Error while executing query! Error message was: %s" -msgstr "" - -#: pdoengine.class.php:381 -msgid "The query is too big to parse properly" -msgstr "" - -#: pdoengine.class.php:583 -#, php-format -msgid "Problem in creating table or index. Error was: %s" -msgstr "" - -#: pdoengine.class.php:626 -#, php-format -msgid "Problem in executing alter query. Error was: %s" -msgstr "" - -#: schema.php:80 -#, php-format -msgid "" -"Error occured while creating tables or indexes...We have been unable to connect to the specified database.
The error message received was %s"), $this->dbh->errorInfo()));
return;
}
+ $is_enabled_foreign_keys = @$this->get_var('PRAGMA foreign_keys');
+ if ($is_enabled_foreign_keys == '0') @$this->query('PRAGMA foreign_keys = ON');
$this->ready = true;
}
-
/**
- * overrides wpdb::query()
+ * Method to dummy out wpdb::check_connection()
+ *
+ */
+ function check_connection($allow_bail=true) {
+ return true;
+ }
+ /**
+ * 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) {
@@ -179,25 +261,44 @@ 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.
- * @see wpdb::load_col_info()
+ *
*/
- function load_col_info() {
+ private function _do_query($query) {
+ if (defined('SAVEQUERIES') && SAVEQUERIES) {
+ $this->timer_start();
+ }
+ $this->result = $this->dbh->query($query);
+ $this->num_queries++;
+ if (defined('SAVEQUERIES') && SAVEQUERIES) {
+ $this->queries[] = array($query, $this->timer_stop(), $this->get_caller());
+ }
+ }
+ /**
+ * Method to set the class variable $col_info.
+ *
+ * This overrides wpdb::load_col_info(), which uses a mysql function.
+ *
+ * @see wpdb::load_col_info()
+ * @access protected
+ */
+ protected function load_col_info() {
if ($this->col_info)
return;
$this->col_info = $this->dbh->get_columns();
}
/**
- * 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) {
@@ -213,17 +314,22 @@ 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 newest mysql version.
+ *
* @see wpdb::db_version()
*/
function db_version() {
- global $required_mysql_version;
- return $required_mysql_version;
+// global $required_mysql_version;
+// return $required_mysql_version;
+ return '5.5';
}
}
-/**
+/*
* Initialize $wpdb with PDODB class
*/
if (!isset($wpdb)) {
diff --git a/pdoengine.class.php b/pdoengine.class.php
index 6064e2f..5caa6da 100644
--- a/pdoengine.class.php
+++ b/pdoengine.class.php
@@ -1,58 +1,184 @@
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
+ * Method to initialize database, executed in the contructor.
+ *
+ * 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() {
- $dsn = 'sqlite:' . FQDB;
+ $dsn = 'sqlite:' . FQDB;
$result = $this->prepare_directory();
if (!$result) return false;
if (is_file(FQDB)) {
@@ -67,9 +193,9 @@ class PDOEngine extends PDO {
array( // PDO options
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
));
- $statement = $this->pdo->query("SELECT COUNT(*) FROM sqlite_master WHERE type='table'");
+ $statement = $this->pdo->query("SELECT COUNT(*) FROM sqlite_master WHERE type='table'");
$number_of_tables = $statement->fetchColumn(0);
- $statement = null;
+ $statement = null;
if ($number_of_tables == 0) {
$this->make_sqlite_tables();
}
@@ -80,8 +206,8 @@ class PDOEngine extends PDO {
if ($status == 5 || $status == 6) {
$locked = true;
} else {
- $message = __("Database connection error!
", 'sqlite-integration');
- $message .= sprintf(__("Error message is: %s", 'sqlite-integration'), $err->getMessage());
+ $message = 'Database connection error!
';
+ $message .= sprintf("Error message is: %s", $err->getMessage());
$this->set_error(__LINE__, __FUNCTION__, $message);
return false;
}
@@ -96,8 +222,8 @@ class PDOEngine extends PDO {
try {
$this->pdo = new PDO($dsn, null, null, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch (PDOException $err) {
- $message = __("Database connection error!
", 'sqlite-integration');
- $message .= sprintf(__("Error message is: %s", 'sqlite-integration'), $err->getMessage());
+ $message = 'Database initialization error!
';
+ $message .= sprintf("Error message is: %s", $err->getMessage());
$this->set_error(__LINE__, __FUNCTION__, $message);
return false;
}
@@ -106,62 +232,108 @@ class PDOEngine extends PDO {
}
/**
- * Make database direcotry and .htaccess file
- * executed once while installation process
+ * This method makes database direcotry and .htaccess file.
+ *
+ * It is executed only once when the installation begins.
*/
private function prepare_directory() {
global $wpdb;
$u = umask(0000);
if (!is_dir(FQDBDIR)) {
- if (!@mkdir(FQDBDIR, 0777, true)) {
+ if (!@mkdir(FQDBDIR, 0707, true)) {
umask($u);
- $message = __('Unable to create the required directory! Please check your server settings.', 'sqlite-integration');
- echo $message;
- return false;
+ $message = 'Unable to create the required directory! Please check your server settings.';
+ wp_die($message, 'Error!');
}
}
if (!is_writable(FQDBDIR)) {
umask($u);
- $message = __('Unable to create a file in the directory! Please check your server settings.', 'sqlite-integration');
- echo $message;
- return false;
+ $message = 'Unable to create a file in the directory! Please check your server settings.';
+ wp_die($message, 'Error!');
}
if (!is_file(FQDBDIR . '.htaccess')) {
$fh = fopen(FQDBDIR . '.htaccess', "w");
if (!$fh) {
umask($u);
- $message = __('Unable to create a file in the directory! Please check your server settings.', 'sqlite-integration');
+ $message = 'Unable to create a file in the directory! Please check your server settings.';
echo $message;
return false;
}
- fwrite($fh, "DENY FROM ALL");
+ fwrite($fh, 'DENY FROM ALL');
fclose($fh);
}
+ if (!is_file(FQDBDIR . 'index.php')) {
+ $fh = fopen(FQDBDIR . 'index.php', "w");
+ if (!$fh) {
+ umask($u);
+ $message = 'Unable to create a file in the directory! Please check your server settings.';
+ echo $message;
+ return false;
+ }
+ fwrite($fh, '');
+ fclose($fh);
+ }
umask($u);
return true;
}
/**
- * Make database file itself and WordPress tables
- * executed once while installation process
+ * Method 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";
+ require_once PDODIR . 'install.php';
}
-
+ /**
+ * Method to execute query().
+ *
+ * Divide the query types into seven different ones. That is to say:
+ *
+ * 1. SELECT SQL_CALC_FOUND_ROWS
+ * 2. INSERT
+ * 3. CREATE TABLE(INDEX)
+ * 4. ALTER TABLE
+ * 5. SHOW VARIABLES
+ * 6. DROP INDEX
+ * 7. THE OTHERS
+ *
+ * #1 is just a tricky play. See the private function handle_sql_count() in query.class.php.
+ * From #2 through #5 call different functions respectively.
+ * #6 call the ALTER TABLE query.
+ * #7 is a normal process: sequentially call prepare_query() and execute_query().
+ *
+ * #1 process has been changed since version 1.5.1.
+ *
+ * @param $query full SQL statement string
+ * @return mixed according to the query type
+ * @see PDO::query()
+ */
public function query($query) {
$this->flush();
- $this->queries[] = "Raw query:\t$query";
+ $this->queries[] = "Raw query:\n$query";
$res = $this->determine_query_type($query);
- if (!$res) {
+ if (!$res && defined(PDO_DEBUG) && PDO_DEBUG) {
$bailoutString = sprintf(__("
Sorry, we cannot determine the type of query that is requested.
The query is %s
", 'sqlite-integration'), $query); $this->set_error(__LINE__, __FUNCTION__, $bailoutString); } switch (strtolower($this->query_type)) { + case 'set': + $this->return_value = false; + break; 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 = $this->found_rows_result; + $_column['FOUND_ROWS()'] = $this->num_rows; +// 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) { @@ -181,12 +353,15 @@ class PDOEngine extends PDO { case 'show_variables': $result = $this->show_variables_workaround($query); break; + case 'showstatus': + $result = $this->show_status_workaround($query); + break; case 'drop_index': $pattern = '/^\\s*(DROP\\s*INDEX\\s*.*?)\\s*ON\\s*(.*)/im'; if (preg_match($pattern, $query, $match)) { - $drop_query = 'ALTER TABLE ' . trim($match[2]) . ' ' . trim($match[1]); - $this->query_type = 'alter'; - $result = $this->execute_alter_query($drop_query); + $drop_query = 'ALTER TABLE ' . trim($match[2]) . ' ' . trim($match[1]); + $this->query_type = 'alter'; + $result = $this->execute_alter_query($drop_query); $this->return_value = $result; } else { $this->return_value = false; @@ -195,7 +370,7 @@ class PDOEngine extends PDO { default: $engine = $this->prepare_engine($this->query_type); $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); - $this->queries[] = "Rewritten: $this->rewritten_query"; + $this->queries[] = "Rewritten:\n$this->rewritten_query"; $this->extract_variables(); $statement = $this->prepare_query(); $this->execute_query($statement); @@ -207,33 +382,114 @@ 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; } - + /** + * Method to return inserted row id. + * + * @return unsigned integer + */ public function get_insert_id() { return $this->last_insert_id; } + /** + * Method to return the number of rows affected. + * + * @return unsigned integer + */ public function get_affected_rows() { return $this->affected_rows; } + /** + * Method to return the queried column names. + * + * These data are meaningless for SQLite. So they are dummy emulating + * MySQL columns data. + * + * @return array of the object + */ public function get_columns() { - return $this->column_names; + if (!empty($this->results)) { + $primary_key = array( + 'meta_id', 'comment_ID', 'link_ID', 'option_id', + 'blog_id', 'option_name', 'ID', 'term_id', 'object_id', + 'term_taxonomy_id', 'umeta_id', 'id'); + $unique_key = array('term_id', 'taxonomy', 'slug'); + $data = array( + 'name' => '', // column name + 'table' => '', // table name + 'max_length' => 0, // max length of the column + 'not_null' => 1, // 1 if not null + 'primary_key' => 0, // 1 if column has primary key + 'unique_key' => 0, // 1 if column has unique key + 'multiple_key' => 0, // 1 if column doesn't have unique key + 'numeric' => 0, // 1 if column has numeric value + 'blob' => 0, // 1 if column is blob + 'type' => '', // type of the column + 'unsigned' => 0, // 1 if column is unsigned integer + 'zerofill' => 0 // 1 if column is zero-filled + ); + if (preg_match("/\s*FROM\s*(.*)?\s*/i", $this->rewritten_query, $match)) { + $table_name = trim($match[1]); + } else { + $table_name = ''; + } + foreach ($this->results[0] as $key => $value) { + $data['name'] = $key; + $data['table'] = $table_name; + if (in_array($key, $primary_key)) { + $data['primary_key'] = 1; + } elseif (in_array($key, $unique_key)) { + $data['unique_key'] = 1; + } else { + $data['multiple_key'] = 1; + } + $this->column_data[] = new ObjectArray($data); + $data['name'] = ''; + $data['table'] = ''; + $data['primary_key'] = 0; + $data['unique_key'] = 0; + $data['multiple_key'] = 0; + } + return $this->column_data; + } else { + return null; + } } + /** + * Method to return the queried result data. + * + * @return mixed + */ public function get_query_results() { return $this->results; } + /** + * Method to return the number of rows from the queried result. + * + * @return unsigned integer + */ public function get_num_rows() { return $this->num_rows; } + /** + * Method to return the queried results according to the query types. + * + * @return mixed + */ public function get_return_value() { return $this->return_value; } - + /** + * Method to return error messages. + * + * @return string + */ public function get_error_message(){ if (count($this->error_messages) === 0){ - $this->is_error = false; + $this->is_error = false; $this->error_messages = array(); return ''; } @@ -253,20 +509,26 @@ class PDOEngine extends PDO { ob_start(); debug_print_backtrace(); - $output .= "" . ob_get_contents() . ""; + $output .= '
' . ob_get_contents() . ''; ob_end_clean(); return $output; } - + /** + * Method 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; } - + /** + * Method to clear previous data. + */ private function flush(){ $this->rewritten_query = ''; $this->query_type = ''; @@ -274,7 +536,7 @@ class PDOEngine extends PDO { $this->_results = null; $this->last_insert_id = null; $this->affected_rows = null; - $this->column_names = array(); + $this->column_data = array(); $this->num_rows = null; $this->return_value = null; $this->extracted_variables = array(); @@ -283,7 +545,15 @@ class PDOEngine extends PDO { $this->queries = array(); $this->param_num = 0; } - + /** + * Method 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'; @@ -297,35 +567,48 @@ class PDOEngine extends PDO { } return $engine; } - + /** + * Method to create a PDO statement object from the query string. + * + * @return PDOStatement + */ private function prepare_query(){ - $this->queries[] = "Prepare:\t". $this->prepared_query; - $reason = 0; - $message = ''; - $statement = null; + $this->queries[] = "Prepare:\n" . $this->prepared_query; + $reason = 0; + $message = ''; + $statement = null; do { try { $statement = $this->pdo->prepare($this->prepared_query); } catch (PDOException $err) { - $reason = $err->getCode(); + $reason = $err->getCode(); $message = $err->getMessage(); } } while (5 == $reason || 6 == $reason); if ($reason > 0){ - $err_message = sprintf(__("Problem preparing the PDO SQL Statement. Error was: %s", 'sqlite-integration'), $message); + $err_message = sprintf("Problem preparing the PDO SQL Statement. Error was: %s", $message); $this->set_error(__LINE__, __FUNCTION__, $err_message); } return $statement; } - + /** + * Method 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; + $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); + $this->queries[] = "Executing:\n" . var_export($this->extracted_variables, true); do { if ($this->query_type == 'update' || $this->query_type == 'replace') { try { @@ -333,7 +616,7 @@ class PDOEngine extends PDO { $statement->execute($this->extracted_variables); $this->commit(); } catch (PDOException $err) { - $reason = $err->getCode(); + $reason = $err->getCode(); $message = $err->getMessage(); $this->rollBack(); } @@ -341,13 +624,13 @@ class PDOEngine extends PDO { try { $statement->execute($this->extracted_variables); } catch (PDOException $err) { - $reason = $err->getCode(); + $reason = $err->getCode(); $message = $err->getMessage(); } } } while (5 == $reason || 6 == $reason); } else { - $this->queries[] = "Executing: (no parameters)\t "; + $this->queries[] = 'Executing: (no parameters)'; do{ if ($this->query_type == 'update' || $this->query_type == 'replace') { try { @@ -355,7 +638,7 @@ class PDOEngine extends PDO { $statement->execute(); $this->commit(); } catch (PDOException $err) { - $reason = $err->getCode(); + $reason = $err->getCode(); $message = $err->getMessage(); $this->rollBack(); } @@ -363,14 +646,14 @@ class PDOEngine extends PDO { try { $statement->execute(); } catch (PDOException $err) { - $reason = $err->getCode(); + $reason = $err->getCode(); $message = $err->getMessage(); } } } while (5 == $reason || 6 == $reason); } if ($reason > 0) { - $err_message = sprintf(__("Error while executing query! Error message was: %s", 'sqlite-integration'), $message); + $err_message = sprintf("Error while executing query! Error message was: %s", $message); $this->set_error(__LINE__, __FUNCTION__, $err_message); return false; } else { @@ -378,32 +661,34 @@ class PDOEngine extends PDO { } //generate the results that $wpdb will want to see switch ($this->query_type) { - case "insert": - case "update": - case "replace": + case 'insert': + case 'update': + case 'replace': $this->last_insert_id = $this->pdo->lastInsertId(); - $this->affected_rows = $statement->rowCount(); - $this->return_value = $this->affected_rows; + $this->affected_rows = $statement->rowCount(); + $this->return_value = $this->affected_rows; break; - case "select": - case "show": - case "showcolumns": - case "showindex": - case "describe": - case "desc": + case 'select': + case 'show': + case 'showcolumns': + case 'showindex': + case 'describe': + case 'desc': + case 'check': + case 'analyze': // case "foundrows": - $this->num_rows = count($this->_results); + $this->num_rows = count($this->_results); $this->return_value = $this->num_rows; break; - case "delete": + case 'delete': $this->affected_rows = $statement->rowCount(); - $this->return_value = $this->affected_rows; + $this->return_value = $this->affected_rows; break; - case "alter": - case "drop": - case "create": - case "optimize": - case "truncate": + case 'alter': + case 'drop': + case 'create': + case 'optimize': + case 'truncate': if ($this->is_error) { $this->return_value = false; } else { @@ -412,19 +697,26 @@ class PDOEngine extends PDO { break; } } - + /** + * Method 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 $pattern = '/(? 10000000) { - $message = __("The query is too big to parse properly", 'sqlite-integration'); + $message = 'The query is too big to parse properly'; $this->set_error(__LINE__, __FUNCTION__, $message); break; //no point in continuing execution, would get into a loop } else { @@ -436,10 +728,15 @@ class PDOEngine extends PDO { //reset the pcre.backtrack_limist ini_set('pcre.backtrack_limit', $_limit); - $this->queries[]= "With Placeholders: $query "; + $this->queries[] = "With Placeholders:\n" . $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]); @@ -463,13 +760,16 @@ 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 + * Method 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 */ private function determine_query_type($query) { - $result = preg_match('/^\\s*(EXPLAIN|PRAGMA|SELECT\\s*FOUND_ROWS|SELECT|INSERT|UPDATE|REPLACE|DELETE|ALTER|CREATE|DROP\\s*INDEX|DROP|SHOW\\s*\\w+\\s*\\w+\\s*|DESCRIBE|DESC|TRUNCATE|OPTIMIZE)/i', $query, $match); + $result = preg_match('/^\\s*(SET|EXPLAIN|PRAGMA|SELECT\\s*FOUND_ROWS|SELECT|INSERT|UPDATE|REPLACE|DELETE|ALTER|CREATE|DROP\\s*INDEX|DROP|SHOW\\s*\\w+\\s*\\w+\\s*|DESCRIBE|DESC|TRUNCATE|OPTIMIZE|CHECK|ANALYZE)/i', $query, $match); if (!$result) { return false; @@ -479,9 +779,11 @@ class PDOEngine extends PDO { $this->query_type = 'foundrows'; } if (stripos($this->query_type, 'show') !== false) { - if (stripos($this->query_type, 'show tables') !== false) { + if (stripos($this->query_type, 'show table status') !== false) { + $this->query_type = 'showstatus'; + } elseif (stripos($this->query_type, 'show tables') !== false || stripos($this->query_type, 'show full tables') !== false) { $this->query_type = 'show'; - } elseif (stripos($this->query_type, 'show columns') !== false || stripos($this->query_type, 'show fields') !== false) { + } elseif (stripos($this->query_type, 'show columns') !== false || stripos($this->query_type, 'show fields') !== false || stripos($this->query_type, 'show full columns') !== false) { $this->query_type = 'showcolumns'; } elseif (stripos($this->query_type, 'show index') !== false || stripos($this->query_type, 'show indexes') !== false || stripos($this->query_type, 'show keys') !== false) { $this->query_type = 'showindex'; @@ -498,30 +800,37 @@ class PDOEngine extends PDO { } /** - * SQLite version 3.7.11 began support multiple rows insert with values + * Method 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) { - $engine = $this->prepare_engine($this->query_type); + $engine = $this->prepare_engine($this->query_type); $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); - $this->queries[] = "Rewritten: $this->rewritten_query"; + $this->queries[] = "Rewritten:\n" . $this->rewritten_query; $this->extract_variables(); - $statement = $this->prepare_query(); + $statement = $this->prepare_query(); $this->execute_query($statement); } /** - * executes the INSERT query for SQLite version 3.7.10 or lesser + * Method 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) { global $wpdb; $multi_insert = false; - $statement = null; - $engine = $this->prepare_engine($this->query_type); + $statement = null; + $engine = $this->prepare_engine($this->query_type); if (preg_match('/(INSERT.*?VALUES\\s*)(\(.*\))/imsx', $query, $matched)) { $query_prefix = $matched[1]; - $values_data = $matched[2]; + $values_data = $matched[2]; if (stripos($values_data, 'ON DUPLICATE KEY') !== false) { $exploded_parts = $values_data; } elseif (stripos($query_prefix, "INSERT INTO $wpdb->comments") !== false) { @@ -542,9 +851,9 @@ class PDOEngine extends PDO { } else { $suffix = ')'; } - $query_string = $query_prefix . ' ' . $value . $suffix; - $this->rewritten_query = $engine->rewrite_query($query_string, $this->query_type); - $this->queries[] = "Rewritten: $this->rewritten_query"; + $query_string = $query_prefix . ' ' . $value . $suffix; + $this->rewritten_query = $engine->rewrite_query($query_string, $this->query_type); + $this->queries[] = "Rewritten:\n" . $this->rewritten_query; $this->extracted_variables = array(); $this->extract_variables(); if ($first) { @@ -557,7 +866,7 @@ class PDOEngine extends PDO { } } else { $this->rewritten_query = $engine->rewrite_query($query, $this->query_type); - $this->queries[] = "Rewritten: $this->rewritten_query"; + $this->queries[] = "Rewritten:\n" . $this->rewritten_query; $this->extract_variables(); $statement = $this->prepare_query(); $this->execute_query($statement); @@ -565,7 +874,10 @@ class PDOEngine extends PDO { } /** - * helper function for execute_insert_query() + * Method to help rewriting multiple row values insert query. + * + * It splits the values clause into an array to execute separately. + * * @param string $values * @return array */ @@ -604,27 +916,28 @@ class PDOEngine extends PDO { } /** - * function to execute CREATE query + * Method to execute CREATE query. + * * @param string * @return boolean */ private function execute_create_query($query) { - $engine = $this->prepare_engine($this->query_type); + $engine = $this->prepare_engine($this->query_type); $rewritten_query = $engine->rewrite_query($query); - $reason = 0; - $message = ''; + $reason = 0; + $message = ''; // $queries = explode(";", $this->rewritten_query); try { $this->beginTransaction(); foreach ($rewritten_query as $single_query) { - $this->queries[] = "Executing:\t" . $single_query; - $single_query = trim($single_query); + $this->queries[] = "Executing:\n" . $single_query; + $single_query = trim($single_query); if (empty($single_query)) continue; $this->pdo->exec($single_query); } $this->commit(); } catch (PDOException $err) { - $reason = $err->getCode(); + $reason = $err->getCode(); $message = $err->getMessage(); if (5 == $reason || 6 == $reason) { $this->commit(); @@ -633,40 +946,45 @@ class PDOEngine extends PDO { } } if ($reason > 0) { - $err_message = sprintf(__("Problem in creating table or index. Error was: %s", 'sqlite-integration'), $message); + $err_message = sprintf("Problem in creating table or index. Error was: %s", $message); $this->set_error(__LINE__, __FUNCTION__, $err_message); return false; } return true; } - /** - * function to execute ALTER TABLE query + * Method to execute ALTER TABLE query. + * * @param string * @return boolean */ private function execute_alter_query($query) { - $engine = $this->prepare_engine($this->query_type); - $reason = 0; - $message = ''; + $engine = $this->prepare_engine($this->query_type); + $reason = 0; + $message = ''; + $re_query = ''; $rewritten_query = $engine->rewrite_query($query, $this->query_type); + if (is_array($rewritten_query) && array_key_exists('recursion', $rewritten_query)) { + $re_query = $rewritten_query['recursion']; + unset($rewritten_query['recursion']); + } try { $this->beginTransaction(); if (is_array($rewritten_query)) { foreach ($rewritten_query as $single_query) { - $this->queries[] = "Executing:\t" . $single_query; - $single_query = trim($single_query); + $this->queries[] = "Executing:\n" . $single_query; + $single_query = trim($single_query); if (empty($single_query)) continue; $this->pdo->exec($single_query); } } else { - $this->queries[] = "Executing:\t" . $rewritten_query; + $this->queries[] = "Executing:\n" . $rewritten_query; $rewritten_query = trim($rewritten_query); $this->pdo->exec($rewritten_query); } $this->commit(); } catch (PDOException $err) { - $reason = $err->getCode(); + $reason = $err->getCode(); $message = $err->getMessage(); if (5 == $reason || 6 == $reason) { $this->commit(); @@ -675,8 +993,11 @@ class PDOEngine extends PDO { $this->rollBack(); } } + if ($re_query != '') { + $this->query($re_query); + } if ($reason > 0) { - $err_message = sprintf(__("Problem in executing alter query. Error was: %s", 'sqlite-integration'), $message); + $err_message = sprintf("Problem in executing alter query. Error was: %s", $message); $this->set_error(__LINE__, __FUNCTION__, $err_message); return false; } @@ -684,52 +1005,105 @@ class PDOEngine extends PDO { } /** - * function to execute SHOW VARIABLES query + * Method 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 */ private function show_variables_workaround($query) { $dummy_data = array('Variable_name' => '', 'Value' => null); - $pattern = '/SHOW\\s*VARIABLES\\s*LIKE\\s*(.*)?$/im'; + $pattern = '/SHOW\\s*VARIABLES\\s*LIKE\\s*(.*)?$/im'; if (preg_match($pattern, $query, $match)) { $value = str_replace("'", '', $match[1]); $dummy_data['Variable_name'] = trim($value); // this is set for Wordfence Security Plugin - if ($value == 'max_allowed_packet') $dummy_data['Value'] = 1047552; + if ($value == 'max_allowed_packet') { + $dummy_data['Value'] = 1047552; + } else { + $dummy_data['Value'] = ''; + } } - $_results[] = new ObjectArray($dummy_data); - $this->results = $_results; - $this->num_rows = count($this->results); + $_results[] = new ObjectArray($dummy_data); + $this->results = $_results; + $this->num_rows = count($this->results); $this->return_value = $this->num_rows; return true; } - + /** + * Method to execute SHOW TABLE STATUS query. + * + * This query is meaningless for SQLite. This function return dummy data. + * + * @param string + * @return ObjectArray + */ + private function show_status_workaround($query) { + $pattern = '/^SHOW\\s*TABLE\\s*STATUS\\s*LIKE\\s*(.*?)$/im'; + if (preg_match($pattern, $query, $match)) { + $table_name = str_replace("'", '', $match[1]); + } else { + $table_name = ''; + } + $dummy_data = array( + 'Name' => $table_name, 'Engine' => '', 'Version' => '', + 'Row_format' => '', 'Rows' => 0, 'Avg_row_length' => 0, + 'Data_length' => 0, 'Max_data_length' => 0, 'Index_length' => 0, + 'Data_free' => 0, 'Auto_increment' => 0, 'Create_time' => '', + 'Update_time' => '', 'Check_time' => '', 'Collation' => '', + 'Checksum' => '', 'Create_options' => '', 'Comment' => '' + ); + $_results[] = new ObjectArray($dummy_data); + $this->results = $_results; + $this->num_rows = count($this->results); + $this->return_value = $this->num_rows; + return true; + } + /** + * Method 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(); } elseif ('showindex' === $this->query_type){ $this->convert_to_index_object(); + } elseif (in_array($this->query_type, array('check', 'analyze'))) { + $this->convert_result_check_or_analyze(); } else { $this->results = $this->_results; } } - + /** + * Method 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); + $this->errors[] = array("line"=>$line, "function"=>$function); $this->error_messages[] = $message; - $this->is_error = true; + $this->is_error = true; if ($wpdb->suppress_errors) return false; 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 + * Method 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(); @@ -742,11 +1116,13 @@ class PDOEngine extends PDO { } $this->results = $_results; } - /** - * method to rewrite pragma results to mysql compatible array + * Method 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(); @@ -767,13 +1143,18 @@ class PDOEngine extends PDO { $_columns['Null'] = $row->notnull ? "NO" : "YES"; $_columns['Key'] = $row->pk ? "PRI" : ""; $_columns['Default'] = $row->dflt_value; - $_results[] = new ObjectArray($_columns); + $_results[] = new ObjectArray($_columns); } } $this->results = $_results; } /** - * rewrites the result of SHOW INDEX to the Object compatible with MySQL + * Method 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(); @@ -838,16 +1219,57 @@ class PDOEngine extends PDO { $_columns['Null'] = 'NO'; $_columns['Index_type'] = 'BTREE'; $_columns['Comment'] = ''; - $_results[] = new ObjectArray($_columns); + $_results[] = new ObjectArray($_columns); + } + if (stripos($this->queries[0], 'WHERE') !== false) { + preg_match('/WHERE\\s*(.*)$/im', $this->queries[0], $match); + list($key, $value) = explode('=', $match[1]); + $key = trim($key); + $value = preg_replace("/[\';]/", '', $value); + $value = trim($value); + foreach ($_results as $result) { + if (stripos($value, $result->$key) !== false) { + unset($_results); + $_results[] = $result; + break; + } + } } } $this->results = $_results; } - + /** + * Method to the CHECK query data to an object. + * + * @access private + */ + private function convert_result_check_or_analyze() { + $results = array(); + if ($this->query_type == 'check') { + $_columns = array( + 'Table' => '', + 'Op' => 'check', + 'Msg_type' => 'status', + 'Msg_text' => 'OK' + ); + } else { + $_columns = array( + 'Table' => '', + 'Op' => 'analyze', + 'Msg_type' => 'status', + 'Msg_text' => 'Table is already up to date' + ); + } + $_results[] = new ObjectArray($_columns); + $this->results = $_results; + } /** - * function to get SQLite library version - * this is used for checking if SQLite can execute multiple rows insert + * Method 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 { @@ -860,8 +1282,10 @@ class PDOEngine extends PDO { } } /** - * function call to PDO::beginTransaction() + * Method to call PDO::beginTransaction(). + * * @see PDO::beginTransaction() + * @return boolean */ public function beginTransaction() { if ($this->has_active_transaction) { @@ -872,7 +1296,8 @@ class PDOEngine extends PDO { } } /** - * function call to PDO::commit() + * Method to call PDO::commit(). + * * @see PDO::commit() */ public function commit() { @@ -880,7 +1305,8 @@ class PDOEngine extends PDO { $this->has_active_transaction = false; } /** - * function call to PDO::rollBack() + * Method to call PDO::rollBack(). + * * @see PDO::rollBack() */ public function rollBack() { @@ -889,6 +1315,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 0f0a396..45e58f4 100644 --- a/query.class.php +++ b/query.class.php @@ -1,22 +1,56 @@ query_type = $query_type; $this->_query = $query; + $this->parse_query(); switch ($this->query_type) { case 'truncate': - $this->_handle_truncate_query(); + $this->handle_truncate_query(); break; case 'alter': - $this->_handle_alter_query(); + $this->handle_alter_query(); break; case 'create': - $this->_handle_create_query(); + $this->handle_create_query(); break; case 'describe': case 'desc': - $this->_handle_describe_query(); + $this->handle_describe_query(); break; case 'show': - $this->_handle_show_query(); + $this->handle_show_query(); break; case 'showcolumns': - $this->_handle_show_columns_query(); + $this->handle_show_columns_query(); break; case 'showindex': - $this->_handle_show_index(); + $this->handle_show_index(); break; case 'select': - $this->_strip_backticks(); - $this->_handle_sql_count(); - $this->_rewrite_date_sub(); - $this->_delete_index_hints(); - $this->_rewrite_regexp(); - $this->_rewrite_boolean(); + //$this->strip_backticks(); + $this->handle_sql_count(); + $this->rewrite_date_sub(); + $this->delete_index_hints(); + $this->rewrite_regexp(); + //$this->rewrite_boolean(); + $this->fix_date_quoting(); + $this->rewrite_between(); break; case 'insert': - $this->_strip_backticks(); - $this->_execute_duplicate_key_update(); - $this->_rewrite_insert_ignore(); - $this->_rewrite_regexp(); + //$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->_rewrite_update_ignore(); + //$this->safe_strip_backticks(); + $this->rewrite_update_ignore(); // $this->_rewrite_date_sub(); - $this->_rewrite_limit_usage(); - $this->_rewrite_order_by_usage(); - $this->_rewrite_regexp(); + $this->rewrite_limit_usage(); + $this->rewrite_order_by_usage(); + $this->rewrite_regexp(); + $this->rewrite_between(); break; case 'delete': - $this->_strip_backticks(); - $this->_rewrite_limit_usage(); - $this->_rewrite_order_by_usage(); - $this->_rewrite_date_sub(); - $this->_rewrite_regexp(); - $this->_delete_workaround(); + //$this->strip_backticks(); + $this->rewrite_limit_usage(); + $this->rewrite_order_by_usage(); + $this->rewrite_date_sub(); + $this->rewrite_regexp(); + $this->delete_workaround(); break; case 'replace': - $this->_strip_backticks(); - $this->_rewrite_date_sub(); - $this->_rewrite_regexp(); + //$this->safe_strip_backticks(); + $this->rewrite_date_sub(); + $this->rewrite_regexp(); break; case 'optimize': - $this->_rewrite_optimize(); + $this->rewrite_optimize(); break; + case 'pragma': + break; default: + if (defined(WP_DEBUG) && WP_DEBUG) { + break; + } else { + $this->return_true(); + break; + } } return $this->_query; } - + /** - * method to dummy the SHOW TABLES query + * Method to parse query string and determine which operation is needed. + * + * Remove backticks and change true/false values into 1/0. And determines + * if rewriting CALC_FOUND_ROWS or ON DUPLICATE KEY UPDATE etc is needed. + * + * @access private */ - private function _handle_show_query(){ + private function parse_query() { + $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) { + if (strpos($token, '`') !== false) { + $token = str_replace('`', '', $token); + } + if (preg_match('/\\bTRUE\\b/i', $token)) { + $token = str_ireplace('TRUE', '1', $token); + } + if (preg_match('/\\bFALSE\\b/i', $token)) { + $token = str_ireplace('FALSE', '0', $token); + } + if (stripos($token, 'SQL_CALC_FOUND_ROWS') !== false) { + $this->rewrite_calc_found = true; + } + if (stripos($token, 'ON DUPLICATE KEY UPDATE') !== false) { + $this->rewrite_duplicate_key = true; + } + if (stripos($token, 'USE INDEX') !== false) { + $this->rewrite_index_hint = true; + } + if (stripos($token, 'IGNORE INDEX') !== false) { + $this->rewrite_index_hint = true; + } + if (stripos($token, 'FORCE INDEX') !== false) { + $this->rewrite_index_hint = true; + } + if (stripos($token, 'BETWEEN') !== false) { + $this->rewrite_between = true; + } + } + } + $query_string .= $token; + } + $this->_query = $query_string; + } + /** + * method to handle SHOW TABLES query. + * + * @access private + */ + private function handle_show_query(){ + $this->_query = str_ireplace(' FULL', '', $this->_query); $table_name = ''; - $pattern = '/^\\s*SHOW\\s*TABLES\\s*(LIKE\\s*(.*))$/im'; + $pattern = '/^\\s*SHOW\\s*TABLES\\s*.*?(LIKE\\s*(.*))$/im'; if (preg_match($pattern, $this->_query, $matches)) { $table_name = str_replace(array("'", ';'), '', $matches[2]); } @@ -106,112 +210,166 @@ 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. + * + * Obsolite since 1.5.1 + * + * @access private */ - private function _strip_backticks(){ + private function strip_backticks(){ $this->_query = str_replace('`', '', $this->_query); } - /** - * method to emulate the SQL_CALC_FOUND_ROWS placeholder for mysql - * - * 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 + * Method to strip all column qualifiers (backticks) from a query except post data. * - * 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. + * 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. * - * this kind of statement is required for WordPress to calculate the paging. - * see also WP_Query class in wp-includes/query.php + * Obsolite since 1.5.1 + * + * @access private */ - private function _handle_sql_count(){ - if (stripos($this->_query, 'SELECT SQL_CALC_FOUND_ROWS') !== false){ - global $wpdb; - // first strip the code. this is the end of rewriting process - $this->_query = str_ireplace('SQL_CALC_FOUND_ROWS', '', $this->_query); - // we make the data for next SELECE FOUND_ROWS() statement - $unlimited_query = preg_replace('/\\bLIMIT\\s*.*/imsx', '', $this->_query); -// $unlimited_query = preg_replace('/\\bFALSE\\s*.*/imsx', '0', $unlimited_query); - $unlimited_query = preg_replace('/\\bGROUP\\s*BY\\s*.*/imsx', '', $unlimited_query); - $unlimited_query = $this->__transform_to_count($unlimited_query); - $_wpdb = new PDODB(); - $result = $_wpdb->query($unlimited_query); - $wpdb->dbh->found_rows_result = $_wpdb->last_result; + 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; } - /** - * transforms a select query to a select count(*) + * Method to emulate the SQL_CALC_FOUND_ROWS placeholder for MySQL. + * + * 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 the rewritten query + * 3. give the returned value (integer: number of the rows) to the original instance variable without LIMIT + * + * We no longer use SELECT COUNT query, because it returns the inexact values when used with WP_Meta_Query(). + * + * This kind of statement is required for WordPress to calculate the paging information. + * see also WP_Query class in wp-includes/query.php + * + * @access private + */ + private function handle_sql_count(){ + if (!$this->rewrite_calc_found) return; + global $wpdb; + // first strip the code. this is the end of rewriting process + $this->_query = str_ireplace('SQL_CALC_FOUND_ROWS', '', $this->_query); + // we make the data for next SELECE FOUND_ROWS() statement + $unlimited_query = preg_replace('/\\bLIMIT\\s*.*/imsx', '', $this->_query); + //$unlimited_query = preg_replace('/\\bGROUP\\s*BY\\s*.*/imsx', '', $unlimited_query); + // we no longer use SELECT COUNT query + //$unlimited_query = $this->_transform_to_count($unlimited_query); + $_wpdb = new PDODB(); + $result = $_wpdb->query($unlimited_query); + $wpdb->dbh->found_rows_result = $result; + $_wpdb = null; + } + /** + * Call back method to change SELECT query to SELECT COUNT(). + * + * obsolite since 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'; + private function _transform_to_count($query){ + $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(){ + 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(){ + 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(){ + private function rewrite_date_add(){ //(date,interval expression unit) $pattern = '/\\s*date_add\\s*\(([^,]*),([^\)]*)\)/imsx'; if (preg_match($pattern, $this->_query, $matches)) { - $expression = "'".trim($matches[2])."'"; + $expression = "'".trim($matches[2])."'"; $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(){ + private function rewrite_date_sub(){ //(date,interval expression unit) $pattern = '/\\s*date_sub\\s*\(([^,]*),([^\)]*)\)/imsx'; if (preg_match($pattern, $this->_query, $matches)) { - $expression = "'".trim($matches[2])."'"; + $expression = "'".trim($matches[2])."'"; $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'; + private function handle_create_query(){ + 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(){ + private function handle_alter_query(){ require_once PDODIR . 'query_alter.class.php'; $engine = new AlterQuery(); $this->_query = $engine->rewrite_query($this->_query, 'alter'); @@ -219,10 +377,14 @@ 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(){ + private function handle_describe_query(){ // $this->_query = "select 1=1"; $pattern = '/^\\s*(DESCRIBE|DESC)\\s*(.*)/i'; if (preg_match($pattern, $this->_query, $match)) { @@ -230,42 +392,69 @@ 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(){ + private function rewrite_limit_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*LIMIT\\s*[0-9]$/i', '', $this->_query); } } /** + * 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() { + 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); } } - - private function _handle_truncate_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(){ + 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. @@ -273,110 +462,125 @@ class PDOSQLiteDriver { * I don't understand that... * * @return void + * @access private */ - private function _rewrite_badly_formed_dates(){ + 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 - * - * @return void - */ - private function _delete_index_hints(){ - $pattern = '/use\s+index\s*\(.*?\)/i'; - $this->_query = preg_replace($pattern, '', $this->_query); - } - - /** - * Justin Adie says: - * method to fix inconsistent use of quoted, unquoted etc date values in query function - * this is ironic, given the above rewrite badlyformed dates method - * examples - * where month(fieldname)=08 becomes month(fieldname)='8' - * where month(fieldname)='08' becomes month(fieldname)='8' - * - * I don't understand... + * Method to remove INDEX HINT. * * @return void + * @access private */ - private function _fix_date_quoting(){ - $pattern = '/(month|year|second|day|minute|hour|dayofmonth)\s*\((.*?)\)\s*=\s*["\']?(\d{1,4})[\'"]?\s*/ei'; - $this->_query = preg_replace($pattern, "'\\1(\\2)=\'' . intval('\\3') . '\' ' ", $this->_query); + private function delete_index_hints(){ + $pattern = '/\\s*(use|ignore|force)\\s+index\\s*\(.*?\)/i'; + $this->_query = preg_replace($pattern, '', $this->_query); } - - private function _rewrite_regexp(){ + /** + * Method to fix the date string and quoting. + * + * 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. + * + * Obsolite since 1.5.1 + * + * @access private */ - private function _rewrite_boolean() { + 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() { + private function handle_show_columns_query() { + $this->_query = str_ireplace(' FULL', '', $this->_query); $pattern_like = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?\\s*LIKE\\s*(.*)?/i'; - $pattern = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?/i'; + $pattern = '/^\\s*SHOW\\s*(COLUMNS|FIELDS)\\s*FROM\\s*(.*)?/i'; if (preg_match($pattern_like, $this->_query, $matches)) { - $table_name = str_replace("'", "", trim($matches[2])); - $column_name = str_replace("'", "", trim($matches[3])); + $table_name = str_replace("'", "", trim($matches[2])); + $column_name = str_replace("'", "", trim($matches[3])); $query_string = "SELECT sql FROM sqlite_master WHERE tbl_name='$table_name' AND sql LIKE '%$column_name%'"; $this->_query = $query_string; } elseif (preg_match($pattern, $this->_query, $matches)) { - $table_name = $matches[2]; + $table_name = $matches[2]; $query_string = preg_replace($pattern, "PRAGMA table_info($table_name)", $this->_query); $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() { - $_columns = array(// No, you'll get no meaningful information.. - 'Key_name' => 'name', - ); - $pattern_0 = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?\\s*WHERE\\s*(.*)$/im'; - $pattern_1 = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?/im'; - if (preg_match($pattern_0, $this->_query, $match_0)) { - $table_name = str_replace("'", '', $match_0[1]); - list($key, $value) = explode('=', $match_0[2]); - $key = trim($key); - $value = preg_replace("/[\';]/", '', $value); - $value = trim($value); - if (array_key_exists($key, $_columns)) { - $key = $_columns[$key]; - $where_clause = 'AND ' . $key . ' LIKE ' . "'" . $value . "%'"; - } else { - $where_clause = ''; - } - $this->_query = "SELECT * FROM sqlite_master WHERE tbl_name='$table_name' $where_clause"; - } elseif (preg_match($pattern_1, $this->_query, $match_1)) { - $table_name = preg_replace("/[\';]/", '', $match_1[1]); - $table_name = trim($table_name); + private function handle_show_index() { + $pattern = '/^\\s*SHOW\\s*(?:INDEX|INDEXES|KEYS)\\s*FROM\\s*(\\w+)?/im'; + if (preg_match($pattern, $this->_query, $match)) { + $table_name = preg_replace("/[\';]/", '', $match[1]); + $table_name = trim($table_name); $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 ways. + * + * Added the literal check since the version 1.5.1. * * @return void + * @access private */ - private function _execute_duplicate_key_update() { - $update = false; + private function execute_duplicate_key_update() { + if (!$this->rewrite_duplicate_key) return; $unique_keys_for_cond = array(); $unique_keys_for_check = array(); $pattern = '/^\\s*INSERT\\s*INTO\\s*(\\w+)?\\s*(.*)\\s*ON\\s*DUPLICATE\\s*KEY\\s*UPDATE\\s*(.*)$/ims'; @@ -402,14 +606,14 @@ class PDOSQLiteDriver { $unique_keys_for_check = array_map('trim', $unique_keys_for_check); } else { // Without unique key or primary key, UPDATE statement will affect all the rows! - $query = 'INSERT INTO '.$table_name.' '.$insert_data; + $query = 'INSERT INTO '.$table_name.' '.$insert_data; $this->_query = $query; $_wpdb = null; return; } // data check - if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/im', $insert_data, $match_1)) { - $col_array = explode(',', $match_1[1]); + if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/ims', $insert_data, $match_1)) { + $col_array = explode(',', $match_1[1]); $ins_data_array = explode(',', $match_1[2]); foreach ($col_array as $col) { $val = trim(array_shift($ins_data_array)); @@ -420,7 +624,7 @@ class PDOSQLiteDriver { foreach ($unique_keys_for_cond as $unique_key) { if (strpos($unique_key, ',') !== false) { $unique_key_array = explode(',', $unique_key); - $counter = count($unique_key_array); + $counter = count($unique_key_array); for ($i = 0; $i < $counter; ++$i) { $col = trim($unique_key_array[$i]); if (isset($ins_data_assoc[$col]) && $i == $counter - 1) { @@ -441,9 +645,9 @@ class PDOSQLiteDriver { } } } - $condition = rtrim($condition, ' OR '); + $condition = rtrim($condition, ' OR '); $test_query = "SELECT * FROM {$table_name} WHERE {$condition}"; - $results = $_wpdb->query($test_query); + $results = $_wpdb->query($test_query); $_wpdb = null; if ($results == 0) { $this->_query = 'INSERT INTO '.$table_name.' '.$insert_data; @@ -453,7 +657,7 @@ class PDOSQLiteDriver { if (preg_match('/^\((.*)\)\\s*VALUES\\s*\((.*)\)$/im', $insert_data, $match_2)) { $col_array = explode(',', $match_2[1]); $ins_array = explode(',', $match_2[2]); - $count = count($col_array); + $count = count($col_array); for ($i = 0; $i < $count; $i++) { $col = trim($col_array[$i]); $val = trim($ins_array[$i]); @@ -463,17 +667,17 @@ class PDOSQLiteDriver { // change col = data, col = data to array(col=>data, col=>data) // some plugins have semi-colon at the end of the query $update_data = rtrim($update_data, ';'); - $tmp_array = explode(',', $update_data); + $tmp_array = explode(',', $update_data); foreach ($tmp_array as $pair) { list($col, $value) = explode('=', $pair); - $col = trim($col); + $col = trim($col); $value = trim($value); $update_array_assoc[$col] = $value; } // change array(col=>values(col)) to array(col=>data) foreach ($update_array_assoc as $key => &$value) { if (preg_match('/^VALUES\\s*\((.*)\)$/im', $value, $match_3)) { - $col = trim($match_3[1]); + $col = trim($match_3[1]); $value = $ins_array_assoc[$col]; } } @@ -491,36 +695,72 @@ class PDOSQLiteDriver { } } $update_strings = rtrim($update_strings, ','); - $unique_where = array_unique($where_array, SORT_REGULAR); - $where_string = ' WHERE ' . implode(' AND ', $unique_where); + $unique_where = array_unique($where_array, SORT_REGULAR); + $where_string = ' WHERE ' . implode(' AND ', $unique_where); // $where_string = ' WHERE ' . rtrim($where_string, ','); $update_query = 'UPDATE ' . $table_name . ' SET ' . $update_strings . $where_string; $this->_query = $update_query; } } - } else { - // wordaround... - $pattern = '/ ON DUPLICATE KEY UPDATE.*$/im'; - $replace_query = preg_replace($pattern, '', $this->_query); - $replace_query = str_ireplace('INSERT ', 'INSERT OR REPLACE ', $replace_query); - $this->_query = $replace_query; } +// else { +// $pattern = '/ ON DUPLICATE KEY UPDATE.*$/im'; +// $replace_query = preg_replace($pattern, '', $this->_query); +// $replace_query = str_ireplace('INSERT ', 'INSERT OR REPLACE ', $replace_query); +// $this->_query = $replace_query; +// } } - /** - * workaround function to avoid DELETE with JOIN + * 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() { + if (!$this->rewrite_between) return; + $pattern = '/\\s*(CAST\(.+?\)|[^\\s\(]*)?\\s*BETWEEN\\s*([^\\s]*)?\\s*AND\\s*([^\\s\)]*)?\\s*/ims'; + if (preg_match($pattern, $this->_query, $match)) { + $column_name = trim($match[1]); + $min_value = trim($match[2]); + $max_value = trim($match[3]); + $max_value = rtrim($max_value); + $replacement = " $column_name >= $min_value AND $column_name <= $max_value"; + $this->_query = str_ireplace($match[0], $replacement, $this->_query); + } + } + /** + * 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() { + private function delete_workaround() { global $wpdb; // $pattern = "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2 USING (option_name) WHERE o2.option_id > o1.option_id"; - $pattern = "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2"; + $pattern = "DELETE o1 FROM $wpdb->options AS o1 JOIN $wpdb->options AS o2"; $rewritten = "DELETE FROM $wpdb->options WHERE option_id IN (SELECT MIN(option_id) FROM $wpdb->options GROUP BY option_name HAVING COUNT(*) > 1)"; if (stripos($this->_query, $pattern) !== false) { $this->_query = $rewritten; } } + /** + * 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'; + } } ?> \ No newline at end of file diff --git a/query_alter.class.php b/query_alter.class.php index 5061546..933183c 100644 --- a/query_alter.class.php +++ b/query_alter.class.php @@ -1,170 +1,219 @@ split_multiple($command); - foreach ($command_array as $single_command) { - $command_tokens = $this->command_tokenizer($single_command); - if (!empty($command_tokens)) { - $tokens[] = array_merge($tmp_tokens, $command_tokens); - } else { - $this->_query = 'SELECT 1=1'; - } +// $command_array = $this->split_multiple($command); + $command_array = explode(',', $command); + + $single_command = array_shift($command_array); + if (!empty($command_array)) { + $re_command = 'ALTER TABLE ' . $tmp_tokens['table_name'] . ' '; + $re_command .= implode(',', $command_array); + } + $command_tokens = $this->command_tokenizer($single_command); + if (!empty($command_tokens)) { + $tokens = array_merge($tmp_tokens, $command_tokens); + } else { + $this->_query = 'SELECT 1=1'; + return $this->_query; } - foreach ($tokens as $token) { - $command_name = $token['command']; - switch ($command_name) { - case 'add column': case 'rename to': case 'add index': case 'drop index': - $this->_query = $this->handle_single_command($token); - break; - case 'add primary key': - $this->_query = $this->handle_add_primary_key($token); - break; - case 'drop primary key': - $this->_query = $this->handle_drop_primary_key($token); - break; - case 'modify column': - $this->_query = $this->handle_modify_command($token); - break; - case 'change column': - $this->_query = $this->handle_change_command($token); - break; - case 'alter column': - $this->_query = $this->handle_alter_command($token); - break; - default: - break; +// foreach ($tokens as $token) { + $command_name = strtolower($tokens['command']); + switch ($command_name) { + case 'add column': case 'rename to': case 'add index': case 'drop index': + $tmp_query = $this->handle_single_command($tokens); + break; + case 'add primary key': + $tmp_query = $this->handle_add_primary_key($tokens); + break; + case 'drop primary key': + $tmp_query = $this->handle_drop_primary_key($tokens); + break; + case 'modify column': + $tmp_query = $this->handle_modify_command($tokens); + break; + case 'change column': + $tmp_query = $this->handle_change_command($tokens); + break; + case 'alter column': + $tmp_query = $this->handle_alter_command($tokens); + break; + default: + break; } - } +// } + if (!is_array($tmp_query)) { + $this->_query[] = $tmp_query; + } else { + $this->_query = $tmp_query; + } + if ($re_command != '') { + $this->_query = array_merge($this->_query, array('recursion' => $re_command)); + } } else { $this->_query = 'SELECT 1=1'; } return $this->_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)) { + if (preg_match('/^(ADD|DROP|RENAME|MODIFY|CHANGE|ALTER)\\s*(\\w+)?\\s*(\\w+(\(.+\)|))?\\s*/ims', $command, $match)) { $the_rest = str_ireplace($match[0], '', $command); - $match_1 = strtolower(trim($match[1])); - $match_2 = strtolower(trim($match[2])); - $match_3 = isset($match[3]) ? strtolower(trim($match[3])) : ''; - switch ($match_1) { + $match_1 = trim($match[1]); + $match_2 = trim($match[2]); + $match_3 = isset($match[3]) ? trim($match[3]) : ''; + switch (strtolower($match_1)) { case 'add': - if (in_array($match_2, array('fulltext', 'constraint', 'foreign'))) { + if (in_array(strtolower($match_2), array('fulltext', 'constraint', 'foreign'))) { break; - } elseif ($match_2 == 'column') { - $tokens['command'] = $match_1.' '.$match_2; + } elseif (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; $tokens['column_name'] = $match_3; - $tokens['column_def'] = trim($the_rest); - } elseif ($match_2 == 'primary') { - $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; + $tokens['column_def'] = trim($the_rest); + } elseif (stripos('primary', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; $tokens['column_name'] = $the_rest; - } elseif ($match_2 == 'unique') { + } elseif (stripos('unique', $match_2) !== false) { list($index_name, $col_name) = preg_split('/[\(\)]/s', trim($the_rest), -1, PREG_SPLIT_DELIM_CAPTURE); - $tokens['unique'] = true; - $tokens['command'] = $match_1.' '.$match_3; - $tokens['index_name'] = trim($index_name); + $tokens['unique'] = true; + $tokens['command'] = $match_1.' '.$match_3; + $tokens['index_name'] = trim($index_name); $tokens['column_name'] = '('.trim($col_name).')'; - } elseif (in_array($match_2, array('index', 'key'))) { + } elseif (in_array(strtolower($match_2), array('index', 'key'))) { $tokens['command'] = $match_1.' '.$match_2; - $tokens['index_name'] = $match_3; + if ($match_3 == '') { + $tokens['index_name'] = str_replace(array('(', ')'), '', $the_rest); + } else { + $tokens['index_name'] = $match_3; + } $tokens['column_name'] = trim($the_rest); } else { - $tokens['command'] = $match_1.' column'; + $tokens['command'] = $match_1.' COLUMN'; $tokens['column_name'] = $match_2; - $tokens['column_def'] = $match_3.' '.$the_rest; + $tokens['column_def'] = $match_3.' '.$the_rest; } break; case 'drop': - if ($match_2 == 'column') { - $tokens['command'] = $match_1.' '.$match_2; + if (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; $tokens['column_name'] = trim($match_3); - } elseif ($match_2 == 'primary') { + } elseif (stripos('primary', $match_2) !== false) { $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; - } elseif (in_array($match_2, array('index', 'key'))) { - $tokens['command'] = $match_1.' '.$match_2; + } elseif (in_array(strtolower($match_2), array('index', 'key'))) { + $tokens['command'] = $match_1.' '.$match_2; $tokens['index_name'] = $match_3; - } elseif ($match_2 == 'primary') { + } elseif (stripos('primary', $match_2) !== false) { $tokens['command'] = $match_1.' '.$match_2.' '.$match_3; } else { - $tokens['command'] = $match_1.' column'; + $tokens['command'] = $match_1.' COLUMN'; $tokens['column_name'] = $match_2; } break; case 'rename': - if ($match_2 == 'to') { - $tokens['command'] = $match_1.' '.$match_2; + if (stripos('to', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; $tokens['column_name'] = $match_3; } else { - $tokens['command'] = $match_1.' to'; + $tokens['command'] = $match_1.' TO'; $tokens['column_name'] = $match_2; } break; case 'modify': - if ($match_2 == 'column') { - $tokens['command'] = $match_1.' '.$match_2; + if (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; $tokens['column_name'] = $match_3; - $tokens['column_def'] = trim($the_rest); + $tokens['column_def'] = trim($the_rest); } else { - $tokens['command'] = $match_1.' column'; + $tokens['command'] = $match_1.' COLUMN'; $tokens['column_name'] = $match_2; - $tokens['column_def'] = $match_3.' '.trim($the_rest); + $tokens['column_def'] = $match_3.' '.trim($the_rest); } break; case 'change': - if ($match_2 == 'column') { - $tokens['command'] = $match_1.' '.$match_2; + $the_rest = trim($the_rest); + if (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; $tokens['old_column'] = $match_3; - list($new_col) = preg_split('/\s/s', trim($the_rest), -1, PREG_SPLIT_DELIM_CAPTURE); - $tokens['new_column'] = $new_col; - $col_def = str_ireplace($new_col, '', $the_rest); - $tokens['column_def'] = trim($col_def); + list($new_col) = explode(' ', $the_rest); + $tmp_col = preg_replace('/\(.+?\)/im', '', $new_col); + if (array_key_exists(strtolower($tmp_col), $this->array_types)) { + $tokens['column_def'] = $the_rest; + } else { + $tokens['new_column'] = $new_col; + $col_def = str_replace($new_col, '', $the_rest); + $tokens['column_def'] = trim($col_def); + } } else { - $tokens['command'] = $match_1.' column'; + $tokens['command'] = $match_1.' column'; $tokens['old_column'] = $match_2; - $tokens['new_column'] = $match_3; - $tokens['column_def'] = trim($the_rest); + $tmp_col = preg_replace('/\(.+?\)/im', '', $match_3); + if (array_key_exists(strtolower($tmp_col), $this->array_types)) { + $tokens['column_def'] = $match_3 . ' ' . $the_rest; + } else { + $tokens['new_column'] = $match_3; + $tokens['column_def'] = $the_rest; + } } break; case 'alter': - if ($match_2 == 'column') { - $tokens['command'] = $match_1.' '.$match_2; + if (stripos('column', $match_2) !== false) { + $tokens['command'] = $match_1.' '.$match_2; $tokens['column_name'] = $match_3; - list($set_or_drop) = explode(' ', $the_rest); - if ($set_or_drop == 'set') { - $tokens['default_command'] = 'set default'; - $default_value = str_ireplace('set default', '', $the_rest); - $tokens['default_value'] = trim($default_value); + list($set_or_drop) = explode(' ', $the_rest); + if (stripos('set', $set_or_drop) !== false) { + $tokens['default_command'] = 'SET DEFAULT'; + $default_value = str_ireplace('set default', '', $the_rest); + $tokens['default_value'] = trim($default_value); } else { - $tokens['default_command'] = 'drop default'; + $tokens['default_command'] = 'DROP DEFAULT'; } } else { - $tokens['command'] = $match_1.' column'; + $tokens['command'] = $match_1.' COLUMN'; $tokens['column_name'] = $match_2; - if ($match_3 == 'set') { - $tokens['default_command'] = 'set default'; - $default_value = str_ireplace('default', '', $the_rest); - $tokens['default_value'] = trim($default_value); + if (stripos('set', $match_3) !== false) { + $tokens['default_command'] = 'SET DEFAULT'; + $default_value = str_ireplace('default', '', $the_rest); + $tokens['default_value'] = trim($default_value); } else { - $tokens['default_command'] = 'drop default'; + $tokens['default_command'] = 'DROP DEFAULT'; } } break; @@ -174,12 +223,20 @@ 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
+ + +
++ +
++ +
++ +
+ + + + + ++ +
+ tables('all'); + ?> + + + +'.$fix_results.'
'; + echo ''.$message.'
'; + echo ''. $column_header . ' | '. $type_header . ' | ' . $null_header . ' | ' . $default_header . ' |
---|---|---|---|
' . $column->Field . ' | '; + echo '' . $column->Type . ' | '; + echo '' . $column->Null . ' | '; + echo '' . $column->Default . ' | '; + echo '
' . $results; + echo '
- 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.5.1 and 3.6 beta).', $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,10 +73,10 @@ class SQLiteIntegrationDocument {
Support Forum.', $domain);?> @@ -86,7 +93,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());?>
- | - | + | + | reason;?> | - +
---|
- -
-- 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 +121,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 +156,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 +185,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 +206,12 @@ class SQLiteIntegrationUtils {
}
}
/**
- * function to return contents of 'wp-content/db.php' file
- * if the file is not existent, returns false.
- * @return string|boolean
+ * Method to show the contents of 'wp-content/db.php' file.
+ *
+ * If this file is not existent, shows message and returns false.
+ *
+ * @return string
+ * @access private
*/
private function show_db_php() {
if (defined('WP_CONTENT_DIR')) {
@@ -146,19 +222,21 @@ class SQLiteIntegrationUtils {
if (file_exists($file)) {
if (is_readable($file)) {
$contents = file_get_contents($file);
- echo $contents;
+ return $contents;
} else {
- echo 'file is not readable';
+ $contents = 'file is not readable';
}
} else {
- echo 'file doesn\'t exist';
- return false;
+ $contents = 'file doesn\'t exist';
}
+ return $contents;
}
/**
- * 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 +259,44 @@ class SQLiteIntegrationUtils {
return true;
}
/**
- * function to optimize database file
- * only to give vacuum command to SQLite
+ * Method to replace the old db.php with the new one.
+ *
* @return boolean
+ * @access private
+ */
+ private function update_db_file() {
+ $new_file = PDODIR . 'db.php';
+ if (file_exists($new_file) && is_readable($new_file)) {
+ $contents = file_get_contents($new_file);
+ } else {
+ return false;
+ }
+ if (defined('WP_CONTENT_DIR')) {
+ $path = WP_CONTENT_DIR . '/db.php';
+ } else {
+ $path = ABSPATH . 'wp-content/db.php';
+ }
+ if (($handle = @fopen($path, 'w+')) && flock($handle, LOCK_EX)) {
+ if (fwrite($handle, $contents) == false) {
+ flock($handle, LOCK_UN);
+ fclose($handle);
+ return false;
+ }
+ flock($handle, LOCK_UN);
+ fclose($handle);
+ } else {
+ return false;
+ }
+ return true;
+ }
+ /**
+ * 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,21 +304,25 @@ 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;
if (file_exists($db_file)) {
$size = filesize($db_file);
- clearstatcache(false, $db_file);
+ clearstatcache(true, $db_file);
return $this->convert_to_formatted_number($size);
}
}
/**
- * 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 +335,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;
@@ -251,7 +371,11 @@ class SQLiteIntegrationUtils {
$compat = __('No', $domain);
break;
case 'Checked':
- $compat = __('Checked', $domain);
+ if (!empty($plugin_info->informed) && stripos($plugin_info->informed, 'Users\' Information') !== false) {
+ $compat = __('Checked*', $domain);
+ } else {
+ $compat = __('Checked', $domain);
+ }
break;
default:
$compat = __('Not Checked', $domain);
@@ -279,9 +403,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 +439,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();
@@ -329,10 +457,147 @@ class SQLiteIntegrationUtils {
}
}
+ /**
+ * Method to parse FQDBDIR and return backup database files.
+ *
+ * @return nothing returned.
+ * @access private
+ */
+ private function get_backup_files() {
+ $db_name = basename(FQDB);
+ $names_to_exclude = array('.', '..', '.htaccess', 'debug.txt', '.ht.sqlite', 'index.php', $db_name);
+ $backup_files = array();
+ if (is_dir(FQDBDIR)) {
+ if ($dir_handle = opendir(FQDBDIR)) {
+ while (($file_name = readdir($dir_handle)) !== false) {
+ if (in_array($file_name, $names_to_exclude)) continue;
+ $backup_files[] = $file_name;
+ }
+ }
+ }
+ return $backup_files;
+ }
+
+ /**
+ * Method to create backup database file.
+ *
+ * @return string array
+ * @access private
+ */
+ private function backup_db() {
+ $domain = $this->text_domain;
+ $result = array();
+ $database_file = FQDB;
+ $db_name = basename(FQDB);
+ if (!file_exists($database_file)) {
+ return false;
+ }
+ $today = date("Ymd");
+ if (!extension_loaded('zip')) {
+ $backup_file = $database_file . '.' . $today . '.back';
+ if (copy($database_file, $backup_file)) {
+ $result['success'] = basename($backup_file) . __(' was created.', $domain);
+ } else {
+ $result['error'] = basename($backup_file) . __(' was not created.', $domain);
+ }
+ } else {
+ $backup_file = $database_file . '.' . $today . '.zip';
+ $zip = new ZipArchive();
+ $res = $zip->open($backup_file, ZipArchive::CREATE | ZipArchive::OVERWRITE);
+ if ($res === true) {
+ $zip->addFile($database_file, $db_name);
+ $result['success'] = basename($backup_file) . __(' was created.', $domain);
+ } else {
+ $result['error'] = basename($backup_file) . __(' was not created.', $domain);
+ }
+ $zip->close();
+ }
+ return $result;
+ }
+ /**
+ * Method to delete backup database file(s).
+ *
+ * Users can delete multiple files at a time.
+ *
+ * @return false if file names aren't checked, empty array if failed, array of messages if succeeded.
+ * @access private
+ */
+ private function delete_backup_db() {
+ $domain = $this->text_domain;
+ $file_names = array();
+ $results = array();
+ if (isset($_POST['backup_checked'])) {
+ $file_names = $_POST['backup_checked'];
+ } else {
+ return false;
+ }
+ if (chdir(FQDBDIR)) {
+ foreach ($file_names as $file) {
+ if (unlink($file)) {
+ $results[$file] = sprintf(__('File %s was deleted.', $domain), $file);
+ } else {
+ $results[$file] = sprintf(__('Error! File was not deleted.', $domain), $file);
+ }
+ }
+ }
+ return $results;
+ }
+ /**
+ * Method to download a backup file.
+ *
+ * This method uses header() function, so we have to register this function using
+ * admin_init action hook. It must also be declared as public. We check HTTP_REFERER
+ * and input button name, and ,after that, wp_nonce. When the admin_init is executed
+ * it only returns true.
+ *
+ * The database file might be several hundred mega bytes, so we don't use readfile()
+ * but use fread() instead.
+ *
+ * Users can download one file at a time.
+ *
+ * @return 1 if the file name isn't checked, 2 if multiple files are checked, true if succeeded.
+ */
+ static function download_backup_db() {
+ if (is_multisite()) {
+ $script_url = network_admin_url('settings.php?page=setting-file');
+ } else {
+ $script_url = admin_url('options-general.php?page=setting-file');
+ }
+ if (isset($_POST['download_backup_file']) && stripos($_SERVER['HTTP_REFERER'], $script_url) !== false) {
+ check_admin_referer('sqliteintegration-backup-manip-stats');
+ if (!isset($_POST['backup_checked'])) return 1;
+ $file_names = array();
+ $file_names = $_POST['backup_checked'];
+ if (count($file_names) != 1) return 2;
+ $file_name = $file_names[0];
+ $file_path = FQDBDIR . $file_name;
+ $blog_name = str_replace(array(' ', ' ', ';'), array('_', '_', '_'), get_bloginfo('name'));
+ $download_file_name = $blog_name . '_' . $file_name;
+ header('Pragma: public');
+ header('Cache-Control: must-revalidate,post-check=0,pre-check=0');
+ header('Content-Type: application/force-download');
+ header('Content-Type: application/octet-stream');
+ header('Content-Type: application/download');
+ header('Content-Disposition: attachment; filename='.$download_file_name.';');
+ header('Content-Transfer-Encoding: binary');
+ header('Content-Length: '.filesize($file_path));
+ $fp = fopen($file_path, 'r');
+ while (!feof($fp)) {
+ echo fread($fp, 65536);
+ flush();
+ }
+ fclose($fp);
+ }
+ return true;
+ }
+ /**
+ * Method to show Welcome page.
+ *
+ */
function welcome() {
$domain = $this->text_domain;
if (isset($_GET['page']) && $_GET['page'] == 'sqlite-integration') :?>
-
+ +
@@ -632,7 +971,47 @@ class SQLiteIntegrationUtils {
- + ++ +
++ +
++ +
+ get_backup_files();?> + +@@ -641,39 +1020,43 @@ class SQLiteIntegrationUtils { wp_nonce_field('sqlitewordpress-log-reset-stats'); } ?> - +
- -
- If you don\'t understand well, please don\'t edit this file.', $domain)?> -
- '; ?> + + + + -