.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.favicons.cache.FaviconCacheSQLite Class Reference
+ Inheritance diagram for searx.favicons.cache.FaviconCacheSQLite:
+ Collaboration diagram for searx.favicons.cache.FaviconCacheSQLite:

Public Member Functions

 __init__ (self, FaviconCacheConfig cfg)
 
None|tuple[None|bytes, None|str] __call__ (self, str resolver, str authority)
 
bool set (self, str resolver, str authority, str|None mime, bytes|None data)
 
int next_maintenance_time (self)
 
 maintenance (self, force=False)
 
FaviconCacheStats state (self)
 
- Public Member Functions inherited from searx.sqlitedb.SQLiteAppl
sqlite3.Connection connect (self)
 
 register_functions (self, conn)
 
sqlite3.Connection DB (self)
 
 init (self)
 
 create_schema (self, conn)
 
- Public Member Functions inherited from searx.favicons.cache.FaviconCache

Public Attributes

 cfg = cfg
 
 next_maintenance_time
 
- Public Attributes inherited from searx.sqlitedb.SQLiteAppl
 db_url = db_url
 
 properties = SQLiteProperties(db_url)
 
 thread_local = threading.local()
 

Static Public Attributes

int DB_SCHEMA = 1
 
str DDL_BLOBS
 
str DDL_BLOB_MAP
 
dict DDL_CREATE_TABLES
 
tuple SQL_DROP_LEFTOVER_BLOBS
 
tuple SQL_ITER_BLOBS_SHA256_BYTES_C
 
tuple SQL_INSERT_BLOBS
 
tuple SQL_INSERT_BLOB_MAP
 
- Static Public Attributes inherited from searx.sqlitedb.SQLiteAppl
dict DDL_CREATE_TABLES = {}
 
int DB_SCHEMA = 1
 
dict SQLITE_THREADING_MODE
 
str SQLITE_JOURNAL_MODE = "WAL"
 
dict SQLITE_CONNECT_ARGS
 

Protected Member Functions

 _query_val (self, sql, default=None)
 
- Protected Member Functions inherited from searx.sqlitedb.SQLiteAppl
 _compatibility (self)
 

Additional Inherited Members

- Protected Attributes inherited from searx.sqlitedb.SQLiteAppl
bool _init_done = False
 
 _DB = None
 

Detailed Description

Favicon cache that manages the favicon BLOBs in a SQLite DB.  The DB
model in the SQLite DB is implemented using the abstract class
:py:obj:`sqlitedb.SQLiteAppl`.

The following configurations are required / supported:

- :py:obj:`FaviconCacheConfig.db_url`
- :py:obj:`FaviconCacheConfig.HOLD_TIME`
- :py:obj:`FaviconCacheConfig.LIMIT_TOTAL_BYTES`
- :py:obj:`FaviconCacheConfig.BLOB_MAX_BYTES`
- :py:obj:`MAINTENANCE_PERIOD`
- :py:obj:`MAINTENANCE_MODE`

Definition at line 234 of file cache.py.

Constructor & Destructor Documentation

◆ __init__()

searx.favicons.cache.FaviconCacheSQLite.__init__ ( self,
FaviconCacheConfig cfg )
An instance of the favicon cache is build up from the configuration.

Reimplemented from searx.sqlitedb.SQLiteAppl.

Definition at line 304 of file cache.py.

304 def __init__(self, cfg: FaviconCacheConfig):
305 """An instance of the favicon cache is build up from the configuration.""" #
306
307 if cfg.db_url == ":memory:":
308 logger.critical("don't use SQLite DB in :memory: in production!!")
309 super().__init__(cfg.db_url)
310 self.cfg = cfg
311

References searx.favicons.cache.FaviconCacheSQLite.__init__().

Referenced by searx.favicons.cache.FaviconCacheSQLite.__init__().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Function Documentation

◆ __call__()

None | tuple[None | bytes, None | str] searx.favicons.cache.FaviconCacheSQLite.__call__ ( self,
str resolver,
str authority )
Returns ``None`` or the tuple of ``(data, mime)`` that has been
registered in the cache.  The ``None`` indicates that there was no entry
in the cache.

Reimplemented from searx.favicons.cache.FaviconCache.

Definition at line 312 of file cache.py.

312 def __call__(self, resolver: str, authority: str) -> None | tuple[None | bytes, None | str]:
313
314 sql = "SELECT sha256 FROM blob_map WHERE resolver = ? AND authority = ?"
315 res = self.DB.execute(sql, (resolver, authority)).fetchone()
316 if res is None:
317 return None
318
319 data, mime = (None, None)
320 sha256 = res[0]
321 if sha256 == FALLBACK_ICON:
322 return data, mime
323
324 sql = "SELECT data, mime FROM blobs WHERE sha256 = ?"
325 res = self.DB.execute(sql, (sha256,)).fetchone()
326 if res is not None:
327 data, mime = res
328 return data, mime
329

References searx.sqlitedb.SQLiteAppl.DB().

+ Here is the call graph for this function:

◆ _query_val()

searx.favicons.cache.FaviconCacheSQLite._query_val ( self,
sql,
default = None )
protected

Definition at line 410 of file cache.py.

410 def _query_val(self, sql, default=None):
411 val = self.DB.execute(sql).fetchone()
412 if val is not None:
413 val = val[0]
414 if val is None:
415 val = default
416 return val
417

References searx.sqlitedb.SQLiteAppl.DB().

Referenced by searx.favicons.cache.FaviconCacheSQLite.state().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ maintenance()

searx.favicons.cache.FaviconCacheSQLite.maintenance ( self,
force = False )
Performs maintenance on the cache

Reimplemented from searx.favicons.cache.FaviconCache.

Definition at line 369 of file cache.py.

369 def maintenance(self, force=False):
370
371 # Prevent parallel DB maintenance cycles from other DB connections
372 # (e.g. in multi thread or process environments).
373
374 if not force and int(time.time()) < self.next_maintenance_time:
375 logger.debug("no maintenance required yet, next maintenance interval is in the future")
376 return
377 self.properties.set("LAST_MAINTENANCE", "") # hint: this (also) sets the m_time of the property!
378
379 # do maintenance tasks
380
381 with self.connect() as conn:
382
383 # drop items not in HOLD time
384 res = conn.execute(
385 f"DELETE FROM blob_map"
386 f" WHERE cast(m_time as integer) < cast(strftime('%s', 'now') as integer) - {self.cfg.HOLD_TIME}"
387 )
388 logger.debug("dropped %s obsolete blob_map items from db", res.rowcount)
389 res = conn.execute(self.SQL_DROP_LEFTOVER_BLOBS)
390 logger.debug("dropped %s obsolete BLOBS from db", res.rowcount)
391
392 # drop old items to be in LIMIT_TOTAL_BYTES
393 total_bytes = conn.execute("SELECT SUM(bytes_c) FROM blobs").fetchone()[0] or 0
394 if total_bytes > self.cfg.LIMIT_TOTAL_BYTES:
395
396 x = total_bytes - self.cfg.LIMIT_TOTAL_BYTES
397 c = 0
398 sha_list = []
399 for row in conn.execute(self.SQL_ITER_BLOBS_SHA256_BYTES_C):
400 sha256, bytes_c = row
401 sha_list.append(sha256)
402 c += bytes_c
403 if c > x:
404 break
405 if sha_list:
406 conn.execute("DELETE FROM blobs WHERE sha256 IN ('%s')" % "','".join(sha_list))
407 conn.execute("DELETE FROM blob_map WHERE sha256 IN ('%s')" % "','".join(sha_list))
408 logger.debug("dropped %s blobs with total size of %s bytes", len(sha_list), c)
409

Referenced by searx.favicons.cache.FaviconCacheSQLite.set().

+ Here is the caller graph for this function:

◆ next_maintenance_time()

int searx.favicons.cache.FaviconCacheSQLite.next_maintenance_time ( self)
Returns (unix epoch) time of the next maintenance.

Definition at line 364 of file cache.py.

364 def next_maintenance_time(self) -> int:
365 """Returns (unix epoch) time of the next maintenance."""
366
367 return self.cfg.MAINTENANCE_PERIOD + self.properties.m_time("LAST_MAINTENANCE")
368

References searx.botdetection.config.Config.cfg, searx.favicons.cache.FaviconCacheMEM.cfg, searx.favicons.cache.FaviconCacheSQLite.cfg, and searx.sqlitedb.SQLiteAppl.properties.

Referenced by searx.favicons.cache.FaviconCacheSQLite.set().

+ Here is the caller graph for this function:

◆ set()

bool searx.favicons.cache.FaviconCacheSQLite.set ( self,
str resolver,
str authority,
str | None mime,
bytes | None data )
Set data and mime-type in the cache.  If data is None, the
:py:obj:`FALLBACK_ICON` is registered. in the cache.

Reimplemented from searx.favicons.cache.FaviconCache.

Definition at line 330 of file cache.py.

330 def set(self, resolver: str, authority: str, mime: str | None, data: bytes | None) -> bool:
331
332 if self.cfg.MAINTENANCE_MODE == "auto" and int(time.time()) > self.next_maintenance_time:
333 # Should automatic maintenance be moved to a new thread?
334 self.maintenance()
335
336 if data is not None and mime is None:
337 logger.error(
338 "favicon resolver %s tries to cache mime-type None for authority %s",
339 resolver,
340 authority,
341 )
342 return False
343
344 bytes_c = len(data or b"")
345 if bytes_c > self.cfg.BLOB_MAX_BYTES:
346 logger.info(
347 "favicon of resolver: %s / authority: %s to big to cache (bytes: %s) " % (resolver, authority, bytes_c)
348 )
349 return False
350
351 if data is None:
352 sha256 = FALLBACK_ICON
353 else:
354 sha256 = hashlib.sha256(data).hexdigest()
355
356 with self.connect() as conn:
357 if sha256 != FALLBACK_ICON:
358 conn.execute(self.SQL_INSERT_BLOBS, (sha256, bytes_c, mime, data))
359 conn.execute(self.SQL_INSERT_BLOB_MAP, (sha256, resolver, authority))
360
361 return True
362

References searx.botdetection.config.Config.cfg, searx.favicons.cache.FaviconCacheMEM.cfg, searx.favicons.cache.FaviconCacheSQLite.cfg, searx.sqlitedb.SQLiteAppl.connect(), searx.favicons.cache.FaviconCache.maintenance(), searx.favicons.cache.FaviconCacheMEM.maintenance(), searx.favicons.cache.FaviconCacheNull.maintenance(), searx.favicons.cache.FaviconCacheSQLite.maintenance(), searx.favicons.cache.FaviconCacheSQLite.next_maintenance_time(), searx.favicons.cache.FaviconCacheSQLite.next_maintenance_time, searx.favicons.cache.FaviconCacheSQLite.SQL_INSERT_BLOB_MAP, and searx.favicons.cache.FaviconCacheSQLite.SQL_INSERT_BLOBS.

+ Here is the call graph for this function:

◆ state()

FaviconCacheStats searx.favicons.cache.FaviconCacheSQLite.state ( self)
Returns a :py:obj:`FaviconCacheStats` (key/values) with information
on the state of the cache.

Reimplemented from searx.favicons.cache.FaviconCache.

Definition at line 418 of file cache.py.

418 def state(self) -> FaviconCacheStats:
419 return FaviconCacheStats(
420 favicons=self._query_val("SELECT count(*) FROM blobs", 0),
421 bytes=self._query_val("SELECT SUM(bytes_c) FROM blobs", 0),
422 domains=self._query_val("SELECT count(*) FROM (SELECT authority FROM blob_map GROUP BY authority)", 0),
423 resolvers=self._query_val("SELECT count(*) FROM (SELECT resolver FROM blob_map GROUP BY resolver)", 0),
424 )
425
426

References searx.favicons.cache.FaviconCacheSQLite._query_val().

+ Here is the call graph for this function:

Member Data Documentation

◆ cfg

◆ DB_SCHEMA

int searx.favicons.cache.FaviconCacheSQLite.DB_SCHEMA = 1
static

◆ DDL_BLOB_MAP

str searx.favicons.cache.FaviconCacheSQLite.DDL_BLOB_MAP
static
Initial value:
= """\
CREATE TABLE IF NOT EXISTS blob_map (
m_time INTEGER DEFAULT (strftime('%s', 'now')), -- last modified (unix epoch) time in sec.
sha256 TEXT,
resolver TEXT,
authority TEXT,
PRIMARY KEY (resolver, authority))"""

Definition at line 261 of file cache.py.

◆ DDL_BLOBS

str searx.favicons.cache.FaviconCacheSQLite.DDL_BLOBS
static
Initial value:
= """\
CREATE TABLE IF NOT EXISTS blobs (
sha256 TEXT,
bytes_c INTEGER,
mime TEXT NOT NULL,
data BLOB NOT NULL,
PRIMARY KEY (sha256))"""

Definition at line 251 of file cache.py.

◆ DDL_CREATE_TABLES

dict searx.favicons.cache.FaviconCacheSQLite.DDL_CREATE_TABLES
static
Initial value:
= {
"blobs": DDL_BLOBS,
"blob_map": DDL_BLOB_MAP,
}

Definition at line 271 of file cache.py.

Referenced by searx.sqlitedb.SQLiteAppl.create_schema().

◆ next_maintenance_time

searx.favicons.cache.FaviconCacheSQLite.next_maintenance_time

Definition at line 374 of file cache.py.

Referenced by searx.favicons.cache.FaviconCacheSQLite.set().

◆ SQL_DROP_LEFTOVER_BLOBS

tuple searx.favicons.cache.FaviconCacheSQLite.SQL_DROP_LEFTOVER_BLOBS
static
Initial value:
= (
"DELETE FROM blobs WHERE sha256 IN ("
" SELECT b.sha256"
" FROM blobs b"
" LEFT JOIN blob_map bm"
" ON b.sha256 = bm.sha256"
" WHERE bm.sha256 IS NULL)"
)

Definition at line 276 of file cache.py.

◆ SQL_INSERT_BLOB_MAP

searx.favicons.cache.FaviconCacheSQLite.SQL_INSERT_BLOB_MAP
static
Initial value:
= (
"INSERT INTO blob_map (sha256, resolver, authority) VALUES (?, ?, ?)"
" ON CONFLICT DO UPDATE "
" SET sha256=excluded.sha256, m_time=strftime('%s', 'now')"
)

Definition at line 298 of file cache.py.

Referenced by searx.favicons.cache.FaviconCacheSQLite.set().

◆ SQL_INSERT_BLOBS

searx.favicons.cache.FaviconCacheSQLite.SQL_INSERT_BLOBS
static
Initial value:
= (
"INSERT INTO blobs (sha256, bytes_c, mime, data) VALUES (?, ?, ?, ?)"
" ON CONFLICT (sha256) DO NOTHING"
)

Definition at line 293 of file cache.py.

Referenced by searx.favicons.cache.FaviconCacheSQLite.set().

◆ SQL_ITER_BLOBS_SHA256_BYTES_C

searx.favicons.cache.FaviconCacheSQLite.SQL_ITER_BLOBS_SHA256_BYTES_C
static
Initial value:
= (
"SELECT b.sha256, b.bytes_c FROM blobs b"
" JOIN blob_map bm "
" ON b.sha256 = bm.sha256"
" ORDER BY bm.m_time ASC"
)

Definition at line 286 of file cache.py.


The documentation for this class was generated from the following file: