2013-07-07 06:49:38 +00:00
< ? php
/**
2014-01-29 09:35:06 +00:00
* This file defines PDOEngine class .
*
2013-07-07 06:49:38 +00:00
* @ package SQLite Integration
2014-01-29 09:35:06 +00:00
* @ author Kojima Toshiyasu
2013-07-07 06:49:38 +00:00
*
*/
/**
2014-01-29 09:35:06 +00:00
* This class extends PDO class and does the real work .
*
* It accepts a request from wpdb class , initialize PDO instance ,
* execute SQL statement , and returns the results to WordPress .
2013-07-07 06:49:38 +00:00
*/
class PDOEngine extends PDO {
2014-01-29 09:35:06 +00:00
/**
* Class variable to check if there is an error .
*
* @ var boolean
*/
2013-07-07 06:49:38 +00:00
public $is_error = false ;
2014-01-29 09:35:06 +00:00
/**
* Class variable which is used for CALC_FOUND_ROW query .
*
* @ var unsigned integer
*/
public $found_rows_result = null ;
/**
* Class variable to store the rewritten queries .
*
* @ var array
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $rewritten_query ;
2014-01-29 09:35:06 +00:00
/**
* Class variable to have what kind of query to execute .
*
* @ var string
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $query_type ;
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the result of the query .
*
* @ var reference to the PHP object
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $results = null ;
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the results of the query .
*
* This is for the backward compatibility .
*
* @ var reference to the PHP object
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $_results = null ;
2014-01-29 09:35:06 +00:00
/**
* Class variable to reference to the PDO instance .
*
* @ var PDO object
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $pdo ;
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the query string prepared to execute .
*
* @ var string | array
*/
2013-07-07 06:49:38 +00:00
private $prepared_query ;
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the values in the query string .
*
* @ var array
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $extracted_variables = array ();
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the error messages .
*
* @ var array
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $error_messages = array ();
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the file name and function to cause error .
*
* @ var array
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $errors ;
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the query strings .
*
* @ var array
*/
2013-07-07 06:49:38 +00:00
public $queries = array ();
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the affected row id .
*
* @ var unsigned integer
* @ access private
*/
2013-07-07 06:49:38 +00:00
private $last_insert_id ;
2014-01-29 09:35:06 +00:00
/**
* Class variable to store the number of rows affected .
*
* @ var unsigned integer
*/
2013-07-07 06:49:38 +00:00
private $affected_rows ;
2014-01-29 09:35:06 +00:00
/**
2014-02-05 19:29:23 +00:00
* Class variable to store the queried column info .
2014-01-29 09:35:06 +00:00
*
* @ var array
*/
2014-02-05 19:29:23 +00:00
private $column_data ;
/**
* Variable to emulate MySQL affected row .
*
* @ var integer
*/
2013-07-07 06:49:38 +00:00
private $num_rows ;
2014-02-05 19:29:23 +00:00
/**
* Return value from query () .
*
* Each query has its own return value .
*
* @ var mixed
*/
2013-07-07 06:49:38 +00:00
private $return_value ;
2014-02-05 19:29:23 +00:00
/**
* Variable to determine which insert query to use .
*
* Whether VALUES clause in the INSERT query can take multiple values or not
* depends on the version of SQLite library . We check the version and set
* this varable to true or false .
*
* @ var boolean
*/
2013-07-07 06:49:38 +00:00
private $can_insert_multiple_rows = false ;
2014-02-05 19:29:23 +00:00
/**
*
* @ var integer
*/
2013-07-07 06:49:38 +00:00
private $param_num ;
2014-01-29 09:35:06 +00:00
/**
* Varible to check if there is an active transaction .
* @ var boolean
2014-02-05 19:29:23 +00:00
* @ access protected
2014-01-29 09:35:06 +00:00
*/
2013-07-07 06:49:38 +00:00
protected $has_active_transaction = false ;
/**
* Constructor
2014-01-29 09:35:06 +00:00
*
* @ param none
2013-07-07 06:49:38 +00:00
*/
function __construct () {
$this -> init ();
}
2014-01-29 09:35:06 +00:00
/**
* Destructor
*
* @ return boolean
*/
2013-07-07 06:49:38 +00:00
function __destruct () {
$this -> pdo = null ;
return true ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to initialize database , executed in the contructor .
2014-01-29 09:35:06 +00:00
*
* It checks if there ' s a database directory and database file , creates the tables ,
* and binds the user defined function to the pdo object .
*
2013-07-07 06:49:38 +00:00
* @ return boolean
*/
private function init () {
2014-02-05 19:29:23 +00:00
$dsn = 'sqlite:' . FQDB ;
2013-07-07 06:49:38 +00:00
$result = $this -> prepare_directory ();
if ( ! $result ) return false ;
if ( is_file ( FQDB )) {
$locked = false ;
do {
try {
if ( $locked ) $locked = false ;
$this -> pdo = new PDO (
$dsn , // data source name
null , // user name
null , // user password
array ( // PDO options
PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION
));
2014-02-05 19:29:23 +00:00
$statement = $this -> pdo -> query ( " SELECT COUNT(*) FROM sqlite_master WHERE type='table' " );
2013-07-07 06:49:38 +00:00
$number_of_tables = $statement -> fetchColumn ( 0 );
2014-02-05 19:29:23 +00:00
$statement = null ;
2013-07-07 06:49:38 +00:00
if ( $number_of_tables == 0 ) {
$this -> make_sqlite_tables ();
}
} catch ( PDOException $err ) {
$status = $err -> getCode ();
// code 5 => The database file is locked
// code 6 => A table in the database is locked
if ( $status == 5 || $status == 6 ) {
$locked = true ;
} else {
2014-02-05 19:29:23 +00:00
$message = 'Database connection error!<br />' ;
2013-09-25 07:40:16 +00:00
$message .= sprintf ( " Error message is: %s " , $err -> getMessage ());
2013-07-07 06:49:38 +00:00
$this -> set_error ( __LINE__ , __FUNCTION__ , $message );
return false ;
}
}
} while ( $locked );
require_once UDF_FILE ;
new PDOSQLiteUDFS ( $this -> pdo );
if ( version_compare ( $this -> get_sqlite_version (), '3.7.11' , '>=' )) {
$this -> can_insert_multiple_rows = true ;
}
} else { // database file is not found, so we make it and create tables...
try {
$this -> pdo = new PDO ( $dsn , null , null , array ( PDO :: ATTR_ERRMODE => PDO :: ERRMODE_EXCEPTION ));
} catch ( PDOException $err ) {
2014-02-05 19:29:23 +00:00
$message = 'Database initialization error!<br />' ;
2013-09-25 07:40:16 +00:00
$message .= sprintf ( " Error message is: %s " , $err -> getMessage ());
2013-07-07 06:49:38 +00:00
$this -> set_error ( __LINE__ , __FUNCTION__ , $message );
return false ;
}
$this -> make_sqlite_tables ();
}
}
/**
2014-04-17 02:45:32 +00:00
* This method makes database direcotry and . htaccess file .
2014-01-29 09:35:06 +00:00
*
* It is executed only once when the installation begins .
2013-07-07 06:49:38 +00:00
*/
private function prepare_directory () {
global $wpdb ;
$u = umask ( 0000 );
if ( ! is_dir ( FQDBDIR )) {
2013-09-15 21:04:53 +00:00
if ( !@ mkdir ( FQDBDIR , 0707 , true )) {
2013-07-07 06:49:38 +00:00
umask ( $u );
2013-08-13 00:34:40 +00:00
$message = 'Unable to create the required directory! Please check your server settings.' ;
2014-04-17 02:45:32 +00:00
wp_die ( $message , 'Error!' );
2013-07-07 06:49:38 +00:00
}
}
if ( ! is_writable ( FQDBDIR )) {
umask ( $u );
2013-08-13 00:34:40 +00:00
$message = 'Unable to create a file in the directory! Please check your server settings.' ;
2014-04-17 02:45:32 +00:00
wp_die ( $message , 'Error!' );
2013-07-07 06:49:38 +00:00
}
if ( ! is_file ( FQDBDIR . '.htaccess' )) {
$fh = fopen ( FQDBDIR . '.htaccess' , " w " );
if ( ! $fh ) {
umask ( $u );
2013-08-13 00:34:40 +00:00
$message = 'Unable to create a file in the directory! Please check your server settings.' ;
2013-07-07 06:49:38 +00:00
echo $message ;
return false ;
}
2013-09-25 07:40:16 +00:00
fwrite ( $fh , 'DENY FROM ALL' );
2013-07-07 06:49:38 +00:00
fclose ( $fh );
}
2014-04-17 02:45:32 +00:00
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 , '<?php // Silence is gold. ?>' );
fclose ( $fh );
}
2013-07-07 06:49:38 +00:00
umask ( $u );
return true ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to call install () function which overrides WordPress install () .
2014-01-29 09:35:06 +00:00
*
* This function is executed only once during the installation process .
2013-07-07 06:49:38 +00:00
*/
private function make_sqlite_tables () {
2013-09-25 07:40:16 +00:00
require_once PDODIR . 'install.php' ;
2013-07-07 06:49:38 +00:00
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to execute query () .
2014-01-29 09:35:06 +00:00
*
2014-03-18 10:06:36 +00:00
* 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.
*
2014-01-29 09:35:06 +00:00
* @ param $query full SQL statement string
* @ return mixed according to the query type
* @ see PDO :: query ()
*/
2013-07-07 06:49:38 +00:00
public function query ( $query ) {
$this -> flush ();
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Raw query: \n $query " ;
2013-07-07 06:49:38 +00:00
$res = $this -> determine_query_type ( $query );
2014-03-18 10:06:36 +00:00
if ( ! $res && defined ( PDO_DEBUG ) && PDO_DEBUG ) {
2013-07-07 06:49:38 +00:00
$bailoutString = sprintf ( __ ( " <h1>Unknown query type</h1><p>Sorry, we cannot determine the type of query that is requested.</p><p>The query is %s</p> " , 'sqlite-integration' ), $query );
$this -> set_error ( __LINE__ , __FUNCTION__ , $bailoutString );
}
switch ( strtolower ( $this -> query_type )) {
2014-04-17 02:45:32 +00:00
case 'set' :
$this -> return_value = false ;
break ;
2013-07-07 06:49:38 +00:00
case 'foundrows' :
2014-01-29 09:35:06 +00:00
$_column = array ( 'FOUND_ROWS()' => '' );
2014-02-05 19:29:23 +00:00
$column = array ();
2014-01-29 09:35:06 +00:00
if ( ! is_null ( $this -> found_rows_result )) {
2014-03-18 10:06:36 +00:00
$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;
// }
2014-02-05 19:29:23 +00:00
$column [] = new ObjectArray ( $_column );
$this -> results = $column ;
2014-01-29 09:35:06 +00:00
$this -> found_rows_result = null ;
}
2013-07-07 06:49:38 +00:00
break ;
case 'insert' :
if ( $this -> can_insert_multiple_rows ) {
$this -> execute_insert_query_new ( $query );
} else {
$this -> execute_insert_query ( $query );
}
break ;
case 'create' :
$result = $this -> execute_create_query ( $query );
$this -> return_value = $result ;
break ;
case 'alter' :
$result = $this -> execute_alter_query ( $query );
$this -> return_value = $result ;
break ;
case 'show_variables' :
$result = $this -> show_variables_workaround ( $query );
break ;
2014-04-17 02:45:32 +00:00
case 'showstatus' :
$result = $this -> show_status_workaround ( $query );
break ;
2013-07-24 02:31:01 +00:00
case 'drop_index' :
$pattern = '/^\\s*(DROP\\s*INDEX\\s*.*?)\\s*ON\\s*(.*)/im' ;
if ( preg_match ( $pattern , $query , $match )) {
2014-02-05 19:29:23 +00:00
$drop_query = 'ALTER TABLE ' . trim ( $match [ 2 ]) . ' ' . trim ( $match [ 1 ]);
$this -> query_type = 'alter' ;
$result = $this -> execute_alter_query ( $drop_query );
2013-07-24 02:31:01 +00:00
$this -> return_value = $result ;
} else {
$this -> return_value = false ;
}
break ;
2013-07-07 06:49:38 +00:00
default :
$engine = $this -> prepare_engine ( $this -> query_type );
$this -> rewritten_query = $engine -> rewrite_query ( $query , $this -> query_type );
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Rewritten: \n $this->rewritten_query " ;
2013-07-07 06:49:38 +00:00
$this -> extract_variables ();
$statement = $this -> prepare_query ();
$this -> execute_query ( $statement );
if ( ! $this -> is_error ) {
$this -> process_results ( $engine );
} else { // Error
;
}
break ;
}
if ( defined ( 'PDO_DEBUG' ) && PDO_DEBUG === true ) {
2014-01-29 09:35:06 +00:00
file_put_contents ( FQDBDIR . 'debug.txt' , $this -> get_debug_info (), FILE_APPEND );
2013-07-07 06:49:38 +00:00
}
return $this -> return_value ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to return inserted row id .
2014-01-29 09:35:06 +00:00
*
* @ return unsigned integer
*/
2013-07-07 06:49:38 +00:00
public function get_insert_id () {
return $this -> last_insert_id ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to return the number of rows affected .
2014-01-29 09:35:06 +00:00
*
* @ return unsigned integer
*/
2013-07-07 06:49:38 +00:00
public function get_affected_rows () {
return $this -> affected_rows ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to return the queried column names .
2014-01-29 09:35:06 +00:00
*
2014-02-05 19:29:23 +00:00
* These data are meaningless for SQLite . So they are dummy emulating
* MySQL columns data .
*
* @ return array of the object
2014-01-29 09:35:06 +00:00
*/
2013-07-07 06:49:38 +00:00
public function get_columns () {
2014-02-05 19:29:23 +00:00
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 ;
}
2013-07-07 06:49:38 +00:00
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to return the queried result data .
2014-01-29 09:35:06 +00:00
*
* @ return mixed
*/
2013-07-07 06:49:38 +00:00
public function get_query_results () {
return $this -> results ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to return the number of rows from the queried result .
2014-01-29 09:35:06 +00:00
*
* @ return unsigned integer
*/
2013-07-07 06:49:38 +00:00
public function get_num_rows () {
return $this -> num_rows ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to return the queried results according to the query types .
2014-01-29 09:35:06 +00:00
*
* @ return mixed
*/
2013-07-07 06:49:38 +00:00
public function get_return_value () {
return $this -> return_value ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to return error messages .
2014-01-29 09:35:06 +00:00
*
* @ return string
*/
2013-07-07 06:49:38 +00:00
public function get_error_message (){
if ( count ( $this -> error_messages ) === 0 ){
2014-02-05 19:29:23 +00:00
$this -> is_error = false ;
2013-07-07 06:49:38 +00:00
$this -> error_messages = array ();
return '' ;
}
$output = '<div style="clear:both"> </div>' ;
if ( $this -> is_error === false ){
// return $output;
return '' ;
}
$output .= " <div class= \" queries \" style= \" clear:both; margin_bottom:2px; border: red dotted thin; \" >Queries made or created this session were<br/> \r \n \t <ol> \r \n " ;
foreach ( $this -> queries as $q ){
$output .= " \t \t <li> " . $q . " </li> \r \n " ;
}
$output .= " \t </ol> \r \n </div> " ;
foreach ( $this -> error_messages as $num => $m ){
$output .= " <div style= \" clear:both; margin_bottom:2px; border: red dotted thin; \" class= \" error_message \" style= \" border-bottom:dotted blue thin; \" >Error occurred at line { $this -> errors [ $num ][ 'line' ] } in Function { $this -> errors [ $num ][ 'function' ] } . <br/> Error message was: $m </div> " ;
}
ob_start ();
debug_print_backtrace ();
2013-09-25 07:40:16 +00:00
$output .= '<pre>' . ob_get_contents () . '</pre>' ;
2013-07-07 06:49:38 +00:00
ob_end_clean ();
return $output ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to return information about query string for debugging .
2014-01-29 09:35:06 +00:00
*
* @ return string
*/
2013-07-07 06:49:38 +00:00
private function get_debug_info (){
$output = '' ;
foreach ( $this -> queries as $q ){
2014-01-29 09:35:06 +00:00
$output .= $q . " \n " ;
2013-07-07 06:49:38 +00:00
}
return $output ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to clear previous data .
2014-01-29 09:35:06 +00:00
*/
2013-07-07 06:49:38 +00:00
private function flush (){
$this -> rewritten_query = '' ;
$this -> query_type = '' ;
$this -> results = null ;
$this -> _results = null ;
$this -> last_insert_id = null ;
$this -> affected_rows = null ;
2014-02-05 19:29:23 +00:00
$this -> column_data = array ();
2013-07-07 06:49:38 +00:00
$this -> num_rows = null ;
$this -> return_value = null ;
$this -> extracted_variables = array ();
$this -> error_messages = array ();
$this -> is_error = false ;
$this -> queries = array ();
$this -> param_num = 0 ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to include the apropreate class files .
2014-01-29 09:35:06 +00:00
*
* 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
*/
2013-07-07 06:49:38 +00:00
private function prepare_engine ( $query_type = null ) {
if ( stripos ( $query_type , 'create' ) !== false ) {
require_once PDODIR . 'query_create.class.php' ;
$engine = new CreateQuery ();
} elseif ( stripos ( $query_type , 'alter' ) !== false ) {
require_once PDODIR . 'query_alter.class.php' ;
$engine = new AlterQuery ();
} else {
require_once PDODIR . 'query.class.php' ;
$engine = new PDOSQLiteDriver ();
}
return $engine ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to create a PDO statement object from the query string .
2014-01-29 09:35:06 +00:00
*
* @ return PDOStatement
*/
2013-07-07 06:49:38 +00:00
private function prepare_query (){
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Prepare: \n " . $this -> prepared_query ;
$reason = 0 ;
$message = '' ;
$statement = null ;
2013-07-07 06:49:38 +00:00
do {
try {
$statement = $this -> pdo -> prepare ( $this -> prepared_query );
} catch ( PDOException $err ) {
2014-02-05 19:29:23 +00:00
$reason = $err -> getCode ();
2013-07-07 06:49:38 +00:00
$message = $err -> getMessage ();
}
} while ( 5 == $reason || 6 == $reason );
if ( $reason > 0 ){
2013-09-25 07:40:16 +00:00
$err_message = sprintf ( " Problem preparing the PDO SQL Statement. Error was: %s " , $message );
2013-07-07 06:49:38 +00:00
$this -> set_error ( __LINE__ , __FUNCTION__ , $err_message );
}
return $statement ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to execute PDO statement object .
2014-01-29 09:35:06 +00:00
*
* 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
*/
2013-07-07 06:49:38 +00:00
private function execute_query ( $statement ) {
2014-02-05 19:29:23 +00:00
$reason = 0 ;
2013-07-07 06:49:38 +00:00
$message = '' ;
if ( ! is_object ( $statement ))
2014-01-29 09:35:06 +00:00
return false ;
2013-07-07 06:49:38 +00:00
if ( count ( $this -> extracted_variables ) > 0 ) {
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Executing: \n " . var_export ( $this -> extracted_variables , true );
2013-07-07 06:49:38 +00:00
do {
if ( $this -> query_type == 'update' || $this -> query_type == 'replace' ) {
try {
$this -> beginTransaction ();
$statement -> execute ( $this -> extracted_variables );
$this -> commit ();
} catch ( PDOException $err ) {
2014-02-05 19:29:23 +00:00
$reason = $err -> getCode ();
2013-07-07 06:49:38 +00:00
$message = $err -> getMessage ();
$this -> rollBack ();
}
} else {
try {
$statement -> execute ( $this -> extracted_variables );
} catch ( PDOException $err ) {
2014-02-05 19:29:23 +00:00
$reason = $err -> getCode ();
2013-07-07 06:49:38 +00:00
$message = $err -> getMessage ();
}
}
} while ( 5 == $reason || 6 == $reason );
} else {
2013-09-25 07:40:16 +00:00
$this -> queries [] = 'Executing: (no parameters)' ;
2013-07-07 06:49:38 +00:00
do {
if ( $this -> query_type == 'update' || $this -> query_type == 'replace' ) {
try {
$this -> beginTransaction ();
$statement -> execute ();
$this -> commit ();
} catch ( PDOException $err ) {
2014-02-05 19:29:23 +00:00
$reason = $err -> getCode ();
2013-07-07 06:49:38 +00:00
$message = $err -> getMessage ();
$this -> rollBack ();
}
} else {
try {
$statement -> execute ();
} catch ( PDOException $err ) {
2014-02-05 19:29:23 +00:00
$reason = $err -> getCode ();
2013-07-07 06:49:38 +00:00
$message = $err -> getMessage ();
}
}
} while ( 5 == $reason || 6 == $reason );
}
if ( $reason > 0 ) {
2013-09-25 07:40:16 +00:00
$err_message = sprintf ( " Error while executing query! Error message was: %s " , $message );
2013-07-07 06:49:38 +00:00
$this -> set_error ( __LINE__ , __FUNCTION__ , $err_message );
return false ;
} else {
$this -> _results = $statement -> fetchAll ( PDO :: FETCH_OBJ );
}
//generate the results that $wpdb will want to see
switch ( $this -> query_type ) {
2013-09-25 07:40:16 +00:00
case 'insert' :
case 'update' :
case 'replace' :
2013-07-07 06:49:38 +00:00
$this -> last_insert_id = $this -> pdo -> lastInsertId ();
2014-02-05 19:29:23 +00:00
$this -> affected_rows = $statement -> rowCount ();
$this -> return_value = $this -> affected_rows ;
2013-07-07 06:49:38 +00:00
break ;
2013-09-25 07:40:16 +00:00
case 'select' :
case 'show' :
case 'showcolumns' :
case 'showindex' :
case 'describe' :
case 'desc' :
2013-11-06 19:23:32 +00:00
case 'check' :
case 'analyze' :
2013-07-07 06:49:38 +00:00
// case "foundrows":
2014-02-05 19:29:23 +00:00
$this -> num_rows = count ( $this -> _results );
2013-07-07 06:49:38 +00:00
$this -> return_value = $this -> num_rows ;
break ;
2013-09-25 07:40:16 +00:00
case 'delete' :
2013-07-07 06:49:38 +00:00
$this -> affected_rows = $statement -> rowCount ();
2014-02-05 19:29:23 +00:00
$this -> return_value = $this -> affected_rows ;
2013-07-07 06:49:38 +00:00
break ;
2013-09-25 07:40:16 +00:00
case 'alter' :
case 'drop' :
case 'create' :
case 'optimize' :
case 'truncate' :
2013-07-07 06:49:38 +00:00
if ( $this -> is_error ) {
$this -> return_value = false ;
} else {
$this -> return_value = true ;
}
break ;
}
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to extract field data to an array and prepare the query statement .
2014-01-29 09:35:06 +00:00
*
* If original SQL statement is CREATE query , this function do nothing and return
* true . This returned value is not used .
*
* @ return boolean
*/
2013-07-07 06:49:38 +00:00
private function extract_variables () {
if ( $this -> query_type == 'create' ) {
$this -> prepared_query = $this -> rewritten_query ;
2014-01-29 09:35:06 +00:00
return true ;
2013-07-07 06:49:38 +00:00
}
//long queries can really kill this
$pattern = '/(?<!\\\\)([\'"])(.*?)(?<!\\\\)\\1/imsx' ;
2014-02-05 19:29:23 +00:00
$_limit = $limit = ini_get ( 'pcre.backtrack_limit' );
2013-07-07 06:49:38 +00:00
do {
if ( $limit > 10000000 ) {
2013-09-25 07:40:16 +00:00
$message = 'The query is too big to parse properly' ;
2013-07-07 06:49:38 +00:00
$this -> set_error ( __LINE__ , __FUNCTION__ , $message );
break ; //no point in continuing execution, would get into a loop
} else {
ini_set ( 'pcre.backtrack_limit' , $limit );
$query = preg_replace_callback ( $pattern , array ( $this , 'replace_variables_with_placeholders' ), $this -> rewritten_query );
}
$limit = $limit * 10 ;
} while ( empty ( $query ));
//reset the pcre.backtrack_limist
ini_set ( 'pcre.backtrack_limit' , $_limit );
2014-02-05 19:29:23 +00:00
$this -> queries [] = " With Placeholders: \n " . $query ;
2013-07-07 06:49:38 +00:00
$this -> prepared_query = $query ;
}
2014-01-29 09:35:06 +00:00
/**
* Call back function to replace field data with PDO parameter .
*
* @ param string $matches
* @ return string
*/
2013-07-07 06:49:38 +00:00
private function replace_variables_with_placeholders ( $matches ) {
//remove the wordpress escaping mechanism
$param = stripslashes ( $matches [ 0 ]);
//remove trailing spaces
$param = trim ( $param );
//remove the quotes at the end and the beginning
if ( in_array ( $param { strlen ( $param ) - 1 }, array ( " ' " , '"' ))) {
$param = substr ( $param , 0 , - 1 ) ; //end
}
if ( in_array ( $param { 0 }, array ( " ' " , '"' ))) {
$param = substr ( $param , 1 ); //start
}
//$this->extracted_variables[] = $param;
$key = ':param_' . $this -> param_num ++ ;
$this -> extracted_variables [] = $param ;
//return the placeholder
//return ' ? ';
return ' ' . $key . ' ' ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to determine which query type the argument is .
2014-01-29 09:35:06 +00:00
*
* 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 .
*
2013-07-07 06:49:38 +00:00
* @ param string $query
* @ return boolean | string
*/
private function determine_query_type ( $query ) {
2014-04-17 02:45:32 +00:00
$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 );
2013-07-07 06:49:38 +00:00
if ( ! $result ) {
return false ;
}
$this -> query_type = strtolower ( $match [ 1 ]);
if ( stripos ( $this -> query_type , 'found' ) !== false ) {
$this -> query_type = 'foundrows' ;
}
if ( stripos ( $this -> query_type , 'show' ) !== false ) {
2014-04-17 02:45:32 +00:00
if ( stripos ( $this -> query_type , 'show table status' ) !== false ) {
$this -> query_type = 'showstatus' ;
2014-05-05 03:38:15 +00:00
} elseif ( stripos ( $this -> query_type , 'show tables' ) !== false || stripos ( $this -> query_type , 'show full tables' ) !== false ) {
2013-07-07 06:49:38 +00:00
$this -> query_type = 'show' ;
2014-05-05 03:38:15 +00:00
} elseif ( stripos ( $this -> query_type , 'show columns' ) !== false | | stripos ( $this -> query_type , 'show fields' ) !== false || stripos ( $this -> query_type , 'show full columns' ) !== false ) {
2013-07-07 06:49:38 +00:00
$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' ;
} elseif ( stripos ( $this -> query_type , 'show variables' ) !== false || stripos ( $this -> query_type , 'show global variables' ) !== false || stripos ( $this -> query_type , 'show session variables' ) !== false ) {
$this -> query_type = 'show_variables' ;
} else {
return false ;
}
}
2013-07-24 02:31:01 +00:00
if ( stripos ( $this -> query_type , 'drop index' ) !== false ) {
$this -> query_type = 'drop_index' ;
}
2013-07-07 06:49:38 +00:00
return true ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to execute INSERT query for SQLite version 3.7 . 11 or later .
2014-01-29 09:35:06 +00:00
*
* SQLite version 3.7 . 11 began to support multiple rows insert with values
2013-07-07 06:49:38 +00:00
* clause . This is for that version or later .
2014-01-29 09:35:06 +00:00
*
2013-07-07 06:49:38 +00:00
* @ param string $query
*/
private function execute_insert_query_new ( $query ) {
2014-02-05 19:29:23 +00:00
$engine = $this -> prepare_engine ( $this -> query_type );
2013-07-07 06:49:38 +00:00
$this -> rewritten_query = $engine -> rewrite_query ( $query , $this -> query_type );
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Rewritten: \n " . $this -> rewritten_query ;
2013-07-07 06:49:38 +00:00
$this -> extract_variables ();
2014-02-05 19:29:23 +00:00
$statement = $this -> prepare_query ();
2013-07-07 06:49:38 +00:00
$this -> execute_query ( $statement );
}
/**
2014-04-17 02:45:32 +00:00
* Method to execute INSERT query for SQLite version 3.7 . 10 or lesser .
2014-01-29 09:35:06 +00:00
*
* It executes the INSERT query for SQLite version 3.7 . 10 or lesser . It is
* necessary to rewrite multiple row values .
*
2013-07-07 06:49:38 +00:00
* @ param string $query
*/
private function execute_insert_query ( $query ) {
global $wpdb ;
$multi_insert = false ;
2014-02-05 19:29:23 +00:00
$statement = null ;
$engine = $this -> prepare_engine ( $this -> query_type );
2013-07-07 06:49:38 +00:00
if ( preg_match ( '/(INSERT.*?VALUES\\s*)(\(.*\))/imsx' , $query , $matched )) {
$query_prefix = $matched [ 1 ];
2014-02-05 19:29:23 +00:00
$values_data = $matched [ 2 ];
2013-07-07 06:49:38 +00:00
if ( stripos ( $values_data , 'ON DUPLICATE KEY' ) !== false ) {
$exploded_parts = $values_data ;
} elseif ( stripos ( $query_prefix , " INSERT INTO $wpdb->comments " ) !== false ) {
$exploded_parts = $values_data ;
} else {
$exploded_parts = $this -> parse_multiple_inserts ( $values_data );
}
$count = count ( $exploded_parts );
if ( $count > 1 ) {
$multi_insert = true ;
}
}
if ( $multi_insert ) {
$first = true ;
foreach ( $exploded_parts as $value ) {
if ( substr ( $value , - 1 , 1 ) === ')' ) {
$suffix = '' ;
} else {
$suffix = ')' ;
}
2014-02-05 19:29:23 +00:00
$query_string = $query_prefix . ' ' . $value . $suffix ;
$this -> rewritten_query = $engine -> rewrite_query ( $query_string , $this -> query_type );
$this -> queries [] = " Rewritten: \n " . $this -> rewritten_query ;
2013-07-07 06:49:38 +00:00
$this -> extracted_variables = array ();
$this -> extract_variables ();
if ( $first ) {
$statement = $this -> prepare_query ();
$this -> execute_query ( $statement );
$first = false ;
} else {
$this -> execute_query ( $statement );
}
}
} else {
$this -> rewritten_query = $engine -> rewrite_query ( $query , $this -> query_type );
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Rewritten: \n " . $this -> rewritten_query ;
2013-07-07 06:49:38 +00:00
$this -> extract_variables ();
$statement = $this -> prepare_query ();
$this -> execute_query ( $statement );
}
}
/**
2014-04-17 02:45:32 +00:00
* Method to help rewriting multiple row values insert query .
2014-01-29 09:35:06 +00:00
*
* It splits the values clause into an array to execute separately .
*
2013-07-07 06:49:38 +00:00
* @ param string $values
* @ return array
*/
private function parse_multiple_inserts ( $values ) {
$tokens = preg_split ( " /(''|(?<! \\ \\ )'|(?<! \ () \ ),(?= \ s* \ ())/s " , $values , - 1 , PREG_SPLIT_DELIM_CAPTURE );
$exploded_parts = array ();
$part = '' ;
$literal = false ;
foreach ( $tokens as $token ) {
switch ( $token ) {
case " ), " :
if ( ! $literal ) {
$exploded_parts [] = $part ;
$part = '' ;
} else {
$part .= $token ;
}
break ;
case " ' " :
if ( $literal ) {
$literal = false ;
} else {
$literal = true ;
}
$part .= $token ;
break ;
default :
$part .= $token ;
break ;
}
}
if ( ! empty ( $part )) {
$exploded_parts [] = $part ;
}
return $exploded_parts ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to execute CREATE query .
2014-01-29 09:35:06 +00:00
*
2013-07-07 06:49:38 +00:00
* @ param string
* @ return boolean
*/
private function execute_create_query ( $query ) {
2014-02-05 19:29:23 +00:00
$engine = $this -> prepare_engine ( $this -> query_type );
2013-07-07 06:49:38 +00:00
$rewritten_query = $engine -> rewrite_query ( $query );
2014-02-05 19:29:23 +00:00
$reason = 0 ;
$message = '' ;
2013-07-07 06:49:38 +00:00
// $queries = explode(";", $this->rewritten_query);
try {
$this -> beginTransaction ();
foreach ( $rewritten_query as $single_query ) {
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Executing: \n " . $single_query ;
$single_query = trim ( $single_query );
2013-07-07 06:49:38 +00:00
if ( empty ( $single_query )) continue ;
$this -> pdo -> exec ( $single_query );
}
$this -> commit ();
} catch ( PDOException $err ) {
2014-02-05 19:29:23 +00:00
$reason = $err -> getCode ();
2013-07-07 06:49:38 +00:00
$message = $err -> getMessage ();
if ( 5 == $reason || 6 == $reason ) {
$this -> commit ();
} else {
$this -> rollBack ();
}
}
if ( $reason > 0 ) {
2013-09-25 07:40:16 +00:00
$err_message = sprintf ( " Problem in creating table or index. Error was: %s " , $message );
2013-07-07 06:49:38 +00:00
$this -> set_error ( __LINE__ , __FUNCTION__ , $err_message );
return false ;
}
return true ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to execute ALTER TABLE query .
2014-01-29 09:35:06 +00:00
*
2013-07-07 06:49:38 +00:00
* @ param string
* @ return boolean
*/
private function execute_alter_query ( $query ) {
2014-02-05 19:29:23 +00:00
$engine = $this -> prepare_engine ( $this -> query_type );
$reason = 0 ;
$message = '' ;
$re_query = '' ;
2013-07-07 06:49:38 +00:00
$rewritten_query = $engine -> rewrite_query ( $query , $this -> query_type );
2013-09-11 19:39:01 +00:00
if ( is_array ( $rewritten_query ) && array_key_exists ( 'recursion' , $rewritten_query )) {
$re_query = $rewritten_query [ 'recursion' ];
unset ( $rewritten_query [ 'recursion' ]);
}
2013-07-07 06:49:38 +00:00
try {
$this -> beginTransaction ();
if ( is_array ( $rewritten_query )) {
foreach ( $rewritten_query as $single_query ) {
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Executing: \n " . $single_query ;
$single_query = trim ( $single_query );
2013-07-07 06:49:38 +00:00
if ( empty ( $single_query )) continue ;
$this -> pdo -> exec ( $single_query );
}
} else {
2014-02-05 19:29:23 +00:00
$this -> queries [] = " Executing: \n " . $rewritten_query ;
2013-07-07 06:49:38 +00:00
$rewritten_query = trim ( $rewritten_query );
$this -> pdo -> exec ( $rewritten_query );
}
$this -> commit ();
} catch ( PDOException $err ) {
2014-02-05 19:29:23 +00:00
$reason = $err -> getCode ();
2013-07-07 06:49:38 +00:00
$message = $err -> getMessage ();
if ( 5 == $reason || 6 == $reason ) {
$this -> commit ();
usleep ( 10000 );
} else {
$this -> rollBack ();
}
}
2013-09-11 19:39:01 +00:00
if ( $re_query != '' ) {
$this -> query ( $re_query );
}
2013-07-07 06:49:38 +00:00
if ( $reason > 0 ) {
2013-09-25 07:40:16 +00:00
$err_message = sprintf ( " Problem in executing alter query. Error was: %s " , $message );
2013-07-07 06:49:38 +00:00
$this -> set_error ( __LINE__ , __FUNCTION__ , $err_message );
return false ;
}
return true ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to execute SHOW VARIABLES query
2013-07-07 06:49:38 +00:00
*
2014-01-29 09:35:06 +00:00
* This query is meaningless for SQLite . This function returns null data with some
* exceptions and only avoids the error message .
2013-07-07 06:49:38 +00:00
*
* @ param string
* @ return ObjectArray
*/
private function show_variables_workaround ( $query ) {
$dummy_data = array ( 'Variable_name' => '' , 'Value' => null );
2014-02-05 19:29:23 +00:00
$pattern = '/SHOW\\s*VARIABLES\\s*LIKE\\s*(.*)?$/im' ;
2013-07-07 06:49:38 +00:00
if ( preg_match ( $pattern , $query , $match )) {
$value = str_replace ( " ' " , '' , $match [ 1 ]);
$dummy_data [ 'Variable_name' ] = trim ( $value );
// this is set for Wordfence Security Plugin
2013-09-15 21:04:53 +00:00
if ( $value == 'max_allowed_packet' ) {
$dummy_data [ 'Value' ] = 1047552 ;
} else {
$dummy_data [ 'Value' ] = '' ;
}
2013-07-07 06:49:38 +00:00
}
2014-02-05 19:29:23 +00:00
$_results [] = new ObjectArray ( $dummy_data );
$this -> results = $_results ;
$this -> num_rows = count ( $this -> results );
2013-07-07 06:49:38 +00:00
$this -> return_value = $this -> num_rows ;
return true ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* 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 .
2014-01-29 09:35:06 +00:00
*
* @ param string $engine
*/
2013-07-07 06:49:38 +00:00
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 ();
2013-11-06 19:23:32 +00:00
} elseif ( in_array ( $this -> query_type , array ( 'check' , 'analyze' ))) {
$this -> convert_result_check_or_analyze ();
2013-07-07 06:49:38 +00:00
} else {
$this -> results = $this -> _results ;
}
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to format the error messages and put out to the file .
2014-01-29 09:35:06 +00:00
*
* 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
*/
2013-07-07 06:49:38 +00:00
private function set_error ( $line , $function , $message ){
global $wpdb ;
2014-02-05 19:29:23 +00:00
$this -> errors [] = array ( " line " => $line , " function " => $function );
2013-07-07 06:49:38 +00:00
$this -> error_messages [] = $message ;
2014-02-05 19:29:23 +00:00
$this -> is_error = true ;
2013-07-07 06:49:38 +00:00
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 );
}
/**
2014-04-17 02:45:32 +00:00
* Method to change the queried data to PHP object format .
2014-01-29 09:35:06 +00:00
*
* It takes the associative array of query results and creates a numeric
* array of anonymous objects
*
* @ access private
2013-07-07 06:49:38 +00:00
*/
private function convert_to_object (){
$_results = array ();
if ( count ( $this -> results ) === 0 ){
echo $this -> get_error_message ();
} else {
foreach ( $this -> results as $row ){
$_results [] = new ObjectArray ( $row );
}
}
$this -> results = $_results ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to convert the SHOW COLUMNS query data to an object .
2014-01-29 09:35:06 +00:00
*
* It rewrites pragma results to mysql compatible array
2013-07-07 06:49:38 +00:00
* when query_type is describe , we use sqlite pragma function .
2014-01-29 09:35:06 +00:00
*
* @ access private
2013-07-07 06:49:38 +00:00
*/
private function convert_to_columns_object () {
$_results = array ();
$_columns = array ( //Field names MySQL SHOW COLUMNS returns
'Field' => " " ,
'Type' => " " ,
'Null' => " " ,
'Key' => " " ,
'Default' => " " ,
'Extra' => " "
);
if ( count ( $this -> _results ) === 0 ) {
echo $this -> get_error_message ();
} else {
foreach ( $this -> _results as $row ) {
$_columns [ 'Field' ] = $row -> name ;
$_columns [ 'Type' ] = $row -> type ;
$_columns [ 'Null' ] = $row -> notnull ? " NO " : " YES " ;
$_columns [ 'Key' ] = $row -> pk ? " PRI " : " " ;
$_columns [ 'Default' ] = $row -> dflt_value ;
2014-02-05 19:29:23 +00:00
$_results [] = new ObjectArray ( $_columns );
2013-07-07 06:49:38 +00:00
}
}
$this -> results = $_results ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to convert SHOW INDEX query data to PHP object .
2014-01-29 09:35:06 +00:00
*
* It rewrites the result of SHOW INDEX to the Object compatible with MySQL
2013-09-09 01:39:25 +00:00
* added the WHERE clause manipulation ( ver 1.3 . 1 )
2014-01-29 09:35:06 +00:00
*
* @ access private
2013-07-07 06:49:38 +00:00
*/
private function convert_to_index_object () {
$_results = array ();
$_columns = array (
'Table' => " " ,
'Non_unique' => " " , // unique -> 0, not unique -> 1
'Key_name' => " " , // the name of the index
'Seq_in_index' => " " , // column sequence number in the index. begins at 1
'Column_name' => " " ,
'Collation' => " " , //A(scend) or NULL
'Cardinality' => " " ,
'Sub_part' => " " , // set to NULL
'Packed' => " " , // How to pack key or else NULL
'Null' => " " , // If column contains null, YES. If not, NO.
'Index_type' => " " , // BTREE, FULLTEXT, HASH, RTREE
'Comment' => " "
);
if ( count ( $this -> _results ) == 0 ) {
echo $this -> get_error_message ();
} else {
foreach ( $this -> _results as $row ) {
if ( $row -> type == 'table' && ! stripos ( $row -> sql , 'primary' ))
continue ;
if ( $row -> type == 'index' && stripos ( $row -> name , 'sqlite_autoindex' ) !== false )
continue ;
switch ( $row -> type ) {
case 'table' :
$pattern1 = '/^\\s*PRIMARY.*\((.*)\)/im' ;
$pattern2 = '/^\\s*(\\w+)?\\s*.*PRIMARY.*(?!\()/im' ;
if ( preg_match ( $pattern1 , $row -> sql , $match )) {
$col_name = trim ( $match [ 1 ]);
$_columns [ 'Key_name' ] = 'PRIMARY' ;
$_columns [ 'Non_unique' ] = 0 ;
$_columns [ 'Column_name' ] = $col_name ;
} elseif ( preg_match ( $pattern2 , $row -> sql , $match )) {
$col_name = trim ( $match [ 1 ]);
$_columns [ 'Key_name' ] = 'PRIMARY' ;
$_columns [ 'Non_unique' ] = 0 ;
$_columns [ 'Column_name' ] = $col_name ;
}
break ;
case 'index' :
if ( stripos ( $row -> sql , 'unique' ) !== false ) {
$_columns [ 'Non_unique' ] = 0 ;
} else {
$_columns [ 'Non_unique' ] = 1 ;
}
if ( preg_match ( '/^.*\((.*)\)/i' , $row -> sql , $match )) {
$col_name = str_replace ( " ' " , '' , $match [ 1 ]);
$_columns [ 'Column_name' ] = trim ( $col_name );
}
$_columns [ 'Key_name' ] = $row -> name ;
break ;
default :
break ;
}
$_columns [ 'Table' ] = $row -> tbl_name ;
$_columns [ 'Collation' ] = NULL ;
$_columns [ 'Cardinality' ] = 0 ;
$_columns [ 'Sub_part' ] = NULL ;
$_columns [ 'Packed' ] = NULL ;
$_columns [ 'Null' ] = 'NO' ;
$_columns [ 'Index_type' ] = 'BTREE' ;
$_columns [ 'Comment' ] = '' ;
2014-02-05 19:29:23 +00:00
$_results [] = new ObjectArray ( $_columns );
2013-07-07 06:49:38 +00:00
}
2013-09-09 01:39:25 +00:00
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 ;
}
}
}
2013-07-07 06:49:38 +00:00
}
$this -> results = $_results ;
}
2014-01-29 09:35:06 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to the CHECK query data to an object .
2014-01-29 09:35:06 +00:00
*
* @ access private
*/
2013-11-06 19:23:32 +00:00
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'
);
}
2014-02-05 19:29:23 +00:00
$_results [] = new ObjectArray ( $_columns );
2013-11-06 19:23:32 +00:00
$this -> results = $_results ;
}
2013-07-07 06:49:38 +00:00
/**
2014-04-17 02:45:32 +00:00
* Method to check SQLite library version .
2014-01-29 09:35:06 +00:00
*
* This is used for checking if SQLite can execute multiple rows insert .
*
2013-07-07 06:49:38 +00:00
* @ return version number string or 0
2014-01-29 09:35:06 +00:00
* @ access private
2013-07-07 06:49:38 +00:00
*/
private function get_sqlite_version () {
try {
$statement = $this -> pdo -> prepare ( 'SELECT sqlite_version()' );
$statement -> execute ();
$result = $statement -> fetch ( PDO :: FETCH_NUM );
return $result [ 0 ];
} catch ( PDOException $err ) {
return '0' ;
}
}
/**
2014-04-17 02:45:32 +00:00
* Method to call PDO :: beginTransaction () .
2014-01-29 09:35:06 +00:00
*
2013-07-07 06:49:38 +00:00
* @ see PDO :: beginTransaction ()
2014-01-29 09:35:06 +00:00
* @ return boolean
2013-07-07 06:49:38 +00:00
*/
public function beginTransaction () {
if ( $this -> has_active_transaction ) {
return false ;
} else {
$this -> has_active_transaction = $this -> pdo -> beginTransaction ();
return $this -> has_active_transaction ;
}
}
/**
2014-04-17 02:45:32 +00:00
* Method to call PDO :: commit () .
2014-01-29 09:35:06 +00:00
*
2013-07-07 06:49:38 +00:00
* @ see PDO :: commit ()
*/
public function commit () {
$this -> pdo -> commit ();
$this -> has_active_transaction = false ;
}
/**
2014-04-17 02:45:32 +00:00
* Method to call PDO :: rollBack () .
2014-01-29 09:35:06 +00:00
*
2013-07-07 06:49:38 +00:00
* @ see PDO :: rollBack ()
*/
public function rollBack () {
$this -> pdo -> rollBack ();
$this -> has_active_transaction = false ;
}
}
2014-01-29 09:35:06 +00:00
/**
* Class to change queried data to PHP object .
*
* @ author kjm
*/
2013-07-07 06:49:38 +00:00
class ObjectArray {
function __construct ( $data = null , & $node = null ) {
foreach ( $data as $key => $value ) {
if ( is_array ( $value ) ) {
if ( ! $node ) {
$node =& $this ;
}
$node -> $key = new stdClass ();
self :: __construct ( $value , $node -> $key );
} else {
if ( ! $node ) {
$node =& $this ;
}
$node -> $key = $value ;
}
}
}
}
?>