Reviewed by Levi and Tim Omernick.
authorbeidson <beidson@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Jun 2006 22:43:46 +0000 (22:43 +0000)
committerbeidson <beidson@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Jun 2006 22:43:46 +0000 (22:43 +0000)
        -Added a skeleton sqlite3 icon database file to IconDatabase
        -Added functionality to validate and recreate this icon.db file
        -Fixed some buggys in SQLDatabase.cpp

        * icon/IconDatabase.cpp:
        (WebCore::IconDatabase::open):
        (WebCore::IconDatabase::isValidDatabase):
        (WebCore::IconDatabase::clearDatabase):
        (WebCore::IconDatabase::recreateDatabase):
        * icon/IconDatabase.h:

        * icon/SQLStatement.cpp:
        (WebCore::SQLStatement::columnCount):
        (WebCore::SQLStatement::getColumnName):
        (WebCore::SQLStatement::getColumnName16):
        (WebCore::SQLStatement::getColumnText):
        (WebCore::SQLStatement::getColumnText16):
        (WebCore::SQLStatement::getColumnDouble):
        (WebCore::SQLStatement::getColumnInt):
        (WebCore::SQLStatement::getColumnInt64):
        (WebCore::SQLStatement::getColumnBlob):
        -Added checks to make sure we had a valid working sqlite3_statement as the sqlite3_*
        function calls weren't as error-tolerant as documentation advertised
        (maybe differences between the 3.3 docs I looked at and the 3.1.3 version installed on OSX)

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@14825 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/icon/IconDatabase.cpp
WebCore/icon/IconDatabase.h
WebCore/icon/SQLStatement.cpp

index cad40af12ea4a0ebbdefbe287eee9289902ccf9a..6775c61c1fc2fee0f7c7edce6470720e27950513 100644 (file)
@@ -1,3 +1,32 @@
+2006-06-12  Brady Eidson  <beidson@apple.com>
+
+        Reviewed by Levi and Tim Omernick.
+
+        -Added a skeleton sqlite3 icon database file to IconDatabase
+        -Added functionality to validate and recreate this icon.db file
+        -Fixed some buggys in SQLDatabase.cpp
+
+        * icon/IconDatabase.cpp:
+        (WebCore::IconDatabase::open):
+        (WebCore::IconDatabase::isValidDatabase):
+        (WebCore::IconDatabase::clearDatabase):
+        (WebCore::IconDatabase::recreateDatabase):
+        * icon/IconDatabase.h:
+
+        * icon/SQLStatement.cpp:
+        (WebCore::SQLStatement::columnCount):
+        (WebCore::SQLStatement::getColumnName):
+        (WebCore::SQLStatement::getColumnName16):
+        (WebCore::SQLStatement::getColumnText):
+        (WebCore::SQLStatement::getColumnText16):
+        (WebCore::SQLStatement::getColumnDouble):
+        (WebCore::SQLStatement::getColumnInt):
+        (WebCore::SQLStatement::getColumnInt64):
+        (WebCore::SQLStatement::getColumnBlob):
+        -Added checks to make sure we had a valid working sqlite3_statement as the sqlite3_*
+        function calls weren't as error-tolerant as documentation advertised
+        (maybe differences between the 3.3 docs I looked at and the 3.1.3 version installed on OSX)
+
 2006-06-12  Brady Eidson  <beidson@apple.com>
 
         Reviewed by Levi.
index db79514ad9865c0903449f0415c248c73fe6835e..99322ec1a1a6775c1fa8c91adbeb8843e3afef8a 100644 (file)
@@ -37,6 +37,7 @@ const char* DefaultIconDatabaseFilename = "/icon.db";
 namespace WebCore {
 
 IconDatabase* IconDatabase::m_sharedInstance = 0;
+const int IconDatabase::currentDatabaseVersion = 3;
 
 IconDatabase* IconDatabase::sharedIconDatabase()
 {
@@ -55,7 +56,18 @@ bool IconDatabase::open(const String& databasePath)
 {
     close();
     String dbFilename = databasePath + DefaultIconDatabaseFilename;
-    return m_db.open(dbFilename);
+    if (!m_db.open(dbFilename)) {
+        LOG(IconDatabase, "Unable to open icon database at path %s", dbFilename.deprecatedString().ascii());
+        return false;
+    }
+    
+    if (!isValidDatabase()) {
+        LOG(IconDatabase, "%s is in an invalid state - reconstructing", dbFilename.deprecatedString().ascii());
+        clearDatabase();
+        recreateDatabase();
+    }
+    
+    return isOpen();
 }
 
 void IconDatabase::close()
@@ -64,6 +76,75 @@ void IconDatabase::close()
     m_db.close();
 }
 
+
+bool IconDatabase::isValidDatabase()
+{
+    if (!m_db.tableExists("IconDatabaseInfo")) {
+        return false;
+    }
+    
+    String query = "SELECT value FROM IconDatabaseInfo WHERE key = 'Version';";
+    SQLStatement sql(m_db, query);
+    sql.prepare();
+    sql.step();
+    if (sql.getColumnInt(0) < currentDatabaseVersion) {
+        LOG(IconDatabase, "DB version is not found or below expected valid version");
+        return false;
+    }
+    
+    if (!m_db.tableExists("Icon") || !m_db.tableExists("PageURL") || !m_db.tableExists("IconResource")) {
+        return false;
+    }
+    return true;
+}
+
+void IconDatabase::clearDatabase()
+{
+    String query = "SELECT name FROM sqlite_master WHERE type='table';";
+    Vector<String> tables;
+    if (!SQLStatement(m_db, query).returnTextResults16(0, tables)) {
+        LOG(IconDatabase, "Unable to retrieve list of tables from database");
+        return;
+    }
+    
+    for (Vector<String>::iterator table = tables.begin(); table != tables.end(); ++table ) {
+        if (!m_db.executeCommand("DROP TABLE " + *table)) {
+            LOG(IconDatabase, "Unable to drop table %s", (*table).deprecatedString().ascii());
+        }
+    }
+}
+
+void IconDatabase::recreateDatabase()
+{
+    if (!m_db.executeCommand("CREATE TABLE IconDatabaseInfo (key varchar NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value integer NOT NULL ON CONFLICT FAIL);")) {
+        LOG_ERROR("Could not create IconDatabaseInfo table in icon.db (%i)\n%s", m_db.lastError(), m_db.lastErrorMsg());
+        m_db.close();
+        return;
+    }
+    if (!m_db.executeCommand(String("INSERT INTO IconDatabaseInfo VALUES ('Version', ") + String::number(currentDatabaseVersion) + ");")) {
+        LOG_ERROR("Could not insert icon database version into IconDatabaseInfo table (%i)\n%s", m_db.lastError(), m_db.lastErrorMsg());
+        m_db.close();
+        return;
+    }
+    if (!m_db.executeCommand("CREATE TABLE PageURL (url varchar NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,iconID integer NOT NULL ON CONFLICT FAIL);")) {
+        LOG_ERROR("Could not create PageURL table in icon.db (%i)\n%s", m_db.lastError(), m_db.lastErrorMsg());
+        m_db.close();
+        return;
+    }
+    if (!m_db.executeCommand("CREATE TABLE Icon (id integer PRIMARY KEY ON CONFLICT FAIL,url varchar NOT NULL UNIQUE ON CONFLICT FAIL);")) {
+        LOG_ERROR("Could not create Icon table in icon.db (%i)\n%s", m_db.lastError(), m_db.lastErrorMsg());
+        m_db.close();
+        return;
+    }
+    if (!m_db.executeCommand("CREATE TABLE IconResource (iconID integer NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,data blob NOT NULL ON CONFLICT FAIL);")) {
+        LOG_ERROR("Could not create IconResource table in icon.db (%i)\n%s", m_db.lastError(), m_db.lastErrorMsg());
+        m_db.close();
+        return;
+    }
+    
+    
+}    
+
 IconDatabase::~IconDatabase()
 {
     m_db.close();
index 7ea1627e1a6cfc13a7cb021ec708ceeb6c669470..96a9e22ea08438a5b512cbdaccd1e30189307058 100644 (file)
@@ -42,10 +42,15 @@ public:
     bool isOpen() { return m_db.isOpen(); }
     void close();
     
+    static const int currentDatabaseVersion;
 private:
     IconDatabase();
     ~IconDatabase();
     
+    bool isValidDatabase();
+    void clearDatabase();
+    void recreateDatabase();
+    
     static IconDatabase* m_sharedInstance;
     
     SQLDatabase m_db;
index 1aac0dcfaf01290d16ce950a9910e41e0f63b354..eb9cf94a7f5ee59e294c0347d8cd7480713fc96b 100644 (file)
@@ -121,46 +121,66 @@ int SQLStatement::bindText(int index, const char* text, bool copy)
 
 int SQLStatement::columnCount()
 {
-    return sqlite3_column_count(m_statement);
+    if (m_statement)
+        return sqlite3_column_count(m_statement);
+    return 0;
 }
 
 String SQLStatement::getColumnName(int col)
 {
-    return String(sqlite3_column_name(m_statement, col));
+    if (m_statement)
+        return String(sqlite3_column_name(m_statement, col));
+    return "";
 }
 
 String SQLStatement::getColumnName16(int col)
 {
-    return String((const UChar*)sqlite3_column_name16(m_statement, col));
+    if (m_statement)
+        return String((const UChar*)sqlite3_column_name16(m_statement, col));
+    return "";
 }
     
 String SQLStatement::getColumnText(int col)
 {
-    return String((const char*)sqlite3_column_text(m_statement, col));
+    if (m_statement)
+        return String((const char*)sqlite3_column_text(m_statement, col));
+    return "";
 }
 
 String SQLStatement::getColumnText16(int col)
 {
-    return String((const UChar*)sqlite3_column_text16(m_statement, col));
+    if (m_statement)
+        return String((const UChar*)sqlite3_column_text16(m_statement, col));
+    return "";
 }
     
 double SQLStatement::getColumnDouble(int col)
 {
-    return sqlite3_column_double(m_statement, col);
+    if (m_statement)
+        return sqlite3_column_double(m_statement, col);
+    return 0.0;
 }
 
 int SQLStatement::getColumnInt(int col)
 {
-    return sqlite3_column_int(m_statement, col);
+    if (m_statement)
+        return sqlite3_column_int(m_statement, col);
+    return 0;
 }
 
 int64_t SQLStatement::getColumnInt64(int col)
 {
-    return sqlite3_column_int64(m_statement, col);
+    if (m_statement)
+        return sqlite3_column_int64(m_statement, col);
+    return 0;
 }
     
 const void* SQLStatement::getColumnBlob(int col, int& size)
 {
+    if (!m_statement) {
+        size = 0;
+        return 0;
+    }
     const void* blob = sqlite3_column_blob(m_statement, col);
     if (blob) {
         size = sqlite3_column_bytes(m_statement, col);