Source for file DbModel.php

Documentation is available at DbModel.php

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

Documentation generated on Mon, 26 Jun 2006 14:25:23 +0200 by phpDocumentor 1.3.0RC6