/**
  * Constructeur
  * @param	CopixDBProfil	$pProfil	le profil de connexion à utiliser
  */
 public function __construct($pProfil)
 {
     parent::__construct($pProfil);
     try {
         $this->_pdo = new PDO(substr($pProfil->getConnectionString(), 4), $pProfil->getUser(), $pProfil->getPassword(), $pProfil->getOptions());
     } catch (PDOException $e) {
         throw new CopixDBException($e->getMessage());
     }
 }
 function CopixDBConnectionMySQL()
 {
     parent::CopixDBConnection();
     // fonction d'echappement pour les chaines
     // on essaie de prendre mysql_real_escape_string car tient compte du charset de la base utilisée
     // par contre existe seulement depuis php 4.3.0..
     // on le fait ici, car c'est un test en moins à faire à chaque quote()
     $this->_fctEscapeString = function_exists('mysql_real_escape_string') ? 'mysql_real_escape_string' : 'mysql_escape_string';
 }
 /**
  * Analyse la requète pour qu'elle passe sans encombre dans le driver MySQL
  */
 protected function _parseQuery($pQueryString, $pParameters = array(), $pOffset = null, $pCount = null)
 {
     $toReturn = parent::_parseQuery($pQueryString, $pParameters, $pOffset, $pCount);
     //only for select query
     if ($toReturn['isSelect'] && ($pOffset !== null || $pCount !== null)) {
         $pos = stripos($toReturn['query'], "select");
         if ($pCount === null) {
             $pCount = $this->_getMaxCount();
         }
         $pOffset = intval($pOffset);
         $pCount = intval($pCount);
         $toReturn['query'] = $toReturn['query'] . " LIMIT {$pOffset}, {$pCount}";
         $toReturn['offset'] = true;
         $toReturn['count'] = true;
     }
     if (!$toReturn['isSelect']) {
         $toReturn['isSelect'] = stripos(trim($pQueryString), 'SHOW') === 0 || stripos(trim($pQueryString), 'DESCRIBE') === 0;
     }
     return $toReturn;
 }
 /**
  * Exprime les conditions en SQL
  * @param $pConditions les conditions à mettre dans le SQL
  * @param boolean	$pExplainKind si l'on souhaite expliquer le and / or
  * @param array	$pFields tableau des champs sur lesquels travailler
  *    $pFields[nomPropriete][0] == nom champ
  *    $pFields[nomPropriete][1] == type champ
  *    $pFields[nomPropriete][2] == table
  * @param	CopixDBConnection	$pConnection	La connection qui corresponds à l'emplacement ou l'on souhaite lancer la requête
  * @return string SQL
  */
 private function _explainSQLCondition($pConditions, $pExplainKind, $pFields, $pConnection = null)
 {
     $r = ' ';
     $fieldsForQueryParams = array();
     //direct conditions for the group
     $first = true;
     foreach ($pConditions->conditions as $conditionDescription) {
         //Si c'est une valeur sous la forme d'un tableau mais qu'aucune valeur
         //n'est indiquée, on passe à la suivante.
         if (array_key_exists('value', $conditionDescription) && is_array($conditionDescription['value']) && count($conditionDescription['value']) == 0) {
             continue;
         }
         //Si c'est une forme SQL et que la chaine est vide, on passe à la condition suivante.
         if (array_key_exists('sql', $conditionDescription) && strlen($conditionDescription['sql']) === 0) {
             continue;
         }
         //Si ce n'est pas le premier passage, il faut ajouter le mot clef relatif à la condition
         if (!$first) {
             $r .= ' ' . $conditionDescription['kind'] . ' ';
         }
         //Nous ne sommes plus dans le premier passage.
         $first = false;
         if (isset($conditionDescription['sql'])) {
             //C'est une condition SQL rajoutée à la main.
             //on remplace les noms de paramètres pour s'assurer de l'unicité.
             //On parcours dans le sens inverse de l'ordre alpha pour éviter de remplacer
             //des portions de nom de variable (ex :a avant :ab)
             krsort($conditionDescription['params']);
             foreach ($conditionDescription['params'] as $paramName => $paramValue) {
                 $conditionDescription['sql'] = str_replace($paramName, $newParamName = $paramName . self::$_countParam, $conditionDescription['sql']);
                 self::$_countParam++;
                 //ajout du paramètre dans le tableau des paramètres
                 $fieldsForQueryParams[$newParamName] = $paramValue;
             }
             //Ajout de la chaine SQL traitée.
             $r .= ' ' . $conditionDescription['sql'] . ' ';
         } else {
             //C'est une condition gérée par addCondition.
             $prefix = $pFields[$conditionDescription['field_id']][2] . '.' . $pFields[$conditionDescription['field_id']][0];
             $prefixNoCondition = $prefix;
             $prefix .= ' ' . $conditionDescription['condition'] . ' ';
             if (!is_array($conditionDescription['value'])) {
                 $variableName = ':' . $this->_compressVariable($pFields[$conditionDescription['field_id']][0] . '_' . $pFields[$conditionDescription['field_id']][2] . '_' . self::$_countParam);
                 if ($conditionDescription['value'] === null && $conditionDescription['condition'] == '=') {
                     $r .= $prefixNoCondition . ' IS NULL';
                 } elseif ($conditionDescription['value'] === null && $conditionDescription['condition'] == '<>') {
                     $r .= $prefixNoCondition . ' IS NOT NULL';
                 } else {
                     $fieldsForQueryParams[$variableName] = $this->_variableValue($pFields[$conditionDescription['field_id']][1], $conditionDescription['value'], $pConnection ? $pConnection->getProfile()->getDriverName() : null);
                     if ($pConnection !== null && $pConnection->getProfile()->getDriverName() == 'oci' && in_array($pFields[$conditionDescription['field_id']][1], array('datetime', 'date', 'time'))) {
                         if ($pFields[$conditionDescription['field_id']][1] == 'datetime') {
                             $r .= 'to_char(' . $prefixNoCondition . ', \'YYYYMMDDHH24MISS\') ' . $conditionDescription['condition'] . ' ' . $variableName;
                         } elseif ($pFields[$conditionDescription['field_id']][1] == 'date') {
                             $r .= 'to_char(' . $prefixNoCondition . ', \'YYYYMMDD\') ' . $conditionDescription['condition'] . ' ' . $variableName;
                         } elseif ($pFields[$conditionDescription['field_id']][1] == 'time') {
                             $r .= 'to_char(' . $prefixNoCondition . ', \'HH24MISS\') ' . $conditionDescription['condition'] . ' ' . $variableName;
                         }
                     } else {
                         $methodDebut = '';
                         $methodFin = '';
                         if (isset($pFields[$conditionDescription['field_id']][4])) {
                             $methodDebut = $pFields[$conditionDescription['field_id']][4] . '(';
                             $methodFin = ')';
                         }
                         $r .= $prefix . $methodDebut . $variableName . $methodFin;
                     }
                     self::$_countParam++;
                 }
             } else {
                 if (count($conditionDescription['value'])) {
                     $r .= ' ( ';
                     $firstCV = true;
                     foreach ($conditionDescription['value'] as $conditionValue) {
                         $variableName = ':' . $this->_compressVariable($pFields[$conditionDescription['field_id']][0] . '_' . $pFields[$conditionDescription['field_id']][2] . '_' . self::$_countParam);
                         if (!$firstCV) {
                             $r .= ' or ';
                         }
                         if ($conditionValue === null && $conditionDescription['condition'] == '=') {
                             $r .= $prefixNoCondition . ' IS NULL';
                         } elseif ($conditionValue === null && $conditionDescription['condition'] == '<>') {
                             $r .= $prefixNoCondition . ' IS NOT NULL';
                         } else {
                             if ($pConnection !== null && $pConnection->getProfile()->getDriverName() == 'oci' && in_array($pFields[$conditionDescription['field_id']][1], array('datetime', 'date', 'time'))) {
                                 if ($pFields[$conditionDescription['field_id']][1] == 'datetime') {
                                     $r .= 'to_char(' . $prefixNoCondition . ', \'YYYYMMDDHH24MISS\') ' . $conditionDescription['condition'] . ' ' . $variableName;
                                 } elseif ($pFields[$conditionDescription['field_id']][1] == 'date') {
                                     $r .= 'to_char(' . $prefixNoCondition . ', \'YYYYMMDD\') ' . $conditionDescription['condition'] . ' ' . $variableName;
                                 } elseif ($pFields[$conditionDescription['field_id']][1] == 'time') {
                                     $r .= 'to_char(' . $prefixNoCondition . ', \'HH24MISS\') ' . $conditionDescription['condition'] . ' ' . $variableName;
                                 }
                             } else {
                                 $methodDebut = '';
                                 $methodFin = '';
                                 if (isset($pFields[$conditionDescription['field_id']][4])) {
                                     $methodDebut = $pFields[$conditionDescription['field_id']][4] . '(';
                                     $methodFin = ')';
                                 }
                                 $r .= $prefix . $methodDebut . $variableName . $methodFin;
                             }
                             $fieldsForQueryParams[$variableName] = $this->_variableValue($pFields[$conditionDescription['field_id']][1], $conditionValue, $pConnection ? $pConnection->getProfile()->getDriverName() : null);
                             //			                	$fieldsForQueryParams[$variableName] = $conditionValue;
                         }
                         $firstCV = false;
                         self::$_countParam++;
                     }
                     $r .= ' ) ';
                 }
             }
         }
     }
     //sub conditions
     foreach ($pConditions->group as $conditionDetail) {
         list($sql, $fields) = $this->_explainSQLCondition($conditionDetail, !$first, $pFields, $pConnection);
         $r .= $sql;
         $fieldsForQueryParams = array_merge($fieldsForQueryParams, $fields);
         if (!$conditionDetail->isEmpty()) {
             $first = false;
         }
     }
     //adds parenthesis around the sql if needed (non empty)
     if (strlen(trim($r)) > 0) {
         $r = ($pExplainKind ? ' ' . $pConditions->kind . ' ' : '') . '(' . $r . ')';
     }
     return array($r, $fieldsForQueryParams);
 }
 /**
  * Analyse la requète pour qu'elle passe sans encombre dans le driver PDO_OCI
  */
 protected function _parseQuery($pQueryString, $pParameters = array(), $pOffset = null, $pCount = null)
 {
     $toReturn = parent::_parseQuery($pQueryString, $pParameters, $pOffset, $pCount);
     //only for select query
     if ($toReturn['isSelect'] && ($pOffset !== null || $pCount !== null)) {
         $toReturn['query'] = $this->_parseLimit($toReturn['query'], $pOffset, $pCount);
         $toReturn['count'] = true;
         $toReturn['offset'] = true;
     }
     if (!$toReturn['isSelect']) {
         $toReturn['isSelect'] = stripos(trim($pQueryString), 'DESCRIBE') === 0;
     }
     return $toReturn;
 }
 /**
  * prepare un ensemble de valeur de manière à étre incluse dans une
  * requète SQL
  * EXPERIMENTAL !!!
  * @param   object   $object         objet dont les propriétés vont être incluse dans la requète
  * @param   CopixObjectDbProperties    $objectProperties objet de propriétes des champs de l'objet
  * @param   array    $propertiesList   liste de propriété à inclure ou exclure dans la preparation
  * @param   boolean  $excludePropertiesList  indique si la liste des propriétés $propertiesList est à inclure ou exclure
  * @return  array    liste des propriétés avec leurs valeurs.
  */
 function prepareValues(&$object, &$objectProperties, $propertiesList = null, $excludePropertiesList = true)
 {
     $propTypes = $objectProperties->fieldTypeList;
     $mapping = array_flip($objectProperties->fieldPropList);
     $properties = get_object_vars($object);
     $fields = array();
     foreach ($properties as $propname => $value) {
         if (!isset($mapping[$propname])) {
             // est ce que cette propriété est référencée dans le mapping ?
             continue;
         }
         if ($excludePropertiesList) {
             if (is_array($propertiesList) && in_array($propname, $propertiesList)) {
                 // est ce une propriété exclue temporairement ?
                 continue;
             }
         } else {
             if (!is_array($propertiesList)) {
                 continue;
             }
             if (!in_array($propname, $propertiesList)) {
                 // est ce une propriété qu'il faut inclure ?
                 continue;
             }
         }
         $fieldname = $mapping[$propname];
         if (isset($propTypes[$fieldname])) {
             switch ($propTypes[$fieldname] & 0xff) {
                 case COPIXDB_TYPE_INTEGER:
                     $value = intval($value);
                     break;
                 case COPIXDB_TYPE_FLOAT:
                     $value = doubleval($value);
                     break;
                 case COPIXDB_TYPE_BOOLEAN:
                     switch ($propTypes[$fieldname]) {
                         case COPIXDB_TYPE_BOOLEAN_01:
                             $value = $value ? 1 : 0;
                             break;
                         case COPIXDB_TYPE_BOOLEAN_YN:
                             $value = $value ? '\'Y\'' : '\'N\'';
                             break;
                         case COPIXDB_TYPE_BOOLEAN_BOOL:
                             $value = $value ? 'true' : 'false';
                             break;
                         case COPIXDB_TYPE_BOOLEAN_STR:
                             $value = $value ? '\'1\'' : '\'\'';
                             break;
                     }
                     break;
                 default:
                     $value = $this->connector->quote($value);
             }
         } else {
             $value = $this->connector->quote($value);
         }
         if (isset($objectProperties->appliedFunctionToIUList[$fieldname])) {
             $value = sprintf($objectProperties->appliedFunctionToIUList[$fieldname], $value);
         }
         $fields[$fieldname] = $value;
     }
     return $fields;
 }