sqlite-integration/functions.php

687 lines
20 KiB
PHP
Raw Permalink Normal View History

<?php
/**
* This file contains the class that defines user defined functions for PDO library.
*
* This file is for PHP 5.3.x or later. For PHP 5.2.x or lesser, functions-5-2.php is
* loaded. PHP version is checked in the db.php and that will load the apropriate
* one.
*
* @package SQLite Integration
* @author Kojima Toshiyasu
*
*/
/**
* This class defines user defined functions(UDFs) for PDO library.
*
* These functions replace those used in the SQL statement with the PHP functions.
*
* Usage:
*
* <code>
* new PDOSQLiteUDFS(ref_to_pdo_obj);
* </code>
*
* 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){
if (!$pdo) {
wp_die('Database is not initialized.', 'Database Error');
}
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',
'day' => 'day',
'unix_timestamp' => 'unix_timestamp',
'now' => 'now',
'char_length' => 'char_length',
'md5' => 'md5',
'curdate' => 'curdate',
'rand' => 'rand',
'substring' => 'substring',
'dayofmonth' => 'day',
'second' => 'second',
'minute' => 'minute',
'hour' => 'hour',
'date_format' => 'dateformat',
'from_unixtime' => 'from_unixtime',
'date_add' => 'date_add',
'date_sub' => 'date_sub',
'adddate' => 'date_add',
'subdate' => 'date_sub',
'localtime' => 'now',
'localtimestamp' => 'now',
'isnull' => 'isnull',
'if' => '_if',
'regexpp' => 'regexp',
'concat' => 'concat',
'field' => 'field',
'log' => 'log',
'least' => 'least',
'greatest' => 'greatest',
'get_lock' => 'get_lock',
'release_lock' => 'release_lock',
'ucase' => 'ucase',
'lcase' => 'lcase',
'inet_ntoa' => 'inet_ntoa',
'inet_aton' => 'inet_aton',
'datediff' => 'datediff',
'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 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){
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);
$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->add(new DateInterval($interval));
$returnval = $objDate->format("Y-m-d");
break;
case "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->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->sub(new DateInterval($interval));
$returnval = $objDate->format("Y-m-d");
break;
case "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->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);
foreach ($parts as $part) {
if (!empty($part)) {
$_parts[] = $part;
}
}
$type = strtolower(end($_parts));
switch ($type) {
case "second": $unit = 'S'; return 'PT' . $_parts[0] . $unit; break;
case "minute": $unit = 'M'; return 'PT' . $_parts[0] . $unit; break;
case "hour": $unit = 'H'; return 'PT' . $_parts[0] . $unit; break;
case "day": $unit = 'D'; return 'P' . $_parts[0] . $unit; break;
case "week": $unit = 'W'; return 'P' . $_parts[0] . $unit; break;
case "month": $unit = 'M'; return 'P' . $_parts[0] . $unit; break;
case "year": $unit = 'Y'; return 'P' . $_parts[0] . $unit; break;
case "minute_second":
list($minutes, $seconds) = explode(':', $_parts[0]);
return 'PT' . $minutes . 'M' . $seconds . 'S';
case "hour_second":
list($hours, $minutes, $seconds) = explode (':', $_parts[0]);
return 'PT' . $hours . 'H' . $minutes . 'M' . $seconds . 'S';
case "hour_minute":
list($hours, $minutes) = explode (':', $_parts[0]);
return 'PT' . $hours . 'H' . $minutes . 'M';
case "day_second":
$days = intval($_parts[0]);
list($hours, $minutes, $seconds) = explode (':', $_parts[1]);
return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M' . $seconds . 'S';
case "day_minute":
$days = intval($_parts[0]);
list($hours, $minutes) = explode(':', $parts[1]);
return 'P' . $days . 'D' . 'T' . $hours . 'H' . $minutes . 'M';
case "day_hour":
$days = intval($_parts[0]);
$hours = intval($_parts[1]);
return 'P' . $days . 'D' . 'T' . $hours . 'H';
case "year_month":
list($years, $months) = explode ('-', $_parts[0]);
return 'P' . $years . 'Y' . $months . 'M';
}
}
/**
* 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();
$argsList = func_get_args();
for ($i = 0; $i < $argsNum; $i++) {
if (is_null($argsList[$i])) {
return null;
}
$returnValue .= $argsList[$i];
}
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() {
global $wpdb;
$numArgs = func_num_args();
if ($numArgs < 2 or is_null(func_get_arg(0))) {
return 0;
} else {
$arg_list = func_get_args();
}
$searchString = array_shift($arg_list);
$str_to_check = substr($searchString, 0, strpos($searchString, '.'));
$str_to_check = str_replace($wpdb->prefix, '', $str_to_check);
if ($str_to_check && in_array(trim($str_to_check), $wpdb->tables)) return;
for ($i = 0; $i < $numArgs-1; $i++) {
if ($searchString === strtolower($arg_list[$i])) {
return $i + 1;
}
}
return 0;
}
/**
* Method to emulate MySQL LOG() function.
*
* Used with one argument, it returns the natural logarithm of X.
* <code>
* LOG(X)
* </code>
* Used with two arguments, it returns the natural logarithm of X base B.
* <code>
* LOG(B, X)
* </code>
* 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) {
$arg1 = func_get_arg(0);
return log($arg1);
} else if ($numArgs == 2) {
$arg1 = func_get_arg(0);
$arg2 = func_get_arg(1);
return log($arg1)/log($arg2);
} else {
return null;
}
}
/**
* 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
*/
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';
}
/**
* 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)";
}
/**
* 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;
}
/**
* 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) {
if (version_compare(PHP_VERSION, '5.3.2', '==')) {
$start_date = strtotime($start);
$end_date = strtotime($end);
$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);
return $interval->format('%r%a');
}
}
/**
* 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')) {
if (($val = stros($str, $substr, $pos)) !== false) {
return $val + 1;
} else {
return 0;
}
} else {
if (($val = mb_strpos($str, $substr, $pos)) !== false) {
return $val + 1;
} else {
return 0;
}
}
}
/**
* 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';
}
}
?>