⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expr.inc.php

📁 PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。
💻 PHP
📖 第 1 页 / 共 4 页
字号:
        if (in_array($value, array('AND','OR','NOT')))
        {
            $value = strtolower($value);
        }
        $this->value= $value;
        $this->fuzzy = $fuzzy;
        $this->proximity = $proximity;
    }

    public function getValue()
    {

        return $this->value;
    }

    /**
     * Converts the value to a string
     *
     * @return unknown
     */
    public function __toString()
    {
        return (string) "\"$this->value\"";
    }

    public function toViz(&$str, $phase)
    {
        if ($phase == 0)
        {
            $expr_id = $this->getExprId();
            $value = addslashes($this->value);
            $str .= "struct$expr_id [style=ellipse, label=\"$expr_id: \\\"$value\\\"\"]\n";
        }
    }




	public function getSQL($field, $fieldname, $op, $not=false)
    {
    	$val = $this->getValue();
    	if (strpos($val, '*') !== false || strpos($val, '?') !== false)
    	{
			$val = str_replace(array('?','*'), array('_','%'), $val);
    	}

    	switch($op)
    	{
    		case ExprOp::LIKE:
    			break;
    		case ExprOp::CONTAINS:
    			$val = "%$val%";
    			break;
    		case ExprOp::STARTS_WITH:
    			$val = "$val%";
    			break;
    		case ExprOp::ENDS_WITH:
    			$val = "%$val";
    			break;
    	}

    	$val = $field->modifyValue($val);
    	$quote = '';
    	if ($field->isValueQuoted())
    	{
    		$val = addslashes($val);
    		$quote = '\'';
    	}

        switch($op)
        {
            case ExprOp::LIKE:
                $sql = "$fieldname LIKE $quote$val$quote";
                if ($not) $sql = "not ($sql)";
                break;
            case ExprOp::CONTAINS:
                $sql = "$fieldname LIKE $quote$val$quote";
                if ($not) $sql = "not ($sql)";
                break;
            case ExprOp::STARTS_WITH:
                $sql = "$fieldname LIKE $quote$val$quote";
                if ($not) $sql = "not ($sql)";
                break;
            case ExprOp::ENDS_WITH:
                $sql = "$fieldname LIKE $quote$val$quote";
                if ($not) $sql = "not ($sql)";
                break;
            case ExprOp::IS:
            	if ($not)
                	$sql = "$fieldname != $quote$val$quote";
                else
                	$sql = "$fieldname = $quote$val$quote";
                break;
            case ExprOp::GREATER_THAN :
            	if ($not)
                	$sql = "$fieldname <= $quote$val$quote";
                else
                	$sql = "$fieldname > $quote$val$quote";
                break;
            case ExprOp::GREATER_THAN_EQUAL  :
            	if ($not)
                	$sql = "$fieldname < $quote$val$quote";
                else
                	$sql = "$fieldname >= $quote$val$quote";
                break;
            case ExprOp::LESS_THAN  :
            	if ($not)
                	$sql = "$fieldname >= $quote$val$quote";
                else
                	$sql = "$fieldname < $quote$val$quote";
                break;
            case ExprOp::LESS_THAN_EQUAL :
            	if ($not)
	                $sql = "$fieldname > $quote$val$quote";
	            else
                	$sql = "$fieldname <= $quote$val$quote";
                break;
            default:
                throw new Exception(sprintf(_kt('Unknown op: %s'), $op));
        }

        return $sql;
    }

}

class ValueListExpr extends Expr
{
    /**
     * The value
     *
     * @var mixed
     */
    protected $values;

    /**
     * Constructor for the value expression
     *
     * @param mixed $value
     */
    public function __construct($value)
    {
        parent::__construct($value);
        $this->values=array($value);
    }

    public function addValue($value)
    {
    	$this->values[] = $value;
    }


    public function getValue($param=null)
    {
    	if (!empty($param))
    	{
    		return $this->values[$param];
    	}
        $str = '';

        foreach($this->values as $value)
        {
        	if ($str != '') $str .= ',';
        	$str .= "\"$value\"";
        }

        return $str;
    }

    /**
     * Converts the value to a string
     *
     * @return unknown
     */
    public function __toString()
    {
        return $this->getValue();
    }

    public function toViz(&$str, $phase)
    {
        if ($phase == 0)
        {
            $expr_id = $this->getExprId();

            $str .= "struct$expr_id [style=ellipse, label=\"$expr_id: ";
            $i=0;
            foreach($this->values as $value)
            {
            	if ($i++>0) $str .= ',';
            	$value = addslashes($value);
            	$str .= "\\\"$value\\\"";
            }
            $str .= "\"]\n";
        }
    }



    public function rewrite(&$left, &$op, &$right, &$not)
    {
    	if (count($this->values) == 1)
		{
			$right = new ValueExpr($this->values[0]);
			return;
		}
		$newops = array();
		foreach($this->values as $value)
		{
			$classname = get_class($left);
			$class = new $classname;
			$newop = new OpExpr($class, $op, $value);
			$newops[] = $newop;
		}

		$result = $newops[0];
		for($i=1;$i<count($newops);$i++)
		{
			$result = new OpExpr($result, ExprOp::OP_OR, $newops[$i]);
		}

		$left = $result->left();
		$op = $result->op();
		$right = $result->right();
    }

}


class BetweenValueExpr extends ValueExpr
{
    protected $endvalue;

    public function __construct($start, $end)
    {
        parent::__construct($start);
        $this->endvalue = $end;
    }

    public function getStart()
    {
        return $this->getValue();
    }

    public function getEnd()
    {
        return $this->endvalue;
    }

    /**
     * Converts the value to a string
     *
     * @return unknown
     */
    public function __toString()
    {
        return (string) $this->value  . ' AND ' . $this->endvalue;
    }

    public function toViz(&$str, $phase)
    {
        if ($phase == 0)
        {
            $value = addslashes($this->value);
            $value2 = addslashes($this->endvalue);

            $expr_id = $this->getExprId();
            $str .= "struct$expr_id [style=rounded, label=\"$expr_id: $value AND $value2\"]\n";
        }
    }

    public function getSQL($field, $fieldname, $op, $not=false)
    {
        if ($op != ExprOp::BETWEEN)
        {
            throw new Exception(sprintf(_kt('Unexpected operator: %s'), $op));
        }

		$quote = '';

		$start = $field->modifyValue($this->getStart());
		$end = $field->modifyValue($this->getEnd());

		if ($field->isValueQuoted())
    	{
    		$start = addslashes($start);
    		$end = addslashes($end);
    		$quote = '\'';
    	}


        $not = $not?' NOT ':'';
        return "$not ($fieldname $op $quote$start$quote AND $quote$end$quote) ";
    }
}

interface QueryBuilder
{
	function buildComplexQuery($expr);

	function buildSimpleQuery($op, $group);

	function getRanking($result);

	function getResultText($result);

}

class TextQueryBuilder implements QueryBuilder
{
	private $text;
	private $query;

	public function buildComplexQuery($expr)
	{
		$left = $expr->left();
        $right = $expr->right();
		if (DefaultOpCollection::isBoolean($expr))
		{
			$query = '(' . $this->buildComplexQuery($left) . ' ' . $expr->op() . ' ' . $this->buildComplexQuery($right)  . ')';

			if ($expr->not())
			{
				$query = "NOT $query";
			}
		}
		else
		{
			$fieldname = $left->getField();
            $value = addslashes($right->getValue());

            $not = $expr->not()?' NOT ':'';
            if (empty($value))
            {
                // minor hack to prevent the case of 'field:'. results are no 'field:""'
                $value = ' ';
            }

            if (strpos($value, ' ') === false)
            {
            	$query = "$not$fieldname:$value";
            }
            else
            {
            	$query = "$not$fieldname:\"$value\"";
            }
		}

		return $query;
	}

	public function buildSimpleQuery($op, $group)
	{
		$query = '';
		foreach($group as $expr)
		{
			if (!empty($query))
			{
				$query .= " $op ";
			}

			$left = $expr->left();
            $right = $expr->right();

			$fieldname = $left->getField();
            $value = addslashes($right->getValue());

            $not = $expr->not()?' NOT ':'';

            if (strpos($value, ' ') !== false)
				$query .= "$not$fieldname:\"$value\"";
			else
				$query .= "$not$fieldname:$value";
		}

		return $query;
	}

	public function getRanking($result)
	{
		$init = $result->Rank;
		$score=0;
		$ranker = RankManager::get();
		$score += $init *$ranker->scoreField('DocumentText', 'S');
		return $score;
	}

	public function setQuery($query)
	{
		$this->query = $query;
	}

	function getResultText($result)
	{
		// not require!
		return '';
	}
}

class SQLQueryBuilder implements QueryBuilder
{
	private $used_tables;
	private $aliases;
	private $sql;
	private $db;
	private $metadata;
	private $context;

	public function __construct($context)
	{
	    $this->context = $context;

	    switch ($context)
	    {
	        case ExprContext::DOCUMENT:
	            $this->used_tables = array(
	               'documents'=>1,
	               'document_metadata_version'=>1,
	               'document_content_version'=>0,
	               'tag_words'=>0,
	               'document_fields_link'=>0
	            );

	            $this->aliases = array(
	               'documents'=>'d',
	               'document_metadata_version'=>'dmv',
	               'document_content_version'=>'dcv',
	               'tag_words'=>'tw',
	               'document_fields_link'=>'pdfl'
	            );
	            break;
	        case ExprContext::FOLDER:
	            $this->used_tables = array(
	               'folders'=>1,
	            );

	            $this->aliases = array(
	               'folders'=>'f',
	            );
	            break;
	        default:
	            throw new Exception('This was not expected - Context = ' . $context);
	    }

		$this->sql = '';
		$this->db = array();
		$this->metadata = array();
	}

	/**
	 * This looks up a table name to find the appropriate alias.
	 *
	 * @param string $tablename
	 * @return string
	 */
	private function resolveTableToAlias($tablename)
	{
		if (array_key_exists($tablename, $this->aliases))
		{
			return $this->aliases[$tablename];
		}
		throw new Exception("Unknown tablename '$tablename'");
	}

	private function exploreExprs($expr, $parent=null)
	{
		if ($expr->isMetadataField())
		{
			$this->metadata[] = & $parent;
		}
		elseif ($expr->isDBExpr())
		{
		    if (($this->context & $expr->appliesToContext()) == $this->context)
		    {
		        $this->db[]  = & $parent;
		        $tablename = $expr->getTable();
		        if (array_key_exists($tablename, $this->used_tables))
		        {
		            $this->used_tables[$tablename]++;
		        }
		    }
		}
		elseif ($expr->isOpExpr())
		{
			$left = & $expr->left();
			$right = & $expr->right();
			if (DefaultOpCollection::isBoolean($expr))
			{
				$this->exploreExprs($left, $expr);
				$this->exploreExprs($right, $expr);
			}
			else
			{
				// if it is not a boolean, we only need to explore left as it is the one where the main field is defined.
				$this->exploreExprs($left, $expr);
			}
		}
	}

	private function exploreGroup($group)
	{
		// split up metadata and determine table usage
        foreach($group as $expr)
        {
            $field = $expr->left();

            if ($field->isMetadataField())
            {
                $this->metadata[] = $expr->getParent();
            }
            elseif ($field->isDBExpr())
            {
                $this->db[]  = $expr->getParent();
                $tablename = $field->getTable();
                if (array_key_exists($tablename, $this->used_tables))
                {
                    $this->used_tables[$tablename]++;
                }
            }
        }
	}

	private function getFieldnameFromExpr($expr)
	{
		$field = $expr->left();
		if (is_null($field->getJoinTable()))
		{
			$alias      = $this->resolveTableToAlias($field->getTable());
			$fieldname  = $alias . '.' . $field->getField();
		}
		else
		{
			$offset = $this->resolveJoinOffset($expr);
			$matching = $field->getMatchingField();
			$tablename = $field->getJoinTable();
			$fieldname = "$tablename$offset.$matching";
		}

		return $fieldname;
	}

	private function getSQLEvalExpr($expr)
	{
		$left = $expr->left();
		$right = $expr->right();
		$isNot = $expr->not();
		if ($left->isMetadataField() )
		{
		    if ($this->context == ExprContext::DOCUMENT)
		    {
		        $offset = $this->resolveMetadataOffset($expr) + 1;

		        $fieldset = $left->getField();
		        $query = '(';

		        if ($isNot)
		        {
		            $query .= "df$offset.name IS NULL OR ";
		        }

		        $query .= '(' . "df$offset.name='$fieldset' AND " .  $right->getSQL($left, "dfl$offset.value", $expr->op(), $isNot) . ')';

		        $query .= ')';
		    }
		    else
		    {
		        $query = 'false';
		    }
		}
		else
		{
		    if ($this->context == ExprContext::FOLDER && $left->getContext() != ExprContext::FOLDER)
		    {
		        $query = 'false';
		    }
		    else
		    {
			    $fieldname = $this->getFieldnameFromExpr($expr);
			    $query = $right->getSQL($left, $left->modifyName($fieldname), $expr->op(), $isNot);
		    }
		}
		return $query;
	}

	private function buildCoreSQL()
	{
		if (count($this->metadata) + count($this->db) == 0)
        {
            // return empty result set

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -