void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota) { LockHolder lockDatabase(m_databaseGuard); if (quotaForOriginNoLock(origin) == quota) return; openTrackerDatabase(CreateIfDoesNotExist); if (!m_database.isOpen()) return; #if PLATFORM(IOS) bool insertedNewOrigin = false; #endif bool originEntryExists = hasEntryForOriginNoLock(origin); if (!originEntryExists) { SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)"); if (statement.prepare() != SQLITE_OK) { LOG_ERROR("Unable to establish origin %s in the tracker", origin->databaseIdentifier().ascii().data()); } else { statement.bindText(1, origin->databaseIdentifier()); statement.bindInt64(2, quota); if (statement.step() != SQLITE_DONE) LOG_ERROR("Unable to establish origin %s in the tracker", origin->databaseIdentifier().ascii().data()); #if PLATFORM(IOS) else insertedNewOrigin = true; #endif } } else { SQLiteStatement statement(m_database, "UPDATE Origins SET quota=? WHERE origin=?"); bool error = statement.prepare() != SQLITE_OK; if (!error) { statement.bindInt64(1, quota); statement.bindText(2, origin->databaseIdentifier()); error = !statement.executeCommand(); } if (error) LOG_ERROR("Failed to set quota %llu in tracker database for origin %s", quota, origin->databaseIdentifier().ascii().data()); } if (m_client) { #if PLATFORM(IOS) if (insertedNewOrigin) m_client->dispatchDidAddNewOrigin(origin); #endif m_client->dispatchDidModifyOrigin(origin); } }
bool DatabaseTracker::hasAdequateQuotaForOrigin(SecurityOrigin* origin, unsigned long estimatedSize, DatabaseError& err) { ASSERT(!m_databaseGuard.tryLock()); unsigned long long usage = usageForOrigin(origin); // If the database will fit, allow its creation. unsigned long long requirement = usage + std::max<unsigned long long>(1, estimatedSize); if (requirement < usage) { // The estimated size is so big it causes an overflow; don't allow creation. err = DatabaseError::DatabaseSizeOverflowed; return false; } if (requirement <= quotaForOriginNoLock(origin)) return true; err = DatabaseError::DatabaseSizeExceededQuota; return false; }
void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota) { MutexLocker lockDatabase(m_databaseGuard); if (quotaForOriginNoLock(origin) == quota) return; openTrackerDatabase(CreateIfDoesNotExist); if (!m_database.isOpen()) return; bool originEntryExists = hasEntryForOriginNoLock(origin); if (!originEntryExists) { SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)"); if (statement.prepare() != SQLResultOk) { LOG_ERROR("Unable to establish origin %s in the tracker", origin->databaseIdentifier().ascii().data()); } else { statement.bindText(1, origin->databaseIdentifier()); statement.bindInt64(2, quota); if (statement.step() != SQLResultDone) LOG_ERROR("Unable to establish origin %s in the tracker", origin->databaseIdentifier().ascii().data()); } } else { SQLiteStatement statement(m_database, "UPDATE Origins SET quota=? WHERE origin=?"); bool error = statement.prepare() != SQLResultOk; if (!error) { statement.bindInt64(1, quota); statement.bindText(2, origin->databaseIdentifier()); error = !statement.executeCommand(); } if (error) #if OS(WINDOWS) LOG_ERROR("Failed to set quota %I64u in tracker database for origin %s", quota, origin->databaseIdentifier().ascii().data()); #else LOG_ERROR("Failed to set quota %llu in tracker database for origin %s", quota, origin->databaseIdentifier().ascii().data()); #endif } if (m_client) m_client->dispatchDidModifyOrigin(origin); }
unsigned long long DatabaseTracker::getMaxSizeForDatabase(const DatabaseBackendBase* database) { // The maximum size for a database is the full quota for its origin, minus the current usage within the origin, // plus the current usage of the given database MutexLocker lockDatabase(m_databaseGuard); SecurityOrigin* origin = database->securityOrigin(); unsigned long long quota = quotaForOriginNoLock(origin); unsigned long long diskUsage = usageForOrigin(origin); unsigned long long databaseFileSize = SQLiteFileSystem::getDatabaseFileSize(database->fileName()); ASSERT(databaseFileSize <= diskUsage); if (diskUsage > quota) return databaseFileSize; // A previous error may have allowed the origin to exceed its quota, or may // have allowed this database to exceed our cached estimate of the origin // disk usage. Don't multiply that error through integer underflow, or the // effective quota will permanently become 2^64. unsigned long long maxSize = quota - diskUsage + databaseFileSize; if (maxSize > quota) maxSize = databaseFileSize; return maxSize; }
unsigned long long DatabaseTracker::quotaForOrigin(SecurityOrigin* origin) { MutexLocker lockDatabase(m_databaseGuard); return quotaForOriginNoLock(origin); }