aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/sqlite/unix/sqlite-3.5.1/ext/icu
diff options
context:
space:
mode:
authordan miller2007-10-20 02:49:29 +0000
committerdan miller2007-10-20 02:49:29 +0000
commite36d23a85ebff914d74bb541558c2b6082b78edb (patch)
tree54b58fdf162e78af64055282a6035c8d2443389d /libraries/sqlite/unix/sqlite-3.5.1/ext/icu
parent* Fixed an issue whereby avatar chat distances were being calculated against ... (diff)
downloadopensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.zip
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.gz
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.bz2
opensim-SC-e36d23a85ebff914d74bb541558c2b6082b78edb.tar.xz
sqlite source (unix build) added to libraries
Diffstat (limited to 'libraries/sqlite/unix/sqlite-3.5.1/ext/icu')
-rw-r--r--libraries/sqlite/unix/sqlite-3.5.1/ext/icu/README.txt170
-rw-r--r--libraries/sqlite/unix/sqlite-3.5.1/ext/icu/icu.c499
2 files changed, 669 insertions, 0 deletions
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/ext/icu/README.txt b/libraries/sqlite/unix/sqlite-3.5.1/ext/icu/README.txt
new file mode 100644
index 0000000..5c995cc
--- /dev/null
+++ b/libraries/sqlite/unix/sqlite-3.5.1/ext/icu/README.txt
@@ -0,0 +1,170 @@
1
2This directory contains source code for the SQLite "ICU" extension, an
3integration of the "International Components for Unicode" library with
4SQLite. Documentation follows.
5
6 1. Features
7
8 1.1 SQL Scalars upper() and lower()
9 1.2 Unicode Aware LIKE Operator
10 1.3 ICU Collation Sequences
11 1.4 SQL REGEXP Operator
12
13 2. Compilation and Usage
14
15 3. Bugs, Problems and Security Issues
16
17 3.1 The "case_sensitive_like" Pragma
18 3.2 The SQLITE_MAX_LIKE_PATTERN_LENGTH Macro
19 3.3 Collation Sequence Security Issue
20
21
221. FEATURES
23
24 1.1 SQL Scalars upper() and lower()
25
26 SQLite's built-in implementations of these two functions only
27 provide case mapping for the 26 letters used in the English
28 language. The ICU based functions provided by this extension
29 provide case mapping, where defined, for the full range of
30 unicode characters.
31
32 ICU provides two types of case mapping, "general" case mapping and
33 "language specific". Refer to ICU documentation for the differences
34 between the two. Specifically:
35
36 http://www.icu-project.org/userguide/caseMappings.html
37 http://www.icu-project.org/userguide/posix.html#case_mappings
38
39 To utilise "general" case mapping, the upper() or lower() scalar
40 functions are invoked with one argument:
41
42 upper('ABC') -> 'abc'
43 lower('abc') -> 'ABC'
44
45 To access ICU "language specific" case mapping, upper() or lower()
46 should be invoked with two arguments. The second argument is the name
47 of the locale to use. Passing an empty string ("") or SQL NULL value
48 as the second argument is the same as invoking the 1 argument version
49 of upper() or lower():
50
51 lower('I', 'en_us') -> 'i'
52 lower('I', 'tr_tr') -> 'ı' (small dotless i)
53
54 1.2 Unicode Aware LIKE Operator
55
56 Similarly to the upper() and lower() functions, the built-in SQLite LIKE
57 operator understands case equivalence for the 26 letters of the English
58 language alphabet. The implementation of LIKE included in this
59 extension uses the ICU function u_foldCase() to provide case
60 independent comparisons for the full range of unicode characters.
61
62 The U_FOLD_CASE_DEFAULT flag is passed to u_foldCase(), meaning the
63 dotless 'I' character used in the Turkish language is considered
64 to be in the same equivalence class as the dotted 'I' character
65 used by many languages (including English).
66
67 1.3 ICU Collation Sequences
68
69 A special SQL scalar function, icu_load_collation() is provided that
70 may be used to register ICU collation sequences with SQLite. It
71 is always called with exactly two arguments, the ICU locale
72 identifying the collation sequence to ICU, and the name of the
73 SQLite collation sequence to create. For example, to create an
74 SQLite collation sequence named "turkish" using Turkish language
75 sorting rules, the SQL statement:
76
77 SELECT icu_load_collation('tr_TR', 'turkish');
78
79 Or, for Australian English:
80
81 SELECT icu_load_collation('en_AU', 'australian');
82
83 The identifiers "turkish" and "australian" may then be used
84 as collation sequence identifiers in SQL statements:
85
86 CREATE TABLE aust_turkish_penpals(
87 australian_penpal_name TEXT COLLATE australian,
88 turkish_penpal_name TEXT COLLATE turkish
89 );
90
91 1.4 SQL REGEXP Operator
92
93 This extension provides an implementation of the SQL binary
94 comparision operator "REGEXP", based on the regular expression functions
95 provided by the ICU library. The syntax of the operator is as described
96 in SQLite documentation:
97
98 <string> REGEXP <re-pattern>
99
100 This extension uses the ICU defaults for regular expression matching
101 behaviour. Specifically, this means that:
102
103 * Matching is case-sensitive,
104 * Regular expression comments are not allowed within patterns, and
105 * The '^' and '$' characters match the beginning and end of the
106 <string> argument, not the beginning and end of lines within
107 the <string> argument.
108
109 Even more specifically, the value passed to the "flags" parameter
110 of ICU C function uregex_open() is 0.
111
112
1132 COMPILATION AND USAGE
114
115 The easiest way to compile and use the ICU extension is to build
116 and use it as a dynamically loadable SQLite extension. To do this
117 using gcc on *nix:
118
119 gcc -shared icu.c `icu-config --ldflags` -o libSqliteIcu.so
120
121 You may need to add "-I" flags so that gcc can find sqlite3ext.h
122 and sqlite3.h. The resulting shared lib, libSqliteIcu.so, may be
123 loaded into sqlite in the same way as any other dynamically loadable
124 extension.
125
126
1273 BUGS, PROBLEMS AND SECURITY ISSUES
128
129 3.1 The "case_sensitive_like" Pragma
130
131 This extension does not work well with the "case_sensitive_like"
132 pragma. If this pragma is used before the ICU extension is loaded,
133 then the pragma has no effect. If the pragma is used after the ICU
134 extension is loaded, then SQLite ignores the ICU implementation and
135 always uses the built-in LIKE operator.
136
137 The ICU extension LIKE operator is always case insensitive.
138
139 3.2 The SQLITE_MAX_LIKE_PATTERN_LENGTH Macro
140
141 Passing very long patterns to the built-in SQLite LIKE operator can
142 cause a stack overflow. To curb this problem, SQLite defines the
143 SQLITE_MAX_LIKE_PATTERN_LENGTH macro as the maximum length of a
144 pattern in bytes (irrespective of encoding). The default value is
145 defined in internal header file "limits.h".
146
147 The ICU extension LIKE implementation suffers from the same
148 problem and uses the same solution. However, since the ICU extension
149 code does not include the SQLite file "limits.h", modifying
150 the default value therein does not affect the ICU extension.
151 The default value of SQLITE_MAX_LIKE_PATTERN_LENGTH used by
152 the ICU extension LIKE operator is 50000, defined in source
153 file "icu.c".
154
155 3.3 Collation Sequence Security Issue
156
157 Internally, SQLite assumes that indices stored in database files
158 are sorted according to the collation sequence indicated by the
159 SQL schema. Changing the definition of a collation sequence after
160 an index has been built is therefore equivalent to database
161 corruption. The SQLite library is not very well tested under
162 these conditions, and may contain potential buffer overruns
163 or other programming errors that could be exploited by a malicious
164 programmer.
165
166 If the ICU extension is used in an environment where potentially
167 malicious users may execute arbitrary SQL (i.e. gears), they
168 should be prevented from invoking the icu_load_collation() function,
169 possibly using the authorisation callback.
170
diff --git a/libraries/sqlite/unix/sqlite-3.5.1/ext/icu/icu.c b/libraries/sqlite/unix/sqlite-3.5.1/ext/icu/icu.c
new file mode 100644
index 0000000..11bb116
--- /dev/null
+++ b/libraries/sqlite/unix/sqlite-3.5.1/ext/icu/icu.c
@@ -0,0 +1,499 @@
1/*
2** 2007 May 6
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11*************************************************************************
12** $Id: icu.c,v 1.6 2007/06/22 15:21:16 danielk1977 Exp $
13**
14** This file implements an integration between the ICU library
15** ("International Components for Unicode", an open-source library
16** for handling unicode data) and SQLite. The integration uses
17** ICU to provide the following to SQLite:
18**
19** * An implementation of the SQL regexp() function (and hence REGEXP
20** operator) using the ICU uregex_XX() APIs.
21**
22** * Implementations of the SQL scalar upper() and lower() functions
23** for case mapping.
24**
25** * Integration of ICU and SQLite collation seqences.
26**
27** * An implementation of the LIKE operator that uses ICU to
28** provide case-independent matching.
29*/
30
31#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU)
32
33/* Include ICU headers */
34#include <unicode/utypes.h>
35#include <unicode/uregex.h>
36#include <unicode/ustring.h>
37#include <unicode/ucol.h>
38
39#include <assert.h>
40
41#ifndef SQLITE_CORE
42 #include "sqlite3ext.h"
43 SQLITE_EXTENSION_INIT1
44#else
45 #include "sqlite3.h"
46#endif
47
48/*
49** Maximum length (in bytes) of the pattern in a LIKE or GLOB
50** operator.
51*/
52#ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH
53# define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000
54#endif
55
56/*
57** Version of sqlite3_free() that is always a function, never a macro.
58*/
59static void xFree(void *p){
60 sqlite3_free(p);
61}
62
63/*
64** Compare two UTF-8 strings for equality where the first string is
65** a "LIKE" expression. Return true (1) if they are the same and
66** false (0) if they are different.
67*/
68static int icuLikeCompare(
69 const uint8_t *zPattern, /* LIKE pattern */
70 const uint8_t *zString, /* The UTF-8 string to compare against */
71 const UChar32 uEsc /* The escape character */
72){
73 static const int MATCH_ONE = (UChar32)'_';
74 static const int MATCH_ALL = (UChar32)'%';
75
76 int iPattern = 0; /* Current byte index in zPattern */
77 int iString = 0; /* Current byte index in zString */
78
79 int prevEscape = 0; /* True if the previous character was uEsc */
80
81 while( zPattern[iPattern]!=0 ){
82
83 /* Read (and consume) the next character from the input pattern. */
84 UChar32 uPattern;
85 U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
86 assert(uPattern!=0);
87
88 /* There are now 4 possibilities:
89 **
90 ** 1. uPattern is an unescaped match-all character "%",
91 ** 2. uPattern is an unescaped match-one character "_",
92 ** 3. uPattern is an unescaped escape character, or
93 ** 4. uPattern is to be handled as an ordinary character
94 */
95 if( !prevEscape && uPattern==MATCH_ALL ){
96 /* Case 1. */
97 uint8_t c;
98
99 /* Skip any MATCH_ALL or MATCH_ONE characters that follow a
100 ** MATCH_ALL. For each MATCH_ONE, skip one character in the
101 ** test string.
102 */
103 while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){
104 if( c==MATCH_ONE ){
105 if( zString[iString]==0 ) return 0;
106 U8_FWD_1_UNSAFE(zString, iString);
107 }
108 iPattern++;
109 }
110
111 if( zPattern[iPattern]==0 ) return 1;
112
113 while( zString[iString] ){
114 if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){
115 return 1;
116 }
117 U8_FWD_1_UNSAFE(zString, iString);
118 }
119 return 0;
120
121 }else if( !prevEscape && uPattern==MATCH_ONE ){
122 /* Case 2. */
123 if( zString[iString]==0 ) return 0;
124 U8_FWD_1_UNSAFE(zString, iString);
125
126 }else if( !prevEscape && uPattern==uEsc){
127 /* Case 3. */
128 prevEscape = 1;
129
130 }else{
131 /* Case 4. */
132 UChar32 uString;
133 U8_NEXT_UNSAFE(zString, iString, uString);
134 uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
135 uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
136 if( uString!=uPattern ){
137 return 0;
138 }
139 prevEscape = 0;
140 }
141 }
142
143 return zString[iString]==0;
144}
145
146/*
147** Implementation of the like() SQL function. This function implements
148** the build-in LIKE operator. The first argument to the function is the
149** pattern and the second argument is the string. So, the SQL statements:
150**
151** A LIKE B
152**
153** is implemented as like(B, A). If there is an escape character E,
154**
155** A LIKE B ESCAPE E
156**
157** is mapped to like(B, A, E).
158*/
159static void icuLikeFunc(
160 sqlite3_context *context,
161 int argc,
162 sqlite3_value **argv
163){
164 const unsigned char *zA = sqlite3_value_text(argv[0]);
165 const unsigned char *zB = sqlite3_value_text(argv[1]);
166 UChar32 uEsc = 0;
167
168 /* Limit the length of the LIKE or GLOB pattern to avoid problems
169 ** of deep recursion and N*N behavior in patternCompare().
170 */
171 if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){
172 sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1);
173 return;
174 }
175
176
177 if( argc==3 ){
178 /* The escape character string must consist of a single UTF-8 character.
179 ** Otherwise, return an error.
180 */
181 int nE= sqlite3_value_bytes(argv[2]);
182 const unsigned char *zE = sqlite3_value_text(argv[2]);
183 int i = 0;
184 if( zE==0 ) return;
185 U8_NEXT(zE, i, nE, uEsc);
186 if( i!=nE){
187 sqlite3_result_error(context,
188 "ESCAPE expression must be a single character", -1);
189 return;
190 }
191 }
192
193 if( zA && zB ){
194 sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc));
195 }
196}
197
198/*
199** This function is called when an ICU function called from within
200** the implementation of an SQL scalar function returns an error.
201**
202** The scalar function context passed as the first argument is
203** loaded with an error message based on the following two args.
204*/
205static void icuFunctionError(
206 sqlite3_context *pCtx, /* SQLite scalar function context */
207 const char *zName, /* Name of ICU function that failed */
208 UErrorCode e /* Error code returned by ICU function */
209){
210 char zBuf[128];
211 sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e));
212 zBuf[127] = '\0';
213 sqlite3_result_error(pCtx, zBuf, -1);
214}
215
216/*
217** Function to delete compiled regexp objects. Registered as
218** a destructor function with sqlite3_set_auxdata().
219*/
220static void icuRegexpDelete(void *p){
221 URegularExpression *pExpr = (URegularExpression *)p;
222 uregex_close(pExpr);
223}
224
225/*
226** Implementation of SQLite REGEXP operator. This scalar function takes
227** two arguments. The first is a regular expression pattern to compile
228** the second is a string to match against that pattern. If either
229** argument is an SQL NULL, then NULL Is returned. Otherwise, the result
230** is 1 if the string matches the pattern, or 0 otherwise.
231**
232** SQLite maps the regexp() function to the regexp() operator such
233** that the following two are equivalent:
234**
235** zString REGEXP zPattern
236** regexp(zPattern, zString)
237**
238** Uses the following ICU regexp APIs:
239**
240** uregex_open()
241** uregex_matches()
242** uregex_close()
243*/
244static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){
245 UErrorCode status = U_ZERO_ERROR;
246 URegularExpression *pExpr;
247 UBool res;
248 const UChar *zString = sqlite3_value_text16(apArg[1]);
249
250 /* If the left hand side of the regexp operator is NULL,
251 ** then the result is also NULL.
252 */
253 if( !zString ){
254 return;
255 }
256
257 pExpr = sqlite3_get_auxdata(p, 0);
258 if( !pExpr ){
259 const UChar *zPattern = sqlite3_value_text16(apArg[0]);
260 if( !zPattern ){
261 return;
262 }
263 pExpr = uregex_open(zPattern, -1, 0, 0, &status);
264
265 if( U_SUCCESS(status) ){
266 sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete);
267 }else{
268 assert(!pExpr);
269 icuFunctionError(p, "uregex_open", status);
270 return;
271 }
272 }
273
274 /* Configure the text that the regular expression operates on. */
275 uregex_setText(pExpr, zString, -1, &status);
276 if( !U_SUCCESS(status) ){
277 icuFunctionError(p, "uregex_setText", status);
278 return;
279 }
280
281 /* Attempt the match */
282 res = uregex_matches(pExpr, 0, &status);
283 if( !U_SUCCESS(status) ){
284 icuFunctionError(p, "uregex_matches", status);
285 return;
286 }
287
288 /* Set the text that the regular expression operates on to a NULL
289 ** pointer. This is not really necessary, but it is tidier than
290 ** leaving the regular expression object configured with an invalid
291 ** pointer after this function returns.
292 */
293 uregex_setText(pExpr, 0, 0, &status);
294
295 /* Return 1 or 0. */
296 sqlite3_result_int(p, res ? 1 : 0);
297}
298
299/*
300** Implementations of scalar functions for case mapping - upper() and
301** lower(). Function upper() converts it's input to upper-case (ABC).
302** Function lower() converts to lower-case (abc).
303**
304** ICU provides two types of case mapping, "general" case mapping and
305** "language specific". Refer to ICU documentation for the differences
306** between the two.
307**
308** To utilise "general" case mapping, the upper() or lower() scalar
309** functions are invoked with one argument:
310**
311** upper('ABC') -> 'abc'
312** lower('abc') -> 'ABC'
313**
314** To access ICU "language specific" case mapping, upper() or lower()
315** should be invoked with two arguments. The second argument is the name
316** of the locale to use. Passing an empty string ("") or SQL NULL value
317** as the second argument is the same as invoking the 1 argument version
318** of upper() or lower().
319**
320** lower('I', 'en_us') -> 'i'
321** lower('I', 'tr_tr') -> 'ı' (small dotless i)
322**
323** http://www.icu-project.org/userguide/posix.html#case_mappings
324*/
325static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
326 const UChar *zInput;
327 UChar *zOutput;
328 int nInput;
329 int nOutput;
330
331 UErrorCode status = U_ZERO_ERROR;
332 const char *zLocale = 0;
333
334 assert(nArg==1 || nArg==2);
335 if( nArg==2 ){
336 zLocale = (const char *)sqlite3_value_text(apArg[1]);
337 }
338
339 zInput = sqlite3_value_text16(apArg[0]);
340 if( !zInput ){
341 return;
342 }
343 nInput = sqlite3_value_bytes16(apArg[0]);
344
345 nOutput = nInput * 2 + 2;
346 zOutput = sqlite3_malloc(nOutput);
347 if( !zOutput ){
348 return;
349 }
350
351 if( sqlite3_user_data(p) ){
352 u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
353 }else{
354 u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
355 }
356
357 if( !U_SUCCESS(status) ){
358 icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
359 return;
360 }
361
362 sqlite3_result_text16(p, zOutput, -1, xFree);
363}
364
365/*
366** Collation sequence destructor function. The pCtx argument points to
367** a UCollator structure previously allocated using ucol_open().
368*/
369static void icuCollationDel(void *pCtx){
370 UCollator *p = (UCollator *)pCtx;
371 ucol_close(p);
372}
373
374/*
375** Collation sequence comparison function. The pCtx argument points to
376** a UCollator structure previously allocated using ucol_open().
377*/
378static int icuCollationColl(
379 void *pCtx,
380 int nLeft,
381 const void *zLeft,
382 int nRight,
383 const void *zRight
384){
385 UCollationResult res;
386 UCollator *p = (UCollator *)pCtx;
387 res = ucol_strcoll(p, (UChar *)zLeft, nLeft/2, (UChar *)zRight, nRight/2);
388 switch( res ){
389 case UCOL_LESS: return -1;
390 case UCOL_GREATER: return +1;
391 case UCOL_EQUAL: return 0;
392 }
393 assert(!"Unexpected return value from ucol_strcoll()");
394 return 0;
395}
396
397/*
398** Implementation of the scalar function icu_load_collation().
399**
400** This scalar function is used to add ICU collation based collation
401** types to an SQLite database connection. It is intended to be called
402** as follows:
403**
404** SELECT icu_load_collation(<locale>, <collation-name>);
405**
406** Where <locale> is a string containing an ICU locale identifier (i.e.
407** "en_AU", "tr_TR" etc.) and <collation-name> is the name of the
408** collation sequence to create.
409*/
410static void icuLoadCollation(
411 sqlite3_context *p,
412 int nArg,
413 sqlite3_value **apArg
414){
415 sqlite3 *db = (sqlite3 *)sqlite3_user_data(p);
416 UErrorCode status = U_ZERO_ERROR;
417 const char *zLocale; /* Locale identifier - (eg. "jp_JP") */
418 const char *zName; /* SQL Collation sequence name (eg. "japanese") */
419 UCollator *pUCollator; /* ICU library collation object */
420 int rc; /* Return code from sqlite3_create_collation_x() */
421
422 assert(nArg==2);
423 zLocale = (const char *)sqlite3_value_text(apArg[0]);
424 zName = (const char *)sqlite3_value_text(apArg[1]);
425
426 if( !zLocale || !zName ){
427 return;
428 }
429
430 pUCollator = ucol_open(zLocale, &status);
431 if( !U_SUCCESS(status) ){
432 icuFunctionError(p, "ucol_open", status);
433 return;
434 }
435 assert(p);
436
437 rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator,
438 icuCollationColl, icuCollationDel
439 );
440 if( rc!=SQLITE_OK ){
441 ucol_close(pUCollator);
442 sqlite3_result_error(p, "Error registering collation function", -1);
443 }
444}
445
446/*
447** Register the ICU extension functions with database db.
448*/
449int sqlite3IcuInit(sqlite3 *db){
450 struct IcuScalar {
451 const char *zName; /* Function name */
452 int nArg; /* Number of arguments */
453 int enc; /* Optimal text encoding */
454 void *pContext; /* sqlite3_user_data() context */
455 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
456 } scalars[] = {
457 {"regexp",-1, SQLITE_ANY, 0, icuRegexpFunc},
458
459 {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16},
460 {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16},
461 {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16},
462 {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16},
463
464 {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16},
465 {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16},
466 {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16},
467 {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16},
468
469 {"like", 2, SQLITE_UTF8, 0, icuLikeFunc},
470 {"like", 3, SQLITE_UTF8, 0, icuLikeFunc},
471
472 {"icu_load_collation", 2, SQLITE_UTF8, (void*)db, icuLoadCollation},
473 };
474
475 int rc = SQLITE_OK;
476 int i;
477
478 for(i=0; rc==SQLITE_OK && i<(sizeof(scalars)/sizeof(struct IcuScalar)); i++){
479 struct IcuScalar *p = &scalars[i];
480 rc = sqlite3_create_function(
481 db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0
482 );
483 }
484
485 return rc;
486}
487
488#if !SQLITE_CORE
489int sqlite3_extension_init(
490 sqlite3 *db,
491 char **pzErrMsg,
492 const sqlite3_api_routines *pApi
493){
494 SQLITE_EXTENSION_INIT2(pApi)
495 return sqlite3IcuInit(db);
496}
497#endif
498
499#endif