Commit fd718eba authored by Torsten Zühlsdorff's avatar Torsten Zühlsdorff
Browse files

add new feature: configurable explicit data-type binding

parent e1313b95
......@@ -31,11 +31,11 @@
<item url="inc/handler/class_result_format.php" uploadstatus="1" />
<item url="inc/handler/" uploadstatus="1" />
<item url="inc/handler/class_default_handler.php" uploadstatus="1" />
<item url="inc/exceptions/DDDBLQueryException.inc.php" />
<item url="inc/exceptions/" />
<item url="tests/database.conf" />
<item url="tests/" />
<item url="tests/test.php" />
<item url="tests/query.sdef" />
<item url="inc/exceptions/DDDBLQueryException.inc.php" uploadstatus="1" />
<item url="inc/exceptions/" uploadstatus="1" />
<item url="tests/database.conf" uploadstatus="1" />
<item url="tests/" uploadstatus="1" />
<item url="tests/test.php" uploadstatus="1" />
<item url="tests/query.sdef" uploadstatus="1" />
</project>
</webproject>
......@@ -20,32 +20,37 @@ class DDDBL_DB {
/* contains the type of the db - could be Oracle, MySQL etc */
private $strDBType = null;
/* contains the definition of the database-connection */
private $arrDefinition = array();
/**
*
* @param $strDBType - the type of the db - could be Oracle, MySQL etc.
* @param $strDSN - the data source name specification - take a look at "http://php.net/pdo construct"
* @param $strUsername - the username which will be used to connect to the db
* @param $strPassword - the password which will be used to connect to the db
* @param $arrDefinition - contains the complete definition
* for database-connection and handling
*
* create a new PDO object (which is the db-connection)
* and store it in the class variable
*
**/
public function __construct($strDBType, $strDSN, $strUsername, $strPassword) {
assert(is_string($strDBType));
assert(is_string($strDSN));
assert(is_string($strUsername));
assert(is_string($strPassword));
public function __construct($arrDefinition) {
$this->arrDefinition = $arrDefinition;
assert(is_string($this->arrDefinition[DDDBL_DB_TYPE]));
assert(is_string($this->arrDefinition[DDDBL_DB_CONNECTION]));
assert(is_string($this->arrDefinition[DDDBL_DB_USER]));
assert(is_string($this->arrDefinition[DDDBL_DB_PASSWORD]));
assert(!is_string($this->strDBType));
assert(!is_object($this->objDB));
try {
$this->strDBType = $strDBType;
$this->strDBType = $this->arrDefinition[DDDBL_DB_TYPE];
$this->objDB = new PDO($strDSN, $strUsername, $strPassword);
$this->objDB = new PDO($this->arrDefinition[DDDBL_DB_CONNECTION],
$this->arrDefinition[DDDBL_DB_USER],
$this->arrDefinition[DDDBL_DB_PASSWORD]);
} catch (PDOException $objException) {
......@@ -164,19 +169,19 @@ class DDDBL_DB {
/**
*
* @param $strStatement - the string to quote for use in a query
* @param $strParameter - the string to quote for use in a query
*
* @return (string) the quoted string
*
* quote the given string for use in a query
*
**/
public function quote($strStatement) {
public function quote($strParameter) {
assert(is_object($this->objDB));
assert(is_string($strStatement));
assert(is_string($strParameter));
return $this->objDB->quote($strStatement);
return $this->objDB->quote($strParameter);
}
......@@ -235,5 +240,30 @@ class DDDBL_DB {
return $this->strDBType;
}
/**
*
* @param $strKey - the key of the definition which should be returned
*
* @exception Exception - if somebody try to get the password
*
* @return (string) the definition stored under the given key
* @return (null) if keyword do not exists
*
* return the part of the database-definition stored under the given keyword
*
* ATTENTION: for security reason's you are not allowed to get the password!
*
**/
public function getDefinitionByKey($strKey) {
if(DDDBL_DB_PASSWORD === $strKey)
throw new Exception ('for security reasons it is not allowed to read the password of the connection');
if(!isset($this->arrDefinition[$strKey]))
return null;
return $this->arrDefinition[$strKey];
}
}
\ No newline at end of file
......@@ -34,7 +34,8 @@ class DDDBL_DB_Pool {
* - will be used, to validate the database-definition
**/
private $arrSupportedDefinitionKeys = array(DDDBL_DB_CONNECTION, DDDBL_DB_TYPE,
DDDBL_DB_USER, DDDBL_DB_PASSWORD, DDDBL_DB_DEFAULT);
DDDBL_DB_USER, DDDBL_DB_PASSWORD, DDDBL_DB_DEFAULT,
DDDBL_CONFIG_BIND_DATA_TYPE);
/**
* store the given alias of an default database
......@@ -67,8 +68,7 @@ class DDDBL_DB_Pool {
throw new Exception ('unknown database-alias: ' . $strAlias);
if(!isset($this->arrDBs[$strAlias]))
$this->arrDBs[$strAlias] = new DDDBL_DB($arrDefinition[DDDBL_DB_TYPE], $arrDefinition[DDDBL_DB_CONNECTION],
$arrDefinition[DDDBL_DB_USER], $arrDefinition[DDDBL_DB_PASSWORD]);
$this->arrDBs[$strAlias] = new DDDBL_DB($arrDefinition);
assert(is_object($this->arrDBs[$strAlias]));
......
......@@ -100,8 +100,7 @@ class DDDBL_Query {
$this->objPrepared->setFetchMode(PDO::FETCH_ASSOC);
foreach($arrParameter AS $intIndex => $mixedParameter)
$this->objPrepared->bindValue($intIndex + 1, $mixedParameter);
self::bindParameter($arrParameter);
if(!$this->objPrepared->execute())
throw new DDDBLQueryException ($this->objPrepared, $this->arrConfig, $arrParameter);
......@@ -109,5 +108,98 @@ class DDDBL_Query {
return $this->objPrepared;
}
/**
*
* @param $arrParameter - list of parameter we're going to bind to prepared statement
*
* @exception Exception - if option BIND-DATA-TYPE is true, but an unknown data-type occurs
*
* @see http://www.php.net/pdo.constants
*
* check if the option BIND-DATA-TYPE is true.
* if it is true, bind parameter explicitly with PDO-supported data-types
* otherwise just bind them and hope for the best
*
* Supported Datatypes:
* - NULL
* - boolean
* - integer
* - string
*
**/
private function bindParameter($arrParameter) {
if(true === self::getBindDataTypeOption()) {
foreach($arrParameter AS $intIndex => $mixedParameter)
$this->objPrepared->bindValue($intIndex + 1, $mixedParameter, self::mapDataTypeForPDO($mixedParameter));
return;
}
foreach($arrParameter AS $intIndex => $mixedParameter)
$this->objPrepared->bindValue($intIndex + 1, $mixedParameter);
}
/**
*
* @param $mixedParameter - parameter which data-type should be bound
*
* @exception Exception - if an unknown data-type occurs
*
* @return (string) the PDO-Flag for the data-type of the parameter
*
* resolve the datatype of the given parameter and map it to the
* PDO supported parameter flag
*
**/
private function mapDataTypeForPDO($mixedParameter) {
$arrDataTypeMap = array('NULL' => PDO::PARAM_NULL,
'boolean' => PDO::PARAM_BOOL,
'integer' => PDO::PARAM_INT,
'string' => PDO::PARAM_STR);
$strDataType = gettype($mixedParameter);
if(!isset($arrDataTypeMap[$strDataType]))
throw new Exception ('could not bind parameters data type - type is not supported by PDO: ' . $strDataType);
return $arrDataTypeMap[$strDataType];
}
/**
*
* @return (boolean) true, if explicity data-type binding is needed
* @return (boolean) false, if explicity data-type binding is NOT needed
*
* check if explicity data-type binding is needed
* therefor the configuration of database-connection
* and the active query is analysed
*
* ATTENTION: the special configuration of the query,
* overwrites the general connection configuration
*
**/
private function getBindDataTypeOption() {
// if query defines this option, always use that value
if(isset($this->arrConfig[DDDBL_CONFIG_BIND_DATA_TYPE]))
return ('1' === $this->arrConfig[DDDBL_CONFIG_BIND_DATA_TYPE]) ? true : false;
// if query has no data-type-bind-specification,
// use the general one of the database connection
$strBindDataType = $this->objDB->getDefinitionByKey(DDDBL_CONFIG_BIND_DATA_TYPE);
if(!is_string($strBindDataType))
$boolBindDataType = false;
return ('1' === $strBindDataType) ? true : false;
}
}
\ No newline at end of file
......@@ -16,8 +16,9 @@ if(!defined('DDDBL_CONSTANTS')) {
define('DDDBL_DB', 'DB');
define('DDDBL_CONFIG_QUERY', 'QUERY');
define('DDDBL_CONFIG_HANDLER', 'HANDLER');
define('DDDBL_CONFIG_QUERY', 'QUERY');
define('DDDBL_CONFIG_HANDLER', 'HANDLER');
define('DDDBL_CONFIG_BIND_DATA_TYPE', 'BIND-DATA-TYPE');
define('DDDBL_CONFIG_RESULT_TYPE', 'RESULT-TYPE');
define('DDDBL_CONFIG_RESULT_TYPE_POSITION', 0);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment