.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
searx.sqlitedb.SQLiteAppl Class Reference
+ Inheritance diagram for searx.sqlitedb.SQLiteAppl:
+ Collaboration diagram for searx.sqlitedb.SQLiteAppl:

Public Member Functions

 __init__ (self, db_url)
 
sqlite3.Connection connect (self)
 
 register_functions (self, conn)
 
sqlite3.Connection DB (self)
 
bool init (self, sqlite3.Connection conn)
 
 create_schema (self, sqlite3.Connection conn)
 

Public Attributes

 db_url = db_url
 
 properties = SQLiteProperties(db_url)
 

Static Public Attributes

dict DDL_CREATE_TABLES = {}
 
int DB_SCHEMA = 1
 
dict SQLITE_THREADING_MODE
 
str SQLITE_JOURNAL_MODE = "WAL"
 
dict SQLITE_CONNECT_ARGS
 

Protected Member Functions

 _compatibility (self)
 
sqlite3.Connection _connect (self)
 

Protected Attributes

bool _init_done = False
 
 _DB = None
 

Detailed Description

Abstract base class for implementing convenient DB access in SQLite
applications.  In the constructor, a :py:obj:`SQLiteProperties` instance is
already aggregated under ``self.properties``.

Definition at line 89 of file sqlitedb.py.

Constructor & Destructor Documentation

◆ __init__()

searx.sqlitedb.SQLiteAppl.__init__ ( self,
db_url )

Definition at line 152 of file sqlitedb.py.

152 def __init__(self, db_url):
153
154 self.db_url = db_url
155 self.properties = SQLiteProperties(db_url)
156 self._init_done = False
157 self._compatibility()
158 # atexit.register(self.tear_down)
159

Member Function Documentation

◆ _compatibility()

searx.sqlitedb.SQLiteAppl._compatibility ( self)
protected

Definition at line 168 of file sqlitedb.py.

168 def _compatibility(self):
169
170 if self.SQLITE_THREADING_MODE == "serialized":
171 self._DB = None
172 else:
173 msg = (
174 f"SQLite library is compiled with {self.SQLITE_THREADING_MODE} mode,"
175 " read https://docs.python.org/3/library/sqlite3.html#sqlite3.threadsafety"
176 )
177 if threading.active_count() > 1:
178 logger.error(msg)
179 else:
180 logger.warning(msg)
181
182 if sqlite3.sqlite_version_info <= (3, 35):
183 # See "Generalize UPSERT:" in https://sqlite.org/releaselog/3_35_0.html
184 logger.critical(
185 "SQLite runtime library version %s is not supported (require >= 3.35)", sqlite3.sqlite_version
186 )
187

References SQLITE_THREADING_MODE.

◆ _connect()

sqlite3.Connection searx.sqlitedb.SQLiteAppl._connect ( self)
protected

Definition at line 188 of file sqlitedb.py.

188 def _connect(self) -> sqlite3.Connection:
189 conn = sqlite3.Connection(self.db_url, **self.SQLITE_CONNECT_ARGS) # type: ignore
190 conn.execute(f"PRAGMA journal_mode={self.SQLITE_JOURNAL_MODE}")
191 self.register_functions(conn)
192 return conn
193

References searx.cache.ExpireCacheCfg.db_url, searx.favicons.cache.FaviconCacheConfig.db_url, db_url, register_functions(), and SQLITE_CONNECT_ARGS.

Referenced by connect().

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

◆ connect()

sqlite3.Connection searx.sqlitedb.SQLiteAppl.connect ( self)
Creates a new DB connection (:py:obj:`SQLITE_CONNECT_ARGS`).  If not
already done, the DB schema is set up.  The caller must take care of
closing the resource.  Alternatively, :py:obj:`SQLiteAppl.DB` can also
be used (the resource behind `self.DB` is automatically closed when the
process or thread is terminated).

Definition at line 194 of file sqlitedb.py.

194 def connect(self) -> sqlite3.Connection:
195 """Creates a new DB connection (:py:obj:`SQLITE_CONNECT_ARGS`). If not
196 already done, the DB schema is set up. The caller must take care of
197 closing the resource. Alternatively, :py:obj:`SQLiteAppl.DB` can also
198 be used (the resource behind `self.DB` is automatically closed when the
199 process or thread is terminated).
200 """
201 if sys.version_info < (3, 12):
202 # Prior Python 3.12 there is no "autocommit" option
203 self.SQLITE_CONNECT_ARGS.pop("autocommit", None)
204
205 msg = (
206 f"[{threading.current_thread().ident}] {self.__class__.__name__}({self.db_url})"
207 f" {self.SQLITE_CONNECT_ARGS} // {self.SQLITE_JOURNAL_MODE}"
208 )
209 logger.debug(msg)
210
211 with self._connect() as conn:
212 self.init(conn)
213 return conn
214

References _connect(), searx.cache.ExpireCacheSQLite.init(), searx.data.currencies.CurrenciesDB.init(), searx.plugins._core.Plugin.init(), searx.plugins._core.PluginStorage.init(), searx.plugins.ahmia_filter.SXNGPlugin.init(), searx.plugins.hostnames.SXNGPlugin.init(), init(), and SQLITE_CONNECT_ARGS.

Referenced by searx.cache.ExpireCacheSQLite.create_table(), searx.favicons.cache.FaviconCacheSQLite.set(), and searx.cache.ExpireCacheSQLite.truncate_tables().

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

◆ create_schema()

searx.sqlitedb.SQLiteAppl.create_schema ( self,
sqlite3.Connection conn )

Reimplemented in searx.sqlitedb.SQLiteProperties.

Definition at line 306 of file sqlitedb.py.

306 def create_schema(self, conn: sqlite3.Connection):
307
308 logger.debug("create schema ..")
309 self.properties.set("DB_SCHEMA", self.DB_SCHEMA)
310 self.properties.set("LAST_MAINTENANCE", "")
311 with conn:
312 for table_name, sql in self.DDL_CREATE_TABLES.items():
313 conn.execute(sql)
314 self.properties.set(f"Table {table_name} created", table_name)
315
316

References searx.cache.ExpireCacheSQLite.DB_SCHEMA, searx.favicons.cache.FaviconCacheSQLite.DB_SCHEMA, DB_SCHEMA, searx.cache.ExpireCacheSQLite.DDL_CREATE_TABLES, searx.favicons.cache.FaviconCacheSQLite.DDL_CREATE_TABLES, DDL_CREATE_TABLES, and properties.

Referenced by init(), and searx.sqlitedb.SQLiteProperties.init().

+ Here is the caller graph for this function:

◆ DB()

sqlite3.Connection searx.sqlitedb.SQLiteAppl.DB ( self)
Provides a DB connection.  The connection is a *singleton* and
therefore well suited for read access.  If
:py:obj:`SQLITE_THREADING_MODE` is ``serialized`` only one DB connection
is created for all threads.

.. note::

   For dedicated `transaction control`_, it is recommended to create a
   new connection (:py:obj:`SQLiteAppl.connect`).

.. _transaction control:
    https://docs.python.org/3/library/sqlite3.html#sqlite3-controlling-transactions

Definition at line 240 of file sqlitedb.py.

240 def DB(self) -> sqlite3.Connection:
241 """Provides a DB connection. The connection is a *singleton* and
242 therefore well suited for read access. If
243 :py:obj:`SQLITE_THREADING_MODE` is ``serialized`` only one DB connection
244 is created for all threads.
245
246 .. note::
247
248 For dedicated `transaction control`_, it is recommended to create a
249 new connection (:py:obj:`SQLiteAppl.connect`).
250
251 .. _transaction control:
252 https://docs.python.org/3/library/sqlite3.html#sqlite3-controlling-transactions
253 """
254
255 conn = None
256
257 if self.SQLITE_THREADING_MODE == "serialized":
258 # Theoretically it is possible to reuse the DB cursor across threads
259 # as of Python 3.12, in practice the threading of the cursor seems
260 # to me a little faulty that I prefer to establish one connection
261 # per thread.
262 #
263 # may we can activate this code one day ..
264 # if self._DB is None:
265 # self._DB = self.connect()
266 # conn = self._DB
267 conn = DBSession.get_connect(self)
268 else:
269 conn = DBSession.get_connect(self)
270
271 # Since more than one instance of SQLiteAppl share the same DB
272 # connection, we need to make sure that each SQLiteAppl instance has run
273 # its init method at least once.
274 self.init(conn)
275
276 return conn
277

References searx.cache.ExpireCacheSQLite.init(), searx.data.currencies.CurrenciesDB.init(), searx.plugins._core.Plugin.init(), searx.plugins._core.PluginStorage.init(), searx.plugins.ahmia_filter.SXNGPlugin.init(), searx.plugins.hostnames.SXNGPlugin.init(), init(), and SQLITE_THREADING_MODE.

Referenced by searx.favicons.cache.FaviconCacheSQLite.__call__(), and searx.favicons.cache.FaviconCacheSQLite._query_val().

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

◆ init()

bool searx.sqlitedb.SQLiteAppl.init ( self,
sqlite3.Connection conn )
Initializes the DB schema and properties, is only executed once even
if called several times.

If the initialization has not yet taken place, it is carried out and a
`True` is returned to the caller at the end.  If the initialization has
already been carried out in the past, `False` is returned.

Reimplemented in searx.cache.ExpireCacheSQLite, and searx.sqlitedb.SQLiteProperties.

Definition at line 278 of file sqlitedb.py.

278 def init(self, conn: sqlite3.Connection) -> bool:
279 """Initializes the DB schema and properties, is only executed once even
280 if called several times.
281
282 If the initialization has not yet taken place, it is carried out and a
283 `True` is returned to the caller at the end. If the initialization has
284 already been carried out in the past, `False` is returned.
285 """
286
287 if self._init_done:
288 return False
289 self._init_done = True
290
291 logger.debug("init DB: %s", self.db_url)
292 self.properties.init(conn)
293
294 ver = self.properties("DB_SCHEMA")
295 if ver is None:
296 with conn:
297 self.create_schema(conn)
298 else:
299 ver = int(ver)
300 if ver != self.DB_SCHEMA:
301 raise sqlite3.DatabaseError("Expected DB schema v%s, DB schema is v%s" % (self.DB_SCHEMA, ver))
302 logger.debug("DB_SCHEMA = %s", ver)
303
304 return True
305

References _init_done, create_schema(), searx.cache.ExpireCacheSQLite.DB_SCHEMA, searx.favicons.cache.FaviconCacheSQLite.DB_SCHEMA, DB_SCHEMA, searx.cache.ExpireCacheCfg.db_url, searx.favicons.cache.FaviconCacheConfig.db_url, db_url, init(), and properties.

Referenced by connect(), DB(), and init().

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

◆ register_functions()

searx.sqlitedb.SQLiteAppl.register_functions ( self,
conn )
Create user-defined_ SQL functions.

``REGEXP(<pattern>, <field>)`` : 0 | 1
   `re.search`_ returns (int) 1 for a match and 0 for none match of
   ``<pattern>`` in ``<field>``.

   .. code:: sql

      SELECT '12' AS field WHERE REGEXP('^[0-9][0-9]$', field)
      -- 12

      SELECT REGEXP('[0-9][0-9]', 'X12Y')
      -- 1
      SELECT REGEXP('[0-9][0-9]', 'X1Y')
      -- 0

.. _user-defined: https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function
.. _deterministic: https://sqlite.org/deterministic.html
.. _re.search: https://docs.python.org/3/library/re.html#re.search

Definition at line 215 of file sqlitedb.py.

215 def register_functions(self, conn):
216 """Create user-defined_ SQL functions.
217
218 ``REGEXP(<pattern>, <field>)`` : 0 | 1
219 `re.search`_ returns (int) 1 for a match and 0 for none match of
220 ``<pattern>`` in ``<field>``.
221
222 .. code:: sql
223
224 SELECT '12' AS field WHERE REGEXP('^[0-9][0-9]$', field)
225 -- 12
226
227 SELECT REGEXP('[0-9][0-9]', 'X12Y')
228 -- 1
229 SELECT REGEXP('[0-9][0-9]', 'X1Y')
230 -- 0
231
232 .. _user-defined: https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function
233 .. _deterministic: https://sqlite.org/deterministic.html
234 .. _re.search: https://docs.python.org/3/library/re.html#re.search
235 """
236
237 conn.create_function("regexp", 2, lambda x, y: 1 if re.search(x, y) else 0, deterministic=True)
238

Referenced by _connect().

+ Here is the caller graph for this function:

Member Data Documentation

◆ _DB

searx.sqlitedb.SQLiteAppl._DB = None
protected

Definition at line 171 of file sqlitedb.py.

◆ _init_done

bool searx.sqlitedb.SQLiteAppl._init_done = False
protected

Definition at line 156 of file sqlitedb.py.

Referenced by init(), and searx.sqlitedb.SQLiteProperties.init().

◆ DB_SCHEMA

searx.sqlitedb.SQLiteAppl.DB_SCHEMA = 1
static

Definition at line 96 of file sqlitedb.py.

Referenced by create_schema(), and init().

◆ db_url

searx.sqlitedb.SQLiteAppl.db_url = db_url

Definition at line 154 of file sqlitedb.py.

Referenced by _connect(), init(), and searx.sqlitedb.SQLiteProperties.init().

◆ DDL_CREATE_TABLES

dict searx.sqlitedb.SQLiteAppl.DDL_CREATE_TABLES = {}
static

Definition at line 94 of file sqlitedb.py.

Referenced by create_schema().

◆ properties

◆ SQLITE_CONNECT_ARGS

dict searx.sqlitedb.SQLiteAppl.SQLITE_CONNECT_ARGS
static
Initial value:
= {
# "timeout": 5.0,
# "detect_types": 0,
"check_same_thread": bool(SQLITE_THREADING_MODE != "serialized"),
"cached_statements": 0, # https://github.com/python/cpython/issues/118172
# "uri": False,
"isolation_level": None,
}

Definition at line 122 of file sqlitedb.py.

Referenced by _connect(), and connect().

◆ SQLITE_JOURNAL_MODE

str searx.sqlitedb.SQLiteAppl.SQLITE_JOURNAL_MODE = "WAL"
static

Definition at line 116 of file sqlitedb.py.

◆ SQLITE_THREADING_MODE

dict searx.sqlitedb.SQLiteAppl.SQLITE_THREADING_MODE
static
Initial value:
= {
0: "single-thread",
1: "multi-thread",
3: "serialized"}[sqlite3.threadsafety]

Definition at line 101 of file sqlitedb.py.

Referenced by _compatibility(), and DB().


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