20 public static function getInstance($sConfig){
21 return self::_getInstance(__CLASS__,$sConfig);
24 public function findMany($tSql,$sClassRow){
25 $tRows=$this->query($this->
bind($tSql),$sClassRow);
33 public function findManySimple($tSql,$sClassRow){
34 return $this->findMany($tSql,$sClassRow);
36 public function findOne($tSql,$sClassRow){
37 $tRs=$this->query($this->
bind($tSql),$sClassRow);
45 public function findOneSimple($tSql,$sClassRow){
46 return $this->findOne($tSql,$sClassRow);
48 public function execute($tSql){
49 return $this->query($this->
bind($tSql));
52 public function update($sTable,$tProperty,$tWhere){
53 $iId=$this->getIdFromTab($tWhere);
55 $sFile=$this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/'.$iId.
'.xml';
56 $oXml=simplexml_load_file($sFile);
60 $this->removeRowFromAllIndex($sTable,$tXml);
63 foreach($tProperty as $sVar => $sVal){
64 $tXml[$sVar]=(string)$sVal;
68 $this->addRowInAllIndex($sTable,$tXml);
70 $this->save($tXml,$sFile);
72 public function insert($sTable,$tProperty){
73 $iId=$this->getMaxId($sTable);
75 $tMax=array(
'max'=>($iId+1));
77 $tProperty[
'id']=$iId;
79 $sFile=$this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/'.$iId.
'.xml';
80 $this->save($tProperty,$sFile);
81 $sFileMax=$this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/max.xml';
82 $this->save($tMax,$sFileMax);
84 $this->addRowInAllIndex($sTable,$tProperty);
88 public function delete($sTable,$tWhere){
89 $iId=$this->getIdFromTab($tWhere);
91 $sFile=$this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/'.$iId.
'.xml';
92 $oXml=simplexml_load_file($sFile);
96 $this->removeRowFromAllIndex($sTable,$tXml);
98 unlink($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/'.$iId.
'.xml');
101 public function getListColumn($sTable){
103 $sFile=$this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/structure.xml';
104 $oXml=simplexml_load_file($sFile);
107 return $tXml[
'colonne'];
110 public function getListTable(){
111 $oDir=
new _dir( $this->_tConfig[$this->_sConfig.
'.database']);
112 $tDir=$oDir->getList();
114 foreach($tDir as $oDir){
115 $tSDir[]= $oDir->getName();
120 private function query($sReq,$sClassRow){
125 if(substr($sReq,0,6)==
'SELECT'){
127 $tReq=$this->explainSql($sReq);
132 if(isset($tReq[
'select']) and preg_match(
'/COUNT\(/i',$tReq[
'select'])){
136 $tCritere=$this->findListCritere($tReq);
138 $sTable=trim($tReq[
'from']);
141 $tSqlFieldEqual=array_keys($tCritere);
143 $sIndexToUse=$this->findIndexForTable($sTable,$tSqlFieldEqual);
147 if($sIndexToUse!=
''){
148 $tObj=$this->findWithTableIndex($sClassRow,$sTable,$sIndexToUse,$tCritere);
150 }elseif($tSqlFieldEqual==array(
'=id')){
151 $sFilename=$this->_tConfig[$this->_sConfig.
'.database'];
152 $sFilename.=$sTable.
'/'.(string)$tCritere[
'=id'].
'.xml';
154 $tRow=(array)simplexml_load_file($sFilename,null,LIBXML_NOCDATA);
156 $oRow=
new $sClassRow($tRow);
160 $tObj=$this->findInTableWithCritere($sClassRow,$sTable,$tCritere);
166 $iCount=count($tObj);
167 return array($iCount);
168 }
else if(isset($tReq[
'order']) and $tObj!=null){
169 return $this->sortResult($tObj,$tReq);
178 private function explainSql($sReq){
180 preg_match_all(
'/^SELECT(?<select>.*)FROM(?<from>.*)WHERE(?<where>.*)ORDER BY(?<order>.*)/i'
181 ,$sReq,$tResult,PREG_SET_ORDER)
183 preg_match_all(
'/^SELECT(?<select>.*)FROM(?<from>.*)ORDER BY(?<order>.*)/i',$sReq,$tResult,PREG_SET_ORDER)
185 preg_match_all(
'/^SELECT(?<select>.*)FROM(?<from>.*)WHERE(?<where>.*)/i',$sReq,$tResult,PREG_SET_ORDER)
187 preg_match_all(
'/^SELECT(?<select>.*)FROM(?<from>.*)/i',$sReq,$tResult,PREG_SET_ORDER)
189 if(isset($tResult[0][
'where']) and preg_match(
'/ or /i',$tResult[0][
'where'])){
190 $this->erreur(
'Requete non supportee : '.$sReq.$msg);
191 }elseif(isset($tResult[0][
'order']) and !preg_match(
'/\s[ASC|DESC]/i',trim($tResult[0][
'order'])) ){
192 $this->erreur(
'Il faut definir un sens de tri: ASC ou DESC dans la requete'.$sReq.$msg);
198 $msg.=
"Le driver xml gere les requetes de type : \n";
199 $msg.=
"- SELECT liste_des_champs FROM ma_table WHERE champ=valeur ORDER BY champ DESC/ASC \n";
200 $msg.=
"- SELECT liste_des_champs FROM ma_table ORDER BY champ DESC/ASC \n";
201 $msg.=
"- SELECT liste_des_champs FROM ma_table WHERE champ=valeur \n";
202 $msg.=
"- SELECT liste_des_champs FROM ma_table \n";
203 $msg.=
" la clause where accepte uniquement champ=valeur, champ!=valeur et AND \n";
205 $this->erreur(
'Requete non supportee : '.$sReq.$msg);
208 private function findListCritere($tReq){
211 if(isset($tReq[
'where'])){
212 if(preg_match(
'/ and /i',$tReq[
'where'])){
213 $tWhere=preg_split(
'/ AND /i',$tReq[
'where']);
214 foreach($tWhere as $sWhereVal){
215 if(preg_match(
'/!=/',$sWhereVal)){
216 list($sVar,$sVal)=preg_split(
'/!=/',$sWhereVal);
217 $tCritere[trim($sVar)]=
'!'.trim($sVal);
218 }elseif(preg_match(
'/=/',$sWhereVal)){
219 list($sVar,$sVal)=preg_split(
'/=/',$sWhereVal);
220 $tCritere[trim($sVar)]=
'='.trim($sVal);
224 if(preg_match(
'/!=/',$tReq[
'where'])){
225 list($sVar,$sVal)=preg_split(
'/!=/',$tReq[
'where']);
226 $tCritere[trim($sVar)]=
'!'.trim($sVal);
227 }elseif(preg_match(
'/=/',$tReq[
'where'])){
228 list($sVar,$sVal)=preg_split(
'/=/',$tReq[
'where']);
229 $tCritere[trim($sVar)]=
'='.trim($sVal);
236 private function sortResult($tObj,$tReq){
238 list($sChamp,$sSens)=preg_split(
'/ /',trim($tReq[
'order']));
242 foreach($tObj as $i => $oObj){
244 $tTri[ $i ]=(string)$oObj->$sChamp;
253 $tOrderedObj=array();
254 $tId= array_keys($tTri);
255 foreach($tId as $id){
256 $tOrderedObj[]=$tIdObj[$id];
261 private function findIndexForTable($sTable,$tSqlFieldEqual){
262 $oDirIndex=
new _dir($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index');
263 if($oDirIndex->exist()){
264 $tFileIndex=$oDirIndex->getListDir();
265 foreach($tFileIndex as $oFileIndex){
266 $tFieldIndex=$this->getFieldsFromIndex($oFileIndex->getName());
268 foreach($tSqlFieldEqual as $sSqlFieldEqual){
270 $sSqlFieldEqual[0]==
'=' and !in_array(substr($sSqlFieldEqual,1),$tFieldIndex)
272 $sSqlFieldEqual[0]==
'!' and in_array(substr($sSqlFieldEqual,1),$tFieldIndex)
278 return $oFileIndex->getName();
283 private function findWithTableIndex($sClassRow,$sTable,$sIndexToUse,$tCritere){
284 $sDirIndex=$this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index/'.$sIndexToUse;
286 $tFieldIndex=preg_split(
'/\./',$sIndexToUse);
288 $oDirIndex=
new _dir($sDirIndex);
289 $tFileIndex=$oDirIndex->getListFile();
292 foreach($tFileIndex as $oFileIndex){
293 $sFileIndex=trim($oFileIndex->getName());
295 $tRow=$this->getRowValueFromIndex($sFileIndex,$tFieldIndex);
297 foreach($tCritere as $sCritereField => $sCritereVal){
299 if(!isset($tRow[$sCritereField]) or
301 ($sCritereVal[0]==
'=' and (
string)$sCritereVal!=(
string)
'='.$tRow[$sCritereField])
305 ($sCritereVal[0]==
'!' and (
string)$sCritereVal==(
string)
'!'.$tRow[$sCritereField])
312 $tMatchedFile=file( $sDirIndex.
'/'.$sFileIndex );
313 foreach($tMatchedFile as $sMatchedFile){
314 $sMatchedFile=trim($sMatchedFile);
315 $sFilename=$this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/'.$sMatchedFile;
316 $tRow=(array)simplexml_load_file($sFilename,null,LIBXML_NOCDATA);
318 $oRow=
new $sClassRow($tRow);
325 private function findInTableWithCritere($sClassRow,$sTable,$tCritere){
326 $oDir=
new _dir($this->_tConfig[$this->_sConfig.
'.database'].$sTable);
327 $tFile=$oDir->getListFile();
331 foreach($tFile as $oFile){
332 if( in_array($oFile->getName(),array(
'structure.xml',
'max.xml'))){
continue; }
333 $tRow=(array)simplexml_load_file($oFile->getAdresse(),null,LIBXML_NOCDATA);
336 foreach($tCritere as $sCritereField => $sCritereVal){
338 if(!isset($tRow[$sCritereField]) or
340 ($sCritereVal[0]==
'=' and (
string)$sCritereVal!=(
string)
'='.$tRow[$sCritereField])
344 ($sCritereVal[0]==
'!' and (
string)$sCritereVal==(
string)
'!'.$tRow[$sCritereField])
352 $oRow=
new $sClassRow($tRow);
362 public function quote($sVal){
365 public function getWhereAll(){
369 private function getFieldsFromIndex($sIndex){
370 $tFields=preg_split(
'/\./',substr($sIndex,0,-6));
373 private function getRowValueFromIndex($sFileIndex,$tFieldIndex){
374 $tValue=preg_split(
'/####/',substr($sFileIndex,0,-4) );
376 foreach($tFieldIndex as $i => $var){
377 $tRow[$var]=$tValue[$i];
381 private function getFileIndexFromTab($sIndex,$tRow){
382 $tFields=$this->getFieldsFromIndex($sIndex);
384 foreach($tFields as $sField){
385 $sFileIndex.=$tRow[$sField];
388 return $sFileIndex.
'.csv';
390 public function generateIndexForTable($sTable,$sIndex){
391 $tFields=$this->getFieldsFromIndex($sIndex);
393 $oDir=
new _dir($this->_tConfig[$this->_sConfig.
'.database'].$sTable);
394 $tFile=$oDir->getListFile();
396 $tIndexContent=array();
398 foreach($tFile as $oFile){
399 if($oFile->getName() ==
'structure.xml'){
continue;}
400 if($oFile->getName() ==
'max.xml'){
continue;}
402 $tRow=(array)simplexml_load_file($oFile->getAdresse(),null,LIBXML_NOCDATA);
407 foreach($tFields as $sField){
408 $sKey.=$tRow[$sField];
411 $tIndexContent[$sKey][]=$tRow[
'id'].
'.xml';
415 $oDir=
new _dir($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index/'.$sIndex);
416 foreach($oDir->getListFile() as $oFile){
420 foreach($tIndexContent as $sKey => $tFile){
421 $oFile=
new _file($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index/'.$sIndex.
'/'.$sKey.
'.csv');
422 $oFile->setContent(implode($tFile,
"\n"));
426 private function addRowInAllIndex($sTable,$tProperty){
428 $oDir=
new _dir($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index');
430 $tDirIndex=$oDir->getListDir();
431 foreach($tDirIndex as $oDirIndex){
432 $this->addRowInIndex($sTable,$tProperty,$oDirIndex->getName());
436 private function addRowInIndex($sTable,$tProperty,$sIndex){
438 $sFileIndex=$this->getFileIndexFromTab($sIndex,$tProperty);
440 $oFile=
new _file($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index/'.$sIndex.
'/'.$sFileIndex);
441 $oFile->addContent($tProperty[
'id'].
'.xml');
444 private function removeRowFromAllIndex($sTable,$tProperty){
446 $oDir=
new _dir($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index');
448 $tDirIndex=$oDir->getListDir();
449 foreach($tDirIndex as $oDirIndex){
450 $this->removeRowFromIndex($sTable,$tProperty,$oDirIndex->getName());
454 private function removeRowFromIndex($sTable,$tProperty,$sIndex){
456 $sFileIndex=$this->getFileIndexFromTab($sIndex,$tProperty);
458 if(!file_exists($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index/'.$sIndex.
'/'.$sFileIndex)){
462 $tLine=file($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index/'.$sIndex.
'/'.$sFileIndex);
464 foreach($tLine as $sLine){
466 if($sLine==$tProperty[
'id'].
'.xml'){
472 $oFile=
new _file($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/index/'.$sIndex.
'/'.$sFileIndex);
473 $oFile->setContent(implode(
"\n",$tContent));
477 private function getIdFromTab($tId){
479 return current($tId);
484 private function save($tProperty,$sFichier){
485 $oFile=
new _file($sFichier);
487 $sXml=
'<?xml version="1.0" encoding="ISO-8859-1"?>'.$sRet;
488 $sXml.=
'<main>'.$sRet;
489 foreach($tProperty as $sVar => $sVal){
490 $sXml.=
'<'.$sVar.
'><![CDATA['.$sVal.
']]></'.$sVar.
'>'.$sRet;
492 $sXml.=
'</main>'.$sRet;
493 $oFile->write($sXml);
495 private function getMaxId($sTable){
496 $oXml=simplexml_load_file($this->_tConfig[$this->_sConfig.
'.database'].$sTable.
'/max.xml');
497 return (
int)$oXml->max;