* 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', '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() { $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); 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. * * 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) { $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'; } } ?>