Source for file FilterGenerator.php

Documentation is available at FilterGenerator.php

  1. <?php
  2.  
  3. /**
  4. *   Generates SQL from Sparql FILTER parts
  5. *
  6. *   @author Christian Weiske <cweiske@cweiske.de>
  7. *
  8. *   @package sparql
  9. */
  10. {
  11.     /**
  12.     *   SQL Generator
  13.     *   @var SparqlEngineDb_SqlGenerator 
  14.     */
  15.     protected $sg = null;
  16.  
  17.     /**
  18.     *   If the filter is in an optional statement
  19.     *   @var boolean 
  20.     */
  21.     protected $bOptional    = false;
  22.  
  23.     /**
  24.     *   Number of parameters for the functions supported.
  25.     *   First value is minimum, second is maximum.
  26.     *   @var array 
  27.     */
  28.     protected static $arFuncParamNumbers array(
  29.         'bound'         => array(11),
  30.         'datatype'      => array(11),
  31.         'isblank'       => array(11),
  32.         'isiri'         => array(11),
  33.         'isliteral'     => array(11),
  34.         'isuri'         => array(11),
  35.         'lang'          => array(11),
  36.         'langmatches'   => array(22),
  37.         'regex'         => array(23),
  38.         'sameterm'      => array(22),
  39.         'str'           => array(11),
  40.         'xsd:datetime'  => array(11),
  41.     );
  42.  
  43.     /**
  44.     *   List of operators and their counterpart if operands are switched.
  45.     *   (a > b) => (b < a)
  46.     *   @var array 
  47.     */
  48.     protected static $arOperatorSwitches array(
  49.         '>'     => '<',
  50.         '<'     => '>',
  51.         '>='    => '<=',
  52.         '<='    => '>=',
  53.     );
  54.  
  55.     protected static $arDumbOperators array(
  56.         '&&''||'
  57.     );
  58.  
  59.     protected static $typeXsdBoolean  'http://www.w3.org/2001/XMLSchema#boolean';
  60.     protected static $typeXsdDateTime 'http://www.w3.org/2001/XMLSchema#dateTime';
  61.     protected static $typeXsdDouble   'http://www.w3.org/2001/XMLSchema#double';
  62.     protected static $typeXsdInteger  'http://www.w3.org/2001/XMLSchema#integer';
  63.     protected static $typeXsdString   'http://www.w3.org/2001/XMLSchema#string';
  64.     protected static $typeVariable    'variable';
  65.  
  66.  
  67.  
  68.     public function __construct(SparqlEngineDb_SqlGenerator $sg)
  69.     {
  70.         $this->sg = $sg;
  71.     }//public function __construct(SparqlEngineDb_SqlGenerator $sqlgen)
  72.  
  73.  
  74.  
  75.     /**
  76.     *   Creates the SQL representing a Sparql FILTER.
  77.     *
  78.     *   @param array $tree  Filter element tree as returned by
  79.     *                        SparqlParser::parseConstraintTree()
  80.     *   @param boolean $bOptional   If the filter is in an optional statement
  81.     *   @return string  SQL WHERE part with prefixed AND
  82.     */
  83.     public function createFilterSql($tree$bOptional$nUnionCount)
  84.     {
  85.         if (count($tree== 0{
  86.             //empty filter pattern?
  87.             return '';
  88.         }
  89.  
  90.         $this->bOptional = $bOptional;
  91.         $this->nUnionCount $nUnionCount;
  92.  
  93.         return ' AND ' $this->createTreeSql($treenull);
  94.     }//public function createFilterSql($tree)
  95.  
  96.  
  97.  
  98.     /**
  99.     *
  100.     */
  101.     protected function createTreeSql($tree$parent)
  102.     {
  103.         switch ($tree['type']{
  104.             case 'equation':
  105.                 $sql $this->createEquation($tree);
  106.                 break;
  107.             case 'value':
  108.                 if ($parent != null{
  109.                     $bDumbParent $parent['type'== 'equation'
  110.                         && in_array($parent['operator']self::$arDumbOperators);
  111.                 else {
  112.                     $bDumbParent true;
  113.                 }
  114.                 $sql $this->createValue($tree$bDumbParent);
  115.                 break;
  116.             case 'function':
  117.                 $sql $this->createFunction($tree);
  118.                 break;
  119.             default:
  120.                 var_dump($tree);
  121.                 throw new Exception('Unsupported tree type: ' $tree['type']);
  122.                 break;
  123.         }
  124.  
  125.         if (isset($tree['negated'])) {
  126.             $sql '!(' $sql ')';
  127.         }
  128.  
  129.         return $sql;
  130.     }//protected function createTreeSql($tree, $strParentType)
  131.  
  132.  
  133.  
  134.     /**
  135.     *   Creates the sql for an element of type "value".
  136.     *
  137.     *   @param array $tree  Element
  138.     *   @param boolean $bDumbParent True if the parent is a boolean equation or null.
  139.     */
  140.     protected function createValue($tree$bDumbParent)
  141.     {
  142.         $strValue stripslashes($tree['value']);
  143.         if (SparqlEngineDb_SqlGenerator::isVariable($strValue)) {
  144.             if (!isset($this->sg->arUnionVarAssignments[$this->nUnionCount][$strValue])) {
  145.                 throw new SparqlEngineDb_SqlGeneratorException(
  146.                     'Unknown variable in filter: ' $strValue
  147.                 );
  148.             }
  149.  
  150.             if ($bDumbParent{
  151.                 return $this->createBooleanValue($tree);
  152.             else if ($this->isObject($tree)) {
  153.                 //convert datetime to datetime if necessary
  154.                 return self::mkVal(
  155.                     '(CASE'
  156.                     . ' WHEN ' $this->getIsCol($tree' = "' self::$typeXsdDateTime '"'
  157.                     . ' THEN ' $this->getDateConversionSql($this->getValueCol($tree))
  158.                     . ' ELSE ' $this->getValueCol($tree)
  159.                     . ' END)',
  160.                     self::$typeVariable
  161.                 );
  162.             else {
  163.                 return self::mkVal(
  164.                     $this->getValueCol($tree),
  165.                     self::$typeVariable
  166.                 );
  167.             }
  168.         }
  169.  
  170.         if ($this->isNumber($tree)) {
  171.             return $strValue;
  172.         else if ($tree['quoted'=== false{
  173.             $strValueNew $this->sg->query->getFullUri($strValue);
  174.             if ($strValueNew === false{
  175.                 if ($strValue[0== '<' && substr($strValue-1== '>'{
  176.                     $strValue substr($strValue1-1);
  177.                 else {
  178.                     throw new SparqlEngineDb_SqlGeneratorException(
  179.                         'Unexpected value "' $strValueNew '" (expected datatype)'
  180.                     );
  181.                 }
  182.             else {
  183.                 $strValue $strValueNew;
  184.             }
  185.         else if (isset($tree['datatype'])) {
  186.             switch ($tree['datatype']{
  187.                 case self::$typeXsdBoolean:
  188.                     if (strtolower($strValue== 'false'{
  189.                         //fix: (bool)"false" === true
  190.                         $strValue false;
  191.                     }
  192.                     return self::mkVal(
  193.                         (bool)$strValue 'TRUE' 'FALSE',
  194.                         self::$typeXsdBoolean
  195.                     );
  196.  
  197.                 default:
  198.                     throw new SparqlEngineDb_SqlGeneratorException(
  199.                         'Unsupported datatype "' $tree['datatype']
  200.                     );
  201.             }
  202.         }
  203.  
  204.         return self::mkVal(
  205.             '"' addslashes($strValue'"',
  206.             self::$typeXsdString
  207.         );
  208.     }//protected function createValue($tree)
  209.  
  210.  
  211.  
  212.     protected function createBooleanValue($tree)
  213.     {
  214.         list($strTable$chType$this->sg->arUnionVarAssignments[$this->nUnionCount][$tree['value']];
  215.         if (!$this->isObject($tree)) {
  216.             //Maybe needs a fix
  217.             $strSqlCol SparqlEngineDb_SqlGenerator::$arTableColumnNames[$chType]['value'];
  218.             return self::mkVal(
  219.                 $strTable '.' $strSqlCol ' != ""',
  220.                 self::$typeXsdBoolean
  221.             );
  222.         }
  223.  
  224.         $cType  $strTable '.l_datatype';
  225.         $cValue $strTable '.object';
  226.         $xsd    'http://www.w3.org/2001/XMLSchema';
  227.  
  228.         return self::mkVal(
  229.             '('
  230.             . "(($cType = '' || $cType = '$xsd#string') AND $cValue != '')"
  231.             . " OR ($cType = '$xsd#booleanAND $cValue != 'false')"
  232.             . " OR (($cType = '$xsd#integer' || $cType = '$xsd#double') AND CAST($cValue AS DECIMAL) != 0)"
  233.             //plain check for all unknown datatypes
  234.             . " OR ($cType != '' AND $cType != '$xsd#stringAND $cType != '$xsd#booleanAND $cType != '$xsd#integerAND $cType != '$xsd#doubleAND $cValue != '')"
  235.             . ')',
  236.             self::$typeXsdBoolean
  237.         );
  238.     }//protected function createBooleanValue($tree)
  239.  
  240.  
  241.  
  242.     protected function createFunction($tree)
  243.     {
  244.         $strFuncName strtolower($tree['name']);
  245.         if (!isset(self::$arFuncParamNumbers[$strFuncName])) {
  246.             throw new SparqlEngineDb_SqlGeneratorException(
  247.                 'Unsupported FILTER function: ' $strFuncName
  248.             );
  249.         }
  250.  
  251.         $nParams     count($tree['parameter']);
  252.         if ($nParams self::$arFuncParamNumbers[$strFuncName][0]
  253.          || $nParams self::$arFuncParamNumbers[$strFuncName][1]
  254.         {
  255.             throw new SparqlEngineDb_SqlGeneratorException(
  256.                 'Wrong parameter count for FILTER function: ' $strFuncName
  257.                 . ' (got ' $nParams ', expected '
  258.                 . self::$arFuncParamNumbers[$strFuncName][0]
  259.                 . '-' self::$arFuncParamNumbers[$strFuncName][1]
  260.             );
  261.         }
  262.  
  263.         $strThisFunc 'createFunction_' str_replace(':''_'$strFuncName);
  264.         return $this->$strThisFunc($tree);
  265.     }//protected function createFunction($tree)
  266.  
  267.  
  268.  
  269.     protected function createEquation($tree)
  270.     {
  271.         $strExtra       '';
  272.         $strIsNull      '';
  273.         $strIsNullEnd   '';
  274.  
  275.         if (($this->isNumber($tree['operand1']|| $this->isPlainString($tree['operand1']))
  276.             && $this->isObject($tree['operand2'])
  277.         {
  278.             //switch operands and operator
  279.             $tmp $tree['operand1'];
  280.             $tree['operand1'$tree['operand2'];
  281.             $tree['operand2'$tmp;
  282.             $tree['operator'self::switchOperator($tree['operator']);
  283.         }
  284.  
  285.         $val1 $this->createTreeSql($tree['operand1']$tree);
  286.         $val2 $this->createTreeSql($tree['operand2']$tree);
  287.  
  288.         if ($this->isObject($tree['operand1'])) {
  289.             if ($this->bOptional{
  290.                 $strIsNull    '(';
  291.                 $strIsNullEnd ' OR ' $val1 ' IS NULL)';
  292.             }
  293.             if (isset($tree['operand2']['language'])) {
  294.                 $strColLanguage $this->getLangCol($tree['operand1']);
  295.                 $strExtra .= ' AND ' $strColLanguage ' = "'
  296.                     . addslashes($tree['operand2']['language'])
  297.                     . '"';
  298.             }
  299.  
  300.             if ($this->isNumber($tree['operand2'])) {
  301.                 $strColDatatype $this->getDatatypeCol($tree['operand1']);
  302.                 $strExtra .= ' AND (' $strColDatatype '  = "' self::$typeXsdDouble '"'
  303.                     . ' OR ' $strColDatatype '  = "' self::$typeXsdInteger '"'
  304.                     . ')';
  305.                 return $strIsNull '('
  306.                     . 'CAST(' $val1 ' AS DECIMAL)'
  307.                     . ' ' $tree['operator'' '
  308.                     . $val2
  309.                     . $strExtra
  310.                     . ')' $strIsNullEnd;
  311.             }
  312.         }
  313.  
  314.         //I don't check the operator since it is already checked in the parser
  315.         return $strIsNull '('
  316.             . '('
  317.                 . $val1
  318.                 . ' ' $tree['operator'' '
  319.                 . $val2
  320.                 . $strExtra
  321.             . ')'
  322.             . $this->createTypeEquation(
  323.                 $tree['operator']$val1$val2,
  324.                 $tree['operand1']$tree['operand2']
  325.             )
  326.             . ')' $strIsNullEnd;
  327.     }//protected function createEquation($tree)
  328.  
  329.  
  330.  
  331.     /**
  332.     *   Generates sql code to make sure the datatypes of the two operands match
  333.     */
  334.     protected function createTypeEquation($operator$val1$val2$tree1$tree2)
  335.     {
  336.         if (in_array($operatorarray('&&''||'))) {
  337.             return '';
  338.         }
  339.  
  340.         if ($val1->type != self::$typeVariable && $val2->type != self::$typeVariable{
  341.             //both are not variables -> type needs to be the same
  342.             return $val1->type == $val2->type '' ' AND FALSE';
  343.         }
  344.         $so1 $this->isObjectOrSubject($tree1);
  345.         $so2 $this->isObjectOrSubject($tree2);
  346.         $o1  $this->isObject($tree1);
  347.         $o2  $this->isObject($tree2);
  348.  
  349.         if ($so1 && $so2{
  350.             $sql ' AND ' $this->getIsCol($tree1' = ' $this->getIsCol($tree2);
  351.             if ($o1 && $o2{
  352.                 //maybe needs string fix
  353.                 $sql .= ' AND ' $this->getDatatypeCol($tree1' = '
  354.                     . $this->getDatatypeCol($tree2);
  355.             }
  356.             return $sql;
  357.         }
  358.  
  359.         if ($o1 && $val2->type != self::$typeVariable{
  360.             return $this->createSingleTypeCheck($val2$tree1);
  361.         else if ($o2 && $val1->type != self::$typeVariable{
  362.             return $this->createSingleTypeCheck($val1$tree2);
  363.         }
  364.  
  365.         //fixme
  366.         return '';
  367.     }//protected function createTypeEquation($operator, $val1, $val2, $tree1, $tree2)
  368.  
  369.  
  370.  
  371.     /**
  372.     *   Creates sql to ensure the type between $val and variable $tree
  373.     *   is the same.
  374.     */
  375.     protected function createSingleTypeCheck($val$tree)
  376.     {
  377.         if ($val->type == self::$typeXsdString{
  378.             //string can be empty type or xsd type
  379.             return ' AND ('
  380.                 . $this->getDatatypeCol($tree' = "' $val->type '"'
  381.                 . ' OR '
  382.                 . $this->getDatatypeCol($tree' = ""'
  383.                 . ')';
  384.         }
  385.         return ' AND ' $this->getDatatypeCol($tree' = "' $val->type '"';
  386.     }//protected function createSingleTypeCheck($val, $tree)
  387.  
  388.  
  389.  
  390.     /*
  391.     *   SQL generation functions
  392.     */
  393.  
  394.  
  395.  
  396.     /**
  397.     *   Creates an sql statement that returns if the element is a blank node
  398.     */
  399.     protected function createFunction_bound($tree)
  400.     {
  401.         if ($this->isVariable($tree['parameter'][0])) {
  402.             return self::mkVal(
  403.                 $this->getValueCol($tree['parameter'][0]' IS NOT NULL',
  404.                 self::$typeXsdBoolean
  405.             );
  406.         }
  407.  
  408.         //We'll see which other cases occur here
  409.         return self::mkVal('TRUE'self::$typeXsdBoolean);
  410.     }//protected function createFunction_bound($tree)
  411.  
  412.  
  413.  
  414.     protected function createFunction_datatype($tree)
  415.     {
  416.         if (!$this->isObject($tree['parameter'][0])) {
  417.             throw new SparqlEngineDb_SqlGeneratorException(
  418.                 'datatype\'s first parameter needs to be an object'
  419.             );
  420.         }
  421.  
  422.         return self::mkVal(
  423.             $this->getDatatypeCol($tree['parameter'][0]),
  424.             self::$typeXsdString
  425.         );
  426.     }//protected function createFunction_datatype($tree)
  427.  
  428.  
  429.  
  430.     /**
  431.     *   Creates an sql statement that returns if the element is a blank node
  432.     */
  433.     protected function createFunction_isblank($tree)
  434.     {
  435.         if (!$this->isObjectOrSubject($tree['parameter'][0])) {
  436.             throw new SparqlEngineDb_SqlGeneratorException(
  437.                 'isBlank\'s first parameter needs to be an object or subject'
  438.             );
  439.         }
  440.  
  441.         return self::mkVal(
  442.             $this->getIsCol($tree['parameter'][0]' = "b"',
  443.             self::$typeXsdBoolean
  444.         );
  445.     }//protected function createFunction_isblank($tree)
  446.  
  447.  
  448.  
  449.     protected function createFunction_isiri($tree)
  450.     {
  451.         return $this->createFunction_isuri($tree);
  452.     }//protected function createFunction_isiri($tree)
  453.  
  454.  
  455.  
  456.     /**
  457.     *   Creates an sql statement that returns the language of the object
  458.     */
  459.     protected function createFunction_isliteral($tree)
  460.     {
  461.         if ($this->isObjectOrSubject($tree['parameter'][0])) {
  462.             return $this->getIsCol($tree['parameter'][0]' = "l"';
  463.         }
  464.  
  465.         //This does not take combined functions into account (subfunctions)
  466.         return self::mkVal(
  467.             $this->isPlainString($tree'TRUE' 'FALSE',
  468.             self::$typeXsdBoolean
  469.         );
  470.     }//protected function createFunction_isliteral($tree)
  471.  
  472.  
  473.  
  474.     protected function createFunction_isuri($tree)
  475.     {
  476.         if ($this->isObjectOrSubject($tree['parameter'][0])) {
  477.             return self::mkVal(
  478.                 $this->getIsCol($tree['parameter'][0]' = "r"',
  479.                 self::$typeXsdBoolean
  480.             );
  481.         else {
  482.             //predicates are iris
  483.             return self::mkVal('TRUE'self::$typeXsdBoolean);
  484.         }
  485.     }//protected function createFunction_isuri($tree)
  486.  
  487.  
  488.  
  489.     /**
  490.     *   Creates an sql statement that returns the language of the object
  491.     */
  492.     protected function createFunction_lang($tree)
  493.     {
  494.         if (!$this->isObject($tree['parameter'][0])) {
  495.             throw new SparqlEngineDb_SqlGeneratorException(
  496.                 'lang\'s first parameter needs to be an object'
  497.             );
  498.         }
  499.         return self::mkVal(
  500.             $this->getLangCol($tree['parameter'][0]),
  501.             self::$typeXsdString
  502.         );
  503.     }//protected function createFunction_lang($tree)
  504.  
  505.  
  506.  
  507.     /**
  508.     *   Creates an sql statement that checks if the variable
  509.     *   matches a given language
  510.     */
  511.     protected function createFunction_langmatches($tree)
  512.     {
  513.         //those two restrictions are needed until we have a mysql-only
  514.         // langmatches function
  515.         if ($tree['parameter'][0]['type'!= 'function'
  516.          || $tree['parameter'][0]['name'!= 'lang'
  517.         {
  518.             throw new SparqlEngineDb_SqlGeneratorException(
  519.                 'langMatches\' first parameter needs to be a lang() function'
  520.             );
  521.         }
  522.  
  523.         if (!$this->isPlainString($tree['parameter'][1])) {
  524.             throw new SparqlEngineDb_SqlGeneratorException(
  525.                 'langMatches\' second parameter needs to be a string'
  526.             );
  527.         }
  528.  
  529.         $lang  $tree['parameter'][1]['value'];
  530.         $col   $this->createTreeSql($tree['parameter'][0]$tree);
  531.  
  532.         switch ($lang{
  533.             case '*':
  534.                 //anything but nothing
  535.                 $sql $col ' != ""';
  536.                 break;
  537.             case '':
  538.                 //nothing
  539.                 $sql $col ' = ""';
  540.                 break;
  541.             default:
  542.                 //language, maybe with different subcode
  543.                 // en -> en, en-US
  544.                 $sql '(' $col ' = "' addslashes($lang'" OR '
  545.                     . $col ' LIKE "' addslashes($lang'-%")';
  546.                 break;
  547.         }
  548.  
  549.         return self::mkVal($sqlself::$typeXsdBoolean);
  550.     }//protected function createFunction_isuri($tree)
  551.  
  552.  
  553.  
  554.     /**
  555.     *   Creates an sql statement that checks if the given part matches
  556.     *   an regex
  557.     */
  558.     protected function createFunction_regex($tree)
  559.     {
  560.         $strVar   $this->createTreeSql($tree['parameter'][0]$tree);
  561.         $strRegex $this->createTreeSql($tree['parameter'][1]$tree);
  562.  
  563.         if (isset($tree['parameter'][2])) {
  564.             //is quoted
  565.             $strMod $this->createTreeSql($tree['parameter'][2]$tree);
  566.             switch ($strMod{
  567.                 case '':
  568.                 case '""':
  569.                     $sql $strVar ' REGEXP ' $strRegex;
  570.                     break;
  571.  
  572.                 case '"i"':
  573.                     $sql 'CAST(' $strVar ' AS CHAR) REGEXP ' $strRegex;
  574.                     break;
  575.  
  576.                 default:
  577.                     throw new SparqlEngineDb_SqlGeneratorException(
  578.                         'Unsupported regex modifier "'
  579.                         . $strMod
  580.                         . '"'
  581.                     );
  582.             }
  583.         else {
  584.             $sql $strVar ' REGEXP ' $strRegex;
  585.         }
  586.  
  587.         if ($this->isObject($tree['parameter'][0])) {
  588.             $col $this->getIsCol($tree['parameter'][0]);
  589.             $sql "($sql AND $col = 'l')";
  590.         }
  591.  
  592.         return self::mkVal($sqlself::$typeXsdBoolean);
  593.     }//protected function createFunction_regex($tree)
  594.  
  595.  
  596.  
  597.     /**
  598.     *   Creates an sql statement that checks if both terms are the same
  599.     */
  600.     protected function createFunction_sameterm($tree)
  601.     {
  602.         //FIXME: dead simple implementation that does not cover all cases
  603.         return self::mkVal(
  604.             $this->createTreeSql($tree['parameter'][0]$tree)
  605.                 . ' = '
  606.                 . $this->createTreeSql($tree['parameter'][1]$tree),
  607.             self::$typeXsdBoolean
  608.         );
  609.     }//protected function createFunction_sameterm($tree)
  610.  
  611.  
  612.  
  613.     /**
  614.     *   Creates an sql statement that returns the string representation
  615.     *   of the given element
  616.     */
  617.     protected function createFunction_str($tree)
  618.     {
  619.         if ($this->isObject($tree['parameter'][0])) {
  620.             return self::mkVal(
  621.                 '(CASE ' $this->getIsCol($tree['parameter'][0])
  622.                 . ' WHEN "b" THEN ""'
  623.                 . ' ELSE ' $this->getValueCol($tree['parameter'][0])
  624.                 . ' END)',
  625.                 self::$typeXsdString
  626.             );
  627.         }
  628.  
  629.         return $this->createTreeSql($tree['parameter'][0]$tree);
  630.     }//protected function createFunction_str($tree)
  631.  
  632.  
  633.  
  634.     /**
  635.     *   Creates an sql statement that returns the datetime representation
  636.     *   of the given element
  637.     */
  638.     protected function createFunction_xsd_datetime($tree)
  639.     {
  640.         $val $this->createTreeSql($tree['parameter'][0]$tree);
  641.         if ($val->type == self::$typeXsdDateTime
  642.          || $val->type == self::$typeVariable{
  643.             //no need to cast again
  644.             return $val;
  645.         }
  646.         return self::mkVal(
  647.             $this->getDateConversionSql($val),
  648.             self::$typeXsdDateTime
  649.         );
  650.     }//protected function createFunction_xsd_datetime($tree)
  651.  
  652.  
  653.  
  654.  
  655.     /*
  656.     *   Helper methods
  657.     */
  658.  
  659.  
  660.  
  661.     protected static function mkVal($value$type null{
  662.         return new SparqlEngineDb_FilterGenerator_Value($value$type);
  663.     }
  664.  
  665.  
  666.  
  667.     protected function getCol($tree$type)
  668.     {
  669.         list($strTable$chType$this->sg->arUnionVarAssignments[$this->nUnionCount][$tree['value']];
  670.         if (!isset(SparqlEngineDb_SqlGenerator::$arTableColumnNames[$chType][$type])) {
  671.             return false;
  672.         }
  673.         $strSqlCol SparqlEngineDb_SqlGenerator::$arTableColumnNames[$chType][$type];
  674.         return $strTable '.' $strSqlCol;
  675.     }
  676.  
  677.  
  678.  
  679.     protected function getDatatypeCol($tree)
  680.     {
  681.         list($strTable$chType$this->sg->arUnionVarAssignments[$this->nUnionCount][$tree['value']];
  682.         return $strTable '.l_datatype';
  683.     }
  684.  
  685.  
  686.  
  687.     protected function getDateConversionSql($strValue)
  688.     {
  689.         return 'STR_TO_DATE(' $strValue ', "%Y-%m-%dT%H:%i:%sZ")';
  690.     }//protected function getDateConversionSql($strValue)
  691.  
  692.  
  693.  
  694.     protected function getIsCol($tree)
  695.     {
  696.         return $this->getCol($tree'is');
  697.     }
  698.  
  699.  
  700.  
  701.     protected function getLangCol($tree)
  702.     {
  703.         list($strTable$chType$this->sg->arUnionVarAssignments[$this->nUnionCount][$tree['value']];
  704.         return $strTable '.l_language';
  705.     }
  706.  
  707.  
  708.  
  709.     protected function getValueCol($tree)
  710.     {
  711.         return $this->getCol($tree'value');
  712.     }
  713.  
  714.  
  715.  
  716.     protected function isNumber($tree)
  717.     {
  718.         return $tree['type'== 'value'
  719.          && $tree['quoted'=== false
  720.          && preg_match('#^[0-9.]+$#'$tree['value'])
  721.          && floatval($tree['value']== $tree['value'];
  722.     }//protected function isNumber($tree)
  723.  
  724.  
  725.  
  726.     /**
  727.     *   Checks if the given tree element is a variable
  728.     *   and the variable is actually an object in the database.
  729.     *
  730.     *   @param array $tree  Tree element
  731.     *   @return boolean True if the element is an object
  732.     */
  733.     protected function isObject($tree)
  734.     {
  735.         return $this->isVariable($tree)
  736.          && $this->sg->arUnionVarAssignments[$this->nUnionCount][$tree['value']][1== 'o';
  737.     }//protected function isVariable($tree)
  738.  
  739.  
  740.  
  741.     /**
  742.     *   Checks if the given tree element is a variable
  743.     *   and the variable is actually an object or a subject in the database.
  744.     *
  745.     *   @param array $tree  Tree element
  746.     *   @return boolean True if the element is an object or an subject
  747.     */
  748.     protected function isObjectOrSubject($tree)
  749.     {
  750.         return $this->isVariable($tree)
  751.          && (
  752.             $this->sg->arUnionVarAssignments[$this->nUnionCount][$tree['value']][1== 'o'
  753.          || $this->sg->arUnionVarAssignments[$this->nUnionCount][$tree['value']][1== 's'
  754.         );
  755.     }//protected function isObjectOrSubject($tree)
  756.  
  757.  
  758.  
  759.     /**
  760.     *   Checks if the given tree element is a plain string (no variable)
  761.     *
  762.     *   @param array $tree  Tree element
  763.     *   @return boolean True if the element is a string
  764.     */
  765.     protected function isPlainString($tree)
  766.     {
  767.         return $tree['type'== 'value'
  768.          && $tree['quoted'=== true;
  769.     }//protected function isPlainString($tree)
  770.  
  771.  
  772.  
  773.     protected function isValueButNotVariableNorString($tree)
  774.     {
  775.         return $tree['type'== 'value'
  776.          && $tree['type']['quoted'=== false
  777.          && !SparqlEngineDb_SqlGenerator::isVariable($tree['value']);
  778.     }//protected function isValueButNotVariableNorString($tree)
  779.  
  780.  
  781.  
  782.     /**
  783.     *   Checks if the given tree element is a variable
  784.     *
  785.     *   @param array $tree  Tree element
  786.     *   @return boolean True if the element is a variable
  787.     */
  788.     protected function isVariable($tree)
  789.     {
  790.         return $tree['type'== 'value'
  791.          && $tree['quoted'=== false
  792.          && SparqlEngineDb_SqlGenerator::isVariable($tree['value'])
  793.          && isset($this->sg->arUnionVarAssignments[$this->nUnionCount][$tree['value']]);
  794.     }//protected function isVariable($tree)
  795.  
  796.  
  797.  
  798.     protected static function switchOperator($op)
  799.     {
  800.         if (!isset(self::$arOperatorSwitches[$op])) {
  801.             return $op;
  802.         else {
  803.             return self::$arOperatorSwitches[$op];
  804.         }
  805.     }//protected static function switchOperator($op)
  806.  
  807. }//class SparqlEngineDb_FilterGenerator
  808.  
  809.  
  810.  
  811.  
  812. /**
  813. *   Value class that holds some arbitrary value
  814. *   and a datatype.
  815. *   Objects of this class can transparently be used in strings since
  816. *   its __toString() returns the value.
  817. */
  818. {
  819.     public $value = null;
  820.     public $type  = null;
  821.  
  822.  
  823.  
  824.     public function __construct($value$type null)
  825.     {
  826.         $this->value = $value;
  827.         $this->type  = $type;
  828.     }
  829.  
  830.  
  831.  
  832.     public function __toString()
  833.     {
  834.         return $this->value;
  835.     }
  836.  
  837. }//class SparqlEngineDb_FilterGenerator_Value
  838.  
  839. ?>

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