persistentstorage/sql/SRC/Server/SqlSrvCollation.cpp
changeset 0 08ec8eefde2f
child 23 26645d81f48d
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // SqlSrvStatementCollation.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "SqlSrvCollation.h"
       
    19 #include "SqlPanic.h"
       
    20 #include "SqlUtil.h"
       
    21 #include "sqlite3.h"
       
    22 #include "SqliteSymbian.h"		//sqlite3SymbianLastOsError()
       
    23 
       
    24 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    25 /////////////////////////////        Local const data   ///////////////////////////////////////////////////////
       
    26 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    27 
       
    28 //4 collated comparisons + 1 folded comparison
       
    29 const TInt KCollationMethodCount = 4 + 1;
       
    30 
       
    31 //Names of the user defined collations (zero-terminated 16-bit strings)
       
    32 const TUint16* KCollationMethodName[KCollationMethodCount] = 
       
    33 	{
       
    34 	(const TUint16*)L"CompareC0", 
       
    35 	(const TUint16*)L"CompareC1", 
       
    36 	(const TUint16*)L"CompareC2", 
       
    37 	(const TUint16*)L"CompareC3", 
       
    38 	(const TUint16*)L"CompareF"
       
    39 	};
       
    40 
       
    41 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    42 /////////////////////////////        Local functions      /////////////////////////////////////////////////////
       
    43 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
    44 
       
    45 //User-defined collation function prototype, accepted by SQLITE
       
    46 typedef TInt (*TCollationMethodPtr)(void* aUserDefinedData, TInt aByteSize1, const void* aPtr1, TInt aByteSize2, const void* aPtr2);
       
    47 
       
    48 /**
       
    49 This function is used for collated/folded string comparisons,
       
    50 {aByteSize1, aPtr1} - string 1, UTF16 encoded. aByteSize1 - length in bytes.
       
    51 {aByteSize2, aPtr2} - string 2, UTF16 encoded. aByteSize2 - length in bytes.
       
    52 aLevel - 0,1,2,3 - collation level; -1 - folded string comparison;
       
    53 The function returns negative, zero or positive if the first string is less than, equal to, or 
       
    54 greater than the second string.
       
    55 
       
    56 @internalComponent
       
    57 */
       
    58 static TInt Compare(TInt aLevel, TInt aByteSize1, const void* aPtr1, TInt aByteSize2, const void* aPtr2)
       
    59 	{
       
    60 	TPtrC16 ptr1(static_cast <const TUint16*> (aPtr1), (TUint)aByteSize1 /sizeof(TUint16));
       
    61 	TPtrC16 ptr2(static_cast <const TUint16*> (aPtr2), (TUint)aByteSize2 /sizeof(TUint16));
       
    62 	
       
    63 	return aLevel >= 0 ? ptr1.CompareC(ptr2, aLevel, NULL) : ptr1.CompareF(ptr2);
       
    64 	}
       
    65 
       
    66 /**
       
    67 User defined function which will be used by SQLITE engine for collated string comparisons,
       
    68 collation level 0.
       
    69 {aByteSize1, aPtr1} - string 1, UTF16 encoded. aByteSize1 - length in bytes.
       
    70 {aByteSize2, aPtr2} - string 2, UTF16 encoded. aByteSize2 - length in bytes.
       
    71 The function returns negative, zero or positive if the first string is less than, equal to, or 
       
    72 greater than the second string.
       
    73 
       
    74 @internalComponent
       
    75 */
       
    76 static TInt CompareC0(void*, TInt aByteSize1, const void* aPtr1, TInt aByteSize2, const void* aPtr2)
       
    77 	{
       
    78 	return Compare(0, aByteSize1, aPtr1, aByteSize2, aPtr2);
       
    79 	}
       
    80 
       
    81 /**
       
    82 User defined function which will be used by SQLITE engine for collated string comparisons,
       
    83 collation level 1.
       
    84 {aByteSize1, aPtr1} - string 1, UTF16 encoded. aByteSize1 - length in bytes.
       
    85 {aByteSize2, aPtr2} - string 2, UTF16 encoded. aByteSize2 - length in bytes.
       
    86 The function returns negative, zero or positive if the first string is less than, equal to, or 
       
    87 greater than the second string.
       
    88 
       
    89 @internalComponent
       
    90 */
       
    91 static TInt CompareC1(void*, TInt aByteSize1, const void* aPtr1, TInt aByteSize2, const void* aPtr2)
       
    92 	{
       
    93 	return Compare(1, aByteSize1, aPtr1, aByteSize2, aPtr2);
       
    94 	}
       
    95 
       
    96 /**
       
    97 User defined function which will be used by SQLITE engine for collated string comparisons,
       
    98 collation level 2.
       
    99 {aByteSize1, aPtr1} - string 1, UTF16 encoded. aByteSize1 - length in bytes.
       
   100 {aByteSize2, aPtr2} - string 2, UTF16 encoded. aByteSize2 - length in bytes.
       
   101 The function returns negative, zero or positive if the first string is less than, equal to, or 
       
   102 greater than the second string.
       
   103 
       
   104 @internalComponent
       
   105 */
       
   106 static TInt CompareC2(void*, TInt aByteSize1, const void* aPtr1, TInt aByteSize2, const void* aPtr2)
       
   107 	{
       
   108 	return Compare(2, aByteSize1, aPtr1, aByteSize2, aPtr2);
       
   109 	}
       
   110 
       
   111 /**
       
   112 User defined function which will be used by SQLITE engine for collated string comparisons,
       
   113 collation level 3.
       
   114 {aByteSize1, aPtr1} - string 1, UTF16 encoded. aByteSize1 - length in bytes.
       
   115 {aByteSize2, aPtr2} - string 2, UTF16 encoded. aByteSize2 - length in bytes.
       
   116 The function returns negative, zero or positive if the first string is less than, equal to, or 
       
   117 greater than the second string.
       
   118 
       
   119 @internalComponent
       
   120 */
       
   121 static TInt CompareC3(void*, TInt aByteSize1, const void* aPtr1, TInt aByteSize2, const void* aPtr2)
       
   122 	{
       
   123 	return Compare(3, aByteSize1, aPtr1, aByteSize2, aPtr2);
       
   124 	}
       
   125 
       
   126 /**
       
   127 User defined function which will be used by SQLITE engine for folded string comparisons,
       
   128 {aByteSize1, aPtr1} - string 1, UTF16 encoded. aByteSize1 - length in bytes.
       
   129 {aByteSize2, aPtr2} - string 2, UTF16 encoded. aByteSize2 - length in bytes.
       
   130 The function returns negative, zero or positive if the first string is less than, equal to, or 
       
   131 greater than the second string.
       
   132 
       
   133 @internalComponent
       
   134 */
       
   135 static TInt CompareF(void*, TInt aByteSize1, const void* aPtr1, TInt aByteSize2, const void* aPtr2)
       
   136 	{
       
   137 	return Compare(-1, aByteSize1, aPtr1, aByteSize2, aPtr2);
       
   138 	}
       
   139 
       
   140 //KCollationMethodPtr array contains function pointers to all user-defined collation functions
       
   141 const TCollationMethodPtr KCollationMethodPtr[KCollationMethodCount] = 
       
   142 	{
       
   143 	&CompareC0, &CompareC1, &CompareC2, &CompareC3, &CompareF
       
   144 	};
       
   145 
       
   146 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   147 /////////////////////////////        TSqlCollationUtil class definition      //////////////////////////////////
       
   148 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
       
   149 
       
   150 /**
       
   151 Initializes TSqlCollationUtil data members.
       
   152 
       
   153 @panic SqlDb 4 In _DEBUG mode. aDbHandle is NULL.
       
   154 */
       
   155 TSqlCollationUtil::TSqlCollationUtil(sqlite3* aDbHandle) :
       
   156 	iDbHandle(aDbHandle)
       
   157 	{
       
   158 	__SQLASSERT(iDbHandle != NULL, ESqlPanicBadArgument);
       
   159 	}
       
   160 
       
   161 /**
       
   162 Installs user defined collations.
       
   163 
       
   164 At the moment 5 user defined collations with the following names are installed:
       
   165 - CompareC0 - 16-bit strings collated comaprison at level 0;
       
   166 - CompareC1 - 16-bit strings collated comaprison at level 1;
       
   167 - CompareC2 - 16-bit strings collated comaprison at level 2;
       
   168 - CompareC3 - 16-bit strings collated comaprison at level 3;
       
   169 - CompareF  - 16-bit strings folded comaprison;
       
   170 
       
   171 These user defined collations can be used in the following cases:
       
   172 
       
   173 - as column constraint in "CREATE TABLE" SQL statements. For example:
       
   174 @code
       
   175   CREATE TABLE A(Col1 TEXT COLLATE CompareC1)
       
   176 @endcode
       
   177 In this case every time when Col1 values have to be compared, the SQL server will use CompareC1 collation.
       
   178 
       
   179 - as column constraint in "CREATE INDEX" SQL statements. For example:
       
   180 @code
       
   181   CREATE INDEX I ON A(Col1 COLLATE CompareC2)
       
   182 @endcode
       
   183 In this case SQL server will use CompareC2 collation to compare Col1 values when using the index.
       
   184 
       
   185 - In "ORDER BY" clause of "SELECT" SQL statements. For example:
       
   186 @code
       
   187   SELECT * FROM A ORDER BY Col1 COLLATE CompareC3
       
   188 @endcode
       
   189 In this case SQL server will use CompareC3 collation to compare Col1 values when building the result set.
       
   190 
       
   191 @leave The function may leave with some database specific errors categorised as ESqlDbError.
       
   192 
       
   193 @panic SqlDb 2 In _DEBUG mode. iDbHandle is NULL.
       
   194 */
       
   195 void TSqlCollationUtil::InstallCollationsL()
       
   196 	{
       
   197 	__SQLASSERT(iDbHandle != NULL, ESqlPanicInvalidObj);
       
   198 	(void)sqlite3SymbianLastOsError();//clear last OS error
       
   199 	//Register user defined collations
       
   200 	for(TInt i=0;i<KCollationMethodCount;++i)
       
   201 		{
       
   202 		TInt err = sqlite3_create_collation16(iDbHandle, reinterpret_cast <const char*> (KCollationMethodName[i]), 
       
   203 											  SQLITE_UTF16 | SQLITE_UTF16_ALIGNED, 0, KCollationMethodPtr[i]);
       
   204 		__SQLLEAVE_IF_ERROR(::Sql2OsErrCode(err, sqlite3SymbianLastOsError()));
       
   205 		}
       
   206 	}
       
   207 
       
   208 /**
       
   209 @return User-defined collation methods count.
       
   210 
       
   211 @see TSqlCollationUtil::CollationName() 
       
   212 */
       
   213 TInt TSqlCollationUtil::CollationCount() const
       
   214 	{
       
   215 	return KCollationMethodCount;
       
   216 	}
       
   217 
       
   218 /**
       
   219 @return The name of the collation method, identified by aIndex.
       
   220 
       
   221 @panic SqlDb 4 In _DEBUG mode. aIndex >= CollationMethodCount().
       
   222 
       
   223 @see TSqlCollationUtil::CollationsCount() 
       
   224 */
       
   225 TPtrC TSqlCollationUtil::CollationName(TInt aIndex) const
       
   226 	{
       
   227 	__SQLASSERT((TUint)aIndex < KCollationMethodCount, ESqlPanicBadArgument);
       
   228 	return TPtrC(KCollationMethodName[aIndex]);
       
   229 	}