void Statistics::initialize(const String& databasePath) { ASSERT(RunLoop::isMain()); auto startTime = std::chrono::system_clock::now(); StringCapture databasePathCapture(databasePath); StringCapture networkCachePathCapture(singleton().recordsPath()); serialBackgroundIOQueue().dispatch([this, databasePathCapture, networkCachePathCapture, startTime] { WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter; String databasePath = databasePathCapture.string(); if (!WebCore::makeAllDirectories(WebCore::directoryName(databasePath))) return; LOG(NetworkCache, "(NetworkProcess) Opening network cache statistics database at %s...", databasePath.utf8().data()); m_database.open(databasePath); m_database.disableThreadingChecks(); if (!m_database.isOpen()) { LOG_ERROR("Network cache statistics: Failed to open / create the network cache statistics database"); return; } executeSQLCommand(m_database, ASCIILiteral("CREATE TABLE IF NOT EXISTS AlreadyRequested (hash TEXT PRIMARY KEY)")); executeSQLCommand(m_database, ASCIILiteral("CREATE TABLE IF NOT EXISTS UncachedReason (hash TEXT PRIMARY KEY, reason INTEGER)")); WebCore::SQLiteStatement statement(m_database, ASCIILiteral("SELECT count(*) FROM AlreadyRequested")); if (statement.prepareAndStep() != SQLITE_ROW) { LOG_ERROR("Network cache statistics: Failed to count the number of rows in AlreadyRequested table"); return; } m_approximateEntryCount = statement.getColumnInt(0); #if !LOG_DISABLED auto elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - startTime).count(); #endif LOG(NetworkCache, "(NetworkProcess) Network cache statistics database load complete, entries=%lu time=%lldms", static_cast<size_t>(m_approximateEntryCount), elapsedMS); if (!m_approximateEntryCount) { bootstrapFromNetworkCache(networkCachePathCapture.string()); #if !LOG_DISABLED elapsedMS = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - startTime).count(); #endif LOG(NetworkCache, "(NetworkProcess) Network cache statistics database bootstrapping complete, entries=%lu time=%lldms", static_cast<size_t>(m_approximateEntryCount), elapsedMS); } }); }
void Statistics::clear() { ASSERT(RunLoop::isMain()); serialBackgroundIOQueue().dispatch([this] { if (m_database.isOpen()) { WebCore::SQLiteTransactionInProgressAutoCounter transactionCounter; WebCore::SQLiteTransaction deleteTransaction(m_database); deleteTransaction.begin(); executeSQLCommand(m_database, ASCIILiteral("DELETE FROM AlreadyRequested")); executeSQLCommand(m_database, ASCIILiteral("DELETE FROM UncachedReason")); deleteTransaction.commit(); m_approximateEntryCount = 0; } }); }
//Changes a user's password void changePassword(sqlite3 *db, char *username, char *password) { //Create SQL statement char * sql = sqlite3_mprintf( "Update Database set Password = '******' where Username = '******';" , password, username); //Execute SQL statement executeSQLCommand(db, sql); }
//Removes a user from the database void removeUser(sqlite3 *db, char *username) { //Create SQL statement char *sql = sqlite3_mprintf( "Delete from Database Where Username = '******';" , username); //Execute SQL statement executeSQLCommand(db, sql); }
//Adds a user to the database void addUser(sqlite3 *db, int isAdmin,char *username, char *password) { //Create SQL statement char *sql = sqlite3_mprintf( "Insert into Database values " "((Select max(ID) From Database)+1, %d, '%q', '%q');" , isAdmin, username, password); //Execute SQL statement executeSQLCommand(db, sql); }
void ApplicationCacheStorage::empty() { openDatabase(false); if (!m_database.isOpen()) return; // Clear cache groups, caches and cache resources. executeSQLCommand("DELETE FROM CacheGroups"); executeSQLCommand("DELETE FROM Caches"); executeSQLCommand("DELETE FROM CacheResources"); // Clear the storage IDs for the caches in memory. // The caches will still work, but cached resources will not be saved to disk // until a cache update process has been initiated. CacheGroupMap::const_iterator end = m_cachesInMemory.end(); for (CacheGroupMap::const_iterator it = m_cachesInMemory.begin(); it != end; ++it) it->second->clearStorageID(); }
void ApplicationCacheStorage::openDatabase(bool createIfDoesNotExist) { if (m_database.isOpen()) return; // The cache directory should never be null, but if it for some weird reason is we bail out. if (m_cacheDirectory.isNull()) return; String applicationCachePath = pathByAppendingComponent(m_cacheDirectory, "ApplicationCache.db"); if (!createIfDoesNotExist && !fileExists(applicationCachePath)) return; makeAllDirectories(m_cacheDirectory); m_database.open(applicationCachePath); if (!m_database.isOpen()) return; verifySchemaVersion(); // Create tables executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheGroups (id INTEGER PRIMARY KEY AUTOINCREMENT, " "manifestHostHash INTEGER NOT NULL ON CONFLICT FAIL, manifestURL TEXT UNIQUE ON CONFLICT FAIL, newestCache INTEGER)"); executeSQLCommand("CREATE TABLE IF NOT EXISTS Caches (id INTEGER PRIMARY KEY AUTOINCREMENT, cacheGroup INTEGER)"); executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheWhitelistURLs (url TEXT NOT NULL ON CONFLICT FAIL, cache INTEGER NOT NULL ON CONFLICT FAIL)"); executeSQLCommand("CREATE TABLE IF NOT EXISTS FallbackURLs (namespace TEXT NOT NULL ON CONFLICT FAIL, fallbackURL TEXT NOT NULL ON CONFLICT FAIL, " "cache INTEGER NOT NULL ON CONFLICT FAIL)"); executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheEntries (cache INTEGER NOT NULL ON CONFLICT FAIL, type INTEGER, resource INTEGER NOT NULL)"); executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResources (id INTEGER PRIMARY KEY AUTOINCREMENT, url TEXT NOT NULL ON CONFLICT FAIL, " "statusCode INTEGER NOT NULL, responseURL TEXT NOT NULL, mimeType TEXT, textEncodingName TEXT, headers TEXT, data INTEGER NOT NULL ON CONFLICT FAIL)"); executeSQLCommand("CREATE TABLE IF NOT EXISTS CacheResourceData (id INTEGER PRIMARY KEY AUTOINCREMENT, data BLOB)"); // When a cache is deleted, all its entries and its whitelist should be deleted. executeSQLCommand("CREATE TRIGGER IF NOT EXISTS CacheDeleted AFTER DELETE ON Caches" " FOR EACH ROW BEGIN" " DELETE FROM CacheEntries WHERE cache = OLD.id;" " DELETE FROM CacheWhitelistURLs WHERE cache = OLD.id;" " DELETE FROM FallbackURLs WHERE cache = OLD.id;" " END"); // When a cache resource is deleted, its data blob should also be deleted. executeSQLCommand("CREATE TRIGGER IF NOT EXISTS CacheResourceDeleted AFTER DELETE ON CacheResources" " FOR EACH ROW BEGIN" " DELETE FROM CacheResourceData WHERE id = OLD.data;" " END"); }
//Creates databases void createDatabase(char *databaseName) { sqlite3 *db; /* Open database */ int rc = sqlite3_open(databaseName, &db); openDBResponse(rc); /* Create SQL statement */ char *sql = "Create Table Database(" "ID Int PRIMARY KEY NOT NULL," "IsAdmin Int NOT NULL," "Username Text NOT NULL," "Password Char(100) NOT NULL);" "Insert into Database values (1, 1, 'admin', '123456'); "; rc = executeSQLCommand(db, sql); sqlite3_close(db); }
void ApplicationCacheStorage::verifySchemaVersion() { if (m_database.tableExists("SchemaVersion")) { int version = SQLiteStatement(m_database, "SELECT version from SchemaVersion").getColumnInt(0); if (version == SchemaVersion) return; } m_database.clearAllTables(); SQLiteTransaction createSchemaVersionTable(m_database); createSchemaVersionTable.begin(); executeSQLCommand("CREATE TABLE SchemaVersion (version INTEGER NOT NULL)"); SQLiteStatement statement(m_database, "INSERT INTO SchemaVersion (version) VALUES (?)"); if (statement.prepare() != SQLResultOk) return; statement.bindInt64(1, SchemaVersion); executeStatement(statement); createSchemaVersionTable.commit(); }
//Shows a list of users in the database void listUsers(sqlite3 *db) { executeSQLCommand(db, "Select Username From Database Order by Username;"); }