| OLD | NEW |
| 1 Index: Makefile.linux-gcc | |
| 2 =================================================================== | |
| 3 --- Makefile.linux-gcc 2009-09-03 13:32:06.000000000 -0700 | |
| 4 +++ Makefile.linux-gcc 2009-07-01 12:08:39.000000000 -0700 | |
| 5 @@ -14,7 +14,7 @@ | |
| 6 #### The toplevel directory of the source tree. This is the directory | |
| 7 # that contains this "Makefile.in" and the "configure.in" script. | |
| 8 # | |
| 9 -TOP = ../sqlite | |
| 10 +TOP = .. | |
| 11 | |
| 12 #### C Compiler and options for use in building executables that | |
| 13 # will run on the platform that is doing the build. | |
| 14 @@ -33,13 +33,13 @@ | |
| 15 # appropriately: | |
| 16 # | |
| 17 #THREADSAFE = -DTHREADSAFE=1 | |
| 18 -THREADSAFE = -DTHREADSAFE=0 | |
| 19 +THREADSAFE = -DTHREADSAFE=1 | |
| 20 | |
| 21 #### Specify any extra linker options needed to make the library | |
| 22 # thread safe | |
| 23 # | |
| 24 #THREADLIB = -lpthread | |
| 25 -THREADLIB = | |
| 26 +THREADLIB = -lpthread | |
| 27 | |
| 28 #### Specify any extra libraries needed to access required functions. | |
| 29 # | |
| 30 @@ -57,8 +57,29 @@ | |
| 31 #OPTS = -DSQLITE_DEBUG=2 | |
| 32 #OPTS = -DSQLITE_DEBUG=1 | |
| 33 #OPTS = | |
| 34 -OPTS = -DNDEBUG=1 | |
| 35 -OPTS += -DHAVE_FDATASYNC=1 | |
| 36 + | |
| 37 +# These flags match those for SQLITE_CFLAGS in config.mk. | |
| 38 + | |
| 39 +OPTS += -DNDEBUG | |
| 40 +OPTS += -DSQLITE_CORE | |
| 41 +OPTS += -DSQLITE_ENABLE_FTS1 -DSQLITE_ENABLE_BROKEN_FTS1 | |
| 42 +OPTS += -DSQLITE_ENABLE_FTS2 -DSQLITE_ENABLE_BROKEN_FTS2 | |
| 43 +OPTS += -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600 | |
| 44 +OPTS += -DHAVE_USLEEP=1 | |
| 45 + | |
| 46 +# Additional SQLite tests. | |
| 47 +OPTS += -DSQLITE_MEMDEBUG=1 | |
| 48 + | |
| 49 +# Don't include these ones, they break the SQLite tests. | |
| 50 +# -DSQLITE_OMIT_ATTACH=1 \ | |
| 51 +# -DSQLITE_OMIT_LOAD_EXTENSION=1 \ | |
| 52 +# -DSQLITE_OMIT_VACUUM=1 \ | |
| 53 +# -DSQLITE_TRANSACTION_DEFAULT_IMMEDIATE=1 \ | |
| 54 + | |
| 55 +SHELL_ICU = $(TOP)/src/shell_icu_linux.c -licuuc | |
| 56 + | |
| 57 +# TODO(shess) I can't see why I need this setting. | |
| 58 +OPTS += -DOS_UNIX=1 | |
| 59 | |
| 60 #### The suffix to add to executable files. ".exe" for windows. | |
| 61 # Nothing for unix. | |
| 62 @@ -91,16 +112,16 @@ | |
| 63 | |
| 64 #### Extra compiler options needed for programs that use the TCL library. | |
| 65 # | |
| 66 -#TCL_FLAGS = | |
| 67 +TCL_FLAGS = -I/usr/include/tcl8.4 | |
| 68 #TCL_FLAGS = -DSTATIC_BUILD=1 | |
| 69 -TCL_FLAGS = -I/home/drh/tcltk/8.4linux | |
| 70 +#TCL_FLAGS = -I/home/drh/tcltk/8.4linux | |
| 71 #TCL_FLAGS = -I/home/drh/tcltk/8.4win -DSTATIC_BUILD=1 | |
| 72 #TCL_FLAGS = -I/home/drh/tcltk/8.3hpux | |
| 73 | |
| 74 #### Linker options needed to link against the TCL library. | |
| 75 # | |
| 76 -#LIBTCL = -ltcl -lm -ldl | |
| 77 -LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl | |
| 78 +LIBTCL = -ltcl8.4 -lm -ldl | |
| 79 +#LIBTCL = /home/drh/tcltk/8.4linux/libtcl8.4g.a -lm -ldl | |
| 80 #LIBTCL = /home/drh/tcltk/8.4win/libtcl84s.a -lmsvcrt | |
| 81 #LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc | |
| 82 | |
| 83 Index: ext/fts1/fts1.c | |
| 84 =================================================================== | |
| 85 --- ext/fts1/fts1.c 2009-09-04 13:37:41.000000000 -0700 | |
| 86 +++ ext/fts1/fts1.c 2009-09-14 18:16:55.000000000 -0700 | |
| 87 @@ -1225,10 +1225,6 @@ | |
| 88 break; | |
| 89 } | |
| 90 return rc; | |
| 91 - | |
| 92 - err: | |
| 93 - sqlite3_finalize(s); | |
| 94 - return rc; | |
| 95 } | |
| 96 | |
| 97 /* Like sql_step_statement(), but convert SQLITE_DONE to SQLITE_OK. | |
| 98 Index: ext/icu/icu.c | 1 Index: ext/icu/icu.c |
| 99 =================================================================== | 2 =================================================================== |
| 100 --- ext/icu/icu.c 2009-09-03 13:32:06.000000000 -0700 | 3 --- ext/icu/icu.c 2009-09-03 13:32:06.000000000 -0700 |
| 101 +++ ext/icu/icu.c 2009-07-01 12:08:37.000000000 -0700 | 4 +++ ext/icu/icu.c 2009-07-01 12:08:37.000000000 -0700 |
| 102 @@ -38,6 +38,11 @@ | 5 @@ -38,6 +38,11 @@ |
| 103 | 6 |
| 104 #include <assert.h> | 7 #include <assert.h> |
| 105 | 8 |
| 106 +// TODO(evanm): this is cut'n'pasted from fts2.c. Why is it necessary? | 9 +// TODO(evanm): this is cut'n'pasted from fts2.c. Why is it necessary? |
| 107 +#if !defined(SQLITE_CORE) | 10 +#if !defined(SQLITE_CORE) |
| 108 +# define SQLITE_CORE 1 | 11 +# define SQLITE_CORE 1 |
| 109 +#endif | 12 +#endif |
| 110 + | 13 + |
| 111 #ifndef SQLITE_CORE | 14 #ifndef SQLITE_CORE |
| 112 #include "sqlite3ext.h" | 15 #include "sqlite3ext.h" |
| 113 SQLITE_EXTENSION_INIT1 | 16 SQLITE_EXTENSION_INIT1 |
| 114 Index: main.mk | |
| 115 =================================================================== | |
| 116 --- main.mk 2009-09-10 12:18:17.000000000 -0700 | |
| 117 +++ main.mk 2009-09-15 11:45:21.000000000 -0700 | |
| 118 @@ -69,6 +69,16 @@ | |
| 119 walker.o where.o utf.o vtab.o | |
| 120 | |
| 121 | |
| 122 +LIBOBJ += fts1.o \ | |
| 123 + fts1_hash.o \ | |
| 124 + fts1_tokenizer1.o \ | |
| 125 + fts1_porter.o | |
| 126 +LIBOBJ += fts2.o \ | |
| 127 + fts2_hash.o \ | |
| 128 + fts2_icu.o \ | |
| 129 + fts2_porter.o \ | |
| 130 + fts2_tokenizer.o \ | |
| 131 + fts2_tokenizer1.o | |
| 132 | |
| 133 # All of the source code files. | |
| 134 # | |
| 135 @@ -243,6 +253,25 @@ | |
| 136 $(TOP)/src/test_thread.c \ | |
| 137 $(TOP)/src/test_wsd.c | |
| 138 | |
| 139 +TESTSRC += \ | |
| 140 + $(TOP)/ext/fts1/fts1.c \ | |
| 141 + $(TOP)/ext/fts1/fts1.h \ | |
| 142 + $(TOP)/ext/fts1/fts1_hash.c \ | |
| 143 + $(TOP)/ext/fts1/fts1_hash.h \ | |
| 144 + $(TOP)/ext/fts1/fts1_porter.c \ | |
| 145 + $(TOP)/ext/fts1/fts1_tokenizer.h \ | |
| 146 + $(TOP)/ext/fts1/fts1_tokenizer1.c | |
| 147 +TESTSRC += \ | |
| 148 + $(TOP)/ext/fts2/fts2.c \ | |
| 149 + $(TOP)/ext/fts2/fts2.h \ | |
| 150 + $(TOP)/ext/fts2/fts2_hash.c \ | |
| 151 + $(TOP)/ext/fts2/fts2_hash.h \ | |
| 152 + $(TOP)/ext/fts2/fts2_icu.c \ | |
| 153 + $(TOP)/ext/fts2/fts2_porter.c \ | |
| 154 + $(TOP)/ext/fts2/fts2_tokenizer.h \ | |
| 155 + $(TOP)/ext/fts2/fts2_tokenizer.c \ | |
| 156 + $(TOP)/ext/fts2/fts2_tokenizer1.c | |
| 157 + | |
| 158 #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c | |
| 159 #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c | |
| 160 | |
| 161 @@ -314,8 +343,8 @@ | |
| 162 | |
| 163 sqlite3$(EXE): $(TOP)/src/shell.c libsqlite3.a sqlite3.h | |
| 164 $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) \ | |
| 165 - $(TOP)/src/shell.c \ | |
| 166 - libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) | |
| 167 + $(TOP)/src/shell.c $(SHELL_ICU) \ | |
| 168 + libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) -ldl | |
| 169 | |
| 170 objects: $(LIBOBJ_ORIG) | |
| 171 | |
| 172 @@ -447,6 +476,20 @@ | |
| 173 $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c | |
| 174 | |
| 175 | |
| 176 + | |
| 177 + | |
| 178 +fts1.o: $(TOP)/ext/fts1/fts1.c $(HDR) $(EXTHDR) | |
| 179 + $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1.c | |
| 180 + | |
| 181 +fts1_hash.o: $(TOP)/ext/fts1/fts1_hash.c $(HDR) $(EXTHDR) | |
| 182 + $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_hash.c | |
| 183 + | |
| 184 +fts1_tokenizer1.o: $(TOP)/ext/fts1/fts1_tokenizer1.c $(HDR) $(EXTHDR) | |
| 185 + $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_tokenizer1.c | |
| 186 + | |
| 187 +fts1_porter.o: $(TOP)/ext/fts1/fts1_porter.c $(HDR) $(EXTHDR) | |
| 188 + $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts1/fts1_porter.c | |
| 189 + | |
| 190 # Rules for building test programs and for running tests | |
| 191 # | |
| 192 tclsqlite3: $(TOP)/src/tclsqlite.c libsqlite3.a | |
| 193 @@ -484,6 +527,15 @@ | |
| 194 test: testfixture$(EXE) sqlite3$(EXE) | |
| 195 ./testfixture$(EXE) $(TOP)/test/veryquick.test | |
| 196 | |
| 197 +ftstest: testfixture$(EXE) sqlite3$(EXE) | |
| 198 + ./testfixture$(EXE) $(TOP)/test/fts.test | |
| 199 + | |
| 200 +fts1test: testfixture$(EXE) sqlite3$(EXE) | |
| 201 + ./testfixture$(EXE) $(TOP)/test/fts1.test | |
| 202 + | |
| 203 +fts2test: testfixture$(EXE) sqlite3$(EXE) | |
| 204 + ./testfixture$(EXE) $(TOP)/test/fts2.test | |
| 205 + | |
| 206 sqlite3_analyzer$(EXE): $(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \ | |
| 207 $(TOP)/tool/spaceanal.tcl | |
| 208 sed \ | |
| 209 Index: src/expr.c | 17 Index: src/expr.c |
| 210 =================================================================== | 18 =================================================================== |
| 211 --- src/expr.c 2009-09-08 12:16:11.000000000 -0700 | 19 --- src/expr.c 2009-09-08 12:16:11.000000000 -0700 |
| 212 +++ src/expr.c 2009-09-23 16:58:47.000000000 -0700 | 20 +++ src/expr.c 2009-09-23 16:58:47.000000000 -0700 |
| 213 @@ -804,7 +804,9 @@ | 21 @@ -804,7 +804,9 @@ |
| 214 }else{ | 22 }else{ |
| 215 int nSize = exprStructSize(p); | 23 int nSize = exprStructSize(p); |
| 216 memcpy(zAlloc, p, nSize); | 24 memcpy(zAlloc, p, nSize); |
| 217 - memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); | 25 - memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); |
| 218 + if( EXPR_FULLSIZE>nSize ){ | 26 + if( EXPR_FULLSIZE>nSize ){ |
| 219 + memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); | 27 + memset(&zAlloc[nSize], 0, EXPR_FULLSIZE-nSize); |
| 220 + } | 28 + } |
| 221 } | 29 } |
| 222 | 30 |
| 223 /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. *
/ | 31 /* Set the EP_Reduced, EP_TokenOnly, and EP_Static flags appropriately. *
/ |
| 224 Index: src/func.c | 32 Index: src/func.c |
| 225 =================================================================== | 33 =================================================================== |
| 226 --- src/func.c 2009-09-04 13:37:42.000000000 -0700 | 34 --- src/func.c 2009-09-04 13:37:42.000000000 -0700 |
| 227 +++ src/func.c 2009-09-14 18:18:18.000000000 -0700 | 35 +++ src/func.c 2009-09-14 18:18:18.000000000 -0700 |
| 228 @@ -1020,7 +1020,7 @@ | 36 @@ -1020,7 +1020,7 @@ |
| 229 } | 37 } |
| 230 } | 38 } |
| 231 if( zCharSet ){ | 39 if( zCharSet ){ |
| 232 - sqlite3_free(azChar); | 40 - sqlite3_free(azChar); |
| 233 + sqlite3_free((void*)azChar); | 41 + sqlite3_free((void*)azChar); |
| 234 } | 42 } |
| 235 } | 43 } |
| 236 sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); | 44 sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); |
| 237 Index: src/os.h | |
| 238 =================================================================== | |
| 239 --- src/os.h 2009-09-04 13:37:42.000000000 -0700 | |
| 240 +++ src/os.h 2009-09-14 18:18:24.000000000 -0700 | |
| 241 @@ -29,6 +29,10 @@ | |
| 242 ** will defined to either 1 or 0. One of the four will be 1. The other | |
| 243 ** three will be 0. | |
| 244 */ | |
| 245 +#ifdef OS_SYMBIAN | |
| 246 +# define SQLITE_OS_SYMBIAN 1 | |
| 247 +# define SQLITE_OS_OTHER 1 | |
| 248 +#endif | |
| 249 #if defined(SQLITE_OS_OTHER) | |
| 250 # if SQLITE_OS_OTHER==1 | |
| 251 # undef SQLITE_OS_UNIX | |
| 252 Index: src/os_unix.c | |
| 253 =================================================================== | |
| 254 --- src/os_unix.c 2009-09-10 12:14:55.000000000 -0700 | |
| 255 +++ src/os_unix.c 2009-09-15 16:50:43.000000000 -0700 | |
| 256 @@ -3215,6 +3215,7 @@ | |
| 257 ********************** End sqlite3_file Methods ******************************* | |
| 258 ******************************************************************************/ | |
| 259 | |
| 260 + | |
| 261 /* | |
| 262 ** This division contains definitions of sqlite3_io_methods objects that | |
| 263 ** implement various file locking strategies. It also contains definitions | |
| 264 @@ -3496,9 +3497,16 @@ | |
| 265 */ | |
| 266 | |
| 267 /* | |
| 268 +** Initializes a unixFile structure with zeros. | |
| 269 +*/ | |
| 270 +void initUnixFile(sqlite3_file* file) { | |
| 271 + memset(file, 0, sizeof(unixFile)); | |
| 272 +} | |
| 273 + | |
| 274 +/* | |
| 275 ** Initialize the contents of the unixFile structure pointed to by pId. | |
| 276 */ | |
| 277 -static int fillInUnixFile( | |
| 278 +int fillInUnixFile( | |
| 279 sqlite3_vfs *pVfs, /* Pointer to vfs object */ | |
| 280 int h, /* Open file descriptor of file being opened */ | |
| 281 int dirfd, /* Directory file descriptor */ | |
| 282 Index: src/os_win.c | |
| 283 =================================================================== | |
| 284 --- src/os_win.c 2009-09-10 15:08:39.000000000 -0700 | |
| 285 +++ src/os_win.c 2009-09-14 18:26:16.000000000 -0700 | |
| 286 @@ -1890,4 +1890,11 @@ | |
| 287 return SQLITE_OK; | |
| 288 } | |
| 289 | |
| 290 +void chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE ha
ndle) { | |
| 291 + winFile* winSQLite3File = (winFile*)file; | |
| 292 + memset(file, 0, sizeof(*file)); | |
| 293 + winSQLite3File->pMethod = &winIoMethod; | |
| 294 + winSQLite3File->h = handle; | |
| 295 +} | |
| 296 + | |
| 297 #endif /* SQLITE_OS_WIN */ | |
| 298 Index: src/pcache.c | |
| 299 =================================================================== | |
| 300 --- src/pcache.c 2009-09-04 13:37:42.000000000 -0700 | |
| 301 +++ src/pcache.c 2009-09-15 16:41:55.000000000 -0700 | |
| 302 @@ -542,14 +542,12 @@ | |
| 303 return nPage; | |
| 304 } | |
| 305 | |
| 306 -#ifdef SQLITE_TEST | |
| 307 /* | |
| 308 ** Get the suggested cache-size value. | |
| 309 */ | |
| 310 int sqlite3PcacheGetCachesize(PCache *pCache){ | |
| 311 return pCache->nMax; | |
| 312 } | |
| 313 -#endif | |
| 314 | |
| 315 /* | |
| 316 ** Set the suggested cache-size value. | |
| 317 Index: src/pcache.h | |
| 318 =================================================================== | |
| 319 --- src/pcache.h 2009-09-04 13:37:42.000000000 -0700 | |
| 320 +++ src/pcache.h 2009-09-15 16:41:52.000000000 -0700 | |
| 321 @@ -139,9 +139,7 @@ | |
| 322 ** of the suggested cache-sizes. | |
| 323 */ | |
| 324 void sqlite3PcacheSetCachesize(PCache *, int); | |
| 325 -#ifdef SQLITE_TEST | |
| 326 int sqlite3PcacheGetCachesize(PCache *); | |
| 327 -#endif | |
| 328 | |
| 329 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT | |
| 330 /* Try to return memory used by the pcache module to the main memory heap */ | |
| 331 Index: src/shell.c | |
| 332 =================================================================== | |
| 333 --- src/shell.c 2009-09-04 13:37:43.000000000 -0700 | |
| 334 +++ src/shell.c 2009-09-15 11:32:08.000000000 -0700 | |
| 335 @@ -3007,6 +3007,18 @@ | |
| 336 int i; | |
| 337 int rc = 0; | |
| 338 | |
| 339 + /* Begin evanm patch. */ | |
| 340 +#ifdef SQLITE_GEARS_DISABLE_SHELL_ICU | |
| 341 + /* Gears doesn't use this. */ | |
| 342 +#else | |
| 343 + extern int sqlite_shell_init_icu(); | |
| 344 + if( !sqlite_shell_init_icu() ){ | |
| 345 + fprintf(stderr, "%s: warning: couldn't find icudt38.dll; " | |
| 346 + "queries against ICU FTS tables will fail.\n", argv[0]); | |
| 347 + } | |
| 348 +#endif | |
| 349 + /* End evanm patch. */ | |
| 350 + | |
| 351 Argv0 = argv[0]; | |
| 352 main_init(&data); | |
| 353 stdin_is_interactive = isatty(0); | |
| 354 Index: src/sqlite3ext.h | |
| 355 =================================================================== | |
| 356 --- src/sqlite3ext.h 2009-09-03 13:32:06.000000000 -0700 | |
| 357 +++ src/sqlite3ext.h 2009-09-15 11:34:43.000000000 -0700 | |
| 358 @@ -372,9 +372,15 @@ | |
| 359 #define sqlite3_next_stmt sqlite3_api->next_stmt | |
| 360 #define sqlite3_sql sqlite3_api->sql | |
| 361 #define sqlite3_status sqlite3_api->status | |
| 362 -#endif /* SQLITE_CORE */ | |
| 363 | |
| 364 #define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0; | |
| 365 #define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v; | |
| 366 | |
| 367 +#else | |
| 368 + | |
| 369 +#define SQLITE_EXTENSION_INIT1 | |
| 370 +#define SQLITE_EXTENSION_INIT2(v) | |
| 371 + | |
| 372 +#endif /* SQLITE_CORE */ | |
| 373 + | |
| 374 #endif /* _SQLITE3EXT_H_ */ | |
| 375 Index: src/test_autoext.c | |
| 376 =================================================================== | |
| 377 --- src/test_autoext.c 2009-09-03 13:32:06.000000000 -0700 | |
| 378 +++ src/test_autoext.c 2009-09-15 18:14:35.000000000 -0700 | |
| 379 @@ -17,7 +17,9 @@ | |
| 380 #include "sqlite3ext.h" | |
| 381 | |
| 382 #ifndef SQLITE_OMIT_LOAD_EXTENSION | |
| 383 +#ifndef SQLITE_CORE | |
| 384 static SQLITE_EXTENSION_INIT1 | |
| 385 +#endif | |
| 386 | |
| 387 /* | |
| 388 ** The sqr() SQL function returns the square of its input value. | |
| 389 Index: src/quick.test | |
| 390 =================================================================== | |
| 391 --- test/quick.test 2009-09-04 13:37:44.000000000 -0700 | |
| 392 +++ test/quick.test 2009-09-15 11:34:54.000000000 -0700 | |
| 393 @@ -58,6 +58,9 @@ | |
| 394 crash7.test | |
| 395 delete3.test | |
| 396 fts3.test | |
| 397 + fts.test | |
| 398 + fts1.test | |
| 399 + fts2.test | |
| 400 fuzz.test | |
| 401 fuzz3.test | |
| 402 fuzz_malloc.test | |
| 403 Index: src/os_symbian.cc | |
| 404 =================================================================== | |
| 405 --- src/os_symbian.cc 1969-12-31 16:00:00.000000000 -0800 | |
| 406 +++ src/os_symbian.cc 2009-07-01 12:08:37.000000000 -0700 | |
| 407 @@ -0,0 +1,579 @@ | |
| 408 +// Copyright 2008, Google Inc. | |
| 409 +// | |
| 410 +// Redistribution and use in source and binary forms, with or without | |
| 411 +// modification, are permitted provided that the following conditions are met: | |
| 412 +// | |
| 413 +// 1. Redistributions of source code must retain the above copyright notice, | |
| 414 +// this list of conditions and the following disclaimer. | |
| 415 +// 2. Redistributions in binary form must reproduce the above copyright notice
, | |
| 416 +// this list of conditions and the following disclaimer in the documentatio
n | |
| 417 +// and/or other materials provided with the distribution. | |
| 418 +// 3. Neither the name of Google Inc. nor the names of its contributors may be | |
| 419 +// used to endorse or promote products derived from this software without | |
| 420 +// specific prior written permission. | |
| 421 +// | |
| 422 +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
| 423 +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
| 424 +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
| 425 +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 426 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 427 +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
| 428 +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
| 429 +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
| 430 +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
| 431 +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 432 + | |
| 433 +// This file contains code that is specific to Symbian. | |
| 434 +// Differently from the rest of SQLite, it is implemented in C++ as this is | |
| 435 +// the native language of the OS and all interfaces we need to use are C++. | |
| 436 +// | |
| 437 +// This file follows the Gears code style guidelines. | |
| 438 + | |
| 439 +#ifdef OS_SYMBIAN | |
| 440 +#include <coemain.h> | |
| 441 +#include <e32math.h> | |
| 442 +#include <f32file.h> | |
| 443 +#include <utf.h> | |
| 444 + | |
| 445 +extern "C" { | |
| 446 +#include "sqliteInt.h" | |
| 447 +#include "os_common.h" | |
| 448 +} | |
| 449 + | |
| 450 +const TInt kFileLockAttempts = 3; | |
| 451 + | |
| 452 +// The global file system session. | |
| 453 +RFs g_fs_session; | |
| 454 + | |
| 455 +static TInt UTF8ToUTF16(const char *in, TDes *out16) { | |
| 456 + assert(in); | |
| 457 + TPtrC8 in_des(reinterpret_cast<const unsigned char*>(in)); | |
| 458 + return CnvUtfConverter::ConvertToUnicodeFromUtf8(*out16, in_des); | |
| 459 +} | |
| 460 + | |
| 461 +static TInt UTF16ToUTF8(const TDesC16& in16, TDes8 *out8) { | |
| 462 + return CnvUtfConverter::ConvertFromUnicodeToUtf8(*out8, in16); | |
| 463 +} | |
| 464 + | |
| 465 +// The SymbianFile structure is a subclass of sqlite3_file* specific to the | |
| 466 +// Symbian portability layer. | |
| 467 +struct SymbianFile { | |
| 468 + const sqlite3_io_methods *methods; | |
| 469 + RFile handle; // The file handle | |
| 470 + TUint8 lock_type; // Type of lock currently held on this file | |
| 471 + TUint16 shared_lock_byte; // Randomly chosen byte used as a shared lock | |
| 472 +}; | |
| 473 + | |
| 474 +static SymbianFile* ConvertToSymbianFile(sqlite3_file* const id) { | |
| 475 + assert(id); | |
| 476 + return reinterpret_cast<SymbianFile*>(id); | |
| 477 +} | |
| 478 + | |
| 479 +static int SymbianClose(sqlite3_file *id) { | |
| 480 + SymbianFile *file_id = ConvertToSymbianFile(id); | |
| 481 + file_id->handle.Close(); | |
| 482 + OpenCounter(-1); | |
| 483 + return SQLITE_OK; | |
| 484 +} | |
| 485 + | |
| 486 +static int SymbianRead(sqlite3_file *id, | |
| 487 + void *buffer, | |
| 488 + int amount, | |
| 489 + sqlite3_int64 offset) { | |
| 490 + assert(buffer); | |
| 491 + assert(amount >=0); | |
| 492 + assert(offset >=0); | |
| 493 + | |
| 494 + SymbianFile* file_id = ConvertToSymbianFile(id); | |
| 495 + TPtr8 dest(static_cast<unsigned char*>(buffer), amount); | |
| 496 + | |
| 497 + if (KErrNone == file_id->handle.Read(offset, dest, amount)) { | |
| 498 + if (dest.Length() == amount) { | |
| 499 + return SQLITE_OK; | |
| 500 + } else { | |
| 501 + return SQLITE_IOERR_SHORT_READ; | |
| 502 + } | |
| 503 + } else { | |
| 504 + return SQLITE_IOERR; | |
| 505 + } | |
| 506 +} | |
| 507 + | |
| 508 +static int SymbianWrite(sqlite3_file *id, | |
| 509 + const void *buffer, | |
| 510 + int amount, | |
| 511 + sqlite3_int64 offset) { | |
| 512 + assert(buffer); | |
| 513 + assert(amount >=0); | |
| 514 + assert(offset >=0); | |
| 515 + | |
| 516 + SymbianFile *file_id = ConvertToSymbianFile(id); | |
| 517 + TPtrC8 src(static_cast<const unsigned char*>(buffer), amount); | |
| 518 + if (file_id->handle.Write(offset, src) != KErrNone) { | |
| 519 + return SQLITE_IOERR_WRITE; | |
| 520 + } | |
| 521 + | |
| 522 + return SQLITE_OK; | |
| 523 +} | |
| 524 + | |
| 525 +static int SymbianTruncate(sqlite3_file *id, sqlite3_int64 bytes) { | |
| 526 + assert(bytes >=0); | |
| 527 + | |
| 528 + SymbianFile *file_id = ConvertToSymbianFile(id); | |
| 529 + if (file_id->handle.SetSize(bytes) != KErrNone) { | |
| 530 + return SQLITE_IOERR; | |
| 531 + } | |
| 532 + return SQLITE_OK; | |
| 533 +} | |
| 534 + | |
| 535 +static int SymbianSync(sqlite3_file *id, int /*flags*/) { | |
| 536 + SymbianFile *file_id = ConvertToSymbianFile(id); | |
| 537 + if (file_id->handle.Flush() != KErrNone) { | |
| 538 + return SQLITE_IOERR; | |
| 539 + } else { | |
| 540 + return SQLITE_OK; | |
| 541 + } | |
| 542 +} | |
| 543 + | |
| 544 +static int SymbianFileSize(sqlite3_file *id, sqlite3_int64 *size) { | |
| 545 + assert(size); | |
| 546 + | |
| 547 + SymbianFile *file_id = ConvertToSymbianFile(id); | |
| 548 + TInt size_tmp; | |
| 549 + if (file_id->handle.Size(size_tmp) != KErrNone) { | |
| 550 + return SQLITE_IOERR; | |
| 551 + } | |
| 552 + *size = size_tmp; | |
| 553 + return SQLITE_OK; | |
| 554 +} | |
| 555 + | |
| 556 +// File lock/unlock functions; see os_win.c for a description | |
| 557 +// of the algorithm used. | |
| 558 +static int GetReadLock(SymbianFile *file) { | |
| 559 + file->shared_lock_byte = Math::Random() % (SHARED_SIZE - 1); | |
| 560 + return file->handle.Lock(SHARED_FIRST + file->shared_lock_byte, 1); | |
| 561 +} | |
| 562 + | |
| 563 +static int UnlockReadLock(SymbianFile *file) { | |
| 564 + return file->handle.UnLock(SHARED_FIRST + file->shared_lock_byte, 1); | |
| 565 +} | |
| 566 + | |
| 567 +static int SymbianLock(sqlite3_file *id, int lock_type) { | |
| 568 + SymbianFile *file = ConvertToSymbianFile(id); | |
| 569 + if (file->lock_type >= lock_type) { | |
| 570 + return SQLITE_OK; | |
| 571 + } | |
| 572 + | |
| 573 + // Make sure the locking sequence is correct | |
| 574 + assert(file->lock_type != NO_LOCK || lock_type == SHARED_LOCK); | |
| 575 + assert(lock_type != PENDING_LOCK); | |
| 576 + assert(lock_type != RESERVED_LOCK || file->lock_type == SHARED_LOCK); | |
| 577 + | |
| 578 + // Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or | |
| 579 + // a SHARED lock. If we are acquiring a SHARED lock, the acquisition of | |
| 580 + // the PENDING_LOCK byte is temporary. | |
| 581 + int new_lock_type = file->lock_type; | |
| 582 + int got_pending_lock = 0; | |
| 583 + int res = KErrNone; | |
| 584 + if (file->lock_type == NO_LOCK || | |
| 585 + (lock_type == EXCLUSIVE_LOCK && file->lock_type == RESERVED_LOCK)) { | |
| 586 + int count = kFileLockAttempts; | |
| 587 + while (count-- > 0 && | |
| 588 + (res = file->handle.Lock(PENDING_BYTE, 1)) != KErrNone ) { | |
| 589 + // Try 3 times to get the pending lock. The pending lock might be | |
| 590 + // held by another reader process who will release it momentarily. | |
| 591 + OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt); | |
| 592 + User::After(1000); | |
| 593 + } | |
| 594 + got_pending_lock = (res == KErrNone? 1 : 0); | |
| 595 + } | |
| 596 + | |
| 597 + // Acquire a shared lock | |
| 598 + if (lock_type == SHARED_LOCK && res == KErrNone) { | |
| 599 + assert(file->lock_type == NO_LOCK); | |
| 600 + res = GetReadLock(file); | |
| 601 + if (res == KErrNone) { | |
| 602 + new_lock_type = SHARED_LOCK; | |
| 603 + } | |
| 604 + } | |
| 605 + | |
| 606 + // Acquire a RESERVED lock | |
| 607 + if (lock_type == RESERVED_LOCK && res == KErrNone) { | |
| 608 + assert(file->lock_type == SHARED_LOCK); | |
| 609 + res = file->handle.Lock(RESERVED_BYTE, 1); | |
| 610 + if (res == KErrNone) { | |
| 611 + new_lock_type = RESERVED_LOCK; | |
| 612 + } | |
| 613 + } | |
| 614 + | |
| 615 + // Acquire a PENDING lock | |
| 616 + if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) { | |
| 617 + new_lock_type = PENDING_LOCK; | |
| 618 + got_pending_lock = 0; | |
| 619 + } | |
| 620 + | |
| 621 + // Acquire an EXCLUSIVE lock | |
| 622 + if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) { | |
| 623 + assert(file->lock_type >= SHARED_LOCK); | |
| 624 + res = UnlockReadLock(file); | |
| 625 + OSTRACE2("unreadlock = %d\n", res); | |
| 626 + res = file->handle.Lock(SHARED_FIRST, SHARED_SIZE); | |
| 627 + if (res == KErrNone) { | |
| 628 + new_lock_type = EXCLUSIVE_LOCK; | |
| 629 + } else { | |
| 630 + OSTRACE2("error-code = %d\n", GetLastError()); | |
| 631 + GetReadLock(file); | |
| 632 + } | |
| 633 + } | |
| 634 + | |
| 635 + // If we are holding a PENDING lock that ought to be released, then | |
| 636 + // release it now. | |
| 637 + if (got_pending_lock && lock_type == SHARED_LOCK) { | |
| 638 + file->handle.UnLock(PENDING_BYTE, 1); | |
| 639 + } | |
| 640 + | |
| 641 + // Update the state of the lock held in the file descriptor, then | |
| 642 + // return the appropriate result code. | |
| 643 + file->lock_type = new_lock_type; | |
| 644 + if (res == KErrNone) { | |
| 645 + return SQLITE_OK; | |
| 646 + } else { | |
| 647 + OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", file->handle, | |
| 648 + lock_type, new_lock_type); | |
| 649 + return SQLITE_BUSY; | |
| 650 + } | |
| 651 +} | |
| 652 + | |
| 653 +static int SymbianUnlock(sqlite3_file *id, int lock_type) { | |
| 654 + int type; | |
| 655 + int rc = SQLITE_OK; | |
| 656 + SymbianFile *file = ConvertToSymbianFile(id); | |
| 657 + assert(lock_type <= SHARED_LOCK); | |
| 658 + OSTRACE5("UNLOCK %d to %d was %d(%d)\n", file->handle, lock_type, | |
| 659 + file->lock_type, file->shared_lock_byte); | |
| 660 + type = file->lock_type; | |
| 661 + if (type >= EXCLUSIVE_LOCK) { | |
| 662 + file->handle.UnLock(SHARED_FIRST, SHARED_SIZE); | |
| 663 + if (lock_type == SHARED_LOCK && GetReadLock(file) != KErrNone) { | |
| 664 + // This should never happen. We should always be able to | |
| 665 + // reacquire the read lock | |
| 666 + rc = SQLITE_IOERR_UNLOCK; | |
| 667 + } | |
| 668 + } | |
| 669 + if (type >= RESERVED_LOCK) { | |
| 670 + file->handle.UnLock(RESERVED_BYTE, 1); | |
| 671 + } | |
| 672 + if (lock_type == NO_LOCK && type >= SHARED_LOCK) { | |
| 673 + UnlockReadLock(file); | |
| 674 + } | |
| 675 + if (type >= PENDING_LOCK) { | |
| 676 + file->handle.UnLock(PENDING_BYTE, 1); | |
| 677 + } | |
| 678 + file->lock_type = lock_type; | |
| 679 + return rc; | |
| 680 +} | |
| 681 + | |
| 682 +static int SymbianCheckReservedLock(sqlite3_file *id, int *result) { | |
| 683 + int rc; | |
| 684 + SymbianFile *file = ConvertToSymbianFile(id); | |
| 685 + if (file->lock_type >= RESERVED_LOCK) { | |
| 686 + rc = 1; | |
| 687 + OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc); | |
| 688 + } else { | |
| 689 + rc = file->handle.Lock(RESERVED_BYTE, 1); | |
| 690 + if (rc == KErrNone) { | |
| 691 + file->handle.UnLock(RESERVED_BYTE, 1); | |
| 692 + } | |
| 693 + rc = !rc; | |
| 694 + OSTRACE3("TEST WR-LOCK %d %d (remote)\n", file->handle, rc); | |
| 695 + } | |
| 696 + *result = rc; | |
| 697 + return SQLITE_OK; | |
| 698 +} | |
| 699 + | |
| 700 +static int SymbianFileControl(sqlite3_file */*id*/, | |
| 701 + int /*op*/, | |
| 702 + void */*arg*/) { | |
| 703 + return SQLITE_OK; | |
| 704 +} | |
| 705 + | |
| 706 +static int SymbianSectorSize(sqlite3_file */*id*/) { | |
| 707 + return SQLITE_DEFAULT_SECTOR_SIZE; | |
| 708 +} | |
| 709 + | |
| 710 +static int SymbianDeviceCharacteristics(sqlite3_file */*id*/) { | |
| 711 + return 0; | |
| 712 +} | |
| 713 + | |
| 714 +/* | |
| 715 +** This vector defines all the methods that can operate on a | |
| 716 +** sqlite3_file for Symbian. | |
| 717 +*/ | |
| 718 +static const sqlite3_io_methods SymbianIoMethod = { | |
| 719 + 1, // iVersion | |
| 720 + SymbianClose, | |
| 721 + SymbianRead, | |
| 722 + SymbianWrite, | |
| 723 + SymbianTruncate, | |
| 724 + SymbianSync, | |
| 725 + SymbianFileSize, | |
| 726 + SymbianLock, | |
| 727 + SymbianUnlock, | |
| 728 + SymbianCheckReservedLock, | |
| 729 + SymbianFileControl, | |
| 730 + SymbianSectorSize, | |
| 731 + SymbianDeviceCharacteristics | |
| 732 +}; | |
| 733 + | |
| 734 +// ============================================================================ | |
| 735 +// vfs methods begin here | |
| 736 +// ============================================================================ | |
| 737 +static int SymbianOpen(sqlite3_vfs */*vfs*/, | |
| 738 + const char *name, | |
| 739 + sqlite3_file *id, | |
| 740 + int flags, | |
| 741 + int *out_flags) { | |
| 742 + TUint desired_access; | |
| 743 + TUint share_mode; | |
| 744 + TInt err = KErrNone; | |
| 745 + TFileName name_utf16; | |
| 746 + SymbianFile *file = ConvertToSymbianFile(id); | |
| 747 + | |
| 748 + if (out_flags) { | |
| 749 + *out_flags = flags; | |
| 750 + } | |
| 751 + | |
| 752 + // if the name is NULL we have to open a temporary file. | |
| 753 + if (!name) { | |
| 754 + TPath private_path; | |
| 755 + TFileName file_name; | |
| 756 + if (g_fs_session.PrivatePath(private_path) != KErrNone) { | |
| 757 + return SQLITE_CANTOPEN; | |
| 758 + } | |
| 759 + if (file->handle.Temp(g_fs_session, | |
| 760 + private_path, | |
| 761 + file_name, | |
| 762 + EFileWrite) != | |
| 763 + KErrNone) { | |
| 764 + return SQLITE_CANTOPEN; | |
| 765 + } | |
| 766 + file->methods = &SymbianIoMethod; | |
| 767 + file->lock_type = NO_LOCK; | |
| 768 + file->shared_lock_byte = 0; | |
| 769 + OpenCounter(+1); | |
| 770 + return SQLITE_OK; | |
| 771 + } | |
| 772 + | |
| 773 + if (UTF8ToUTF16(name, &name_utf16) != KErrNone) | |
| 774 + return SQLITE_CANTOPEN; | |
| 775 + | |
| 776 + if (flags & SQLITE_OPEN_READWRITE) { | |
| 777 + desired_access = EFileWrite; | |
| 778 + } else { | |
| 779 + desired_access = EFileRead; | |
| 780 + } | |
| 781 + if (flags & SQLITE_OPEN_MAIN_DB) { | |
| 782 + share_mode = EFileShareReadersOrWriters; | |
| 783 + } else { | |
| 784 + share_mode = 0; | |
| 785 + } | |
| 786 + | |
| 787 + if (flags & SQLITE_OPEN_CREATE) { | |
| 788 + err = file->handle.Create(g_fs_session, | |
| 789 + name_utf16, | |
| 790 + desired_access | share_mode); | |
| 791 + if (err != KErrNone && err != KErrAlreadyExists) { | |
| 792 + return SQLITE_CANTOPEN; | |
| 793 + } | |
| 794 + } | |
| 795 + | |
| 796 + if (err != KErrNone) { | |
| 797 + err = file->handle.Open(g_fs_session, | |
| 798 + name_utf16, | |
| 799 + desired_access | share_mode); | |
| 800 + if (err != KErrNone && flags & SQLITE_OPEN_READWRITE) { | |
| 801 + if (out_flags) { | |
| 802 + *out_flags = (flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE; | |
| 803 + } | |
| 804 + desired_access = EFileRead; | |
| 805 + err = file->handle.Open(g_fs_session, | |
| 806 + name_utf16, | |
| 807 + desired_access | share_mode); | |
| 808 + } | |
| 809 + if (err != KErrNone) { | |
| 810 + return SQLITE_CANTOPEN; | |
| 811 + } | |
| 812 + } | |
| 813 + file->methods = &SymbianIoMethod; | |
| 814 + file->lock_type = NO_LOCK; | |
| 815 + file->shared_lock_byte = 0; | |
| 816 + OpenCounter(+1); | |
| 817 + return SQLITE_OK; | |
| 818 +} | |
| 819 + | |
| 820 +static int SymbianDelete(sqlite3_vfs */*vfs*/, | |
| 821 + const char *file_name, | |
| 822 + int /*sync_dir*/) { | |
| 823 + assert(file_name); | |
| 824 + TFileName file_name_utf16; | |
| 825 + | |
| 826 + if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) { | |
| 827 + return SQLITE_ERROR; | |
| 828 + } | |
| 829 + | |
| 830 + TInt result = g_fs_session.Delete(file_name_utf16); | |
| 831 + return (result == KErrNone || result == KErrPathNotFound)? | |
| 832 + SQLITE_OK : SQLITE_IOERR_DELETE; | |
| 833 +} | |
| 834 + | |
| 835 +static int SymbianAccess(sqlite3_vfs */*vfs*/, | |
| 836 + const char *file_name, | |
| 837 + int flags, | |
| 838 + int *result) { | |
| 839 + assert(file_name); | |
| 840 + TEntry entry; | |
| 841 + TFileName file_name_utf16; | |
| 842 + | |
| 843 + if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) { | |
| 844 + return SQLITE_ERROR; | |
| 845 + } | |
| 846 + | |
| 847 + if (g_fs_session.Entry(file_name_utf16, entry) != KErrNone) { | |
| 848 + *result = 0; | |
| 849 + return SQLITE_OK; | |
| 850 + } | |
| 851 + | |
| 852 + switch (flags) { | |
| 853 + case SQLITE_ACCESS_READ: | |
| 854 + case SQLITE_ACCESS_EXISTS: | |
| 855 + *result = !entry.IsDir(); | |
| 856 + break; | |
| 857 + case SQLITE_ACCESS_READWRITE: | |
| 858 + *result = !entry.IsDir() && !entry.IsReadOnly(); | |
| 859 + break; | |
| 860 + default: | |
| 861 + return SQLITE_ERROR; | |
| 862 + } | |
| 863 + | |
| 864 + return SQLITE_OK; | |
| 865 +} | |
| 866 + | |
| 867 +static int SymbianFullPathname(sqlite3_vfs */*vfs*/, | |
| 868 + const char *relative, | |
| 869 + int full_len, | |
| 870 + char *full) { | |
| 871 + assert(relative); | |
| 872 + assert(full); | |
| 873 + | |
| 874 + TParse parse; | |
| 875 + TPath relative_utf16; | |
| 876 + TPath base_path; | |
| 877 + TPtr8 full_utf8(reinterpret_cast<unsigned char*>(full), full_len); | |
| 878 + | |
| 879 + g_fs_session.PrivatePath(base_path); | |
| 880 + | |
| 881 + if (UTF8ToUTF16(relative, &relative_utf16) != KErrNone) { | |
| 882 + return SQLITE_ERROR; | |
| 883 + } | |
| 884 + | |
| 885 + if (parse.Set(relative_utf16, &base_path, NULL) != KErrNone) { | |
| 886 + return SQLITE_ERROR; | |
| 887 + } | |
| 888 + | |
| 889 + TDesC full_utf16(parse.FullName()); | |
| 890 + if (UTF16ToUTF8(relative_utf16, &full_utf8) != KErrNone) { | |
| 891 + return SQLITE_ERROR; | |
| 892 + } | |
| 893 + | |
| 894 + full_utf8.PtrZ(); | |
| 895 + return SQLITE_OK; | |
| 896 +} | |
| 897 + | |
| 898 +static int SymbianRandomness(sqlite3_vfs */*vfs*/, int buf_len, char *buffer) { | |
| 899 + assert(buffer); | |
| 900 + TInt64 seed = User::TickCount(); | |
| 901 + for (TInt i = 0; i < buf_len; i++) { | |
| 902 + buffer[i] = Math::Rand(seed) % 255; | |
| 903 + } | |
| 904 + return SQLITE_OK; | |
| 905 +} | |
| 906 + | |
| 907 +static int SymbianSleep(sqlite3_vfs */*vfs*/, int microsec) { | |
| 908 + User::After(microsec); | |
| 909 + return SQLITE_OK; | |
| 910 +} | |
| 911 + | |
| 912 +int SymbianCurrentTime(sqlite3_vfs */*vfs*/, double *now) { | |
| 913 + _LIT(kEpoch, "19700101:000000.000000"); | |
| 914 + assert(now); | |
| 915 + TTime time; | |
| 916 + TTime epoch_time(kEpoch); | |
| 917 + TTimeIntervalSeconds interval; | |
| 918 + | |
| 919 + time.HomeTime(); | |
| 920 + // calculate seconds elapsed since 1-1-1970 | |
| 921 + time.SecondsFrom(epoch_time, interval); | |
| 922 + | |
| 923 + // Julian date @ 1-1-1970 = 2440587.5 | |
| 924 + // seconds per day = 86400.0 | |
| 925 + *now = interval.Int()/86400.0 + 2440587.5; | |
| 926 + return SQLITE_OK; | |
| 927 +} | |
| 928 + | |
| 929 +static int SymbianGetLastError(sqlite3_vfs */*vfs*/, | |
| 930 + int /*buf_len*/, | |
| 931 + char */*buf*/) { | |
| 932 + assert(buf[0] == '\0'); | |
| 933 + return 0; | |
| 934 +} | |
| 935 + | |
| 936 +// Interfaces for opening a shared library, finding entry points | |
| 937 +// within the shared library, and closing the shared library. | |
| 938 +// TODO(marcogelmi): implement. | |
| 939 +#define SymbianDlOpen 0 | |
| 940 +#define SymbianDlError 0 | |
| 941 +#define SymbianDlSym 0 | |
| 942 +#define SymbianDlClose 0 | |
| 943 + | |
| 944 +// Initialize and deinitialize the operating system interface. | |
| 945 +int sqlite3_os_init(void) { | |
| 946 + static sqlite3_vfs symbian_vfs = { | |
| 947 + 1, // iVersion | |
| 948 + sizeof(SymbianFile), // szOsFile | |
| 949 + KMaxPath, // mxPathname | |
| 950 + 0, // pNext | |
| 951 + "symbian", // name | |
| 952 + 0, // pAppData | |
| 953 + | |
| 954 + SymbianOpen, // xOpen | |
| 955 + SymbianDelete, // xDelete | |
| 956 + SymbianAccess, // xAccess | |
| 957 + SymbianFullPathname, // xFullPathname | |
| 958 + SymbianDlOpen, // xDlOpen | |
| 959 + SymbianDlError, // xDlError | |
| 960 + SymbianDlSym, // xDlSym | |
| 961 + SymbianDlClose, // xDlClose | |
| 962 + SymbianRandomness, // xRandomness | |
| 963 + SymbianSleep, // xSleep | |
| 964 + SymbianCurrentTime, // xCurrentTime | |
| 965 + SymbianGetLastError // xGetLastError | |
| 966 + }; | |
| 967 + | |
| 968 + if (g_fs_session.Connect() != KErrNone) { | |
| 969 + return SQLITE_ERROR; | |
| 970 + } | |
| 971 + | |
| 972 + if (g_fs_session.ShareAuto() != KErrNone) { | |
| 973 + g_fs_session.Close(); | |
| 974 + return SQLITE_ERROR; | |
| 975 + } | |
| 976 + | |
| 977 + sqlite3_vfs_register(&symbian_vfs, 1); | |
| 978 + return SQLITE_OK; | |
| 979 +} | |
| 980 + | |
| 981 +int sqlite3_os_end(void) { | |
| 982 + g_fs_session.Close(); | |
| 983 + return SQLITE_OK; | |
| 984 +} | |
| 985 + | |
| 986 +#endif /* OS_SYMBIAN*/ | |
| 987 Index: src/shell_icu_linux.c | |
| 988 =================================================================== | |
| 989 --- src/shell_icu_linux.c 1969-12-31 16:00:00.000000000 -0800 | |
| 990 +++ src/shell_icu_linux.c 2009-09-17 13:48:49.000000000 -0700 | |
| 991 @@ -0,0 +1,26 @@ | |
| 992 +/* Copyright 2007 Google Inc. All Rights Reserved. | |
| 993 +**/ | |
| 994 + | |
| 995 +#include <limits.h> | |
| 996 +#include <unistd.h> | |
| 997 +#include "unicode/udata.h" | |
| 998 + | |
| 999 +/* | |
| 1000 +** This function attempts to load the ICU data tables from a data file. | |
| 1001 +** Returns 0 on failure, nonzero on success. | |
| 1002 +** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. | |
| 1003 +*/ | |
| 1004 +int sqlite_shell_init_icu() { | |
| 1005 + char bin_dir[PATH_MAX + 1]; | |
| 1006 + int bin_dir_size = readlink("/proc/self/exe", bin_dir, PATH_MAX); | |
| 1007 + if (bin_dir_size < 0 || bin_dir_size > PATH_MAX) | |
| 1008 + return 0; | |
| 1009 + bin_dir[bin_dir_size] = 0;; | |
| 1010 + | |
| 1011 + u_setDataDirectory(bin_dir); | |
| 1012 + // Only look for the packaged data file; | |
| 1013 + // the default behavior is to look for individual files. | |
| 1014 + UErrorCode err = U_ZERO_ERROR; | |
| 1015 + udata_setFileAccess(UDATA_ONLY_PACKAGES, &err); | |
| 1016 + return err == U_ZERO_ERROR; | |
| 1017 +} | |
| 1018 Index: src/shell_icu_win.c | |
| 1019 =================================================================== | |
| 1020 --- src/shell_icu_win.c 1969-12-31 16:00:00.000000000 -0800 | |
| 1021 +++ src/shell_icu_win.c 2011-03-03 14:29:11.000000000 -0700 | |
| 1022 @@ -0,0 +1,32 @@ | |
| 1023 +/* Copyright 2011 Google Inc. All Rights Reserved. | |
| 1024 +**/ | |
| 1025 + | |
| 1026 +#include <windows.h> | |
| 1027 +#include "unicode/udata.h" | |
| 1028 + | |
| 1029 +/* | |
| 1030 +** This function attempts to load the ICU data tables from a DLL. | |
| 1031 +** Returns 0 on failure, nonzero on success. | |
| 1032 +** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. | |
| 1033 +*/ | |
| 1034 + | |
| 1035 +#define ICU_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" | |
| 1036 +int sqlite_shell_init_icu() { | |
| 1037 + HMODULE module; | |
| 1038 + FARPROC addr; | |
| 1039 + UErrorCode err; | |
| 1040 + | |
| 1041 + // Chrome dropped U_ICU_VERSION_SHORT from the icu data dll name. | |
| 1042 + module = LoadLibrary(L"icudt.dll"); | |
| 1043 + if (!module) | |
| 1044 + return 0; | |
| 1045 + | |
| 1046 + addr = GetProcAddress(module, ICU_DATA_SYMBOL); | |
| 1047 + if (!addr) | |
| 1048 + return 0; | |
| 1049 + | |
| 1050 + err = U_ZERO_ERROR; | |
| 1051 + udata_setCommonData(addr, &err); | |
| 1052 + | |
| 1053 + return 1; | |
| 1054 +} | |
| 1055 Index: test/fts.test | |
| 1056 =================================================================== | |
| 1057 --- test/fts.test 1969-12-31 16:00:00.000000000 -0800 | |
| 1058 +++ test/fts.test 2009-07-01 12:08:39.000000000 -0700 | |
| 1059 @@ -0,0 +1,61 @@ | |
| 1060 +# | |
| 1061 +# May you do good and not evil. | |
| 1062 +# May you find forgiveness for yourself and forgive others. | |
| 1063 +# May you share freely, never taking more than you give. | |
| 1064 +# | |
| 1065 +#*********************************************************************** | |
| 1066 +# This file runs the fts tests. | |
| 1067 +# | |
| 1068 +# $Id$ | |
| 1069 + | |
| 1070 +proc lshift {lvar} { | |
| 1071 + upvar $lvar l | |
| 1072 + set ret [lindex $l 0] | |
| 1073 + set l [lrange $l 1 end] | |
| 1074 + return $ret | |
| 1075 +} | |
| 1076 +while {[set arg [lshift argv]] != ""} { | |
| 1077 + switch -- $arg { | |
| 1078 + -sharedpagercache { | |
| 1079 + sqlite3_enable_shared_cache 1 | |
| 1080 + } | |
| 1081 + default { | |
| 1082 + set argv [linsert $argv 0 $arg] | |
| 1083 + break | |
| 1084 + } | |
| 1085 + } | |
| 1086 +} | |
| 1087 + | |
| 1088 +set testdir [file dirname $argv0] | |
| 1089 +source $testdir/tester.tcl | |
| 1090 +rename finish_test really_finish_test | |
| 1091 +proc finish_test {} {} | |
| 1092 +set ISQUICK 1 | |
| 1093 + | |
| 1094 +set EXCLUDE { | |
| 1095 + fts.test | |
| 1096 + fts1.test | |
| 1097 + fts2.test | |
| 1098 +} | |
| 1099 + | |
| 1100 +if {[sqlite3 -has-codec]} { | |
| 1101 + # lappend EXCLUDE \ | |
| 1102 + # conflict.test | |
| 1103 +} | |
| 1104 + | |
| 1105 +foreach testfile [lsort -dictionary [glob $testdir/fts*.test]] { | |
| 1106 + set tail [file tail $testfile] | |
| 1107 + puts "test: $tail" | |
| 1108 + if {[lsearch -exact $EXCLUDE $tail]>=0} continue | |
| 1109 + source $testfile | |
| 1110 + catch {db close} | |
| 1111 + if {$sqlite_open_file_count>0} { | |
| 1112 + puts "$tail did not close all files: $sqlite_open_file_count" | |
| 1113 + incr nErr | |
| 1114 + lappend ::failList $tail | |
| 1115 + } | |
| 1116 +} | |
| 1117 +source $testdir/misuse.test | |
| 1118 + | |
| 1119 +set sqlite_open_file_count 0 | |
| 1120 +really_finish_test | |
| 1121 Index: test/fts1.test | |
| 1122 =================================================================== | |
| 1123 --- test/fts1.test 1969-12-31 16:00:00.000000000 -0800 | |
| 1124 +++ test/fts1.test 2009-07-01 12:08:39.000000000 -0700 | |
| 1125 @@ -0,0 +1,61 @@ | |
| 1126 +# | |
| 1127 +# May you do good and not evil. | |
| 1128 +# May you find forgiveness for yourself and forgive others. | |
| 1129 +# May you share freely, never taking more than you give. | |
| 1130 +# | |
| 1131 +#*********************************************************************** | |
| 1132 +# This file runs the fts tests. | |
| 1133 +# | |
| 1134 +# $Id$ | |
| 1135 + | |
| 1136 +proc lshift {lvar} { | |
| 1137 + upvar $lvar l | |
| 1138 + set ret [lindex $l 0] | |
| 1139 + set l [lrange $l 1 end] | |
| 1140 + return $ret | |
| 1141 +} | |
| 1142 +while {[set arg [lshift argv]] != ""} { | |
| 1143 + switch -- $arg { | |
| 1144 + -sharedpagercache { | |
| 1145 + sqlite3_enable_shared_cache 1 | |
| 1146 + } | |
| 1147 + default { | |
| 1148 + set argv [linsert $argv 0 $arg] | |
| 1149 + break | |
| 1150 + } | |
| 1151 + } | |
| 1152 +} | |
| 1153 + | |
| 1154 +set testdir [file dirname $argv0] | |
| 1155 +source $testdir/tester.tcl | |
| 1156 +rename finish_test really_finish_test | |
| 1157 +proc finish_test {} {} | |
| 1158 +set ISQUICK 1 | |
| 1159 + | |
| 1160 +set EXCLUDE { | |
| 1161 + fts.test | |
| 1162 + fts1.test | |
| 1163 + fts2.test | |
| 1164 +} | |
| 1165 + | |
| 1166 +if {[sqlite3 -has-codec]} { | |
| 1167 + # lappend EXCLUDE \ | |
| 1168 + # conflict.test | |
| 1169 +} | |
| 1170 + | |
| 1171 +foreach testfile [lsort -dictionary [glob $testdir/fts1*.test]] { | |
| 1172 + set tail [file tail $testfile] | |
| 1173 + puts "test: $tail" | |
| 1174 + if {[lsearch -exact $EXCLUDE $tail]>=0} continue | |
| 1175 + source $testfile | |
| 1176 + catch {db close} | |
| 1177 + if {$sqlite_open_file_count>0} { | |
| 1178 + puts "$tail did not close all files: $sqlite_open_file_count" | |
| 1179 + incr nErr | |
| 1180 + lappend ::failList $tail | |
| 1181 + } | |
| 1182 +} | |
| 1183 +source $testdir/misuse.test | |
| 1184 + | |
| 1185 +set sqlite_open_file_count 0 | |
| 1186 +really_finish_test | |
| OLD | NEW |