sqlite-integration/pdoengine.class.php

912 lines
29 KiB
PHP
Raw Normal View History

<?php
/**
* @package SQLite Integration
* @version 1.0
* @author Kojima Toshiyasu, Justin Adie
*
*/
/**
* This class does the real work
* accepts a request from wpdb class, initialize PDO instance,
* execute SQL statement, and returns the results to wpdb class.
*/
class PDOEngine extends PDO {
public $is_error = false;
public $found_rows_result;
private $rewritten_query;
private $query_type;
private $results = null;
private $_results = null;
private $pdo;
private $prepared_query;
private $extracted_variables = array();
private $error_messages = array();
private $errors;
public $queries = array();
private $last_insert_id;
private $affected_rows;
private $column_names;
private $num_rows;
private $return_value;
private $can_insert_multiple_rows = false;
private $param_num;
protected $has_active_transaction = false;
/**
* Constructor
* registers __destruct function and initialize the database environment
* @param array $DatabaseParams
*/
function __construct() {
register_shutdown_function(array($this, '__destruct'));
$this->init();
}
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
* @return boolean
*/
private function init() {
$dsn = 'sqlite:' . FQDB;
$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
));
$statement = $this->pdo->query("SELECT COUNT(*) FROM sqlite_master WHERE type='table'");
$number_of_tables = $statement->fetchColumn(0);
$statement = null;
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 {
$message = __("Database connection error!<br />", 'sqlite-integration');
$message .= sprintf(__("Error message is: %s", 'sqlite-integration'), $err->getMessage());
$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) {
$message = __("Database connection error!<br />", 'sqlite-integration');
$message .= sprintf(__("Error message is: %s", 'sqlite-integration'), $err->getMessage());
$this->set_error(__LINE__, __FUNCTION__, $message);
return false;
}
$this->make_sqlite_tables();
}
}
/**
* Make database direcotry and .htaccess file
* executed once while installation process
*/
private function prepare_directory() {
global $wpdb;
$u = umask(0000);
if (!is_dir(FQDBDIR)) {
if (!@mkdir(FQDBDIR, 0777, true)) {
umask($u);
$message = __('Unable to create the required directory! Please check your server settings.', 'sqlite-integration');
echo $message;
return false;
}
}
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;
}
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');
echo $message;
return false;
}
fwrite($fh, "DENY FROM ALL");
fclose($fh);
}
umask($u);
return true;
}
/**
* Make database file itself and WordPress tables
* executed once while installation process
*/
private function make_sqlite_tables() {
require_once PDODIR . "install.php";
}
public function query($query) {
$this->flush();
$this->queries[] = "Raw query:\t$query";
$res = $this->determine_query_type($query);
if (!$res) {
$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)) {
case 'foundrows':
$this->results = $this->found_rows_result;
$this->num_rows = count($this->results);
$this->found_rows_result = null;
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;
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);
$this->return_value = $result;
} else {
$this->return_value = false;
}
break;
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->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) {
file_put_contents(FQDBDIR . 'debug.txt', $this->get_debug_info(), FLIE_APPEND);
}
return $this->return_value;
}
public function get_insert_id() {
return $this->last_insert_id;
}
public function get_affected_rows() {
return $this->affected_rows;
}
public function get_columns() {
return $this->column_names;
}
public function get_query_results() {
return $this->results;
}
public function get_num_rows() {
return $this->num_rows;
}
public function get_return_value() {
return $this->return_value;
}
public function get_error_message(){
if (count($this->error_messages) === 0){
$this->is_error = false;
$this->error_messages = array();
return '';
}
$output = '<div style="clear:both">&nbsp;</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();
$output .= "<pre>" . ob_get_contents() . "</pre>";
ob_end_clean();
return $output;
}
private function get_debug_info(){
$output = '';
foreach ($this->queries as $q){
$output .= $q ."\r\n";
}
return $output;
}
private function flush(){
$this->rewritten_query = '';
$this->query_type = '';
$this->results = null;
$this->_results = null;
$this->last_insert_id = null;
$this->affected_rows = null;
$this->column_names = array();
$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;
}
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;
}
private function prepare_query(){
$this->queries[] = "Prepare:\t". $this->prepared_query;
$reason = 0;
$message = '';
$statement = null;
do {
try {
$statement = $this->pdo->prepare($this->prepared_query);
} catch (PDOException $err) {
$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);
$this->set_error(__LINE__, __FUNCTION__, $err_message);
}
return $statement;
}
private function execute_query($statement) {
$reason = 0;
$message = '';
if (!is_object($statement))
return;
if (count($this->extracted_variables) > 0) {
$this->queries[] = "Executing: ". var_export($this->extracted_variables, true);
do {
if ($this->query_type == 'update' || $this->query_type == 'replace') {
try {
$this->beginTransaction();
$statement->execute($this->extracted_variables);
$this->commit();
} catch (PDOException $err) {
$reason = $err->getCode();
$message = $err->getMessage();
$this->rollBack();
}
} else {
try {
$statement->execute($this->extracted_variables);
} catch (PDOException $err) {
$reason = $err->getCode();
$message = $err->getMessage();
}
}
} while (5 == $reason || 6 == $reason);
} else {
$this->queries[] = "Executing: (no parameters)\t ";
do{
if ($this->query_type == 'update' || $this->query_type == 'replace') {
try {
$this->beginTransaction();
$statement->execute();
$this->commit();
} catch (PDOException $err) {
$reason = $err->getCode();
$message = $err->getMessage();
$this->rollBack();
}
} else {
try {
$statement->execute();
} catch (PDOException $err) {
$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);
$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) {
case "insert":
case "update":
case "replace":
$this->last_insert_id = $this->pdo->lastInsertId();
$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 "foundrows":
$this->num_rows = count($this->_results);
$this->return_value = $this->num_rows;
break;
case "delete":
$this->affected_rows = $statement->rowCount();
$this->return_value = $this->affected_rows;
break;
case "alter":
case "drop":
case "create":
case "optimize":
case "truncate":
if ($this->is_error) {
$this->return_value = false;
} else {
$this->return_value = true;
}
break;
}
}
private function extract_variables() {
if ($this->query_type == 'create') {
$this->prepared_query = $this->rewritten_query;
return;
}
//long queries can really kill this
$pattern = '/(?<!\\\\)([\'"])(.*?)(?<!\\\\)\\1/imsx';
$_limit = $limit = ini_get('pcre.backtrack_limit');
do {
if ($limit > 10000000) {
$message = __("The query is too big to parse properly", 'sqlite-integration');
$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);
$this->queries[]= "With Placeholders: $query ";
$this->prepared_query = $query;
}
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.' ';
}
/**
* 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
* @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);
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) {
if (stripos($this->query_type, 'show tables') !== false) {
$this->query_type = 'show';
} elseif (stripos($this->query_type, 'show columns') !== false || stripos($this->query_type, 'show fields') !== 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';
} 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;
}
}
if (stripos($this->query_type, 'drop index') !== false) {
$this->query_type = 'drop_index';
}
return true;
}
/**
* SQLite version 3.7.11 began 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);
$this->rewritten_query = $engine->rewrite_query($query, $this->query_type);
$this->queries[] = "Rewritten: $this->rewritten_query";
$this->extract_variables();
$statement = $this->prepare_query();
$this->execute_query($statement);
}
/**
* executes the INSERT query for SQLite version 3.7.10 or lesser
* @param string $query
*/
private function execute_insert_query($query) {
global $wpdb;
$multi_insert = false;
$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];
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 = ')';
}
$query_string = $query_prefix . ' ' . $value . $suffix;
$this->rewritten_query = $engine->rewrite_query($query_string, $this->query_type);
$this->queries[] = "Rewritten: $this->rewritten_query";
$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);
$this->queries[] = "Rewritten: $this->rewritten_query";
$this->extract_variables();
$statement = $this->prepare_query();
$this->execute_query($statement);
}
}
/**
* helper function for execute_insert_query()
* @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;
}
/**
* function to execute CREATE query
* @param string
* @return boolean
*/
private function execute_create_query($query) {
$engine = $this->prepare_engine($this->query_type);
$rewritten_query = $engine->rewrite_query($query);
$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);
if (empty($single_query)) continue;
$this->pdo->exec($single_query);
}
$this->commit();
} catch (PDOException $err) {
$reason = $err->getCode();
$message = $err->getMessage();
if (5 == $reason || 6 == $reason) {
$this->commit();
} else {
$this->rollBack();
}
}
if ($reason > 0) {
$err_message = sprintf(__("Problem in creating table or index. Error was: %s", 'sqlite-integration'), $message);
$this->set_error(__LINE__, __FUNCTION__, $err_message);
return false;
}
return true;
}
/**
* function 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 = '';
$rewritten_query = $engine->rewrite_query($query, $this->query_type);
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);
if (empty($single_query)) continue;
$this->pdo->exec($single_query);
}
} else {
$this->queries[] = "Executing:\t" . $rewritten_query;
$rewritten_query = trim($rewritten_query);
$this->pdo->exec($rewritten_query);
}
$this->commit();
} catch (PDOException $err) {
$reason = $err->getCode();
$message = $err->getMessage();
if (5 == $reason || 6 == $reason) {
$this->commit();
usleep(10000);
} else {
$this->rollBack();
}
}
if ($reason > 0) {
$err_message = sprintf(__("Problem in executing alter query. Error was: %s", 'sqlite-integration'), $message);
$this->set_error(__LINE__, __FUNCTION__, $err_message);
return false;
}
return true;
}
/**
* function to execute SHOW VARIABLES query
*
* This query is meaningless for SQLite. This function returns null data and
* avoid 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';
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;
}
$_results[] = new ObjectArray($dummy_data);
$this->results = $_results;
$this->num_rows = count($this->results);
$this->return_value = $this->num_rows;
return true;
}
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();
} else {
$this->results = $this->_results;
}
}
private function set_error ($line, $function, $message){
global $wpdb;
$this->errors[] = array("line"=>$line, "function"=>$function);
$this->error_messages[] = $message;
$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
*/
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;
}
/**
* method to rewrite pragma results to mysql compatible array
* when query_type is describe, we use sqlite pragma function.
* see pdo_sqlite_driver.php
*/
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;
$_results[] = new ObjectArray($_columns);
}
}
$this->results = $_results;
}
/**
* rewrites the result of SHOW INDEX to the Object compatible with MySQL
*/
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'] = '';
$_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
* @return version number string or 0
*/
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';
}
}
/**
* function call to PDO::beginTransaction()
* @see PDO::beginTransaction()
*/
public function beginTransaction() {
if ($this->has_active_transaction) {
return false;
} else {
$this->has_active_transaction = $this->pdo->beginTransaction();
return $this->has_active_transaction;
}
}
/**
* function call to PDO::commit()
* @see PDO::commit()
*/
public function commit() {
$this->pdo->commit();
$this->has_active_transaction = false;
}
/**
* function call to PDO::rollBack()
* @see PDO::rollBack()
*/
public function rollBack() {
$this->pdo->rollBack();
$this->has_active_transaction = false;
}
}
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;
}
}
}
}
?>