| Server IP : 195.130.67.5 / Your IP : 216.73.217.154 Web Server : Microsoft-IIS/10.0 System : Windows NT WEBSERVER1 10.0 build 17763 (Windows Server 2016) i586 User : IUSR ( 0) PHP Version : 7.4.19 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Old Sites/Civilgeo/ojs/lib/pkp/classes/db/ |
Upload File : |
<?php
/**
* @file classes/db/SQLParser.inc.php
*
* Copyright (c) 2000-2012 John Willinsky
* Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
*
* @class SQLParser
* @ingroup db
*
* @brief Class for parsing and executing statements in SQL files.
*/
// $Id$
class SQLParser {
/** @var $driver string The database driver */
var $driver;
/** @var $dataSource object The database connection object */
var $dataSource;
/** @var $debug boolean Enable debugging (print SQL statements as they are executed) */
var $debug;
/** @var $errorMsg string Error message */
var $errorMsg;
/** @var $commentDelim string Delimiter for SQL comments used by the data source */
var $commentDelim;
/** @var $statementDelim string Delimiter for SQL statements used by the data source */
var $statementDelim;
/**
* Constructor.
* @param $driver string the database driver (currently only "mysql" is supported)
* @param $debug boolean echo each statement as it's executed
*/
function SQLParser($driver, &$dataSource, $debug = false) {
$this->driver = $driver;
$this->dataSource =& $dataSource;
$this->debug = $debug;
$this->errorMsg = array();
$this->commentDelim = '(\-\-|#)';
$this->statementDelim = ';';
}
/**
* Parse an SQL file and execute all SQL statements in it.
* @param $file string full path to the file
* @param $failOnError boolean stop execution if an error is encountered
* @return boolean true if no errors occurred, false otherwise
*/
function executeFile($file, $failOnError = true) {
if (!file_exists($file) || !is_readable($file)) {
array_push($this->errorMsg, "$file does not exist or is not readble!");
return false;
}
// Read file and break up into SQL statements
$sql = join('', file($file));
$this->stripComments($sql);
$statements =& $this->parseStatements($sql);
// Execute each SQL statement
for ($i=0, $count=count($statements); $i < $count; $i++) {
if ($this->debug) {
echo 'Executing: ', $statements[$i], "\n\n";
}
$this->dataSource->execute($statements[$i]);
if ($this->dataSource->errorNo() != 0) {
// An error occurred executing the statement
array_push($this->errorMsg, $this->dataSource->errorMsg());
if ($failOnError) {
// Abort if fail on error is enabled
return false;
} else {
$error = true;
}
}
}
return isset($error) ? false : true;
}
/**
* Strip SQL comments from SQL string.
* @param $sql string
*/
function stripComments(&$sql) {
$sql = trim(String::regexp_replace(sprintf('/^\s*%s(.*)$/m', $this->commentDelim), '', $sql));
}
/**
* Parse SQL content into individual SQL statements.
* @param $sql string
* @return array
*/
function &parseStatements(&$sql) {
$statements = array();
$statementsTmp = explode($this->statementDelim, $sql);
$currentStatement = '';
$numSingleQuotes = $numEscapedSingleQuotes = 0;
// This method for parsing the SQL statements was adapted from one used in phpBB (http://www.phpbb.com/)
for ($i=0, $count=count($statementsTmp); $i < $count; $i++) {
// Get total number of single quotes in string
$numSingleQuotes += String::substr_count($statementsTmp[$i], "'");
// Get number of escaped single quotes
$numEscapedSingleQuotes += String::regexp_match_all("/(?<!\\\\)(\\\\\\\\)*\\\\'/", $statementsTmp[$i], $matches);
$currentStatement .= $statementsTmp[$i];
if (($numSingleQuotes - $numEscapedSingleQuotes) % 2 == 0) {
// Even number of unescaped single quotes, so statement must be complete
if (trim($currentStatement) !== '') {
array_push($statements, trim($currentStatement));
}
$currentStatement = '';
$numSingleQuotes = $numEscapedSingleQuotes = 0;
} else {
// The statement is not complete, the delimiter must be inside the statement
$currentStatement .= $this->statementDelim;
}
}
return $statements;
}
/**
* Return the last error message that occurred in parsing.
* @return string
*/
function getErrorMsg() {
return count($this->errorMsg) == 0 ? null : array_pop($this->errorMsg);
}
}
?>