예제 #1
0
    /**
     * Test deprecation of SQLQuery::getWhere working appropriately
     */
    public function testDeprecatedGetWhere()
    {
        // Temporarily disable deprecation
        Deprecation::notification_version(null);
        $query = new SQLQuery();
        $query->setSelect(array('"SQLQueryTest_DO"."Name"'));
        $query->setFrom('"SQLQueryTest_DO"');
        $query->addWhere(array('"SQLQueryTest_DO"."Date" > ?' => '2012-08-08 12:00'));
        $query->addWhere('"SQLQueryTest_DO"."Name" = \'Richard\'');
        $query->addWhere(array('"SQLQueryTest_DO"."Meta" IN (?, \'Who?\', ?)' => array('Left', 'Right')));
        $expectedSQL = <<<EOS
SELECT "SQLQueryTest_DO"."Name"
 FROM "SQLQueryTest_DO"
 WHERE ("SQLQueryTest_DO"."Date" > ?)
 AND ("SQLQueryTest_DO"."Name" = 'Richard')
 AND ("SQLQueryTest_DO"."Meta" IN (?, 'Who?', ?))
EOS;
        $expectedParameters = array('2012-08-08 12:00', 'Left', 'Right');
        // Check sql evaluation of this query maintains the parameters
        $sql = $query->sql($parameters);
        $this->assertSQLEquals($expectedSQL, $sql);
        $this->assertEquals($expectedParameters, $parameters);
        // Check that ->toAppropriateExpression()->setWhere doesn't modify the query
        $query->setWhere($query->toAppropriateExpression()->getWhere());
        $sql = $query->sql($parameters);
        $this->assertSQLEquals($expectedSQL, $sql);
        $this->assertEquals($expectedParameters, $parameters);
        // Check that getWhere are all flattened queries
        $expectedFlattened = array('"SQLQueryTest_DO"."Date" > \'2012-08-08 12:00\'', '"SQLQueryTest_DO"."Name" = \'Richard\'', '"SQLQueryTest_DO"."Meta" IN (\'Left\', \'Who?\', \'Right\')');
        $this->assertEquals($expectedFlattened, $query->getWhere());
    }
 public function augmentSQL(SQLQuery &$query, DataQuery &$dataQuery = null)
 {
     // Get locale and translation zone to use
     $default = Fluent::default_locale();
     $locale = $dataQuery->getQueryParam('Fluent.Locale') ?: Fluent::current_locale();
     // Get all tables to translate fields for, and their respective field names
     $includedTables = $this->getTranslatedTables();
     // Iterate through each select clause, replacing each with the translated version
     foreach ($query->getSelect() as $alias => $select) {
         // Skip fields without table context
         if (!preg_match('/^"(?<class>\\w+)"\\."(?<field>\\w+)"$/i', $select, $matches)) {
             continue;
         }
         $class = $matches['class'];
         $field = $matches['field'];
         // If this table doesn't have translated fields then skip
         if (empty($includedTables[$class])) {
             continue;
         }
         // If this field shouldn't be translated, skip
         if (!in_array($field, $includedTables[$class])) {
             continue;
         }
         // Select visible field from translated fields (Title_fr_FR || Title => Title)
         $translatedField = Fluent::db_field_for_locale($field, $locale);
         $expression = $this->localiseSelect($class, $translatedField, $field);
         $query->selectField($expression, $alias);
         // At the same time, rewrite the selector for the default field to make sure that
         // (in the case it is blank, which happens if installing fluent for the first time)
         // that it also populated from the root field.
         $defaultField = Fluent::db_field_for_locale($field, $default);
         $defaultExpression = $this->localiseSelect($class, $defaultField, $field);
         $query->selectField($defaultExpression, $defaultField);
     }
     // Rewrite where conditions with parameterised query (3.2 +)
     $where = $query->toAppropriateExpression()->getWhere();
     foreach ($where as $index => $condition) {
         // Extract parameters from condition
         if ($condition instanceof SQLConditionGroup) {
             $parameters = array();
             $predicate = $condition->conditionSQL($parameters);
         } else {
             $parameters = array_values(reset($condition));
             $predicate = key($condition);
         }
         // determine the table/column this condition is against
         $filterColumn = $this->detectFilterColumn($predicate, $includedTables, $locale);
         if (empty($filterColumn)) {
             continue;
         }
         // Duplicate the condition with all localisable fields replaced
         $localisedPredicate = $this->localiseFilterCondition($predicate, $includedTables, $locale);
         if ($localisedPredicate === $predicate) {
             continue;
         }
         // Generate new condition that conditionally executes one of the two conditions
         // depending on field nullability.
         // If the filterColumn is null or empty, then it's considered untranslated, and
         // thus the query should continue running on the default column unimpeded.
         $castColumn = "COALESCE(CAST({$filterColumn} AS CHAR), '')";
         $newPredicate = "\n\t\t\t\t({$castColumn} != '' AND {$castColumn} != '0' AND ({$localisedPredicate}))\n\t\t\t\tOR (\n\t\t\t\t\t({$castColumn} = '' OR {$castColumn} = '0') AND ({$predicate})\n\t\t\t\t)";
         // Duplicate this condition with parameters duplicated
         $where[$index] = array($newPredicate => array_merge($parameters, $parameters));
     }
     $query->setWhere($where);
     // Augment search if applicable
     if ($adapter = Fluent::search_adapter()) {
         $adapter->augmentSearch($query, $dataQuery);
     }
 }
예제 #3
0
 public function conditionSQL(&$parameters)
 {
     $parameters = array();
     // Ignore empty conditions
     $query = $this->whereQuery->toAppropriateExpression();
     $where = $query->getWhere();
     if (empty($where)) {
         return null;
     }
     // Allow database to manage joining of conditions
     $sql = DB::get_conn()->getQueryBuilder()->buildWhereFragment($query, $parameters);
     return preg_replace('/^\\s*WHERE\\s*/i', '', $sql);
 }