|
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 } |