Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
56.25% |
18 / 32 |
CRAP | |
60.80% |
183 / 301 |
| sgbd_json | |
0.00% |
0 / 1 |
|
56.25% |
18 / 32 |
755.65 | |
60.80% |
183 / 301 |
| getInstance | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| findMany | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| findManySimple | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| findOne | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| findOneSimple | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| execute | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| update | |
100.00% |
1 / 1 |
2 | |
100.00% |
11 / 11 |
|||
| insert | |
100.00% |
1 / 1 |
2 | |
100.00% |
13 / 13 |
|||
| delete | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
| getListColumn | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| getListTable | |
100.00% |
1 / 1 |
2 | |
100.00% |
7 / 7 |
|||
| query | |
0.00% |
0 / 1 |
11.03 | |
93.94% |
31 / 33 |
|||
| explainSql | |
0.00% |
0 / 1 |
9.33 | |
84.00% |
21 / 25 |
|||
| findListCritere | |
100.00% |
1 / 1 |
8 | |
100.00% |
23 / 23 |
|||
| sortResult | |
100.00% |
1 / 1 |
4 | |
100.00% |
17 / 17 |
|||
| findIndexForTable | |
0.00% |
0 / 1 |
42.33 | |
18.75% |
3 / 16 |
|||
| findWithTableIndex | |
0.00% |
0 / 1 |
90 | |
0.00% |
0 / 27 |
|||
| findInTableWithCritere | |
0.00% |
0 / 1 |
9.01 | |
94.74% |
18 / 19 |
|||
| quote | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| getWhereAll | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| getFieldsFromIndex | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| getRowValueFromIndex | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 6 |
|||
| getFileIndexFromTab | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 7 |
|||
| generateIndexForTable | |
0.00% |
0 / 1 |
56 | |
0.00% |
0 / 25 |
|||
| addRowInAllIndex | |
0.00% |
0 / 1 |
5.20 | |
37.50% |
3 / 8 |
|||
| addRowInIndex | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 5 |
|||
| removeRowFromAllIndex | |
0.00% |
0 / 1 |
5.20 | |
37.50% |
3 / 8 |
|||
| removeRowFromIndex | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 15 |
|||
| getIdFromTab | |
0.00% |
0 / 1 |
2.15 | |
66.67% |
2 / 3 |
|||
| save | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| getMaxId | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| json_decode | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| <?php | |
| /* | |
| This file is part of Mkframework. | |
| Mkframework is free software: you can redistribute it and/or modify | |
| it under the terms of the GNU Lesser General Public License as published by | |
| the Free Software Foundation, either version 3 of the License. | |
| Mkframework 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 Lesser General Public License for more details. | |
| You should have received a copy of the GNU Lesser General Public License | |
| along with Mkframework. If not, see <http://www.gnu.org/licenses/>. | |
| */ | |
| class sgbd_json extends abstract_sgbd{ | |
| public static function getInstance($sConfig){ | |
| return self::_getInstance(__CLASS__,$sConfig); | |
| } | |
| public function findMany($tSql,$sClassRow){ | |
| $tRows=$this->query($this->bind($tSql),$sClassRow); | |
| if(!$tRows){ | |
| return null; | |
| } | |
| return $tRows; | |
| } | |
| public function findManySimple($tSql,$sClassRow){ | |
| return $this->findMany($tSql,$sClassRow); | |
| } | |
| public function findOne($tSql,$sClassRow){ | |
| $tRs=$this->query($this->bind($tSql),$sClassRow); | |
| if(empty($tRs)){ | |
| return null; | |
| } | |
| return $tRs[0]; | |
| } | |
| public function findOneSimple($tSql,$sClassRow){ | |
| return $this->findOne($tSql,$sClassRow); | |
| } | |
| public function execute($tSql){ | |
| throw new Exception('method execute not available for this driver'); | |
| } | |
| public function update($sTable,$tProperty,$tWhere){ | |
| $iId=$this->getIdFromTab($tWhere); | |
| $sFile=$this->_tConfig[$this->_sConfig.'.database'].$sTable.'/'.$iId.'.json'; | |
| $oJson=$this->json_decode($sFile); | |
| $tJson=(array) $oJson; | |
| //remove index | |
| $this->removeRowFromAllIndex($sTable,$tJson); | |
| foreach($tProperty as $sVar => $sVal){ | |
| $oJson->$sVar=$sVal; | |
| } | |
| //add in index | |
| $this->addRowInAllIndex($sTable,$tJson); | |
| $this->save($oJson,$sFile); | |
| } | |
| public function insert($sTable,$tProperty){ | |
| $iId=$this->getMaxId($sTable); | |
| $iMax=($iId+1); | |
| $oJson=new stdclass; | |
| $oJson->id=$iId; | |
| foreach($tProperty as $sVar => $sVal){ | |
| $oJson->$sVar=$sVal; | |
| } | |
| $sFile=$this->_tConfig[$this->_sConfig.'.database'].$sTable.'/'.$iId.'.json'; | |
| $this->save($oJson,$sFile); | |
| $sFileMax=$this->_tConfig[$this->_sConfig.'.database'].$sTable.'/max.txt'; | |
| file_put_contents($sFileMax,$iMax); | |
| $this->addRowInAllIndex($sTable,$tProperty); | |
| return $iId; | |
| } | |
| public function delete($sTable,$tWhere){ | |
| $iId=$this->getIdFromTab($tWhere); | |
| $sFile=$this->_tConfig[$this->_sConfig.'.database'].$sTable.'/'.$iId.'.json'; | |
| $oJson=$this->json_decode($sFile); | |
| $tJson=(array) $oJson; | |
| //remove index | |
| $this->removeRowFromAllIndex($sTable,$tJson); | |
| unlink($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/'.$iId.'.json'); | |
| } | |
| public function getListColumn($sTable){ | |
| $sFile=$this->_tConfig[$this->_sConfig.'.database'].$sTable.'/structure.csv'; | |
| $sColumns=trim(file_get_contents($sFile)); | |
| $tColumn=explode(';',$sColumns); | |
| return $tColumn; | |
| } | |
| public function getListTable(){ | |
| $oDir=new _dir( $this->_tConfig[$this->_sConfig.'.database']); | |
| $tDir=$oDir->getList(); | |
| $tSDir=array(); | |
| foreach($tDir as $oDir){ | |
| $tSDir[]= $oDir->getName(); | |
| } | |
| return $tSDir; | |
| } | |
| private function query($sReq,$sClassRow){ | |
| //traitement de la requete $sReq | |
| $sReq=trim($sReq); | |
| $this->_sReq=$sReq; | |
| if(substr($sReq,0,6)== 'SELECT'){ | |
| $tReq=$this->explainSql($sReq); | |
| //count | |
| $bCount=false; | |
| $iCount=0; | |
| if(isset($tReq['select']) and preg_match('/COUNT\(/i',$tReq['select'])){ | |
| $bCount=true; | |
| } | |
| $tCritere=$this->findListCritere($tReq); | |
| $sTable=trim($tReq['from']); | |
| //UTILISATION D UN INDEX | |
| $tSqlFieldEqual=array_keys($tCritere); | |
| $sIndexToUse=$this->findIndexForTable($sTable,$tSqlFieldEqual); | |
| $tObj=array(); | |
| //UTILISATION D UN INDEX | |
| if($sIndexToUse!=''){ | |
| $tObj=$this->findWithTableIndex($sClassRow,$sTable,$sIndexToUse,$tCritere); | |
| }elseif($tSqlFieldEqual==array('id') and substr((string)$tCritere['id'],0,1)=='='){ | |
| $sFilename=$this->_tConfig[$this->_sConfig.'.database']; | |
| $sFilename.=$sTable.'/'.substr((string)$tCritere['id'],1).'.json'; | |
| if(file_exists($sFilename)){ | |
| $tRow=(array)$this->json_decode($sFilename); | |
| $oRow=new $sClassRow($tRow); | |
| $tObj[]=$oRow; | |
| } | |
| }else{ | |
| $tObj=$this->findInTableWithCritere($sClassRow,$sTable,$tCritere); | |
| } | |
| //count | |
| if($bCount){ | |
| $iCount=count($tObj); | |
| return array($iCount); | |
| }else if(isset($tReq['order']) and $tObj!=null){ | |
| return $this->sortResult($tObj,$tReq); | |
| }else{ | |
| return $tObj; | |
| } | |
| } | |
| } | |
| private function explainSql($sReq){ | |
| if( | |
| preg_match_all('/^SELECT(?<select>.*)FROM(?<from>.*)WHERE(?<where>.*)ORDER BY(?<order>.*)/i' | |
| ,$sReq,$tResult,PREG_SET_ORDER) | |
| or | |
| preg_match_all('/^SELECT(?<select>.*)FROM(?<from>.*)ORDER BY(?<order>.*)/i',$sReq,$tResult,PREG_SET_ORDER) | |
| or | |
| preg_match_all('/^SELECT(?<select>.*)FROM(?<from>.*)WHERE(?<where>.*)/i',$sReq,$tResult,PREG_SET_ORDER) | |
| or | |
| preg_match_all('/^SELECT(?<select>.*)FROM(?<from>.*)/i',$sReq,$tResult,PREG_SET_ORDER) | |
| ){ | |
| if(isset($tResult[0]['where']) and preg_match('/ or /i',$tResult[0]['where'])){ | |
| $this->erreur('Requete non supportee : '.$sReq); | |
| }elseif(isset($tResult[0]['order']) and !preg_match('/\s[ASC|DESC]/i',trim($tResult[0]['order'])) ){ | |
| $this->erreur('Il faut definir un sens de tri: ASC ou DESC dans la requete'.$sReq); | |
| }else{ | |
| return $tResult[0]; | |
| } | |
| }else{ | |
| $msg="\n\n"; | |
| $msg.="Le driver xml gere les requetes de type : \n"; | |
| $msg.="- SELECT liste_des_champs FROM ma_table WHERE champ=valeur ORDER BY champ DESC/ASC \n"; | |
| $msg.="- SELECT liste_des_champs FROM ma_table ORDER BY champ DESC/ASC \n"; | |
| $msg.="- SELECT liste_des_champs FROM ma_table WHERE champ=valeur \n"; | |
| $msg.="- SELECT liste_des_champs FROM ma_table \n"; | |
| $msg.=" la clause where accepte uniquement champ=valeur, champ!=valeur et AND \n"; | |
| $this->erreur('Requete non supportee : '.$sReq.$msg); | |
| } | |
| } | |
| private function findListCritere($tReq){ | |
| $tCritere=array(); | |
| if(isset($tReq['where'])){ | |
| if(preg_match('/ and /i',$tReq['where'])){ | |
| $tWhere=preg_split('/ AND /i',$tReq['where']); | |
| foreach($tWhere as $sWhereVal){ | |
| if(preg_match('/!=/',$sWhereVal)){ | |
| list($sVar,$sVal)=preg_split('/!=/',$sWhereVal); | |
| $tCritere[trim($sVar)]='!'.trim($sVal); | |
| }elseif(preg_match('/=/',$sWhereVal)){ | |
| list($sVar,$sVal)=preg_split('/=/',$sWhereVal); | |
| $tCritere[trim($sVar)]='='.trim($sVal); | |
| } | |
| } | |
| }else{ | |
| if(preg_match('/!=/',$tReq['where'])){ | |
| list($sVar,$sVal)=preg_split('/!=/',$tReq['where']); | |
| $tCritere[trim($sVar)]='!'.trim($sVal); | |
| }elseif(preg_match('/=/',$tReq['where'])){ | |
| list($sVar,$sVal)=preg_split('/=/',$tReq['where']); | |
| $tCritere[trim($sVar)]='='.trim($sVal); | |
| } | |
| } | |
| } | |
| return $tCritere; | |
| } | |
| private function sortResult($tObj,$tReq){ | |
| list($sChamp,$sSens)=preg_split('/ /',trim($tReq['order'])); | |
| $tTri=array(); | |
| $tIdObj=array(); | |
| foreach($tObj as $i => $oObj){ | |
| $tIdObj[ $i ]=$oObj; | |
| $tTri[ $i ]=(string)$oObj->$sChamp; | |
| } | |
| if($sSens=='DESC'){ | |
| arsort($tTri); | |
| }else{ | |
| asort($tTri); | |
| } | |
| $tOrderedObj=array(); | |
| $tId= array_keys($tTri); | |
| foreach($tId as $id){ | |
| $tOrderedObj[]=$tIdObj[$id]; | |
| } | |
| return $tOrderedObj; | |
| } | |
| private function findIndexForTable($sTable,$tSqlFieldEqual){ | |
| $oDirIndex=new _dir($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index'); | |
| if($oDirIndex->exist()){ | |
| $tFileIndex=$oDirIndex->getListDir(); | |
| foreach($tFileIndex as $oFileIndex){ | |
| $tFieldIndex=$this->getFieldsFromIndex($oFileIndex->getName()); | |
| foreach($tSqlFieldEqual as $sSqlFieldEqual){ | |
| if( | |
| $sSqlFieldEqual[0]=='=' and !in_array(substr($sSqlFieldEqual,1),$tFieldIndex) | |
| or | |
| $sSqlFieldEqual[0]=='!' and in_array(substr($sSqlFieldEqual,1),$tFieldIndex) | |
| ){ | |
| continue 2; | |
| } | |
| } | |
| return $oFileIndex->getName(); | |
| } | |
| } | |
| return null; | |
| } | |
| private function findWithTableIndex($sClassRow,$sTable,$sIndexToUse,$tCritere){ | |
| $sDirIndex=$this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index/'.$sIndexToUse; | |
| $tFieldIndex=preg_split('/\./',$sIndexToUse); | |
| $oDirIndex=new _dir($sDirIndex); | |
| $tFileIndex=$oDirIndex->getListFile(); | |
| $tObj=array(); | |
| foreach($tFileIndex as $oFileIndex){ | |
| $sFileIndex=trim($oFileIndex->getName()); | |
| $tRow=$this->getRowValueFromIndex($sFileIndex,$tFieldIndex); | |
| foreach($tCritere as $sCritereField => $sCritereVal){ | |
| if(!isset($tRow[$sCritereField]) or | |
| ( | |
| ($sCritereVal[0]=='=' and (string)$sCritereVal!=(string)'='.$tRow[$sCritereField]) | |
| or | |
| ($sCritereVal[0]=='!' and (string)$sCritereVal==(string)'!'.$tRow[$sCritereField]) | |
| ) | |
| ){ | |
| continue 2; | |
| } | |
| } | |
| $tMatchedFile=file( $sDirIndex.'/'.$sFileIndex ); | |
| foreach($tMatchedFile as $sMatchedFile){ | |
| $sMatchedFile=trim($sMatchedFile); | |
| $sFilename=$this->_tConfig[$this->_sConfig.'.database'].$sTable.'/'.$sMatchedFile; | |
| $tRow=(array)$this->json_decode($sFilename); | |
| $oRow=new $sClassRow($tRow); | |
| $tObj[]=$oRow; | |
| } | |
| } | |
| return $tObj; | |
| } | |
| private function findInTableWithCritere($sClassRow,$sTable,$tCritere){ | |
| $oDir=new _dir($this->_tConfig[$this->_sConfig.'.database'].$sTable); | |
| $tFile=$oDir->getListFile(); | |
| $tObj=array(); | |
| foreach($tFile as $oFile){ | |
| if( in_array($oFile->getName(),array('structure.csv','max.txt'))){ continue; } | |
| $tRow=(array)$this->json_decode($oFile->getAdresse()); | |
| foreach($tCritere as $sCritereField => $sCritereVal){ | |
| if(!isset($tRow[$sCritereField]) or | |
| ( | |
| ($sCritereVal[0]=='=' and (string)$sCritereVal!=(string)'='.$tRow[$sCritereField]) | |
| or | |
| ($sCritereVal[0]=='!' and (string)$sCritereVal==(string)'!'.$tRow[$sCritereField]) | |
| ) | |
| ){ | |
| continue 2; | |
| } | |
| } | |
| $oRow=new $sClassRow($tRow); | |
| $tObj[]=$oRow; | |
| } | |
| return $tObj; | |
| } | |
| public function quote($sVal){ | |
| return $sVal; | |
| } | |
| public function getWhereAll(){ | |
| return '1=1'; | |
| } | |
| private function getFieldsFromIndex($sIndex){ | |
| $tFields=preg_split('/\./',substr($sIndex,0,-6));//field.field.index | |
| return $tFields; | |
| } | |
| private function getRowValueFromIndex($sFileIndex,$tFieldIndex){ | |
| $tValue=preg_split('/####/',substr($sFileIndex,0,-4) ); | |
| $tRow=array(); | |
| foreach($tFieldIndex as $i => $var){ | |
| $tRow[$var]=$tValue[$i]; | |
| } | |
| return $tRow; | |
| } | |
| private function getFileIndexFromTab($sIndex,$tRow){ | |
| $tFields=$this->getFieldsFromIndex($sIndex); | |
| $sFileIndex=''; | |
| foreach($tFields as $sField){ | |
| $sFileIndex.=$tRow[$sField]; | |
| $sFileIndex.='####'; | |
| } | |
| return $sFileIndex.'.csv'; | |
| } | |
| public function generateIndexForTable($sTable,$sIndex){ | |
| $tFields=$this->getFieldsFromIndex($sIndex); | |
| $oDir=new _dir($this->_tConfig[$this->_sConfig.'.database'].$sTable); | |
| $tFile=$oDir->getListFile(); | |
| $tIndexContent=array(); | |
| foreach($tFile as $oFile){ | |
| if($oFile->getName() == 'structure.csv'){ continue;} | |
| if($oFile->getName() == 'max.txt'){ continue;} | |
| $tRow=(array)$this->json_decode($oFile->getAdresse()); | |
| $sKey=''; | |
| foreach($tFields as $sField){ | |
| $sKey.=$tRow[$sField]; | |
| $sKey.='####'; | |
| } | |
| $tIndexContent[$sKey][]=$tRow['id'].'.json'; | |
| } | |
| $oDir=new _dir($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index/'.$sIndex); | |
| foreach($oDir->getListFile() as $oFile){ | |
| $oFile->delete(); | |
| } | |
| foreach($tIndexContent as $sKey => $tFile){ | |
| $oFile=new _file($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index/'.$sIndex.'/'.$sKey.'.csv'); | |
| $oFile->setContent(implode($tFile,"\n")); | |
| $oFile->save(); | |
| } | |
| } | |
| private function addRowInAllIndex($sTable,$tProperty){ | |
| $oDir=new _dir($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index'); | |
| if($oDir->exist()){ | |
| $tDirIndex=$oDir->getListDir(); | |
| foreach($tDirIndex as $oDirIndex){ | |
| $this->addRowInIndex($sTable,$tProperty,$oDirIndex->getName()); | |
| } | |
| } | |
| } | |
| private function addRowInIndex($sTable,$tProperty,$sIndex){ | |
| $sFileIndex=$this->getFileIndexFromTab($sIndex,$tProperty); | |
| $oFile=new _file($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index/'.$sIndex.'/'.$sFileIndex); | |
| $oFile->addContent($tProperty['id'].'.json'); | |
| $oFile->save('a'); | |
| } | |
| private function removeRowFromAllIndex($sTable,$tProperty){ | |
| $oDir=new _dir($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index'); | |
| if($oDir->exist()){ | |
| $tDirIndex=$oDir->getListDir(); | |
| foreach($tDirIndex as $oDirIndex){ | |
| $this->removeRowFromIndex($sTable,$tProperty,$oDirIndex->getName()); | |
| } | |
| } | |
| } | |
| private function removeRowFromIndex($sTable,$tProperty,$sIndex){ | |
| $sFileIndex=$this->getFileIndexFromTab($sIndex,$tProperty); | |
| if(!file_exists($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index/'.$sIndex.'/'.$sFileIndex)){ | |
| return; | |
| } | |
| $tLine=file($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index/'.$sIndex.'/'.$sFileIndex); | |
| $tContent=array(); | |
| foreach($tLine as $sLine){ | |
| $sLine=trim($sLine); | |
| if($sLine==$tProperty['id'].'.json'){ | |
| continue; | |
| } | |
| $tContent[]=$sLine; | |
| } | |
| $oFile=new _file($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/index/'.$sIndex.'/'.$sFileIndex); | |
| $oFile->setContent(implode("\n",$tContent)); | |
| $oFile->save(); | |
| } | |
| private function getIdFromTab($tId){ | |
| if(is_array($tId)){ | |
| return current($tId); | |
| }else{ | |
| return $tId; | |
| } | |
| } | |
| private function save($oJson,$sFichier){ | |
| $sJson=json_encode($oJson); | |
| file_put_contents($sFichier,$sJson); | |
| } | |
| private function getMaxId($sTable){ | |
| $iMax=trim(file_get_contents($this->_tConfig[$this->_sConfig.'.database'].$sTable.'/max.txt')); | |
| return (int)$iMax; | |
| } | |
| private function json_decode($sFile){ | |
| return json_decode(file_get_contents($sFile)); | |
| } | |
| } |