idTZdZddlmZddlmZddlmZddlmZ Gdd eZ e Z d S) a .. dialect:: sqlite+pysqlcipher :name: pysqlcipher :dbapi: pysqlcipher :connectstring: sqlite+pysqlcipher://:passphrase/file_path[?kdf_iter=] :url: https://pypi.python.org/pypi/pysqlcipher ``pysqlcipher`` is a fork of the standard ``pysqlite`` driver to make use of the `SQLCipher `_ backend. ``pysqlcipher3`` is a fork of ``pysqlcipher`` for Python 3. This dialect will attempt to import it if ``pysqlcipher`` is non-present. .. versionadded:: 1.1.4 - added fallback import for pysqlcipher3 .. versionadded:: 0.9.9 - added pysqlcipher dialect Driver ------ The driver here is the `pysqlcipher `_ driver, which makes use of the SQLCipher engine. This system essentially introduces new PRAGMA commands to SQLite which allows the setting of a passphrase and other encryption parameters, allowing the database file to be encrypted. `pysqlcipher3` is a fork of `pysqlcipher` with support for Python 3, the driver is the same. Connect Strings --------------- The format of the connect string is in every way the same as that of the :mod:`~sqlalchemy.dialects.sqlite.pysqlite` driver, except that the "password" field is now accepted, which should contain a passphrase:: e = create_engine('sqlite+pysqlcipher://:testing@/foo.db') For an absolute file path, two leading slashes should be used for the database name:: e = create_engine('sqlite+pysqlcipher://:testing@//path/to/foo.db') A selection of additional encryption-related pragmas supported by SQLCipher as documented at https://www.zetetic.net/sqlcipher/sqlcipher-api/ can be passed in the query string, and will result in that PRAGMA being called for each new connection. Currently, ``cipher``, ``kdf_iter`` ``cipher_page_size`` and ``cipher_use_hmac`` are supported:: e = create_engine('sqlite+pysqlcipher://:testing@/foo.db?cipher=aes-256-cfb&kdf_iter=64000') Pooling Behavior ---------------- The driver makes a change to the default pool behavior of pysqlite as described in :ref:`pysqlite_threading_pooling`. The pysqlcipher driver has been observed to be significantly slower on connection than the pysqlite driver, most likely due to the encryption overhead, so the dialect here defaults to using the :class:`.SingletonThreadPool` implementation, instead of the :class:`.NullPool` pool used by pysqlite. As always, the pool implementation is entirely configurable using the :paramref:`_sa.create_engine.poolclass` parameter; the :class:`.StaticPool` may be more feasible for single-threaded use, or :class:`.NullPool` may be used to prevent unencrypted connections from being held open for long periods of time, at the expense of slower startup time for new connections. )absolute_import)SQLiteDialect_pysqlite)pool)urlc\eZdZdZdZedZedZfdZfdZ xZ S)SQLiteDialect_pysqlcipher pysqlcipher)kdf_iterciphercipher_page_sizecipher_use_hmacct ddlm}n/#t$r"} ddlm}n#t$r|wxYwYd}~nd}~wwxYw|S)Nr)dbapi2)r r ImportError pysqlcipher3)cls sqlcipheres [/opt/cloudlinux/venv/lib/python3.11/site-packages/sqlalchemy/dialects/sqlite/pysqlcipher.pydbapizSQLiteDialect_pysqlcipher.dbapi]s  7 7 7 7 7 7 7    <<<<<<<    =<<<<  s 50 (05ctjSN)rSingletonThreadPool)rrs rget_pool_classz(SQLiteDialect_pysqlcipher.get_pool_classhs ''cVdd}tfd|jD}tt|j|i}|d|z|D]#\}}||d|d|d$|S)N passphrasec3HK|]}||dfVdSr)pop).0keycparamss r z4SQLiteDialect_pysqlcipher.connect..os6MMW[[d334MMMMMMrzpragma key="%s"zpragma z="")r"dictpragmassuperr connectexecuteitems) selfcargsr%rr)connpragvalue __class__s ` rr+z!SQLiteDialect_pysqlcipher.connectls[[r22 MMMM MMMMM=u.55=     &3444"==?? ? ?KD%  uuu=>>> rctj|j|j|j|j|j}tt| |\}}|j |d<||fS)N)usernamehostdatabasequeryr) _urlURL drivernamer5r6r7r8r*r create_connect_argspassword)r.r super_urlc_argsoptsr3s rr<z-SQLiteDialect_pysqlcipher.create_connect_args{suH N\\)     %t   i ( ( !\\t|r) __name__ __module__ __qualname__driverr) classmethodrrr+r< __classcell__)r3s@rr r Xs FKG[(([(              rr N) __doc__ __future__rpysqliterr renginerr9r dialectrrrMsGGR'&&&&&,,,,,,!!!!!!///// 6///d $r