Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the start of the ICU extension. (CVS 3931) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
f473e8526770b6a332dfde3e1fd1ddf8 |
User & Date: | danielk1977 2007-05-06 16:04:12.000 |
Context
2007-05-06
| ||
20:04 | Do not flatten subqueries that are part of a compound SELECT and which have both an ORDER BY and a LIMIT clause. Ticket #2339. (CVS 3932) (check-in: 9600a99804 user: drh tags: trunk) | |
16:04 | Add the start of the ICU extension. (CVS 3931) (check-in: f473e85267 user: danielk1977 tags: trunk) | |
2007-05-05
| ||
22:45 | Add "Powered By SQLite" logo contributed by Alberto Simoes. (CVS 3930) (check-in: 25cfa7740a user: drh tags: trunk) | |
Changes
Added ext/icu/icu.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | /* ** This file implements an integration between the ICU library ** ("International Components for Unicode", an open-source library ** for handling unicode data) and SQLite. The integration uses ** ICU to provide the following to SQLite: ** ** * Implementations of the SQL scalar upper() and lower() ** functions for case mapping, ** ** * Collation sequences ** ** * Implementation of the SQL regexp() function (and hence REGEXP ** operator) using the ICU uregex_XX() APIs. ** ** * LIKE */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) #include <unicode/utypes.h> #include <unicode/uregex.h> #include <unicode/ustring.h> #include <assert.h> #include "sqlite3.h" #ifndef SQLITE_CORE #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 #endif /* ** Collation sequences: ** ** ucol_open() ** ucol_strcoll() ** ucol_close() */ /* ** Version of sqlite3_free() that is always a function, never a macro. */ static void xFree(void *p){ sqlite3_free(p); } /* ** Function to delete compiled regexp objects. Registered as ** a destructor function with sqlite3_set_auxdata(). */ static void icuRegexpDelete(void *p){ URegularExpression *pExpr = (URegularExpression *)p; uregex_close(pExpr); } /* ** Implementation of SQLite REGEXP operator. This scalar function takes ** two arguments. The first is a regular expression pattern to compile ** the second is a string to match against that pattern. If either ** argument is an SQL NULL, then NULL Is returned. Otherwise, the result ** is 1 if the string matches the pattern, or 0 otherwise. ** ** SQLite maps the regexp() function to the regexp() operator such ** that the following two are equivalent: ** ** zString REGEXP zPattern ** regexp(zPattern, zString) ** ** Uses the following ICU regexp APIs: ** ** uregex_open() ** uregex_matches() ** uregex_close() */ static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ UErrorCode status = U_ZERO_ERROR; URegularExpression *pExpr; UBool res; const UChar *zString = sqlite3_value_text16(apArg[1]); /* If the left hand side of the regexp operator is NULL, ** then the result is also NULL. */ if( !zString ){ return; } pExpr = sqlite3_get_auxdata(p, 0); if( !pExpr ){ const UChar *zPattern = sqlite3_value_text16(apArg[0]); if( !zPattern ){ return; } pExpr = uregex_open(zPattern, -1, 0, 0, &status); if( U_SUCCESS(status) ){ sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); }else{ assert(!pExpr); sqlite3_result_error(p, "Error compiling regular expression", -1); return; } } /* Configure the text that the regular expression operates on. */ uregex_setText(pExpr, zString, -1, &status); if( !U_SUCCESS(status) ){ sqlite3_result_error(p, "Error configuring regular expression", -1); return; } /* Attempt the match */ res = uregex_matches(pExpr, 0, &status); if( !U_SUCCESS(status) ){ sqlite3_result_error(p, "Error matching regular expression", -1); return; } /* Set the text that the regular expression operates on to a NULL ** pointer. This is not really necessary, but it is tidier than ** leaving the regular expression object configured with an invalid ** pointer after this function returns. */ uregex_setText(pExpr, 0, 0, &status); /* Return 1 or 0. */ sqlite3_result_int(p, res ? 1 : 0); } /* ** Implementations of scalar functions for case mapping - upper() and ** lower(). Function upper() converts it's input to upper-case (ABC). ** Function lower() converts to lower-case (abc). ** ** ICU provides two types of case mapping, "general" case mapping and ** "language specific". Refer to ICU documentation for the differences ** between the two. ** ** To utilise "general" case mapping, the upper() or lower() scalar ** functions are invoked with one argument: ** ** upper('ABC') -> 'abc' ** lower('abc') -> 'ABC' ** ** To access ICU "language specific" case mapping, upper() or lower() ** should be invoked with two arguments. The second argument is the name ** of the locale to use. Passing an empty string ("") or SQL NULL value ** as the second argument is the smae as invoking the 1 argument version ** of upper() or lower(). ** ** lower('I', 'en_us') -> 'i' ** lower('I', 'tr_tr') -> 'ı' (small dotless i) */ static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ const UChar *zInput; UChar *zOutput; int nInput; int nOutput; UErrorCode status = U_ZERO_ERROR; const char *zLocale = 0; assert(nArg==1 || nArg==2); if( nArg==2 ){ zLocale = (const char *)sqlite3_value_text(apArg[1]); } zInput = sqlite3_value_text16(apArg[0]); nInput = sqlite3_value_bytes16(apArg[0]); nOutput = nInput * 2 + 2; zOutput = sqlite3_malloc(nInput*2+2); if( !zOutput ){ return; } if( sqlite3_user_data(p) ){ u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); }else{ u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status); } if( !U_SUCCESS(status) ){ sqlite3_result_error(p, "Error converting case", -1); return; } sqlite3_result_text16(p, zOutput, -1, xFree); } /* ** Register the ICU extension functions with database db. */ int sqlite3IcuInit(sqlite3 *db){ int rc; int ii; struct IcuScalar { const char *zName; int nArg; int enc; void *pContext; void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { {"regexp", 2, SQLITE_ANY, 0, icuRegexpFunc}, {"lower", 1, SQLITE_UTF16, 0, icuCaseFunc16}, {"lower", 2, SQLITE_UTF16, 0, icuCaseFunc16}, {"upper", 1, SQLITE_UTF16, (void*)1, icuCaseFunc16}, {"upper", 2, SQLITE_UTF16, (void*)1, icuCaseFunc16}, {"lower", 1, SQLITE_UTF8, 0, icuCaseFunc16}, {"lower", 2, SQLITE_UTF8, 0, icuCaseFunc16}, {"upper", 1, SQLITE_UTF8, (void*)1, icuCaseFunc16}, {"upper", 2, SQLITE_UTF8, (void*)1, icuCaseFunc16}, }; for(ii=0; ii<(sizeof(scalars)/sizeof(struct IcuScalar)); ii++){ struct IcuScalar *p = &scalars[ii]; rc = sqlite3_create_function( db, p->zName, p->nArg, p->enc, p->pContext, p->xFunc, 0, 0 ); } return SQLITE_OK; } #if !SQLITE_CORE int sqlite3_extension_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi) return sqlite3IcuInit(db); } #endif #endif |
Changes to main.mk.
︙ | ︙ | |||
60 61 62 63 64 65 66 67 68 69 70 71 72 73 | expr.o func.o hash.o insert.o loadext.o \ main.o malloc.o opcodes.o os.o os_os2.o os_unix.o os_win.o \ pager.o parse.o pragma.o prepare.o printf.o random.o \ select.o table.o tclsqlite.o tokenize.o trigger.o \ update.o util.o vacuum.o \ vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbefifo.o vdbemem.o \ where.o utf.o legacy.o vtab.o # All of the source code files. # SRC = \ $(TOP)/src/alter.c \ $(TOP)/src/analyze.c \ $(TOP)/src/attach.c \ | > > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | expr.o func.o hash.o insert.o loadext.o \ main.o malloc.o opcodes.o os.o os_os2.o os_unix.o os_win.o \ pager.o parse.o pragma.o prepare.o printf.o random.o \ select.o table.o tclsqlite.o tokenize.o trigger.o \ update.o util.o vacuum.o \ vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbefifo.o vdbemem.o \ where.o utf.o legacy.o vtab.o LIBOBJ += icu.o # All of the source code files. # SRC = \ $(TOP)/src/alter.c \ $(TOP)/src/analyze.c \ $(TOP)/src/attach.c \ |
︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 | $(TOP)/ext/fts2/fts2.c \ $(TOP)/ext/fts2/fts2.h \ $(TOP)/ext/fts2/fts2_hash.c \ $(TOP)/ext/fts2/fts2_hash.h \ $(TOP)/ext/fts2/fts2_porter.c \ $(TOP)/ext/fts2/fts2_tokenizer.h \ $(TOP)/ext/fts2/fts2_tokenizer1.c # Generated source code files # SRC += \ keywordhash.h \ opcodes.c \ opcodes.h \ | > > | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | $(TOP)/ext/fts2/fts2.c \ $(TOP)/ext/fts2/fts2.h \ $(TOP)/ext/fts2/fts2_hash.c \ $(TOP)/ext/fts2/fts2_hash.h \ $(TOP)/ext/fts2/fts2_porter.c \ $(TOP)/ext/fts2/fts2_tokenizer.h \ $(TOP)/ext/fts2/fts2_tokenizer1.c SRC += \ $(TOP)/ext/icu/icu.c # Generated source code files # SRC += \ keywordhash.h \ opcodes.c \ opcodes.h \ |
︙ | ︙ | |||
306 307 308 309 310 311 312 313 314 315 316 317 318 319 | $(TCCX) -c $(TOP)/src/expr.c func.o: $(TOP)/src/func.c $(HDR) $(TCCX) -c $(TOP)/src/func.c hash.o: $(TOP)/src/hash.c $(HDR) $(TCCX) -c $(TOP)/src/hash.c insert.o: $(TOP)/src/insert.c $(HDR) $(TCCX) -c $(TOP)/src/insert.c legacy.o: $(TOP)/src/legacy.c $(HDR) $(TCCX) -c $(TOP)/src/legacy.c | > > > | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | $(TCCX) -c $(TOP)/src/expr.c func.o: $(TOP)/src/func.c $(HDR) $(TCCX) -c $(TOP)/src/func.c hash.o: $(TOP)/src/hash.c $(HDR) $(TCCX) -c $(TOP)/src/hash.c icu.o: $(TOP)/ext/icu/icu.c $(HDR) $(TCCX) -c $(TOP)/ext/icu/icu.c insert.o: $(TOP)/src/insert.c $(HDR) $(TCCX) -c $(TOP)/src/insert.c legacy.o: $(TOP)/src/legacy.c $(HDR) $(TCCX) -c $(TOP)/src/legacy.c |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.371 2007/05/06 16:04:12 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** The version of the library |
︙ | ︙ | |||
980 981 982 983 984 985 986 987 988 989 990 991 992 993 | #ifdef SQLITE_ENABLE_FTS2 { extern int sqlite3Fts2Init(sqlite3*); sqlite3Fts2Init(db); } #endif /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking ** mode. Doing nothing at all also makes NORMAL the default. */ #ifdef SQLITE_DEFAULT_LOCKING_MODE db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; | > > > > > > > | 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 | #ifdef SQLITE_ENABLE_FTS2 { extern int sqlite3Fts2Init(sqlite3*); sqlite3Fts2Init(db); } #endif #ifdef SQLITE_ENABLE_ICU { extern int sqlite3IcuInit(sqlite3*); sqlite3IcuInit(db); } #endif /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking ** mode. Doing nothing at all also makes NORMAL the default. */ #ifdef SQLITE_DEFAULT_LOCKING_MODE db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.247 2007/05/06 16:04:12 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 | #endif #ifdef SQLITE_OMIT_GLOBALRECOVER Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_INCRBLOB Tcl_SetVar2(interp, "sqlite_options", "incrblob", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "incrblob", "1", TCL_GLOBAL_ONLY); #endif /* SQLITE_OMIT_AUTOVACUUM */ | > > > > > > | 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 | #endif #ifdef SQLITE_OMIT_GLOBALRECOVER Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_ENABLE_ICU Tcl_SetVar2(interp, "sqlite_options", "icu", "1", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "icu", "0", TCL_GLOBAL_ONLY); #endif #ifdef SQLITE_OMIT_INCRBLOB Tcl_SetVar2(interp, "sqlite_options", "incrblob", "0", TCL_GLOBAL_ONLY); #else Tcl_SetVar2(interp, "sqlite_options", "incrblob", "1", TCL_GLOBAL_ONLY); #endif /* SQLITE_OMIT_AUTOVACUUM */ |
︙ | ︙ |