<?php
// ##################################################################################
// Title                     : RDQL_db (class_rdql_db.php)
// Version                   : 1.0 
// Author                    : Luis Argerich (lrargerich@yahoo.com)
// Last modification date    : 07-03-2002
// Description               : This class implements the RDQL language
//                             for RDF documents stored in a MySQL database
//                             methds to store and rertieve RDF documents
//                             from a MySQL database are provided as well.
// ##################################################################################
// History: 
// 07-03-2002                : First release of this class
// ##################################################################################
// To-Dos:
// ##################################################################################
// How to use it: First read the README, then check the documentation in
//                class_rdql_db.html and the example in example.php
// ##################################################################################

include_once("class_rdql.php");
include_once("class_rdf_parser.php");

class RDQL_query_db {
  // Queries documents passed as urls or filenames (use urls or filenames in the FROM part of the RDQL query)
  function rdql_query_db($query)              
  {
    $iterator = new RDF_rdqldb_iterator();
    $q = new RDQL_query($iterator);
    $res = $q->parse_query($query);
    // Now process the query result 
    return $res;
  }
} // end of class


// This class provides 
class RDQL_db {
  var $error='';
  var $warning_mode=0;
  var $collection;
  var $key;
  var $statements;

  function get_error() {
    return $this->error; 
  }
  
  // Sets warning mode, if true all the errors produce a PHP warning
  function set_warning_mode($b) {
    $this->warning_mode=$b; 
  }

  function _throw_error($msg) 
  {
    $this->error = $msg; 
    if($this->warning_mode) {
      trigger_error($this->error,E_USER_WARNING); 
    }
    return false;
  }  
  
  function remove_rdf_document($key) {
    $query = "delete from rdf_documents where docKey='$key'";
    mysql_query($query);
    $query = "delete from rdf_data where docKey='$key'";
    mysql_query($query);
    return true; 
  }
  
  function store_rdf_document($url,$key)
  {
    $this->key = $key;
    $this->statements = 0;
    $query = "select count(*) from rdf_documents where docKey='$key'";
    $result = mysql_query($query);
    $res = mysql_fetch_row($result);
    $exist = $res[0];
    if($exist) {
      $this->_throw_error("The collection $collection already has a document with key=$key"); 
      return false;
    }
    $fp = fopen($url,"r");
    if(!$fp) {
      $this->_throw_error("The url or filename $url cannot be opened"); 
      return false;
    }
    $rdf_parser=new Rdf_parser();
    $rdf_parser->rdf_parser_create( NULL );
    $rdf_parser->rdf_set_statement_handler( "_class_rdf_store_statement_handler" );
    $rdf_parser->rdf_set_user_data( $this );
    $size = 0;
    $date = date("U");
    $query = "insert into rdf_documents(date,docKey,type,data)
                     values($date,'$key','rdf','')";
    $result = mysql_query($query);                     
    if(!$result) {
      $this->_throw_error(mysql_error()." in: ".$query);
      return false;
    }
    while(!feof($fp)) {
      $buf = fread($fp,512);
      $size+=strlen($buf);
      $bufd=addslashes($buf);
      if (!$rdf_parser->rdf_parse($buf, strlen($data), feof($fp))) {
        $this->_throw_error("XML error while parsing the document in line:".xml_get_current_line_number($rdf_parser->rdf_get_xml_parser()));
        return false;
      }
      $query = "update rdf_documents set data = concat(data,'$bufd') where docKey='$key'";
      mysql_query($query);
    }
    $query="update rdf_documents set size='$size' where docKey='$key'";
    mysql_query($query);
    $query = "update rdf_documents set statements='$this->statements' where docKey='$key'";
    mysql_query($query);
    $rdf_parser->rdf_parser_free();
    return true;
  }

  function get_rdf_document($key)
  {
    $query = "select data from rdf_documents where docKey='$key'";
    $result = mysql_query($query);
    if(mysql_num_rows($result)==0) {
      $this->_throw_error("No $key document was found in collection $collection"); 
      return false;
    }
    $res = mysql_fetch_array($result);
    return $res["data"];
  }
  
  
} //end of class

/* This function is used by the class as a hander to the RDF_parser */
function _class_rdf_store_statement_handler(&$user_data,$subject_type,$subject,$predicate,$ordinal,$object_type,$object,$xml_lang) {
  //Just store the information in a database row.   
  $key = $user_data->key;
  $collection = $user_data->collection;
  $query="insert into rdf_data(docKey,subject_type,subject,predicate,object_type,object,ordinal) 
          values('$key',$subject_type,'$subject','$predicate',$object_type,'$object',$ordinal)";
  mysql_query($query);        
  $user_data->statements++;
}




class RDF_rdqldb_iterator extends RDF_iterator {
  var $tuples;
  var $collection;
  
  function init($sources) {
    
  }
  
  function set_collection($id) {
    $this->collection=$id; 
  }
  
  function get_tuple() {
    
  }
  
  function find_tuples($sources,$subject,$predicate,$object) {
    $this->tuples=Array();
    
    // If sources is * then select all documents in the collection 
    
    if(count($sources)==1 && ((trim($sources[0])=='*')||(trim($sources[0])=='<*>') )) {
      $sources=Array();
      $query="select docKey from rdf_documents";
      $result=mysql_query($query);
      while($res=mysql_fetch_array($result)) {
        $sources[]='<'.$res["docKey"].'>';
      } 
    }
    // And now we have the sources
    
    foreach($sources as $source) {
      preg_match("/\<([^>]*)\>/",$source,$reqs);
      $source=$reqs[1];
      $query="select subject,predicate,object from rdf_data where docKey='$source'";
      //print($query);die;
      $sql_result=mysql_query($query);
      if(!$sql_result) {
       die(mysql_error()); 
      }
      while($res=mysql_fetch_array($sql_result)) {
        $result=Array();
        if($this->tuple_match($subject,$res["subject"]) &&
           $this->tuple_match($predicate,$res["predicate"]) &&
           $this->tuple_match($object,$res["object"])) {
           $result=Array();
           if($subject{0}=='?') {
             $result[$subject]=$res["subject"]; 
           }
           if($predicate{0}=='?') {
             $result[$predicate]=$res["predicate"]; 
           }    
           if($object{0}=='?') {
             $result[$object]=$res["object"]; 
           }
           if(count($result)>0) {
             $this->tuples[]=$result; 
           }
        }   
      } 
      
    }    
    return $this->tuples;
  }

  function RDF_mysql_iterator() {
    
  } 
  
}


?>