/**
  * Lancement d'une requête SQL
  * @param	string	$pQueryString	la requête à lancer
  * @param	array	$pParameters	tableau de paramètres
  * @param	int		$pOffset		l'offset à partir duquel nous allons lire les résultats => Si null, pas d'offset
  * @param	int		$pCount			le nombre d'élément que l'on souhaites récupérer depuis la base. Si null => le maximum
  */
 public function iDoQuery($pQueryString, $pParameters = array(), $pOffset = null, $pCount = null)
 {
     $resultsOfQueryParsing = $this->_parseQuery($pQueryString, $pParameters, $pOffset, $pCount);
     CopixLog::log($resultsOfQueryParsing['query'] . var_export($pParameters, true), "query", CopixLog::INFORMATION);
     if ($resultsOfQueryParsing['isSelect'] && ($resultsOfQueryParsing['offset'] === false || $resultsOfQueryParsing['count'] === false)) {
         //Si nous sommes dans un select et que l'offset et le count ne sont pas gérés autoamtiquement, alors il nous faut un curseur "movable"
         //TODO: lorsque les curseurs movable seront supportés, mettre ça
         //         $stmt = $this->_pdo->prepare ($resultsOfQueryParsing['query'], array(PDO::ATTR_CURSOR, PDO::CURSOR_SCROLL));
         $stmt = $this->_pdo->prepare($resultsOfQueryParsing['query']);
     } else {
         $stmt = $this->_pdo->prepare($resultsOfQueryParsing['query']);
     }
     if (!$stmt) {
         throw new CopixDBException('Impossible de préparer la requête [' . $resultsOfQueryParsing['query'] . ']' . serialize($pParameters) . implode('-', $this->_pdo->errorInfo()));
     }
     if (!$stmt->execute($pParameters)) {
         throw new CopixDBException('Impossible d\'exécuter la requête [' . $resultsOfQueryParsing['query'] . ']' . serialize($pParameters) . implode('-', $stmt->errorInfo()));
     }
     if (!$resultsOfQueryParsing['isSelect']) {
         return $stmt->rowCount();
     }
     @$stmt->setFetchMode(PDO::FETCH_CLASS, 'StdClass');
     if ($resultsOfQueryParsing['offset'] && $resultsOfQueryParsing['count']) {
         return new CopixDBPDOResultSetIterator($stmt);
     } else {
         $results = array();
         //hack pour déplacer à l'offset donné.
         $row = true;
         $pLeft = $pCount;
         while (($pLeft > 0 || $pLeft === null) && $row !== false) {
             if ($row = $stmt->fetch()) {
                 if ($pOffset == 0) {
                     $results[] = $row;
                     if ($pLeft !== null) {
                         $pLeft--;
                     }
                 } else {
                     $pOffset--;
                 }
             }
         }
         /*
         
         for ($toFetch = $pCount, $row = $stmt->fetch(PDO::FETCH_CLASS, PDO::FETCH_ORI_REL, $pOffset === null ? 0 : $pOffset);
         $row !== false && ($toFetch-- > 0 || $toFetch === null);
         $row = $stmt->fetch()){
         $results[] = $row;
         }
         *
         */
         $stmt->closeCursor();
         return $results;
     }
 }
 /**
  * Lance l'enregistrement
  * Teste la validité des champs
  * @return array les pk créé
  */
 public function doRecord()
 {
     if (!$this->_mustDoRecord) {
         return array();
     }
     if ($this->_datasourceName == null) {
         throw new CopixFormException(_i18n('copix:copixform.message.noDatasource'));
     }
     $this->errors = array();
     $result = null;
     try {
         if (!isset($this->_create) || $this->_create) {
             CopixLog::log('create : ' . var_export($this->_record, true), 'copixforms');
             $result = $this->_datasource->save($this->_record);
         } else {
             CopixLog::log('update : ' . var_export($this->_record, true), 'copixforms');
             $result = $this->_datasource->update($this->_record);
         }
     } catch (CopixDAOCheckException $e) {
         $this->errors = $e->getErrors();
         CopixLog::log(serialize($this->errors));
         throw new CopixFormCheckException($e->getErrors());
     }
     $arPk = array();
     foreach ($this->_datasource->getPk() as $pk) {
         $arPk[$pk] = isset($result->{$pk}) ? $result->{$pk} : null;
     }
     return $arPk;
 }
 /**
  * Lance une procédure stockées sur la connextion courante
  * @param string $pProcedure la procédure a lancer
  * @param array $pParams un tableau de paramètre à donner à la procédure
  *  le tableau est de la forme $pParams['nom'] = array ('type'=>, 'length'), 'in'=>, ''
  * @return array un tableau de résultat avec array['results'] = résultats,
  *    array['params']['nomParam'] = valeur
  */
 public function doProcedure($pProcedure, $pParams)
 {
     CopixLog::log($pProcedure . var_export($pParams, true), 'query', CopixLog::INFORMATION);
     //Préparation de la requête
     $stmt = @ociparse($this->_ct, $pProcedure);
     if ($stmt === false) {
         throw new CopixDBException('[CopixDB] Impossible de préparer la procédure ' . $pProcedure);
     }
     //On analyse les paramètres
     $arVariablesName = array();
     $arVariables = array();
     foreach ($pParams as $name => $param) {
         $variableName = substr($name, 1);
         if (!is_array($param)) {
             ${$variableName} = $param;
             if (!OCIBindByName($stmt, $name, ${$variableName}, 255)) {
                 throw new Exception("[CopixDB] Impossible de rapprocher '{$name}' avec '" . ${$variableName} . "' taille " . $arVariables[$variableName]['maxlength'] . " type " . $this->_convertQueryParam($arVariables[$variableName]['type']));
             }
             $arVariables[$variableName]['type'] = 'AUTO';
             $arVariables[$variableName]['value'] = $param;
         } else {
             if (!isset(${$variableName})) {
                 ${$variableName} = isset($param['value']) ? $param['value'] : null;
             }
             $arVariables[$variableName] = $param;
             if (!isset($arVariables[$variableName]['type'])) {
                 $arVariables[$variableName]['type'] = CopixDBQueryParam::DB_AUTO;
             }
             if (!isset($arVariables[$variableName]['maxlength'])) {
                 $arVariables[$variableName]['maxlength'] = -1;
             }
             if ($arVariables[$variableName]['type'] === CopixDBQueryParam::DB_CURSOR) {
                 ${$variableName} = oci_new_cursor($this->_ct);
             }
             if (!OCIBindByName($stmt, $name, ${$variableName}, $arVariables[$variableName]['maxlength'], $this->_convertQueryParam($arVariables[$variableName]['type']))) {
                 oci_free_statement($stmt);
                 throw new CopixDBException("[CopixDB] Impossible de rapprocher '{$name}' avec '" . ${$variableName} . "' taille " . $arVariables[$variableName]['maxlength'] . " type " . $this->_convertQueryParam($arVariables[$variableName]['type']));
             }
         }
     }
     //on exécute la requête
     if (!ociexecute($stmt, OCI_DEFAULT)) {
         $statementErrors = oci_error($stmt);
         oci_free_statement($stmt);
         throw new CopixDBException('[CopixDB] Impossible d\'exécuter la procédure ' . $pProcedure . ' - ' . var_dump($statementErrors) . ' avec les variables ' . var_dump($arVariables));
     }
     //analyse des résultats
     foreach ($arVariables as $name => $value) {
         //Si c'est un curseur
         if ($value['type'] === CopixDBQueryParam::DB_CURSOR) {
             if (!@ociexecute(${$name})) {
                 oci_free_statement(${$name});
                 oci_free_statement($stmt);
                 throw new CopixDBException("Impossible de récupérer l'ensemble de résultat de la variable {$name}");
             }
             $toReturn[':' . $name] = array();
             while ($r = oci_fetch_object(${$name})) {
                 $toReturn[':' . $name][] = $r;
             }
             oci_free_statement(${$name});
         } else {
             $toReturn[':' . $name] = ${$name};
         }
     }
     //On commit si le mode est autocommit
     if ($this->_autoCommitMode == self::OCI_AUTO_COMMIT) {
         $this->commit();
     }
     oci_free_statement($stmt);
     CopixLog::log('Terminé', 'Procedure');
     return $toReturn;
 }
/**
 * Alias à CopixLog::log
 * @see CopixLog::log
 * @param 	string	$pChaine	Le message à loguer
 * @param	string	$pType		le type d'élément à loguer
 * @param	int		$pLevel		Le niveau d'information à loguer
 * @param	array	$arExtra	Tableau d'éléments supplémentaires
 */
function _log($pChaine, $pType = "default", $pLevel = CopixLog::INFORMATION, $arExtra = array())
{
    CopixLog::log($pChaine, $pType, $pLevel, $arExtra);
}