Karima Rafes has uploaded a new change for review. https://gerrit.wikimedia.org/r/178065
Change subject: Fix hyperlink for HTML and update lib ...................................................................... Fix hyperlink for HTML and update lib Change-Id: I8d2f198d9a2e0ad436f3d005f925750a1ee422b0 --- M LinkedWiki.php A lib/SPARQL/ConversionMimetype.php M lib/SPARQL/Curl.php M lib/SPARQL/Endpoint.php M lib/SPARQL/ParserCSV.php M lib/SPARQL/ParserSparqlResult.php M lib/SPARQL/ParserTurtle.php M lib/SPARQL/README.md A lib/SPARQL/ToolsBlankNode.php A lib/SPARQL/ToolsConvert.php M lib/SPARQL/composer.json M lib/SPARQL/query M test/sparqlbasic.feature M test/table2CSV.feature M test/tests.sh 15 files changed, 1,111 insertions(+), 185 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/LinkedWiki refs/changes/65/178065/1 diff --git a/LinkedWiki.php b/LinkedWiki.php index 456bab6..cd44a47 100644 --- a/LinkedWiki.php +++ b/LinkedWiki.php @@ -563,7 +563,7 @@ $str .= "<td>"; if($row[$variable." type"] == "uri" ){ - $str .= efSparqlParserFunction_uri2Link($row[$variable]) ; + $str .= "<a href='".$row[$variable]."'>".$row[$variable]."</a>" ; }else{ $str .= $row[$variable] ; } diff --git a/lib/SPARQL/ConversionMimetype.php b/lib/SPARQL/ConversionMimetype.php new file mode 100644 index 0000000..84ec1d2 --- /dev/null +++ b/lib/SPARQL/ConversionMimetype.php @@ -0,0 +1,59 @@ +<?php +/** + * @git g...@github.com:BorderCloud/SPARQL.git + * @author Karima Rafes <karima.ra...@bordercloud.com> + * @license http://creativecommons.org/licenses/by-sa/4.0/ +*/ + +class ConversionMimetype { + + private static $_mimetypeToShortname; + private static $_filenameExtensionToMimetype; + + private static function init() + { + $_mimetypeToShortname = array(); + $_filenameExtensionToMimetype = array(); + self::add('rdf','rdf', 'application/rdf+xml'); + self::add('nt','text', 'text/plain'); + self::add('csv','csv', 'text/csv; charset=utf-8'); + self::add('','csv', 'text/csv'); + self::add('tsv','tsv', 'text/tab-separated-values; charset=utf-8'); + self::add('','tsv', 'text/tab-separated-values'); + self::add('ttl','ttl', 'text/turtle'); + self::add('srx','xml', 'application/sparql-results+xml'); + self::add('srj','json', 'application/sparql-results+json'); + } + + private static function add($extension, $shortname, $mimetype) + { + self::$_mimetypeToShortname[$mimetype] = $shortname; + + if(!EMPTY($extension)) + self::$_filenameExtensionToMimetype[$extension] = $mimetype; + } + + public static function getMimetypeOfFilenameExtensions($extension) + { + if (self::$_filenameExtensionToMimetype == null) + self::init(); + + if (array_key_exists($extension, self::$_filenameExtensionToMimetype)) { + return self::$_filenameExtensionToMimetype[$extension]; + }else{ + return NULL; + } + } + + public static function getShortnameOfMimetype($mimetype) + { + if (self::$_mimetypeToShortname == null) + self::init(); + + if (array_key_exists($mimetype, self::$_mimetypeToShortname)) { + return self::$_mimetypeToShortname[$mimetype]; + }else{ + return NULL; + } + } +} \ No newline at end of file diff --git a/lib/SPARQL/Curl.php b/lib/SPARQL/Curl.php index bca705d..9c50cd4 100644 --- a/lib/SPARQL/Curl.php +++ b/lib/SPARQL/Curl.php @@ -12,21 +12,21 @@ * @access private * @var resource */ - public $ch ; + var $ch ; /** * set debug to true in order to get usefull output * @access private * @var string */ - public $debug = false; + var $debug = false; /** * Contain last error message if error occured * @access private * @var string */ - public $error_msg; + var $error_msg; /** * Curl_HTTP_Client constructor @@ -63,7 +63,12 @@ */ function set_credentials($username,$password) { - curl_setopt($this->ch, CURLOPT_USERPWD, "$username:$password"); + + curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($this->ch, CURLOPT_USERPWD, $username.":".$password); + curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true); } /** @@ -117,7 +122,7 @@ * @return string data * @access public */ - function send_post_data($url, $postdata, $arrayHeader=null, $ip=null, $timeout=10) + function send_post_data($url, $postdata, $arrayHeader=null, $ip=null, $timeout=600) { //set various curl options first if($this->debug) diff --git a/lib/SPARQL/Endpoint.php b/lib/SPARQL/Endpoint.php index b4f5aac..8d4b5bb 100644 --- a/lib/SPARQL/Endpoint.php +++ b/lib/SPARQL/Endpoint.php @@ -7,7 +7,10 @@ require_once("Curl.php"); require_once("Net.php"); require_once("Base.php"); +require_once("ToolsConvert.php"); +require_once("ToolsBlankNode.php"); require_once("ParserSparqlResult.php"); +//require_once("ConversionMimetype.php"); /** * Sparql HTTP Client for SPARQL1.1's Endpoint @@ -224,6 +227,10 @@ */ private $_nameParameterQueryWrite; + + private $_login; + private $_password; + /** For Arc2 **/ // private $_arc2_RemoteStore; // private $_arc2_Reader; @@ -360,6 +367,42 @@ public function getNameParameterQueryRead() { return $this->_nameparameterQueryRead; } + + /** + * Set the server login + * @param string $login : server login + * @access public + */ + public function setLogin($login) { + $this->_login = $login; + } + + /** + * Get the server login + * @return string $login : server login + * @access public + */ + public function getLogin() { + return $this->_login; + } + + /** + * Set the server password + * @param string $password : server password + * @access public + */ + public function setPassword($password) { + $this->_password = $password; + } + + /** + * Get the server login + * @return string $password : server password + * @access public + */ + public function getPassword() { + return $this->_password; + } /** * Check if the server is up. @@ -452,7 +495,9 @@ $response = $client->send_post_data($sUri,$data); }else{ $data = array($this->_nameParameterQueryRead => $query, + //"output" => ConversionMimetype::getShortnameOfMimetype($typeOutput), //possible fix for 4store/fuseki.. "Accept" => $typeOutput); //fix for sesame + //print_r($data); $response = $client->send_post_data($sUri,$data,array('Accept: '.$typeOutput)); } @@ -462,7 +507,7 @@ if($code < 200 || $code >= 300) { - $error = $this->errorLog($query,$data,$sUri,$code,$response); + $error = $this->errorLog($query,$data,$sUri,$code,$response. $client->get_error_msg() ); $this->addError($error); return false; } @@ -490,6 +535,7 @@ $response = $client->send_post_data($sUri,$data); }else{ $data = array($this->_nameParameterQueryWrite => $query, + //"output" => ConversionMimetype::getShortnameOfMimetype($typeOutput), //possible fix for 4store/fuseki... "Accept" => $typeOutput); //fix for sesame $response = $client->send_post_data($sUri,$data,array('Accept: '.$typeOutput)); } @@ -565,10 +611,13 @@ * @access private */ private function initCurl(){ - $objCurl = new Curl(); + $objCurl = new Curl();//$this->_debug if($this->_proxy_host != null && $this->_proxy_port != null){ $objCurl->set_proxy($this->_proxy_host.":".$this->_proxy_port); } + if($this->_login != null && $this->_password != null){ + $objCurl->set_credentials($this->_login,$this->_password); + } return $objCurl; } } diff --git a/lib/SPARQL/ParserCSV.php b/lib/SPARQL/ParserCSV.php index 686923b..3409fca 100644 --- a/lib/SPARQL/ParserCSV.php +++ b/lib/SPARQL/ParserCSV.php @@ -7,7 +7,8 @@ class ParserCSV { - function csv_to_array($csv, $delimiter = ',', $enclosure = '"', $escape = '\\', $terminator = "\n") { + function csv_to_array($csv, $delimiter = ',', $enclosure = '\'', $escape = '\\', $terminator = "\n") { + $r = array(); //$string = utf8_encode($csv); //echo mb_detect_encoding($names); @@ -19,13 +20,21 @@ foreach ($rows as $row) { if (trim($row)) { $values =str_getcsv($row,$delimiter,$enclosure,$escape) ; + if (!$values) $values = array_fill(0,$nc,null); $tabTemp = array(); //array_combine($names,$values); foreach($names as $key=>$nameCol){ if(isset($values[$key])){ - $tabTemp[$nameCol] = $values[$key]; + + $value = $values[$key]; + if (ToolsConvert::isTrueFloat($value)) { + $value = floatval($value); + } elseif (is_int($value)) { + $value = intval($value); + } + $tabTemp[$nameCol] = $value; }else{ $tabTemp[$nameCol] = NULL; } @@ -76,4 +85,120 @@ usort($result, 'ParserCSV::mySortAllColumn'); return $result; } + + public static function compare($rs1,$rs2,$ordered=false,$distinct=false) { + $difference=array(); + //A/ Check the variables lists in the header are the same. + if(count($rs1) ==0 && count($rs2) ==0){ + return $difference; //return true ; + }elseif (count($rs1[0]) != count($rs2[0])) { + $difference[1]="Nb columns :".count($rows1); + $difference[2]="Nb columns :".count($rows2); + return $difference; //return false ; + } + + + //Check if there are blanknodes////////////////////// + //ref : http://blog.datagraph.org/2010/03/rdf-isomorphism + + // 1.Compare graph sizes and all statements without blank nodes. If they do not match, fail. + //1.1 remove blank nodes + $clone1WithoutBlanknodes = NULL; + $clone2WithoutBlanknodes = NULL; + if($distinct){ + $clone1WithoutBlanknodes = $rs1; + $clone2WithoutBlanknodes = $rs2; + }else{ + $clone1WithoutBlanknodes = ToolsBlankNode::removeDuplicate($rs1); + $clone2WithoutBlanknodes = ToolsBlankNode::removeDuplicate($rs2); + } + + $bnodesInRs1=array(); + $bnodesInRs2=array(); + $patternBlankNode = '/^_:/'; + + // echo "AVANT"; + // print_r($clone1); + // print_r($clone2); + foreach ($clone1WithoutBlanknodes as &$row) { + foreach ($row as $key=>&$value) { + if (preg_match($patternBlankNode, $value)) { + $bnodesInRs1[] = $value ; + $value = "BLANKNODE";//remove + } + } + } + foreach ($clone2WithoutBlanknodes as &$row) { + foreach ($row as $key=>&$value) { + if (preg_match($patternBlankNode, $value)) { + $bnodesInRs2[] = $value ; + $value = "BLANKNODE";//remove + } + } + } + + // print_r($clone1WithoutBlanknodes); + //print_r($clone2WithoutBlanknodes); + //exit(); + //1.2 compare + if($ordered){ + $difference = ToolsBlankNode::array_diff_assoc_recursive( $clone1WithoutBlanknodes, $clone2WithoutBlanknodes); + }else{ + $difference = ToolsBlankNode::array_diff_assoc_unordered( $clone1WithoutBlanknodes, $clone2WithoutBlanknodes) ; + } + + //Check if there are blank nodes + if((count($bnodesInRs1) == 0 && count($bnodesInRs2) == 0 ) || count($difference) != 0) + return $difference; + + //With blank nodes + $bnodesInRs1=array_values(array_unique($bnodesInRs1)); + $bnodesInRs2=array_values(array_unique($bnodesInRs2)); + if(count($bnodesInRs1) != count($bnodesInRs2)) { + $difference[1]="Nb bnode :".count($bnodesInRs1); + $difference[2]="Nb bnode :".count($bnodesInRs2); + return $difference; //return false ; + } + +// echo "BLANKNODE\n"; +// print_r($bnodesInRs1); +// print_r($bnodesInRs2); + + $clone1 = $rs1; +// print_r($clone1); + + // 2.Repeat, for each graph: + $arrayPermutationsBnode = ToolsBlankNode::AllPermutations($bnodesInRs2); + //echo "PERMUTATION\n"; + //print_r($arrayPermutationsBnode ); + //exit(); + foreach ( $arrayPermutationsBnode as $permute) { +// print_r($permute); + $clone2 = $rs2; + foreach ( $clone2 as $key=>&$row) { + $arrayVariableTypeBnode = array_keys( $row , "bnode") ; + foreach ($arrayVariableTypeBnode as $variableTypeBnode) { + $variableArray = split(" ",$variableTypeBnode); + $variable=$variableArray[0]; + + $row[$variable] = $bnodesInRs1[array_search($row[$variable] ,$permute)]; + } + } + +// print_r($clone2); + + if($ordered){ + $difference = ToolsBlankNode::array_diff_assoc_recursive( $clone1WithoutBlanknodes, $clone2WithoutBlanknodes); + }else{ + $difference = ToolsBlankNode::array_diff_assoc_unordered( $clone1WithoutBlanknodes, $clone2WithoutBlanknodes) ; + } + if(count($difference) == 0){ + return $difference; //true + } + } + + return $difference; + } + + } diff --git a/lib/SPARQL/ParserSparqlResult.php b/lib/SPARQL/ParserSparqlResult.php index f03702d..1247797 100644 --- a/lib/SPARQL/ParserSparqlResult.php +++ b/lib/SPARQL/ParserSparqlResult.php @@ -63,86 +63,258 @@ //callback for the end of each element function endElement($parser_object, $elementname) { if($elementname == "binding"){ - if(!isset($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"])) - $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"]=NULL; - - if($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"] == "uri"){ - $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = trim($this->_value); - }elseif($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"] == "literal"){ - $value = trim($this->_value); - if(array_key_exists($this->_cellCurrent." datatype",$this->_result['result']['rows'][$this->_rowCurrent])){ - if($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." datatype"] == "http://www.w3.org/2001/XMLSchema#double" || - $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." datatype"] == "http://www.w3.org/2001/XMLSchema#decimal" - ){ - $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = floatval($value); - }elseif($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." datatype"] == "http://www.w3.org/2001/XMLSchema#integer" - ){ - $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = intval($value); - }elseif($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." datatype"] == "http://www.w3.org/2001/XMLSchema#boolean" - ){ - $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = $value === "true" ? true : false; - }else{ - $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = $value; - } - }else{ + + if(strlen(trim($this->_value)) == 0) + return; + + if(!isset($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"])) + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"]=NULL; + + if($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"] == "uri"){ + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = trim($this->_value); + }elseif($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"] == "bnode"){ + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = trim($this->_value); + }elseif($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." type"] == "literal"){ + $value = trim($this->_value); + if(array_key_exists($this->_cellCurrent." datatype",$this->_result['result']['rows'][$this->_rowCurrent])){ + if($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." datatype"] == "http://www.w3.org/2001/XMLSchema#double" || + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." datatype"] == "http://www.w3.org/2001/XMLSchema#decimal" + ){ + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = floatval($value); + }elseif($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." datatype"] == "http://www.w3.org/2001/XMLSchema#integer" + ){ + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = intval($value); + }elseif($this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent." datatype"] == "http://www.w3.org/2001/XMLSchema#boolean" + ){ + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = $value === "true" ? true : false; + }else{ $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = $value; } }else{ - $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = $this->_value; + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = $value; } - $this->_cellCurrent = null; - $this->_value = ""; - } - } - - //callback for the content within an element - function contentHandler($parser_object,$data) - { - if($this->_cellCurrent != null){ - // echo "DATA". $data." - ".$this->_cellCurrent."\n"; - $this->_value .= $data; - } - } - - function sortResult($array){ - $result = $array; - if(isset($result['result']['rows'])) - usort($result['result']['rows'], 'ParserSparqlResult::mySortResult'); - return $result; - } - - function mySortResult($row1, $row2){ - $result = 0; - $countTab = 0; - if( count($row1) > count($row2)){ - $countTab = count($row1); }else{ - $countTab = count($row2); + $this->_result['result']['rows'][$this->_rowCurrent][$this->_cellCurrent] = $this->_value; } - - for($i=0; $i < $countTab; $i++){ - if((!isset($row1[$i])) || (!isset($row2[$i]))){ - if(isset($row1[$i]) && isset($row2[$i])){//impossible in theory - $result = 0; - break; - }elseif(!isset($row1[$i])){ - $result = -1; - break; - }elseif(!isset($row2[$i])){ - $result = 1; - break; - } - } - else if($row1[$i] < $row2[$i]){ - $result = 1; - break; - } - else if($row1[$i] < $row2[$i]){ - $result = -1; - break; - } - } - return $result; + $this->_cellCurrent = null; + $this->_value = ""; + } + } + + //callback for the content within an element + function contentHandler($parser_object,$data) + { + if($this->_cellCurrent != null){ + // echo "DATA". $data." - ".$this->_cellCurrent."\n"; + $this->_value .= $data; + } + } + + function sortResult($array){ + $result = $array; + if(isset($result['result']['rows'])) + usort($result['result']['rows'], 'ParserSparqlResult::mySortResult'); + return $result; + } + + function mySortResult($row1, $row2){ + $result = 0; + $countTab = 0; + if( count($row1) > count($row2)){ + $countTab = count($row1); + }else{ + $countTab = count($row2); + } + + for($i=0; $i < $countTab; $i++){ + if((!isset($row1[$i])) || (!isset($row2[$i]))){ + if(isset($row1[$i]) && isset($row2[$i])){//impossible in theory + $result = 0; + break; + }elseif(!isset($row1[$i])){ + $result = -1; + break; + }elseif(!isset($row2[$i])){ + $result = 1; + break; + } + } + else if($row1[$i] < $row2[$i]){ + $result = 1; + break; + } + else if($row1[$i] < $row2[$i]){ + $result = -1; + break; + } + } + return $result; + } + + public static function compare($rs1,$rs2,$ordered=false,$distinct=false) { + $difference=array(); + //A/ Check the variables lists in the header are the same. + if(! isset($rs1['result']['variables']) && ! isset($rs2['result']['variables'])){ + return $difference; //return true ; + }elseif (! isset($rs1['result']['variables']) || ! isset($rs2['result']['variables']) ) { + $difference[1]=$rs1['result']['variables']; + $difference[2]=$rs2['result']['variables']; + return $difference; //return false ; + } + + //Check if there are blanknodes////////////////////// + //ref : http://blog.datagraph.org/2010/03/rdf-isomorphism + +// 1.Compare graph sizes and all statements without blank nodes. If they do not match, fail. +//1.1 remove blank nodes + $clone1WithoutBlanknodes = NULL; + $clone2WithoutBlanknodes = NULL; + if($distinct){ + $clone1WithoutBlanknodes = $rs1['result']['rows']; + $clone2WithoutBlanknodes = $rs2['result']['rows']; + }else{ + $clone1WithoutBlanknodes = ToolsBlankNode::removeDuplicate($rs1['result']['rows']); + $clone2WithoutBlanknodes = ToolsBlankNode::removeDuplicate($rs2['result']['rows']); + } + + $bnodesInRs1=array(); + $bnodesInRs2=array(); + + // echo "AVANT"; + // print_r($clone1); + // print_r($clone2); + foreach ($clone1WithoutBlanknodes as $key=>&$row) { + $arrayVariableTypeBnode = array_keys( $row , "bnode") ; + foreach ($arrayVariableTypeBnode as $variableTypeBnode) { + $variableArray = split(" ",$variableTypeBnode); + $variable=$variableArray[0]; + $bnodesInRs1[] = $row[$variable] ; + $row[$variable] = "BLANKNODE";//remove + } + } + foreach ( $clone2WithoutBlanknodes as $key=>&$row) { + $arrayVariableTypeBnode = array_keys( $row , "bnode") ; + foreach ($arrayVariableTypeBnode as $variableTypeBnode) { + $variableArray = split(" ",$variableTypeBnode); + $variable=$variableArray[0]; + $bnodesInRs2[] = $row[$variable] ; + $row[$variable] = "BLANKNODE";//remove + } + } + + //print_r($clone1WithoutBlanknodes); + //print_r($clone2WithoutBlanknodes); +//1.2 compare + if($ordered){ + $difference = ToolsBlankNode::array_diff_assoc_recursive( $clone1WithoutBlanknodes, $clone2WithoutBlanknodes); + }else{ + $difference = ToolsBlankNode::array_diff_assoc_unordered( $clone1WithoutBlanknodes, $clone2WithoutBlanknodes) ; } - -} \ No newline at end of file + + //Check if there are blank nodes + if((count($bnodesInRs1) == 0 && count($bnodesInRs2) == 0 ) || count($difference) != 0) + return $difference; + + //With blank nodes + $bnodesInRs1=array_values(array_unique($bnodesInRs1)); + $bnodesInRs2=array_values(array_unique($bnodesInRs2)); + if(count($bnodesInRs1) != count($bnodesInRs2)) { + $difference[1]="Nb bnode :".count($bnodesInRs1); + $difference[2]="Nb bnode :".count($bnodesInRs2); + return $difference; //return false ; + } + +// echo "BLANKNODE\n"; +// print_r($bnodesInRs1); +// print_r($bnodesInRs2); + $clone1 = $rs1['result']['rows']; + // print_r($clone1); + //$clone2 = $rs2['result']['rows']; + // 2.Repeat, for each graph: + $arrayPermutationsBnode = ToolsBlankNode::AllPermutations($bnodesInRs2); + //echo "PERMUTATION\n"; + //print_r($arrayPermutationsBnode ); + // exit(); + foreach ( $arrayPermutationsBnode as $permute) { + $clone2 = $rs2['result']['rows']; + + //print_r($clone2); + foreach ( $clone2 as $key=>&$row) { + $arrayVariableTypeBnode = array_keys( $row , "bnode") ; + foreach ($arrayVariableTypeBnode as $variableTypeBnode) { + $variableArray = split(" ",$variableTypeBnode); + $variable=$variableArray[0]; + + $row[$variable] = $bnodesInRs1[array_search($row[$variable] ,$permute)]; + } + } + //print_r($clone2); + //$difference = self::sub_array_diff_assoc_unordered( $clone1,$clone2) ; + if($ordered){ + $difference = ToolsBlankNode::array_diff_assoc_recursive($clone1,$clone2); + }else{ + $difference = ToolsBlankNode::array_diff_assoc_unordered($clone1,$clone2) ; + } + + if(count($difference) == 0){ + return $difference; //true + } + } + + return $difference; + } +/* + private static function sub_array_diff_assoc_unordered( $rows1, $rows2) { + $difference=array(); + + //B/ Check the result set have the same number of rows. + if(count($rows1) != count($rows2)) { + $difference[1]="Nb rows :".count($rows1); + $difference[2]="Nb rows :".count($rows2); + return $difference; //return false ; + } + + //C/ Pick a row from the test results, scan the expected results + // to find a row with same variable/value bindings, and remove + // from the expected results. If all test rows, match then + // (because of B) the result sets have the same rows. + // + //return equivalent(convert(rs1), convert(rs2), new BNodeIso(NodeUtils.sameValue)) ; + $clone1 = $rows1; + $clone2 = $rows2; + + // echo "AVANT"; + // print_r($clone1); + // print_r($clone2); + foreach ($rows1 as $key1=>&$value1) { + $tmpclone2 = $clone2; + foreach ($tmpclone2 as $key2=>&$value2) { + + //echo "-------------"; + //print_r($value1); + //print_r($value2); + if(count(array_diff_assoc($value1,$value2)) == 0 && + count(array_diff_assoc($value2,$value1)) == 0 ){ + unset($clone1[$key1]); + unset($clone2[$key2]); + break; + } + } + //echo "-------------APRES"; + //print_r($clone1); + //print_r($clone2); + } + + if(count($clone1) != 0 || + count($clone2) != 0 ){ + $difference[1]=$clone1; + $difference[2]=$clone2; + $difference[1]=$clone1; + $difference[2]=$clone2; + return $difference; //return false ; + } + return $difference; + } + */ +} + diff --git a/lib/SPARQL/ParserTurtle.php b/lib/SPARQL/ParserTurtle.php index d3c9a7c..e4623e6 100644 --- a/lib/SPARQL/ParserTurtle.php +++ b/lib/SPARQL/ParserTurtle.php @@ -7,13 +7,14 @@ class ParserTurtle { - function turtle_to_array($turtle,$baseGraph){ + static function turtle_to_array($turtle,$baseGraph,$idMD5 = false){ $tabResult = array(); $tabResult["prefix"] = array(); $tabResult["prefix"]["base"] = $baseGraph; $tabResult["triples"] = array(); - preg_match_all("/((?:(?:\"|').*(?:\"|')(?:\^\^[^\s]*)?|a|<[^\s]*>|[^\s]*:[^\s]+|;|,|@prefix\s*[^\s]*\s*:\s*<[^\s<>]+>|\s*\r?\n?)+\s\.)/i",$turtle, $matches, PREG_SET_ORDER); + preg_match_all("/((?:(?:\"|').*(?:\"|')(?:\^\^[^\s]*)?|a|<[^\s]*>|[^\s]*:[^\s]+|;|,|@prefix\s*[^\s]*\s*:\s*<[^\s<>]+>|\s*\r?\n?)+\s?\.)/i",$turtle, $matches, PREG_SET_ORDER); + foreach ($matches as $val) { //// http://answers.semanticweb.com/questions/2025/what-is-the-meaning-of-base-and-prefix-in-turtle-documents @@ -23,44 +24,61 @@ $namePrefix = $valMatches[1] == "" ? "empty" : $valMatches[1]; $tabResult["prefix"][$namePrefix] = $valMatches[2]; }elseif(preg_match("/^\s*(<[^\s]*>|[^\s]*:[^\s]+)\s*(.*)\s*\.$/is", $val[0], $valMatches)){ - $object = ParserTurtle::relativeToExplicitURI($valMatches[1],$tabResult["prefix"]) ; - - preg_match_all("/\s*(a|<[^\s]*>|[^\s]*:[^\s]+)\s*((?:(?:<[^\s]*>|[^\s]*:[^\s]+|(?:\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*')(?:\^\^[^\s]*)?|\s*),?)+\s*);?/is",$valMatches[2], $propertyMatches, PREG_SET_ORDER); - foreach ($propertyMatches as $propertyVal) { - $property =""; - if($propertyVal[1] == "a"){ - $property = "<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>" ; - }else{ - $property = ParserTurtle::relativeToExplicitURI($propertyVal[1],$tabResult["prefix"]) ; - } - preg_match_all("/(<[^\s]*>|[^\s]*:[^\s]+|(?:\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*')(?:\^\^[^\s]*)?)\s*,?/is",$propertyVal[2], $valueMatches, PREG_SET_ORDER); - - foreach ($valueMatches as $valueVal) { - $value = ParserTurtle::relativeToExplicitURI($valueVal[1],$tabResult["prefix"]) ; - //echo "s=>".$object." p=>".$property." o=>".$value."\n"; - $tabResult["triples"][] = array("s"=>$object,"p"=>$property,"o"=>$value); - } - } - } + $object = ParserTurtle::relativeToExplicitURI($valMatches[1],$tabResult["prefix"]) ; + preg_match_all("/\s*(a|<[^\s\,\;]*>|[^\s]*:[^\s\;]+)\s*((?:(?:<[^\s\,\;]*>|[^\s]*:[^\s\;]+|(?:\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*')(?:\^\^[^\s\;]*)?|\s*),?)+\s*);?/is",$valMatches[2], $propertyMatches, PREG_SET_ORDER); + foreach ($propertyMatches as $propertyVal) { + + $property =""; + if($propertyVal[1] == "a"){ + $property = "<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>" ; + }else{ + $property = ParserTurtle::relativeToExplicitURI($propertyVal[1],$tabResult["prefix"]) ; + } + preg_match_all("/(<[^\s\,\;]*>|[^\s]*:[^\s\,]+|(?:\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*')(?:\^\^[^\s\,]*)?)\s*,?/is",$propertyVal[2], $valueMatches, PREG_SET_ORDER); + foreach ($valueMatches as $valueVal) { + $value = ParserTurtle::relativeToExplicitURI($valueVal[1],$tabResult["prefix"]) ; + //echo "s=>".$object." p=>".$property." o=>".$value."\n"; + if($idMD5) + $tabResult["triples"][md5($object.$property.$value)] = array("s"=>$object,"p"=>$property,"o"=>$value); + else + $tabResult["triples"][] = array("s"=>$object,"p"=>$property,"o"=>$value); + } + } + } } return $tabResult; } - function relativeToExplicitURI($uri,$prefix){ + static function relativeToExplicitURI($uri,$prefix){ $result = $uri; - if(preg_match("/^(\"(?:\\\"|[^\"])*\"|'(?:\\'|[^'])*')(?:\^\^([^\s]*))?$/i",$uri, $matches)){//<> if(isset($matches[2])){ - $result = $matches[1]."^^".ParserTurtle::relativeToExplicitURI($matches[2],$prefix); + $type = ParserTurtle::relativeToExplicitURI($matches[2],$prefix); + $value = $matches[1]; + if($type == "http://www.w3.org/2001/XMLSchema#double" || + $type == "http://www.w3.org/2001/XMLSchema#decimal" ){ + $value = floatval($value); + }elseif($type == "http://www.w3.org/2001/XMLSchema#integer"){ + $value = intval($value); + //}elseif($type == "http://www.w3.org/2001/XMLSchema#boolean"){ + // $value = $value === "true" ? true : false; + } + $result = "\"".$value."\"^^".$type; }else{ - $result = $matches[1]; + $value = $matches[1]; + if (ToolsConvert::isTrueFloat($value)) { + $value = floatval($value); + } elseif (is_int($value)) { + $value = intval($value); + } + $result = $value; } }elseif(preg_match("/^<>$/i",$uri, $matches)){//<> $result = "<".$prefix["base"].">"; }elseif(preg_match("/^<#([^:]+)>$/i",$uri, $matches)){//<#truc> $result = "<".$prefix["base"].$matches[1].">"; - }elseif(preg_match("/^<#([^:]+)>$/i",$uri, $matches)){//<truc> + }elseif(preg_match("/^<([^:]+)>$/i",$uri, $matches)){//<truc> $len = strlen( $prefix["base"]); $prefixbase = substr( $prefix["base"], 0, strrpos ($prefix["base"] , "/")); $result = "<".$prefixbase.$matches[1].">"; @@ -68,11 +86,19 @@ $result = "<".$prefix["empty"].$matches[1].">"; }elseif(preg_match("/^([^:_]*):([^><]*)$/i",$uri, $matches)){//x:truc $result = "<".$prefix[$matches[1]].$matches[2].">"; + }else{ + $value = $uri; + if (ToolsConvert::isTrueFloat($value)) { + $value = floatval($value); + } elseif (is_int($value)) { + $value = intval($value); + } + $result = $value; } return $result; } - function mySortTriples($itm1, $itm2){ + static function mySortTriples($itm1, $itm2){ if($itm1["s"] > $itm2["s"]){ return 1; } @@ -100,12 +126,210 @@ } } - function sortTriples($arrayTurtle){ - $result = $arrayTurtle; - array_multisort($result["prefix"],SORT_ASC,SORT_STRING); + static function sortTriples($arrayTurtle){ + $result = $arrayTurtle; + array_multisort($result["prefix"],SORT_ASC,SORT_STRING); + + usort($result["triples"], 'ParserTurtle::mySortTriples'); + + return $result; + } + + static function getKey($arrayTurtle, $s,$p){ + $result = null; + if(!EMPTY($arrayTurtle)){ + foreach ($arrayTurtle["triples"] as $key=>$triple) { + if("<".$s.">" == $triple["s"] && "<".$p.">" == $triple["p"] ){ + $result = $key; + break; + } + } + } + return $key; + } + static function getTriple($arrayTurtle, $s,$p){ + $result = null; + if(!EMPTY($arrayTurtle)){ + foreach ($arrayTurtle["triples"] as $key=>$triple) { + if("<".$s.">" == $triple["s"] && "<".$p.">" == $triple["p"] ){ + $result = $triple; + preg_match( '@^(?:<tel\:([^<>]+)>|<mailto\:([^<>]+)>|<([^<>]+)>|([^\"<>]+)|\"(.*)\"[^\"]*)$@i',$triple["o"], $matches); +//\<mailto\:([^\<\>])+\>|\<([^\<\>])+\>| +//print_r($triple["o"]); + //print_r($matches); + foreach ($matches as $key=>$match) { + if($key != 0 && ! EMPTY($match)){ + $result["value"] = $match; + break; + } + } + break; + } + } + } + return $result; + } + + public static function compare($rs1,$rs2,$ordered=false,$distinct=false) { + $difference=array(); + $rs1Triples = NULL; + $rs2Triples = NULL; + + if($distinct){ + $rs1Triples = $rs1["triples"]; + $rs2Triples = $rs2["triples"]; + }else{ + $rs1Triples = ToolsBlankNode::removeDuplicate($rs1["triples"]); + $rs2Triples = ToolsBlankNode::removeDuplicate($rs2["triples"]); + } + + //B/ Check the result set have the same number of rows. + if(count($rs1Triples) != count($rs2Triples)) { + $difference[1]="Nb rows :".count($rs1Triples); + $difference[2]="Nb rows :".count($rs2Triples); + return $difference; //return false ; + } + + //Check if there are blanknodes////////////////////// + //ref : http://blog.datagraph.org/2010/03/rdf-isomorphism + +// 1.Compare graph sizes and all statements without blank nodes. If they do not match, fail. +//1.1 remove blank nodes + $clone1WithoutBlanknodes =$rs1Triples; + $clone2WithoutBlanknodes = $rs2Triples; + $bnodesInRs1=array(); + $bnodesInRs2=array(); + $patternBlankNode = '/^_:/'; + + // echo "AVANT"; + // print_r($clone1); + // print_r($clone2); + foreach ($clone1WithoutBlanknodes as &$row) { + foreach ($row as $key=>&$value) { + if (preg_match($patternBlankNode, $value)) { + $bnodesInRs1[] = $value ; + $value = "BLANKNODE";//remove + } + } + } + foreach ($clone2WithoutBlanknodes as &$row) { + foreach ($row as $key=>&$value) { + if (preg_match($patternBlankNode, $value)) { + $bnodesInRs2[] = $value ; + $value = "BLANKNODE";//remove + } + } + } + + //print_r($clone1WithoutBlanknodes); + //print_r($clone2WithoutBlanknodes); +//1.2 compare + if($ordered){ + $difference = ToolsBlankNode::array_diff_assoc_recursive( $clone1WithoutBlanknodes, $clone2WithoutBlanknodes); + }else{ + $difference = ToolsBlankNode::array_diff_assoc_unordered( $clone1WithoutBlanknodes, $clone2WithoutBlanknodes) ; + } + + //Check if there are blank nodes + if((count($bnodesInRs1) == 0 && count($bnodesInRs2) == 0 ) || count($difference) != 0) + return $difference; + + //With blank nodes + $bnodesInRs1=array_values(array_unique($bnodesInRs1)); + $bnodesInRs2=array_values(array_unique($bnodesInRs2)); + if(count($bnodesInRs1) != count($bnodesInRs2)) { + $difference[1]="Nb bnode :".count($bnodesInRs1); + $difference[2]="Nb bnode :".count($bnodesInRs2); + return $difference; //return false ; + } + + //echo "BLANKNODE\n"; + //print_r($bnodesInRs1); + //print_r($bnodesInRs2); + $clone1 = $rs1Triples; + // print_r($clone1); + // 2.Repeat, for each graph: + $arrayPermutationsBnode = ToolsBlankNode::AllPermutations($bnodesInRs2); + //echo "PERMUTATION\n"; + //print_r($arrayPermutationsBnode ); + //exit(); + foreach ( $arrayPermutationsBnode as $permute) { + //print_r($permute); + $clone2 = $rs2Triples; + foreach ( $clone2 as $key=>&$row) { + $arrayVariableTypeBnode = array_keys( $row , "bnode") ; + foreach ($arrayVariableTypeBnode as $variableTypeBnode) { + $variableArray = split(" ",$variableTypeBnode); + $variable=$variableArray[0]; + + $row[$variable] = $bnodesInRs1[array_search($row[$variable] ,$permute)]; + } + } + + //print_r($clone2); + //$difference = self::sub_array_diff_assoc_unordered( $clone1,$clone2) ; + if($ordered){ + $difference = ToolsBlankNode::array_diff_assoc_recursive($clone1,$clone2); + }else{ + $difference = ToolsBlankNode::array_diff_assoc_unordered($clone1,$clone2) ; + } + if(count($difference) == 0){ + return $difference; //true + } + } + + return $difference; + } + /* + public static function array_diff_assoc_unordered( $rs1, $rs2) { + $difference=array(); + $rs1Triples = $rs1["triples"]; + $rs2Triples = $rs2["triples"]; + + //B/ Check the result set have the same number of rows. + if(count($rs1Triples) != count($rs2Triples)) { + $difference[1]="Nb rows :".count($rs1Triples); + $difference[2]="Nb rows :".count($rs2Triples); + return $difference; //return false ; + } + + //C/ Pick a row from the test results, scan the expected results + // to find a row with same variable/value bindings, and remove + // from the expected results. If all test rows, match then + // (because of B) the result sets have the same rows. + // + //return equivalent(convert(rs1), convert(rs2), new BNodeIso(NodeUtils.sameValue)) ; + $clone1 = $rs1Triples; + $clone2 = $rs2Triples; +// echo "AVANT"; +// print_r($clone1); +// print_r($clone2); + foreach ($rs1Triples as $key1=>&$value1) { + $tmpclone2 = $clone2; + foreach ($tmpclone2 as $key2=>&$value2) { - usort($result["triples"], 'ParserTurtle::mySortTriples'); - - return $result; - } +// echo "-------------"; +// print_r($value1); +// print_r($value2); + if(count(array_diff_assoc($value1,$value2)) == 0 && + count(array_diff_assoc($value2,$value1)) == 0 ){ + unset($clone1[$key1]); + unset($clone2[$key2]); + break; + } + } +// echo "-------------APRES"; +// print_r($clone1); +// print_r($clone2); + } + + if(count($clone1) != 0 || + count($clone2) != 0 ){ + $difference[1]=$clone1; + $difference[2]=$clone2; + return $difference; //return false ; + } + + return $difference; + }*/ } diff --git a/lib/SPARQL/README.md b/lib/SPARQL/README.md index f2ab54d..561b70e 100644 --- a/lib/SPARQL/README.md +++ b/lib/SPARQL/README.md @@ -45,8 +45,12 @@ the request http to write. (by default : update) -f,--file=File File of the query. - -t, --typeOutput=TYPE Type of response: txt,csv,tsv,ttl,srx,srj - (by default : txt) + -t, --typeOutput=TYPE Type of response: table,txt,csv,tsv,ttl,srx,srj + (by default : table) + + -l, --login=LOGIN Server login + -p, --password=PASSWORD Server password + -v, --verbose Mode verbose -d, --debug Mode debug @@ -90,7 +94,7 @@ -f ./example/queryRead1.rq ``` -### Example with API +### Examples Send a simple query to DBpedia : ```php @@ -98,11 +102,47 @@ require_once('bordercloud/Endpoint.php'); - $endpoint ="http://dbpedia.org/"; + $endpoint ="http://dbpedia.org/sparql"; $sp_readonly = new Endpoint($endpoint); $q = "select * where {?x ?y ?z.} LIMIT 5"; $rows = $sp_readonly->query($q, 'rows'); $err = $sp_readonly->getErrors(); + if ($err) { + print_r($err); + throw new Exception(print_r($err,true)); + } + + foreach($rows["result"]["variables"] as $variable){ + printf("%-20.20s",$variable); + echo '|'; + } + echo "\n"; + + foreach ($rows["result"]["rows"] as $row){ + foreach($rows["result"]["variables"] as $variable){ + printf("%-20.20s",$row[$variable]); + echo '|'; + } + echo "\n"; + } +?> +``` + +Send a simple query via an endpoint sparql-auth (with OpenLink Virtuoso Open-Source Edition) : +```php +<?php + +require_once('../Endpoint.php'); + + $endpoint = "https://example.com/sparql-auth"; + $sp_ReadAndWrite = new Endpoint($endpoint,false); + + $sp_ReadAndWrite->setLogin("login"); + $sp_ReadAndWrite->setPassword("password"); + + $q = "select * where {?x ?y ?z.} LIMIT 5"; + $rows = $sp_ReadAndWrite->query($q, 'rows'); + $err = $sp_ReadAndWrite->getErrors(); if ($err) { print_r($err); throw new Exception(print_r($err,true)); @@ -132,9 +172,6 @@ TODO !! git clone http://github.com/BorderCloud/SPARQL.git -### Howto TESTS -TODO !! - ### Contact If you have remarks, questions, or suggestions, please send them to @@ -142,7 +179,7 @@ ### Release-Notes -* V0.1.0.0 version SPARQL.Pro lib PHP by Karima Rafes <karima.ra...@bordercloud.com> +* V1.O.0.0 version SPARQL.Pro lib PHP by Karima Rafes <karima.ra...@bordercloud.com> ### license SPARQL.Pro lib PHP (c)2014 by Karima Rafes - BorderCloud diff --git a/lib/SPARQL/ToolsBlankNode.php b/lib/SPARQL/ToolsBlankNode.php new file mode 100644 index 0000000..31b5523 --- /dev/null +++ b/lib/SPARQL/ToolsBlankNode.php @@ -0,0 +1,165 @@ +<?php +/** + * @git g...@github.com:BorderCloud/SPARQL.git + * @author Karima Rafes <karima.ra...@bordercloud.com> + * @license http://creativecommons.org/licenses/by-sa/4.0/ +*/ +class ToolsBlankNode { + + public static function removeDuplicate($set) + { + $find = false; + $result = array(); + foreach ($set as $key1=>$value1) { + $find = false; + foreach ($result as $key2=>$value2) { + if(count(array_diff_assoc($value1,$value2)) == 0 ){ + $find = true; + break; + } + } + if(! $find) + $result[] = $value1; + + } + return $result; + } + + public static function AllPermutations($set) + { + $solutions=array(); + $solutions[]=$set; + $n=count($set); + $p=array_keys($set); + $i=1; + + while ($i<$n) + { + if ($p[$i]>0){ + $p[$i]--; + $j=0; + if ($i%2==1) + $j=$p[$i]; + //swap + $tmp=$set[$j]; + $set[$j]=$set[$i]; + $set[$i]=$tmp; + $i=1; + $solutions[]=$set; + } + elseif ($p[$i]==0){ + $p[$i]=$i; + $i++; + } + } + return $solutions; + } + + + public static function array_diff_assoc_unordered( $rows1, $rows2) { + $difference=array(); + + //B/ Check the result set have the same number of rows. + if(count($rows1) != count($rows2)) { + $difference[1]="Nb rows :".count($rows1); + $difference[2]="Nb rows :".count($rows2); + return $difference; //return false ; + } + + //C/ Pick a row from the test results, scan the expected results + // to find a row with same variable/value bindings, and remove + // from the expected results. If all test rows, match then + // (because of B) the result sets have the same rows. + // + //return equivalent(convert(rs1), convert(rs2), new BNodeIso(NodeUtils.sameValue)) ; + $clone1 = $rows1; + $clone2 = $rows2; + + // echo "AVANT"; + // print_r($clone1); + // print_r($clone2); + foreach ($rows1 as $key1=>&$value1) { + $tmpclone2 = $clone2; + foreach ($tmpclone2 as $key2=>&$value2) { + + //echo "-------------"; + //print_r($value1); + //print_r($value2); + if(count(array_diff_assoc($value1,$value2)) == 0 && + count(array_diff_assoc($value2,$value1)) == 0 ){ + unset($clone1[$key1]); + unset($clone2[$key2]); + break; + } + } + //echo "-------------APRES"; + //print_r($clone1); + //print_r($clone2); + } + + if(count($clone1) != 0 || + count($clone2) != 0 ){ + $difference[1]=$clone1; + $difference[2]=$clone2; + $difference[1]=$clone1; + $difference[2]=$clone2; + return $difference; //return false ; + } + return $difference; + } + + public static function array_diff_assoc_recursive($array1, $array2) { + $difference=array(); + foreach($array1 as $key => $value) { + if( is_array($value) ) { + if( !isset($array2[$key]) || !is_array($array2[$key]) ) { + $difference[1][$key] = $value; + $difference[2][$key] = "Not set"; + } else { + $new_diff = self::array_diff_assoc_recursive($value, $array2[$key]); + if( count($new_diff)>0 ){ + $difference[1][$key] = $new_diff[1]; + $difference[2][$key] = $new_diff[2]; + } + } + } else if( !array_key_exists($key,$array2)) { + $difference[1][$key] = $value; + $difference[2][$key] = "Key doesnt exist"; + } else if($array2[$key] !== $value) { + $difference[1][$key] = $value; + $difference[2][$key] = $array2[$key]; + } + } + return $difference; + } + /* + function array_diff_assoc_recursive_with_blanknode($array1, $array2) { + $difference=array(); + $node = array(); + foreach($array1 as $key => $value) { + if( is_array($value) ) { + if( !isset($array2[$key]) || !is_array($array2[$key]) ) { + $difference[$key] = $value; + } else { + $new_diff = Tools::array_diff_assoc_recursive_with_blanknode($value, $array2[$key]); + if( !empty($new_diff) ) + $difference[$key] = $new_diff; + } + } else if( !array_key_exists($key,$array2) ) { + $difference[$key] = $value; + } else if( $array2[$key] !== $value && floatval($array2[$key]) !== floatval($value)) { + if(isset($value[0]) && $value[0] == "_"){//(array_key_exists("type",$array1) && $array1["type"] == "bnode"){ + if(!array_key_exists($value,$node )){ + $node[$value] = $array2[$key]; + }else if($node[$value] !== $array2[$key] ){ + $difference[$key] = $value; + } + }else{ + $difference[$key] = $value; + } + } + } + return $difference; + } + */ +} \ No newline at end of file diff --git a/lib/SPARQL/ToolsConvert.php b/lib/SPARQL/ToolsConvert.php new file mode 100644 index 0000000..6ff57ea --- /dev/null +++ b/lib/SPARQL/ToolsConvert.php @@ -0,0 +1,16 @@ +<?php +/** + * @git g...@github.com:BorderCloud/SPARQL.git + * @author Karima Rafes <karima.ra...@bordercloud.com> + * @license http://creativecommons.org/licenses/by-sa/4.0/ +*/ +class ToolsConvert { + + public static function isTrueFloat($val) + { + $pattern = '/^[+-]?(\d*\.\d+([eE]?[+-]?\d+)?|\d+[eE][+-]?\d+)$/'; + //echo 'Val:'. $val."\n"; + //var_dump(is_float($val) || preg_match($pattern, trim($val))); + return (is_float($val) || preg_match($pattern, trim($val))); + } +} \ No newline at end of file diff --git a/lib/SPARQL/composer.json b/lib/SPARQL/composer.json index 1648b04..e1ce7ac 100644 --- a/lib/SPARQL/composer.json +++ b/lib/SPARQL/composer.json @@ -1,5 +1,23 @@ { - "name": "BorderCloud/SPARQL", + "name": "bordercloud/sparql", + "type": "library", + "description": "Lib PHP very easy for SPARQL 1.1", + "keywords": ["SPARQL","RDF"], + "homepage": "https://github.com/BorderCloud/SPARQL", + "license": "CC-BY-SA-4.0", + "version": "1.0.0", + "authors": [ + { + "name": "Karima Rafes", + "email": "karima.ra...@bordercloud.com", + "homepage": "http://www.bordercloud.com/", + "role": "Developer" + } + ], + "require": { + "php": ">=5.3.0" + }, + "repositories": [ { "type": "vcs", @@ -7,7 +25,7 @@ } ], "require-dev": { - "evert/phpdoc-md" : "0.0.*", + "evert/phpdoc-md" : "0.0.*", "phpdocumentor/phpdocumentor": "2.*" } } diff --git a/lib/SPARQL/query b/lib/SPARQL/query index 687cf2e..162a2c6 100755 --- a/lib/SPARQL/query +++ b/lib/SPARQL/query @@ -28,8 +28,12 @@ the request http to write. (by default : update) -f,--file=File File of the query. - -t, --typeOutput=TYPE Type of response: txt,csv,tsv,ttl,srx,srj - (by default : txt) + -t, --typeOutput=TYPE Type of response: table,txt,csv,tsv,ttl,srx,srj + (by default : table) + + -l, --login=LOGIN Server login + -p, --password=PASSWORD Server password + -v, --verbose Mode verbose -d, --debug Mode debug @@ -86,12 +90,14 @@ $endpointUpdateOnly = ""; $nameParameterQuery = "query"; $nameParameterUpdate = "update"; +$endpointLogin = ""; +$endpointPassword = ""; $modeRead = false; $modeWrite = false; $filename= ""; -$typeOutput="txt"; +$typeOutput="table"; $type=""; //Client web @@ -236,18 +242,50 @@ break; case "-t": if(! array_key_exists($i + 1, $argv)){ - echo "ERROR : forget parameter after -f (see --help)\n"; + echo "ERROR : forget parameter after -t (see --help)\n"; exit(); } $typeOutput = $argv[$i + 1]; $i++; + break; case "--typeOutput": if(! array_key_exists(1, $param)){ - echo "ERROR : forget parameter after --endpointQueryOnly (see --help)\n"; + echo "ERROR : forget parameter after --typeOutput (see --help)\n"; exit(); } $typeOutput = $param[1]; - break; + break; + + case "-l": + if(! array_key_exists($i + 1, $argv)){ + echo "ERROR : forget parameter after -l (see --help)\n"; + exit(); + } + $endpointLogin = $argv[$i + 1]; + $i++; + break; + case "--login": + if(! array_key_exists(1, $param)){ + echo "ERROR : forget parameter after --login (see --help)\n"; + exit(); + } + $endpointLogin = $param[1]; + break; + case "-p": + if(! array_key_exists($i + 1, $argv)){ + echo "ERROR : forget parameter after -p (see --help)\n"; + exit(); + } + $endpointPassword = $argv[$i + 1]; + $i++; + break; + case "--password": + if(! array_key_exists(1, $param)){ + echo "ERROR : forget parameter after --password (see --help)\n"; + exit(); + } + $endpointPassword = $param[1]; + break; default: //echo $usage; exit(); echo "ERROR usage ! (".$param[0]."?)"; @@ -278,9 +316,16 @@ $ENDPOINT->setNameParameterQueryWrite($nameParameterUpdate); } +if($endpointLogin != "" && $endpointPassword != ""){ + $ENDPOINT->setLogin($endpointLogin); + $ENDPOINT->setPassword($endpointPassword); +} + + switch($typeOutput){ case "txt": $type = "text/plain"; + break; case "csv": $type = "text/csv; charset=utf-8"; break; @@ -290,6 +335,7 @@ case "ttl": $type = "text/turtle"; break; + case "table": case "srx": $type = "application/sparql-results+xml"; break; @@ -308,6 +354,8 @@ - Mode verbose : ".($modeVerbose?"ON":"OFF")." - Mode debug : ".($modeDebug?"ON":"OFF")." - Type output : ".$type." +- Endpoint login : ".$ENDPOINT->getLogin()." +- Endpoint password : ".$ENDPOINT->getPassword()." "; } @@ -317,45 +365,50 @@ //queryRead /* -$rows = $ENDPOINT->query( file_get_contents($filename), 'rows'); -$err = $ENDPOINT->getErrors(); - if ($err) { - echo "ERROR \n"; - print_r($err,true); - exit(); - } - -foreach($rows["result"]["variables"] as $variable){ - printf("%-20.20s",$variable); - echo '|'; -} -echo "\n"; - -foreach ($rows["result"]["rows"] as $row){ - foreach($rows["result"]["variables"] as $variable){ - printf("%-20.20s",$row[$variable]); - echo '|'; - } - echo "\n"; -} */ -if($modeRead) - $response = $ENDPOINT->queryRead( file_get_contents($filename),$type); -elseif ($modeWrite) - $response = $ENDPOINT->queryUpdate( file_get_contents($filename),$type); -else{ - echo "ERROR : forget parameter after -r or -w (see --help)\n"; - exit(); -} - -$err = $ENDPOINT->getErrors(); - if ($err) { - echo "ERROR \n"; - print_r($err,true); - exit(); - } - echo $response; \ No newline at end of file +if($typeOutput === "table"){ + $rows = $ENDPOINT->query( file_get_contents($filename), 'rows'); + $err = $ENDPOINT->getErrors(); + + if ($err) { + echo "ERROR \n"; + print_r($err,true); + exit(); + } + + foreach($rows["result"]["variables"] as $variable){ + printf("%-20.20s",$variable); + echo '|'; + } + echo "\n"; + + foreach ($rows["result"]["rows"] as $row){ + foreach($rows["result"]["variables"] as $variable){ + printf("%-20.20s",$row[$variable]); + echo '|'; + } + echo "\n"; + } + }else{ + if($modeRead) + $response = $ENDPOINT->queryRead( file_get_contents($filename),$type); + elseif ($modeWrite) + $response = $ENDPOINT->queryUpdate( file_get_contents($filename),$type); + else{ + echo "ERROR : forget parameter after -r or -w (see --help)\n"; + exit(); + } + + $err = $ENDPOINT->getErrors(); + + if ($err) { + echo "ERROR \n"; + print_r($err,true); + exit(); + } + echo $response; + } \ No newline at end of file diff --git a/test/sparqlbasic.feature b/test/sparqlbasic.feature index 406fdfc..4239849 100644 --- a/test/sparqlbasic.feature +++ b/test/sparqlbasic.feature @@ -39,7 +39,7 @@ Scenario: Print a empty table with a query SPARQL Given I am at page that does not exist - And I has a empty graph http://example.com/data in the triplestore http://192.168.1.100:8181 + And I has a empty graph http://example.com/data in the triplestore http://192.168.1.40:8181 When I click link Create source And I enter the wikitext: """ @@ -48,7 +48,7 @@ GRAPH <http://example.com/data> { ?x ?y ?z . } } -|endpoint=http://192.168.1.100:8181/sparql/ +|endpoint=http://192.168.1.40:8181/sparql/ }} """ And I click Save page button @@ -58,8 +58,8 @@ Scenario: Print a table with a query SPARQL Given I am at page that does not exist - And I has a empty graph http://example.com/data in the triplestore http://192.168.1.100:8181 - And I do this SPARQL query in the triplestore http://192.168.1.100:8181: + And I has a empty graph http://example.com/data in the triplestore http://192.168.1.40:8181 + And I do this SPARQL query in the triplestore http://192.168.1.40:8181: """ PREFIX dc: <http://purl.org/dc/elements/1.1/> INSERT DATA @@ -75,18 +75,18 @@ """ {{#sparql: PREFIX dc: <http://purl.org/dc/elements/1.1/> -SELECT ?title ?creator WHERE { +SELECT ?x ?title ?creator WHERE { GRAPH <http://example.com/data> { ?x dc:title ?title ; dc:creator ?creator . } } ORDER BY ?title ?creator -|endpoint=http://192.168.1.100:8181/sparql/ +|endpoint=http://192.168.1.40:8181/sparql/ }} """ And I click Save page button Then newly created page should open And LinkedWiki's table should be there: - | title | creator | - | Book 1 | A.N.Other1 | - | Book 2 | A.N.Other2 | + | x | title | creator | + | http://example/book1 | Book 1 | A.N.Other1 | + | http://example/book2 | Book 2 | A.N.Other2 | \ No newline at end of file diff --git a/test/table2CSV.feature b/test/table2CSV.feature index df87e09..7285c93 100644 --- a/test/table2CSV.feature +++ b/test/table2CSV.feature @@ -2,8 +2,8 @@ Feature: table2CSV Background: Given I am logged in - And I has a empty graph http://example.com/data in the triplestore http://192.168.1.100:8181 - And I do this SPARQL query in the triplestore http://192.168.1.100:8181: + And I has a empty graph http://example.com/data in the triplestore http://192.168.1.40:8181 + And I do this SPARQL query in the triplestore http://192.168.1.40:8181: """ PREFIX dc: <http://purl.org/dc/elements/1.1/> INSERT DATA @@ -29,7 +29,7 @@ dc:creator ?creator . } } ORDER BY ?title ?creator -|endpoint=http://192.168.1.100:8181/sparql/ +|endpoint=http://192.168.1.40:8181/sparql/ }} """ And I click Save page button diff --git a/test/tests.sh b/test/tests.sh index 73ebd3d..4428a2b 100755 --- a/test/tests.sh +++ b/test/tests.sh @@ -1,3 +1,6 @@ +#vagrant config nfs_shares no +#vagrant up + export MEDIAWIKI_URL=http://127.0.0.1:8080/wiki/ cp -R * ~/git/browsertests/features/ -- To view, visit https://gerrit.wikimedia.org/r/178065 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I8d2f198d9a2e0ad436f3d005f925750a1ee422b0 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/LinkedWiki Gerrit-Branch: master Gerrit-Owner: Karima Rafes <karima.ra...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits