+2007-10-19 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Sam
+
+ Queue -> Deque! and small style tweaks
+
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+ * wtf/Deque.h: Added.
+ (WTF::DequeNode::DequeNode):
+ (WTF::Deque::Deque):
+ (WTF::Deque::~Deque):
+ (WTF::Deque::size):
+ (WTF::Deque::isEmpty):
+ (WTF::Deque::append):
+ (WTF::Deque::prepend):
+ (WTF::Deque::first):
+ (WTF::Deque::last):
+ (WTF::Deque::removeFirst):
+ (WTF::Deque::clear):
+ * wtf/Queue.h: Removed.
+
+
+2007-10-19 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Oliver
+
+ Added a simple LinkedList based Queue to wtf
+ We can make a better, more sophisticated an efficient one later, but have
+ needed one for some time, now!
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/Queue.h: Added.
+ (WTF::QueueNode::QueueNode):
+ (WTF::Queue::Queue):
+ (WTF::Queue::~Queue):
+ (WTF::Queue::size):
+ (WTF::Queue::isEmpty):
+ (WTF::Queue::append):
+ (WTF::Queue::prepend):
+ (WTF::Queue::first):
+ (WTF::Queue::last):
+ (WTF::Queue::removeFirst):
+ (WTF::Queue::clear):
+
2007-10-19 Nikolas Zimmermann <zimmermann@kde.org>
Reviewed by Anders.
RelativePath="..\..\wtf\Assertions.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\wtf\Deque.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\wtf\FastMalloc.cpp"\r
>\r
14BD5A360A3E91F600BAF59C /* JavaScriptCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 14BD5A2F0A3E91F600BAF59C /* JavaScriptCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
14F137830A3A765B00F26F90 /* context.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F137820A3A765B00F26F90 /* context.h */; settings = {ATTRIBUTES = (Private, ); }; };
1CAF34890A6C421700ABE06E /* WebScriptObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF34880A6C421700ABE06E /* WebScriptObject.h */; };
+ 5186111E0CC824900081412B /* Deque.h in Headers */ = {isa = PBXBuildFile; fileRef = 5186111D0CC824830081412B /* Deque.h */; settings = {ATTRIBUTES = (Private, ); }; };
51F648D70BB4E2CA0033D760 /* RetainPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F648D60BB4E2CA0033D760 /* RetainPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
5DBD18AC0C54018700C15EAE /* CollectorHeapIntrospector.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD18AA0C54018700C15EAE /* CollectorHeapIntrospector.h */; };
5DBD18B00C5401A700C15EAE /* MallocZoneSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */; };
5182A53B06012C3000CBD2F2 /* c_class.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = c_class.h; path = bindings/c/c_class.h; sourceTree = "<group>"; tabWidth = 8; };
51856D8F0562EE95008B9D83 /* jni_utility.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jni_utility.cpp; path = bindings/jni/jni_utility.cpp; sourceTree = "<group>"; tabWidth = 8; };
51856D900562EE95008B9D83 /* jni_utility.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = jni_utility.h; path = bindings/jni/jni_utility.h; sourceTree = "<group>"; tabWidth = 8; };
+ 5186111D0CC824830081412B /* Deque.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Deque.h; sourceTree = "<group>"; };
518CF93605C72271003CF905 /* objc_class.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; name = objc_class.h; path = bindings/objc/objc_class.h; sourceTree = "<group>"; tabWidth = 8; };
518CF93705C72271003CF905 /* objc_class.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = objc_class.mm; path = bindings/objc/objc_class.mm; sourceTree = "<group>"; tabWidth = 8; };
518CF93805C72271003CF905 /* objc_runtime.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = objc_runtime.mm; path = bindings/objc/objc_runtime.mm; sourceTree = "<group>"; tabWidth = 8; };
938C4F690CA06BC700D9310A /* ASCIICType.h */,
65E217B808E7EECC0023E5F6 /* Assertions.cpp */,
65E217B708E7EECC0023E5F6 /* Assertions.h */,
+ 5186111D0CC824830081412B /* Deque.h */,
938C4F6B0CA06BCE00D9310A /* DisallowCType.h */,
65E217B908E7EECC0023E5F6 /* FastMalloc.cpp */,
65E217BA08E7EECC0023E5F6 /* FastMalloc.h */,
95C18D490C90E82600E72F73 /* JSRetainPtr.h in Headers */,
938C4F6A0CA06BC700D9310A /* ASCIICType.h in Headers */,
938C4F6C0CA06BCE00D9310A /* DisallowCType.h in Headers */,
+ 5186111E0CC824900081412B /* Deque.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#ifndef WTF_Deque_h
+#define WTF_Deque_h
+
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+
+namespace WTF {
+
+ template<typename T>
+ class DequeNode {
+ public:
+ DequeNode(const T& item) : m_value(item), m_next(0) { }
+
+ T m_value;
+ DequeNode* m_next;
+ };
+
+ template<typename T>
+ class Deque : Noncopyable {
+ public:
+ Deque()
+ : m_size(0)
+ , m_first(0)
+ , m_last(0)
+ {
+ }
+
+ ~Deque()
+ {
+ clear();
+ }
+
+ size_t size() const { return m_size; }
+ bool isEmpty() const { return !size(); }
+
+ void append(const T& item)
+ {
+ DequeNode<T>* newNode = new DequeNode<T>(item);
+ if (m_last)
+ m_last->m_next = newNode;
+ m_last = newNode;
+ if (!m_first)
+ m_first = newNode;
+ ++m_size;
+ }
+
+ void prepend(const T& item)
+ {
+ DequeNode<T>* newNode = new DequeNode<T>(item);
+ newNode->m_next = m_first;
+ m_first = newNode;
+ if (!m_last)
+ m_last = newNode;
+ ++m_size;
+ }
+
+ T& first() { ASSERT(m_first); return m_first->m_value; }
+ const T& first() const { ASSERT(m_first); return m_first->m_value; }
+ T& last() { ASSERT(m_last); return m_last->m_value; }
+ const T& last() const { ASSERT(m_last); return m_last->m_value; }
+
+ void removeFirst()
+ {
+ ASSERT(m_first);
+ if (DequeNode<T>* n = m_first) {
+ m_first = m_first->m_next;
+ if (n == m_last)
+ m_last = 0;
+
+ m_size--;
+ delete n;
+ }
+ }
+
+ void clear()
+ {
+ DequeNode<T>* n = m_first;
+ m_first = 0;
+ m_last = 0;
+ m_size = 0;
+ while (n) {
+ DequeNode<T>* next = n->m_next;
+ delete n;
+ n = next;
+ }
+ }
+
+ private:
+ size_t m_size;
+ DequeNode<T>* m_first;
+ DequeNode<T>* m_last;
+
+ };
+
+} // namespace WTF
+
+using WTF::Deque;
+
+#endif // WTF_Deque_h
+2007-10-19 Brady Eidson <beidson@apple.com>
+ Reviewed by Anders
+
+ Windows specific changes, as well as renaming Queue -> Deque
+
+ * ForwardingHeaders/wtf/Deque.h: Added.
+ * ForwardingHeaders/wtf/Queue.h: Removed.
+ * platform/win/FileSystemWin.cpp:
+ (WebCore::fileSize):
+ (WebCore::fileExists):
+ (WebCore::deleteFile):
+ (WebCore::pathByAppendingComponent):
+ (WebCore::fileSystemRepresentation):
+ (WebCore::makeAllDirectories):
+ (WebCore::homeDirectoryPath):
+ * storage/Database.h:
+ * storage/DatabaseThread.cpp:
+ (WebCore::DatabaseThread::documentGoingAway):
+ (WebCore::DatabaseThread::databaseGoingAway):
+ (WebCore::DatabaseThread::dispatchNextTaskIdentifier):
+ (WebCore::DatabaseThread::scheduleTask):
+ (WebCore::DatabaseThread::scheduleImmediateTask):
+ * storage/DatabaseThread.h:
+
+2007-10-19 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Tim and Anders
+
+ Preliminary support for HTML5 local database storage (http://www.whatwg.org/specs/web-apps/current-work/)
+
+ The specification is still in flux but the fundamentals are pretty solid and we can start using and testing
+ this implementation even while filing bugs to track changes in the spec as it becomes more final
+
+ There are some implementation details in this patch that seem unused or useless, but they remain in place
+ while the spec is in flux and might go one way or another.
+
+ * platform/Logging.cpp: Add StorageAPI logging channel
+ * platform/Logging.h:
+
+ * storage/Database.cpp: Added.
+ (WebCore::Database::databaseInfoTableName):
+ (WebCore::databaseVersionKey):
+ (WebCore::Database::openDatabase): C++ version of the window.openDatabase() javascript API
+ (WebCore::Database::Database):
+ (WebCore::Database::~Database):
+ (WebCore::Database::openAndVerifyVersion):
+ (WebCore::retrieveTextResultFromDatabase):
+ (WebCore::Database::getVersionFromDatabase):
+ (WebCore::setTextValueInDatabase):
+ (WebCore::Database::setVersionInDatabase):
+ (WebCore::Database::databaseThreadGoingAway): May be removed in the future
+ (WebCore::Database::disableAuthorizer): For internal (WebInspector) use to get around the authorizer's restrictions
+ (WebCore::Database::enableAuthorizer):
+ (WebCore::Database::guidForOriginAndName): Candidate for refactoring and/or moving to the database tracker.
+ The GUID for each database identifier is currently for tracking the database version, but might be rescoped in the future
+ (WebCore::Database::resetAuthorizer):
+ (WebCore::Database::performPolicyChecks): Currently, the only post-executeSql policy check planned is the origin size usage
+ (WebCore::Database::scheduleDatabaseCallback):
+ (WebCore::Database::performOpenAndVerify):
+ (WebCore::Database::performChangeVersion):
+ (WebCore::Database::performExecuteSql):
+ (WebCore::Database::performCloseTransaction):
+ (WebCore::Database::performGetTableNames):
+ (WebCore::Database::version): C++ version of the javascript API
+ (WebCore::Database::changeVersion): Ditto
+ (WebCore::Database::executeSql): Ditto
+ (WebCore::Database::closeTransaction): Ditto
+ (WebCore::Database::tableNames): For internal (WebInspector) use
+ (WebCore::Database::deliverAllPendingCallbacks):
+ (WebCore::Database::deliverPendingCallbacks):
+ * storage/Database.h: Added.
+ (WebCore::Database::databaseDebugName): For debug logging purposes
+ * storage/Database.idl: Added.
+
+ * storage/DatabaseAuthorizer.cpp: Added.
+ The DatabaseAuthorizer is used to both prevent the script from doing "illegal" things in sql as well as
+ tracking when effects certain sql statements might have (such as increasing the size of the database)
+ (WebCore::DatabaseAuthorizer::DatabaseAuthorizer):
+ (WebCore::DatabaseAuthorizer::reset):
+ (WebCore::DatabaseAuthorizer::createTable):
+ (WebCore::DatabaseAuthorizer::createTempTable):
+ (WebCore::DatabaseAuthorizer::dropTable):
+ (WebCore::DatabaseAuthorizer::dropTempTable):
+ (WebCore::DatabaseAuthorizer::allowAlterTable):
+ (WebCore::DatabaseAuthorizer::createIndex):
+ (WebCore::DatabaseAuthorizer::createTempIndex):
+ (WebCore::DatabaseAuthorizer::dropIndex):
+ (WebCore::DatabaseAuthorizer::dropTempIndex):
+ (WebCore::DatabaseAuthorizer::createTrigger):
+ (WebCore::DatabaseAuthorizer::createTempTrigger):
+ (WebCore::DatabaseAuthorizer::dropTrigger):
+ (WebCore::DatabaseAuthorizer::dropTempTrigger):
+ (WebCore::DatabaseAuthorizer::createVTable):
+ (WebCore::DatabaseAuthorizer::dropVTable):
+ (WebCore::DatabaseAuthorizer::allowDelete):
+ (WebCore::DatabaseAuthorizer::allowInsert):
+ (WebCore::DatabaseAuthorizer::allowUpdate):
+ (WebCore::DatabaseAuthorizer::allowRead):
+ (WebCore::DatabaseAuthorizer::allowAnalyze):
+ (WebCore::DatabaseAuthorizer::allowPragma):
+ (WebCore::DatabaseAuthorizer::allowAttach):
+ (WebCore::DatabaseAuthorizer::allowDetach):
+ (WebCore::DatabaseAuthorizer::allowFunction):
+ (WebCore::DatabaseAuthorizer::disable):
+ (WebCore::DatabaseAuthorizer::enable):
+ (WebCore::DatabaseAuthorizer::denyBasedOnTableName): Don't allow access to the __WebKit meta info table as
+ it should be invisible to scripts
+ * storage/DatabaseAuthorizer.h: Added.
+ (WebCore::DatabaseAuthorizer::lastActionWasInsert):
+ (WebCore::DatabaseAuthorizer::lastActionIncreasedSize):
+
+ * storage/DatabaseCallback.cpp: Added.
+ Generic item to queue up for callbacks on the main thread for database activities that take place on
+ a secondary thread
+ (WebCore::DatabaseChangeVersionCallback::DatabaseChangeVersionCallback):
+ (WebCore::DatabaseChangeVersionCallback::performCallback):
+ (WebCore::DatabaseExecuteSqlCallback::DatabaseExecuteSqlCallback):
+ (WebCore::DatabaseExecuteSqlCallback::performCallback):
+ * storage/DatabaseCallback.h: Added.
+ (WebCore::DatabaseCallback::~DatabaseCallback):
+ (WebCore::DatabaseChangeVersionCallback::~DatabaseChangeVersionCallback):
+ (WebCore::DatabaseExecuteSqlCallback::~DatabaseExecuteSqlCallback):
+
+ * storage/DatabaseTask.h: Added.
+ Generic work-item to be queued up on the background database thread
+ (WebCore::DatabaseTask::isComplete):
+ (WebCore::DatabaseOpenTask::exceptionCode):
+ (WebCore::DatabaseOpenTask::openSuccessful):
+ (WebCore::DatabaseTableNamesTask::tableNames):
+ * storage/DatabaseTask.cpp: Added.
+ (WebCore::DatabaseTask::DatabaseTask):
+ (WebCore::DatabaseTask::~DatabaseTask):
+ (WebCore::DatabaseTask::performTask):
+ (WebCore::DatabaseTask::lockForSynchronousScheduling): Used when the main thread needs this task accomplished
+ synchronously
+ (WebCore::DatabaseTask::waitForSynchronousCompletion):
+
+ (WebCore::DatabaseOpenTask::DatabaseOpenTask):
+ (WebCore::DatabaseOpenTask::doPerformTask):
+
+ (WebCore::DatabaseExecuteSqlTask::DatabaseExecuteSqlTask):
+ (WebCore::DatabaseExecuteSqlTask::doPerformTask):
+
+ (WebCore::DatabaseChangeVersionTask::DatabaseChangeVersionTask):
+ (WebCore::DatabaseChangeVersionTask::doPerformTask):
+
+ (WebCore::DatabaseTableNamesTask::DatabaseTableNamesTask):
+ (WebCore::DatabaseTableNamesTask::doPerformTask):
+
+ * storage/DatabaseThread.cpp: Added.
+ The current design is that each Document will have its own DatabaseThread. This makes scripts on each
+ individual document more response at the cost of adding more threads and potentially creating concurrency
+ issues when the same database is open twice from two different documents
+ (WebCore::DatabaseThread::DatabaseThread):
+ (WebCore::DatabaseThread::~DatabaseThread):
+ (WebCore::DatabaseThread::start):
+ (WebCore::DatabaseThread::documentGoingAway): Called to shut the thread down when the document is destroyed
+ (WebCore::DatabaseThread::databaseGoingAway): Remove all pending tasks for this database
+ (WebCore::DatabaseThread::databaseThreadStart):
+ (WebCore::DatabaseThread::databaseThread):
+ (WebCore::DatabaseThread::dispatchNextTaskIdentifier):
+ (WebCore::DatabaseThread::scheduleTask):
+ (WebCore::DatabaseThread::scheduleImmediateTask): Schedule a task that gets to "cut to the front of the line" when
+ the main thread requires a task be performed synchronously
+ (WebCore::DatabaseThread::wakeWorkThread):
+ * storage/DatabaseThread.h: Added.
+
+ * storage/DatabaseTracker.cpp: Added.
+ The DatabaseTracker is the master management of all databases. It will keep track of the filename for a given
+ unique database, keep track of the total disk usage per-origin, and policys per database/origin
+ (WebCore::DatabaseTracker::setDatabasePath):
+ (WebCore::DatabaseTracker::databasePath):
+ (WebCore::DatabaseTracker::tracker):
+ (WebCore::DatabaseTracker::DatabaseTracker):
+ (WebCore::DatabaseTracker::fullPathForDatabase):
+ (WebCore::DatabaseTracker::populateOrigins):
+ (WebCore::DatabaseTracker::origins):
+ (WebCore::DatabaseTracker::databaseNamesForOrigin):
+ (WebCore::DatabaseTracker::addDatabase):
+ (WebCore::DatabaseTracker::deleteAllDatabases):
+ (WebCore::DatabaseTracker::deleteAllDatabasesForOrigin):
+ * storage/DatabaseTracker.h: Added.
+
+ * storage/SQLCallback.h: Added. C++ version of the javascript executeSql() callback
+ (WebCore::SQLCallback::~SQLCallback):
+ * storage/SQLCallback.idl: Added.
+
+ * storage/SQLResultSet.cpp: Added. C++ version of the javascript SQLResultSet object
+ (WebCore::SQLResultSet::SQLResultSet):
+ (WebCore::SQLResultSet::insertId):
+ (WebCore::SQLResultSet::rowsAffected):
+ (WebCore::SQLResultSet::errorCode):
+ (WebCore::SQLResultSet::error):
+ (WebCore::SQLResultSet::rows):
+ (WebCore::SQLResultSet::setInsertId):
+ (WebCore::SQLResultSet::setRowsAffected):
+ (WebCore::SQLResultSet::setErrorCode):
+ (WebCore::SQLResultSet::setErrorMessage):
+ * storage/SQLResultSet.h: Added.
+ * storage/SQLResultSet.idl: Added.
+
+ * storage/SQLResultSetRowList.cpp: Added. C++ version of the javascript SQLResultSetRowList object
+ (WebCore::SQLResultSetRowList::length):
+ * storage/SQLResultSetRowList.h: Added.
+ (WebCore::SQLResultSetRowList::columnNames):
+ (WebCore::SQLResultSetRowList::values):
+ (WebCore::SQLResultSetRowList::addColumn):
+ (WebCore::SQLResultSetRowList::addResult):
+ * storage/SQLResultSetRowList.idl: Added.
+
+ * storage/VersionChangeCallback.h: Added. C++ version of the javascript changeVersion() callback
+ (WebCore::VersionChangeCallback::~VersionChangeCallback):
+ * storage/VersionChangeCallback.idl: Added.
+
+2007-10-19 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Oliver + Same
+
+ Forwarding header for the new wtf/Queue.h
+
+ * ForwardingHeaders/wtf/Queue.h: Added.
+
+2007-10-19 Anders Carlsson <beidson@apple.com>
+
+ Reviewed by Sam Weinig
+
+ Most of the Javascript binding support for the Storage API
+
+ * bindings/js/JSCustomSQLCallback.cpp: Added.
+ (WebCore::JSCustomSQLCallback::JSCustomSQLCallback):
+ (WebCore::JSCustomSQLCallback::handleEvent):
+ * bindings/js/JSCustomSQLCallback.h: Added.
+ Add JSCustomSQLCallback which is an SQLCallback implementation that dispatches
+ handleEvent to a JS function or a JS object with a handleEvent function.
+
+ * bindings/js/JSCustomVersionChangeCallback.cpp: Added.
+ (WebCore::JSCustomVersionChangeCallback::JSCustomVersionChangeCallback):
+ (WebCore::JSCustomVersionChangeCallback::handleEvent):
+ * bindings/js/JSCustomVersionChangeCallback.h: Added.
+ Add JSCustomSQLCallback which is an SQLCallback implementation that dispatches
+ handleEvent to a JS function or a JS object with a handleEvent function.
+
+ * bindings/js/JSDatabaseCustom.cpp: Added.
+ (WebCore::JSDatabase::executeSql):
+ Custom implementation of executeSql that takes an array of parameters.
+
+ (WebCore::JSDatabase::changeVersion):
+ Custom implementation of changeVersion.
+
+ * bindings/js/JSSQLResultSetRowListCustom.cpp: Added.
+ (WebCore::JSSQLResultSetRowList::item):
+ Custom method that returns a JS object that corresponds to a given row in the database.
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::openDatabase):
+ * page/DOMWindow.h:
+ * page/DOMWindow.idl:
+ Add openDatabase implementation.
+
+2007-10-19 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Oliver
+
+ Added tons of utility to the FileSystem abstractions, including moving
+ some stuff over from IconDatabase
+
+ * platform/FileSystem.h:
+
+ * platform/cf/FileSystemCF.cpp: Added.
+ (WebCore::fileSystemRepresentation):
+
+ * platform/mac/FileSystemMac.mm:
+
+ * platform/posix/FileSystemPOSIX.cpp: Added.
+ (WebCore::fileExists):
+ (WebCore::deleteFile):
+ (WebCore::fileSize):
+ (WebCore::pathByAppendingComponent):
+ (WebCore::makeAllDirectories):
+
+2007-10-19 Timothy Hatcher <timothy@apple.com>
+
+ Reviewed by Adam Roben
+
+ Preliminary Web Inspector support for the Storage API
+ (This patch does not include the support artwork)
+
+ * page/InspectorController.cpp:
+ (WebCore::InspectorDatabaseResource::InspectorDatabaseResource):
+ (WebCore::InspectorDatabaseResource::setScriptObject):
+ (WebCore::databaseTableNames): Return the table names for a Database object.
+ (WebCore::InspectorController::setWindowVisible):
+ (WebCore::InspectorController::windowScriptObjectAvailable):
+ (WebCore::InspectorController::populateScriptResources):
+ (WebCore::InspectorController::addDatabaseScriptResource): Add the script object for the database.
+ (WebCore::InspectorController::removeDatabaseScriptResource): Remove the script object for the database.
+ (WebCore::InspectorController::clearDatabaseScriptResources): Remove all the database resources.
+ (WebCore::InspectorController::didCommitLoad): Call clearDatabaseScriptResources().
+ (WebCore::InspectorController::didOpenDatabase): Make a new InspectorDatabaseResource and add it to m_databaseResources.
+ * page/InspectorController.h:
+ * page/inspector/Database.js: Added.
+ * page/inspector/DatabasePanel.js: Added.
+ * page/inspector/ResourceCategory.js: Make resource categories assume less about the resource.
+ * page/inspector/inspector.css: Add styles for the database panel.
+ * page/inspector/inspector.html: Include DatabasePanel.js
+ * page/inspector/inspector.js: Support for adding and removing Database resources.
+
+2007-10-19 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Tim Hatcher
+
+ Added support for Chrome prompts required by the Storage API
+
+ * page/Chrome.cpp:
+ (WebCore::Chrome::runDatabaseSizeLimitPrompt):
+ * page/Chrome.h:
+ * page/ChromeClient.h:
+ * platform/graphics/svg/SVGImageEmptyClients.h:
+
+2007-10-19 Brady Eidson <beidson@apple.com>
+
+ Contributions and Review by Anders
+
+ Various SQLite tweaks in preparation for the storage API
+
+ * loader/icon/SQLDatabase.cpp:
+ (WebCore::SQLDatabase::~SQLDatabase):
+ (WebCore::SQLDatabase::authorizerFunction): Static callback from sqlite for authorizer functions
+ (WebCore::SQLDatabase::setAuthorizer):
+ (WebCore::SQLDatabase::lock):
+ (WebCore::SQLDatabase::unlock):
+ * loader/icon/SQLDatabase.h:
+
+ * loader/icon/SQLStatement.cpp:
+ (WebCore::SQLStatement::prepare): Switch to prepare16_v2
+ (WebCore::SQLStatement::bindDouble): Added
+ (WebCore::SQLStatement::bindValue): Bind a wrapped SQLValue object (described later)
+ (WebCore::SQLStatement::bindParameterCount): Accessor to the sqlite3 API for validating statements
+ * loader/icon/SQLStatement.h:
+ (WebCore::SQLStatement::isPrepared):
+
+ * platform/sql/SQLAuthorizer.cpp: Added. Fully virtual interface to implement your own SQLite authorizer
+ * platform/sql/SQLAuthorizer.h: Added.
+ (WebCore::SQLAuthorizer::~SQLAuthorizer):
+ (WebCore::SQLAuthorizer::createTable):
+ (WebCore::SQLAuthorizer::createTempTable):
+ (WebCore::SQLAuthorizer::dropTable):
+ (WebCore::SQLAuthorizer::dropTempTable):
+ (WebCore::SQLAuthorizer::allowAlterTable):
+ (WebCore::SQLAuthorizer::createIndex):
+ (WebCore::SQLAuthorizer::createTempIndex):
+ (WebCore::SQLAuthorizer::dropIndex):
+ (WebCore::SQLAuthorizer::dropTempIndex):
+ (WebCore::SQLAuthorizer::createTrigger):
+ (WebCore::SQLAuthorizer::createTempTrigger):
+ (WebCore::SQLAuthorizer::dropTrigger):
+ (WebCore::SQLAuthorizer::dropTempTrigger):
+ (WebCore::SQLAuthorizer::createView):
+ (WebCore::SQLAuthorizer::createTempView):
+ (WebCore::SQLAuthorizer::dropView):
+ (WebCore::SQLAuthorizer::dropTempView):
+ (WebCore::SQLAuthorizer::createVTable):
+ (WebCore::SQLAuthorizer::dropVTable):
+ (WebCore::SQLAuthorizer::allowDelete):
+ (WebCore::SQLAuthorizer::allowInsert):
+ (WebCore::SQLAuthorizer::allowUpdate):
+ (WebCore::SQLAuthorizer::allowTransaction):
+ (WebCore::SQLAuthorizer::allowSelect):
+ (WebCore::SQLAuthorizer::allowRead):
+ (WebCore::SQLAuthorizer::allowAttach):
+ (WebCore::SQLAuthorizer::allowDetach):
+ (WebCore::SQLAuthorizer::allowReindex):
+ (WebCore::SQLAuthorizer::allowAnalyze):
+ (WebCore::SQLAuthorizer::allowFunction):
+
+ * platform/sql/SQLValue.cpp: Added. Contains a value for a SQLite database that can be one of a few types.
+ For now, just a String or a double
+ (WebCore::SQLValue::SQLValue):
+ (WebCore::SQLValue::string):
+ (WebCore::SQLValue::number):
+ * platform/sql/SQLValue.h: Added.
+ (WebCore::SQLValue::):
+ (WebCore::SQLValue::SQLValue):
+ (WebCore::SQLValue::type):
+
+2007-10-19 Brady Eidson <beidson@apple.com>
+
+ Reviewed by Maciej
+
+ Changed IconDatabase over to use new FileSystem apis
+
+ * loader/icon/IconDatabase.cpp:
+ (WebCore::IconDatabase::open):
+
2007-10-19 David Hyatt <hyatt@apple.com>
Fix for ebay parser crash.
$(WebCore)/dom \
$(WebCore)/html \
$(WebCore)/page \
+ $(WebCore)/storage \
$(WebCore)/xml \
$(WebCore)/ksvg2/svg \
$(WebCore)/ksvg2/events \
JSComment.h \
JSCounter.h \
JSCSSStyleDeclaration.h \
+ JSDatabase.h \
JSDOMExceptionConstructor.lut.h \
JSDOMImplementation.h \
JSDOMParser.h \
JSRange.h \
JSRangeException.h \
JSRect.h \
+ JSSQLCallback.h \
+ JSSQLResultSet.h \
+ JSSQLResultSetRowList.h \
JSSVGAElement.h \
JSSVGAngle.h \
JSSVGAnimatedAngle.h \
JSTextEvent.h \
JSTreeWalker.h \
JSUIEvent.h \
+ JSVersionChangeCallback.h \
JSXPathEvaluator.h \
JSXPathExpression.h \
JSXPathNSResolver.h \
--- /dev/null
+#include <JavaScriptCore/Deque.h>
__ZN7WebCore15BackForwardListC1EPNS_4PageE
__ZN7WebCore15BackForwardListD1Ev
__ZN7WebCore15ContextMenuItem26releasePlatformDescriptionEv
+__ZN7WebCore15DatabaseTracker14deleteDatabaseERKNS_6StringES3_
+__ZN7WebCore15DatabaseTracker15setDatabasePathERKNS_6StringE
+__ZN7WebCore15DatabaseTracker18deleteAllDatabasesEv
+__ZN7WebCore15DatabaseTracker22databaseNamesForOriginERKNS_6StringERN3WTF6VectorIS1_Lm0EEE
+__ZN7WebCore15DatabaseTracker27deleteAllDatabasesForOriginERKNS_6StringE
+__ZN7WebCore15DatabaseTracker7originsEv
+__ZN7WebCore15DatabaseTracker7trackerEv
__ZN7WebCore15FocusController15setFocusedFrameEN3WTF10PassRefPtrINS_5FrameEEE
__ZN7WebCore15FocusController15setInitialFocusENS_14FocusDirectionEPNS_13KeyboardEventE
__ZN7WebCore15FocusController18focusedOrMainFrameEv
__ZN7WebCore16DeprecatedStringC1Ev
__ZN7WebCore16DeprecatedStringD1Ev
__ZN7WebCore16DeprecatedStringaSERKS0_
+__ZN7WebCore16FontPlatformDataC1EP6NSFontbb
+__ZN7WebCore16FontPlatformDataD1Ev
__ZN7WebCore16MIMETypeRegistry24isSupportedImageMIMETypeERKNS_6StringE
__ZN7WebCore16MIMETypeRegistry26getSupportedImageMIMETypesEv
__ZN7WebCore16MIMETypeRegistry29getSupportedNonImageMIMETypesEv
__ZN7WebCore4FontC1Ev
__ZN7WebCore4FontD1Ev
__ZN7WebCore4FontaSERKS0_
-__ZN7WebCore16FontPlatformDataC1EP6NSFontbb
-__ZN7WebCore16FontPlatformDataD1Ev
__ZN7WebCore4KURL13decode_stringERKNS_16DeprecatedStringE
__ZN7WebCore4KURLC1EP5NSURL
__ZN7WebCore4KURLC1ERKNS_16DeprecatedStringE
<Tool\r
Name="VCCLCompilerTool"\r
Optimization="0"\r
- AdditionalIncludeDirectories=""$(ProjectDir)..\";"$(ProjectDir)..";"$(ProjectDir)..\css";"$(ProjectDir)..\css";"$(ProjectDir)..\editing";"$(ProjectDir)..\editing";"$(ProjectDir)..\rendering";"$(ProjectDir)..\rendering";"$(ProjectDir)..\bindings\js";"$(ProjectDir)..\bindings\js";"$(ProjectDir)..\dom";"$(ProjectDir)..\dom";"$(ProjectDir)..\history";"$(ProjectDir)..\html";"$(ProjectDir)..\html";"$(ProjectDir)..\bridge";"$(ProjectDir)..\bridge";"$(ProjectDir)..\bridge\win";"$(ProjectDir)..\bridge\win";"$(ProjectDir)..\loader";"$(ProjectDir)..\loader";"$(ProjectDir)..\loader\icon";"$(ProjectDir)..\loader\icon";"$(ProjectDir)..\page";"$(ProjectDir)..\page";"$(ProjectDir)..\platform";"$(ProjectDir)..\platform\win";"$(ProjectDir)..\platform\network";"$(ProjectDir)..\platform\network\win";"$(ProjectDir)..\platform";"$(ProjectDir)..\platform\cf";"$(ProjectDir)..\platform\network";"$(ProjectDir)..\platform\network\cf";"$(ProjectDir)..\platform\network\win";"$(ProjectDir)..\platform\graphics";"$(ProjectDir)..\platform\graphics";"$(ProjectDir)..\platform\graphics\cairo";"$(ProjectDir)..\platform\graphics\cairo";"$(ProjectDir)..\platform\graphics\cg";"$(ProjectDir)..\platform\graphics\cg";"$(ProjectDir)..\platform\graphics\win";"$(ProjectDir)..\platform\graphics\win";"$(ProjectDir)..\platform\image-decoders";"$(ProjectDir)..\platform\image-decoders";"$(ProjectDir)..\platform\image-decoders\bmp";"$(ProjectDir)..\platform\image-decoders\bmp";"$(ProjectDir)..\platform\image-decoders\gif";"$(ProjectDir)..\platform\image-decoders\gif";"$(ProjectDir)..\platform\image-decoders\ico";"$(ProjectDir)..\platform\image-decoders\ico";"$(ProjectDir)..\platform\image-decoders\jpeg";"$(ProjectDir)..\platform\image-decoders\jpeg";"$(ProjectDir)..\platform\image-decoders\png";"$(ProjectDir)..\platform\image-decoders\png";"$(ProjectDir)..\platform\image-decoders\xbm";"$(ProjectDir)..\platform\image-decoders\xbm";"$(ProjectDir)..\platform\image-decoders\zlib";"$(ProjectDir)..\platform\image-decoders\zlib";"$(ProjectDir)..\xml";"$(ProjectDir)..\xml";"$(WebKitOutputDir)\obj\WebCore\DerivedSources";"$(ProjectDir)..\platform\win";"$(ProjectDir)..\plugins\win";"$(ProjectDir)..\platform\cairo\pixman\src";"$(ProjectDir)..\platform\cairo\pixman\src";"$(ProjectDir)..\platform\cairo\cairo\src";"$(ProjectDir)..\platform\cairo\cairo\src";"$(ProjectDir)..\platform\graphics\svg";"$(ProjectDir)..\platform\graphics\svg\cg";"$(ProjectDir)..\platform\graphics\svg\filters";"$(ProjectDir)..\kcanvas";"$(ProjectDir)..\kcanvas\device";"$(ProjectDir)..\kcanvas\device\quartz";"$(ProjectDir)..\ksvg2";"$(ProjectDir)..\ksvg2\css";"$(ProjectDir)..\ksvg2\events";"$(ProjectDir)..\ksvg2\misc";"$(ProjectDir)..\ksvg2\svg";"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\JavaScriptCore";"$(ProjectDir)..\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\icu";"$(WebKitLibrariesDir)\include\iconv";"$(WebKitLibrariesDir)\include\pthreads";"$(WebKitLibrariesDir)\include\sqlite";"$(WebKitLibrariesDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility""\r
+ AdditionalIncludeDirectories=""$(ProjectDir)..\";"$(ProjectDir)..";"$(ProjectDir)..\css";"$(ProjectDir)..\editing";"$(ProjectDir)..\rendering";"$(ProjectDir)..\bindings\js";"$(ProjectDir)..\dom";"$(ProjectDir)..\history";"$(ProjectDir)..\html";"$(ProjectDir)..\bridge";"$(ProjectDir)..\bridge\win";"$(ProjectDir)..\loader";"$(ProjectDir)..\loader\icon";"$(ProjectDir)..\page";"$(ProjectDir)..\platform";"$(ProjectDir)..\platform\sql";"$(ProjectDir)..\platform\win";"$(ProjectDir)..\platform\network";"$(ProjectDir)..\platform\network\win";"$(ProjectDir)..\platform\cf";"$(ProjectDir)..\platform\network\cf";"$(ProjectDir)..\platform\graphics";"$(ProjectDir)..\platform\graphics\cairo";"$(ProjectDir)..\platform\graphics\cg";"$(ProjectDir)..\platform\graphics\win";"$(ProjectDir)..\platform\image-decoders";"$(ProjectDir)..\platform\image-decoders\bmp";"$(ProjectDir)..\platform\image-decoders\gif";"$(ProjectDir)..\platform\image-decoders\ico";"$(ProjectDir)..\platform\image-decoders\jpeg";"$(ProjectDir)..\platform\image-decoders\png";"$(ProjectDir)..\platform\image-decoders\xbm";"$(ProjectDir)..\platform\image-decoders\zlib";"$(ProjectDir)..\xml";"$(WebKitOutputDir)\obj\WebCore\DerivedSources";"$(ProjectDir)..\plugins\win";"$(ProjectDir)..\platform\cairo\pixman\src";"$(ProjectDir)..\platform\cairo\cairo\src";"$(ProjectDir)..\platform\graphics\svg";"$(ProjectDir)..\platform\graphics\svg\cg";"$(ProjectDir)..\platform\graphics\svg\filters";"$(ProjectDir)..\kcanvas";"$(ProjectDir)..\kcanvas\device";"$(ProjectDir)..\kcanvas\device\quartz";"$(ProjectDir)..\ksvg2";"$(ProjectDir)..\ksvg2\css";"$(ProjectDir)..\ksvg2\events";"$(ProjectDir)..\ksvg2\misc";"$(ProjectDir)..\ksvg2\svg";"$(ProjectDir)..\storage";"$(WebKitOutputDir)\include";"$(WebKitOutputDir)\include\JavaScriptCore";"$(ProjectDir)..\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\icu";"$(WebKitLibrariesDir)\include\iconv";"$(WebKitLibrariesDir)\include\pthreads";"$(WebKitLibrariesDir)\include\sqlite";"$(WebKitLibrariesDir)\include\JavaScriptCore";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders";"$(WebKitLibrariesDir)\Include\CoreFoundation\OSXCompatibilityHeaders\GNUCompatibility""\r
PreprocessorDefinitions="WIN32;__WIN32__;_SCL_SECURE_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ENABLE_XSLT;ENABLE_XPATH;ENABLE_SVG;ENABLE_SVG_EXPERIMENTAL_FEATURES;WEBCORE_CONTEXT_MENUS;USE_SAFARI_THEME"\r
MinimalRebuild="true"\r
ExceptionHandling="0"\r
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSCSSValueList.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSDatabase.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSDatabase.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSDocument.cpp"\r
>\r
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSScreen.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSSQLCallback.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSSQLCallback.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSSQLResultSet.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSSQLResultSet.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSSQLResultSetRowList.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSSQLResultSetRowList.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="$(WebKitOutputDir)\obj\$(ProjectName)\DerivedSources\JSStyleSheet.cpp"\r
>\r
>\r
</File>\r
</Filter>\r
+ <Filter\r
+ Name="sql"\r
+ >\r
+ <File\r
+ RelativePath="..\platform\sql\SQLAuthorizer.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\platform\sql\SQLAuthorizer.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\platform\sql\SQLValue.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\platform\sql\SQLValue.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
</Filter>\r
<Filter\r
Name="css"\r
RelativePath="..\bindings\js\JSCSSValueCustom.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\bindings\js\JSCustomSQLCallback.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\bindings\js\JSCustomSQLCallback.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\bindings\js\JSCustomVersionChangeCallback.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\bindings\js\JSCustomVersionChangeCallback.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\bindings\js\JSCustomXPathNSResolver.cpp"\r
>\r
RelativePath="..\bindings\js\JSCustomXPathNSResolver.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\bindings\js\JSDatabaseCustom.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\bindings\js\JSDocumentCustom.cpp"\r
>\r
RelativePath="..\bindings\js\JSNodeListCustom.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\bindings\js\JSSQLResultSetRowListCustom.cpp"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\bindings\js\JSStyleSheetCustom.cpp"\r
>\r
RelativePath="..\ForwardingHeaders\wtf\Assertions.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\ForwardingHeaders\wtf\Deque.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\ForwardingHeaders\wtf\FastMalloc.h"\r
>\r
>\r
</File>\r
</Filter>\r
+ <Filter\r
+ Name="storage"\r
+ >\r
+ <File\r
+ RelativePath="..\storage\Database.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\Database.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseAuthorizer.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseAuthorizer.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseCallback.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseCallback.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseTask.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseTask.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseThread.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseThread.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseTracker.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\DatabaseTracker.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\SQLCallback.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\SQLResultSet.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\SQLResultSet.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\SQLResultSetRowList.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\SQLResultSetRowList.h"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\storage\VersionChangeCallback.h"\r
+ >\r
+ </File>\r
+ </Filter>\r
<File\r
RelativePath="..\config.h"\r
>\r
1A1D13810A5325520064BF5F /* DOMXPath.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1A1D137F0A5325520064BF5F /* DOMXPath.mm */; };
1A2A68230B5BEDE70002A480 /* ProgressTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A68210B5BEDE70002A480 /* ProgressTracker.cpp */; };
1A2A68240B5BEDE70002A480 /* ProgressTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2A68220B5BEDE70002A480 /* ProgressTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1A2E6E590CC55213004A2062 /* SQLValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2E6E570CC55213004A2062 /* SQLValue.cpp */; };
+ 1A2E6E5A0CC55213004A2062 /* SQLValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2E6E580CC55213004A2062 /* SQLValue.h */; };
+ 1A2E6E7A0CC556D5004A2062 /* SQLAuthorizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2E6E780CC556D5004A2062 /* SQLAuthorizer.cpp */; };
+ 1A2E6E7B0CC556D5004A2062 /* SQLAuthorizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2E6E790CC556D5004A2062 /* SQLAuthorizer.h */; };
1A2E6FA40CC5795D004A2062 /* ThreadingPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2E6FA30CC5795D004A2062 /* ThreadingPthreads.cpp */; };
+ 1A2E6FF50CC67855004A2062 /* VersionChangeCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2E6FF30CC67855004A2062 /* VersionChangeCallback.h */; };
+ 1A2E6FF80CC6788D004A2062 /* VersionChangeCallback.idl in Resources */ = {isa = PBXBuildFile; fileRef = 1A2E6FF70CC6788D004A2062 /* VersionChangeCallback.idl */; };
+ 1A2E6FFE0CC67907004A2062 /* JSVersionChangeCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2E6FFC0CC67907004A2062 /* JSVersionChangeCallback.cpp */; };
+ 1A2E6FFF0CC67907004A2062 /* JSVersionChangeCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2E6FFD0CC67907004A2062 /* JSVersionChangeCallback.h */; };
+ 1A2E70620CC67CAA004A2062 /* JSCustomVersionChangeCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2E70600CC67CAA004A2062 /* JSCustomVersionChangeCallback.h */; };
+ 1A2E70630CC67CAA004A2062 /* JSCustomVersionChangeCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A2E70610CC67CAA004A2062 /* JSCustomVersionChangeCallback.cpp */; };
1A3178930B20A81600316987 /* SubresourceLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A3178920B20A81600316987 /* SubresourceLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
1A494BFA0A122F4400FDAFC1 /* JSHTMLElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A494BF80A122F4400FDAFC1 /* JSHTMLElement.cpp */; };
1A494BFB0A122F4400FDAFC1 /* JSHTMLElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A494BF90A122F4400FDAFC1 /* JSHTMLElement.h */; };
1ACE53EB0A8D18E70022947D /* XMLSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ACE53E50A8D18E70022947D /* XMLSerializer.h */; };
1ACE53F60A8D19470022947D /* JSXMLSerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ACE53F40A8D19470022947D /* JSXMLSerializer.cpp */; };
1ACE53F70A8D19470022947D /* JSXMLSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ACE53F50A8D19470022947D /* JSXMLSerializer.h */; };
+ 1AD51A140CB59CD300953D11 /* DatabaseTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AD51A120CB59CD300953D11 /* DatabaseTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 1AD51A150CB59CD300953D11 /* DatabaseTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AD51A130CB59CD300953D11 /* DatabaseTracker.cpp */; };
1AE2AA1E0A1CDAB400B42B25 /* JSHTMLAreaElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE2AA0A0A1CDAB300B42B25 /* JSHTMLAreaElement.cpp */; };
1AE2AA1F0A1CDAB400B42B25 /* JSHTMLAreaElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AE2AA0B0A1CDAB300B42B25 /* JSHTMLAreaElement.h */; };
1AE2AA200A1CDAB400B42B25 /* JSHTMLBaseFontElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE2AA0C0A1CDAB300B42B25 /* JSHTMLBaseFontElement.cpp */; };
1AE2AEE70A1D2A7500B42B25 /* JSHTMLBlockquoteElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AE2AEE50A1D2A7500B42B25 /* JSHTMLBlockquoteElement.h */; };
1AE42F6A0AA4B8CB00C8612D /* StringCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE42F680AA4B8CB00C8612D /* StringCF.cpp */; };
1AE42F6B0AA4B8CB00C8612D /* StringImplCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE42F690AA4B8CB00C8612D /* StringImplCF.cpp */; };
+ 1AE82F8F0CAAFA9D002237AE /* JSDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE82F8D0CAAFA9D002237AE /* JSDatabase.cpp */; };
+ 1AE82F900CAAFA9D002237AE /* JSDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AE82F8E0CAAFA9D002237AE /* JSDatabase.h */; };
+ 1AE82FEC0CAB07EE002237AE /* JSSQLResultSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE82FEA0CAB07EE002237AE /* JSSQLResultSet.cpp */; };
+ 1AE82FED0CAB07EE002237AE /* JSSQLResultSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AE82FEB0CAB07EE002237AE /* JSSQLResultSet.h */; };
+ 1AE8301D0CAB0999002237AE /* JSSQLCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE8301B0CAB0999002237AE /* JSSQLCallback.cpp */; };
+ 1AE8301E0CAB0999002237AE /* JSSQLCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AE8301C0CAB0999002237AE /* JSSQLCallback.h */; };
+ 1AE830440CAB0ED1002237AE /* JSDatabaseCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE830420CAB0ED1002237AE /* JSDatabaseCustom.cpp */; };
+ 1AE831060CAB166E002237AE /* JSCustomSQLCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AE831040CAB166E002237AE /* JSCustomSQLCallback.h */; };
+ 1AE831070CAB166E002237AE /* JSCustomSQLCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AE831050CAB166E002237AE /* JSCustomSQLCallback.cpp */; };
+ 1AFE117D0CBFFB36003017FA /* SQLResultSetRowList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFE117B0CBFFB36003017FA /* SQLResultSetRowList.cpp */; };
+ 1AFE117E0CBFFB36003017FA /* SQLResultSetRowList.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AFE117C0CBFFB36003017FA /* SQLResultSetRowList.h */; };
+ 1AFE118D0CBFFC4E003017FA /* SQLResultSetRowList.idl in Resources */ = {isa = PBXBuildFile; fileRef = 1AFE118C0CBFFC4E003017FA /* SQLResultSetRowList.idl */; };
+ 1AFE11990CBFFCC4003017FA /* JSSQLResultSetRowList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AFE11970CBFFCC4003017FA /* JSSQLResultSetRowList.cpp */; };
+ 1AFE119A0CBFFCC4003017FA /* JSSQLResultSetRowList.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AFE11980CBFFCC4003017FA /* JSSQLResultSetRowList.h */; };
1C11CCB50AA6093700DADB20 /* DOMNotation.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85CA96E80A9624E900690CCF /* DOMNotation.h */; };
1C11CCB60AA6093700DADB20 /* DOMComment.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85089CD10A98C42700A275AA /* DOMComment.h */; };
1C11CCB70AA6093700DADB20 /* DOMNamedNodeMap.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 8518DD760A9CF31B0091B7A6 /* DOMNamedNodeMap.h */; };
513F14540AB634C400094DDF /* IconLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 513F14520AB634C400094DDF /* IconLoader.h */; };
514B3F730C722047000530DF /* FileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 514B3F720C722047000530DF /* FileSystem.h */; };
514B3F760C722055000530DF /* FileSystemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 514B3F750C722055000530DF /* FileSystemMac.mm */; };
+ 5160300B0CC4251200C8AC25 /* FileSystemPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5160300A0CC4251200C8AC25 /* FileSystemPOSIX.cpp */; };
+ 5160306C0CC4362300C8AC25 /* FileSystemCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5160306B0CC4362300C8AC25 /* FileSystemCF.cpp */; };
5160F3BC0B0A99C900C1D2AF /* CachedPageMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160F3BB0B0A99C900C1D2AF /* CachedPageMac.mm */; };
5160F4980B0AA75F00C1D2AF /* HistoryItemMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */; };
51741D0F0B07259A00ED442C /* BackForwardList.h in Headers */ = {isa = PBXBuildFile; fileRef = 51741D0B0B07259A00ED442C /* BackForwardList.h */; settings = {ATTRIBUTES = (Private, ); }; };
51741D100B07259A00ED442C /* BackForwardList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51741D0C0B07259A00ED442C /* BackForwardList.cpp */; };
51741D110B07259A00ED442C /* HistoryItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 51741D0D0B07259A00ED442C /* HistoryItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
51741D120B07259A00ED442C /* HistoryItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51741D0E0B07259A00ED442C /* HistoryItem.cpp */; };
+ 5196116A0CAC56570010A80C /* Database.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5196115E0CAC56570010A80C /* Database.cpp */; };
+ 5196116B0CAC56570010A80C /* Database.h in Headers */ = {isa = PBXBuildFile; fileRef = 5196115F0CAC56570010A80C /* Database.h */; };
+ 5196116D0CAC56570010A80C /* DatabaseThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 519611610CAC56570010A80C /* DatabaseThread.cpp */; };
+ 519611710CAC56570010A80C /* SQLCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 519611650CAC56570010A80C /* SQLCallback.h */; };
+ 519611730CAC56570010A80C /* SQLResultSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 519611670CAC56570010A80C /* SQLResultSet.cpp */; };
+ 519611740CAC56570010A80C /* SQLResultSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 519611680CAC56570010A80C /* SQLResultSet.h */; };
+ 519611780CAC56A80010A80C /* DatabaseThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 519611620CAC56570010A80C /* DatabaseThread.h */; };
+ 519611EA0CAC749C0010A80C /* DatabaseTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 519611E80CAC749C0010A80C /* DatabaseTask.h */; };
+ 519611EB0CAC749C0010A80C /* DatabaseTask.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 519611E90CAC749C0010A80C /* DatabaseTask.cpp */; };
+ 51A45B560CAD7FD7000D2BE9 /* DatabaseAuthorizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 51A45B540CAD7FD7000D2BE9 /* DatabaseAuthorizer.h */; };
+ 51A45B570CAD7FD7000D2BE9 /* DatabaseAuthorizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51A45B550CAD7FD7000D2BE9 /* DatabaseAuthorizer.cpp */; };
51AA3F6F0BD5AA9E00892971 /* ResourceLoaderMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51AA3F6E0BD5AA9E00892971 /* ResourceLoaderMac.mm */; };
51C81B890C4422F70019ECE3 /* FTPDirectoryParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51C81B870C4422F70019ECE3 /* FTPDirectoryParser.cpp */; };
51C81B8A0C4422F70019ECE3 /* FTPDirectoryParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 51C81B880C4422F70019ECE3 /* FTPDirectoryParser.h */; };
51D3EA160A3D24D300BADA35 /* SQLDatabase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51D3EA130A3D24D300BADA35 /* SQLDatabase.cpp */; };
51D3EA170A3D24D300BADA35 /* SQLDatabase.h in Headers */ = {isa = PBXBuildFile; fileRef = 51D3EA140A3D24D300BADA35 /* SQLDatabase.h */; settings = {ATTRIBUTES = (Private, ); }; };
51D3EA180A3D24D300BADA35 /* SQLStatement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51D3EA150A3D24D300BADA35 /* SQLStatement.cpp */; };
+ 51DCE8020CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51DCE8010CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp */; };
51DF6D7E0B92A16D00C2DC85 /* ThreadCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 51DF6D7D0B92A16D00C2DC85 /* ThreadCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
51DF6D800B92A18E00C2DC85 /* ThreadCheck.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51DF6D7F0B92A18E00C2DC85 /* ThreadCheck.mm */; };
51E1ECAF0C91C54600DC255B /* AutodrainedPool.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51E1ECAD0C91C54600DC255B /* AutodrainedPool.mm */; };
51E1ECC30C91C90400DC255B /* PageURLRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E1ECBD0C91C90400DC255B /* PageURLRecord.h */; };
51E4ADB60C42B4CF0042BC55 /* FTPDirectoryDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51E4ADB20C42B4CF0042BC55 /* FTPDirectoryDocument.cpp */; };
51E4ADB70C42B4CF0042BC55 /* FTPDirectoryDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E4ADB30C42B4CF0042BC55 /* FTPDirectoryDocument.h */; };
+ 51EC054F0CC6A615001DA88F /* DatabaseCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 51EC054E0CC6A615001DA88F /* DatabaseCallback.h */; };
+ 51EC05510CC6ACBA001DA88F /* DatabaseCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51EC05500CC6ACBA001DA88F /* DatabaseCallback.cpp */; };
51F11E150A48C2920034A24E /* SQLTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51F11E140A48C2920034A24E /* SQLTransaction.cpp */; };
550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 550A0BC7085F6039007353D6 /* QualifiedName.cpp */; };
550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */ = {isa = PBXBuildFile; fileRef = 550A0BC8085F6039007353D6 /* QualifiedName.h */; settings = {ATTRIBUTES = (Private, ); }; };
1A1D137F0A5325520064BF5F /* DOMXPath.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMXPath.mm; sourceTree = "<group>"; };
1A2A68210B5BEDE70002A480 /* ProgressTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProgressTracker.cpp; sourceTree = "<group>"; };
1A2A68220B5BEDE70002A480 /* ProgressTracker.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProgressTracker.h; sourceTree = "<group>"; };
+ 1A2E6E570CC55213004A2062 /* SQLValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLValue.cpp; path = sql/SQLValue.cpp; sourceTree = "<group>"; };
+ 1A2E6E580CC55213004A2062 /* SQLValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLValue.h; path = sql/SQLValue.h; sourceTree = "<group>"; };
+ 1A2E6E780CC556D5004A2062 /* SQLAuthorizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLAuthorizer.cpp; path = sql/SQLAuthorizer.cpp; sourceTree = "<group>"; };
+ 1A2E6E790CC556D5004A2062 /* SQLAuthorizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLAuthorizer.h; path = sql/SQLAuthorizer.h; sourceTree = "<group>"; };
1A2E6FA30CC5795D004A2062 /* ThreadingPthreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadingPthreads.cpp; path = pthreads/ThreadingPthreads.cpp; sourceTree = "<group>"; };
+ 1A2E6FF30CC67855004A2062 /* VersionChangeCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VersionChangeCallback.h; sourceTree = "<group>"; };
+ 1A2E6FF70CC6788D004A2062 /* VersionChangeCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VersionChangeCallback.idl; sourceTree = "<group>"; };
+ 1A2E6FFC0CC67907004A2062 /* JSVersionChangeCallback.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = JSVersionChangeCallback.cpp; sourceTree = "<group>"; };
+ 1A2E6FFD0CC67907004A2062 /* JSVersionChangeCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVersionChangeCallback.h; sourceTree = "<group>"; };
+ 1A2E70600CC67CAA004A2062 /* JSCustomVersionChangeCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomVersionChangeCallback.h; sourceTree = "<group>"; };
+ 1A2E70610CC67CAA004A2062 /* JSCustomVersionChangeCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomVersionChangeCallback.cpp; sourceTree = "<group>"; };
1A3178920B20A81600316987 /* SubresourceLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubresourceLoaderClient.h; sourceTree = "<group>"; };
1A494BBB0A122DCD00FDAFC1 /* HTMLElement.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = HTMLElement.idl; sourceTree = "<group>"; };
1A494BF80A122F4400FDAFC1 /* JSHTMLElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLElement.cpp; sourceTree = "<group>"; };
1ACE53E60A8D18E70022947D /* XMLSerializer.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = XMLSerializer.idl; sourceTree = "<group>"; };
1ACE53F40A8D19470022947D /* JSXMLSerializer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSXMLSerializer.cpp; sourceTree = "<group>"; };
1ACE53F50A8D19470022947D /* JSXMLSerializer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSXMLSerializer.h; sourceTree = "<group>"; };
+ 1AD51A120CB59CD300953D11 /* DatabaseTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseTracker.h; sourceTree = "<group>"; };
+ 1AD51A130CB59CD300953D11 /* DatabaseTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseTracker.cpp; sourceTree = "<group>"; };
1AE2A9F00A1CDA5700B42B25 /* HTMLAreaElement.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = HTMLAreaElement.idl; sourceTree = "<group>"; };
1AE2A9F10A1CDA5700B42B25 /* HTMLBaseFontElement.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = HTMLBaseFontElement.idl; sourceTree = "<group>"; };
1AE2A9F20A1CDA5700B42B25 /* HTMLBodyElement.idl */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = HTMLBodyElement.idl; sourceTree = "<group>"; };
1AE2AEE50A1D2A7500B42B25 /* JSHTMLBlockquoteElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSHTMLBlockquoteElement.h; sourceTree = "<group>"; };
1AE42F680AA4B8CB00C8612D /* StringCF.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = StringCF.cpp; sourceTree = "<group>"; };
1AE42F690AA4B8CB00C8612D /* StringImplCF.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = StringImplCF.cpp; sourceTree = "<group>"; };
+ 1AE82F8D0CAAFA9D002237AE /* JSDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDatabase.cpp; sourceTree = "<group>"; };
+ 1AE82F8E0CAAFA9D002237AE /* JSDatabase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDatabase.h; sourceTree = "<group>"; };
+ 1AE82FEA0CAB07EE002237AE /* JSSQLResultSet.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = JSSQLResultSet.cpp; sourceTree = "<group>"; };
+ 1AE82FEB0CAB07EE002237AE /* JSSQLResultSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSQLResultSet.h; sourceTree = "<group>"; };
+ 1AE8301B0CAB0999002237AE /* JSSQLCallback.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = JSSQLCallback.cpp; sourceTree = "<group>"; };
+ 1AE8301C0CAB0999002237AE /* JSSQLCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSQLCallback.h; sourceTree = "<group>"; };
+ 1AE830420CAB0ED1002237AE /* JSDatabaseCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDatabaseCustom.cpp; sourceTree = "<group>"; };
+ 1AE831040CAB166E002237AE /* JSCustomSQLCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomSQLCallback.h; sourceTree = "<group>"; };
+ 1AE831050CAB166E002237AE /* JSCustomSQLCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCustomSQLCallback.cpp; sourceTree = "<group>"; };
+ 1AFE117B0CBFFB36003017FA /* SQLResultSetRowList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLResultSetRowList.cpp; sourceTree = "<group>"; };
+ 1AFE117C0CBFFB36003017FA /* SQLResultSetRowList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLResultSetRowList.h; sourceTree = "<group>"; };
+ 1AFE118C0CBFFC4E003017FA /* SQLResultSetRowList.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLResultSetRowList.idl; sourceTree = "<group>"; };
+ 1AFE11970CBFFCC4003017FA /* JSSQLResultSetRowList.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.cpp; fileEncoding = 4; path = JSSQLResultSetRowList.cpp; sourceTree = "<group>"; };
+ 1AFE11980CBFFCC4003017FA /* JSSQLResultSetRowList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSSQLResultSetRowList.h; sourceTree = "<group>"; };
1C14E7690AD8C81C00B6158B /* deleteButtonPressed.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = deleteButtonPressed.tiff; sourceTree = "<group>"; };
1C14E76A0AD8C81C00B6158B /* deleteButton.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = deleteButton.tiff; sourceTree = "<group>"; };
1C4C8EFF0AD85D87009475CE /* DeleteButtonController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeleteButtonController.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
514B3F750C722055000530DF /* FileSystemMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FileSystemMac.mm; sourceTree = "<group>"; };
5150C2A10702629000AF642C /* WebDashboardRegion.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebDashboardRegion.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
5150C2A50702629800AF642C /* WebDashboardRegion.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebDashboardRegion.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+ 5160300A0CC4251200C8AC25 /* FileSystemPOSIX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystemPOSIX.cpp; sourceTree = "<group>"; };
+ 5160306B0CC4362300C8AC25 /* FileSystemCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FileSystemCF.cpp; sourceTree = "<group>"; };
5160F3BB0B0A99C900C1D2AF /* CachedPageMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = CachedPageMac.mm; path = mac/CachedPageMac.mm; sourceTree = "<group>"; };
5160F4970B0AA75F00C1D2AF /* HistoryItemMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = HistoryItemMac.mm; path = mac/HistoryItemMac.mm; sourceTree = "<group>"; };
51741D0B0B07259A00ED442C /* BackForwardList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackForwardList.h; sourceTree = "<group>"; };
51741D0C0B07259A00ED442C /* BackForwardList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackForwardList.cpp; sourceTree = "<group>"; };
51741D0D0B07259A00ED442C /* HistoryItem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HistoryItem.h; sourceTree = "<group>"; };
51741D0E0B07259A00ED442C /* HistoryItem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = HistoryItem.cpp; sourceTree = "<group>"; };
+ 5196115E0CAC56570010A80C /* Database.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Database.cpp; sourceTree = "<group>"; };
+ 5196115F0CAC56570010A80C /* Database.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Database.h; sourceTree = "<group>"; };
+ 519611600CAC56570010A80C /* Database.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Database.idl; sourceTree = "<group>"; };
+ 519611610CAC56570010A80C /* DatabaseThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseThread.cpp; sourceTree = "<group>"; };
+ 519611620CAC56570010A80C /* DatabaseThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseThread.h; sourceTree = "<group>"; };
+ 519611650CAC56570010A80C /* SQLCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLCallback.h; sourceTree = "<group>"; };
+ 519611660CAC56570010A80C /* SQLCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLCallback.idl; sourceTree = "<group>"; };
+ 519611670CAC56570010A80C /* SQLResultSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLResultSet.cpp; sourceTree = "<group>"; };
+ 519611680CAC56570010A80C /* SQLResultSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLResultSet.h; sourceTree = "<group>"; };
+ 519611690CAC56570010A80C /* SQLResultSet.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SQLResultSet.idl; sourceTree = "<group>"; };
+ 519611E80CAC749C0010A80C /* DatabaseTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseTask.h; sourceTree = "<group>"; };
+ 519611E90CAC749C0010A80C /* DatabaseTask.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseTask.cpp; sourceTree = "<group>"; };
+ 51A45B540CAD7FD7000D2BE9 /* DatabaseAuthorizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseAuthorizer.h; sourceTree = "<group>"; };
+ 51A45B550CAD7FD7000D2BE9 /* DatabaseAuthorizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseAuthorizer.cpp; sourceTree = "<group>"; };
51AA3F6E0BD5AA9E00892971 /* ResourceLoaderMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceLoaderMac.mm; sourceTree = "<group>"; };
51C81B870C4422F70019ECE3 /* FTPDirectoryParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectoryParser.cpp; sourceTree = "<group>"; };
51C81B880C4422F70019ECE3 /* FTPDirectoryParser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FTPDirectoryParser.h; sourceTree = "<group>"; };
51D3EA130A3D24D300BADA35 /* SQLDatabase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SQLDatabase.cpp; sourceTree = "<group>"; };
51D3EA140A3D24D300BADA35 /* SQLDatabase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SQLDatabase.h; sourceTree = "<group>"; };
51D3EA150A3D24D300BADA35 /* SQLStatement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SQLStatement.cpp; sourceTree = "<group>"; };
+ 51DCE8010CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSQLResultSetRowListCustom.cpp; sourceTree = "<group>"; };
51DF6D7D0B92A16D00C2DC85 /* ThreadCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadCheck.h; sourceTree = "<group>"; };
51DF6D7F0B92A18E00C2DC85 /* ThreadCheck.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ThreadCheck.mm; sourceTree = "<group>"; };
51E1ECAD0C91C54600DC255B /* AutodrainedPool.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AutodrainedPool.mm; sourceTree = "<group>"; };
51E1ECBD0C91C90400DC255B /* PageURLRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageURLRecord.h; sourceTree = "<group>"; };
51E4ADB20C42B4CF0042BC55 /* FTPDirectoryDocument.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FTPDirectoryDocument.cpp; sourceTree = "<group>"; };
51E4ADB30C42B4CF0042BC55 /* FTPDirectoryDocument.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FTPDirectoryDocument.h; sourceTree = "<group>"; };
+ 51EC054E0CC6A615001DA88F /* DatabaseCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatabaseCallback.h; sourceTree = "<group>"; };
+ 51EC05500CC6ACBA001DA88F /* DatabaseCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseCallback.cpp; sourceTree = "<group>"; };
51F11E140A48C2920034A24E /* SQLTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SQLTransaction.cpp; sourceTree = "<group>"; };
51F6A3D50663BF04004D2919 /* HTMLCanvasElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLCanvasElement.cpp; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
51F6A3D60663BF04004D2919 /* HTMLCanvasElement.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HTMLCanvasElement.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
65BF02180974806300C43196 /* page */,
BCF1A5BA097832090061A123 /* platform */,
F523D2F302DE443B018635CA /* rendering */,
+ 1AE82EC90CAAE177002237AE /* storage */,
E1F0424309839389006694EA /* xml */,
656580EC09D12B20000E61D7 /* Derived Sources */,
089C1665FE841158C02AAC07 /* Resources */,
14CF78A509F58CD800EB3665 /* JSCSSValue.h */,
A8D05FA90A23B30F005E7203 /* JSCSSValueList.cpp */,
A8D05FAA0A23B30F005E7203 /* JSCSSValueList.h */,
+ 1AE82F8D0CAAFA9D002237AE /* JSDatabase.cpp */,
+ 1AE82F8E0CAAFA9D002237AE /* JSDatabase.h */,
659DDC8009E198BA001BF3C6 /* JSDocument.cpp */,
659DDC8109E198BA001BF3C6 /* JSDocument.h */,
1A494EDC0A123F4C00FDAFC1 /* JSDocumentFragment.cpp */,
BCFE2F100C1B58370020235F /* JSRect.h */,
BCEC01C00C274DDD009F4EC9 /* JSScreen.cpp */,
BCEC01C10C274DDD009F4EC9 /* JSScreen.h */,
+ 1AE8301B0CAB0999002237AE /* JSSQLCallback.cpp */,
+ 1AE8301C0CAB0999002237AE /* JSSQLCallback.h */,
+ 1AE82FEA0CAB07EE002237AE /* JSSQLResultSet.cpp */,
+ 1AE82FEB0CAB07EE002237AE /* JSSQLResultSet.h */,
+ 1AFE11970CBFFCC4003017FA /* JSSQLResultSetRowList.cpp */,
+ 1AFE11980CBFFCC4003017FA /* JSSQLResultSetRowList.h */,
BCE013980C0BEF180043860A /* JSStyleSheet.cpp */,
BCE013990C0BEF180043860A /* JSStyleSheet.h */,
A84EBD820CB8C97700079609 /* JSStyleSheetList.cpp */,
1A750D5B0A90DEE1000FF215 /* JSTreeWalker.h */,
A86629CA09DA2B47009633A5 /* JSUIEvent.cpp */,
A86629C909DA2B47009633A5 /* JSUIEvent.h */,
+ 1A2E6FFC0CC67907004A2062 /* JSVersionChangeCallback.cpp */,
+ 1A2E6FFD0CC67907004A2062 /* JSVersionChangeCallback.h */,
65DF31F109D1CC60000BE325 /* JSWheelEvent.cpp */,
65DF31F209D1CC60000BE325 /* JSWheelEvent.h */,
656581D709D1508D000E61D7 /* JSXMLHttpRequest.lut.h */,
path = DerivedSources/WebCore;
sourceTree = BUILT_PRODUCTS_DIR;
};
+ 1A2E6E560CC551E0004A2062 /* sql */ = {
+ isa = PBXGroup;
+ children = (
+ 1A2E6E780CC556D5004A2062 /* SQLAuthorizer.cpp */,
+ 1A2E6E790CC556D5004A2062 /* SQLAuthorizer.h */,
+ 1A2E6E570CC55213004A2062 /* SQLValue.cpp */,
+ 1A2E6E580CC55213004A2062 /* SQLValue.h */,
+ );
+ name = sql;
+ sourceTree = "<group>";
+ };
1AE42F670AA4B8CB00C8612D /* cf */ = {
isa = PBXGroup;
children = (
1A98956A0AA78F80005EF5EF /* KURLCFNet.cpp */,
1AE42F680AA4B8CB00C8612D /* StringCF.cpp */,
1AE42F690AA4B8CB00C8612D /* StringImplCF.cpp */,
+ 5160306B0CC4362300C8AC25 /* FileSystemCF.cpp */,
);
path = cf;
sourceTree = "<group>";
};
+ 1AE82EC90CAAE177002237AE /* storage */ = {
+ isa = PBXGroup;
+ children = (
+ 5196115E0CAC56570010A80C /* Database.cpp */,
+ 5196115F0CAC56570010A80C /* Database.h */,
+ 519611600CAC56570010A80C /* Database.idl */,
+ 51A45B550CAD7FD7000D2BE9 /* DatabaseAuthorizer.cpp */,
+ 51A45B540CAD7FD7000D2BE9 /* DatabaseAuthorizer.h */,
+ 51EC05500CC6ACBA001DA88F /* DatabaseCallback.cpp */,
+ 51EC054E0CC6A615001DA88F /* DatabaseCallback.h */,
+ 519611E90CAC749C0010A80C /* DatabaseTask.cpp */,
+ 519611E80CAC749C0010A80C /* DatabaseTask.h */,
+ 519611610CAC56570010A80C /* DatabaseThread.cpp */,
+ 519611620CAC56570010A80C /* DatabaseThread.h */,
+ 1AD51A130CB59CD300953D11 /* DatabaseTracker.cpp */,
+ 1AD51A120CB59CD300953D11 /* DatabaseTracker.h */,
+ 519611650CAC56570010A80C /* SQLCallback.h */,
+ 519611660CAC56570010A80C /* SQLCallback.idl */,
+ 519611670CAC56570010A80C /* SQLResultSet.cpp */,
+ 519611680CAC56570010A80C /* SQLResultSet.h */,
+ 519611690CAC56570010A80C /* SQLResultSet.idl */,
+ 1AFE117B0CBFFB36003017FA /* SQLResultSetRowList.cpp */,
+ 1AFE117C0CBFFB36003017FA /* SQLResultSetRowList.h */,
+ 1AFE118C0CBFFC4E003017FA /* SQLResultSetRowList.idl */,
+ 1A2E6FF30CC67855004A2062 /* VersionChangeCallback.h */,
+ 1A2E6FF70CC6788D004A2062 /* VersionChangeCallback.idl */,
+ );
+ indentWidth = 4;
+ path = storage;
+ sourceTree = "<group>";
+ tabWidth = 8;
+ usesTabs = 0;
+ };
1CDD44660BA9C80000F90147 /* Configurations */ = {
isa = PBXGroup;
children = (
name = pthreads;
sourceTree = "<group>";
};
+ 516030090CC4245400C8AC25 /* posix */ = {
+ isa = PBXGroup;
+ children = (
+ 5160300A0CC4251200C8AC25 /* FileSystemPOSIX.cpp */,
+ );
+ path = posix;
+ sourceTree = "<group>";
+ };
5160F4920B0AA71500C1D2AF /* mac */ = {
isa = PBXGroup;
children = (
93F8B3060A300FEA00F61AB8 /* CodeGeneratorJS.pm */,
1432E8480C51493F00B1500F /* GCController.cpp */,
1432E8460C51493800B1500F /* GCController.h */,
+ 1AE831050CAB166E002237AE /* JSCustomSQLCallback.cpp */,
+ 1AE831040CAB166E002237AE /* JSCustomSQLCallback.h */,
+ 1A2E70610CC67CAA004A2062 /* JSCustomVersionChangeCallback.cpp */,
+ 1A2E70600CC67CAA004A2062 /* JSCustomVersionChangeCallback.h */,
E10B93C20B73C291003ED890 /* JSCustomXPathNSResolver.cpp */,
E10B937B0B73C00A003ED890 /* JSCustomXPathNSResolver.h */,
BCD9C2680C17AA81005C90A2 /* JSDOMExceptionConstructor.cpp */,
BC46C1ED0C0DDBDF0020CFC3 /* JSCSSRuleCustom.cpp */,
BC5825F20C0B89380053F1B5 /* JSCSSStyleDeclarationCustom.cpp */,
BC20FB7E0C0E8E6C00D1447F /* JSCSSValueCustom.cpp */,
+ 1AE830420CAB0ED1002237AE /* JSDatabaseCustom.cpp */,
929264760B61FC7200B41D34 /* JSDocumentCustom.cpp */,
BCD9C25E0C17AA67005C90A2 /* JSDOMWindowCustom.cpp */,
BC2ED5540C6B9BD300920BFF /* JSElementCustom.cpp */,
BCB773600C17853D00132BA4 /* JSNodeFilterCustom.cpp */,
1A750DD30A90E729000FF215 /* JSNodeIteratorCustom.cpp */,
BCD9C2610C17AA67005C90A2 /* JSNodeListCustom.cpp */,
+ 51DCE8010CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp */,
BC98A27C0C0C9950004BEBF7 /* JSStyleSheetCustom.cpp */,
A84EBD770CB8C89200079609 /* JSStyleSheetListCustom.cpp */,
B25DFAAE0B2E2929000E6510 /* JSSVGMatrixCustom.cpp */,
B2A015910AF6CD53006BCE0E /* graphics */,
6582A14809999D6C00BEEB6D /* mac */,
656B84D70AEA1CE900A095B4 /* network */,
+ 516030090CC4245400C8AC25 /* posix */,
5154498E0CAA35F600194B2D /* pthreads */,
+ 1A2E6E560CC551E0004A2062 /* sql */,
BCFB2F74097A2E1A00BA703D /* Arena.cpp */,
BCFB2F75097A2E1A00BA703D /* Arena.h */,
BCB16B890979B01400467741 /* ArrayImpl.cpp */,
51E1ECC10C91C90400DC255B /* IconRecord.h in Headers */,
51E1ECC30C91C90400DC255B /* PageURLRecord.h in Headers */,
0A4844990CA44CB200B7BD48 /* SoftLinking.h in Headers */,
+ 1AE82F900CAAFA9D002237AE /* JSDatabase.h in Headers */,
+ 1AE82FED0CAB07EE002237AE /* JSSQLResultSet.h in Headers */,
+ 1AE8301E0CAB0999002237AE /* JSSQLCallback.h in Headers */,
+ 1AE831060CAB166E002237AE /* JSCustomSQLCallback.h in Headers */,
+ 5196116B0CAC56570010A80C /* Database.h in Headers */,
+ 519611710CAC56570010A80C /* SQLCallback.h in Headers */,
+ 519611740CAC56570010A80C /* SQLResultSet.h in Headers */,
+ 519611780CAC56A80010A80C /* DatabaseThread.h in Headers */,
+ 519611EA0CAC749C0010A80C /* DatabaseTask.h in Headers */,
+ 51A45B560CAD7FD7000D2BE9 /* DatabaseAuthorizer.h in Headers */,
+ 1AD51A140CB59CD300953D11 /* DatabaseTracker.h in Headers */,
+ 1AFE117E0CBFFB36003017FA /* SQLResultSetRowList.h in Headers */,
+ 1AFE119A0CBFFCC4003017FA /* JSSQLResultSetRowList.h in Headers */,
A8F4FB940C169E7B002AFED5 /* SVGRenderSupport.h in Headers */,
AA31B5B50C1DFD1000AE7083 /* RenderSVGRoot.h in Headers */,
B266CD4E0C3AEC6500EB08D2 /* JSSVGException.h in Headers */,
A8A909AC0CBCD6B50029B807 /* RenderSVGTransformableContainer.h in Headers */,
BC9ADD230CC4032600098C4C /* CSSTransformValue.h in Headers */,
E1ED8AC30CC49BE000BFC557 /* CSSPrimitiveValueMappings.h in Headers */,
+ 1A2E6E5A0CC55213004A2062 /* SQLValue.h in Headers */,
+ 1A2E6E7B0CC556D5004A2062 /* SQLAuthorizer.h in Headers */,
+ 1A2E6FF50CC67855004A2062 /* VersionChangeCallback.h in Headers */,
+ 1A2E6FFF0CC67907004A2062 /* JSVersionChangeCallback.h in Headers */,
+ 1A2E70620CC67CAA004A2062 /* JSCustomVersionChangeCallback.h in Headers */,
+ 51EC054F0CC6A615001DA88F /* DatabaseCallback.h in Headers */,
BC014C750CC5579D009C4B20 /* SecurityOrigin.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
knownRegions = (
English,
06693F7B0BFBC91700216072 /* inspector in Resources */,
1AB1AE7A0C051FDE00139F4F /* zoomInCursor.png in Resources */,
1AB1AE7B0C051FDE00139F4F /* zoomOutCursor.png in Resources */,
+ 1AFE118D0CBFFC4E003017FA /* SQLResultSetRowList.idl in Resources */,
+ 1A2E6FF80CC6788D004A2062 /* VersionChangeCallback.idl in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
51E1ECB00C91C54600DC255B /* Threading.mm in Sources */,
51E1ECC00C91C90400DC255B /* IconRecord.cpp in Sources */,
51E1ECC20C91C90400DC255B /* PageURLRecord.cpp in Sources */,
+ 1AE82F8F0CAAFA9D002237AE /* JSDatabase.cpp in Sources */,
+ 1AE82FEC0CAB07EE002237AE /* JSSQLResultSet.cpp in Sources */,
+ 1AE8301D0CAB0999002237AE /* JSSQLCallback.cpp in Sources */,
+ 1AE830440CAB0ED1002237AE /* JSDatabaseCustom.cpp in Sources */,
+ 1AE831070CAB166E002237AE /* JSCustomSQLCallback.cpp in Sources */,
+ 5196116A0CAC56570010A80C /* Database.cpp in Sources */,
+ 5196116D0CAC56570010A80C /* DatabaseThread.cpp in Sources */,
+ 519611730CAC56570010A80C /* SQLResultSet.cpp in Sources */,
+ 519611EB0CAC749C0010A80C /* DatabaseTask.cpp in Sources */,
+ 51DCE8020CAC9F1C00488358 /* JSSQLResultSetRowListCustom.cpp in Sources */,
+ 51A45B570CAD7FD7000D2BE9 /* DatabaseAuthorizer.cpp in Sources */,
+ 1AD51A150CB59CD300953D11 /* DatabaseTracker.cpp in Sources */,
+ 1AFE117D0CBFFB36003017FA /* SQLResultSetRowList.cpp in Sources */,
+ 1AFE11990CBFFCC4003017FA /* JSSQLResultSetRowList.cpp in Sources */,
+ 5160300B0CC4251200C8AC25 /* FileSystemPOSIX.cpp in Sources */,
+ 5160306C0CC4362300C8AC25 /* FileSystemCF.cpp in Sources */,
A8F4FB960C169E85002AFED5 /* SVGRenderSupport.cpp in Sources */,
AA31B5B40C1DFD1000AE7083 /* RenderSVGRoot.cpp in Sources */,
B2D3FC8A0C2212CB00CF3618 /* JSSVGTransformListCustom.cpp in Sources */,
A84EC1390CB9FDBC00079609 /* SVGCSSComputedStyleDeclaration.cpp in Sources */,
A8A909AD0CBCD6B50029B807 /* RenderSVGTransformableContainer.cpp in Sources */,
BC9ADD800CC4092200098C4C /* CSSTransformValue.cpp in Sources */,
+ 1A2E6E590CC55213004A2062 /* SQLValue.cpp in Sources */,
+ 1A2E6E7A0CC556D5004A2062 /* SQLAuthorizer.cpp in Sources */,
1A2E6FA40CC5795D004A2062 /* ThreadingPthreads.cpp in Sources */,
+ 1A2E6FFE0CC67907004A2062 /* JSVersionChangeCallback.cpp in Sources */,
+ 1A2E70630CC67CAA004A2062 /* JSCustomVersionChangeCallback.cpp in Sources */,
+ 51EC05510CC6ACBA001DA88F /* DatabaseCallback.cpp in Sources */,
BC014C740CC5579D009C4B20 /* SecurityOrigin.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#include "config.h"
+#include "JSCustomSQLCallback.h"
+
+#include "CString.h"
+#include "Frame.h"
+#include "kjs_proxy.h"
+#include "JSSQLResultSet.h"
+#include "Page.h"
+
+namespace WebCore {
+
+using namespace KJS;
+
+JSCustomSQLCallback::JSCustomSQLCallback(JSObject* callback, Frame* frame)
+ : m_callback(callback)
+ , m_frame(frame)
+{
+
+}
+
+void JSCustomSQLCallback::handleEvent(SQLResultSet* resultSet)
+{
+ ASSERT(m_callback);
+ ASSERT(m_frame);
+
+ KJSProxy* proxy = m_frame->scriptProxy();
+ if (!proxy)
+ return;
+
+ ScriptInterpreter* interpreter = proxy->interpreter();
+ ExecState* exec = interpreter->globalExec();
+
+ KJS::JSLock lock;
+
+ JSValue* handleEventFuncValue = m_callback->get(exec, "handleEvent");
+ JSObject* handleEventFunc = 0;
+ if (handleEventFuncValue->isObject()) {
+ handleEventFunc = static_cast<JSObject*>(handleEventFuncValue);
+ if (!handleEventFunc->implementsCall())
+ handleEventFunc = 0;
+ }
+
+ if (!handleEventFunc && !m_callback->implementsCall()) {
+ // FIXME: Should an exception be thrown here?
+ return;
+ }
+
+ RefPtr<JSCustomSQLCallback> protect(this);
+
+ List args;
+ args.append(toJS(exec, resultSet));
+
+ interpreter->startTimeoutCheck();
+ if (handleEventFunc)
+ handleEventFunc->call(exec, m_callback, args);
+ else
+ m_callback->call(exec, m_callback, args);
+ interpreter->stopTimeoutCheck();
+
+ if (exec->hadException()) {
+ JSObject* exception = exec->exception()->toObject(exec);
+ String message = exception->get(exec, exec->propertyNames().message)->toString(exec);
+ int lineNumber = exception->get(exec, "line")->toInt32(exec);
+ String sourceURL = exception->get(exec, "sourceURL")->toString(exec);
+ if (Interpreter::shouldPrintExceptions())
+ printf("SQLCallback: %s\n", message.utf8().data());
+ if (Page* page = m_frame->page())
+ page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL);
+ exec->clearException();
+ }
+
+ Document::updateDocumentsRendering();
+}
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#include "SQLCallback.h"
+
+#include <kjs/object.h>
+#include <kjs/protect.h>
+#include <wtf/Forward.h>
+
+namespace KJS {
+ class JSObject;
+}
+
+namespace WebCore {
+
+class Frame;
+class SQLResultSet;
+
+class JSCustomSQLCallback : public SQLCallback {
+public:
+ JSCustomSQLCallback(KJS::JSObject* callback, Frame*);
+
+ virtual void handleEvent(SQLResultSet*);
+private:
+ KJS::ProtectedPtr<KJS::JSObject> m_callback;
+ RefPtr<Frame> m_frame;
+};
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#include "config.h"
+#include "JSCustomVersionChangeCallback.h"
+
+#include "CString.h"
+#include "Frame.h"
+#include "kjs_proxy.h"
+#include "JSSQLResultSet.h"
+#include "Page.h"
+
+namespace WebCore {
+
+using namespace KJS;
+
+JSCustomVersionChangeCallback::JSCustomVersionChangeCallback(JSObject* callback, Frame* frame)
+ : m_callback(callback)
+ , m_frame(frame)
+{
+
+}
+
+void JSCustomVersionChangeCallback::handleEvent(bool versionChanged)
+{
+ ASSERT(m_callback);
+ ASSERT(m_frame);
+
+ KJSProxy* proxy = m_frame->scriptProxy();
+ if (!proxy)
+ return;
+
+ ScriptInterpreter* interpreter = proxy->interpreter();
+ ExecState* exec = interpreter->globalExec();
+
+ KJS::JSLock lock;
+
+ JSValue* handleEventFuncValue = m_callback->get(exec, "handleEvent");
+ JSObject* handleEventFunc = 0;
+ if (handleEventFuncValue->isObject()) {
+ handleEventFunc = static_cast<JSObject*>(handleEventFuncValue);
+ if (!handleEventFunc->implementsCall())
+ handleEventFunc = 0;
+ }
+
+ if (!handleEventFunc && !m_callback->implementsCall()) {
+ // FIXME: Should an exception be thrown here?
+ return;
+ }
+
+ RefPtr<JSCustomVersionChangeCallback> protect(this);
+
+ List args;
+ args.append(jsBoolean(versionChanged));
+
+ interpreter->startTimeoutCheck();
+ if (handleEventFunc)
+ handleEventFunc->call(exec, m_callback, args);
+ else
+ m_callback->call(exec, m_callback, args);
+ interpreter->stopTimeoutCheck();
+
+ if (exec->hadException()) {
+ JSObject* exception = exec->exception()->toObject(exec);
+ String message = exception->get(exec, exec->propertyNames().message)->toString(exec);
+ int lineNumber = exception->get(exec, "line")->toInt32(exec);
+ String sourceURL = exception->get(exec, "sourceURL")->toString(exec);
+ if (Interpreter::shouldPrintExceptions())
+ printf("VersionChangeCallback: %s\n", message.utf8().data());
+ if (Page* page = m_frame->page())
+ page->chrome()->addMessageToConsole(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL);
+ exec->clearException();
+ }
+
+ Document::updateDocumentsRendering();
+}
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#include "VersionChangeCallback.h"
+
+#include <kjs/object.h>
+#include <kjs/protect.h>
+#include <wtf/Forward.h>
+
+namespace KJS {
+ class JSObject;
+}
+
+namespace WebCore {
+
+ class Frame;
+ class SQLResultSet;
+
+ class JSCustomVersionChangeCallback : public VersionChangeCallback {
+ public:
+ JSCustomVersionChangeCallback(KJS::JSObject* callback, Frame*);
+
+ virtual void handleEvent(bool versionChanges);
+ private:
+ KJS::ProtectedPtr<KJS::JSObject> m_callback;
+ RefPtr<Frame> m_frame;
+ };
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#include "config.h"
+#include "JSDatabase.h"
+
+#include "Database.h"
+#include "Document.h"
+#include "DOMWindow.h"
+#include "ExceptionCode.h"
+#include "kjs_window.h"
+#include "JSCustomSQLCallback.h"
+#include "JSCustomVersionChangeCallback.h"
+#include "PlatformString.h"
+#include "SQLValue.h"
+
+namespace WebCore {
+
+using namespace KJS;
+
+JSValue* JSDatabase::executeSql(ExecState* exec, const List& args)
+{
+ // There has to be at least two arguments
+ if (args.size() < 2) {
+ setDOMException(exec, SYNTAX_ERR);
+ return jsUndefined();
+ }
+
+ String sqlStatement = args[0]->toString(exec);
+
+ // Now assemble the list of SQL arguments
+ Vector<SQLValue> SQLValues;
+
+ for (int i = 0 ; i < args.size() - 2; i++) {
+ JSValue* value = args[i + 1];
+
+ if (value->isNull()) {
+ SQLValues.append(SQLValue());
+ } else if (value->isNumber()) {
+ SQLValues.append(value->getNumber());
+ } else {
+ // Convert the argument to a string and append it
+ SQLValues.append(value->toString(exec));
+ }
+ }
+
+ // REVIEW: This checks that the last argument passed in is a JS Object
+ // (instead of a string or a number for example) and throws a type mismatch exception if it's not.
+ // Should this go into the spec?
+ JSObject* callback = args[args.size() - 1]->getObject();
+ if (!callback) {
+ setDOMException(exec, TYPE_MISMATCH_ERR);
+ return jsUndefined();
+ }
+
+ if (Frame* frame = m_impl->document()->frame()) {
+ ExceptionCode ec = 0;
+ RefPtr<SQLCallback> sqlCallback(new JSCustomSQLCallback(callback, frame));
+ m_impl->executeSql(sqlStatement, SQLValues, sqlCallback, ec);
+ setDOMException(exec, ec);
+ }
+
+ return jsUndefined();
+}
+
+JSValue* JSDatabase::changeVersion(ExecState* exec, const List& args)
+{
+ String oldVersion = args[0]->toString(exec);
+ String newVersion = args[1]->toString(exec);
+
+ JSObject* callback = args[2]->getObject();
+ if (!callback) {
+ setDOMException(exec, TYPE_MISMATCH_ERR);
+ return jsUndefined();
+ }
+
+ if (Frame* frame = m_impl->document()->frame()) {
+ RefPtr<VersionChangeCallback> changeCallback(new JSCustomVersionChangeCallback(callback, frame));
+ m_impl->changeVersion(oldVersion, newVersion, changeCallback.release());
+ }
+
+ return jsUndefined();
+}
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#include "config.h"
+#include "JSSQLResultSetRowList.h"
+
+#include "ExceptionCode.h"
+#include "SQLValue.h"
+#include "SQLResultSetRowList.h"
+
+using namespace KJS;
+
+namespace WebCore {
+
+JSValue* JSSQLResultSetRowList::item(ExecState* exec, const List& args)
+{
+ bool indexOk;
+ int index = args[0]->toInt32(exec, indexOk);
+ if (!indexOk) {
+ setDOMException(exec, TYPE_MISMATCH_ERR);
+ return jsUndefined();
+ }
+ if (index < 0 || (unsigned)index >= m_impl->length()) {
+ setDOMException(exec, INDEX_SIZE_ERR);
+ return jsUndefined();
+ }
+
+ JSObject* object = new JSObject(exec->lexicalInterpreter()->builtinObjectPrototype());
+
+ unsigned numColumns = m_impl->columnNames().size();
+ unsigned valuesIndex = index * numColumns;
+ for (unsigned i = 0; i < numColumns; i++) {
+ const SQLValue& value = m_impl->values()[valuesIndex + i];
+ JSValue* jsValue = 0;
+
+ switch (value.type()) {
+ case SQLValue::StringValue:
+ jsValue = jsString(value.string());
+ break;
+ case SQLValue::NullValue:
+ jsValue = jsNull();
+ break;
+ case SQLValue::NumberValue:
+ jsValue = jsNumber(value.number());
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ object->put(exec, m_impl->columnNames()[i], jsValue, DontDelete | ReadOnly);
+ }
+
+ return object;
+}
+
+}
$type eq "Range" or
$type eq "NodeFilter" or
$type eq "DOMWindow" or
+ $type eq "SQLResultSet" or
$type eq "XPathEvaluator" or
$type eq "XPathNSResolver" or
$type eq "XPathResult" or
#include "CSSValueKeywords.h"
#include "Comment.h"
#include "CookieJar.h"
+#include "DatabaseThread.h"
#include "DOMImplementation.h"
#include "DocLoader.h"
#include "DocumentFragment.h"
, m_isXHTML(isXHTML)
, m_numNodeLists(0)
{
+ printf("Document %p being constructed\n", this);
m_document.resetSkippingRef(this);
m_printing = false;
Document::~Document()
{
+ printf("Document %p is being destroyed\n", this);
ASSERT(!renderer());
ASSERT(!m_inPageCache);
ASSERT(!m_savedRenderer);
for (unsigned i = 0; i < count; i++)
deleteAllValues(m_nameCollectionInfo[i]);
+ if (m_databaseThread) {
+ printf("Destroying document %p which has a database thread\n", this);
+ m_databaseThread->documentGoingAway();
+ m_databaseThread = 0;
+ }
+
if (m_styleSheets)
m_styleSheets->documentDestroyed();
}
element->updateFocusAppearance(false);
}
+DatabaseThread* Document::databaseThread()
+{
+ if (!m_databaseThread) {
+ m_databaseThread = new DatabaseThread(this);
+ if (!m_databaseThread->start())
+ m_databaseThread = 0;
+ }
+
+ return m_databaseThread.get();
+}
+
} // namespace WebCore
class CSSStyleSelector;
class CSSStyleSheet;
class Comment;
+ class DatabaseThread;
class DOMImplementation;
class DOMWindow;
class DocLoader;
bool processingLoadEvent() const { return m_processingLoadEvent; }
+ DatabaseThread* databaseThread();
protected:
void clearXMLVersion() { m_xmlVersion = String(); }
bool m_isXHTML;
unsigned m_numNodeLists;
+
+ RefPtr<DatabaseThread> m_databaseThread;
#if USE(LOW_BANDWIDTH_DISPLAY)
bool m_inLowBandwidthDisplay;
#endif
m_client = client;
}
-bool makeAllDirectories(const String& path)
-{
-#if PLATFORM(WIN_OS)
- String fullPath = path;
- if (!SHCreateDirectoryEx(0, fullPath.charactersWithNullTermination(), 0)) {
- DWORD error = GetLastError();
- if (error != ERROR_FILE_EXISTS && error != ERROR_ALREADY_EXISTS) {
- LOG_ERROR("Failed to create path %s", path.ascii().data());
- return false;
- }
- }
-#else
- CString fullPath = path.utf8();
- if (!access(fullPath.data(), F_OK))
- return true;
-
- char* p = fullPath.mutableData() + 1;
- int length = fullPath.length();
-
- if(p[length - 1] == '/')
- p[length - 1] = '\0';
- for (; *p; ++p)
- if (*p == '/') {
- *p = '\0';
- if (access(fullPath.data(), F_OK))
- if (mkdir(fullPath.data(), S_IRWXU))
- return false;
- *p = '/';
- }
- if (access(fullPath.data(), F_OK))
- if (mkdir(fullPath.data(), S_IRWXU))
- return false;
-#endif
- return true;
-}
-
bool IconDatabase::open(const String& databasePath)
{
ASSERT_NOT_SYNC_THREAD();
m_databaseDirectory = databasePath.copy();
// Formulate the full path for the database file
-#if PLATFORM(WIN_OS)
- if (m_databaseDirectory[m_databaseDirectory.length()] == '\\')
- m_completeDatabasePath = m_databaseDirectory + defaultDatabaseFilename();
- else
- m_completeDatabasePath = m_databaseDirectory + "\\" + defaultDatabaseFilename();
-#else
- if (m_databaseDirectory[m_databaseDirectory.length()] == '/')
- m_completeDatabasePath = m_databaseDirectory + defaultDatabaseFilename();
- else
- m_completeDatabasePath = m_databaseDirectory + "/" + defaultDatabaseFilename();
-#endif
-
+ m_completeDatabasePath = pathByAppendingComponent(m_databaseDirectory, defaultDatabaseFilename());
+
initializeThreading();
// Lock here as well as first thing in the thread so the tread doesn't actually commence until the pthread_create() call
#include "SQLDatabase.h"
#include "Logging.h"
-#include <sqlite3.h>
+#include "SQLAuthorizer.h"
#include "SQLStatement.h"
+#include <sqlite3.h>
namespace WebCore {
-const int SQLResultError = SQLITE_ERROR;
const int SQLResultDone = SQLITE_DONE;
+const int SQLResultError = SQLITE_ERROR;
const int SQLResultOk = SQLITE_OK;
const int SQLResultRow = SQLITE_ROW;
+const int SQLResultSchema = SQLITE_SCHEMA;
+
SQLDatabase::SQLDatabase()
: m_db(0)
#endif
}
+SQLDatabase::~SQLDatabase()
+{
+ close();
+}
+
bool SQLDatabase::open(const String& filename)
{
close();
return sqlite3_errmsg(m_db);
}
+int SQLDatabase::authorizerFunction(void* userData, int actionCode, const char* parameter1, const char* parameter2, const char* /*databaseName*/, const char* /*trigger_or_view*/)
+{
+ SQLAuthorizer* auth = static_cast<SQLAuthorizer*>(userData);
+ ASSERT(auth);
+
+ switch (actionCode) {
+ case SQLITE_CREATE_INDEX:
+ return auth->createIndex(parameter1, parameter2);
+ case SQLITE_CREATE_TABLE:
+ return auth->createTable(parameter1);
+ case SQLITE_CREATE_TEMP_INDEX:
+ return auth->createTempIndex(parameter1, parameter2);
+ case SQLITE_CREATE_TEMP_TABLE:
+ return auth->createTempTable(parameter1);
+ case SQLITE_CREATE_TEMP_TRIGGER:
+ return auth->createTempTrigger(parameter1, parameter2);
+ case SQLITE_CREATE_TEMP_VIEW:
+ return auth->createTempView(parameter1);
+ case SQLITE_CREATE_TRIGGER:
+ return auth->createTrigger(parameter1, parameter2);
+ case SQLITE_CREATE_VIEW:
+ return auth->createView(parameter1);
+ case SQLITE_DELETE:
+ return auth->allowDelete(parameter1);
+ case SQLITE_DROP_INDEX:
+ return auth->dropIndex(parameter1, parameter2);
+ case SQLITE_DROP_TABLE:
+ return auth->dropTable(parameter1);
+ case SQLITE_DROP_TEMP_INDEX:
+ return auth->dropTempIndex(parameter1, parameter2);
+ case SQLITE_DROP_TEMP_TABLE:
+ return auth->dropTempTable(parameter1);
+ case SQLITE_DROP_TEMP_TRIGGER:
+ return auth->dropTempTrigger(parameter1, parameter2);
+ case SQLITE_DROP_TEMP_VIEW:
+ return auth->dropTempView(parameter1);
+ case SQLITE_DROP_TRIGGER:
+ return auth->dropTrigger(parameter1, parameter2);
+ case SQLITE_DROP_VIEW:
+ return auth->dropView(parameter1);
+ case SQLITE_INSERT:
+ return auth->allowInsert(parameter1);
+ case SQLITE_PRAGMA:
+ return auth->allowPragma(parameter1, parameter2);
+ case SQLITE_READ:
+ return auth->allowRead(parameter1, parameter2);
+ case SQLITE_SELECT:
+ return auth->allowSelect();
+ case SQLITE_TRANSACTION:
+ return auth->allowTransaction();
+ case SQLITE_UPDATE:
+ return auth->allowUpdate(parameter1, parameter2);
+ case SQLITE_ATTACH:
+ return auth->allowAttach(parameter1);
+ case SQLITE_DETACH:
+ return auth->allowDetach(parameter1);
+ case SQLITE_ALTER_TABLE:
+ return auth->allowAlterTable(parameter1, parameter2);
+ case SQLITE_REINDEX:
+ return auth->allowReindex(parameter1);
+ case SQLITE_ANALYZE:
+ return auth->allowAnalyze(parameter1);
+ case SQLITE_CREATE_VTABLE:
+ return auth->createVTable(parameter1, parameter2);
+ case SQLITE_DROP_VTABLE:
+ return auth->dropVTable(parameter1, parameter2);
+ case SQLITE_FUNCTION:
+ return auth->allowFunction(parameter1);
+ default:
+ ASSERT_NOT_REACHED();
+ return SQLAuthDeny;
+ }
+}
+
+void SQLDatabase::setAuthorizer(PassRefPtr<SQLAuthorizer> auth)
+{
+ if (!m_db) {
+ LOG_ERROR("Attempt to set an authorizer on a non-open SQL database");
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ MutexLocker locker(m_authorizerLock);
+
+ m_authorizer = auth;
+ if (m_authorizer)
+ sqlite3_set_authorizer(m_db, SQLDatabase::authorizerFunction, m_authorizer.get());
+ else
+ sqlite3_set_authorizer(m_db, NULL, 0);
+}
+
+void SQLDatabase::lock()
+{
+ m_lockingMutex.lock();
+}
+
+void SQLDatabase::unlock()
+{
+ m_lockingMutex.unlock();
+}
+
} // namespace WebCore
#define SQLDatabase_h
#include "PlatformString.h"
+#include "Threading.h"
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
namespace WebCore {
+class SQLAuthorizer;
class SQLStatement;
class SQLTransaction;
-extern const int SQLResultError;
extern const int SQLResultDone;
+extern const int SQLResultError;
extern const int SQLResultOk;
extern const int SQLResultRow;
+extern const int SQLResultSchema;
+
class SQLDatabase : public Noncopyable
{
friend class SQLTransaction;
public:
SQLDatabase();
- ~SQLDatabase() { close(); }
+ ~SQLDatabase();
bool open(const String& filename);
bool isOpen() const { return m_db; }
return m_db;
}
+ void setAuthorizer(PassRefPtr<SQLAuthorizer>);
+
+ // (un)lock's the database like a mutex
+ void lock();
+ void unlock();
private:
+ static int authorizerFunction(void*, int, const char*, const char*, const char*, const char*);
+
String m_path;
sqlite3* m_db;
int m_lastError;
bool m_transactionInProgress;
+ Mutex m_authorizerLock;
+ RefPtr<SQLAuthorizer> m_authorizer;
+
+ Mutex m_lockingMutex;
#ifndef NDEBUG
pthread_t m_openingThread;
#endif
#include "SQLStatement.h"
#include "Logging.h"
+#include "SQLValue.h"
#include <sqlite3.h>
#include <wtf/Assertions.h>
{
const void* tail;
LOG(SQLDatabase, "SQL - prepare - %s", m_query.ascii().data());
+#if SQLITE_VERSION_NUMBER > 3003000
+ if (sqlite3_prepare16_v2(m_database.sqlite3Handle(), m_query.characters(), -1, &m_statement, &tail) != SQLITE_OK) {
+#else
if (sqlite3_prepare16(m_database.sqlite3Handle(), m_query.characters(), -1, &m_statement, &tail) != SQLITE_OK) {
+#endif
LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", lastError(), m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle()));
m_statement = 0;
}
return sqlite3_bind_int64(m_statement, index, integer);
}
+int SQLStatement::bindDouble(int index, double number)
+{
+ return sqlite3_bind_double(m_statement, index, number);
+}
+
int SQLStatement::bindNull(int index)
{
return sqlite3_bind_null(m_statement, index);
}
+int SQLStatement::bindValue(int index, const SQLValue& value)
+{
+ switch (value.type()) {
+ case SQLValue::StringValue:
+ return bindText16(index, value.string());
+ case SQLValue::NumberValue:
+ return bindDouble(index, value.number());
+ case SQLValue::NullValue:
+ return bindNull(index);
+ default:
+ ASSERT_NOT_REACHED();
+ // To keep the compiler happy
+ return SQLITE_ERROR;
+ }
+}
+
+unsigned SQLStatement::bindParameterCount() const
+{
+ ASSERT(isPrepared());
+ return sqlite3_bind_parameter_count(m_statement);
+}
+
int SQLStatement::columnCount()
{
if (m_statement)
namespace WebCore {
class SQLDatabase;
+class SQLValue;
class SQLStatement : public Noncopyable
{
~SQLStatement();
int prepare();
- bool isPrepared() { return m_statement; }
+ bool isPrepared() const { return m_statement; }
int bindBlob(int index, const void* blob, int size, bool copy = true);
int bindText(int index, const char* text, bool copy = true);
int bindText16(int index, const String& text, bool copy = true);
int bindInt64(int index, int64_t integer);
+ int bindDouble(int index, double number);
int bindNull(int index);
+ int bindValue(int index, const SQLValue&);
+ unsigned bindParameterCount() const;
int step();
int finalize();
m_client->print(frame);
}
+bool Chrome::runDatabaseSizeLimitPrompt(Frame* f, const String& origin)
+{
+ return m_client->runDatabaseSizeLimitPrompt(f, origin);
+}
+
+
PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
{
const HashSet<Page*>* group = page->frameNamespace();
void print(Frame*);
+ bool runDatabaseSizeLimitPrompt(Frame*, const String& origin);
+
+
#if PLATFORM(MAC)
void focusNSView(NSView*);
#endif
virtual void setToolTip(const String&) = 0;
virtual void print(Frame*) = 0;
+
+// Possible permission levels -
+// -Allow just this database to be created
+// -Allow this domain to create whatever it wants
+// -Don't allow this database
+// -Don't allow this domain to ever create any
+// -Don't allow any databases
+// virtual bool runDatabaseCreationPrompt(Frame*, const String& origin, const String& name) = 0;
+
+ virtual bool runDatabaseSizeLimitPrompt(Frame*, const String& origin) = 0;
};
}
#include "CSSRuleList.h"
#include "CSSStyleSelector.h"
#include "Chrome.h"
+#include "Database.h"
#include "DOMSelection.h"
#include "Document.h"
#include "Element.h"
return page->chrome()->scaleFactor();
}
+PassRefPtr<Database> DOMWindow::openDatabase(const String& name, const String& version, ExceptionCode& e)
+{
+ if (!m_frame)
+ return 0;
+
+ Document* doc = m_frame->document();
+ ASSERT(doc);
+ if (!doc)
+ return 0;
+
+ return Database::openDatabase(doc, name, version, e);
+}
+
} // namespace WebCore
class BarInfo;
class CSSRuleList;
class CSSStyleDeclaration;
+ class Database;
class DOMSelection;
class Document;
class Element;
class History;
class Screen;
+ typedef int ExceptionCode;
+
class DOMWindow : public Shared<DOMWindow> {
public:
DOMWindow(Frame*);
PassRefPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt, bool authorOnly = true) const;
double devicePixelRatio() const;
+ // HTML 5 client-side database
+ PassRefPtr<Database> openDatabase(const String& name, const String& version, ExceptionCode&);
+
private:
Frame* m_frame;
mutable RefPtr<Screen> m_screen;
in [Optional] boolean authorOnly);
readonly attribute double devicePixelRatio;
+ Database openDatabase(in DOMString name, in DOMString version)
+ raises(DOMException);
+
#if defined(LANGUAGE_JAVASCRIPT)
// Global constructors
attribute StyleSheetConstructor StyleSheet;
#include "CString.h"
#include "CachedResource.h"
+#include "Database.h"
#include "DocLoader.h"
#include "Document.h"
#include "DocumentLoader.h"
#include "FrameTree.h"
#include "HTMLFrameOwnerElement.h"
#include "InspectorClient.h"
+#include "JSDatabase.h"
#include "JSRange.h"
#include "Page.h"
#include "Range.h"
double endTime;
};
+
+struct InspectorDatabaseResource : public Shared<InspectorDatabaseResource> {
+ InspectorDatabaseResource(Database* database, String domain, String name, String version)
+ : database(database)
+ , domain(domain)
+ , name(name)
+ , version(version)
+ , scriptContext(0)
+ , scriptObject(0)
+ {
+ }
+
+ InspectorDatabaseResource()
+ {
+ setScriptObject(0, 0);
+ }
+
+ void setScriptObject(JSContextRef context, JSObjectRef newScriptObject)
+ {
+ if (scriptContext && scriptObject)
+ JSValueUnprotect(scriptContext, scriptObject);
+
+ scriptObject = newScriptObject;
+ scriptContext = context;
+
+ ASSERT((context && newScriptObject) || (!context && !newScriptObject));
+ if (context && newScriptObject)
+ JSValueProtect(context, newScriptObject);
+ }
+
+ RefPtr<Database> database;
+ String domain;
+ String name;
+ String version;
+ JSContextRef scriptContext;
+ JSObjectRef scriptObject;
+};
+
static JSValueRef addSourceToFrame(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
{
JSValueRef undefined = JSValueMakeUndefined(ctx);
return array;
}
+static JSValueRef databaseTableNames(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* /*exception*/)
+{
+ InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
+ if (!controller)
+ return JSValueMakeUndefined(ctx);
+
+ if (argumentCount < 1)
+ return JSValueMakeUndefined(ctx);
+
+ Database* database = toDatabase(toJS(arguments[0]));
+ if (!database)
+ return JSValueMakeUndefined(ctx);
+
+ JSObjectRef global = JSContextGetGlobalObject(ctx);
+ JSStringRef arrayString = JSStringCreateWithUTF8CString("Array");
+ JSObjectRef arrayConstructor = JSValueToObject(ctx, JSObjectGetProperty(ctx, global, arrayString, 0), 0);
+ JSStringRelease(arrayString);
+
+ JSObjectRef result = JSObjectCallAsConstructor(ctx, arrayConstructor, 0, 0, 0);
+
+ JSStringRef pushString = JSStringCreateWithUTF8CString("push");
+ JSObjectRef pushFunction = JSValueToObject(ctx, JSObjectGetProperty(ctx, result, pushString, 0), 0);
+ JSStringRelease(pushString);
+
+ Vector<String> tableNames = database->tableNames();
+ unsigned length = tableNames.size();
+ for (unsigned i = 0; i < length; ++i) {
+ String tableName = tableNames[i];
+ JSStringRef tableNameString = JSStringCreateWithCharacters(tableName.characters(), tableName.length());
+ JSValueRef tableNameValue = JSValueMakeString(ctx, tableNameString);
+ JSStringRelease(tableNameString);
+
+ JSValueRef pushArguments[] = { tableNameValue };
+ JSObjectCallAsFunction(ctx, pushFunction, result, 1, pushArguments, 0);
+ }
+
+ return result;
+}
+
static JSValueRef inspectedWindow(JSContextRef ctx, JSObjectRef /*function*/, JSObjectRef thisObject, size_t /*argumentCount*/, const JSValueRef[] /*arguments[]*/, JSValueRef* /*exception*/)
{
InspectorController* controller = reinterpret_cast<InspectorController*>(JSObjectGetPrivate(thisObject));
} else {
clearScriptResources();
clearScriptConsoleMessages();
+ clearDatabaseScriptResources();
clearNetworkTimeline();
}
}
{ "detach", detach, kJSPropertyAttributeNone },
{ "log", log, kJSPropertyAttributeNone },
{ "search", search, kJSPropertyAttributeNone },
+ { "databaseTableNames", databaseTableNames, kJSPropertyAttributeNone },
{ "inspectedWindow", inspectedWindow, kJSPropertyAttributeNone },
{ 0, 0, 0 }
};
clearScriptResources();
clearScriptConsoleMessages();
+ clearDatabaseScriptResources();
clearNetworkTimeline();
ResourcesMap::iterator resourcesEnd = m_resources.end();
unsigned messageCount = m_consoleMessages.size();
for (unsigned i = 0; i < messageCount; ++i)
addScriptConsoleMessage(m_consoleMessages[i]);
+
+ DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
+ for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it)
+ addDatabaseScriptResource((*it).get());
+}
+
+JSObjectRef InspectorController::addDatabaseScriptResource(InspectorDatabaseResource* resource)
+{
+ ASSERT_ARG(resource, resource);
+
+ if (resource->scriptObject)
+ return resource->scriptObject;
+
+ ASSERT(m_scriptContext);
+ ASSERT(m_scriptObject);
+ if (!m_scriptContext || !m_scriptObject)
+ return 0;
+
+ JSStringRef databaseString = JSStringCreateWithUTF8CString("Database");
+ JSObjectRef databaseConstructor = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, databaseString, 0), 0);
+ JSStringRelease(databaseString);
+
+ JSValueRef database = toRef(toJS(toJS(m_scriptContext), resource->database.get()));
+
+ JSStringRef domain = JSStringCreateWithCharacters(resource->domain.characters(), resource->domain.length());
+ JSValueRef domainValue = JSValueMakeString(m_scriptContext, domain);
+ JSStringRelease(domain);
+
+ JSStringRef name = JSStringCreateWithCharacters(resource->name.characters(), resource->name.length());
+ JSValueRef nameValue = JSValueMakeString(m_scriptContext, name);
+ JSStringRelease(name);
+
+ JSStringRef version = JSStringCreateWithCharacters(resource->version.characters(), resource->version.length());
+ JSValueRef versionValue = JSValueMakeString(m_scriptContext, version);
+ JSStringRelease(version);
+
+ JSValueRef arguments[] = { database, domainValue, nameValue, versionValue };
+ JSObjectRef result = JSObjectCallAsConstructor(m_scriptContext, databaseConstructor, 4, arguments, 0);
+
+ resource->setScriptObject(m_scriptContext, result);
+
+ ASSERT(result);
+
+ JSStringRef addResourceString = JSStringCreateWithUTF8CString("addResource");
+ JSObjectRef addResourceFunction = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, addResourceString, 0), 0);
+ JSStringRelease(addResourceString);
+
+ JSValueRef addArguments[] = { result };
+ JSObjectCallAsFunction(m_scriptContext, addResourceFunction, m_scriptObject, 1, addArguments, 0);
+
+ return result;
+}
+
+void InspectorController::removeDatabaseScriptResource(InspectorDatabaseResource* resource)
+{
+ ASSERT(m_scriptContext);
+ ASSERT(m_scriptObject);
+ if (!m_scriptContext || !m_scriptObject)
+ return;
+
+ ASSERT(resource);
+ ASSERT(resource->scriptObject);
+ if (!resource || !resource->scriptObject)
+ return;
+
+ JSStringRef removeResourceString = JSStringCreateWithUTF8CString("removeResource");
+ JSObjectRef removeResourceFunction = JSValueToObject(m_scriptContext, JSObjectGetProperty(m_scriptContext, m_scriptObject, removeResourceString, 0), 0);
+ JSStringRelease(removeResourceString);
+
+ JSValueRef arguments[] = { resource->scriptObject };
+ JSObjectCallAsFunction(m_scriptContext, removeResourceFunction, m_scriptObject, 1, arguments, 0);
+
+ resource->setScriptObject(0, 0);
}
void InspectorController::addScriptConsoleMessage(const ConsoleMessage* message)
callClearFunction(m_scriptContext, m_scriptObject, "clearResources");
}
+void InspectorController::clearDatabaseScriptResources()
+{
+ if (!m_scriptContext || !m_scriptObject)
+ return;
+
+ DatabaseResourcesSet::iterator databasesEnd = m_databaseResources.end();
+ for (DatabaseResourcesSet::iterator it = m_databaseResources.begin(); it != databasesEnd; ++it) {
+ InspectorDatabaseResource* resource = (*it).get();
+ resource->setScriptObject(0, 0);
+ }
+
+ callClearFunction(m_scriptContext, m_scriptObject, "clearDatabaseResources");
+}
+
void InspectorController::clearScriptConsoleMessages()
{
if (!m_scriptContext || !m_scriptObject)
// FIXME: Should look into asserting that m_mainResource->loader == loader here.
m_client->inspectedURLChanged(loader->URL().url());
+
deleteAllValues(m_consoleMessages);
m_consoleMessages.clear();
+
+ m_databaseResources.clear();
+
if (windowVisible()) {
clearScriptConsoleMessages();
+ clearDatabaseScriptResources();
clearNetworkTimeline();
// We don't add the main resource until its load is committed. This
}
}
+void InspectorController::didOpenDatabase(Database* database, const String& domain, const String& name, const String& version)
+{
+ if (!enabled())
+ return;
+
+ InspectorDatabaseResource* resource = new InspectorDatabaseResource(database, domain, name, version);
+
+ m_databaseResources.add(resource);
+
+ if (windowVisible())
+ addDatabaseScriptResource(resource);
+}
+
} // namespace WebCore
#include "Chrome.h"
#include <JavaScriptCore/JSContextRef.h>
#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
#include <wtf/Vector.h>
namespace WebCore {
+class Database;
class DocumentLoader;
class InspectorClient;
class Node;
class ResourceError;
struct ConsoleMessage;
+struct InspectorDatabaseResource;
struct InspectorResource;
struct ResourceRequest;
public:
typedef HashMap<long long, RefPtr<InspectorResource> > ResourcesMap;
typedef HashMap<RefPtr<Frame>, ResourcesMap*> FrameResourcesMap;
+ typedef HashSet<RefPtr<InspectorDatabaseResource> > DatabaseResourcesSet;
InspectorController(Page*, InspectorClient*);
~InspectorController();
void didFinishLoading(DocumentLoader*, unsigned long identifier);
void didFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&);
+ void didOpenDatabase(Database*, const String& domain, const String& name, const String& version);
+
const ResourcesMap& resources() const { return m_resources; }
private:
void clearScriptConsoleMessages();
void clearNetworkTimeline();
+ void clearDatabaseScriptResources();
void addResource(InspectorResource*);
void removeResource(InspectorResource*);
void pruneResources(ResourcesMap*, DocumentLoader* loaderToKeep = 0);
void removeAllResources(ResourcesMap* map) { pruneResources(map); }
+ JSObjectRef addDatabaseScriptResource(InspectorDatabaseResource*);
+ void removeDatabaseScriptResource(InspectorDatabaseResource*);
+
Page* m_inspectedPage;
InspectorClient* m_client;
Page* m_page;
ResourcesMap m_resources;
FrameResourcesMap m_frameResources;
Vector<ConsoleMessage*> m_consoleMessages;
+ DatabaseResourcesSet m_databaseResources;
JSObjectRef m_scriptObject;
JSObjectRef m_controllerScriptObject;
JSContextRef m_scriptContext;
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+WebInspector.Database = function(database, domain, name, version)
+{
+ this.database = database;
+ this.domain = domain;
+ this.name = name;
+ this.version = version;
+
+ this.listItem = new WebInspector.ResourceTreeElement(this);
+ this.updateTitle();
+
+ this.category.addResource(this);
+}
+
+WebInspector.Database.prototype = {
+ get database()
+ {
+ return this._database;
+ },
+
+ set database(x)
+ {
+ if (this._database === x)
+ return;
+ this._database = x;
+ },
+
+ get name()
+ {
+ return this._name;
+ },
+
+ set name(x)
+ {
+ if (this._name === x)
+ return;
+ this._name = x;
+ this.updateTitleSoon();
+ },
+
+ get version()
+ {
+ return this._version;
+ },
+
+ set version(x)
+ {
+ if (this._version === x)
+ return;
+ this._version = x;
+ },
+
+ get domain()
+ {
+ return this._domain;
+ },
+
+ set domain(x)
+ {
+ if (this._domain === x)
+ return;
+ this._domain = x;
+ this.updateTitleSoon();
+ },
+
+ get category()
+ {
+ return WebInspector.resourceCategories.databases;
+ },
+
+ updateTitleSoon: function()
+ {
+ if (this.updateTitleTimeout)
+ return;
+ var _self = this;
+ this.updateTitleTimeout = setTimeout(function () { _self.updateTitle() }, 0);
+ },
+
+ updateTitle: function()
+ {
+ delete this.updateTitleTimeout;
+
+ var title = this.name;
+
+ var info = "";
+ if (this.domain && (!WebInspector.mainResource || (WebInspector.mainResource && this.domain !== WebInspector.mainResource.domain)))
+ info = this.domain;
+
+ var fullTitle = "<span class=\"title" + (info && info.length ? "" : " only") + "\">" + title.escapeHTML() + "</span>";
+ if (info && info.length)
+ fullTitle += "<span class=\"info\">" + info.escapeHTML() + "</span>";
+ fullTitle += "<div class=\"icon database\"></div>";
+
+ this.listItem.title = fullTitle;
+ },
+
+ get panel()
+ {
+ if (!this._panel)
+ this._panel = new WebInspector.DatabasePanel(this);
+ return this._panel;
+ },
+
+ select: function()
+ {
+ WebInspector.navigateToResource(this);
+ },
+
+ deselect: function()
+ {
+ this.listItem.deselect(true);
+ if (WebInspector.currentPanel === this._panel)
+ WebInspector.currentPanel = null;
+ },
+
+ attach: function()
+ {
+ this.panel.attach();
+ },
+
+ detach: function()
+ {
+ if (this._panel)
+ this.panel.detach();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+WebInspector.DatabasePanel = function(database)
+{
+ WebInspector.Panel.call(this);
+
+ this.database = database;
+
+ this.queryPromptElement = document.createElement("textarea");
+ this.queryPromptElement.className = "database-prompt";
+ this.element.appendChild(this.queryPromptElement);
+
+ var panel = this;
+ this.queryPromptElement.addEventListener("keydown", function(event) { panel.queryInputKeypress(event) }, false);
+
+ this.queryPromptHistory = [];
+ this.queryPromptHistoryOffset = 0;
+
+ var selectViewFunction = function(event)
+ {
+ WebInspector.navigateToView(event.currentTarget.view);
+ }
+
+ var views = [
+ { name: "query", title: "Query", selected: false },
+ { name: "browse", title: "Browse", selected: true }
+ ];
+
+ this.views = {};
+ this.viewButtons = [];
+ for (var i = 0; i < views.length; ++i) {
+ var buttonElement = document.createElement("button");
+ buttonElement.setAttribute("title", views[i].title);
+ buttonElement.addEventListener("click", selectViewFunction, "true");
+ buttonElement.appendChild(document.createElement("img"));
+
+ var contentElement = document.createElement("div");
+ contentElement.className = "content database-" + views[i].name;
+
+ var view = {};
+ view.panel = this;
+ view.buttonElement = buttonElement;
+ view.contentElement = contentElement;
+ view.buttonElement.view = view;
+
+ this.views[views[i].name] = view;
+ this.viewButtons.push(buttonElement);
+ this.element.appendChild(contentElement);
+ }
+
+ this.currentView = this.views.browse;
+
+ var queryPanel = this.views.query;
+
+ queryPanel.commandListElement = document.createElement("ol");
+ queryPanel.commandListElement.className = "database-command-list";
+ queryPanel.contentElement.appendChild(queryPanel.commandListElement);
+
+ queryPanel.onshow = function()
+ {
+ panel.queryPromptElement.focus();
+ this.commandListElement.scrollTop = this.previousScrollTop;
+ };
+
+ queryPanel.onhide = function()
+ {
+ this.previousScrollTop = this.commandListElement.scrollTop;
+ };
+
+ var browsePanel = this.views.browse;
+
+ browsePanel.reloadTableElement = document.createElement("button");
+ browsePanel.reloadTableElement.appendChild(document.createElement("img"));
+ browsePanel.reloadTableElement.className = "database-table-reload";
+ browsePanel.reloadTableElement.title = "Reload";
+ browsePanel.reloadTableElement.addEventListener("click", function() { panel.updateTableList(); panel.updateTableBrowser() }, false);
+
+ browsePanel.onshow = function()
+ {
+ panel.updateTableList();
+ panel.queryPromptElement.focus();
+
+ this.tableSelectElement.removeStyleClass("hidden");
+ document.getElementById("viewbuttons").appendChild(this.tableSelectElement);
+
+ this.reloadTableElement.removeStyleClass("hidden");
+ document.getElementById("viewbuttons").appendChild(this.reloadTableElement);
+
+ this.contentElement.scrollTop = this.previousScrollTop;
+ };
+
+ browsePanel.onhide = function()
+ {
+ this.tableSelectElement.addStyleClass("hidden");
+ this.reloadTableElement.addStyleClass("hidden");
+ this.previousScrollTop = this.contentElement.scrollTop;
+ };
+}
+
+WebInspector.DatabasePanel.prototype = {
+ show: function()
+ {
+ WebInspector.Panel.prototype.show.call(this);
+ this.queryPromptElement.focus();
+ if (this.currentView && "onshow" in this.currentView)
+ this.currentView.onshow.call(this.currentView);
+ },
+
+ hide: function()
+ {
+ if (this.currentView && "onhide" in this.currentView)
+ this.currentView.onhide();
+ WebInspector.Panel.prototype.hide.call(this);
+ },
+
+ get currentView()
+ {
+ return this._currentView;
+ },
+
+ set currentView(x)
+ {
+ if (this._currentView === x)
+ return;
+
+ if (this._currentView) {
+ if ("onhide" in this._currentView)
+ this._currentView.onhide.call(this._currentView);
+ this._currentView.buttonElement.removeStyleClass("selected");
+ this._currentView.contentElement.removeStyleClass("selected");
+ }
+
+ this._currentView = x;
+
+ if (x) {
+ x.buttonElement.addStyleClass("selected");
+ x.contentElement.addStyleClass("selected");
+ if ("onshow" in x)
+ x.onshow.call(x);
+
+ if (x.contentElement.parentNode !== this.element)
+ InspectorController.log("Tried to set currentView to a view " + x.title + " whose contentElement is a non-child");
+ }
+ },
+
+ get currentTable()
+ {
+ return this._currentTable;
+ },
+
+ set currentTable(x)
+ {
+ if (this._currentTable === x)
+ return;
+
+ this._currentTable = x;
+
+ if (x) {
+ var browseView = this.views.browse;
+ if (browseView.tableSelectElement) {
+ var length = browseView.tableSelectElement.options.length;
+ for (var i = 0; i < length; ++i) {
+ var option = browseView.tableSelectElement.options[i];
+ if (option.value === x) {
+ browseView.tableSelectElement.selectedIndex = i;
+ break;
+ }
+ }
+ }
+
+ this.updateTableBrowser();
+ }
+ },
+
+ updateTableList: function()
+ {
+ var browseView = this.views.browse;
+ if (!browseView.tableSelectElement) {
+ browseView.tableSelectElement = document.createElement("select");
+ browseView.tableSelectElement.className = "database-table-select hidden";
+
+ var panel = this;
+ var changeTableFunction = function()
+ {
+ var browseView = panel.views.browse;
+ var index = browseView.tableSelectElement.selectedIndex;
+ if (index != -1)
+ panel.currentTable = browseView.tableSelectElement.options[index].value;
+ else
+ panel.currentTable = null;
+ };
+
+ browseView.tableSelectElement.addEventListener("change", changeTableFunction, false);
+ }
+
+ browseView.tableSelectElement.removeChildren();
+
+ var selectedTableName = this.currentTable;
+ var tableNames = InspectorController.databaseTableNames(this.database.database).sort();
+
+ var length = tableNames.length;
+ for (var i = 0; i < length; ++i) {
+ var option = document.createElement("option");
+ option.value = tableNames[i];
+ option.text = tableNames[i];
+ browseView.tableSelectElement.appendChild(option);
+
+ if (tableNames[i] === selectedTableName)
+ browseView.tableSelectElement.selectedIndex = i;
+ }
+
+ if (!selectedTableName && length)
+ this.currentTable = tableNames[0];
+ },
+
+ updateTableBrowser: function()
+ {
+ if (!this.currentTable) {
+ this.views.browse.contentElement.removeChildren();
+ return;
+ }
+
+ try {
+ var panel = this;
+ var query = "SELECT * FROM " + this.currentTable;
+ this.database.database.executeSql(query, function(result) { panel.browseQueryFinished(result) });
+ } catch(e) {
+ // FIXME: handle this error a better way.
+ this.views.browse.contentElement.removeChildren();
+ }
+ },
+
+ browseQueryFinished: function(result)
+ {
+ this.views.browse.contentElement.removeChildren();
+
+ var table = this._tableForResult(result);
+ if (table) {
+ var rowCount = table.getElementsByTagName("tr").length;
+ var columnCount = table.getElementsByTagName("tr").item(0).getElementsByTagName("th").length;
+
+ var tr = document.createElement("tr");
+ tr.className = "database-result-filler-row";
+ table.appendChild(tr);
+
+ if (!(rowCount % 2))
+ tr.addStyleClass("alternate");
+
+ for (var i = 0; i < columnCount; ++i) {
+ var td = document.createElement("td");
+ tr.appendChild(td);
+ }
+
+ table.addStyleClass("database-browse-table");
+ this.views.browse.contentElement.appendChild(table);
+ } else {
+ if (!result.errorCode) {
+ var emptyMsgElement = document.createElement("div");
+ emptyMsgElement.className = "database-table-empty";
+ emptyMsgElement.innerHTML = "The <q>" + this.currentTable + "</q><br>table is empty.";
+ this.views.browse.contentElement.appendChild(emptyMsgElement);
+ } else {
+ var errorMsgElement = document.createElement("div");
+ errorMsgElement.className = "database-table-error";
+ errorMsgElement.innerHTML = "An error occurred trying to<br>read the <q>" + this.currentTable + "</q> table.";
+ this.views.browse.contentElement.appendChild(errorMsgElement);
+ }
+ }
+ },
+
+ queryInputKeypress: function(event)
+ {
+ switch (event.keyIdentifier) {
+ case "Enter":
+ this._onQueryInputEnterPressed(event);
+ break;
+ case "Up":
+ this._onQueryInputUpPressed(event);
+ break;
+ case "Down":
+ this._onQueryInputDownPressed(event);
+ break;
+ }
+ },
+
+ queryFinished: function(query, result)
+ {
+ var commandItem = document.createElement("li");
+ commandItem.className = "database-command";
+
+ var queryDiv = document.createElement("div");
+ queryDiv.className = "database-command-query";
+ queryDiv.textContent = query;
+ commandItem.appendChild(queryDiv);
+
+ var resultDiv = document.createElement("div");
+ resultDiv.className = "database-command-result";
+ commandItem.appendChild(resultDiv);
+
+ if (!result.errorCode) {
+ var table = this._tableForResult(result);
+ if (table)
+ resultDiv.appendChild(table);
+ } else {
+ if (this.currentView !== this.views.query)
+ this.currentView = this.views.query;
+
+ if (result.errorCode == 1) {
+ resultDiv.className += " error";
+ resultDiv.textContent = result.error;
+ } else if (result.errorCode == 2) {
+ resultDiv.className += " error";
+ resultDiv.textContent = "Database no longer has expected version.";
+ } else {
+ resultDiv.className += " error";
+ resultDiv.textContent = "An unexpected error " + result.errorCode + " occured.";
+ }
+ }
+
+ this.views.query.commandListElement.appendChild(commandItem);
+ commandItem.scrollIntoView(false);
+ },
+
+ _onQueryInputEnterPressed: function(event)
+ {
+ event.preventDefault();
+ event.stopPropagation();
+
+ var query = this.queryPromptElement.value;
+ if (!query.length)
+ return;
+
+ try {
+ var panel = this;
+ this.database.database.executeSql(query, function(result) { panel.queryFinished(query, result) });
+
+ this.queryPromptHistory.push(query);
+ this.queryPromptHistoryOffset = 0;
+
+ this.queryPromptElement.value = "";
+
+ if (query.match(/^select /i)) {
+ if (this.currentView !== this.views.query)
+ this.currentView = this.views.query;
+ } else {
+ if (query.match(/^create /i) || query.match(/^drop table /i))
+ this.updateTableList();
+
+ // FIXME: we should only call updateTableBrowser() is we know the current table was modified
+ this.updateTableBrowser();
+ }
+ } catch(e) {
+ // FIXME: handle this error some way.
+ }
+ },
+
+ _onQueryInputUpPressed: function(event)
+ {
+ event.preventDefault();
+ event.stopPropagation();
+
+ if (this.queryPromptHistoryOffset == this.queryPromptHistory.length)
+ return;
+
+ if (this.queryPromptHistoryOffset == 0)
+ this.tempSavedQuery = this.queryPromptElement.value;
+
+ ++this.queryPromptHistoryOffset;
+ this.queryPromptElement.value = this.queryPromptHistory[this.queryPromptHistory.length - this.queryPromptHistoryOffset];
+ this.queryPromptElement.moveCursorToEnd();
+ },
+
+ _onQueryInputDownPressed: function(event)
+ {
+ event.preventDefault();
+ event.stopPropagation();
+
+ if (this.queryPromptHistoryOffset == 0)
+ return;
+
+ --this.queryPromptHistoryOffset;
+
+ if (this.queryPromptHistoryOffset == 0) {
+ this.queryPromptElement.value = this.tempSavedQuery;
+ this.queryPromptElement.moveCursorToEnd();
+ delete this.tempSavedQuery;
+ return;
+ }
+
+ this.queryPromptElement.value = this.queryPromptHistory[this.queryPromptHistory.length - this.queryPromptHistoryOffset];
+ this.queryPromptElement.moveCursorToEnd();
+ },
+
+ _tableForResult: function(result)
+ {
+ if (result.errorCode || !result.rows.length)
+ return null;
+
+ var rows = result.rows;
+ var length = rows.length;
+ var columnWidths = [];
+
+ var table = document.createElement("table");
+ table.className = "database-result-table";
+
+ var headerRow = document.createElement("tr");
+ table.appendChild(headerRow);
+
+ var j = 0;
+ for (var column in rows.item(0)) {
+ var th = document.createElement("th");
+ headerRow.appendChild(th);
+
+ var div = document.createElement("div");
+ div.textContent = column;
+ div.title = column;
+ th.appendChild(div);
+
+ columnWidths[j++] = column.length;
+ }
+
+ for (var i = 0; i < length; ++i) {
+ var row = rows.item(i);
+ var tr = document.createElement("tr");
+ if (i % 2)
+ tr.className = "alternate";
+ table.appendChild(tr);
+
+ var j = 0;
+ for (var column in row) {
+ var td = document.createElement("td");
+ tr.appendChild(td);
+
+ var text = row[column];
+ var div = document.createElement("div");
+ div.textContent = text;
+ div.title = text;
+ td.appendChild(div);
+
+ if (text.length > columnWidths[j])
+ columnWidths[j] = text.length;
+ ++j;
+ }
+ }
+
+ var totalColumnWidths = 0;
+ length = columnWidths.length;
+ for (var i = 0; i < length; ++i)
+ totalColumnWidths += columnWidths[i];
+
+ // Calculate the percentage width for the columns.
+ var minimumPrecent = 5;
+ var recoupPercent = 0;
+ for (var i = 0; i < length; ++i) {
+ columnWidths[i] = Math.round((columnWidths[i] / totalColumnWidths) * 100);
+ if (columnWidths[i] < minimumPrecent) {
+ recoupPercent += (minimumPrecent - columnWidths[i]);
+ columnWidths[i] = minimumPrecent;
+ }
+ }
+
+ // Enforce the minimum percentage width.
+ while (recoupPercent > 0) {
+ for (var i = 0; i < length; ++i) {
+ if (columnWidths[i] > minimumPrecent) {
+ --columnWidths[i];
+ --recoupPercent;
+ if (!recoupPercent)
+ break;
+ }
+ }
+ }
+
+ length = headerRow.childNodes.length;
+ for (var i = 0; i < length; ++i) {
+ var th = headerRow.childNodes[i];
+ th.style.width = columnWidths[i] + "%";
+ }
+
+ return table;
+ }
+}
+
+WebInspector.DatabasePanel.prototype.__proto__ = WebInspector.Panel.prototype;
var resourcesLength = this.resources.length;
for (var i = 0; i < resourcesLength; ++i) {
var b = this.resources[i];
- if (a._lastPathComponentLowerCase < b._lastPathComponentLowerCase)
- break;
+ if (a._lastPathComponentLowerCase && b._lastPathComponentLowerCase)
+ if (a._lastPathComponentLowerCase < b._lastPathComponentLowerCase)
+ break;
+ else if (a.name && b.name)
+ if (a.name < b.name)
+ break;
}
this.resources.splice(i, 0, resource);
-webkit-border-image: url(Images/toolbarButtonInactive.png) 3 3 4 3;
}
+#toolbar select, #toolbar select:disabled:active {
+ background-color: transparent;
+ border-width: 3px 12px 4px 3px;
+ border-color: transparent;
+ -webkit-border-image: url(Images/toolbarPopup.png) 3 12 4 3;
+ height: 19px;
+ font-size: 10px;
+ padding-left: 8px;
+ padding-right: 4px;
+ -webkit-box-sizing: border-box;
+ -webkit-border-radius: 0;
+ -webkit-appearance: none;
+ vertical-align: middle;
+}
+
+#toolbar select:focus {
+ outline: none;
+}
+
+#toolbar select:active, #toolbar select.selected {
+ -webkit-border-image: url(Images/toolbarPopupPressed.png) 3 12 4 3;
+}
+
+body.inactive #toolbar select:active, body.inactive #toolbar select.selected {
+ -webkit-border-image: url(Images/toolbarPopupPressedInactive.png) 3 12 4 3;
+}
+
+body.inactive #toolbar select, body.inactive #toolbar select:disabled:active {
+ -webkit-border-image: url(Images/toolbarPopupInactive.png) 3 12 4 3;
+}
+
#toolbar .split-button-divider {
width: 1px;
height: 19px;
top: -1px;
width: 8px;
height: 7px;
+ opacity: 0.66;
}
.view-button-source.selected img {
- content: url(Images/sourceViewButtonSelected.png);
+ opacity: 1;
}
.view-button-dom img {
left: 1px;
width: 10px;
height: 7px;
+ opacity: 0.66;
}
.view-button-dom.selected img {
- content: url(Images/domViewButtonSelected.png);
+ opacity: 1;
}
#viewbuttons {
background-position: center center;
}
+#list .icon.database {
+ background-image: url(Images/database.png);
+}
+
#list .icon.plain {
background-image: url(Images/plainDocument.png);
}
top: 1px;
}
+.view-button-browse img {
+ content: url(Images/databaseBrowserViewButton.png);
+ position: relative;
+ top: -1px;
+ left: 1px;
+ width: 11px;
+ height: 7px;
+ opacity: 0.66;
+}
+
+.view-button-browse.selected img {
+ opacity: 1;
+}
+
+.view-button-query img {
+ content: url(Images/databaseQueryViewButton.png);
+ position: relative;
+ top: -1px;
+ left: 0px;
+ width: 10px;
+ height: 7px;
+ opacity: 0.66;
+}
+
+.view-button-query.selected img {
+ opacity: 1;
+}
+
+.database-table-reload {
+ padding-left: 0;
+ padding-right: 0;
+ width: 20px;
+ margin-left: 6px;
+}
+
+.database-table-reload img {
+ content: url(Images/reload.png);
+ position: relative;
+ top: -2px;
+ left: 0px;
+ width: 10px;
+ height: 11px;
+ opacity: 0.7;
+}
+
+.database-query.content {
+ bottom: 21px;
+}
+
+.database-browse.content {
+ font-size: 10px;
+ overflow-y: auto;
+ overflow-x: hidden;
+ bottom: 21px;
+}
+
+.database-browse.content .database-result-table {
+ border: none;
+}
+
+.database-browse.content .database-table-empty {
+ position: absolute;
+ top: 0;
+ bottom: 25%;
+ left: 0;
+ right: 0;
+ font-size: 24px;
+ color: rgb(75%, 75%, 75%);
+ margin-top: auto;
+ margin-bottom: auto;
+ height: 50px;
+ line-height: 26px;
+ text-align: center;
+ font-weight: bold;
+ padding: 10px;
+}
+
+.database-browse.content .database-table-error {
+ position: absolute;
+ top: 0;
+ bottom: 25%;
+ left: 0;
+ right: 0;
+ font-size: 24px;
+ color: rgb(66%, 33%, 33%);
+ margin-top: auto;
+ margin-bottom: auto;
+ height: 50px;
+ line-height: 26px;
+ text-align: center;
+ padding: 10px;
+}
+
+.database-browse-table {
+ height: 100%;
+}
+
+.database-result-table .database-result-filler-row {
+ height: auto;
+}
+
+.database-result-table .database-result-filler-row.alternate td {
+ background-position-y: 16px;
+}
+
+.database-result-filler-row td {
+ background-image: url(Images/alternateTableRows.png);
+}
+
+.database-table-select {
+ margin-left: 6px;
+ max-width: 150px;
+ min-width: 75px;
+}
+
+.database-command-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ overflow-y: auto;
+ overflow-x: hidden;
+}
+
+.database-prompt {
+ font-family: monospace;
+ font-size: 11px;
+ margin: 0;
+ padding: 2px 0 0;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 18px;
+ resize: none;
+ outline: none;
+ border: none;
+ border-top: 1px solid rgb(64%, 64%, 64%);
+}
+
+.database-command {
+ font-size: 10px;
+ margin: 0;
+ padding: 5px;
+ border-bottom: 1px solid rgb(75%, 75%, 75%);
+ word-break: break-word;
+ position: relative;
+}
+
+.database-command a:hover {
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+.database-command-query {
+ font-family: monospace;
+ font-size: 11px;
+ white-space: pre-wrap;
+}
+
+.database-command-result {
+ margin-top: 3px;
+}
+
+.database-command-result.error {
+ color: red;
+}
+
+.database-result-table {
+ border: 1px solid #aaa;
+ table-layout: fixed;
+ border-spacing: 0;
+ border-collapse: collapse;
+ width: 100%;
+ -webkit-box-sizing: border-box;
+}
+
+.database-result-table th {
+ text-align: left;
+ background: url(Images/glossyHeader.png) repeat-x;
+ border-right: 1px solid #aaa;
+ height: 15px;
+ -webkit-box-sizing: border-box;
+ border-bottom: 1px solid #aaa;
+ font-weight: normal;
+ vertical-align: middle;
+ padding: 0 4px;
+ white-space: nowrap;
+}
+
+.database-result-table tr {
+ height: 16px;
+}
+
+.database-result-table tr.alternate {
+ background-color: rgb(236, 243, 254);
+}
+
+.database-result-table td {
+ vertical-align: top;
+ padding: 2px 4px;
+ -webkit-box-sizing: border-box;
+ white-space: nowrap;
+ border-right: 1px solid #aaa;
+}
+
+.database-result-table td > div, .database-result-table th > div {
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
.network-timeline {
position: absolute;
top: 0;
<script type="text/javascript" src="ResourceCategory.js"></script>
<script type="text/javascript" src="ResourcePanel.js"></script>
<script type="text/javascript" src="NetworkPanel.js"></script>
+ <script type="text/javascript" src="Database.js"></script>
+ <script type="text/javascript" src="DatabasePanel.js"></script>
<link rel="stylesheet" type="text/css" href="inspector.css" />
</head>
<body class="detached">
stylesheets: new WebInspector.ResourceCategory("stylesheets"),
images: new WebInspector.ResourceCategory("images"),
scripts: new WebInspector.ResourceCategory("scripts"),
+ databases: new WebInspector.ResourceCategory("databases"),
other: new WebInspector.ResourceCategory("other")
};
WebInspector.addResource = function(resource)
{
this.resources.push(resource);
- this.resourceURLMap[resource.url] = resource;
if (resource.mainResource)
this.mainResource = resource;
- this.networkPanel.addResourceToTimeline(resource);
+ if (resource.url) {
+ this.resourceURLMap[resource.url] = resource;
+ this.networkPanel.addResourceToTimeline(resource);
+ }
}
WebInspector.removeResource = function(resource)
resource.category.removeResource(resource);
- delete this.resourceURLMap[resource.url];
+ if (resource.url)
+ delete this.resourceURLMap[resource.url];
var resourcesLength = this.resources.length;
for (var i = 0; i < resourcesLength; ++i) {
delete this.mainResource;
}
+WebInspector.clearDatabaseResources = function()
+{
+ this.resourceCategories.databases.removeAllResources();
+}
+
WebInspector.resourceURLChanged = function(resource, oldURL)
{
delete this.resourceURLMap[oldURL];
#ifndef FileSystem_h
#define FileSystem_h
+#include <wtf/Vector.h>
+
namespace WebCore {
+class CString;
class String;
bool fileExists(const String&);
bool deleteFile(const String&);
bool fileSize(const String&, long long& result);
+String pathByAppendingComponent(const String& path, const String& component);
+bool makeAllDirectories(const String& path);
+String homeDirectoryPath();
+
+CString fileSystemRepresentation(const String&);
} // namespace WebCore
WTFLogChannel LogNetwork = { 0x00100000, "WebCoreLogLevel", WTFLogChannelOff };
WTFLogChannel LogFTP = { 0x00200000, "WebCoreLogLevel", WTFLogChannelOff };
WTFLogChannel LogThreading = { 0x00400000, "WebCoreLogLevel", WTFLogChannelOff };
+WTFLogChannel LogStorageAPI = { 0x00800000, "WebCoreLogLevel", WTFLogChannelOff };
+
}
extern WTFLogChannel LogNetwork;
extern WTFLogChannel LogFTP;
extern WTFLogChannel LogThreading;
+ extern WTFLogChannel LogStorageAPI;
void InitializeLoggingChannelsIfNecessary();
}
return equalIgnoringCase(m_host, String(url.host())) && equalIgnoringCase(m_protocol, String(url.protocol())) && m_port == url.port();
}
+String SecurityOrigin::toString() const
+{
+ return m_protocol + ":" + m_host + ":" + String::number(m_port);
+}
+
} // namespace WebCore
bool allowsAccessFrom(const SecurityOrigin&) const;
bool isSecureTransitionTo(const KURL&) const;
+ String toString() const;
+
private:
void clear();
bool isEmpty() const;
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#import "config.h"
+#import "FileSystem.h"
+
+#import "CString.h"
+#import "PlatformString.h"
+#import <wtf/RetainPtr.h>
+
+namespace WebCore {
+
+CString fileSystemRepresentation(const String& path)
+{
+ RetainPtr<CFStringRef> cfString(AdoptCF, path.createCFString());
+
+ if (!cfString)
+ return CString();
+
+ CFIndex size = CFStringGetMaximumSizeOfFileSystemRepresentation(cfString.get());
+
+ char* buffer;
+ CString string = CString::newUninitialized(size, buffer);
+
+ if (!CFStringGetFileSystemRepresentation(cfString.get(), buffer, size)) {
+ LOG_ERROR("Failed to get filesystem representation to create CString from cfString");
+ return CString();
+ }
+
+ return string;
+}
+
+} // namespace WebCore
virtual void setToolTip(const String&) { }
virtual void print(Frame*) { }
+
+ virtual bool runDatabaseSizeLimitPrompt(Frame*, const String&) { return false; }
+
};
class SVGEmptyFrameLoaderClient : public FrameLoaderClient {
namespace WebCore {
-bool fileExists(const String& path)
+String homeDirectoryPath()
{
- const char* fsRep = [(NSString *)path fileSystemRepresentation];
-
- if (!fsRep || fsRep[0] == '\0')
- return false;
-
- struct stat fileInfo;
-
- // stat(...) returns 0 on successful stat'ing of the file, and non-zero in any case where the file doesn't exist or cannot be accessed
- return !stat(fsRep, &fileInfo);
-}
-
-bool deleteFile(const String& path)
-{
- const char* fsRep = [(NSString *)path fileSystemRepresentation];
-
- if (!fsRep || fsRep[0] == '\0')
- return false;
-
- // unlink(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
- return !unlink(fsRep);
-}
-
-bool fileSize(const String& path, long long& result)
-{
- const char* fsRep = [(NSString *)path fileSystemRepresentation];
-
- if (!fsRep || fsRep[0] == '\0')
- return false;
-
- struct stat fileInfo;
-
- if (!stat(fsRep, &fileInfo))
- return false;
-
- result = fileInfo.st_size;
- return true;
+ return NSHomeDirectory();
}
-} //namespace WebCore
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#include "config.h"
+#include "FileSystem.h"
+
+#include "CString.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+bool fileExists(const String& path)
+{
+ if (path.isNull())
+ return false;
+
+ CString fsRep = fileSystemRepresentation(path);
+
+ if (!fsRep.data() || fsRep.data()[0] == '\0')
+ return false;
+
+ struct stat fileInfo;
+
+ // stat(...) returns 0 on successful stat'ing of the file, and non-zero in any case where the file doesn't exist or cannot be accessed
+ return !stat(fsRep.data(), &fileInfo);
+}
+
+bool deleteFile(const String& path)
+{
+ CString fsRep = fileSystemRepresentation(path);
+
+ if (!fsRep.data() || fsRep.data()[0] == '\0')
+ return false;
+
+ // unlink(...) returns 0 on successful deletion of the path and non-zero in any other case (including invalid permissions or non-existent file)
+ return !unlink(fsRep.data());
+}
+
+bool fileSize(const String& path, long long& result)
+{
+ CString fsRep = fileSystemRepresentation(path);
+
+ if (!fsRep.data() || fsRep.data()[0] == '\0')
+ return false;
+
+ struct stat fileInfo;
+
+ if (stat(fsRep.data(), &fileInfo))
+ return false;
+
+ result = fileInfo.st_size;
+ return true;
+}
+
+String pathByAppendingComponent(const String& path, const String& component)
+{
+ if (path.endsWith("/"))
+ return path + component;
+ else
+ return path + "/" + component;
+}
+
+bool makeAllDirectories(const String& path)
+{
+ CString fullPath = fileSystemRepresentation(path);
+ if (!access(fullPath.data(), F_OK))
+ return true;
+
+ char* p = fullPath.mutableData() + 1;
+ int length = fullPath.length();
+
+ if(p[length - 1] == '/')
+ p[length - 1] = '\0';
+ for (; *p; ++p)
+ if (*p == '/') {
+ *p = '\0';
+ if (access(fullPath.data(), F_OK))
+ if (mkdir(fullPath.data(), S_IRWXU))
+ return false;
+ *p = '/';
+ }
+ if (access(fullPath.data(), F_OK))
+ if (mkdir(fullPath.data(), S_IRWXU))
+ return false;
+
+ return true;
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#include "config.h"
+#include "SQLAuthorizer.h"
+
+#include <sqlite3.h>
+
+namespace WebCore {
+
+const int SQLAuthAllow = SQLITE_OK;
+const int SQLAuthIgnore = SQLITE_IGNORE;
+const int SQLAuthDeny = SQLITE_DENY;
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#ifndef SQLAuthorizer_h
+#define SQLAuthorizer_h
+
+#include "Threading.h"
+
+namespace WebCore {
+
+class String;
+
+extern const int SQLAuthAllow;
+extern const int SQLAuthIgnore;
+extern const int SQLAuthDeny;
+
+class SQLAuthorizer : public ThreadSafeShared<SQLAuthorizer> {
+public:
+ virtual ~SQLAuthorizer() { }
+
+ virtual int createTable(const String& tableName) { return SQLAuthAllow; }
+ virtual int createTempTable(const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTable(const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTempTable(const String& tableName) { return SQLAuthAllow; }
+ virtual int allowAlterTable(const String& databaseName, const String& tableName) { return SQLAuthAllow; }
+
+ virtual int createIndex(const String& indexName, const String& tableName) { return SQLAuthAllow; }
+ virtual int createTempIndex(const String& indexName, const String& tableName) { return SQLAuthAllow; }
+ virtual int dropIndex(const String& indexName, const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTempIndex(const String& indexName, const String& tableName) { return SQLAuthAllow; }
+
+ virtual int createTrigger(const String& triggerName, const String& tableName) { return SQLAuthAllow; }
+ virtual int createTempTrigger(const String& triggerName, const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTrigger(const String& triggerName, const String& tableName) { return SQLAuthAllow; }
+ virtual int dropTempTrigger(const String& triggerName, const String& tableName) { return SQLAuthAllow; }
+
+ virtual int createView(const String& viewName) { return SQLAuthAllow; }
+ virtual int createTempView(const String& viewName) { return SQLAuthAllow; }
+ virtual int dropView(const String& viewName) { return SQLAuthAllow; }
+ virtual int dropTempView(const String& viewName) { return SQLAuthAllow; }
+
+ virtual int createVTable(const String& tableName, const String& moduleName) { return SQLAuthAllow; }
+ virtual int dropVTable(const String& tableName, const String& moduleName) { return SQLAuthAllow; }
+
+ virtual int allowDelete(const String& tableName) { return SQLAuthAllow; }
+ virtual int allowInsert(const String& tableName) { return SQLAuthAllow; }
+ virtual int allowUpdate(const String& tableName, const String& columnName) { return SQLAuthAllow; }
+ virtual int allowTransaction() { return SQLAuthAllow; }
+
+ virtual int allowSelect() { return SQLAuthAllow; }
+ virtual int allowRead(const String& tableName, const String& columnName) { return SQLAuthAllow; }
+
+ virtual int allowAttach(const String& filename) { return SQLAuthAllow; }
+ virtual int allowDetach(const String& databaseName) { return SQLAuthAllow; }
+
+ virtual int allowReindex(const String& indexName) { return SQLAuthAllow; }
+ virtual int allowAnalyze(const String& tableName) { return SQLAuthAllow; }
+ virtual int allowFunction(const String& functionName) { return SQLAuthAllow; }
+ virtual int allowPragma(const String& pragmaName, const String& firstArgument) { return SQLAuthAllow; }
+};
+
+} // namespace WebCore
+
+#endif // SQLAuthorizer_h
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#include "config.h"
+#include "SQLValue.h"
+
+namespace WebCore {
+
+SQLValue::SQLValue(const SQLValue& val)
+{
+ m_number = val.m_number;
+ m_string = val.m_string.copy();
+ m_type = val.m_type;
+}
+
+String SQLValue::string() const
+{
+ ASSERT(m_type == StringValue);
+
+ // Must return a copy since ref-shared Strings are not thread safe
+ return m_string.copy();
+}
+
+double SQLValue::number() const
+{
+ ASSERT(m_type == NumberValue);
+
+ return m_number;
+}
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#ifndef SQLValue_h
+#define SQLValue_h
+
+#include "PlatformString.h"
+#include "Threading.h"
+
+namespace WebCore {
+
+ class SQLValue {
+ public:
+ enum Type { NullValue, NumberValue, StringValue };
+
+ SQLValue() : m_type(NullValue) { }
+ SQLValue(double number) : m_type(NumberValue), m_number(number) { }
+ SQLValue(const String& s) : m_type(StringValue), m_string(s) { }
+ SQLValue(const SQLValue&);
+
+ Type type() const { return m_type; }
+
+ String string() const;
+ double number() const;
+
+ private:
+ Type m_type;
+ double m_number;
+ String m_string;
+ };
+};
+
+#endif
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
- */
-
-#include "config.h"
-
-#include "FileSystem.h"
-#include "PlatformString.h"
-
-#include <sys/stat.h>
-
-namespace WebCore {
-
-bool fileSize(const String& path, long long& result)
-{
- struct _stat32i64 sb;
- String filename = path;
- int statResult = _wstat32i64(filename.charactersWithNullTermination(), &sb);
- if (statResult != 0 || (sb.st_mode & S_IFMT) != S_IFREG)
- return false;
- result = sb.st_size;
- return true;
-}
-
-bool fileExists(const String& path)
-{
- struct _stat32i64 sb;
- String filename = path;
- return !_wstat32i64(filename.charactersWithNullTermination(), &sb);
-}
-
-bool deleteFile(const String& path)
-{
- String filename = path;
- return !!DeleteFileW(filename.charactersWithNullTermination());
-}
-
-}
+/*\r
+ * Copyright (C) 2007 Apple Inc. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer. \r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution. \r
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of\r
+ * its contributors may be used to endorse or promote products derived\r
+ * from this software without specific prior written permission. \r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY\r
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY\r
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+\r
+#include "config.h"\r
+#include "FileSystem.h"\r
+\r
+#include "CString.h"\r
+#include "NotImplemented.h"\r
+#include "PlatformString.h"\r
+\r
+#include <windows.h>\r
+#include <winbase.h>\r
+#include <shlobj.h>\r
+\r
+namespace WebCore {\r
+\r
+bool fileSize(const String& path, long long& result)\r
+{\r
+ struct _stat32i64 sb;\r
+ String filename = path;\r
+ int statResult = _wstat32i64(filename.charactersWithNullTermination(), &sb);\r
+ if (statResult != 0 || (sb.st_mode & S_IFMT) != S_IFREG)\r
+ return false;\r
+ result = sb.st_size;\r
+ return true;\r
+}\r
+\r
+bool fileExists(const String& path) \r
+{\r
+ struct _stat32i64 sb;\r
+ String filename = path;\r
+ return !_wstat32i64(filename.charactersWithNullTermination(), &sb);\r
+}\r
+\r
+bool deleteFile(const String& path)\r
+{\r
+ String filename = path;\r
+ return !!DeleteFileW(filename.charactersWithNullTermination());\r
+}\r
+\r
+String pathByAppendingComponent(const String& path, const String& component)\r
+{\r
+ if (path.endsWith("\\"))\r
+ return path + component;\r
+ else\r
+ return path + "\\" + component;\r
+}\r
+\r
+CString fileSystemRepresentation(const String&)\r
+{\r
+ return "";\r
+}\r
+\r
+bool makeAllDirectories(const String& path)\r
+{\r
+ String fullPath = path;\r
+ if (!SHCreateDirectoryEx(0, fullPath.charactersWithNullTermination(), 0)) {\r
+ DWORD error = GetLastError();\r
+ if (error != ERROR_FILE_EXISTS && error != ERROR_ALREADY_EXISTS) {\r
+ LOG_ERROR("Failed to create path %s", path.ascii().data());\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+}\r
+\r
+String homeDirectoryPath()\r
+{\r
+ notImplemented();\r
+ return "";\r
+}\r
+\r
+} // namespace WebCore\r
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#include "config.h"
+#include "Database.h"
+
+#include "CString.h"
+#include "DatabaseAuthorizer.h"
+#include "DatabaseCallback.h"
+#include "DatabaseTask.h"
+#include "DatabaseThread.h"
+#include "DatabaseTracker.h"
+#include "Document.h"
+#include "ExceptionCode.h"
+#include "FileSystem.h"
+#include "Frame.h"
+#include "InspectorController.h"
+#include "Logging.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "SQLCallback.h"
+#include "SQLDatabase.h"
+#include "SQLResultSet.h"
+#include "SQLStatement.h"
+#include "VersionChangeCallback.h"
+
+namespace WebCore {
+
+Mutex& Database::globalCallbackMutex()
+{
+ static Mutex mutex;
+ return mutex;
+}
+
+HashSet<RefPtr<Database> >& Database::globalCallbackSet()
+{
+ static HashSet<RefPtr<Database> > set;
+ return set;
+}
+
+bool Database::s_globalCallbackScheduled = false;
+
+Mutex& Database::guidMutex()
+{
+ static Mutex mutex;
+ return mutex;
+}
+
+HashMap<int, String>& Database::guidToVersionMap()
+{
+ static HashMap<int, String> map;
+ return map;
+}
+
+HashMap<int, HashSet<Database*>*>& Database::guidToDatabaseMap()
+{
+ static HashMap<int, HashSet<Database*>*> map;
+ return map;
+}
+
+const String& Database::databaseInfoTableName()
+{
+ static String name = "__WebKitDatabaseInfoTable__";
+ return name;
+}
+
+static const String& databaseVersionKey()
+{
+ static String key = "WebKitDatabaseVersionKey";
+ return key;
+}
+
+PassRefPtr<Database> Database::openDatabase(Document* document, const String& name, const String& expectedVersion, ExceptionCode& e)
+{
+ RefPtr<Database> database = new Database(document, name, expectedVersion);
+
+ if (!database->openAndVerifyVersion(e)) {
+ LOG(StorageAPI, "Failed to open and verify version (expected %s) of database %s", expectedVersion.ascii().data(), database->databaseDebugName().ascii().data());
+ return 0;
+ }
+
+ if (Page* page = document->frame()->page())
+ page->inspectorController()->didOpenDatabase(database.get(), document->securityOrigin().toString(), name, expectedVersion);
+
+ return database;
+}
+
+Database::Database(Document* document, const String& name, const String& expectedVersion)
+ : m_document(document)
+ , m_name(name.copy())
+ , m_guid(0)
+ , m_expectedVersion(expectedVersion)
+ , m_databaseThread(0)
+{
+ ASSERT(document);
+
+ // FIXME: Right now, this is the entire domain of the document, when it really needs to be scheme/host/port only
+ m_securityOrigin = document->securityOrigin();
+
+ if (m_name.isNull())
+ m_name = "";
+
+ m_guid = guidForOriginAndName(m_securityOrigin.toString(), name);
+
+ {
+ MutexLocker locker(guidMutex());
+
+ HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid);
+ if (!hashSet) {
+ hashSet = new HashSet<Database*>;
+ guidToDatabaseMap().set(m_guid, hashSet);
+ }
+
+ hashSet->add(this);
+ }
+
+ {
+ MutexLocker locker(m_databaseThreadMutex);
+ m_databaseThread = document->databaseThread();
+ ASSERT(m_databaseThread);
+ }
+
+ m_filename = DatabaseTracker::tracker().fullPathForDatabase(m_securityOrigin.toString(), m_name);
+}
+
+Database::~Database()
+{
+ MutexLocker locker(guidMutex());
+
+ HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid);
+ ASSERT(hashSet);
+ ASSERT(hashSet->contains(this));
+ hashSet->remove(this);
+ if (hashSet->isEmpty()) {
+ guidToDatabaseMap().remove(m_guid);
+ delete hashSet;
+ ASSERT(guidToVersionMap().contains(m_guid));
+ guidToVersionMap().remove(m_guid);
+ }
+}
+
+bool Database::openAndVerifyVersion(ExceptionCode& e)
+{
+ // Open the main thread connection to the database
+ if (!m_mainSQLDatabase.open(m_filename)) {
+ LOG_ERROR("Unable to open database at path %s", m_filename.ascii().data());
+ e = INVALID_STATE_ERR;
+ return false;
+ }
+
+ m_databaseAuthorizer = new DatabaseAuthorizer();
+ m_mainSQLDatabase.setAuthorizer(m_databaseAuthorizer);
+
+ // Open the background thread connection
+ RefPtr<DatabaseOpenTask> task = new DatabaseOpenTask();
+
+ task->lockForSynchronousScheduling();
+ m_databaseThread->scheduleImmediateTask(this, task.get());
+ task->waitForSynchronousCompletion();
+
+ ASSERT(task->isComplete());
+ e = task->exceptionCode();
+ return task->openSuccessful();
+}
+
+
+static bool retrieveTextResultFromDatabase(SQLDatabase& db, const String& query, String& resultString)
+{
+ SQLStatement statement(db, query);
+ int result = statement.prepare();
+
+ if (result != SQLResultOk) {
+ LOG_ERROR("Error (%i) preparing statement to read text result from database (%s)", result, query.ascii().data());
+ return false;
+ }
+
+ result = statement.step();
+ if (result == SQLResultRow) {
+ resultString = statement.getColumnText16(0);
+ return true;
+ } else if (result == SQLResultDone) {
+ resultString = String();
+ return true;
+ } else {
+ LOG_ERROR("Error (%i) reading text result from database (%s)", result, query.ascii().data());
+ return false;
+ }
+}
+
+bool Database::getVersionFromDatabase(String& version)
+{
+ static String getVersionQuery = "SELECT value FROM " + databaseInfoTableName() + " WHERE key = '" + databaseVersionKey() + "';";
+
+ m_databaseAuthorizer->disable();
+
+ bool result = retrieveTextResultFromDatabase(m_threadSQLDatabase, getVersionQuery.copy(), version);
+ if (!result)
+ LOG_ERROR("Failed to retrieve version from database %s", databaseDebugName().ascii().data());
+
+ m_databaseAuthorizer->enable();
+
+ return result;
+}
+
+static bool setTextValueInDatabase(SQLDatabase& db, const String& query, const String& value)
+{
+ SQLStatement statement(db, query);
+ int result = statement.prepare();
+
+ if (result != SQLResultOk) {
+ LOG_ERROR("Failed to prepare statement to set value in database (%s)", query.ascii().data());
+ return false;
+ }
+
+ statement.bindText16(1, value);
+
+ result = statement.step();
+ if (result != SQLResultDone) {
+ LOG_ERROR("Failed to step statement to set value in database (%s)", query.ascii().data());
+ return false;
+ }
+
+ return true;
+}
+
+bool Database::setVersionInDatabase(const String& version)
+{
+ static String setVersionQuery = "INSERT INTO " + databaseInfoTableName() + " (key, value) VALUES ('" + databaseVersionKey() + "', ?);";
+
+ m_databaseAuthorizer->disable();
+
+ bool result = setTextValueInDatabase(m_threadSQLDatabase, setVersionQuery.copy(), version);
+ if (!result)
+ LOG_ERROR("Failed to set version %s in database (%s)", version.ascii().data(), setVersionQuery.ascii().data());
+
+ m_databaseAuthorizer->enable();
+
+ return result;
+}
+
+void Database::databaseThreadGoingAway()
+{
+ // FIXME: We might not need this anymore
+
+ LOG(StorageAPI, "Database thread is going away for database %p\n", this);
+}
+
+void Database::disableAuthorizer()
+{
+ ASSERT(m_databaseAuthorizer);
+ m_databaseAuthorizer->disable();
+}
+
+void Database::enableAuthorizer()
+{
+ ASSERT(m_databaseAuthorizer);
+ m_databaseAuthorizer->enable();
+}
+
+int Database::guidForOriginAndName(const String& origin, const String& name)
+{
+ static int currentNewGUID = 1;
+ static Mutex stringIdentifierMutex;
+ static HashMap<String, int> stringIdentifierToGUIDMap;
+
+ String stringID;
+ if (origin.endsWith("/"))
+ stringID = origin + name;
+ else
+ stringID = origin + "/" + name;
+
+ MutexLocker locker(stringIdentifierMutex);
+ int guid = stringIdentifierToGUIDMap.get(stringID);
+ if (!guid) {
+ guid = currentNewGUID++;
+ stringIdentifierToGUIDMap.set(stringID, guid);
+ }
+
+ return guid;
+}
+
+void Database::resetAuthorizer()
+{
+ if (m_databaseAuthorizer)
+ m_databaseAuthorizer->reset();
+}
+
+void Database::performPolicyChecks()
+{
+ // FIXME: Code similar to the following will need to be run to enforce the per-origin size limit the spec mandates.
+ // Additionally, we might need a way to pause the database thread while the UA prompts the user for permission to
+ // increase the size limit
+
+ /*
+ if (m_databaseAuthorizer->lastActionIncreasedSize())
+ DatabaseTracker::scheduleFileSizeCheckOnMainThread(this);
+ */
+
+ notImplemented();
+}
+
+bool Database::performOpenAndVerify(ExceptionCode& e)
+{
+ if (!m_threadSQLDatabase.open(m_filename)) {
+ LOG_ERROR("Unable to open database at path %s", m_filename.ascii().data());
+ e = INVALID_STATE_ERR;
+ return false;
+ }
+
+ ASSERT(m_databaseAuthorizer);
+ m_threadSQLDatabase.setAuthorizer(m_databaseAuthorizer);
+
+ if (!m_threadSQLDatabase.executeCommand("CREATE TABLE IF NOT EXISTS " + databaseInfoTableName() + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) {
+ LOG_ERROR("Unable to create table %s in database %s", databaseInfoTableName().ascii().data(), databaseDebugName().ascii().data());
+ e = INVALID_STATE_ERR;
+ return false;
+ }
+
+
+ String currentVersion;
+ {
+ MutexLocker locker(guidMutex());
+ currentVersion = guidToVersionMap().get(m_guid);
+
+
+ if (currentVersion.isNull())
+ LOG(StorageAPI, "Current cached version for guid %i is null", m_guid);
+ else
+ LOG(StorageAPI, "Current cached version for guid %i is %s", m_guid, currentVersion.ascii().data());
+
+ if (currentVersion.isNull()) {
+ if (!getVersionFromDatabase(currentVersion)) {
+ LOG_ERROR("Failed to get current version from database %s", databaseDebugName().ascii().data());
+ e = INVALID_STATE_ERR;
+ return false;
+ }
+ if (currentVersion.length()) {
+ LOG(StorageAPI, "Retrieved current version %s from database %s", currentVersion.ascii().data(), databaseDebugName().ascii().data());
+ } else {
+ LOG(StorageAPI, "Setting version %s in database %s that was just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().data());
+ if (!setVersionInDatabase(m_expectedVersion)) {
+ LOG_ERROR("Failed to set version %s in database %s", m_expectedVersion.ascii().data(), databaseDebugName().ascii().data());
+ e = INVALID_STATE_ERR;
+ return false;
+ }
+
+ currentVersion = m_expectedVersion;
+ }
+
+ guidToVersionMap().set(m_guid, currentVersion.copy());
+ }
+ }
+
+ if (currentVersion.isNull()) {
+ LOG(StorageAPI, "Database %s does not have its version set", databaseDebugName().ascii().data());
+ currentVersion = "";
+ }
+
+ // FIXME: For now, the spec says that if the database has no version, it is valid for any "Expected version" string. That seems silly and I think it should be
+ // changed, and here's where we would change it
+ if (m_expectedVersion.length()) {
+ if (currentVersion.length() && m_expectedVersion != currentVersion) {
+ LOG(StorageAPI, "page expects version %s from database %s, which actually has version name %s - openDatabase() call will fail", m_expectedVersion.ascii().data(),
+ databaseDebugName().ascii().data(), currentVersion.ascii().data());
+ e = INVALID_STATE_ERR;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void Database::scheduleDatabaseCallback(DatabaseCallback* callback)
+{
+ ASSERT(callback);
+ MutexLocker locker(globalCallbackMutex());
+ {
+ MutexLocker locker(m_callbackMutex);
+ m_pendingCallbacks.append(callback);
+ globalCallbackSet().add(this);
+ if (!s_globalCallbackScheduled) {
+ callOnMainThread(deliverAllPendingCallbacks);
+ s_globalCallbackScheduled = true;
+ }
+ }
+}
+
+void Database::performChangeVersion(const String& oldVersion, const String& newVersion, PassRefPtr<VersionChangeCallback> callback)
+{
+ // FIXME: "user agent must obtain a full lock of the database (waiting for all open transactions to be closed)"
+ // Currently, not having implemented the implicit thread transaction, we're not all too worried about this.
+ // Once the transaction is implemented, we'll have to find a way to reschedule the changeVersion over and over as long as
+ // transactions are active. Keep on bumping it to second in line, or something!
+
+ bool result = true;
+
+ MutexLocker locker(guidMutex());
+ {
+ // Run this code in a block to guarantee that actualVersion goes out of scope before the mutex
+ // is released, so we can avoid copying the string when inserting but still avoid
+ // string thread-safety issues
+ String actualVersion;
+ if (!getVersionFromDatabase(actualVersion)) {
+ LOG_ERROR("Unable to retrieve actual current version from database");
+ result = false;
+ }
+
+ if (result && actualVersion != oldVersion) {
+ LOG_ERROR("Old version doesn't match actual version");
+ result = false;
+ }
+
+ if (result && !setVersionInDatabase(newVersion)) {
+ LOG_ERROR("Unable to set new version in database");
+ result = false;
+ }
+
+ if (result)
+ guidToVersionMap().set(m_guid, actualVersion);
+ }
+
+ scheduleDatabaseCallback(new DatabaseChangeVersionCallback(callback, result));
+}
+
+void Database::performExecuteSql(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLCallback> callback)
+{
+ ASSERT(callback);
+
+ RefPtr<SQLResultSet> resultSet = new SQLResultSet;
+ bool succeeded = true;
+
+ m_databaseAuthorizer->reset();
+
+ SQLStatement statement(m_threadSQLDatabase, sqlStatement);
+ int result = statement.prepare();
+ if (result != SQLResultOk) {
+ LOG(StorageAPI, "Failed to prepare sql query '%s' - error was: %s", sqlStatement.ascii().data(), statement.lastErrorMsg());
+ succeeded = false;
+ resultSet->setErrorCode(1);
+ resultSet->setErrorMessage(m_threadSQLDatabase.lastErrorMsg());
+ }
+
+ if (succeeded) {
+ for (unsigned i = 0; i < arguments.size(); ++i) {
+ if (statement.bindValue(i + 1, arguments[i]) != SQLResultOk) {
+ LOG(StorageAPI, "Failed to bind value index %i to statement for query '%s'", i + 1, sqlStatement.ascii().data());
+ // FIXME: Mark the transaction invalid here once we implement the transaction part of the spec
+ succeeded = false;
+ resultSet->setErrorCode(1);
+ resultSet->setErrorMessage(m_threadSQLDatabase.lastErrorMsg());
+ break;
+ }
+ }
+ }
+
+ // Step so we can fetch the column names.
+ result = statement.step();
+ if (result == SQLResultRow && succeeded) {
+ int columnCount = statement.columnCount();
+ SQLResultSetRowList* rows = resultSet->rows();
+
+ for (int i = 0; i < columnCount; i++)
+ rows->addColumn(statement.getColumnName16(i));
+
+ do {
+ for (int i = 0; i < columnCount; i++) {
+ // FIXME: Look at the column type
+ rows->addResult(statement.getColumnText16(i));
+ }
+
+ result = statement.step();
+ } while (result == SQLResultRow);
+
+ if (result != SQLResultDone) {
+ resultSet->setErrorCode(1);
+ resultSet->setErrorMessage(m_threadSQLDatabase.lastErrorMsg());
+ succeeded = false;
+ }
+ } else if (result == SQLResultDone && succeeded) {
+ // Didn't find anything, or was an insert
+ if (m_databaseAuthorizer->lastActionWasInsert())
+ resultSet->setInsertId(m_threadSQLDatabase.lastInsertRowID());
+ } else if (succeeded) {
+ // A new error occured on the first step of the statement - record it here
+ resultSet->setErrorCode(1);
+ resultSet->setErrorMessage(m_threadSQLDatabase.lastErrorMsg());
+ succeeded = false;
+ }
+
+ // FIXME: If the spec allows triggers, and we want to be "accurate" in a different way, we'd use
+ // sqlite3_total_changes() here instead of sqlite3_changed, because that includes rows modified from within a trigger
+ // For now, this seems sufficient
+ if (succeeded)
+ resultSet->setRowsAffected(m_threadSQLDatabase.lastChanges());
+
+ scheduleDatabaseCallback(new DatabaseExecuteSqlCallback(callback, resultSet.release()));
+}
+
+void Database::performCloseTransaction()
+{
+ notImplemented();
+}
+
+Vector<String> Database::performGetTableNames()
+{
+ disableAuthorizer();
+
+ SQLStatement statement(m_threadSQLDatabase, "SELECT name FROM sqlite_master WHERE type='table';");
+ if (statement.prepare() != SQLResultOk) {
+ LOG_ERROR("Unable to retrieve list of tables for database %s", databaseDebugName().ascii().data());
+ enableAuthorizer();
+ return Vector<String>();
+ }
+
+ Vector<String> tableNames;
+ int result;
+ while ((result = statement.step()) == SQLResultRow) {
+ String name = statement.getColumnText16(0);
+ if (name != databaseInfoTableName())
+ tableNames.append(name);
+ }
+
+ enableAuthorizer();
+
+ if (result != SQLResultDone) {
+ LOG_ERROR("Error getting tables for database %s", databaseDebugName().ascii().data());
+ return Vector<String>();
+ }
+
+ return tableNames;
+}
+
+String Database::version() const
+{
+ MutexLocker locker(guidMutex());
+ return guidToVersionMap().get(m_guid).copy();
+}
+
+void Database::changeVersion(const String& oldVersion, const String& newVersion, PassRefPtr<VersionChangeCallback> callback)
+{
+ ASSERT(m_databaseThread);
+ m_databaseThread->scheduleTask(this, new DatabaseChangeVersionTask(oldVersion, newVersion, callback));
+}
+
+void Database::executeSql(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLCallback> callback, ExceptionCode& e)
+{
+ // 4.11.3 Step 1 - Statement and argument validation
+ // FIXME: Currently the best way we have to validate the statement is to create an actual SQLStatement and prepare it. We can't prepare on
+ // the main thread and run on the worker thread, because the worker thread might be in the middle of database activity. So we have two options
+ // 1 - Break up the executeSql task into two steps. Step 1 is prepare the statement on the background thread while the main thread waits. If
+ // the statement is valid, the main thread can return and step 2 would continue asynchronously, actually running the statement and generating results
+ // The synchronous step 1 could "cut in line", but the main thread could still block waiting for any currently running query to complete
+ // 2 - Keep a main thread connection around, and keep a worker thread connection around. The main thread connection will be used solely to prepare
+ // statements, checking them for validity. After a statement is clear, the work can be scheduled on the background thread. This way, if there is a
+ // read-only query running on the background thread, the main thread can simultaneously do the prepare on the main thread and there will be no
+ // contention. This is an advantage over #1. A disadvantage is that between the prepare on the main thread and actually performing the query on the
+ // background thread, there is a time window where the schema could change and the statement is no longer valid.
+ // 3 - A much more complex, less tested, but possibly premium solution is to do #1, but combine it with the use of the sqlite_busy_handler. This would allow
+ // any long-running queries to periodically check and see if there's anything they need to do. The sqlite3 docs claim sqlite is theoretically reentrant,
+ // and therefore a statement could be prepared inside a busy handler, if just to check for validation. But it is also likely untested, and is not recc.
+ // Testing must be done on this possibility before going forward with it
+ //
+ // For now, I'm going with solution #2, as it is easiest to implement and the true badness of its "con" is dubious.
+
+ SQLStatement statement(m_mainSQLDatabase, sqlStatement);
+ int result = statement.prepare();
+
+ // Workaround for <rdar://problem/5537019> - a prepare on 1 connection immediately after a statement that changes the schema on the second connection
+ // can fail with a SQLResultSchema error. Trying to prepare it a second time will succeed, assuming it is actually a valid statement
+ if (result == SQLResultSchema) {
+ statement.finalize();
+ result = statement.prepare();
+ }
+
+ if (result != SQLResultOk) {
+ LOG(StorageAPI, "Unable to verify correctness of statement %s - error %i (%s)", sqlStatement.ascii().data(), result, statement.lastErrorMsg());
+ e = SYNTAX_ERR;
+ return;
+ }
+
+ // FIXME: If the statement uses the ?### syntax supported by sqlite, the bind parameter count is very likely off from the number of question marks.
+ // If this is the case, they might be trying to do something fishy or malicious
+ if (statement.bindParameterCount() != arguments.size()) {
+ LOG(StorageAPI, "Bind parameter count doesn't match number of question marks - someone's trying to use the ?### format and this might be bad");
+ e = SYNTAX_ERR;
+ return;
+ }
+
+ statement.finalize();
+
+ // FIXME: There is one remaining error with the above procedure. The statement might have ?### style binds in it that will still escape the above checks
+ // For example, a statement with "?2 ?2" in it will have 2 question marks, a bind parameter count of 2, but bind number 1 will not be valid.
+ // To catch this, we either need to do a dry run of bindings here (which might be expensive), or do some manual parsing to make sure ?### isn't used at all
+
+ // FIXME: Haven't yet implemented the thread global transaction due to ambiguity/churn in the spec
+ // 4.11.3 Step 2 - Assign existing transaction or begin a new one to "transaction" associated with this statement
+
+ // FIXME: Haven't yet implemented the thread global transaction due to ambiguity/churn in the spec
+ // 4.11.3 Step 3 - If "transaction" is marked as bad, throw "INVALID_STATE_ERR" exception
+
+ ASSERT(m_databaseThread);
+ m_databaseThread->scheduleTask(this, new DatabaseExecuteSqlTask(sqlStatement, arguments, callback));
+}
+
+void Database::closeTransaction()
+{
+ // FIXME: Haven't yet implemented the thread global transaction due to ambiguity/churn in the spec
+ notImplemented();
+}
+
+void Database::deliverAllPendingCallbacks()
+{
+ Vector<RefPtr<Database> > databases;
+ {
+ MutexLocker locker(globalCallbackMutex());
+ copyToVector(globalCallbackSet(), databases);
+ globalCallbackSet().clear();
+ s_globalCallbackScheduled = false;
+ }
+
+ LOG(StorageAPI, "Having %u databases deliver their pending callbacks", databases.size());
+ for (unsigned i = 0; i < databases.size(); ++i)
+ databases[i]->deliverPendingCallbacks();
+}
+
+void Database::deliverPendingCallbacks()
+{
+ Vector<RefPtr<DatabaseCallback> > callbacks;
+ {
+ MutexLocker locker(m_callbackMutex);
+ callbacks.swap(m_pendingCallbacks);
+ }
+
+ LOG(StorageAPI, "Delivering %u callbacks for database %p", callbacks.size(), this);
+ for (unsigned i = 0; i < callbacks.size(); ++i)
+ callbacks[i]->performCallback();
+}
+
+Vector<String> Database::tableNames()
+{
+ RefPtr<DatabaseTableNamesTask> task = new DatabaseTableNamesTask();
+
+ task->lockForSynchronousScheduling();
+ m_databaseThread->scheduleImmediateTask(this, task.get());
+ task->waitForSynchronousCompletion();
+
+ return task->tableNames();
+}
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#ifndef Database_h
+#define Database_h
+
+#include "PlatformString.h"
+#include "SecurityOrigin.h"
+#include "SQLDatabase.h"
+#include "StringHash.h"
+#include "Threading.h"
+#include "Timer.h"
+#include "VersionChangeCallback.h"
+
+#include <wtf/Forward.h>
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/Deque.h>
+
+namespace WebCore {
+
+class DatabaseAuthorizer;
+class DatabaseCallback;
+class DatabaseThread;
+class Document;
+class SQLCallback;
+class SQLResultSet;
+class SQLValue;
+
+typedef int ExceptionCode;
+
+class Database : public ThreadSafeShared<Database> {
+public:
+ ~Database();
+
+// Direct support for the DOM API
+ static PassRefPtr<Database> openDatabase(Document* document, const String& name, const String& expectedVersion, ExceptionCode&);
+
+ String version() const;
+ void changeVersion(const String& oldVersion, const String& newVersion, PassRefPtr<VersionChangeCallback> callback);
+
+ void executeSql(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLCallback> callback, ExceptionCode&);
+ void closeTransaction();
+
+// Internal engine support
+ void databaseThreadGoingAway();
+ static const String& databaseInfoTableName();
+
+ void disableAuthorizer();
+ void enableAuthorizer();
+
+ Vector<String> tableNames();
+
+ Document* document() const { return m_document; }
+
+// Called from DatabaseThread, must be prepared to work on the background thread
+ void resetAuthorizer();
+ void performPolicyChecks();
+
+ bool performOpenAndVerify(ExceptionCode&);
+ void performChangeVersion(const String& oldVersion, const String& newVersion, PassRefPtr<VersionChangeCallback> callback);
+ void performExecuteSql(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLCallback> callback);
+ void performCloseTransaction();
+ Vector<String> performGetTableNames();
+
+private:
+ Database(Document* document, const String& name, const String& expectedVersion);
+
+ bool openAndVerifyVersion(ExceptionCode&);
+ bool getVersionFromDatabase(String&);
+ bool setVersionInDatabase(const String&);
+
+ static void scheduleFileSizeTimerOnMainThread(Database*);
+ static void performScheduleFileSizeTimers();
+ void scheduleFileSizeTimer();
+ void sizeTimerFired(Timer<Database>*);
+ OwnPtr<Timer<Database> > m_sizeTimer;
+
+ static void deliverAllPendingCallbacks();
+ void deliverPendingCallbacks();
+
+ void scheduleDatabaseCallback(DatabaseCallback*);
+
+ // FIXME: Is it okay to reconcile hanging on to the raw pointer? We definitely have to rely on
+ // Document telling DatabaseThread it's going away, and DatabaseThread telling Database its going away
+ Document* m_document;
+ SecurityOrigin m_securityOrigin;
+ String m_name;
+ int m_guid;
+ String m_expectedVersion;
+ String m_filename;
+
+ SQLDatabase m_mainSQLDatabase;
+ SQLDatabase m_threadSQLDatabase;
+ RefPtr<DatabaseAuthorizer> m_databaseAuthorizer;
+
+ Mutex m_databaseThreadMutex;
+ DatabaseThread* m_databaseThread;
+
+ Mutex m_callbackMutex;
+ Vector<RefPtr<DatabaseCallback> > m_pendingCallbacks;
+
+#ifndef NDEBUG
+ String databaseDebugName() const { return m_securityOrigin.toString() + "::" + m_name; }
+#endif
+
+ static Mutex& globalCallbackMutex();
+ static HashSet<RefPtr<Database> >& globalCallbackSet();
+ static bool s_globalCallbackScheduled;
+
+ static int guidForOriginAndName(const String&, const String&);
+
+ static Mutex& guidMutex();
+ static HashMap<int, String>& guidToVersionMap();
+ static HashMap<int, HashSet<Database*>*>& guidToDatabaseMap();
+};
+
+} // namespace WebCore
+
+#endif // Database_h
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+module storage {
+
+ interface Database {
+ readonly attribute DOMString version;
+ [Custom] boolean changeVersion(in DOMString oldVersion, in DOMString newVersion, in VersionChangeCallback callback);
+ [Custom] void executeSql(in DOMString sqlStatement, arguments..., in SQLCallback callback);
+ void closeTransaction();
+ };
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#include "config.h"
+#include "DatabaseAuthorizer.h"
+
+#include "Database.h"
+#include "PlatformString.h"
+
+namespace WebCore {
+
+DatabaseAuthorizer::DatabaseAuthorizer()
+ : m_securityEnabled(false)
+{
+ reset();
+}
+
+void DatabaseAuthorizer::reset()
+{
+ m_lastActionWasInsert = false;
+ m_lastActionIncreasedSize = false;
+}
+
+int DatabaseAuthorizer::createTable(const String& tableName)
+{
+ m_lastActionIncreasedSize = true;
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::createTempTable(const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::dropTable(const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::dropTempTable(const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::allowAlterTable(const String& databaseName, const String& tableName)
+{
+ m_lastActionIncreasedSize = true;
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::createIndex(const String& indexName, const String& tableName)
+{
+ m_lastActionIncreasedSize = true;
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::createTempIndex(const String& indexName, const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::dropIndex(const String& indexName, const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::dropTempIndex(const String& indexName, const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::createTrigger(const String& triggerName, const String& tableName)
+{
+ m_lastActionIncreasedSize = true;
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::createTempTrigger(const String& triggerName, const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::dropTrigger(const String& triggerName, const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::dropTempTrigger(const String& triggerName, const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::createVTable(const String& tableName, const String& moduleName)
+{
+ m_lastActionIncreasedSize = true;
+ return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
+}
+
+int DatabaseAuthorizer::dropVTable(const String& tableName, const String& moduleName)
+{
+ return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
+}
+
+int DatabaseAuthorizer::allowDelete(const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::allowInsert(const String& tableName)
+{
+ m_lastActionIncreasedSize = true;
+ m_lastActionWasInsert = true;
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::allowUpdate(const String& tableName, const String& columnName)
+{
+ m_lastActionIncreasedSize = true;
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::allowRead(const String& tableName, const String& columnName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::allowAnalyze(const String& tableName)
+{
+ return denyBasedOnTableName(tableName);
+}
+
+int DatabaseAuthorizer::allowPragma(const String& pragmaName, const String& firstArgument)
+{
+ return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
+}
+
+int DatabaseAuthorizer::allowAttach(const String& filename)
+{
+ return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
+}
+
+int DatabaseAuthorizer::allowDetach(const String& databaseName)
+{
+ return m_securityEnabled ? SQLAuthDeny : SQLAuthAllow;
+}
+
+int DatabaseAuthorizer::allowFunction(const String& functionName)
+{
+ // FIXME: Are there any of these we need to prevent? One might guess current_date, current_time, current_timestamp because
+ // they would violate the "sandbox environment" part of 4.11.3, but scripts can generate the local client side information via
+ // javascript directly, anyways. Are there any other built-ins we need to be worried about?
+ return SQLAuthAllow;
+}
+
+void DatabaseAuthorizer::disable()
+{
+ m_securityEnabled = false;
+}
+
+void DatabaseAuthorizer::enable()
+{
+ m_securityEnabled = true;
+}
+
+int DatabaseAuthorizer::denyBasedOnTableName(const String& tableName)
+{
+ if (!m_securityEnabled)
+ return SQLAuthAllow;
+
+ // Sadly, normal creates and drops end up affecting sqlite_master in an authorizer callback, so
+ // it will be tough to enforce all of the following policies
+ //if (equalIgnoringCase(tableName, "sqlite_master") || equalIgnoringCase(tableName, "sqlite_temp_master") ||
+ // equalIgnoringCase(tableName, "sqlite_sequence") || equalIgnoringCase(tableName, Database::databaseInfoTableName()))
+ // return SQLAuthDeny;
+
+ if (equalIgnoringCase(tableName, Database::databaseInfoTableName()))
+ return SQLAuthDeny;
+
+ return SQLAuthAllow;
+}
+
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#ifndef DatabaseAuthorizer_h
+#define DatabaseAuthorizer_h
+
+#include "SQLAuthorizer.h"
+
+namespace WebCore {
+
+class DatabaseAuthorizer : public SQLAuthorizer {
+public:
+ DatabaseAuthorizer();
+
+ virtual int createTable(const String& tableName);
+ virtual int createTempTable(const String& tableName);
+ virtual int dropTable(const String& tableName);
+ virtual int dropTempTable(const String& tableName);
+ virtual int allowAlterTable(const String& databaseName, const String& tableName);
+
+ virtual int createIndex(const String& indexName, const String& tableName);
+ virtual int createTempIndex(const String& indexName, const String& tableName);
+ virtual int dropIndex(const String& indexName, const String& tableName);
+ virtual int dropTempIndex(const String& indexName, const String& tableName);
+
+ virtual int createTrigger(const String& triggerName, const String& tableName);
+ virtual int createTempTrigger(const String& triggerName, const String& tableName);
+ virtual int dropTrigger(const String& triggerName, const String& tableName);
+ virtual int dropTempTrigger(const String& triggerName, const String& tableName);
+
+ virtual int createVTable(const String& tableName, const String& moduleName);
+ virtual int dropVTable(const String& tableName, const String& moduleName);
+
+ virtual int allowDelete(const String& tableName);
+ virtual int allowInsert(const String& tableName);
+ virtual int allowUpdate(const String& tableName, const String& columnName);
+
+ virtual int allowRead(const String& tableName, const String& columnName);
+
+ virtual int allowAnalyze(const String& tableName);
+ virtual int allowPragma(const String& pragmaName, const String& firstArgument);
+
+ virtual int allowAttach(const String& filename);
+ virtual int allowDetach(const String& databaseName);
+
+ virtual int allowFunction(const String& functionName);
+
+ void disable();
+ void enable();
+
+ void reset();
+
+ bool lastActionWasInsert() const { return m_lastActionWasInsert; }
+ bool lastActionIncreasedSize() const { return m_lastActionIncreasedSize; }
+private:
+ int denyBasedOnTableName(const String&);
+ bool m_securityEnabled;
+ bool m_lastActionWasInsert;
+ bool m_lastActionIncreasedSize;
+};
+
+} // namespace WebCore
+
+#endif // DatabaseAuthorizer_h
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#include "config.h"
+#include "DatabaseCallback.h"
+
+#include "SQLCallback.h"
+#include "SQLResultSet.h"
+#include "VersionChangeCallback.h"
+
+namespace WebCore {
+
+DatabaseChangeVersionCallback::DatabaseChangeVersionCallback(PassRefPtr<VersionChangeCallback> callback, bool versionChanged)
+ : m_callback(callback)
+ , m_versionChanged(versionChanged)
+{
+ ASSERT(callback->isThreadSafe());
+}
+
+void DatabaseChangeVersionCallback::performCallback()
+{
+ m_callback->handleEvent(m_versionChanged);
+}
+
+DatabaseExecuteSqlCallback::DatabaseExecuteSqlCallback(PassRefPtr<SQLCallback> callback, PassRefPtr<SQLResultSet> resultSet)
+ : m_callback(callback)
+ , m_resultSet(resultSet)
+{
+ ASSERT(callback->isThreadSafe());
+ ASSERT(resultSet->isThreadSafe());
+}
+
+void DatabaseExecuteSqlCallback::performCallback()
+{
+ m_callback->handleEvent(m_resultSet.get());
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#ifndef DatabaseCallback_h
+#define DatabaseCallback_h
+
+#include "Threading.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class SQLCallback;
+class SQLResultSet;
+class VersionChangeCallback;
+
+class DatabaseCallback : public ThreadSafeShared<DatabaseCallback> {
+public:
+ virtual ~DatabaseCallback() { }
+ virtual void performCallback() = 0;
+};
+
+class DatabaseChangeVersionCallback : public DatabaseCallback {
+public:
+ DatabaseChangeVersionCallback(PassRefPtr<VersionChangeCallback>, bool versionChanged);
+ virtual ~DatabaseChangeVersionCallback() { }
+ virtual void performCallback();
+
+private:
+ RefPtr<VersionChangeCallback> m_callback;
+ bool m_versionChanged;
+};
+
+class DatabaseExecuteSqlCallback : public DatabaseCallback {
+public:
+ DatabaseExecuteSqlCallback(PassRefPtr<SQLCallback>, PassRefPtr<SQLResultSet>);
+ virtual ~DatabaseExecuteSqlCallback() { }
+ virtual void performCallback();
+private:
+ RefPtr<SQLCallback> m_callback;
+ RefPtr<SQLResultSet> m_resultSet;
+};
+
+} // namespace WebCore
+
+#endif // DatabaseCallback_h
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#include "config.h"
+#include "DatabaseTask.h"
+
+#include "Database.h"
+#include "Logging.h"
+#include "SQLValue.h"
+#include "SQLCallback.h"
+
+namespace WebCore {
+
+DatabaseTask::DatabaseTask()
+ : m_complete(false)
+ , m_synchronous(false)
+{
+}
+
+DatabaseTask::~DatabaseTask()
+{
+}
+
+void DatabaseTask::performTask(Database* db)
+{
+ // Database tasks are meant to be used only once, so make sure this one hasn't been performed before
+ ASSERT(!m_complete);
+
+ LOG(StorageAPI, "Performing DatabaseTask %p\n", this);
+
+ if (m_synchronous)
+ m_synchronousMutex.lock();
+
+ db->resetAuthorizer();
+ doPerformTask(db);
+ db->performPolicyChecks();
+
+ m_complete = true;
+
+ if (m_synchronous) {
+ m_synchronousCondition.signal();
+ m_synchronousMutex.unlock();
+ }
+}
+
+void DatabaseTask::lockForSynchronousScheduling()
+{
+ m_synchronousMutex.lock();
+ m_synchronous = true;
+}
+
+void DatabaseTask::waitForSynchronousCompletion()
+{
+ // Caller of this method must lock this object beforehand
+ ASSERT(m_synchronousMutex.tryLock() == false);
+
+ m_synchronousCondition.wait(m_synchronousMutex);
+ m_synchronous = false;
+ m_synchronousMutex.unlock();
+}
+
+// *** DatabaseOpenTask ***
+// Opens the database file and verifies the version matches the expected version
+
+DatabaseOpenTask::DatabaseOpenTask()
+ : DatabaseTask()
+ , m_code(0)
+ , m_success(false)
+{
+}
+
+void DatabaseOpenTask::doPerformTask(Database* db)
+{
+ m_success = db->performOpenAndVerify(m_code);
+}
+
+// *** DatabaseExecuteSqlTask ***
+// Runs the passed in sql query along with the arguments, and calls the callback with the results
+
+DatabaseExecuteSqlTask::DatabaseExecuteSqlTask(const String& query, const Vector<SQLValue>& arguments, PassRefPtr<SQLCallback> callback)
+ : DatabaseTask()
+ , m_query(query.copy())
+ , m_arguments(arguments)
+ , m_callback(callback)
+{
+ ASSERT(callback->isThreadSafe());
+}
+
+void DatabaseExecuteSqlTask::doPerformTask(Database* db)
+{
+ db->performExecuteSql(m_query, m_arguments, m_callback);
+}
+
+// *** DatabaseChangeVersionTask ***
+// Atomically verifies the current version is the same as the passed in "old version", and changes it to the new version
+
+DatabaseChangeVersionTask::DatabaseChangeVersionTask(const String& oldVersion, const String& newVersion, PassRefPtr<VersionChangeCallback> callback)
+ : m_oldVersion(oldVersion.copy())
+ , m_newVersion(newVersion.copy())
+ , m_callback(callback)
+{
+ ASSERT(callback->isThreadSafe());
+}
+
+void DatabaseChangeVersionTask::doPerformTask(Database* db)
+{
+ db->performChangeVersion(m_oldVersion, m_newVersion, m_callback);
+}
+
+// *** DatabaseTableNamesTask ***
+// Retrieves a list of all tables in the database - for WebInspector support
+
+DatabaseTableNamesTask::DatabaseTableNamesTask()
+{
+}
+
+void DatabaseTableNamesTask::doPerformTask(Database* db)
+{
+ m_tableNames = db->performGetTableNames();
+}
+
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#ifndef DatabaseTask_h
+#define DatabaseTask_h
+
+#include "ExceptionCode.h"
+#include "PlatformString.h"
+#include "Threading.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Database;
+class DatabaseThread;
+class SQLValue;
+class SQLCallback;
+class VersionChangeCallback;
+
+class DatabaseTask : public ThreadSafeShared<DatabaseTask>
+{
+ friend class Database;
+public:
+ virtual ~DatabaseTask();
+
+ void performTask(Database*);
+
+ bool isComplete() const { return m_complete; }
+protected:
+ DatabaseTask();
+ virtual void doPerformTask(Database* db) = 0;
+
+private:
+ void lockForSynchronousScheduling();
+ void waitForSynchronousCompletion();
+
+ bool m_complete;
+
+ Mutex m_synchronousMutex;
+ bool m_synchronous;
+ ThreadCondition m_synchronousCondition;
+};
+
+class DatabaseOpenTask : public DatabaseTask
+{
+public:
+ DatabaseOpenTask();
+
+ ExceptionCode exceptionCode() const { return m_code; }
+ bool openSuccessful() const { return m_success; }
+
+protected:
+ virtual void doPerformTask(Database* db);
+
+private:
+ ExceptionCode m_code;
+ bool m_success;
+};
+
+class DatabaseChangeVersionTask : public DatabaseTask
+{
+public:
+ DatabaseChangeVersionTask(const String& oldVersion, const String& newVersion, PassRefPtr<VersionChangeCallback>);
+
+protected:
+ virtual void doPerformTask(Database* db);
+
+private:
+ String m_oldVersion;
+ String m_newVersion;
+ RefPtr<VersionChangeCallback> m_callback;
+};
+
+class DatabaseExecuteSqlTask : public DatabaseTask
+{
+public:
+ DatabaseExecuteSqlTask(const String& query, const Vector<SQLValue>& arguments, PassRefPtr<SQLCallback> callback);
+
+protected:
+ virtual void doPerformTask(Database* db);
+
+private:
+ String m_query;
+ Vector<SQLValue> m_arguments;
+ RefPtr<SQLCallback> m_callback;
+};
+
+class DatabaseCloseTransactionTask: public DatabaseTask
+{
+public:
+ DatabaseCloseTransactionTask();
+
+protected:
+ virtual void doPerformTask(Database* db);
+};
+
+class DatabaseTableNamesTask : public DatabaseTask
+{
+public:
+ DatabaseTableNamesTask();
+
+ Vector<String>& tableNames() { return m_tableNames; }
+protected:
+ virtual void doPerformTask(Database* db);
+private:
+ Vector<String> m_tableNames;
+};
+
+} // namespace WebCore
+
+#endif // DatabaseTask_h
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#include "config.h"
+#include "DatabaseThread.h"
+
+#include "AutodrainedPool.h"
+#include "Database.h"
+#include "DatabaseTask.h"
+#include "Logging.h"
+
+namespace WebCore {
+
+DatabaseThread::DatabaseThread(Document* document)
+ : m_threadID(0)
+ , m_terminationRequested(false)
+{
+ m_selfRef = this;
+}
+
+DatabaseThread::~DatabaseThread()
+{
+ // FIXME: Any cleanup required here? Since the thread deletes itself after running its detached course, I don't think so. Lets be sure.
+}
+
+bool DatabaseThread::start()
+{
+ if (m_threadID)
+ return true;
+
+ m_threadID = createThread(DatabaseThread::databaseThreadStart, this);
+
+ return m_threadID;
+}
+
+void DatabaseThread::documentGoingAway()
+{
+ // This document is going away, so this thread is going away.
+ // -Clear records of all Databases out
+ // -Leave the thread main loop
+ // -Detach the thread so the thread itself runs out and releases all thread resources
+ // -Clear the RefPtr<> self so if noone else is hanging on the thread, the object itself is deleted.
+
+ LOG(StorageAPI, "Document owning DatabaseThread %p is going away - starting thread shutdown", this);
+
+ // Clear all database records out, and let Databases know that this DatabaseThread is going away
+ {
+ MutexLocker locker(m_databaseWorkMutex);
+
+ // FIXME - The policy we're enforcing right here is that when a document goes away, any pending
+ // sql queries that were queued up also go away. Is this appropriate?
+
+ HashSet<RefPtr<Database> >::iterator i = m_activeDatabases.begin();
+ HashSet<RefPtr<Database> >::iterator end = m_activeDatabases.end();
+
+ for (; i != end; ++i) {
+ (*i)->databaseThreadGoingAway();
+ Deque<RefPtr<DatabaseTask> >* databaseQueue = m_databaseTaskQueues.get((*i).get());
+ ASSERT(databaseQueue);
+ m_databaseTaskQueues.remove((*i).get());
+ delete databaseQueue;
+ }
+ ASSERT(m_databaseTaskQueues.isEmpty());
+ m_activeDatabases.clear();
+ }
+
+ // Request the thread to cleanup and shutdown
+ m_terminationRequested = true;
+ wakeWorkThread();
+}
+
+void DatabaseThread::databaseGoingAway(Database* database)
+{
+ MutexLocker locker(m_databaseWorkMutex);
+ if (!m_activeDatabases.contains(database))
+ return;
+
+ // FIXME - The policy we're enforcing right here is that when a document goes away, any pending
+ // sql queries that were queued up also go away. Is this appropriate?
+ Deque<RefPtr<DatabaseTask> >* databaseQueue = m_databaseTaskQueues.get(database);
+ ASSERT(databaseQueue);
+ m_databaseTaskQueues.remove(database);
+ delete databaseQueue;
+
+ m_activeDatabases.remove(database);
+}
+
+void* DatabaseThread::databaseThreadStart(void* vDatabaseThread)
+{
+ DatabaseThread* dbThread = static_cast<DatabaseThread*>(vDatabaseThread);
+ return dbThread->databaseThread();
+}
+
+void* DatabaseThread::databaseThread()
+{
+ LOG(StorageAPI, "Starting DatabaseThread %p", this);
+
+ while (!m_terminationRequested) {
+ m_threadMutex.unlock();
+ AutodrainedPool pool;
+
+ LOG(StorageAPI, "Iteration of main loop for DatabaseThread %p", this);
+
+ bool result;
+ do {
+ result = dispatchNextTaskIdentifier();
+ if (m_terminationRequested)
+ break;
+ } while(result);
+
+ if (m_terminationRequested)
+ break;
+
+ pool.cycle();
+ m_threadMutex.lock();
+ m_threadCondition.wait(m_threadMutex);
+ }
+ m_threadMutex.unlock();
+
+ LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount());
+
+ // Detach the thread so its resources are no longer of any concern to anyone else
+ detachThread(m_threadID);
+
+ // Clear the self refptr, possibly resulting in deletion
+ m_selfRef = 0;
+
+ return 0;
+}
+
+bool DatabaseThread::dispatchNextTaskIdentifier()
+{
+ Database* workDatabase = 0;
+ RefPtr<DatabaseTask> task;
+
+ {
+ MutexLocker locker(m_databaseWorkMutex);
+ while (!task && m_globalQueue.size()) {
+ Database* database = m_globalQueue.first();
+ m_globalQueue.removeFirst();
+
+ Deque<RefPtr<DatabaseTask> >* databaseQueue = m_databaseTaskQueues.get(database);
+ ASSERT(databaseQueue || !m_activeDatabases.contains(database));
+ if (!databaseQueue)
+ continue;
+
+ ASSERT(databaseQueue->size());
+ task = databaseQueue->first();
+ workDatabase = database;
+ databaseQueue->removeFirst();
+ }
+ }
+
+ if (task) {
+ ASSERT(workDatabase);
+ workDatabase->resetAuthorizer();
+ task->performTask(workDatabase);
+ return true;
+ }
+
+ return false;
+}
+
+void DatabaseThread::scheduleTask(Database* database, DatabaseTask* task)
+{
+ if (m_terminationRequested) {
+ LOG(StorageAPI, "Attempted to schedule task %p from database %p on DatabaseThread %p after it was requested to terminate", task, database, this);
+ return;
+ }
+
+ MutexLocker locker(m_databaseWorkMutex);
+
+ Deque<RefPtr<DatabaseTask> >* databaseQueue = 0;
+
+ if (!m_activeDatabases.contains(database)) {
+ m_activeDatabases.add(database);
+ databaseQueue = new Deque<RefPtr<DatabaseTask> >;
+ m_databaseTaskQueues.set(database, databaseQueue);
+ }
+
+ if (!databaseQueue)
+ databaseQueue = m_databaseTaskQueues.get(database);
+
+ ASSERT(databaseQueue);
+
+ databaseQueue->append(task);
+ m_globalQueue.append(database);
+
+ wakeWorkThread();
+}
+
+void DatabaseThread::scheduleImmediateTask(Database* database, DatabaseTask* task)
+{
+ if (m_terminationRequested) {
+ LOG_ERROR("Attempted to schedule immediate task %p from database %p on DatabaseThread %p after it was requested to terminate", task, database, this);
+ return;
+ }
+ MutexLocker locker(m_databaseWorkMutex);
+
+ Deque<RefPtr<DatabaseTask> >* databaseQueue = 0;
+
+ if (!m_activeDatabases.contains(database)) {
+ m_activeDatabases.add(database);
+ databaseQueue = new Deque<RefPtr<DatabaseTask> >;
+ m_databaseTaskQueues.set(database, databaseQueue);
+ }
+
+ if (!databaseQueue)
+ databaseQueue = m_databaseTaskQueues.get(database);
+
+ ASSERT(databaseQueue);
+
+ databaseQueue->prepend(task);
+ m_globalQueue.prepend(database);
+
+ wakeWorkThread();
+}
+
+void DatabaseThread::wakeWorkThread()
+{
+ MutexLocker locker(m_threadMutex);
+ m_threadCondition.signal();
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#ifndef DatabaseThread_h
+#define DatabaseThread_h
+
+#include "Threading.h"
+
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/Deque.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+
+class Database;
+class DatabaseTask;
+class Document;
+
+class DatabaseThread : public ThreadSafeShared<DatabaseThread>
+{
+public:
+ DatabaseThread(Document*);
+ ~DatabaseThread();
+
+ bool start();
+ void documentGoingAway();
+ void databaseGoingAway(Database*);
+
+ void scheduleTask(Database*, DatabaseTask*);
+ void scheduleImmediateTask(Database*, DatabaseTask*);
+private:
+ static void* databaseThreadStart(void*);
+ void* databaseThread();
+ void wakeWorkThread();
+ bool dispatchNextTaskIdentifier();
+
+ ThreadIdentifier m_threadID;
+ RefPtr<DatabaseThread> m_selfRef;
+
+ // For waking/sleeping the work thread
+ ThreadCondition m_threadCondition;
+ Mutex m_threadMutex;
+ bool m_terminationRequested;
+
+ // FIXME: Need a much better queue structure than the linked-list based queue being used
+
+ // Work unit and Database management
+ Mutex m_databaseWorkMutex;
+ HashMap<Database*, Deque<RefPtr<DatabaseTask> >*> m_databaseTaskQueues;
+ HashSet<RefPtr<Database> > m_activeDatabases;
+ Deque<Database*> m_globalQueue;
+};
+
+} // namespace WebCore
+
+#endif // DatabaseThread_h
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#include "config.h"
+#include "DatabaseTracker.h"
+
+#include "Database.h"
+#include "FileSystem.h"
+#include "NotImplemented.h"
+#include "SQLStatement.h"
+
+namespace WebCore {
+
+String DatabaseTracker::s_databasePath;
+
+void DatabaseTracker::setDatabasePath(const String& path)
+{
+ s_databasePath = path;
+}
+
+const String& DatabaseTracker::databasePath()
+{
+ return s_databasePath;
+}
+
+DatabaseTracker& DatabaseTracker::tracker()
+{
+ static DatabaseTracker tracker;
+
+ return tracker;
+}
+
+DatabaseTracker::DatabaseTracker()
+{
+ String databasePath = DatabaseTracker::databasePath();
+ makeAllDirectories(databasePath);
+ databasePath = pathByAppendingComponent(databasePath, "Databases.db");
+
+ if (!m_database.open(databasePath)) {
+ // FIXME: What do do here?
+ return;
+ }
+
+ if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS Origins (origin TEXT UNIQUE ON CONFLICT REPLACE, creationPolicy INTEGER NOT NULL ON CONFLICT FAIL, sizePolicy INTEGER NOT NULL ON CONFLICT FAIL);")) {
+ // FIXME: and here
+ }
+
+ if (!m_database.executeCommand("CREATE TABLE IF NOT EXISTS Databases (guid INTEGER PRIMARY KEY AUTOINCREMENT, origin TEXT UNIQUE ON CONFLICT REPLACE, name TEXT UNIQUE ON CONFLICT REPLACE, path TEXT NOT NULL ON CONFLICT FAIL);")) {
+ // FIXME: and here
+ }
+}
+
+String DatabaseTracker::fullPathForDatabase(const String& origin, const String& name)
+{
+ String databasePath = DatabaseTracker::databasePath();
+ SQLStatement statement(m_database, "SELECT path FROM Databases WHERE origin=? AND name=?;");
+
+ if (statement.prepare() != SQLResultOk)
+ return "";
+
+ statement.bindText16(1, origin, false);
+ statement.bindText16(2, name, false);
+
+ int result = statement.step();
+
+ if (result == SQLResultRow)
+ return pathByAppendingComponent(databasePath, statement.getColumnText16(0));
+ if (result != SQLResultDone) {
+ LOG_ERROR("Failed to retrieve filename from Database Tracker for origin %s, name %s", origin.ascii().data(), name.ascii().data());
+ return "";
+ }
+
+ SQLStatement sequenceStatement(m_database, "SELECT seq FROM sqlite_sequence WHERE name='Databases';");
+
+ // FIXME: More informative error handling here, even though these steps should never fail
+ if (sequenceStatement.prepare() != SQLResultOk)
+ return "";
+ result = sequenceStatement.step();
+
+ // This has a range of 2^63 and starts at 0 for every time a user resets Safari -
+ // I can't imagine it'd over overflow
+ int64_t seq = 0;
+ if (result == SQLResultRow) {
+ seq = sequenceStatement.getColumnInt64(0);
+ } else if (result != SQLResultDone)
+ return "";
+
+ String filename;
+ do {
+ ++seq;
+ filename = pathByAppendingComponent(databasePath, String::format("%016llx.db", seq));
+ } while (fileExists(filename));
+
+ sequenceStatement.finalize();
+
+ if (!addDatabase(origin, name, String::format("%016llx.db", seq)))
+ return "";
+
+ return filename;
+}
+
+void DatabaseTracker::populateOrigins()
+{
+ if (m_origins)
+ return;
+
+ m_origins.set(new HashSet<String>);
+
+ if (!m_database.isOpen())
+ return;
+
+ SQLStatement statement(m_database, "SELECT DISTINCT origin FROM Databases;");
+
+ if (statement.prepare() != SQLResultOk)
+ return;
+
+ int result;
+ while ((result = statement.step()) == SQLResultRow)
+ m_origins->add(statement.getColumnText16(0));
+
+ if (result != SQLResultDone)
+ LOG_ERROR("Failed to read in all origins from the database");
+
+ return;
+}
+
+const HashSet<String>& DatabaseTracker::origins()
+{
+ if (!m_origins)
+ populateOrigins();
+
+ return *(m_origins.get());
+}
+
+bool DatabaseTracker::databaseNamesForOrigin(const String& origin, Vector<String>& resultVector)
+{
+ if (!m_database.isOpen())
+ return false;
+
+ SQLStatement statement(m_database, "SELECT name FROM Databases where origin=?;");
+
+ if (statement.prepare() != SQLResultOk)
+ return false;
+
+ statement.bindText16(1, origin, false);
+
+ int result;
+ while ((result = statement.step()) == SQLResultRow)
+ resultVector.append(statement.getColumnText16(0));
+
+ if (result != SQLResultDone) {
+ LOG_ERROR("Failed to retrieve all database names for origin %s", origin.ascii().data());
+ return false;
+ }
+
+ return true;
+}
+
+bool DatabaseTracker::addDatabase(const String& origin, const String& name, const String& path)
+{
+ if (!m_database.isOpen())
+ return false;
+
+ SQLStatement statement(m_database, "INSERT INTO Databases (origin, name, path) VALUES (?, ?, ?);");
+
+ if (statement.prepare() != SQLResultOk)
+ return false;
+
+ statement.bindText16(1, origin, true);
+ statement.bindText16(2, name, true);
+ statement.bindText16(3, path, true);
+
+ if (!statement.executeCommand()) {
+ LOG_ERROR("Failed to add database %s to origin %s: %s\n", name.ascii().data(), origin.ascii().data(), statement.lastErrorMsg());
+ return false;
+ }
+
+ populateOrigins();
+ m_origins->add(origin);
+ return true;
+}
+
+void DatabaseTracker::deleteAllDatabases()
+{
+ notImplemented();
+}
+
+void DatabaseTracker::deleteAllDatabasesForOrigin(const String& origin)
+{
+ notImplemented();
+}
+
+void DatabaseTracker::deleteDatabase(const String& origin, const String& name)
+{
+ notImplemented();
+}
+
+} // namespace WebCore
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+#ifndef DatabaseTracker_h
+#define DatabaseTracker_h
+
+#include "PlatformString.h"
+#include "SQLDatabase.h"
+#include "StringHash.h"
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class DatabaseTracker {
+public:
+ static void setDatabasePath(const String&);
+ static const String& databasePath();
+
+ String fullPathForDatabase(const String& origin, const String& name);
+
+ const HashSet<String>& origins();
+ bool databaseNamesForOrigin(const String& origin, Vector<String>& result);
+
+ void deleteAllDatabases();
+ void deleteAllDatabasesForOrigin(const String& origin);
+ void deleteDatabase(const String& origin, const String& name);
+
+ static DatabaseTracker& tracker();
+private:
+ DatabaseTracker();
+
+ bool addDatabase(const String& origin, const String& name, const String& path);
+ void populateOrigins();
+
+ SQLDatabase m_database;
+ mutable OwnPtr<HashSet<String> > m_origins;
+
+ static String s_databasePath;
+};
+
+} // namespace WebCore
+
+#endif // DatabaseTracker_h
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+#ifndef SQLCallback_h
+#define SQLCallback_h
+
+#include "Threading.h"
+
+namespace WebCore {
+
+class SQLResultSet;
+
+class SQLCallback : public ThreadSafeShared<SQLCallback> {
+public:
+ virtual ~SQLCallback() { }
+ virtual void handleEvent(SQLResultSet*) = 0;
+};
+
+} // namespace WebCore
+
+#endif // SQLCallback_h
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS CONTRIBUTORS 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.
+ */
+
+module storage {
+
+ interface SQLCallback {
+ void handleEvent(in SQLResultSet resultSet);
+ };
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * 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 Apple Computer, Inc. ("Apple") 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 APPLE AND ITS CONTRIBUTORS "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 APPLE OR ITS