Source for file DbModel.php

Documentation is available at DbModel.php

  1. <?php
  2. require_once RDFAPI_INCLUDE_DIR 'model/Model.php';
  3.  
  4. // ----------------------------------------------------------------------------------
  5. // Class: DbModel
  6. // ----------------------------------------------------------------------------------
  7.  
  8. /**
  9. * This class provides methods for manipulating DbModels from DbStore.
  10. * A DbModel is an RDF Model, which is persistently stored in a relational database.
  11. * This Class uses the ADOdb Database Abstraction Library for PHP (http://adodb.sourceforge.net/).
  12. *
  13. *
  14. @version  $Id: fsource_model__modelDbModel.php.html 443 2007-06-01 16:25:38Z cax $
  15. @author   Radoslaw Oldakowski <radol@gmx.de>
  16. *
  17. @package model
  18. @access    public
  19. */
  20.  
  21.  
  22. class DbModel extends Model{
  23.  
  24.     /**
  25.     * Database connection object.
  26.     *
  27.     * @var     object ADOConnection 
  28.     * @access    private
  29.     */
  30.     var $dbConn;
  31.  
  32.     /**
  33.     * Unique model URI.
  34.     * Used to identify the DbModel.
  35.     *
  36.     * @var     string 
  37.     * @access    private
  38.     */
  39.     var $modelURI;
  40.  
  41.  
  42.     /**
  43.     * Database internal modelID.
  44.     * Used to avoid JOINs.
  45.     *
  46.     * @var     string 
  47.     * @access    private
  48.     */
  49.     var $modelID;
  50.  
  51.  
  52.  
  53.  
  54.     /**
  55.     * Constructor
  56.     * Do not call this directly.
  57.     * Use the method getModel,getNewModel or putModel of the Class DbStore instead.
  58.     *
  59.     * @param   object ADOConnection  &$dbConnection 
  60.     * @param   string   $modelURI 
  61.     * @param   string   $modelID 
  62.     * @param   string   $baseURI 
  63.     * @access    public
  64.     */
  65.     function DbModel(&$dbConnection$modelURI$modelID$baseURI=NULL{
  66.  
  67.         $this->dbConn =$dbConnection;
  68.         $this->modelURI $modelURI;
  69.         $this->modelID $modelID;
  70.         $this->baseURI $this->_checkBaseURI($baseURI);
  71.     }
  72.  
  73.  
  74.     /**
  75.     * Set a base URI for the DbModel.
  76.     * Affects creating of new resources and serialization syntax.
  77.     *
  78.     * @param    string    $uri 
  79.     * @throws  SqlError
  80.     * @access    public
  81.     */
  82.     function setBaseURI($uri{
  83.  
  84.         $this->baseURI $this->_checkBaseURI($uri);
  85.  
  86.         $rs $this->dbConn->execute("UPDATE models SET baseURI='" .$this->baseURI ."'
  87.                                  WHERE modelID=" .$this->modelID);
  88.         if (!$rs)
  89.         $this->dbConn->errorMsg();
  90.     }
  91.  
  92.  
  93.     /**
  94.     * Return the number of statements in this DbModel.
  95.     *
  96.     * @return    integer 
  97.     * @access    public
  98.     */
  99.     function size({
  100.  
  101.         $count =$this->dbConn->getOne('SELECT COUNT(modelID) FROM statements
  102.                                     WHERE modelID = ' .$this->modelID);
  103.         return $count;
  104.     }
  105.  
  106.  
  107.     /**
  108.     * Check if this DbModel is empty.
  109.     *
  110.     * @return    boolean 
  111.     * @access    public
  112.     */
  113.     function isEmpty({
  114.  
  115.         if ($this->size(== 0)
  116.         return TRUE;
  117.         return FALSE;
  118.     }
  119.  
  120.  
  121.     /**
  122.     * Add a new triple to this DbModel.
  123.     *
  124.     * @param    object Statement    &$statement 
  125.     * @throws    PhpError
  126.     * @throws  SqlError
  127.     * @access    public
  128.     * @return mixed   true on success, false if the statement is already in the model,
  129.     *                  error message (string) on failure
  130.     */
  131.     function add(&$statement{
  132.  
  133.         if (!is_a($statement'Statement')) {
  134.             $errmsg RDFAPI_ERROR '(class: DbModel; method: add): Statement expected.';
  135.             trigger_error($errmsgE_USER_ERROR);
  136.         }
  137.  
  138.         if (!$this->contains($statement)) {
  139.  
  140.             $subject_is $this->_getNodeFlag($statement->subject());
  141.             $sql "INSERT INTO statements
  142.                     (modelID, subject, predicate, object, l_language, l_datatype, subject_is, object_is)
  143.                     VALUES
  144.                     (" .$this->modelID .","
  145.             ."'" .$statement->getLabelSubject(."',"
  146.             ."'" .$statement->getLabelPredicate(."',";
  147.  
  148.             if (is_a($statement->object()'Literal')) {
  149.                 $quotedLiteral $this->dbConn->qstr($statement->obj->getLabel());
  150.                 $sql .=        $quotedLiteral .","
  151.                 ."'" .$statement->obj->getLanguage(."',"
  152.                 ."'" .$statement->obj->getDatatype(."',"
  153.                 ."'" .$subject_is ."',"
  154.                 ."'l')";
  155.             }else{
  156.                 $object_is $this->_getNodeFlag($statement->object());
  157.                 $sql .=   "'" .$statement->obj->getLabel(."',"
  158.                 ."'',"
  159.                 ."'',"
  160.                 ."'" .$subject_is ."',"
  161.                 ."'" .$object_is ."')";
  162.             }
  163.             $rs =$this->dbConn->execute($sql);
  164.             if (!$rs{
  165.                 return $this->dbConn->errorMsg();
  166.             else {
  167.                 return true;
  168.             }
  169.         else {
  170.             return false;
  171.         }
  172.     }
  173.  
  174.  
  175.     /**
  176.     * Alias for the method add().
  177.     *
  178.     * @param    object Statement    &$statement 
  179.     * @throws    PhpError
  180.     * @throws  SqlError
  181.     * @access    public
  182.     */
  183.     function addWithoutDuplicates(&$statement{
  184.  
  185.         $this->add($statement);
  186.     }
  187.  
  188.  
  189.     /**
  190.     * Remove the given triple from this DbModel.
  191.     *
  192.     * @param    object Statement    &$statement 
  193.     * @throws    PhpError
  194.     * @throws  SqlError
  195.     * @access    public
  196.     */
  197.     function remove(&$statement{
  198.  
  199.         if (!is_a($statement'Statement')) {
  200.             $errmsg RDFAPI_ERROR '(class: DbModel; method: remove): Statement expected.';
  201.             trigger_error($errmsgE_USER_ERROR);
  202.         }
  203.  
  204.         $sql 'DELETE FROM statements
  205.            WHERE modelID=' .$this->modelID;
  206.         $sql .= $this->_createDynSqlPart_SPO ($statement->subj$statement->pred$statement->obj);
  207.  
  208.         $rs =$this->dbConn->execute($sql);
  209.         if (!$rs)
  210.         $this->dbConn->errorMsg();
  211.     }
  212.  
  213.  
  214.     /**
  215.     * Short dump of the DbModel.
  216.     *
  217.     * @return    string 
  218.     * @access    public
  219.     */
  220.     function toString({
  221.  
  222.         return 'DbModel[modelURI=' .$this->modelURI .'; baseURI=' .$this->getBaseURI(.';  size=' .$this->size(.']';
  223.     }
  224.  
  225.  
  226.     /**
  227.     * Dump of the DbModel including all triples.
  228.     *
  229.     * @return    string 
  230.     * @access    public
  231.     */
  232.     function toStringIncludingTriples({
  233.  
  234.         $memModel =$this->getMemModel();
  235.         return $memModel->toStringIncludingTriples();
  236.     }
  237.  
  238.  
  239.  
  240.     /**
  241.     * Create a MemModel containing all the triples of the current DbModel.
  242.     *
  243.     * @return object MemModel 
  244.     * @access public
  245.     */
  246.     function getMemModel({
  247.  
  248.         $recordSet $this->_getRecordSet($this);
  249.         return $this->_convertRecordSetToMemModel($recordSet);
  250.     }
  251.  
  252.  
  253.  
  254.     /**
  255.     * Returns the model id
  256.     *
  257.     * @return int Model id number
  258.     * @access public
  259.     */
  260.     function getModelID()
  261.     {
  262.         return $this->modelID;
  263.     }
  264.  
  265.  
  266.  
  267.     /**
  268.     * Returns the database connection object
  269.     *
  270.     * @return ADOdb Database object
  271.     * @access public
  272.     */
  273.     function &getDbConn()
  274.     {
  275.         return $this->dbConn;
  276.     }
  277.  
  278.  
  279.  
  280.     /**
  281.     * Write the RDF serialization of the _DbModel as HTML.
  282.     *
  283.     * @access    public
  284.     */
  285.     function writeAsHtml({
  286.  
  287.         $memModel =$this->getMemModel();
  288.         $memModel->writeAsHtml();
  289.     }
  290.  
  291.  
  292.     /**
  293.     * Write the RDF serialization of the DbModel as HTML table.
  294.     *
  295.     * @access    public
  296.     */
  297.     function writeAsHtmlTable({
  298.         include_once(RDFAPI_INCLUDE_DIR.PACKAGE_UTILITY);
  299.         $memModel =$this->getMemModel();
  300.         RDFUtil::writeHTMLTable($memModel);
  301.     }
  302.  
  303.  
  304.     /**
  305.     * Write the RDF serialization of the DbModel to string.
  306.     *
  307.     * @return    string 
  308.     * @access    public
  309.     */
  310.     function writeRdfToString({
  311.  
  312.         $memModel =$this->getMemModel();
  313.         return $memModel->writeRdfToString();
  314.     }
  315.  
  316.  
  317.     /**
  318.     * Saves the RDF,N3 or N-Triple serialization of the DbModel to a file.
  319.     * You can decide to which format the model should be serialized by using a
  320.     * corresponding suffix-string as $type parameter. If no $type parameter
  321.     * is placed this method will serialize the model to XML/RDF format.
  322.     * Returns FALSE if the DbModel couldn't be saved to the file.
  323.     *
  324.     * @access    public
  325.     * @param     string     $filename 
  326.     * @param     string     $type 
  327.     * @throws   PhpError
  328.     * @return    boolean 
  329.     */
  330.     function saveAs($filename$type ='rdf'{
  331.  
  332.         $memModel $this->getMemModel();
  333.         $memModel->saveAs($filename$type);
  334.  
  335.     }
  336.  
  337.  
  338.     /**
  339.     * Check if the DbModel contains the given statement.
  340.     *
  341.     * @param object Statement  &$statement 
  342.     * @return    boolean 
  343.     * @access    public
  344.     */
  345.     function contains(&$statement{
  346.  
  347.         $sql 'SELECT modelID FROM statements
  348.            WHERE modelID = ' .$this->modelID;
  349.         $sql .= $this->_createDynSqlPart_SPO($statement->subj$statement->pred$statement->obj);
  350.  
  351.         $res =$this->dbConn->getOne($sql);
  352.  
  353.         if (!$res)
  354.         return FALSE;
  355.         return TRUE;
  356.     }
  357.  
  358.  
  359.     /**
  360.     * Determine if all of the statements in the given model are also contained in this DbModel.
  361.     *
  362.     * @param    object Model    &$model 
  363.     * @return    boolean 
  364.     * @access    public
  365.     */
  366.     function containsAll(&$model{
  367.  
  368.         if (is_a($model'MemModel')) {
  369.  
  370.             foreach($model->triples as $statement)
  371.             if(!$this->contains($statement))
  372.             return FALSE;
  373.             return TRUE;
  374.         }
  375.  
  376.         elseif (is_a($model'DbModel')) {
  377.  
  378.             $recordSet =$this->_getRecordSet($model);
  379.             while (!$recordSet->EOF{
  380.                 if (!$this->_containsRow($recordSet->fields))
  381.                 return FALSE;
  382.                 $recordSet->moveNext();
  383.             }
  384.             return TRUE;
  385.         }
  386.  
  387.         $errmsg RDFAPI_ERROR '(class: DbModel; method: containsAll): Model expected.';
  388.         trigger_error($errmsgE_USER_ERROR);
  389.     }
  390.  
  391.  
  392.     /**
  393.     * Determine if any of the statements in the given model are also contained in this DbModel.
  394.     *
  395.     * @param    object Model    &$model 
  396.     * @return    boolean 
  397.     * @access    public
  398.     */
  399.     function containsAny(&$model{
  400.  
  401.         if (is_a($model'MemModel')) {
  402.  
  403.             foreach($model->triples as $statement)
  404.             if($this->contains($statement))
  405.             return TRUE;
  406.             return FALSE;
  407.         }
  408.  
  409.         elseif (is_a($model'DbModel')) {
  410.  
  411.             $recordSet =$this->_getRecordSet($model);
  412.             while (!$recordSet->EOF{
  413.                 if ($this->_containsRow($recordSet->fields))
  414.                 return TRUE;
  415.                 $recordSet->moveNext();
  416.             }
  417.             return FALSE;
  418.         }
  419.  
  420.         $errmsg RDFAPI_ERROR '(class: DbModel; method: containsAny): Model expected.';
  421.         trigger_error($errmsgE_USER_ERROR);
  422.     }
  423.  
  424.  
  425.     /**
  426.     * General method to search for triples in the DbModel.
  427.     * NULL input for any parameter will match anything.
  428.     * Example:  $result = $m->find( NULL, NULL, $node );
  429.     *           Finds all triples with $node as object.
  430.     *
  431.     * @param    object Resource    $subject 
  432.     * @param    object Resource    $predicate 
  433.     * @param    object Node    $object 
  434.     * @return    object MemModel 
  435.     * @throws    PhpError
  436.     * @throws  SqlError
  437.     * @access    public
  438.     */
  439.     function find($subject$predicate$object{
  440.  
  441.         if ((!is_a($subject'Resource'&& $subject != NULL||
  442.         (!is_a($predicate'Resource'&& $predicate != NULL||
  443.         (!is_a($object'Node'&& $object != NULL)) {
  444.  
  445.             $errmsg RDFAPI_ERROR '(class: DbModel; method: find): Parameters must be subclasses of Node or NULL';
  446.             trigger_error($errmsgE_USER_ERROR);
  447.         }
  448.  
  449.         // static part of the sql statement
  450.         $sql 'SELECT subject, predicate, object, l_language, l_datatype, subject_is, object_is
  451.            FROM statements
  452.            WHERE modelID = ' .$this->modelID;
  453.  
  454.         // dynamic part of the sql statement
  455.         $sql .= $this->_createDynSqlPart_SPO($subject$predicate$object);
  456.  
  457.         // execute the query
  458.         $recordSet =$this->dbConn->execute($sql);
  459.  
  460.         if (!$recordSet)
  461.         echo $this->dbConn->errorMsg();
  462.  
  463.         // write the recordSet into memory Model
  464.         else
  465.         return $this->_convertRecordSetToMemModel($recordSet);
  466.     }
  467.  
  468.  
  469.     /**
  470.     * Method to search for triples using Perl-style regular expressions.
  471.     * NULL input for any parameter will match anything.
  472.     * Example:  $result = $m->find_regex( NULL, NULL, $regex );
  473.     *           Finds all triples where the label of the object node matches
  474.     *the regular expression.
  475.     * Return an empty MemModel if nothing is found.
  476.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  477.     * WARNING: Mhis method loads a DbModel into memory and performs the search
  478.     *          on a MemModel, which can be slow with large models.
  479.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  480.     *
  481.     * @param    string    $subject_regex 
  482.     * @param    string    $predicate_regex 
  483.     * @param    string    $object_regex 
  484.     * @return    object MemModel 
  485.     * @throws    PhpError
  486.     * @throws  SqlError
  487.     * @access    public
  488.     */
  489.     function findRegex($subject_regex$predicate_regex$object_regex{
  490.  
  491.         $mm =$this->getMemModel();
  492.  
  493.         return $mm->findRegex($subject_regex$predicate_regex$object_regex);
  494.     }
  495.  
  496.  
  497.     /**
  498.     * Return all tripels of a certain vocabulary.
  499.     * $vocabulary is the namespace of the vocabulary inluding a # : / char at the end.
  500.     * e.g. http://www.w3.org/2000/01/rdf-schema#
  501.     * Return an empty model if nothing is found.
  502.     *
  503.     * @param    string    $vocabulary 
  504.     * @return    object MemModel 
  505.     * @throws    PhpError
  506.     * @throws  SqlError
  507.     * @access    public
  508.     */
  509.     function findVocabulary($vocabulary{
  510.  
  511.         $sql "SELECT subject, predicate, object, l_language, l_datatype, subject_is, object_is
  512.            FROM statements
  513.            WHERE modelID = " .$this->modelID ."
  514.            AND predicate LIKE '" .$vocabulary ."%'";
  515.  
  516.         $recordSet =$this->dbConn->execute($sql);
  517.  
  518.         if (!$recordSet)
  519.         echo $this->dbConn->errorMsg();
  520.  
  521.         // write the recordSet into memory Model
  522.         else
  523.         return $this->_convertRecordSetToMemModel($recordSet);
  524.     }
  525.  
  526.  
  527.     /**
  528.     * Search for triples and return the first matching statement.
  529.     * NULL input for any parameter will match anything.
  530.     * Return an NULL if nothing is found.
  531.     * You can set an search offset with $offset.
  532.     *
  533.     * @param    object Resource    $subject 
  534.     * @param    object Resource    $predicate 
  535.     * @param    object Node    $object 
  536.     * @param    integer    $offset 
  537.     * @return    object Statement 
  538.     * @throws  PhpError
  539.     * @throws  SqlError
  540.     * @access    public
  541.     */
  542.     function findFirstMatchingStatement($subject$predicate$object$offset = -1{
  543.  
  544.         if ((!is_a($subject'Resource'&& $subject != NULL||
  545.         (!is_a($predicate'Resource'&& $predicate != NULL||
  546.         (!is_a($object'Node'&& $object != NULL)) {
  547.  
  548.             $errmsg RDFAPI_ERROR '(class: DbModel; method: find): Parameters must be subclasses of Node or NULL';
  549.             trigger_error($errmsgE_USER_ERROR);
  550.         }
  551.  
  552.         // static part of the sql statement
  553.         $sql 'SELECT subject, predicate, object, l_language, l_datatype, subject_is, object_is
  554.            FROM statements
  555.            WHERE modelID = ' .$this->modelID;
  556.  
  557.         // dynamic part of the sql statement
  558.         $sql .= $this->_createDynSqlPart_SPO($subject$predicate$object);
  559.  
  560.         // execute the query
  561.         $recordSet =$this->dbConn->selectLimit($sql,1,($offset));
  562.  
  563.         if (!$recordSet)
  564.         echo $this->dbConn->errorMsg();
  565.         else {
  566.             if (!$recordSet->fields)
  567.             return NULL;
  568.             else {
  569.                 $memModel $this->_convertRecordSetToMemModel($recordSet);
  570.                 return $memModel->triples[0];
  571.             }
  572.         }
  573.     }
  574.  
  575.  
  576.     /**
  577.     * Search for triples and return the number of matches.
  578.     * NULL input for any parameter will match anything.
  579.     *
  580.     * @param    object Resource    $subject 
  581.     * @param    object Resource    $predicate 
  582.     * @param    object Node      $object 
  583.     * @return    integer 
  584.     * @throws    PhpError
  585.     * @throws  SqlError
  586.     * @access    public
  587.     */
  588.     function findCount($subject$predicate$object{
  589.  
  590.         if ((!is_a($subject'Resource'&& $subject != NULL||
  591.         (!is_a($predicate'Resource'&& $predicate != NULL||
  592.         (!is_a($object'Node'&& $object != NULL)) {
  593.  
  594.             $errmsg RDFAPI_ERROR '(class: DbModel; method: find): Parameters must be subclasses of Node or NULL';
  595.             trigger_error($errmsgE_USER_ERROR);
  596.         }
  597.  
  598.         // static part of the sql statement
  599.         $sql 'SELECT COUNT(*)
  600.            FROM statements
  601.            WHERE modelID = ' .$this->modelID;
  602.  
  603.         // dynamic part of the sql statement
  604.         $sql .= $this->_createDynSqlPart_SPO($subject$predicate$object);
  605.  
  606.         // execute the query
  607.         $recordSet =$this->dbConn->execute($sql);
  608.  
  609.         if (!$recordSet)
  610.         echo $this->dbConn->errorMsg();
  611.         else
  612.         return $recordSet->fields[0];
  613.     }
  614.  
  615.  
  616.     /**
  617.     * Perform an RDQL query on this DbModel.
  618.     * This method returns an associative array of variable bindings.
  619.     * The values of the query variables can either be RAP's objects (instances of Node)
  620.     * if $returnNodes set to TRUE, or their string serialization.
  621.     *
  622.     * @access    public
  623.     * @param string $queryString 
  624.     * @param boolean $returnNodes 
  625.     * @return  array   [][?VARNAME] = object Node  (if $returnNodes = TRUE)
  626.     *       OR  array   [][?VARNAME] = string
  627.     *
  628.     */
  629.     function rdqlQuery($queryString$returnNodes TRUE{
  630.         require_once(RDFAPI_INCLUDE_DIR.PACKAGE_RDQL);
  631.         $parser new RdqlParser();
  632.         $parsedQuery =$parser->parseQuery($queryString);
  633.  
  634.         // this method can only query this DbModel
  635.         // if another model was specified in the from clause throw an error
  636.         if (isset($parsedQuery['sources'][0]))
  637.         if($parsedQuery['sources'][0!= $this->modelURI{
  638.             $errmsg RDFAPI_ERROR '(class: DbModel; method: rdqlQuery):';
  639.             $errmsg .= ' this method can only query this DbModel';
  640.             trigger_error($errmsgE_USER_ERROR);
  641.         }
  642.  
  643.         $engine new RdqlDbEngine();
  644.         $res =$engine->queryModel($this$parsedQuery$returnNodes);
  645.  
  646.         return $res;
  647.     }
  648.  
  649.  
  650.     /**
  651.     * Perform an RDQL query on this DBModel.
  652.     * This method returns an RdqlResultIterator of variable bindings.
  653.     * The values of the query variables can either be RAP's objects (instances of Node)
  654.     * if $returnNodes set to TRUE, or their string serialization.
  655.     *
  656.     * @access    public
  657.     * @param string $queryString 
  658.     * @param boolean $returnNodes 
  659.     * @return  object RdqlResultIterator = with values as object Node  (if $returnNodes = TRUE)
  660.     *       OR  object RdqlResultIterator = with values as strings if (if $returnNodes = FALSE)
  661.     *
  662.     */
  663.     function rdqlQueryAsIterator($queryString$returnNodes TRUE{
  664.         require_once(RDFAPI_INCLUDE_DIR.PACKAGE_RDQL);
  665.         return new RdqlResultIterator($this->rdqlQuery($queryString$returnNodes));
  666.     }
  667.  
  668.     /**
  669.     * General method to replace nodes of a DbModel.
  670.     * NULL input for any parameter will match nothing.
  671.     * Example:  $m->replace($resource, NULL, $node, $replacement);
  672.     *           Replaces all $node objects beeing subject or object in
  673.     *           any triple of the model with the $replacement node.
  674.     * Throw an error in case of a paramter mismatch.
  675.     *
  676.     * @param    object Resource    $subject 
  677.     * @param    object Resource    $predicate 
  678.     * @param    object Node    $object 
  679.     * @param    object Node    $replacement 
  680.     * @throws    PhpError
  681.     * @throws  SqlError
  682.     * @access    public
  683.     */
  684.     function replace($subject$predicate$object$replacement{
  685.  
  686.         // check the correctness of the passed parameters
  687.         if ( ((!is_a($subject'Resource'&& $subject != NULL||
  688.         (!is_a($predicate'Resource'&& $predicate != NULL||
  689.         (!is_a($object'Node'&& $object != NULL)) ||
  690.         (($subject != NULL && is_a($replacement'Literal')) ||
  691.         ($predicate != NULL && (is_a($replacement'Literal'||
  692.         is_a($replacement'BlankNode')))) )
  693.         {
  694.             $errmsg RDFAPI_ERROR '(class: DbModel; method: find): Parameter mismatch';
  695.             trigger_error($errmsgE_USER_ERROR);
  696.         }
  697.  
  698.         if (!(!$subject && !$predicate && !$object)) {
  699.  
  700.             // create an update sql statement
  701.             $comma '';
  702.             $sql 'UPDATE statements
  703.              SET ';
  704.             if ($subject{
  705.                 $sql .= " subject ='" .$replacement->getLabel(."', "
  706.                 ." subject_is='" .$this->_getNodeFlag($replacement."' ";
  707.                 $comma ',';
  708.             }
  709.             if ($predicate{
  710.                 $sql .= $comma ." predicate='" .$replacement->getLabel(."' ";
  711.                 $comma ',';
  712.             }
  713.             if ($object{
  714.                 $quotedObject $this->dbConn->qstr($replacement->getLabel());
  715.                 $sql .= $comma .' object=' .$quotedObject
  716.                 .", object_is='" .$this->_getNodeFlag($replacement."' ";
  717.                 if (is_a($replacement'Literal')) {
  718.                     $sql .= ", l_language='" .$replacement->getLanguage(."' "
  719.                     .", l_datatype='" .$replacement->getDataType(."' ";
  720.                 }
  721.             }
  722.             $sql .= 'WHERE modelID = ' .$this->modelID;
  723.             $sql .= $this->_createDynSqlPart_SPO($subject$predicate$object);
  724.  
  725.             // execute the query
  726.             $rs =$this->dbConn->execute($sql);
  727.  
  728.             if (!$rs)
  729.             echo $this->dbConn->errorMsg();
  730.         }
  731.     }
  732.  
  733.  
  734.     /**
  735.     * Check if two models are equal.
  736.     * Two models are equal if and only if the two RDF graphs they represent are isomorphic.
  737.     *
  738.     * Warning: This method doesn't work correct with models where the same blank node has different
  739.     * identifiers in the two models. We will correct this in a future version.
  740.     *
  741.     * @param    object    model &$that 
  742.     * @return    boolean 
  743.     * @throws  PhpError
  744.     * @access    public
  745.     */
  746.  
  747.     function equals(&$that)  {
  748.  
  749.         if (!is_a($that'Model')) {
  750.             $errmsg RDFAPI_ERROR '(class: DbModel; method: equals): Model expected.';
  751.             trigger_error($errmsgE_USER_ERROR);
  752.         }
  753.  
  754.         if ($this->size(!= $that->size())
  755.         return FALSE;
  756.  
  757.         include_once(RDFAPI_INCLUDE_DIR"util/ModelComparator.php");
  758.         return ModelComparator::compare($this,$that);
  759.     }
  760.  
  761.  
  762.     /**
  763.     * Return a new MemModel that is the set-union the model with another model.
  764.     *
  765.     * The result of taking the set-union of two or more RDF graphs (i.e. sets of triples)
  766.     * is another graph, which we will call the merge of the graphs.
  767.     * Each of the original graphs is a subgraph of the merged graph. Notice that when forming
  768.     * a merged graph, two occurrences of a given uriref or literal as nodes in two different
  769.     * graphs become a single node in the union graph (since by definition they are the same
  770.     * uriref or literal) but blank nodes are not 'merged' in this way; and arcs are of course
  771.     * never merged. In particular, this means that every blank node in a merged graph can be
  772.     * identified as coming from one particular graph in the original set of graphs.
  773.     *
  774.     * Notice that one does not, in general, obtain the merge of a set of graphs by concatenating
  775.     * their corresponding N-triples documents and constructing the graph described by the merged
  776.     * document, since if some of the documents use the same node identifiers, the merged document
  777.     * will describe a graph in which some of the blank nodes have been 'accidentally' merged.
  778.     * To merge Ntriples documents it is necessary to check if the same nodeID is used in two or
  779.     * more documents, and to replace it with a distinct nodeID in each of them, before merging the
  780.     * documents. (Not implemented yet !!!!!!!!!!!)
  781.     *
  782.     * @param    object Model    $model 
  783.     * @return    object MemModel 
  784.     * @throws PhpError
  785.     * @access    public
  786.     *
  787.     */
  788.     function unite(&$model)  {
  789.  
  790.         if (!is_a($model'Model')) {
  791.             $errmsg RDFAPI_ERROR '(class: DbModel; method: unite): Model expected.';
  792.             trigger_error($errmsgE_USER_ERROR);
  793.         }
  794.  
  795.         if (is_a($model'MemModel')) {
  796.  
  797.             $thisModel =$this->getMemModel();
  798.             return $thisModel->unite($model);
  799.         }
  800.  
  801.         elseif (is_a($model'DbModel')) {
  802.  
  803.             $thisModel =$this->getMemModel();
  804.             $thatModel =$model->getMemModel();
  805.             return $thisModel->unite($thatModel);
  806.         }
  807.     }
  808.  
  809.  
  810.     /**
  811.     * Return a new MemModel that is the subtraction of another model from this DbModel.
  812.     *
  813.     * @param    object Model    $model 
  814.     * @return    object MemModel 
  815.     * @throws PhpError
  816.     * @access    public
  817.     */
  818.  
  819.     function subtract(&$model)  {
  820.  
  821.         if (!is_a($model'Model')) {
  822.             $errmsg RDFAPI_ERROR '(class: DbModel; method: subtract): Model expected.';
  823.             trigger_error($errmsgE_USER_ERROR);
  824.         }
  825.  
  826.         if (is_a($model'MemModel')) {
  827.  
  828.             $thisModel =$this->getMemModel();
  829.             return $thisModel->subtract($model);
  830.         }
  831.  
  832.         elseif (is_a($model'DbModel')) {
  833.  
  834.             $thisModel =$this->getMemModel();
  835.             $thatModel =$model->getMemModel();
  836.             return $thisModel->subtract($thatModel);
  837.         }
  838.     }
  839.  
  840.  
  841.     /**
  842.     * Return a new MemModel containing all the statements which are in both
  843.     * this model and the given model.
  844.     *
  845.     * @param    object Model    $model 
  846.     * @return    object MemModel 
  847.     * @throws  PhpError
  848.     * @access    public
  849.     */
  850.     function intersect(&$model)  {
  851.  
  852.         if (is_a($model'MemModel')) {
  853.  
  854.             $thisModel =$this->getMemModel();
  855.             return $thisModel->intersect($model);
  856.         }
  857.  
  858.         elseif (is_a($model'DbModel')) {
  859.  
  860.             $thisModel =$this->getMemModel();
  861.             $thatModel =$model->getMemModel();
  862.             return $thisModel->intersect($thatModel);
  863.         }
  864.  
  865.         $errmsg RDFAPI_ERROR '(class: DbModel; method: intersect: Model expected.';
  866.         trigger_error($errmsgE_USER_ERROR);
  867.     }
  868.  
  869.  
  870.     /**
  871.     * Add the given model to this DbModel.
  872.     * This function monitors for SQL errors, and will commit if no errors have occured,
  873.     * otherwise it will rollback.
  874.     * If any statement of the model to be added to this model contains a blankNode
  875.     * with an identifier already existing in this model, a new blankNode is generated.
  876.     *
  877.     * @param    object Model    $model 
  878.     * @throws  PhpError
  879.     * @access    public
  880.     */
  881.     function addModel(&$model)  {
  882.  
  883.         if (!is_a($model'Model')) {
  884.             $errmsg RDFAPI_ERROR '(class: DbModel; method: addModel): Model expected.';
  885.             trigger_error($errmsgE_USER_ERROR);
  886.         }
  887.  
  888.         $blankNodes_tmp array();
  889.  
  890.         if (is_a($model'MemModel')) {
  891.  
  892.             $this->dbConn->startTrans();
  893.             foreach ($model->triples as $statement)
  894.             $this->_addStatementFromAnotherModel($statement$blankNodes_tmp);
  895.             $this->addParsedNamespaces($model->getParsedNamespaces());
  896.  
  897.             $this->dbConn->completeTrans();
  898.         }
  899.  
  900.         elseif (is_a($model'DbModel')) {
  901.  
  902.             $this->dbConn->startTrans();
  903.             $memModel =$model->getMemModel();
  904.             foreach($memModel->triples as $statement)
  905.             $this->_addStatementFromAnotherModel($statement$blankNodes_tmp);
  906.             $this->addParsedNamespaces($model->getParsedNamespaces());
  907.             $this->dbConn->completeTrans();
  908.         }
  909.     }
  910.  
  911.  
  912.     /**
  913.     * Reify the DbModel.
  914.     * Return a new MemModel that contains the reifications of all statements of this DbModel.
  915.     *
  916.     * @return    object    MemModel 
  917.     * @access    public
  918.     */
  919.     function reify({
  920.  
  921.         $memModel =$this->getMemModel();
  922.         return $memModel->reify();
  923.     }
  924.  
  925.     /**
  926.     * Remove this DbModel from database and clean up.
  927.     * This function monitors for SQL errors, and will commit if no errors have occured,
  928.     * otherwise it will rollback.
  929.     *
  930.     * @throws  SqlError
  931.     * @access    public
  932.     */
  933.     function delete({
  934.  
  935.         $this->dbConn->startTrans();
  936.         $this->dbConn->execute('DELETE FROM models
  937.                                   WHERE modelID=' .$this->modelID);
  938.         $this->dbConn->execute('DELETE FROM statements
  939.                                   WHERE modelID=' .$this->modelID);
  940.  
  941.         if (!$this->dbConn->completeTrans())
  942.         echo $this->dbConn->errorMsg();
  943.         else
  944.         $this->close();
  945.     }
  946.  
  947.  
  948.     /**
  949.     * Close this DbModel
  950.     *
  951.     * @access    public
  952.     */
  953.     function close({
  954.  
  955.         unset($this);
  956.     }
  957.  
  958.  
  959.     // =============================================================================
  960.     // **************************** private methods ********************************
  961.     // =============================================================================
  962.  
  963.  
  964.  
  965.  
  966.  
  967.     /**
  968.     * If the URI doesn't end with # : or /, then a # is added to the URI.
  969.     * Used at setting the baseURI of this DbModel.
  970.     *
  971.     * @param   string  $uri 
  972.     * @return  string 
  973.     * @access    private
  974.     */
  975.     function _checkBaseURI($uri)  {
  976.  
  977.         if ($uri != NULL{
  978.             $c substr($uristrlen($uri)-,1);
  979.             if (!($c=='#' || $c==':' || $c=='/' || $c=="\\"))
  980.             $uri .= '#';
  981.         }
  982.         return $uri;
  983.     }
  984.  
  985.  
  986.     /**'
  987.     * Return the flag of the Node object.
  988.     * r - Resource, b - BlankNode, l - Literal
  989.     *
  990.     * @param   object Node $object
  991.     * @return  string
  992.     * @access    private
  993.     */
  994.     function _getNodeFlag($object)  {
  995.  
  996.         return is_a($object,'BlankNode')?'b':(is_a($object,'Resource')?'r':'l');
  997.     }
  998.  
  999.  
  1000.     /**
  1001.     * Convert an ADORecordSet to a memory Model.
  1002.     *
  1003.     * Every successful database query returns an ADORecordSet object which is actually
  1004.     * a cursor that holds the current row in the array fields[].
  1005.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1006.     * !!! This method can only be applied to a RecordSet with array fields[]
  1007.     * !!! containing a representation of the database table: statements,
  1008.     * !!! with an index corresponding to following table columns:
  1009.     * !!! [0] - subject, [1] - predicate, [2] - object, [3] - l_language,
  1010.     * !!! [4] - l_datatype, [5] - subject_is, [6] - object_is
  1011.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  1012.     *
  1013.     * @param   object  ADORecordSet 
  1014.     * @return  object  MemModel 
  1015.     * @access    private
  1016.     */
  1017.     function _convertRecordSetToMemModel(&$recordSet)  {
  1018.  
  1019.         $res new MemModel($this->baseURI);
  1020.         while (!$recordSet->EOF{
  1021.  
  1022.             // subject
  1023.             if ($recordSet->fields[5== 'r')
  1024.             $sub new Resource($recordSet->fields[0]);
  1025.             else
  1026.             $sub new BlankNode($recordSet->fields[0]);
  1027.  
  1028.             // predicate
  1029.             $pred new Resource($recordSet->fields[1]);
  1030.  
  1031.             // object
  1032.             if ($recordSet->fields[6== 'r')
  1033.             $obj new Resource($recordSet->fields[2]);
  1034.             elseif ($recordSet->fields[6== 'b')
  1035.             $obj new BlankNode($recordSet->fields[2]);
  1036.             else {
  1037.                 $obj new Literal($recordSet->fields[2]$recordSet->fields[3]);
  1038.                 if ($recordSet->fields[4])
  1039.                 $obj->setDatatype($recordSet->fields[4]);
  1040.             }
  1041.  
  1042.             $statement new Statement($sub$pred$obj);
  1043.             $res->add($statement);
  1044.  
  1045.             $recordSet->moveNext();
  1046.         }
  1047.         $res->addParsedNamespaces($this->getParsedNamespaces());
  1048.         return $res;
  1049.     }
  1050.  
  1051.  
  1052.     /**
  1053.     * Create the dynamic part of an sql statement selecting triples with the
  1054.     * given parameters ($subject, $predicate, $object).
  1055.     *
  1056.     * @param    object Resource    $subject 
  1057.     * @param    object Resource    $predicate 
  1058.     * @param    object Node    $object 
  1059.     * @return  string 
  1060.     * @access    private
  1061.     */
  1062.     function _createDynSqlPart_SPO($subject$predicate$object{
  1063.  
  1064.         // conditions derived from the parameters passed to the function
  1065.  
  1066.         $subject_is=is_a($subject,'BlankNode')?'b':(is_a($subject,'Resource')?'r':'l');
  1067.         $sql='';
  1068.         if ($subject != NULL)
  1069.         $sql .= " AND subject='" .$subject->getLabel(."'
  1070.                 AND subject_is='" .$subject_is ."'";
  1071.         if ($predicate != NULL)
  1072.         $sql .= " AND predicate='" .$predicate->getLabel(."'";
  1073.         if ($object != NULL{
  1074.             $object_is is_a($object,'BlankNode')?'b':(is_a($object,'Resource')?'r':'l');
  1075.             if (is_a($object'Resource'))
  1076.             $sql .= " AND object='" .$object->getLabel(."'
  1077.                    AND object_is ='" .$object_is ."'";
  1078.             else  {
  1079.                 $quotedLiteral $this->dbConn->qstr($object->getLabel());
  1080.                 $sql .= " AND object=" .$quotedLiteral ."
  1081.                    AND l_language='" .$object->getLanguage(."'
  1082.                    AND l_datatype='" .$object->getDataType(."'
  1083.                    AND object_is ='" .$object_is ."'";
  1084.             }
  1085.         }
  1086.         return $sql;
  1087.     }
  1088.  
  1089.  
  1090.     /**
  1091.     * Get an ADORecordSet with array fields[] containing a representation of
  1092.     * the given DbModel stored in the table: statements, with an index corresponding
  1093.     * to following table columns:
  1094.     * [0] - subject, [1] - predicate, [2] - object, [3] - l_language,
  1095.     * [4] - l_datatype, [5] - subject_is, [6] - object_is
  1096.     * (This method operates on data from a DbModel without loading it into a memory model
  1097.     *  in order to save resources and improve speed).
  1098.     *
  1099.     * @param    object DbModel    $DbModel 
  1100.     * @return  object ADORecordSet 
  1101.     * @access    private
  1102.     */
  1103.     function _getRecordSet (&$dbModel{
  1104.  
  1105.         $sql 'SELECT subject, predicate, object, l_language, l_datatype, subject_is, object_is
  1106.            FROM statements
  1107.            WHERE modelID = ' .$dbModel->modelID;
  1108.  
  1109.         return $recordSet =$this->dbConn->execute($sql);
  1110.     }
  1111.  
  1112.  
  1113.     /**
  1114.     * Check if this DbModel contains the given row from the array fields[] of an ADORecordSet
  1115.     * The array index corresponds to following table columns:
  1116.     * [0] - subject, [1] - predicate, [2] - object, [3] - l_language,
  1117.     * [4] - l_datatype, [5] - subject_is, [6] - object_is
  1118.     *
  1119.     * @param   array  $row 
  1120.     * @return  boolean 
  1121.     * @access    private
  1122.     */
  1123.     function _containsRow ($row{
  1124.  
  1125.         $quotedObject $this->dbConn->qstr($row[2]);
  1126.         $sql "SELECT modelID FROM statements
  1127.            WHERE modelID = " .$this->modelID ."
  1128.            AND subject ='" .$row[0."'
  1129.            AND predicate ='" .$row[1."'
  1130.            AND object =" .$quotedObject ."
  1131.            AND l_language='" .$row[3."'
  1132.            AND l_datatype='" .$row[4."'
  1133.            AND subject_is='" .$row[5."'
  1134.            AND object_is='" .$row[6."'";
  1135.  
  1136.         $res =$this->dbConn->getOne($sql);
  1137.  
  1138.         if (!$res)
  1139.         return FALSE;
  1140.         return TRUE;
  1141.     }
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.     /**
  1148.     * Returns the models namespaces.
  1149.     *
  1150.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1151.     * @access   public
  1152.     * @return   Array 
  1153.     */
  1154.     function getParsedNamespaces(){
  1155.         $sql "SELECT * FROM namespaces
  1156.            WHERE modelID = " .$this->modelID;
  1157.         $temp=false;
  1158.         $res $this->dbConn->execute($sql);
  1159.         if($res){
  1160.             while (!$res->EOF{
  1161.                 $temp[$res->fields[1]]=$res->fields[2];
  1162.                 $res->moveNext();
  1163.             }
  1164.         }
  1165.         return $temp;
  1166.     }
  1167.  
  1168.  
  1169.  
  1170.     /**
  1171.     * Adds the namespaces to the model. This method is called by
  1172.     * the parser. !!!! addParsedNamespaces() not overwrites manual
  1173.     * added namespaces in the model !!!!
  1174.     *
  1175.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1176.     * @access   public
  1177.     * @param    Array $newNs 
  1178.     */
  1179.     function addParsedNamespaces($newNs){
  1180.         if($newNs)
  1181.         foreach($newNs as $namespace => $prefix){
  1182.             $this->addNamespace($prefix$namespace);
  1183.         }
  1184.     }
  1185.  
  1186.  
  1187.     /**
  1188.     * Adds a namespace and prefix to the model.
  1189.     *
  1190.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1191.     * @access   public
  1192.     * @param    String $prefix, String $nmsp
  1193.     */
  1194.     function addNamespace($prefix,$nmsp){
  1195.  
  1196.         if($nmsp != '' && $prefix !=''){
  1197.             if($this->_checkNamespace($nmsp)){
  1198.                 $sql "UPDATE namespaces SET prefix='".$prefix."' WHERE
  1199.                 modelID=".$this->modelID." AND namespace='".$nmsp."'";
  1200.             }else{
  1201.                 $sql "INSERT INTO namespaces
  1202.                     (modelID, namespace, prefix)
  1203.                     VALUES
  1204.                     (" .$this->modelID .","
  1205.                 ."'" .$nmsp ."',"
  1206.                 ."'" .$prefix."')";
  1207.             }
  1208.  
  1209.             $rs =$this->dbConn->execute($sql);
  1210.             if (!$rs)
  1211.             $this->dbConn->errorMsg();
  1212.         }
  1213.     }
  1214.  
  1215.     /**
  1216.     * checks if a namespace is already in the model.
  1217.     *
  1218.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1219.     * @access   private
  1220.     * @param    Array $newNs 
  1221.     */
  1222.     function _checkNamespace($nmsp){
  1223.         $res true;
  1224.         $sql "SELECT * FROM namespaces
  1225.                WHERE modelID = " .$this->modelID." AND
  1226.             namespace='".$nmsp."'" ;
  1227.         $rs =$this->dbConn->execute($sql);
  1228.         if (!$rs){
  1229.             $this->dbConn->errorMsg();
  1230.         }else{
  1231.             if($rs->fields == false)
  1232.             $res false;
  1233.         }
  1234.         return $res;
  1235.  
  1236.  
  1237.     }
  1238.  
  1239.     /**
  1240.     * Returns a FindIterator for traversing the MemModel.
  1241.     * @access    public
  1242.     * @return    object    FindIterator 
  1243.     */
  1244.     function iterFind($sub=null,$pred=null,$obj=null{
  1245.         // Import Package Utility
  1246.         include_once(RDFAPI_INCLUDE_DIR.PACKAGE_UTILITY);
  1247.  
  1248.         $if new IterFind($this,$sub,$pred,$obj);
  1249.         return $if;
  1250.     }
  1251.  
  1252.     /**
  1253.     * removes a single namespace from the model
  1254.     *
  1255.     * @author   Tobias Gau�<tobias.gauss@web.de>
  1256.     * @access   public
  1257.     * @param    String $nmsp 
  1258.     */
  1259.     function removeNamespace($nmsp){
  1260.  
  1261.         $sql 'DELETE FROM namespaces
  1262.            WHERE modelID=' .$this->modelID." AND namespace='".$nmsp."'";
  1263.  
  1264.         $rs =$this->dbConn->execute($sql);
  1265.         if (!$rs)
  1266.         $this->dbConn->errorMsg();
  1267.     }
  1268.  
  1269.  
  1270.  
  1271.  
  1272.     /**
  1273.     * Add the given row from the array fields[] of an ADORecordSet to this DbModel
  1274.     * The array index corresponds to following table columns:
  1275.     * [0] - subject, [1] - predicate, [2] - object, [3] - l_language,
  1276.     * [4] - l_datatype, [5] - subject_is, [6] - object_is
  1277.     *
  1278.     * @param   array  $row 
  1279.     * @throws  SqlError
  1280.     * @access    private
  1281.     *
  1282.     function _insertRow ($row) {
  1283.  
  1284.     $quotedObject = $this->dbConn->qstr($row[2]);
  1285.     $sql = "INSERT INTO statements VALUES
  1286.     (" .$this->modelID .","
  1287.     ."'" .$row[0] ."',"
  1288.     ."'" .$row[1] ."',"
  1289.     .""  .$quotedObject .","
  1290.     ."'" .$row[3] ."',"
  1291.     ."'" .$row[4] ."',"
  1292.     ."'" .$row[5] ."',"
  1293.     ."'" .$row[6] ."')";
  1294.  
  1295.     $rs =& $this->dbConn->execute($sql);
  1296.     if (!$rs)
  1297.     $this->dbConn->errorMsg();
  1298.     }
  1299.     */
  1300.  
  1301. // end: Class DbModel
  1302. ?>

Documentation generated on Fri, 1 Jun 2007 16:48:48 +0200 by phpDocumentor 1.3.2