18a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block/* 28a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * Copyright 2010, The Android Open Source Project 38a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * 48a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * Redistribution and use in source and binary forms, with or without 58a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * modification, are permitted provided that the following conditions 68a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * are met: 78a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * * Redistributions of source code must retain the above copyright 88a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * notice, this list of conditions and the following disclaimer. 98a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * * Redistributions in binary form must reproduce the above copyright 108a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * notice, this list of conditions and the following disclaimer in the 118a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * documentation and/or other materials provided with the distribution. 128a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * 138a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 148a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 178a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block */ 258a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 268a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block#include "config.h" 278a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block#include "GeolocationPositionCache.h" 288a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if ENABLE(GEOLOCATION) 30dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 31f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "CrossThreadTask.h" 328a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block#include "Geoposition.h" 338a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block#include "SQLValue.h" 348a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block#include "SQLiteDatabase.h" 35602f856d9f84c00d87576a9d5314f42a695d9850Steve Block#include "SQLiteFileSystem.h" 368a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block#include "SQLiteStatement.h" 378a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block#include "SQLiteTransaction.h" 38f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <wtf/PassOwnPtr.h> 39f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include <wtf/Threading.h> 40f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 41f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochusing namespace WTF; 428a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 438a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Blocknamespace WebCore { 448a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 45f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochstatic int numUsers = 0; 468a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 47f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochGeolocationPositionCache* GeolocationPositionCache::instance() 48f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 49f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch DEFINE_STATIC_LOCAL(GeolocationPositionCache*, instance, (0)); 50f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!instance) 51f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch instance = new GeolocationPositionCache(); 52f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return instance; 53f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 548a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 558a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve BlockGeolocationPositionCache::GeolocationPositionCache() 56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch : m_threadId(0) 57f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 58f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 59f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 60f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::addUser() 618a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block{ 62f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(numUsers >= 0); 63cad810f21b803229eb11403f9209855525a25d57Steve Block MutexLocker databaseLock(m_databaseFileMutex); 64cad810f21b803229eb11403f9209855525a25d57Steve Block if (!numUsers && !m_threadId && !m_databaseFile.isNull()) { 65f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch startBackgroundThread(); 66f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_cachedPositionMutex); 67f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_cachedPosition) 68f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch triggerReadFromDatabase(); 698a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block } 70f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ++numUsers; 718a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block} 728a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 73f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::removeUser() 748a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block{ 75f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_cachedPositionMutex); 76f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch --numUsers; 77f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch ASSERT(numUsers >= 0); 78cad810f21b803229eb11403f9209855525a25d57Steve Block if (!numUsers && m_cachedPosition && m_threadId) 79f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch triggerWriteToDatabase(); 80f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 82f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::setDatabasePath(const String& path) 83f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch static const char* databaseName = "CachedGeoposition.db"; 85f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch String newFile = SQLiteFileSystem::appendDatabaseFileNameToPath(path, databaseName); 86f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_databaseFileMutex); 87f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_databaseFile != newFile) { 88f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_databaseFile = newFile; 89cad810f21b803229eb11403f9209855525a25d57Steve Block if (numUsers && !m_threadId) { 90cad810f21b803229eb11403f9209855525a25d57Steve Block startBackgroundThread(); 91cad810f21b803229eb11403f9209855525a25d57Steve Block if (!m_cachedPosition) 92cad810f21b803229eb11403f9209855525a25d57Steve Block triggerReadFromDatabase(); 93cad810f21b803229eb11403f9209855525a25d57Steve Block } 948a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block } 958a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block} 968a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 978a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Blockvoid GeolocationPositionCache::setCachedPosition(Geoposition* cachedPosition) 988a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block{ 99f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_cachedPositionMutex); 100f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_cachedPosition = cachedPosition; 1018a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block} 1028a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 1038a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve BlockGeoposition* GeolocationPositionCache::cachedPosition() 1048a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block{ 105f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_cachedPositionMutex); 106f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return m_cachedPosition.get(); 107f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 108f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 109f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::startBackgroundThread() 110f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 111f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // FIXME: Consider sharing this thread with other background tasks. 112cad810f21b803229eb11403f9209855525a25d57Steve Block m_threadId = createThread(threadEntryPoint, this, "WebCore: Geolocation cache"); 113f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 114f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 115f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid* GeolocationPositionCache::threadEntryPoint(void* object) 116f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 117f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch static_cast<GeolocationPositionCache*>(object)->threadEntryPointImpl(); 118f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return 0; 119f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 120f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 121f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::threadEntryPointImpl() 122f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 123f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch while (OwnPtr<ScriptExecutionContext::Task> task = m_queue.waitForMessage()) { 124f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // We don't need a ScriptExecutionContext in the callback, so pass 0 here. 125f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch task->performTask(0); 126f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 127f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 128f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 129f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::triggerReadFromDatabase() 130f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 131f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_queue.append(createCallbackTask(&GeolocationPositionCache::readFromDatabase, this)); 1328a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block} 1338a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 134f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::readFromDatabase(ScriptExecutionContext*, GeolocationPositionCache* cache) 1358a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block{ 136f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch cache->readFromDatabaseImpl(); 1378a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block} 1388a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 139f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::readFromDatabaseImpl() 1408a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block{ 1418a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block SQLiteDatabase database; 142f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch { 143f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_databaseFileMutex); 144f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!database.open(m_databaseFile)) 145f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 146f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 1478a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 1488a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block // Create the table here, such that even if we've just created the 1498a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block // DB, the commands below should succeed. 1508a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block if (!database.executeCommand("CREATE TABLE IF NOT EXISTS CachedPosition (" 1518a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "latitude REAL NOT NULL, " 1528a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "longitude REAL NOT NULL, " 1538a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "altitude REAL, " 1548a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "accuracy REAL NOT NULL, " 1558a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "altitudeAccuracy REAL, " 1568a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "heading REAL, " 1578a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "speed REAL, " 1588a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "timestamp INTEGER NOT NULL)")) 159f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 1608a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 1618a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block SQLiteStatement statement(database, "SELECT * FROM CachedPosition"); 1628a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block if (statement.prepare() != SQLResultOk) 163f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 1648a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 1658a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block if (statement.step() != SQLResultRow) 166f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 1678a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 1688a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block bool providesAltitude = statement.getColumnValue(2).type() != SQLValue::NullValue; 1698a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block bool providesAltitudeAccuracy = statement.getColumnValue(4).type() != SQLValue::NullValue; 1708a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block bool providesHeading = statement.getColumnValue(5).type() != SQLValue::NullValue; 1718a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block bool providesSpeed = statement.getColumnValue(6).type() != SQLValue::NullValue; 172602f856d9f84c00d87576a9d5314f42a695d9850Steve Block RefPtr<Coordinates> coordinates = Coordinates::create(statement.getColumnDouble(0), // latitude 173602f856d9f84c00d87576a9d5314f42a695d9850Steve Block statement.getColumnDouble(1), // longitude 1748a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block providesAltitude, statement.getColumnDouble(2), // altitude 175602f856d9f84c00d87576a9d5314f42a695d9850Steve Block statement.getColumnDouble(3), // accuracy 1768a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block providesAltitudeAccuracy, statement.getColumnDouble(4), // altitudeAccuracy 1778a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block providesHeading, statement.getColumnDouble(5), // heading 1788a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block providesSpeed, statement.getColumnDouble(6)); // speed 179f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch DOMTimeStamp timestamp = statement.getColumnInt64(7); // timestamp 180f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 181f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // A position may have been set since we called triggerReadFromDatabase(). 182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_cachedPositionMutex); 183f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_cachedPosition) 184f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 185f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_cachedPosition = Geoposition::create(coordinates.release(), timestamp); 1868a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block} 1878a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 188f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::triggerWriteToDatabase() 1898a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block{ 190f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_queue.append(createCallbackTask(writeToDatabase, this)); 191f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 1928a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 193f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::writeToDatabase(ScriptExecutionContext*, GeolocationPositionCache* cache) 194f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 195f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch cache->writeToDatabaseImpl(); 196f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 197f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 198f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid GeolocationPositionCache::writeToDatabaseImpl() 199f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 2008a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block SQLiteDatabase database; 201f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch { 202f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_databaseFileMutex); 203f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!database.open(m_databaseFile)) 204f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return; 205f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 206f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 207f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch RefPtr<Geoposition> cachedPosition; 208f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch { 209f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch MutexLocker lock(m_cachedPositionMutex); 210f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_cachedPosition) 211f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch cachedPosition = m_cachedPosition->threadSafeCopy(); 212f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 2138a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 2148a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block SQLiteTransaction transaction(database); 2158a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 2168a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block if (!database.executeCommand("DELETE FROM CachedPosition")) 2178a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block return; 2188a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 2198a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block SQLiteStatement statement(database, "INSERT INTO CachedPosition (" 2208a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "latitude, " 2218a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "longitude, " 2228a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "altitude, " 2238a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "accuracy, " 2248a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "altitudeAccuracy, " 2258a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "heading, " 2268a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "speed, " 2278a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "timestamp) " 2288a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block "VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); 2298a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block if (statement.prepare() != SQLResultOk) 2308a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block return; 2318a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 232f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statement.bindDouble(1, cachedPosition->coords()->latitude()); 233f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statement.bindDouble(2, cachedPosition->coords()->longitude()); 234f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (cachedPosition->coords()->canProvideAltitude()) 235f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statement.bindDouble(3, cachedPosition->coords()->altitude()); 2368a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block else 2378a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block statement.bindNull(3); 238f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statement.bindDouble(4, cachedPosition->coords()->accuracy()); 239f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (cachedPosition->coords()->canProvideAltitudeAccuracy()) 240f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statement.bindDouble(5, cachedPosition->coords()->altitudeAccuracy()); 2418a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block else 2428a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block statement.bindNull(5); 243f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (cachedPosition->coords()->canProvideHeading()) 244f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statement.bindDouble(6, cachedPosition->coords()->heading()); 2458a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block else 2468a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block statement.bindNull(6); 247f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (cachedPosition->coords()->canProvideSpeed()) 248f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statement.bindDouble(7, cachedPosition->coords()->speed()); 2498a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block else 2508a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block statement.bindNull(7); 251f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch statement.bindInt64(8, cachedPosition->timestamp()); 252f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2538a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block if (!statement.executeCommand()) 2548a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block return; 2558a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 2568a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block transaction.commit(); 2578a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block} 2588a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block 2598a03f7cd9e884b3db11bb5485b4d9f5095dc0bcaSteve Block} // namespace WebCore 260dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 261dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#endif // ENABLE(GEOLOCATION) 262