summaryrefslogtreecommitdiffstats
path: root/third_party/sqlite
diff options
context:
space:
mode:
authormdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-23 21:12:36 +0000
committermdm@chromium.org <mdm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-23 21:12:36 +0000
commit1bb511df85359d5516b5478b51c0d328d9060f0c (patch)
treeb84b8c4922971ca3e731278e6eb5dcf9cbe210bb /third_party/sqlite
parent969d6633d60a2d37b9135d4149ab3b5b27b1144c (diff)
downloadchromium_src-1bb511df85359d5516b5478b51c0d328d9060f0c.zip
chromium_src-1bb511df85359d5516b5478b51c0d328d9060f0c.tar.gz
chromium_src-1bb511df85359d5516b5478b51c0d328d9060f0c.tar.bz2
Update documentation on how to merge in new SQLite versions. No code change.
BUG=none TEST=none Review URL: http://codereview.chromium.org/209058 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26986 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/sqlite')
-rw-r--r--third_party/sqlite/README.chromium82
-rwxr-xr-xthird_party/sqlite/google_update_sqlite.sh52
-rw-r--r--third_party/sqlite/misc.patch786
-rw-r--r--third_party/sqlite/safe-tolower.patch2
4 files changed, 835 insertions, 87 deletions
diff --git a/third_party/sqlite/README.chromium b/third_party/sqlite/README.chromium
index c393321..6e42b34 100644
--- a/third_party/sqlite/README.chromium
+++ b/third_party/sqlite/README.chromium
@@ -1,59 +1,73 @@
-Instructions for importing a new release of sqlite from sqlite.org.
+Instructions for importing a new release of SQLite from sqlite.org.
First, you need to be on Linux.
-Find the release you want at:
- http://www.sqlite.org/cvstrac/timeline
+# Determine the versions of the release you want and the release we currently
+# have. (See the VERSION file to determine which release we currently have.)
+# You may wish to consult http://www.sqlite.org/changes.html to find out what
+# changes have been made in each release.
+# Set some variables to remember the versions, e.g.:
+BASE=3.6.1
+LATEST=3.6.18
-Search for "Milestone", and find the appropriate release. Click
-through, and snag the "Date" for use in DATE line below.
-Unfortunately, the actual displayed date string on that page will not
-work, you have to make it YYYY/MM/DD. [TODO(shess) Determine if the
-fact that sqlite.org thinks it's running under UTC is relevant.]
+# Get to the src/third_party directory in your Chromium client:
+cd src/third_party
-DATE='2007/01/24 09:54:56'
+# Download the .tar.gz files for the releases:
+# (If the URL changes you might need to find the new one.)
+wget http://www.sqlite.org/sqlite-$BASE.tar.gz
+wget http://www.sqlite.org/sqlite-$LATEST.tar.gz
-# Get to the third_party/sqlite directory in your Chromium client.
-cd ../third_party/sqlite
+# Extract the vanilla current and desired versions:
+tar xzf sqlite-$BASE.tar.gz
+tar xzf sqlite-$LATEST.tar.gz
-# Run the super awesome automatic merge tool (requires kdiff3).
-# NOTE(shess): The following (which runs google_generate_preprocessed.sh) will
-# produce different output on grhat versus goobuntu; I've been running it on
-# goobuntu.
-./google_update_sqlite.sh "$DATE"
+# Use kdiff3 to merge the changes:
+kdiff3 -m sqlite-$BASE sqlite-$LATEST sqlite
# Resolve any conflicts. Figure out if we've got everything we should
# have (see below), or if we can omit any changes we no longer need.
+# Change to the sqlite directory:
+cd sqlite
+
+# Run the google_generate_preprocessed.sh script:
+./google_generate_preprocessed.sh
+
# Find a sucker. Send review.
# TODO(shess) Describe an appropriate comment style. Seems like it
-# should include the DATE line, and the sqlite version number.
-
+# should at least include the SQLite version number.
--------------------------------------------
-Why all this convolution? The problem being solved is that we want to
-harvest changes from the sqlite CVS tree, and merge them with any
-local changes we make. In CVS, you would do this using a "vendor
-import", which is essentially a branch dedictated to the vendor
-version which is merged with local changes.
+For reference, all of our local patches are also kept as .patch files in the
+sqlite directory. Here is a list of the patches, in the order they should be
+applied to a vanilla SQLite (of the version we currently have) to get, in
+principle, exactly what is checked in:
+
+misc.patch
+preload-cache.patch
+safe-tolower.patch
+sqlite-poison.patch
+
+So, e.g. you could do this to apply all our patches to vanilla SQLite:
+
+cd sqlite-$LATEST
+patch -p0 < ../sqlite/misc.patch
+patch -p0 < ../sqlite/preload-cache.patch
+patch -p0 < ../sqlite/safe-tolower.patch
+patch -p0 < ../sqlite/sqlite-poison.patch
-third_party/sqlite_vendor/... is the CVS checkout for a particular
-build from sqlite.org. third_party/sqlite_google/... is the local
-version, with our local modifications. So we update the sqlite_vendor
-tree, then use subversion to downintegrate changes into our
-locally-modified tree. The downintegrate will call out any
-conflicting changes, but will otherwise just merge things together.
-Basically, sqlite_vendor is a gateway between CVS and subversion.
+This will only be the case if all changes we make also update the corresponding
+patch files. Therefore please remember to do that whenever you make a change!
-Scott Hess <shess@google.com>, April 9, 2007.
-[Updated September 14, 2009.]
+Descriptions of the changes we've made can be found at the bottom of this file.
--------------------------------------------
-How to run the SQLite tests for the Gears version of SQLite on Linux.
+How to run the SQLite tests for the Chromium version of SQLite on Linux.
-cd ../third_party/sqlite_google/
+cd src/third_party/sqlite
mkdir build
cd build
make -f ../Makefile.linux-gcc testfixture
diff --git a/third_party/sqlite/google_update_sqlite.sh b/third_party/sqlite/google_update_sqlite.sh
deleted file mode 100755
index 40d33b6..0000000
--- a/third_party/sqlite/google_update_sqlite.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-
-# NOTICE: sqlite is no longer kept in CVS. It is now stored in fossil, a VCS
-# built on top of sqlite (yay recursion). This script is kept as a reference
-# for how to manually do the merge.
-
-head -n 5 "$0"
-exit 1
-
-# A simple script to make it easier to merge in newer versions of sqlite.
-# It may not work perfectly, in which case, it at least serves as an outline
-# of the procedure to follow.
-
-if [ "$1" = "" ]; then
- echo "Usage: $0 <Date to pull from CVS> [<merge tool>]"
- echo "Example: $0 '2007/01/24 09:54:56'"
- exit 1
-fi
-
-if [ ! -f VERSION_DATE ]; then
- echo "You must run this script in the sqlite directory, i.e.:"
- echo "\$ ./google_update_sqlite.sh"
- exit 1
-fi
-
-if [ "$2" = "" ]; then
- MERGE="kdiff3 -m"
-fi
-
-BASE_DATE=`cat VERSION_DATE`
-NEW_DATE="$1"
-
-cd ..
-echo "_____ Logging in to sqlite.org CVS (log in as anonymous)..."
-cvs -d :pserver:anonymous@www.sqlite.org:/sqlite login
-cvs -d :pserver:anonymous@www.sqlite.org:/sqlite checkout -P -D "$BASE_DATE" -d sqlite-base sqlite
-cvs -d :pserver:anonymous@www.sqlite.org:/sqlite checkout -P -D "$NEW_DATE" -d sqlite-latest sqlite
-
-echo "_____ Removing CVS directories..."
-find sqlite-base -type d -name CVS -execdir rm -rf {} + -prune
-find sqlite-latest -type d -name CVS -execdir rm -rf {} + -prune
-
-echo "_____ Running merge tool..."
-$MERGE sqlite-base sqlite-latest sqlite
-
-cd sqlite
-
-echo "_____ Updating VERSION_DATE to be $NEW_DATE ..."
-echo $NEW_DATE > VERSION_DATE
-
-echo "_____ Processing generated files..."
-./google_generate_preprocessed.sh
diff --git a/third_party/sqlite/misc.patch b/third_party/sqlite/misc.patch
index 6fb35a2..09174a4 100644
--- a/third_party/sqlite/misc.patch
+++ b/third_party/sqlite/misc.patch
@@ -792,3 +792,789 @@ Index: src/quick.test
fuzz.test
fuzz3.test
fuzz_malloc.test
+Index: src/os_symbian.cc
+===================================================================
+--- src/os_symbian.cc 1969-12-31 16:00:00.000000000 -0800
++++ src/os_symbian.cc 2009-07-01 12:08:37.000000000 -0700
+@@ -0,0 +1,579 @@
++// Copyright 2008, Google Inc.
++//
++// Redistribution and use in source and binary forms, with or without
++// modification, are permitted provided that the following conditions are met:
++//
++// 1. Redistributions of source code must retain the above copyright notice,
++// this list of conditions and the following disclaimer.
++// 2. Redistributions in binary form must reproduce the above copyright notice,
++// this list of conditions and the following disclaimer in the documentation
++// and/or other materials provided with the distribution.
++// 3. Neither the name of Google Inc. nor the names of its contributors may be
++// used to endorse or promote products derived from this software without
++// specific prior written permission.
++//
++// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
++// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
++// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
++// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
++// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
++// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
++// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++
++// This file contains code that is specific to Symbian.
++// Differently from the rest of SQLite, it is implemented in C++ as this is
++// the native language of the OS and all interfaces we need to use are C++.
++//
++// This file follows the Gears code style guidelines.
++
++#ifdef OS_SYMBIAN
++#include <coemain.h>
++#include <e32math.h>
++#include <f32file.h>
++#include <utf.h>
++
++extern "C" {
++#include "sqliteInt.h"
++#include "os_common.h"
++}
++
++const TInt kFileLockAttempts = 3;
++
++// The global file system session.
++RFs g_fs_session;
++
++static TInt UTF8ToUTF16(const char *in, TDes *out16) {
++ assert(in);
++ TPtrC8 in_des(reinterpret_cast<const unsigned char*>(in));
++ return CnvUtfConverter::ConvertToUnicodeFromUtf8(*out16, in_des);
++}
++
++static TInt UTF16ToUTF8(const TDesC16& in16, TDes8 *out8) {
++ return CnvUtfConverter::ConvertFromUnicodeToUtf8(*out8, in16);
++}
++
++// The SymbianFile structure is a subclass of sqlite3_file* specific to the
++// Symbian portability layer.
++struct SymbianFile {
++ const sqlite3_io_methods *methods;
++ RFile handle; // The file handle
++ TUint8 lock_type; // Type of lock currently held on this file
++ TUint16 shared_lock_byte; // Randomly chosen byte used as a shared lock
++};
++
++static SymbianFile* ConvertToSymbianFile(sqlite3_file* const id) {
++ assert(id);
++ return reinterpret_cast<SymbianFile*>(id);
++}
++
++static int SymbianClose(sqlite3_file *id) {
++ SymbianFile *file_id = ConvertToSymbianFile(id);
++ file_id->handle.Close();
++ OpenCounter(-1);
++ return SQLITE_OK;
++}
++
++static int SymbianRead(sqlite3_file *id,
++ void *buffer,
++ int amount,
++ sqlite3_int64 offset) {
++ assert(buffer);
++ assert(amount >=0);
++ assert(offset >=0);
++
++ SymbianFile* file_id = ConvertToSymbianFile(id);
++ TPtr8 dest(static_cast<unsigned char*>(buffer), amount);
++
++ if (KErrNone == file_id->handle.Read(offset, dest, amount)) {
++ if (dest.Length() == amount) {
++ return SQLITE_OK;
++ } else {
++ return SQLITE_IOERR_SHORT_READ;
++ }
++ } else {
++ return SQLITE_IOERR;
++ }
++}
++
++static int SymbianWrite(sqlite3_file *id,
++ const void *buffer,
++ int amount,
++ sqlite3_int64 offset) {
++ assert(buffer);
++ assert(amount >=0);
++ assert(offset >=0);
++
++ SymbianFile *file_id = ConvertToSymbianFile(id);
++ TPtrC8 src(static_cast<const unsigned char*>(buffer), amount);
++ if (file_id->handle.Write(offset, src) != KErrNone) {
++ return SQLITE_IOERR_WRITE;
++ }
++
++ return SQLITE_OK;
++}
++
++static int SymbianTruncate(sqlite3_file *id, sqlite3_int64 bytes) {
++ assert(bytes >=0);
++
++ SymbianFile *file_id = ConvertToSymbianFile(id);
++ if (file_id->handle.SetSize(bytes) != KErrNone) {
++ return SQLITE_IOERR;
++ }
++ return SQLITE_OK;
++}
++
++static int SymbianSync(sqlite3_file *id, int /*flags*/) {
++ SymbianFile *file_id = ConvertToSymbianFile(id);
++ if (file_id->handle.Flush() != KErrNone) {
++ return SQLITE_IOERR;
++ } else {
++ return SQLITE_OK;
++ }
++}
++
++static int SymbianFileSize(sqlite3_file *id, sqlite3_int64 *size) {
++ assert(size);
++
++ SymbianFile *file_id = ConvertToSymbianFile(id);
++ TInt size_tmp;
++ if (file_id->handle.Size(size_tmp) != KErrNone) {
++ return SQLITE_IOERR;
++ }
++ *size = size_tmp;
++ return SQLITE_OK;
++}
++
++// File lock/unlock functions; see os_win.c for a description
++// of the algorithm used.
++static int GetReadLock(SymbianFile *file) {
++ file->shared_lock_byte = Math::Random() % (SHARED_SIZE - 1);
++ return file->handle.Lock(SHARED_FIRST + file->shared_lock_byte, 1);
++}
++
++static int UnlockReadLock(SymbianFile *file) {
++ return file->handle.UnLock(SHARED_FIRST + file->shared_lock_byte, 1);
++}
++
++static int SymbianLock(sqlite3_file *id, int lock_type) {
++ SymbianFile *file = ConvertToSymbianFile(id);
++ if (file->lock_type >= lock_type) {
++ return SQLITE_OK;
++ }
++
++ // Make sure the locking sequence is correct
++ assert(file->lock_type != NO_LOCK || lock_type == SHARED_LOCK);
++ assert(lock_type != PENDING_LOCK);
++ assert(lock_type != RESERVED_LOCK || file->lock_type == SHARED_LOCK);
++
++ // Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
++ // a SHARED lock. If we are acquiring a SHARED lock, the acquisition of
++ // the PENDING_LOCK byte is temporary.
++ int new_lock_type = file->lock_type;
++ int got_pending_lock = 0;
++ int res = KErrNone;
++ if (file->lock_type == NO_LOCK ||
++ (lock_type == EXCLUSIVE_LOCK && file->lock_type == RESERVED_LOCK)) {
++ int count = kFileLockAttempts;
++ while (count-- > 0 &&
++ (res = file->handle.Lock(PENDING_BYTE, 1)) != KErrNone ) {
++ // Try 3 times to get the pending lock. The pending lock might be
++ // held by another reader process who will release it momentarily.
++ OSTRACE2("could not get a PENDING lock. cnt=%d\n", cnt);
++ User::After(1000);
++ }
++ got_pending_lock = (res == KErrNone? 1 : 0);
++ }
++
++ // Acquire a shared lock
++ if (lock_type == SHARED_LOCK && res == KErrNone) {
++ assert(file->lock_type == NO_LOCK);
++ res = GetReadLock(file);
++ if (res == KErrNone) {
++ new_lock_type = SHARED_LOCK;
++ }
++ }
++
++ // Acquire a RESERVED lock
++ if (lock_type == RESERVED_LOCK && res == KErrNone) {
++ assert(file->lock_type == SHARED_LOCK);
++ res = file->handle.Lock(RESERVED_BYTE, 1);
++ if (res == KErrNone) {
++ new_lock_type = RESERVED_LOCK;
++ }
++ }
++
++ // Acquire a PENDING lock
++ if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) {
++ new_lock_type = PENDING_LOCK;
++ got_pending_lock = 0;
++ }
++
++ // Acquire an EXCLUSIVE lock
++ if (lock_type == EXCLUSIVE_LOCK && res == KErrNone) {
++ assert(file->lock_type >= SHARED_LOCK);
++ res = UnlockReadLock(file);
++ OSTRACE2("unreadlock = %d\n", res);
++ res = file->handle.Lock(SHARED_FIRST, SHARED_SIZE);
++ if (res == KErrNone) {
++ new_lock_type = EXCLUSIVE_LOCK;
++ } else {
++ OSTRACE2("error-code = %d\n", GetLastError());
++ GetReadLock(file);
++ }
++ }
++
++ // If we are holding a PENDING lock that ought to be released, then
++ // release it now.
++ if (got_pending_lock && lock_type == SHARED_LOCK) {
++ file->handle.UnLock(PENDING_BYTE, 1);
++ }
++
++ // Update the state of the lock held in the file descriptor, then
++ // return the appropriate result code.
++ file->lock_type = new_lock_type;
++ if (res == KErrNone) {
++ return SQLITE_OK;
++ } else {
++ OSTRACE4("LOCK FAILED %d trying for %d but got %d\n", file->handle,
++ lock_type, new_lock_type);
++ return SQLITE_BUSY;
++ }
++}
++
++static int SymbianUnlock(sqlite3_file *id, int lock_type) {
++ int type;
++ int rc = SQLITE_OK;
++ SymbianFile *file = ConvertToSymbianFile(id);
++ assert(lock_type <= SHARED_LOCK);
++ OSTRACE5("UNLOCK %d to %d was %d(%d)\n", file->handle, lock_type,
++ file->lock_type, file->shared_lock_byte);
++ type = file->lock_type;
++ if (type >= EXCLUSIVE_LOCK) {
++ file->handle.UnLock(SHARED_FIRST, SHARED_SIZE);
++ if (lock_type == SHARED_LOCK && GetReadLock(file) != KErrNone) {
++ // This should never happen. We should always be able to
++ // reacquire the read lock
++ rc = SQLITE_IOERR_UNLOCK;
++ }
++ }
++ if (type >= RESERVED_LOCK) {
++ file->handle.UnLock(RESERVED_BYTE, 1);
++ }
++ if (lock_type == NO_LOCK && type >= SHARED_LOCK) {
++ UnlockReadLock(file);
++ }
++ if (type >= PENDING_LOCK) {
++ file->handle.UnLock(PENDING_BYTE, 1);
++ }
++ file->lock_type = lock_type;
++ return rc;
++}
++
++static int SymbianCheckReservedLock(sqlite3_file *id, int *result) {
++ int rc;
++ SymbianFile *file = ConvertToSymbianFile(id);
++ if (file->lock_type >= RESERVED_LOCK) {
++ rc = 1;
++ OSTRACE3("TEST WR-LOCK %d %d (local)\n", pFile->h, rc);
++ } else {
++ rc = file->handle.Lock(RESERVED_BYTE, 1);
++ if (rc == KErrNone) {
++ file->handle.UnLock(RESERVED_BYTE, 1);
++ }
++ rc = !rc;
++ OSTRACE3("TEST WR-LOCK %d %d (remote)\n", file->handle, rc);
++ }
++ *result = rc;
++ return SQLITE_OK;
++}
++
++static int SymbianFileControl(sqlite3_file */*id*/,
++ int /*op*/,
++ void */*arg*/) {
++ return SQLITE_OK;
++}
++
++static int SymbianSectorSize(sqlite3_file */*id*/) {
++ return SQLITE_DEFAULT_SECTOR_SIZE;
++}
++
++static int SymbianDeviceCharacteristics(sqlite3_file */*id*/) {
++ return 0;
++}
++
++/*
++** This vector defines all the methods that can operate on a
++** sqlite3_file for Symbian.
++*/
++static const sqlite3_io_methods SymbianIoMethod = {
++ 1, // iVersion
++ SymbianClose,
++ SymbianRead,
++ SymbianWrite,
++ SymbianTruncate,
++ SymbianSync,
++ SymbianFileSize,
++ SymbianLock,
++ SymbianUnlock,
++ SymbianCheckReservedLock,
++ SymbianFileControl,
++ SymbianSectorSize,
++ SymbianDeviceCharacteristics
++};
++
++// ============================================================================
++// vfs methods begin here
++// ============================================================================
++static int SymbianOpen(sqlite3_vfs */*vfs*/,
++ const char *name,
++ sqlite3_file *id,
++ int flags,
++ int *out_flags) {
++ TUint desired_access;
++ TUint share_mode;
++ TInt err = KErrNone;
++ TFileName name_utf16;
++ SymbianFile *file = ConvertToSymbianFile(id);
++
++ if (out_flags) {
++ *out_flags = flags;
++ }
++
++ // if the name is NULL we have to open a temporary file.
++ if (!name) {
++ TPath private_path;
++ TFileName file_name;
++ if (g_fs_session.PrivatePath(private_path) != KErrNone) {
++ return SQLITE_CANTOPEN;
++ }
++ if (file->handle.Temp(g_fs_session,
++ private_path,
++ file_name,
++ EFileWrite) !=
++ KErrNone) {
++ return SQLITE_CANTOPEN;
++ }
++ file->methods = &SymbianIoMethod;
++ file->lock_type = NO_LOCK;
++ file->shared_lock_byte = 0;
++ OpenCounter(+1);
++ return SQLITE_OK;
++ }
++
++ if (UTF8ToUTF16(name, &name_utf16) != KErrNone)
++ return SQLITE_CANTOPEN;
++
++ if (flags & SQLITE_OPEN_READWRITE) {
++ desired_access = EFileWrite;
++ } else {
++ desired_access = EFileRead;
++ }
++ if (flags & SQLITE_OPEN_MAIN_DB) {
++ share_mode = EFileShareReadersOrWriters;
++ } else {
++ share_mode = 0;
++ }
++
++ if (flags & SQLITE_OPEN_CREATE) {
++ err = file->handle.Create(g_fs_session,
++ name_utf16,
++ desired_access | share_mode);
++ if (err != KErrNone && err != KErrAlreadyExists) {
++ return SQLITE_CANTOPEN;
++ }
++ }
++
++ if (err != KErrNone) {
++ err = file->handle.Open(g_fs_session,
++ name_utf16,
++ desired_access | share_mode);
++ if (err != KErrNone && flags & SQLITE_OPEN_READWRITE) {
++ if (out_flags) {
++ *out_flags = (flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE;
++ }
++ desired_access = EFileRead;
++ err = file->handle.Open(g_fs_session,
++ name_utf16,
++ desired_access | share_mode);
++ }
++ if (err != KErrNone) {
++ return SQLITE_CANTOPEN;
++ }
++ }
++ file->methods = &SymbianIoMethod;
++ file->lock_type = NO_LOCK;
++ file->shared_lock_byte = 0;
++ OpenCounter(+1);
++ return SQLITE_OK;
++}
++
++static int SymbianDelete(sqlite3_vfs */*vfs*/,
++ const char *file_name,
++ int /*sync_dir*/) {
++ assert(file_name);
++ TFileName file_name_utf16;
++
++ if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) {
++ return SQLITE_ERROR;
++ }
++
++ TInt result = g_fs_session.Delete(file_name_utf16);
++ return (result == KErrNone || result == KErrPathNotFound)?
++ SQLITE_OK : SQLITE_IOERR_DELETE;
++}
++
++static int SymbianAccess(sqlite3_vfs */*vfs*/,
++ const char *file_name,
++ int flags,
++ int *result) {
++ assert(file_name);
++ TEntry entry;
++ TFileName file_name_utf16;
++
++ if (UTF8ToUTF16(file_name, &file_name_utf16) != KErrNone) {
++ return SQLITE_ERROR;
++ }
++
++ if (g_fs_session.Entry(file_name_utf16, entry) != KErrNone) {
++ *result = 0;
++ return SQLITE_OK;
++ }
++
++ switch (flags) {
++ case SQLITE_ACCESS_READ:
++ case SQLITE_ACCESS_EXISTS:
++ *result = !entry.IsDir();
++ break;
++ case SQLITE_ACCESS_READWRITE:
++ *result = !entry.IsDir() && !entry.IsReadOnly();
++ break;
++ default:
++ return SQLITE_ERROR;
++ }
++
++ return SQLITE_OK;
++}
++
++static int SymbianFullPathname(sqlite3_vfs */*vfs*/,
++ const char *relative,
++ int full_len,
++ char *full) {
++ assert(relative);
++ assert(full);
++
++ TParse parse;
++ TPath relative_utf16;
++ TPath base_path;
++ TPtr8 full_utf8(reinterpret_cast<unsigned char*>(full), full_len);
++
++ g_fs_session.PrivatePath(base_path);
++
++ if (UTF8ToUTF16(relative, &relative_utf16) != KErrNone) {
++ return SQLITE_ERROR;
++ }
++
++ if (parse.Set(relative_utf16, &base_path, NULL) != KErrNone) {
++ return SQLITE_ERROR;
++ }
++
++ TDesC full_utf16(parse.FullName());
++ if (UTF16ToUTF8(relative_utf16, &full_utf8) != KErrNone) {
++ return SQLITE_ERROR;
++ }
++
++ full_utf8.PtrZ();
++ return SQLITE_OK;
++}
++
++static int SymbianRandomness(sqlite3_vfs */*vfs*/, int buf_len, char *buffer) {
++ assert(buffer);
++ TInt64 seed = User::TickCount();
++ for (TInt i = 0; i < buf_len; i++) {
++ buffer[i] = Math::Rand(seed) % 255;
++ }
++ return SQLITE_OK;
++}
++
++static int SymbianSleep(sqlite3_vfs */*vfs*/, int microsec) {
++ User::After(microsec);
++ return SQLITE_OK;
++}
++
++int SymbianCurrentTime(sqlite3_vfs */*vfs*/, double *now) {
++ _LIT(kEpoch, "19700101:000000.000000");
++ assert(now);
++ TTime time;
++ TTime epoch_time(kEpoch);
++ TTimeIntervalSeconds interval;
++
++ time.HomeTime();
++ // calculate seconds elapsed since 1-1-1970
++ time.SecondsFrom(epoch_time, interval);
++
++ // Julian date @ 1-1-1970 = 2440587.5
++ // seconds per day = 86400.0
++ *now = interval.Int()/86400.0 + 2440587.5;
++ return SQLITE_OK;
++}
++
++static int SymbianGetLastError(sqlite3_vfs */*vfs*/,
++ int /*buf_len*/,
++ char */*buf*/) {
++ assert(buf[0] == '\0');
++ return 0;
++}
++
++// Interfaces for opening a shared library, finding entry points
++// within the shared library, and closing the shared library.
++// TODO(marcogelmi): implement.
++#define SymbianDlOpen 0
++#define SymbianDlError 0
++#define SymbianDlSym 0
++#define SymbianDlClose 0
++
++// Initialize and deinitialize the operating system interface.
++int sqlite3_os_init(void) {
++ static sqlite3_vfs symbian_vfs = {
++ 1, // iVersion
++ sizeof(SymbianFile), // szOsFile
++ KMaxPath, // mxPathname
++ 0, // pNext
++ "symbian", // name
++ 0, // pAppData
++
++ SymbianOpen, // xOpen
++ SymbianDelete, // xDelete
++ SymbianAccess, // xAccess
++ SymbianFullPathname, // xFullPathname
++ SymbianDlOpen, // xDlOpen
++ SymbianDlError, // xDlError
++ SymbianDlSym, // xDlSym
++ SymbianDlClose, // xDlClose
++ SymbianRandomness, // xRandomness
++ SymbianSleep, // xSleep
++ SymbianCurrentTime, // xCurrentTime
++ SymbianGetLastError // xGetLastError
++ };
++
++ if (g_fs_session.Connect() != KErrNone) {
++ return SQLITE_ERROR;
++ }
++
++ if (g_fs_session.ShareAuto() != KErrNone) {
++ g_fs_session.Close();
++ return SQLITE_ERROR;
++ }
++
++ sqlite3_vfs_register(&symbian_vfs, 1);
++ return SQLITE_OK;
++}
++
++int sqlite3_os_end(void) {
++ g_fs_session.Close();
++ return SQLITE_OK;
++}
++
++#endif /* OS_SYMBIAN*/
+Index: src/shell_icu_linux.c
+===================================================================
+--- src/shell_icu_linux.c 1969-12-31 16:00:00.000000000 -0800
++++ src/shell_icu_linux.c 2009-09-17 13:48:49.000000000 -0700
+@@ -0,0 +1,26 @@
++/* Copyright 2007 Google Inc. All Rights Reserved.
++**/
++
++#include <limits.h>
++#include <unistd.h>
++#include "unicode/udata.h"
++
++/*
++** This function attempts to load the ICU data tables from a data file.
++** Returns 0 on failure, nonzero on success.
++** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code.
++*/
++int sqlite_shell_init_icu() {
++ char bin_dir[PATH_MAX + 1];
++ int bin_dir_size = readlink("/proc/self/exe", bin_dir, PATH_MAX);
++ if (bin_dir_size < 0 || bin_dir_size > PATH_MAX)
++ return 0;
++ bin_dir[bin_dir_size] = 0;;
++
++ u_setDataDirectory(bin_dir);
++ // Only look for the packaged data file;
++ // the default behavior is to look for individual files.
++ UErrorCode err = U_ZERO_ERROR;
++ udata_setFileAccess(UDATA_ONLY_PACKAGES, &err);
++ return err == U_ZERO_ERROR;
++}
+Index: src/shell_icu_win.c
+===================================================================
+--- src/shell_icu_win.c 1969-12-31 16:00:00.000000000 -0800
++++ src/shell_icu_win.c 2009-09-09 12:29:11.000000000 -0700
+@@ -0,0 +1,34 @@
++/* Copyright 2007 Google Inc. All Rights Reserved.
++**/
++
++#include <windows.h>
++#include "unicode/udata.h"
++
++/*
++** This function attempts to load the ICU data tables from a DLL.
++** Returns 0 on failure, nonzero on success.
++** This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code.
++*/
++
++#define ICU_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat"
++int sqlite_shell_init_icu() {
++ HMODULE module;
++ FARPROC addr;
++ UErrorCode err;
++
++ wchar_t dll_name[12];
++ wsprintf(dll_name, L"icudt%2S.dll", U_ICU_VERSION_SHORT);
++ dll_name[11] = L'\0';
++ module = LoadLibrary(dll_name);
++ if (!module)
++ return 0;
++
++ addr = GetProcAddress(module, ICU_DATA_SYMBOL);
++ if (!addr)
++ return 0;
++
++ err = U_ZERO_ERROR;
++ udata_setCommonData(addr, &err);
++
++ return 1;
++}
+Index: test/fts.test
+===================================================================
+--- test/fts.test 1969-12-31 16:00:00.000000000 -0800
++++ test/fts.test 2009-07-01 12:08:39.000000000 -0700
+@@ -0,0 +1,61 @@
++#
++# May you do good and not evil.
++# May you find forgiveness for yourself and forgive others.
++# May you share freely, never taking more than you give.
++#
++#***********************************************************************
++# This file runs the fts tests.
++#
++# $Id$
++
++proc lshift {lvar} {
++ upvar $lvar l
++ set ret [lindex $l 0]
++ set l [lrange $l 1 end]
++ return $ret
++}
++while {[set arg [lshift argv]] != ""} {
++ switch -- $arg {
++ -sharedpagercache {
++ sqlite3_enable_shared_cache 1
++ }
++ default {
++ set argv [linsert $argv 0 $arg]
++ break
++ }
++ }
++}
++
++set testdir [file dirname $argv0]
++source $testdir/tester.tcl
++rename finish_test really_finish_test
++proc finish_test {} {}
++set ISQUICK 1
++
++set EXCLUDE {
++ fts.test
++ fts1.test
++ fts2.test
++}
++
++if {[sqlite3 -has-codec]} {
++ # lappend EXCLUDE \
++ # conflict.test
++}
++
++foreach testfile [lsort -dictionary [glob $testdir/fts*.test]] {
++ set tail [file tail $testfile]
++ puts "test: $tail"
++ if {[lsearch -exact $EXCLUDE $tail]>=0} continue
++ source $testfile
++ catch {db close}
++ if {$sqlite_open_file_count>0} {
++ puts "$tail did not close all files: $sqlite_open_file_count"
++ incr nErr
++ lappend ::failList $tail
++ }
++}
++source $testdir/misuse.test
++
++set sqlite_open_file_count 0
++really_finish_test
+Index: test/fts1.test
+===================================================================
+--- test/fts1.test 1969-12-31 16:00:00.000000000 -0800
++++ test/fts1.test 2009-07-01 12:08:39.000000000 -0700
+@@ -0,0 +1,61 @@
++#
++# May you do good and not evil.
++# May you find forgiveness for yourself and forgive others.
++# May you share freely, never taking more than you give.
++#
++#***********************************************************************
++# This file runs the fts tests.
++#
++# $Id$
++
++proc lshift {lvar} {
++ upvar $lvar l
++ set ret [lindex $l 0]
++ set l [lrange $l 1 end]
++ return $ret
++}
++while {[set arg [lshift argv]] != ""} {
++ switch -- $arg {
++ -sharedpagercache {
++ sqlite3_enable_shared_cache 1
++ }
++ default {
++ set argv [linsert $argv 0 $arg]
++ break
++ }
++ }
++}
++
++set testdir [file dirname $argv0]
++source $testdir/tester.tcl
++rename finish_test really_finish_test
++proc finish_test {} {}
++set ISQUICK 1
++
++set EXCLUDE {
++ fts.test
++ fts1.test
++ fts2.test
++}
++
++if {[sqlite3 -has-codec]} {
++ # lappend EXCLUDE \
++ # conflict.test
++}
++
++foreach testfile [lsort -dictionary [glob $testdir/fts1*.test]] {
++ set tail [file tail $testfile]
++ puts "test: $tail"
++ if {[lsearch -exact $EXCLUDE $tail]>=0} continue
++ source $testfile
++ catch {db close}
++ if {$sqlite_open_file_count>0} {
++ puts "$tail did not close all files: $sqlite_open_file_count"
++ incr nErr
++ lappend ::failList $tail
++ }
++}
++source $testdir/misuse.test
++
++set sqlite_open_file_count 0
++really_finish_test
diff --git a/third_party/sqlite/safe-tolower.patch b/third_party/sqlite/safe-tolower.patch
index 08ebb31..c42bb06 100644
--- a/third_party/sqlite/safe-tolower.patch
+++ b/third_party/sqlite/safe-tolower.patch
@@ -73,7 +73,7 @@ Index: ext/fts2/fts2.c
===================================================================
--- ext/fts2/fts2.c 2009-09-04 13:37:41.000000000 -0700
+++ ext/fts2/fts2.c 2009-09-14 18:17:02.000000000 -0700
-@@ -348,7 +372,7 @@
+@@ -372,7 +372,7 @@
return (c&0x80)==0 ? isspace(c) : 0;
}
static int safe_tolower(char c){