* @version 0.0.0
* @copyright Copyright (c) 2007, 2008 Roland Haeder, this is free software
* @license GNU GPL 3.0 or any newer version
* @link http://www.ship-simu.org
*
* 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 .
*/
class DatabaseResult extends BaseFrameworkSystem implements SearchableResult, UpdateableResult, SeekableIterator {
// Exception constants
const EXCEPTION_INVALID_DATABASE_RESULT = 0x1c0;
const EXCEPTION_RESULT_UPDATE_FAILED = 0x1c1;
/**
* Current position in array
*/
private $currentPos = -1;
/**
* Current row
*/
private $currentRow = null;
/**
* Result array
*/
private $resultArray = array();
/**
* Array of out-dated entries
*/
private $outDated = array();
/**
* Affected rows
*/
private $affectedRows = 0;
/**
* Protected constructor
*
* @return void
*/
protected function __construct () {
// Call parent constructor
parent::__construct(__CLASS__);
// Set part description
$this->setObjectDescription("Database result");
// Create unique ID number
$this->generateUniqueId();
// Clean up a little
$this->removeNumberFormaters();
$this->removeSystemArray();
}
/**
* Creates an instance of this result by a provided result array
*
* @param $resultArray The array holding the result from query
* @return $resultInstance An instance of this class
*/
public final static function createDatabaseResult (array $resultArray) {
// Get a new instance
$resultInstance = new DatabaseResult();
// Set the result array
$resultInstance->setResultArray($resultArray);
// Return the instance
return $resultInstance;
}
/**
* Setter for result array
*
* @param $resultArray The array holding the result from query
* @return void
*/
protected final function setResultArray (array $resultArray) {
$this->resultArray = $resultArray;
}
/**
* Updates the current entry by given update criteria
*
* @param $updateInstance An instance of an Updateable criteria
* @return void
*/
private function updateCurrentEntryByCriteria (LocalUpdateCriteria $updateInstance) {
// Get the current entry key
$entryKey = $this->key();
// Now get the update criteria array and update all entries
foreach ($updateInstance->getUpdateCriteria() as $criteriaKey=>$criteriaValue) {
// Update data
$this->resultArray['rows'][$entryKey][$criteriaKey] = $criteriaValue;
// Mark it as out-dated
$this->outDated[$criteriaKey] = 1;
} // END - foreach
}
/**
* "Iterator" method next() to advance to the next valid entry. This method
* does also check if the result is invalid
*
* @return $nextValid Wether the next entry is valid
*/
public function next () {
// Default is not valid
$nextValid = false;
// Is the result valid?
if ($this->resultArray['status'] === "ok") {
// The status is fine so let's have a look for the next entry
if ($this->valid()) {
// Next entry found, so count one up and cache it
$this->currentPos++;
$this->currentRow = $this->resultArray['rows'][$this->currentPos];
$nextValid = true;
} // END - if
} // END - if
// Return the result
return $nextValid;
}
/**
* Seeks for to a specified position
*
* @param $index Index to seek for
* @return void
*/
public function seek ($index) {
// Rewind to beginning
$this->rewind();
// Search for the entry
while ($this->currentPos < $index && ($this->valid())) {
// Continue on
$this->next();
} // END - while
}
/**
* Gives back the current position or null if not found
*
* @return $current Current element to give back
*/
public function current () {
// Default is not found
$current = null;
// Does the current enty exist?
if (isset($this->resultArray['rows'][$this->currentPos])) {
// Then get it
$current = $this->resultArray['rows'][$this->currentPos];
} // END - if
// Return the result
return $current;
}
/**
* Checks if next() and rewind will give a valid result
*
* @return $isValid Wether the next/rewind entry is valid
*/
public function valid () {
// By default nothing is valid
$isValid = false;
// Check if
if ((isset($this->resultArray['rows'][($this->currentPos + 1)])) && (isset($this->resultArray['rows'][0]))) {
// All fine!
$isValid = true;
} // END - if
// Return the result
return $isValid;
}
/**
* Gets the current key of iteration
*
* @return $currentPos Key from iterator
*/
public function key () {
return $this->currentPos;
}
/**
* Rewind to the beginning
*
* @return void
*/
public function rewind () {
$this->currentPos = -1;
}
/**
* Searches for an entry in the data result and returns it
*
* @param $criteriaInstance The criteria to look inside the data set
* @return $result Found result entry
*/
public function searchEntry (LocalSearchCriteria $criteriaInstance) {
die(__METHOD__.": Unfinished!");
}
/**
* Adds an update request to the database result for writing it to the
* database layer
*
* @param $criteriaInstance An instance of a updateable criteria
* @return void
* @throws ResultUpdateException If no result was updated
*/
public function add2UpdateQueue (LocalUpdateCriteria $criteriaInstance) {
// Rewind the pointer
$this->rewind();
// Get search criteria
$searchInstance = $criteriaInstance->getSearchInstance();
// And start looking for the result
$foundEntries = 0;
while (($this->valid()) && ($foundEntries < $searchInstance->getLimit())) {
// Get next entry
$this->next();
$currentEntry = $this->current();
// Is this entry found?
if ($searchInstance->ifEntryMatches($currentEntry)) {
// Update this entry
$this->updateCurrentEntryByCriteria($criteriaInstance);
// Count one up
$foundEntries++;
} // END - if
} // END - while
// Set affected rows
$this->setAffectedRows($foundEntries);
// If no entry is found/updated throw an exception
if ($foundEntries == 0) {
// Throw an exception here
throw new ResultUpdateException($this, self::EXCEPTION_RESULT_UPDATE_FAILED);
} // END - if
// Set search instance
$this->setSearchInstance($searchInstance);
}
/**
* Setter for affected rows
*
* @param $rows Number of affected rows
* @return void
*/
public final function setAffectedRows ($rows) {
$this->affectedRows = $rows;
}
/**
* Getter for affected rows
*
* @return $rows Number of affected rows
*/
public final function getAffectedRows () {
return $this->affectedRows;
}
/**
* Checks wether we have out-dated entries or not
*
* @return $needsUpdate Wether we have out-dated entries
*/
public function ifDataNeedsFlush () {
$needsUpdate = (count($this->outDated) > 0);
return $needsUpdate;
}
/**
* Adds registration elements to a given dataset instance
*
* @param $criteriaInstance An instance of a storeable criteria
* @return void
*/
public function addElementsToDataSet (StoreableCriteria $criteriaInstance) {
// Rewind the pointer
$this->rewind();
// Walk through all entries
while ($this->valid()) {
// Get next entry
$this->next();
$currentEntry = $this->current();
// Walk only through out-dated columns
foreach ($this->outDated as $key=>$dummy) {
// Does this key exist?
//* DEBUG: */ echo "outDated: {$key}
\n";
if (isset($currentEntry[$key])) {
// Then update it
$criteriaInstance->addCriteria($key, $currentEntry[$key]);
} // END - foreach
} // END - foreach
} // END - while
}
}
// [EOF]
?>