webengine/osswebengine/WebCore/platform/symbian/FormDataStore.cpp
changeset 0 dd21522fd290
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebCore/platform/symbian/FormDataStore.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,221 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+#include "config.h"
+#include "FormDataStore.h"
+#include "FormFillController.h"
+#include "SQLStatement.h"
+_LIT(KDBFile, "c:\\private\\%08x\\form.db");
+
+namespace WebCore {
+
+// prepareSQLStatement() is a direct copy of readySQLStatement() in IconDatabase.cpp
+inline void prepareSQLStatement(SQLStatement*& statement, SQLDatabase& db, const String& str)
+{
+    if (statement && (statement->database() != &db || statement->isExpired())) {
+        if (statement->isExpired()) {
+            //LOG(IconDatabase, "SQLStatement associated with %s is expired", str.ascii().data());
+        }
+        delete statement;
+        statement = 0;
+    }
+    if (!statement) {
+        statement = new SQLStatement(db, str);
+        int result;
+        result = statement->prepare();
+        ASSERT(result == SQLResultOk);
+    }
+}
+
+
+FormDataStore::FormDataStore(FormFillController*) 
+    : m_setFormValueStatement(0), m_getFormValueStatement(0), m_deleteFormDataStatement(0)
+{
+    if(!openFormDatabase()) {
+        //LOG_ERROR("Could not open form fill database.");
+    }
+}
+
+FormDataStore::~FormDataStore()
+{
+    close();
+}
+
+static inline bool compareString(String a, String b)
+{
+    int i = 0;
+
+    // empty string
+    if( a.isEmpty() ) 
+        return true;
+
+    if( b.isEmpty() )
+        return false;
+
+    int len = a.length() < b.length() ? a.length() : b.length();
+    while (i++<len) {
+        if (a[i] < b[i])
+            return true;
+        else if(a[i] > b[i])
+            return false;
+    }
+    
+    // a is shorter?
+    return (a.length() < b.length());
+}
+
+bool FormDataStore::search(const String& name_, const String& value_, Vector<String>& results)
+{
+    results.clear();
+    if (!m_formDB.isOpen()) 
+        return false;
+    
+    // so that we don't have to query the database on every search.
+    if (m_lastQueriedName != name_)
+        getFormValueQuery(name_);
+    
+    // no search the values in cache
+    if (!m_valueCache.isEmpty()) {
+        HashSet<String>::const_iterator it = m_valueCache.begin(), end = m_valueCache.end();
+        for (; it != end; ++it) {
+            if ((*it).startsWith(value_)) {
+                results.append(*it);
+            }
+        }
+
+        // FIXME: sorting the result? - maybe we could do the sorting in data table insersion.
+        std::stable_sort(results.begin(), results.end(), compareString);
+    }
+
+    return true;
+}
+
+void FormDataStore::add(const String& name_, const String& value_)
+{
+    if (m_lastQueriedName == name_ && m_valueCache.contains(value_))
+        return;
+    if (!m_formDB.isOpen())
+        return;
+
+    // update the local cache
+    if (m_lastQueriedName == name_)
+        m_valueCache.add(value_);
+
+    setFormValueQuery(name_, value_);
+}
+
+void FormDataStore::createDatabaseTable()
+{
+    if (!m_formDB.executeCommand("CREATE TABLE Input (name TEXT NOT NULL ON CONFLICT FAIL, value TEXT NOT NULL ON CONFLICT FAIL);")) {
+        //LOG_ERROR("Could not create Input table in database (%i) - %s", m_formDB.lastError(), m_formDB.lastErrorMsg());
+        m_formDB.close();
+        return;
+    }
+}
+
+void FormDataStore::setFormValueQuery(const String& name, const String& value)
+{
+    prepareSQLStatement( m_setFormValueStatement, m_formDB, "INSERT INTO Input (name, value) VALUES ((?), (?));");
+    m_setFormValueStatement->bindText16(1, name, false);
+    m_setFormValueStatement->bindText16(2, value, false);
+
+    if (m_setFormValueStatement->step() != SQLResultDone) {
+        LOG_ERROR("setFormValueQuery failed");
+    }
+    
+    m_setFormValueStatement->reset();
+}
+
+void FormDataStore::getFormValueQuery(const String& name)
+{
+    prepareSQLStatement(m_getFormValueStatement, m_formDB, "SELECT Input.value FROM Input WHERE Input.name = (?);");
+    m_getFormValueStatement->bindText16(1, name, false);
+
+    int result = m_getFormValueStatement->step();
+
+    // update the result cache
+    m_valueCache.clear();
+    
+    while (result == SQLResultRow) {
+        m_valueCache.add(m_getFormValueStatement->getColumnText16(0));
+        result = m_getFormValueStatement->step();
+    }
+
+    if (result != SQLResultDone) {
+        LOG_ERROR("getFormValueQuery failed");
+    }
+    
+    m_getFormValueStatement->reset();
+    m_lastQueriedName = name;
+}
+
+void FormDataStore::deleteFormDataQuery()
+{
+    prepareSQLStatement(m_deleteFormDataStatement, m_formDB, "DELETE FROM Input");
+    int result = m_deleteFormDataStatement->step();
+    if (result != SQLResultDone) {
+        LOG_ERROR("deleteFormDataQuery failed");
+    }
+}
+
+bool FormDataStore::openFormDatabase()
+{
+    if (m_formDB.isOpen()) {
+        LOG_ERROR("Attempt to reopen the formDatabase which is already open.  Must close it first.");
+        return false;
+    }
+
+    // create the database file in C drive
+    // FIXME: the path shouldn't be hardcoded, move to data-caging directory
+	RProcess myProcess;	
+	TBuf <256>fileName;    
+    fileName.Format(KDBFile, myProcess.Identity());
+    String s(fileName.Ptr(), fileName.Length());
+    if (!m_formDB.open(s)) {
+        return false;
+    }
+
+    if (!m_formDB.tableExists("Input")) {
+        m_formDB.clearAllTables();
+        createDatabaseTable();
+    }
+
+    m_formDB.setSynchronous(SQLDatabase::SyncOff);
+    m_formDB.setFullsync(false);
+
+    return m_formDB.isOpen();
+}
+
+void FormDataStore::close()
+{
+    m_valueCache.clear();
+    delete m_setFormValueStatement;
+    m_setFormValueStatement = NULL;
+    delete m_getFormValueStatement;
+    m_getFormValueStatement = NULL;
+    delete m_deleteFormDataStatement;
+    m_deleteFormDataStatement = NULL;
+    m_formDB.close();
+}
+
+void FormDataStore::deleteAll()
+{
+    m_valueCache.clear();
+    deleteFormDataQuery();
+}
+
+} // END OF FILE