Package org.apache.derby.iapi.types

Source Code of org.apache.derby.iapi.types.WorkHorseForCollatorDatatypes

/*

   Derby - Class org.apache.derby.iapi.types.WorkHorseForCollatorDatatypes
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to you under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/

package org.apache.derby.iapi.types;

import org.apache.derby.iapi.types.DataValueDescriptor;
import org.apache.derby.iapi.types.BooleanDataValue;

import org.apache.derby.iapi.reference.SQLState;

import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.services.sanity.SanityManager;

import java.text.CollationElementIterator;
import java.text.CollationKey;
import java.text.RuleBasedCollator;

/**
* WorkHorseForCollatorDatatypes class holds on to RuleBasedCollator,
* and the base SQLChar object for the collation sensitive SQLChar,
* SQLVarchar, SQLLongvarchar and SQLClob. This class uses RuleBasedCollator
* and SQLChar object in the collation sensitive methods to do the comparison.
* The reason for encapsulating this here is that the collation version of
* SQLChar, SQLVarchar, SQLLongvarchar and SQLClob do not all have to duplicate 
* the code for collation sensitive methods. Instead, they can simply delegate
* the work to methods defined in this class.
*/
final class WorkHorseForCollatorDatatypes 
{
  /**
   * Use this object for collation on character datatype. This collator
   * object is passed as a parameter to the constructor.
   */
  private RuleBasedCollator collatorForCharacterDatatypes;
  /**
   * collatorForCharacterDatatypes will be used on this SQLChar to determine
   * collationElementsForString. The collationElementsForString is used by
   * the like method to do Collator specific comparison.
   * This SQLChar object is passed as a parameter to the constructor.
   */
  private SQLChar stringData;
  /**
   * Following is the array holding a series of collation elements for the
   * string. It will be used in the like method. This gets initialized when
   * the like method is first invoked.
   */
  private int[]  collationElementsForString;
  /**
   * Number of valid collation elements in the array above. Note that this
   * might be smaller than the actual size of the array above. Gets
   * initialized when the like method is first invoked.
   */
  private int    countOfCollationElements;

  // For null strings, cKey = null.
  private CollationKey cKey;

  WorkHorseForCollatorDatatypes(
      RuleBasedCollator collatorForCharacterDatatypes,
      SQLChar stringData)
  {
    this.collatorForCharacterDatatypes = collatorForCharacterDatatypes;
    this.stringData = stringData;
  }
 
  /** @see SQLChar#stringCompare(SQLChar, SQLChar) */
  int stringCompare(SQLChar str1, SQLChar str2)
  throws StandardException
  {
    CollationKey ckey1 = str1.getCollationKey();
    CollationKey ckey2 = str2.getCollationKey();
   
    /*
    ** By convention, nulls sort High, and null == null
    */
    if (ckey1 == null || ckey2 == null)
    {
      if (ckey1 != null// str2 == null
        return -1;
      if (ckey2 != null// this == null
        return 1;
      return 0;      // both == null
    }

    return ckey1.compareTo(ckey2);
  }
 
  /**
   * This method implements the like function for char (with no escape value).
   * The difference in this method and the same method in SQLChar is that
   * here we use special Collator object to do the comparison rather than
   * using the Collator object associated with the default jvm locale.
   *
   * @param pattern    The pattern to use
   *
   * @return  A SQL boolean value telling whether the first operand is
   *      like the second operand
   *
   * @exception StandardException    Thrown on error
   */
  BooleanDataValue like(DataValueDescriptor pattern)
                throws StandardException
  {
    Boolean likeResult;

    if (SanityManager.DEBUG)
      SanityManager.ASSERT(
        pattern instanceof CollationElementsInterface,
        "Both the operands must be instances of CollationElementsInterface");
    CollationElementsInterface patternToCheck = (CollationElementsInterface) pattern;
    likeResult = Like.like(
        getCollationElementsForString(),
        getCountOfCollationElements(),
        patternToCheck.getCollationElementsForString(),
        patternToCheck.getCountOfCollationElements(),
        collatorForCharacterDatatypes);

    return SQLBoolean.truthValue(stringData,
                   pattern,
                   likeResult);
  }
 
  /**
   * This method implements the like function for char with an escape value.
   *
   * @param pattern    The pattern to use
   *
   * @return  A SQL boolean value telling whether the first operand is
   *       like the second operand
   *
   * @exception StandardException    Thrown on error
   */
  BooleanDataValue like(DataValueDescriptor pattern,
      DataValueDescriptor escapethrows StandardException
  {
    Boolean likeResult;

    if (SanityManager.DEBUG)
      SanityManager.ASSERT(
               pattern instanceof CollationElementsInterface &&
               escape instanceof CollationElementsInterface,
      "All three operands must be instances of CollationElementsInterface");
   
    // ANSI states a null escape yields 'unknown' results
    //
    // This method is only called when we have an escape clause, so this
    // test is valid

    if (escape.isNull())
    {
      throw StandardException.newException(SQLState.LANG_ESCAPE_IS_NULL);
    }

    CollationElementsInterface patternToCheck = (CollationElementsInterface) pattern;
    CollationElementsInterface escapeCharacter = (CollationElementsInterface) escape;

    if (escapeCharacter.getCollationElementsForString() != null &&
        (escapeCharacter.getCountOfCollationElements() != 1))
    {
      throw StandardException.newException(SQLState.LANG_INVALID_ESCAPE_CHARACTER,
          new String(escapeCharacter.toString()));
    }
    likeResult = Like.like(
        getCollationElementsForString(),
        getCountOfCollationElements(),
        patternToCheck.getCollationElementsForString(),
        patternToCheck.getCountOfCollationElements(),
        escapeCharacter.getCollationElementsForString(),
        escapeCharacter.getCountOfCollationElements(),
        collatorForCharacterDatatypes);

    return SQLBoolean.truthValue(stringData,
                 pattern,
                 likeResult);
  }

  /**
   * Get the RuleBasedCollator which is getting used for collation sensitive
   * methods.
   */
  RuleBasedCollator getCollatorForCollation()
  {
    return(collatorForCharacterDatatypes);
  }

  /**
   * This method returns the count of collation elements for SQLChar object.
   * It method will return the correct value only if method  
   * getCollationElementsForString has been called previously on the SQLChar
   * object.
   *
   * @return count of collation elements for this instance of CollatorSQLChar
   */
  int getCountOfCollationElements()
  {
    return countOfCollationElements;
  }

  /**
   * This method translates the string into a series of collation elements.
   * These elements will get used in the like method.
   *
   * @return an array of collation elements for the string
   * @throws StandardException
   */
  int[] getCollationElementsForString()
    throws StandardException
  {
    if (stringData.isNull())
    {
      return (int[]) null;
    }



        // Caching of collationElementsForString is not working properly, in
        // order to cache it needs to get invalidated everytime the container
        // type's value is changed - through any interface, eg: readExternal,
        // setValue, ...  To get proper behavior, disabling caching, and will
        // file a performance enhancement to implement correct caching.
        collationElementsForString = null;
        countOfCollationElements   = 0;


    if (collationElementsForString != null)
    {
      return collationElementsForString;
    }

    // countOfCollationElements should always be 0 when
        // collationElementsForString is null
    if (SanityManager.DEBUG)
    {
      if (countOfCollationElements != 0)
      {
        SanityManager.THROWASSERT(
          "countOfCollationElements expected to be 0, not " +
                    countOfCollationElements);
      }
    }
       

    collationElementsForString = new int[stringData.getLength()];

    CollationElementIterator cei =
            collatorForCharacterDatatypes.getCollationElementIterator(
                stringData.getString());

    int nextInt;
    while ((nextInt = cei.next()) != CollationElementIterator.NULLORDER)
    {
      /* Believe it or not, a String might have more
       * collation elements than characters.
       * So, we handle that case by increasing the int array
       * by 5 and copying array elements.
       */
      if (countOfCollationElements == collationElementsForString.length)
      {
        int[] expandedArray = new int[countOfCollationElements + 5];
        System.arraycopy(collationElementsForString, 0, expandedArray,
            0, collationElementsForString.length);
        collationElementsForString = expandedArray;
      }
      collationElementsForString[countOfCollationElements++] = nextInt;
    }

    return collationElementsForString;
  }
}
TOP

Related Classes of org.apache.derby.iapi.types.WorkHorseForCollatorDatatypes

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.