Source for file SqlGenerator.php

Documentation is available at SqlGenerator.php

  1. <?php
  2. require_once RDFAPI_INCLUDE_DIR 'sparql/SparqlEngineDb/TypeSorter.php';
  3. require_once RDFAPI_INCLUDE_DIR 'sparql/SparqlEngineDb/FilterGenerator.php';
  4. require_once RDFAPI_INCLUDE_DIR 'sparql/SparqlEngineDb/SqlGeneratorException.php';
  5.  
  6. /**
  7. *   Creates sql statements from a Query object
  8. *
  9. *   @author Christian Weiske <cweiske@cweiske.de>
  10. *
  11. *   @package sparql
  12. */
  13. {
  14.     public $query = null;
  15.  
  16.     /**
  17.     *   Determines which variables can be found
  18.     *   in which SQL result column.
  19.     *   @example
  20.     *    array(
  21.     *        '?person' => array('t1', 's'),
  22.     '       '?p'      => array('t1', 'p'),
  23.     *        '?mbox'   => array('t2', 'o')
  24.     *    )
  25.     *    Would express that variable ?person is the subject
  26.     *    in result table t1, and ?mbox is the object in
  27.     *    table t2.
  28.     *
  29.     *   @see $arCreationMethods
  30.     *
  31.     *   @internal The array is created in createSql()
  32.     *    and used in convertFromDbResult().
  33.     *
  34.     *   @var array 
  35.     */
  36.     public $arVarAssignments = array();
  37.  
  38.     /**
  39.     *   Array of variable name => table.col assignments
  40.     *   for all variables used in the query not only
  41.     *   the ones that shall be returned.
  42.     *
  43.     *   @example
  44.     *    array(
  45.     *        '?person'   => 't0.subject'
  46.     *    )
  47.     *
  48.     *   @var array 
  49.     */
  50.     public $arUsedVarAssignments = array();
  51.  
  52.     /**
  53.     *   Array of arrays that contain all variable names
  54.     *   which are to be found in the result of
  55.     *   an sql statement in a union.
  56.     *
  57.     *   @example
  58.     *    array(
  59.     *        0 => array(
  60.     *            '?person' => 's',
  61.     *            '?p' => 'o'
  62.     *        ),
  63.     *        1 => array(
  64.     *            '?person' => 's',
  65.     *            '?mbox' => 'o'
  66.     *        )
  67.     *    )
  68.     *
  69.     *   @var array 
  70.     */
  71.     public $arUnionVarAssignments = array();
  72.  
  73.     /**
  74.     *   Which variables have been used as which type?
  75.     *   key is variable name, value is an array of
  76.     *   max. three keys (s, p, o)
  77.     *
  78.     *   @example
  79.     *    array(
  80.     *        '?person' => array(
  81.     *            's' => true
  82.     *        ),
  83.     *        '?mbox' => array(
  84.     *            'o' => true
  85.     *        )
  86.     *    )
  87.     *
  88.     *   @var array 
  89.     */
  90.     protected $arUsedVarTypes = array();
  91.  
  92.     /**
  93.     *   Array with placeholders of prepared statements variables.
  94.     *   key is the variable name (without "??"), value is the
  95.     *   placeholder.
  96.     *   @var array 
  97.     */
  98.     protected $arPlaceholders = array();
  99.  
  100.     /**
  101.     *   Column names for subjects, predicates and
  102.     *   objects for easy access via their character
  103.     *   names (spo).
  104.     *
  105.     *   @var array 
  106.     */
  107.     public static $arTableColumnNames array(
  108.         's' => array(
  109.             'value' => 'subject',
  110.             'is'    => 'subject_is'
  111.         ),
  112.         'p' => array(
  113.             'value' => 'predicate'
  114.         ),
  115.         'o' => array(
  116.             'value' => 'object',
  117.             'is'    => 'object_is'
  118.         )
  119.     );
  120.  
  121.     /**
  122.     *   Current UNION part number
  123.     *   @var int 
  124.     */
  125.     protected $nUnionCount = 0;
  126.  
  127.     protected $nSqlVariableNameCount = 0;
  128.  
  129.  
  130.  
  131.     public function __construct(Query $queryADOConnection $dbConn$modelID)
  132.     {
  133.         $this->query   = $query;
  134.         $this->dbConn  $dbConn;
  135.         $this->modelID $modelID;
  136.     }//public function __construct(Query $query, ADOConnection $dbConn, $modelID)
  137.  
  138.  
  139.  
  140.     /**
  141.     *   Creates an SQL query string from the given Sparql query object.
  142.     *
  143.     *   @internal uses $query variable
  144.     *
  145.     *   @return array       Array of arrays of SQL query string parts: select, from and where
  146.     *
  147.     *   @throws SparqlEngineDb_SqlGeneratorException   If there is no variable in the result set.
  148.     */
  149.     function createSql()
  150.     {
  151. //var_dump($this->query);
  152.         $arSelect   array();
  153.         $arFrom     array();
  154.         $arWhere    array();
  155.  
  156.         $strResultForm $this->query->getResultForm();
  157.         $filterGen     new SparqlEngineDb_FilterGenerator($this);
  158.         switch ($strResultForm{
  159.             case 'construct':
  160.                 $arResultVars $this->query->getConstructPatternVariables();
  161.                 break;
  162.             default:
  163.                 $arResultVars $this->query->getResultVars();
  164.                 break;
  165.         }
  166.  
  167.         $this->nTableId                 0;
  168.         $this->nGraphPatternCount       0;
  169.         $this->nUnionCount              = 0;
  170.         $this->nUnionTriplePatternCount 0;
  171.         $this->arUnionVarAssignments[0array();
  172.  
  173.         foreach ($this->query->getResultPart(as $graphPattern{
  174.             if (self::isEmptyPattern($graphPattern)) {
  175.                 continue;
  176.             }
  177.             if ($graphPattern->getUnion(!== null{
  178.                 ++$this->nUnionCount;
  179.                 $this->nUnionTriplePatternCount 0;
  180.                 $this->nGraphPatternCount 0;
  181.                 $this->arUnionVarAssignments[$this->nUnionCountarray();
  182.             }
  183.             $this->nTriplePatternCount 0;
  184.             $arTriplePattern $graphPattern->getTriplePattern();
  185.             if ($arTriplePattern != null{
  186.                 foreach ($arTriplePattern as $triplePattern{
  187.                     list (
  188.                         $arSelect[$this->nUnionCount][],
  189.                         $arFrom  [$this->nUnionCount][],
  190.                         $arWhere [$this->nUnionCount][]
  191.                     =
  192.                         $this->getTripleSql(
  193.                             $triplePattern,
  194.                             $graphPattern,
  195.                             $arResultVars
  196.                         );
  197.                     ++$this->nTableId;
  198.                     ++$this->nTriplePatternCount;
  199.                     ++$this->nUnionTriplePatternCount;
  200.                 }
  201.             }
  202.             ++$this->nGraphPatternCount;
  203.  
  204.         }
  205.  
  206.         //constraints extra. needed, since OPTIONAL parts are put after
  207.         // the current pattern while the constraint already refers to variables
  208.         // defined in there
  209.         $this->nGraphPatternCount       0;
  210.         $this->nUnionCount              = 0;
  211.         foreach ($this->query->getResultPart(as $graphPattern{
  212.             if ($graphPattern->getUnion(!== null{
  213.                 ++$this->nUnionCount;
  214.             }
  215.             $arConstraints $graphPattern->getConstraint();
  216.             if ($arConstraints != null{
  217.                 foreach ($arConstraints as $constraint{
  218.                     $arWhere[$this->nUnionCount][count($arWhere[$this->nUnionCount]1]
  219.                      .= $filterGen->createFilterSql(
  220.                         $constraint->getTree(),
  221.                         $graphPattern->getOptional(!== null,
  222.                         $this->nUnionCount
  223.                     );
  224.                 }
  225.             }
  226.             ++$this->nGraphPatternCount;
  227.         }
  228.  
  229.         $arSelect    $this->createEqualSelects($arSelect);
  230.         $arStrSelect array();
  231.  
  232.         switch ($strResultForm{
  233.             case 'construct':
  234.             case 'describe':
  235.                 $strSelectType 'SELECT';
  236.             case 'select':
  237.             case 'select distinct':
  238.                 if (!isset($strSelectType)) {
  239.                     $strSelectType $strResultForm;
  240.                 }
  241.                 foreach ($arSelect as $nUnionCount => $arSelectPart{
  242.                     $arSelectPart self::removeNull($arSelectPart);
  243.                     if (count($arSelectPart== 0{
  244.                         throw new SparqlEngineDb_SqlGeneratorException('No variable that could be returned.');
  245.                     }
  246.                     $arStrSelect[$nUnionCountstrtoupper($strSelectType' ' implode(', '   $arSelectPart);
  247.                 }
  248.                 break;
  249.  
  250.             case 'ask':
  251.             case 'count':
  252.                 $strSelect 'SELECT COUNT(*) as count';
  253.                 break;
  254.  
  255.             default:
  256.                 throw new SparqlEngineDb_SqlGeneratorException('Unsupported query type "' $strResultForm '"');
  257.                 break;
  258.         }
  259.  
  260.         $arSqls array();
  261.         foreach ($arSelect as $nUnionCount => $arSelectPart{
  262.             $arSqls[array(
  263.                 'select'    => $arStrSelect[$nUnionCount],
  264.                 'from'      => ' FROM '  implode(' '    self::removeNull($arFrom[$nUnionCount])),
  265.                 'where'     => ' WHERE ' self::fixWhere(
  266.                             implode(' '  self::removeNull($arWhere[$nUnionCount]))
  267.                 )
  268.             );
  269.         }
  270.         return $arSqls;
  271.     }//function createSql()
  272.  
  273.  
  274.  
  275.     /**
  276.     *   Creates some SQL statements from the given triple pattern
  277.     *   array.
  278.     *
  279.     *   @param QueryTriple  $triple                 Array containing subject, predicate and object
  280.     *   @param GraphPattern $graphPattern           Graph pattern object
  281.     *
  282.     *   @return array   Array consisting of on array and two string values:
  283.     *                    SELECT, FROM and WHERE part
  284.     */
  285.     function getTripleSql(QueryTriple $tripleGraphPattern $graphPattern$arResultVars)
  286.     {
  287.         $arSelect  array();
  288.         $strFrom    null;
  289.         $strWhere   null;
  290.         $strWhereEquality   '';
  291.  
  292.         $subject    $triple->getSubject();
  293.         $predicate  $triple->getPredicate();
  294.         $object     $triple->getObject();
  295.  
  296.         $arRefVars      array();
  297.         $strTablePrefix 't' $this->nTableId;
  298.  
  299.         /**
  300.         *   SELECT part
  301.         *   We do select only the columns we need for variables
  302.         */
  303.         if (self::isVariable($subject)) {
  304.             if (isset($this->arUnionVarAssignments[$this->nUnionCount][$subject])) {
  305.                 //already selected -> add equality check
  306.                 $strWhereEquality .= ' AND ' self::getSqlEqualityCondition(
  307.                                 array($strTablePrefix's'),
  308.                                 $this->arVarAssignments[$subject]
  309.                             );
  310.                 $this->arUsedVarTypes[$subject]['s'true;
  311.             else {
  312.                 if (isset($this->arVarAssignments[$subject][0])) {
  313.                     $strTablePrefix $this->arVarAssignments[$subject][0];
  314.                 }
  315.                 $this->arVarAssignments[$subjectarray($strTablePrefix's');
  316.                 $this->arUnionVarAssignments[$this->nUnionCount][$subjectarray($strTablePrefix's');
  317.                 $this->arUsedVarTypes[$subject]['s'true;
  318.                 if (self::isResultVar($subject$arResultVars)) {
  319.                     //new variable that needs to be selected
  320.                     $arSelect[$subjectarray(
  321.                         $strTablePrefix '.subject as "'    $strTablePrefix '.' $this->getSqlVariableNameValue($subject'"',
  322.                         $strTablePrefix '.subject_is as "' $strTablePrefix '.' $this->getSqlVariableNameIs($subject'"'
  323.                     );
  324.                     if (isset($this->arUsedVarAssignments[$subject])) {
  325.                         $arRefVars[$subject$strTablePrefix '.subject';
  326.                     else {
  327.                         $this->arUsedVarAssignments[$subject$strTablePrefix '.subject';
  328.                     }
  329.                 }
  330.             }
  331.         }
  332.  
  333.         if (self::isVariable($predicate)) {
  334.             if (isset($this->arUnionVarAssignments[$this->nUnionCount][$predicate])) {
  335.                 //already selected -> add equality check
  336.                 $strWhereEquality .= ' AND ' self::getSqlEqualityCondition(
  337.                                 array($strTablePrefix'p'),
  338.                                 $this->arVarAssignments[$predicate]
  339.                             );
  340.                 $this->arUsedVarTypes[$predicate]['p'true;
  341.             else {
  342.                 if (isset($this->arVarAssignments[$predicate][0])) {
  343.                     $strTablePrefix $this->arVarAssignments[$predicate][0];
  344.                 }
  345.                 $this->arVarAssignments[$predicatearray($strTablePrefix'p');
  346.                 $this->arUnionVarAssignments[$this->nUnionCount][$predicatearray($strTablePrefix'p');
  347.                 $this->arUsedVarTypes[$predicate]['p'true;
  348.                 if (self::isResultVar($predicate$arResultVars)) {
  349.                     $arSelect[$predicatearray(
  350.                         $strTablePrefix '.predicate as "' $strTablePrefix '.' $this->getSqlVariableNameValue($predicate'"'
  351.                     );
  352.                     if (isset($this->arUsedVarAssignments[$predicate])) {
  353.                         $arRefVars[$predicate$strTablePrefix '.predicate';
  354.                     else {
  355.                         $this->arUsedVarAssignments[$predicate$strTablePrefix '.predicate';
  356.                     }
  357.                 }
  358.             }
  359.         }
  360.  
  361.         if (self::isVariable($object)) {
  362.             if (isset($this->arUnionVarAssignments[$this->nUnionCount][$object])) {
  363.                 //already selected -> add equality check
  364.                 $strWhereEquality .= ' AND ' self::getSqlEqualityCondition(
  365.                                 array($strTablePrefix'o'),
  366.                                 $this->arVarAssignments[$object]
  367.                             );
  368.                 $this->arUsedVarTypes[$object]['o'true;
  369.             else {
  370.                 if (isset($this->arVarAssignments[$object][0])) {
  371.                     $strTablePrefix $this->arVarAssignments[$object][0];
  372.                 }
  373.                 $this->arVarAssignments[$objectarray($strTablePrefix'o');
  374.                 $this->arUnionVarAssignments[$this->nUnionCount][$objectarray($strTablePrefix'o');
  375.                 $this->arUsedVarTypes[$object]['o'true;
  376.                 if (self::isResultVar($object$arResultVars)) {
  377.                     $arSelect[$objectarray(
  378.                         $strTablePrefix '.object as "'     $strTablePrefix '.' $this->getSqlVariableNameValue($object'"',
  379.                         $strTablePrefix '.object_is as "'  $strTablePrefix '.' $this->getSqlVariableNameIs($object'"',
  380.                         $strTablePrefix '.l_language as "' $strTablePrefix '.' $this->getSqlVariableNameLanguage($object'"',
  381.                         $strTablePrefix '.l_datatype as "' $strTablePrefix '.' $this->getSqlVariableNameDatatype($object'"',
  382.                     );
  383.                     if (isset($this->arUsedVarAssignments[$object])) {
  384.                         $arRefVars[$object$strTablePrefix '.object';
  385.                     else {
  386.                         $this->arUsedVarAssignments[$object$strTablePrefix '.object';
  387.                     }
  388.                 }
  389.                 if (isset($this->query->varLanguages[$object])
  390.                  && $this->query->varLanguages[$object!== null
  391.                 {
  392.                     $strWhereEquality .=
  393.                         ' AND ' $strTablePrefix '.l_language = "'
  394.                         . addslashes($this->query->varLanguages[$object]'"';
  395.                 }
  396.                 if (isset($this->query->varDatatypes[$object])
  397.                  && $this->query->varDatatypes[$object!== null
  398.                 {
  399.                     $strWhereEquality .=
  400.                         ' AND ' $strTablePrefix '.l_datatype = "'
  401.                         . addslashes($this->query->varDatatypes[$object]'"';
  402.                 }
  403.             }
  404.         }
  405.  
  406.         /**
  407.         *   FROM part
  408.         */
  409.         if ($this->nUnionTriplePatternCount == 0{
  410.             //first FROM
  411.             $strFrom    'statements as ' $strTablePrefix;
  412.         else {
  413.             //normal join
  414.             $strFrom    'LEFT JOIN statements as ' $strTablePrefix
  415.                         . ' ON t0.modelID = ' $strTablePrefix '.modelID';
  416.             foreach ($arRefVars as $strRefVar => $strSqlVar{
  417.                 $strFrom .= ' AND ' $this->arUsedVarAssignments[$strRefVar' = ' $strSqlVar;
  418.             }
  419.  
  420.             if ($graphPattern->getOptional(!== null{
  421.                 $strFrom .=  $this->getSqlCondition($subject  $strTablePrefix'subject')
  422.                            . $this->getSqlCondition($predicate$strTablePrefix'predicate')
  423.                            . $this->getSqlCondition($object   $strTablePrefix'object')
  424.                            . $strWhereEquality;
  425.             }
  426.         }
  427.  
  428.  
  429.         /**
  430.         *   WHERE part
  431.         */
  432.         if ($this->nUnionTriplePatternCount == 0{
  433.             $strWhere  $strTablePrefix '.modelID = ' intval($this->modelID);
  434.         }
  435.         if ($graphPattern->getOptional(=== null || $this->nGraphPatternCount == 0{
  436.             $strWhere .=  $this->getSqlCondition($subject  $strTablePrefix'subject')
  437.                         . $this->getSqlCondition($predicate$strTablePrefix'predicate')
  438.                         . $this->getSqlCondition($object   $strTablePrefix'object')
  439.                         . $strWhereEquality;
  440.         }
  441.  
  442.         return array($arSelect$strFrom$strWhere);
  443.     }//function getTripleSql(QueryTriple $triple)
  444.  
  445.  
  446.  
  447.     /**
  448.     *   Creates SELECT statements that have the same number of columns.
  449.     *   Needed for UNIONs.
  450.     *
  451.     *   @param array $arSelect  Array of arrays.
  452.     *        array(
  453.     *            //for each union part one
  454.     *            0 => array(
  455.     *                //foreach triple pattern
  456.     *                0 => array(
  457.     *                    '?person'   => array(
  458.     *                        't0.subject as "t0.subject"'
  459.     *                    )
  460.     *                )
  461.     *            )
  462.     *        )
  463.     *   @return array Array of SELECT strings
  464.     */
  465.     protected function createEqualSelects($arSelect)
  466.     {
  467.         $arNewSelect array();
  468.         if (count($arSelect== 1{
  469.             foreach ($arSelect[0as $arTripleVars{
  470.                 $ar array();
  471.                 foreach ($arTripleVars as $arVarParts{
  472.                     $ar[implode(', '$arVarParts);
  473.                 }
  474.                 if (count($ar0{
  475.                     $arNewSelect[0][implode(', '$ar);
  476.                 }
  477.             }
  478.             return $arNewSelect;
  479.         }
  480.  
  481.         $arVars array();
  482.          foreach ($arSelect as $arUnionVars{
  483.             foreach ($arUnionVars as $arTripleVars{
  484.                 $arVars array_merge($arVarsarray_keys($arTripleVars));
  485.             }
  486.         }
  487.         $arVars array_unique($arVars);
  488.  
  489.         foreach ($arSelect as $nUnionCount => $arUnionVars{
  490.             $arSelectVars array();
  491.             foreach ($arUnionVars as $arTripleVars{
  492.                 foreach ($arTripleVars as $strVar => $arVarParts{
  493.                     $arSelectVars[$strVar$arVarParts;
  494.                 }
  495.             }
  496.  
  497.             $ars array();
  498.             foreach ($arVars as $strVar{
  499.                 if (isset($arSelectVars[$strVar])) {
  500.                     $ar     $arSelectVars[$strVar];
  501.                     $nCount count($arSelectVars[$strVar]);
  502.                 else {
  503.                     $ar     array();
  504.                     $nCount 0;
  505.                 }
  506.  
  507.                 if ($nCount == 0{
  508.                     //nothing of this variable in this union part
  509.                     $ar['NULL as '
  510.                         . '"' $this->arVarAssignments[$strVar][0'.' $this->arVarAssignments[$strVar]['sql_value''"';
  511.                 }
  512.                 if ((
  513.                     isset($this->arUsedVarTypes[$strVar]['o'])
  514.                     || isset($this->arUsedVarTypes[$strVar]['s'])
  515.                     && $nCount 2
  516.                 {
  517.                     //it's a subject or object, but we don't want the type
  518.                     $ar['NULL as '
  519.                         . '"' $this->arVarAssignments[$strVar][0'.' $this->arVarAssignments[$strVar]['sql_is''"';
  520.                 }
  521.                 if (isset($this->arUsedVarTypes[$strVar]['o']&& $nCount 4{
  522.                     //it's a subject or object, but we don't want the type
  523.                     if (isset($this->arVarAssignments[$strVar]['sql_lang'])) {
  524.                         $strColLanguage $this->arVarAssignments[$strVar]['sql_lang'];
  525.                     else {
  526.                         $strColLanguage 'dummyLang';
  527.                     }
  528.                     if (isset($this->arVarAssignments[$strVar]['sql_type'])) {
  529.                         $strColDatatype $this->arVarAssignments[$strVar]['sql_type'];
  530.                     else {
  531.                         $strColDatatype 'dummyType';
  532.                     }
  533.                     $ar['NULL as '
  534.                         . '"' $this->arVarAssignments[$strVar][0'.' $strColLanguage '"';
  535.                     $ar['NULL as '
  536.                         . '"' $this->arVarAssignments[$strVar][0'.' $strColDatatype '"';
  537.                 }
  538.                 $ars[implode(', '$ar);
  539.             }
  540.             $arNewSelect[$nUnionCount$ars;
  541.         }
  542.  
  543.         return $arNewSelect;
  544.     }//protected function createEqualSelects($arSelect)
  545.  
  546.  
  547.  
  548.     /**
  549.     *   Creates an SQL statement that checks for the value
  550.     *   of some subject/predicate/object
  551.     *
  552.     *   @param mixed    $bject          subject|predicate|object
  553.     *   @param string   $strTablePrefix Table prefix (e.g. "t0")
  554.     *   @param string   $strType        Type of $bject ('subject'|'predicate'|'object')
  555.     *   @return string  Part of the SQL query (prefixed with AND)
  556.     */
  557.     function getSqlCondition($bject$strTablePrefix$strType)
  558.     {
  559.         if (is_string($bject)) {
  560.             if (self::isVariable($bject)) {
  561.                 //variable?
  562.                 if (self::isPreparedVariable($bject)) {
  563.                     //no, not really
  564.                     $value $this->getPreparedVariablePlaceholder($bject);
  565.                 else {
  566.                     //yes
  567.                     return null;
  568.                 }
  569.             else {
  570.                 $value $this->dbConn->qstr($bject);
  571.             }
  572.             //literal
  573.             return ' AND ' $strTablePrefix '.' $strType ' = ' $value;
  574.         }
  575.  
  576.         if ($bject instanceof BlankNode{
  577.             //Blank node
  578.             throw new SparqlEngineDb_SqlGeneratorException(
  579.                 'FIXME: Querying for blank nodes not supported'
  580.             );
  581.  
  582.         else if ($bject instanceof Resource{
  583.             //Resource
  584.             $r ' AND ' $strTablePrefix '.' $strType ' = '
  585.                 . $this->dbConn->qstr($bject->getURI());
  586.             if ($strType !== 'predicate'{
  587.                 $r .= ' AND ' $strTablePrefix '.' $strType '_is ='
  588.                 . ' "r"';
  589.             }
  590.             return $r;
  591.  
  592.         else if ($bject instanceof Literal{
  593.             //Literal
  594.             //I'm doubling Filter code here, but what the hell
  595.             $strColDatatype $strTablePrefix '.l_datatype';
  596.             if ($bject->dtype == 'http://www.w3.org/2001/XMLSchema#integer'
  597.              || $bject->dtype == 'http://www.w3.org/2001/XMLSchema#double'
  598.             {
  599.                 $strVariable 'CAST(' $strTablePrefix '.' $strType ' AS DECIMAL)';
  600.                 $strValue    $bject->getLabel();
  601.             else {
  602.                 $strVariable $strTablePrefix '.' $strType;
  603.                 $strValue    $this->dbConn->qstr($bject->getLabel());
  604.             }
  605.             $r ' AND ' $strVariable ' = ' $strValue;
  606.             if ($strType !== 'predicate'{
  607.                 $r .= ' AND ' $strTablePrefix '.' $strType '_is ='
  608.                 . ' "l"';
  609.             }
  610.  
  611.             if ($strType == 'object'{
  612.                 if ($bject->dtype == '' || $bject->dtype == 'http://www.w3.org/2001/XMLSchema#string'{
  613.                     //string
  614.                     $r .= ' AND ('
  615.                         . $strColDatatype ' = ""'
  616.                         . ' OR ' $strColDatatype ' = "http://www.w3.org/2001/XMLSchema#string"'
  617.                         . ')';
  618.                 else {
  619.                     $r .= ' AND ' $strColDatatype ' = "'
  620.                         . $bject->dtype
  621.                         . '"';
  622.                 }
  623.             }
  624.  
  625.             if ($bject->lang != ''{
  626.                 $strColLanguage $strTablePrefix '.l_language';
  627.                 $r .= ' AND ' $strColLanguage ' = '
  628.                    . $this->dbConn->qstr($bject->lang);
  629.             }
  630.             return $r;
  631.  
  632.         else {
  633.             throw new SparqlEngineDb_SqlGeneratorException(
  634.                 'Unsupported sentence part: ' get_class($bject)
  635.             );
  636.         }
  637.     }//function getSqlCondition($bject, $strTablePrefix, $strType)
  638.  
  639.  
  640.  
  641.     /**
  642.     *   Checks if the sentence part (subject, predicate or object) in
  643.     *   $arNew has the same content as $arOld.
  644.     *   Required for queries like ":x ?a ?a" where predicate and object
  645.     *   need to have the same value
  646.     *
  647.     *   @param array    $arNew  array($strTablePrefix, $strType = s|p|o)
  648.     *   @param array    $arOld  array($strTablePrefix, $strType = s|p|o)
  649.     *   @return string 
  650.     */
  651.     protected static function getSqlEqualityCondition($arNew$arOld)
  652.     {
  653.         $chTypeNew         $arNew[1]$chTypeOld         $arOld[1];
  654.         $strTablePrefixNew $arNew[0]$strTablePrefixOld $arOld[0];
  655.  
  656.         if ($chTypeNew == 'p' || $chTypeOld == 'p'{
  657.             //just check value
  658.             //FIXME: it might be I need to check for resource type in object and subject
  659.             return
  660.                   $strTablePrefixNew '.' self::$arTableColumnNames[$chTypeNew]['value']
  661.                 . ' = '
  662.                 . $strTablePrefixOld '.' self::$arTableColumnNames[$chTypeOld]['value']
  663.                 ;
  664.         else if ($chTypeNew == 's' || $chTypeOld == 's'{
  665.             //check value and type
  666.             return
  667.                   $strTablePrefixNew '.' self::$arTableColumnNames[$chTypeNew]['value']
  668.                 . ' = '
  669.                 . $strTablePrefixOld '.' self::$arTableColumnNames[$chTypeOld]['value']
  670.                 . ' AND '
  671.                 . $strTablePrefixNew '.' self::$arTableColumnNames[$chTypeNew]['is']
  672.                 . ' = '
  673.                 . $strTablePrefixOld '.' self::$arTableColumnNames[$chTypeOld]['is']
  674.                 ;
  675.         else {
  676.             //two objects -> check everything
  677.             return
  678.                   $strTablePrefixNew '.object = '     $strTablePrefixOld '.object'
  679.                 . ' AND '
  680.                 . $strTablePrefixNew '.object_is = '  $strTablePrefixOld '.object_is'
  681.                 . ' AND '
  682.                 . $strTablePrefixNew '.l_language = ' $strTablePrefixOld '.l_language'
  683.                 . ' AND '
  684.                 . $strTablePrefixNew '.l_datatype = ' $strTablePrefixOld '.l_datatype'
  685.                 ;
  686.         }
  687.     }//protected static function getSqlEqualityCondition($arNew, $arOld)
  688.  
  689.  
  690.  
  691.     /**
  692.     *   Checks if the given variable name is part of the result
  693.     *   variables list.
  694.     *   Needed since $arResultVars may contain "*" that captures all variables.
  695.     *
  696.     *   @param string   $strVar         Variable name (e.g. "?p")
  697.     *   @param array    $arResultVars   Array with result variables
  698.     *   @return boolean     true if it is a result variable
  699.     */
  700.     protected static function isResultVar($strVar&$arResultVars)
  701.     {
  702.         return in_array('*'$arResultVars|| in_array($strVar$arResultVars);
  703.     }//protected static function isResultVar($strVar, &$arResultVars)
  704.  
  705.  
  706.  
  707.     /**
  708.     *   Checks if the given subject/predicate/object
  709.     *   is a variable name.
  710.     *
  711.     *   @return boolean 
  712.     */
  713.     public static function isVariable($bject)
  714.     {
  715.         return is_string($bject&& strlen($bject>= 2
  716.              && ($bject[0== '?' || $bject[0== '$');
  717.     }//public static function isVariable($bject)
  718.  
  719.  
  720.  
  721.     /**
  722.     *   Checks if the given variable is a replacement
  723.     *   for a prepared statement.
  724.     *
  725.     *   @return boolean 
  726.     */
  727.     public static function isPreparedVariable($bject)
  728.     {
  729.         return is_string($bject&& strlen($bject>= 3
  730.              && ($bject[0== '?' || $bject[0== '$')
  731.              && ($bject[1== '?' || $bject[1== '$')
  732.         ;
  733.     }//public static function isPreparedVariable($bject)
  734.  
  735.  
  736.  
  737.     /**
  738.     *   Returns a placeholder to be included in the sql statement.
  739.     *   It will be replaced with a real prepared statement variable later on.
  740.     *   Also adds it to the internal placeholder array.
  741.     *
  742.     *   @param string $strVariable  The variable to get a placeholder for
  743.     *   @return string placeholder
  744.     */
  745.     protected function getPreparedVariablePlaceholder($strVariable)
  746.     {
  747.         $strName substr($strVariable2);
  748.         if (!isset($this->arPlaceholders[$strName])) {
  749.             $this->arPlaceholders[$strName'@$%_PLACEHOLDER_'
  750.                 . count($this->arPlaceholders'_%$@';
  751.         }
  752.         return $this->arPlaceholders[$strName];
  753.     }//protected function getPreparedVariablePlaceholder($strVariable)
  754.  
  755.  
  756.  
  757.     public function getPlaceholders()
  758.     {
  759.         return $this->arPlaceholders;
  760.     }//public function getPlaceholders()
  761.  
  762.  
  763.  
  764.     public function getVarAssignments()
  765.     {
  766.         return $this->arVarAssignments;
  767.     }//public function getVarAssignments()
  768.  
  769.  
  770.  
  771.     public function getUsedVarAssignments()
  772.     {
  773.         return $this->arUsedVarAssignments;
  774.     }//public function getUsedVarAssignments()
  775.  
  776.  
  777.  
  778.     public function getUsedVarTypes()
  779.     {
  780.         return $this->arUsedVarTypes;
  781.     }//public function getUsedVarTypes()
  782.  
  783.  
  784.  
  785.     /**
  786.     *   Checks if the graph pattern is empty (contains no
  787.     *   usable data).
  788.     *   Occurs when using "{}" without pre- or suffixes
  789.     *   WHERE
  790.     *   {
  791.     *    { ?person rdf:type foaf:Person } .
  792.     *   }
  793.     *
  794.     *   @param GraphPattern $graphPattern    Graph pattern to check
  795.     *   @return boolean     True if the pattern is empty.
  796.     */
  797.     protected static function isEmptyPattern(GraphPattern $graphPattern)
  798.     {
  799.         return
  800.                $graphPattern->getTriplePattern(=== false
  801.             && $graphPattern->getGraphname()     === null
  802.             && $graphPattern->getConstraint()    === false
  803.             && $graphPattern->getOptional()      === null
  804.             && $graphPattern->getUnion()         === null
  805.         ;
  806.     }//protected static function isEmptyPattern(GraphPattern $graphPattern)
  807.  
  808.  
  809.  
  810.     /**
  811.     *   Removes all NULL values from an array and returns it.
  812.     *
  813.     *   @param array $array     Some array
  814.     *   @return array $array without the NULL values.
  815.     */
  816.     protected static function removeNull($array)
  817.     {
  818.         foreach ($array as $key => &$value{
  819.             if ($value === null{
  820.                 unset($array[$key]);
  821.             }
  822.         }
  823.         return $array;
  824.     }//protected static function removeNull($array)
  825.  
  826.  
  827.  
  828.     /**
  829.     *   Removes a leading AND from the where clause which would render
  830.     *   the sql illegal.
  831.     */
  832.     protected function fixWhere($strWhere)
  833.     {
  834.         $strWhere ltrim($strWhere);
  835.         if (substr($strWhere04== 'AND '{
  836.             $strWhere substr($strWhere4);
  837.         }
  838.         return $strWhere;
  839.     }//protected function fixWhere($strWhere)
  840.  
  841.  
  842.  
  843.     protected function getSqlVariableName($strSparqlVar)
  844.     {
  845.         if (!isset($this->arVarAssignments[$strSparqlVar]['sqlname'])) {
  846.             if (preg_match('/[a-zA-Z0-9]+/'substr($strSparqlVar1))) {
  847.                 $strName 'v_' substr($strSparqlVar1);
  848.             else {
  849.                 $strName 'va_' $this->nSqlVariableNameCount++;
  850.             }
  851.             $this->arVarAssignments[$strSparqlVar]['sqlname'$strName;
  852.         }
  853.         return $this->arVarAssignments[$strSparqlVar]['sqlname'];
  854.     }//protected function getSqlVariableName($strSparqlVar)
  855.  
  856.  
  857.  
  858.     protected function getSqlVariableNameValue($strSparqlVar)
  859.     {
  860.         $this->arVarAssignments[$strSparqlVar]['sql_value'=
  861.             'value_' $this->getSqlVariableName($strSparqlVar);
  862.         return $this->arVarAssignments[$strSparqlVar]['sql_value'];
  863.     }//protected function getSqlVariableNameValue($strSparqlVar)
  864.  
  865.  
  866.  
  867.     protected function getSqlVariableNameIs($strSparqlVar)
  868.     {
  869.         $this->arVarAssignments[$strSparqlVar]['sql_is'=
  870.             'is_' $this->getSqlVariableName($strSparqlVar);
  871.         return $this->arVarAssignments[$strSparqlVar]['sql_is'];
  872.     }//protected function getSqlVariableNameIs($strSparqlVar)
  873.  
  874.  
  875.  
  876.     protected function getSqlVariableNameLanguage($strSparqlVar)
  877.     {
  878.         $this->arVarAssignments[$strSparqlVar]['sql_lang'=
  879.             'lang_' $this->getSqlVariableName($strSparqlVar);
  880.         return $this->arVarAssignments[$strSparqlVar]['sql_lang'];
  881.     }//protected function getSqlVariableNameLanguage($strSparqlVar)
  882.  
  883.  
  884.  
  885.     protected function getSqlVariableNameDatatype($strSparqlVar)
  886.     {
  887.         $this->arVarAssignments[$strSparqlVar]['sql_type'=
  888.             'type_' $this->getSqlVariableName($strSparqlVar);
  889.         return $this->arVarAssignments[$strSparqlVar]['sql_type'];
  890.     }//protected function getSqlVariableNameDatatype($strSparqlVar)
  891.  
  892. }//class SparqlEngineDb_SqlGenerator
  893. ?>

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