<?php
/**
* SeekQuarry/Yioop --
* Open Source Pure PHP Search Engine, Crawler, and Indexer
*
* Copyright (C) 2009, 2010, 2011 Chris Pollett hide@address.com
*
* LICENSE:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* END LICENSE
*
* @author Chris Pollett hide@address.com
* @package seek_quarry
* @subpackage datasource_manager
* @license http://www.gnu.org/licenses/ GPL3
* @link http://www.seekquarry.com/
* @copyright 2009, 2010, 2011
* @filesource
*/
if(!defined('BASE_DIR')) {echo "BAD REQUEST"; exit();}
/** For timer function, if debug level set to include query statistics */
require_once BASE_DIR."/lib/utility.php";
/**
*
* This abstract class defines the interface through which
* the seek_quarry program communicates with a database and the
* filesystem.
*
* @author Chris Pollett
* @package seek_quarry
* @subpackage datasource_manager
*/
abstract class DatasourceManager
{
/**
* Used to store statistics about what queries have been run depending on
* the debug level
* @var string
*/
var $query_log;
/**
* Used to store the total time taken to execute queries
* @var int
*/
var $total_time;
/** Sets up the query_log for query statistics */
function __construct() {
$this->query_log = array();
$this->total_time = 0;
}
/**
* Connects to a DBMS using data provided or from config.php
*
* @param string $db_url the url of where the database is located
* (not used in all dbms's)
* @param string $db_user the user to connect as
* @param string $db_password the password of the user to connect as
* @return mixed return false if not successful and some kind of
* connection object/identifier otherwise
*/
abstract function connect($db_url = DB_URL, $db_user = DB_USER,
$db_password = DB_PASSWORD);
/**
* Connects to the correct DB on that system
*/
abstract function selectDB($db_name);
/**
* Closes connections to DBMS
*
*/
abstract function disconnect();
/**
* Executes the supplied sql command on the database, depending on debug
* levels computes query statistics
*
* This method operates either query or data manipulation statements
*
* @param string $sql SQL statement to execute
* @return mixed false if query fails, resource or true otherwise
*/
function execute($sql)
{
if(QUERY_STATISTICS) {
$query_info = array();
$query_info['QUERY'] = $sql;
$start_time = microtime();
}
$result =$this->exec($sql);
if(QUERY_STATISTICS) {
$query_info['ELAPSED_TIME'] = changeInMicrotime($start_time);
$this->total_time += $query_info['ELAPSED_TIME'];
$this->query_log[] = $query_info;
}
return $result;
}
/**
* Hook Method for execute(). Executes the sql command on the database
*
* This method operates on either query or data manipulation statements
*
* @param string $sql SQL statement to execute
* @return mixed false if query fails, resource or true otherwise
*/
abstract function exec($sql);
/**
* Returns the number of rows affected by the last sql statement
*
* @return int the number of rows affected by the last
* insert, update, delete
*/
abstract function affectedRows();
/**
* Returns the ID generated by the last insert statement
* if table has an auto increment key column
*
* @return string the ID of the insert
*/
abstract function insertID();
/**
* Returns the next row from the provided result set
*
* @param resource $result result set reference of a query
* @return array the next row from the result set as an
* associative array in the form column_name => value
*/
abstract function fetchArray($result);
/**
* Used to escape strings before insertion in the
* database to avoid SQL injection
*
* @param string $str string to escape
* @return string a string which is safe to insert into the db
*/
abstract function escapeString($str);
/**
* Recursively delete a directory
*
* @param string $dir Directory name
* @param boolean $deleteRootToo Delete specified top directory as well
*/
function unlinkRecursive($dir, $deleteRootToo = true)
{
$this->traverseDirectory($dir, "deleteFileOrDir", $deleteRootToo);
}
/**
* Recursively chmod a directory to 0777
*
* @param string $dir Directory name
* @param boolean $chmodRootToo chmod specified top-level directory as well
*/
function setWorldPermissionsRecursive($dir, $chmodRootToo = true)
{
$this->traverseDirectory($dir, "setWorldPermissions", $chmodRootToo);
}
/**
* Recursively copies a source directory to a destination directory
*
* It would have been coon to use traverseDirectory to implement this, but
* it was a little bit too much of a stretch to showhorn the code to match
*
* @param string $source_dir the name of the source directory
* @param string $desitnation_dir the name of the destination directory
*/
function copyRecursive($source_dir, $destination_dir)
{
if(!$dh = @opendir($source_dir)) {
return;
}
if(!file_exists($destination_dir)) {
@mkdir($destination_dir);
if(!file_exists($destination_dir)) {
return;
}
chmod($destination_dir, 0777);
}
while(false !== ( $obj = readdir($dh)) ) {
if (( $obj != '.' ) && ( $obj != '..' )) {
if ( is_dir($source_dir . '/' . $obj) ) {
$this->copyRecursive($source_dir . '/' .
$obj, $destination_dir . '/' . $obj);
}
else {
copy($source_dir . '/' .
$obj, $destination_dir . '/' . $obj);
chmod($destination_dir . '/' . $obj, 0777);
}
}
}
closedir($dh);
}
/**
* Recursively traverse a directory structure and call a callback function
*
* @param string $dir Directory name
* @param function $callback Function to call as traverse structure
* @param boolean $rootToo do op on top-level directory as well
*/
public function traverseDirectory($dir, $callback, $rootToo = true)
{
if(!$dh = @opendir($dir)) {
return;
}
while (false !== ($obj = readdir($dh))) {
if($obj == '.' || $obj == '..') {
continue;
}
if (is_dir($dir . '/' . $obj)) {
$this->traverseDirectory($dir.'/'.$obj, $callback, true);
}
@$callback($dir . '/' . $obj);
}
closedir($dh);
if ($rootToo) {
@$callback($dir);
}
}
}
?>