tina4-python 3.12.0__tar.gz → 3.12.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tina4_python-3.12.0 → tina4_python-3.12.1}/PKG-INFO +2 -2
- {tina4_python-3.12.0 → tina4_python-3.12.1}/pyproject.toml +2 -5
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/__init__.py +1 -1
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/firebird.py +90 -16
- {tina4_python-3.12.0 → tina4_python-3.12.1}/.gitignore +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/README.md +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/CLAUDE.md +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/HtmlElement.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/Testing.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/ai/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/api/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/auth/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/cache/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/cli/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/container/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/cache.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/constants.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/events.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/middleware.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/rate_limiter.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/request.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/response.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/router.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/core/server.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/crud/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/adapter.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/connection.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/mongodb.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/mssql.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/mysql.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/odbc.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/postgres.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/database/sqlite.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/debug/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/debug/error_overlay.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/dev_admin/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/dev_admin/metrics.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/dev_admin/plan.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/dev_admin/project_index.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/docs.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/dotenv/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/frond/FROND.md +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/frond/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/frond/engine.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/auth/meta.json +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/database/meta.json +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/error-overlay/meta.json +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/orm/meta.json +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/queue/meta.json +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/rest-api/meta.json +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/templates/meta.json +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/graphql/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/i18n/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/mcp/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/mcp/protocol.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/mcp/tools.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/messenger/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/migration/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/migration/runner.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/orm/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/orm/fields.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/orm/model.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/css/tina4.css +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/css/tina4.min.css +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/favicon.ico +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/images/logo.svg +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/js/frond.js +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/js/frond.min.js +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/js/tina4-dev-admin.js +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/js/tina4.min.js +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/js/tina4js.min.js +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/swagger/index.html +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/query_builder/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue/job.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue/kafka_backend.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue/lite_backend.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue/mongo_backend.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue/rabbitmq_backend.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue_backends/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue_backends/kafka_backend.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue_backends/mongo_backend.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_alerts.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_badges.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_buttons.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_cards.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_forms.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_grid.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_modals.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_nav.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_reset.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_tables.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_typography.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_utilities.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/_variables.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/base.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/colors.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/scss/tina4css/tina4.scss +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/seeder/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/service/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/session/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/session_handlers/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/session_handlers/mongodb_handler.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/session_handlers/redis_handler.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/session_handlers/valkey_handler.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/swagger/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/components/crud.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/docker/python/Dockerfile +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/docker/uv/Dockerfile +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/errors/302.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/errors/401.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/errors/403.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/errors/404.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/errors/500.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/errors/502.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/errors/503.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/errors/base.twig +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/frontend/README.md +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/readme.md +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/test_client/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/validator/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/websocket/__init__.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/websocket/backplane.py +0 -0
- {tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/wsdl/__init__.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tina4-python
|
|
3
|
-
Version: 3.12.
|
|
4
|
-
Summary: Tina4
|
|
3
|
+
Version: 3.12.1
|
|
4
|
+
Summary: Tina4 Python v3 — Zero-dependency, lightweight web framework
|
|
5
5
|
Author-email: Andre van Zuydam <andrevanzuydam@gmail.com>
|
|
6
6
|
License: MIT
|
|
7
7
|
Requires-Python: >=3.12
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tina4-python"
|
|
3
|
-
|
|
4
|
-
description = "Tina4
|
|
3
|
+
version = "3.12.1"
|
|
4
|
+
description = "Tina4 Python v3 — Zero-dependency, lightweight web framework"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Andre van Zuydam", email = "andrevanzuydam@gmail.com"}
|
|
7
7
|
]
|
|
@@ -55,9 +55,6 @@ dev = [
|
|
|
55
55
|
requires = ["hatchling"]
|
|
56
56
|
build-backend = "hatchling.build"
|
|
57
57
|
|
|
58
|
-
[tool.hatch.version]
|
|
59
|
-
path = "tina4_python/__init__.py"
|
|
60
|
-
|
|
61
58
|
[tool.hatch.build]
|
|
62
59
|
include = ["tina4_python/**/*"]
|
|
63
60
|
|
|
@@ -28,10 +28,27 @@ except ImportError:
|
|
|
28
28
|
class FirebirdAdapter(DatabaseAdapter):
|
|
29
29
|
"""Firebird database driver using firebird-driver or fdb."""
|
|
30
30
|
|
|
31
|
+
# Substring markers (lowercased) that identify a dead-socket Firebird
|
|
32
|
+
# error worth reconnecting for. Idle Firebird connections die silently
|
|
33
|
+
# behind NAT timeouts, server-side ConnectionIdleTimeout, or Docker
|
|
34
|
+
# network rotation; without this the next prepare() crashes the request.
|
|
35
|
+
_DEAD_CONN_MARKERS = (
|
|
36
|
+
"error writing data to the connection",
|
|
37
|
+
"error reading data from the connection",
|
|
38
|
+
"connection shutdown",
|
|
39
|
+
"connection lost",
|
|
40
|
+
"network error",
|
|
41
|
+
"connection is not active",
|
|
42
|
+
"broken pipe",
|
|
43
|
+
)
|
|
44
|
+
|
|
31
45
|
def __init__(self):
|
|
32
46
|
super().__init__()
|
|
33
47
|
self._conn = None
|
|
34
48
|
self._in_transaction: bool = False
|
|
49
|
+
# Remembered connection params — populated by connect(), used by
|
|
50
|
+
# _reconnect() when a dead socket is detected mid-request.
|
|
51
|
+
self._connect_params: dict | None = None
|
|
35
52
|
|
|
36
53
|
def connect(self, connection_string: str, username: str = "", password: str = "", **kwargs):
|
|
37
54
|
"""Connect to Firebird.
|
|
@@ -54,28 +71,82 @@ class FirebirdAdapter(DatabaseAdapter):
|
|
|
54
71
|
password = parsed.password or password or "masterkey"
|
|
55
72
|
charset = kwargs.pop("charset", "UTF8")
|
|
56
73
|
|
|
74
|
+
# Cache for transparent reconnect — never logged, lives only in
|
|
75
|
+
# adapter memory alongside the connection it owns.
|
|
76
|
+
self._connect_params = {
|
|
77
|
+
"host": host, "port": port, "db_path": db_path,
|
|
78
|
+
"user": user, "password": password, "charset": charset,
|
|
79
|
+
"extra": dict(kwargs),
|
|
80
|
+
}
|
|
81
|
+
self._open()
|
|
82
|
+
|
|
83
|
+
def _open(self) -> None:
|
|
84
|
+
"""Open the underlying Firebird connection from cached params."""
|
|
85
|
+
p = self._connect_params
|
|
86
|
+
if p is None:
|
|
87
|
+
raise RuntimeError("FirebirdAdapter._open called before connect()")
|
|
88
|
+
|
|
57
89
|
if _driver_name == "firebird-driver":
|
|
58
90
|
# Modern firebird-driver uses dsn format: host/port:path
|
|
59
|
-
dsn = f"{host}/{port}:{db_path}" if port != 3050 else f"{host}:{db_path}"
|
|
91
|
+
dsn = f"{p['host']}/{p['port']}:{p['db_path']}" if p['port'] != 3050 else f"{p['host']}:{p['db_path']}"
|
|
60
92
|
self._conn = _driver.connect(
|
|
61
93
|
dsn,
|
|
62
|
-
user=user,
|
|
63
|
-
password=password,
|
|
64
|
-
charset=charset,
|
|
65
|
-
**
|
|
94
|
+
user=p["user"],
|
|
95
|
+
password=p["password"],
|
|
96
|
+
charset=p["charset"],
|
|
97
|
+
**p["extra"],
|
|
66
98
|
)
|
|
67
99
|
else:
|
|
68
100
|
# Legacy fdb
|
|
69
101
|
self._conn = _driver.connect(
|
|
70
|
-
host=host,
|
|
71
|
-
port=port,
|
|
72
|
-
database=db_path,
|
|
73
|
-
user=user,
|
|
74
|
-
password=password,
|
|
75
|
-
charset=charset,
|
|
76
|
-
**
|
|
102
|
+
host=p["host"],
|
|
103
|
+
port=p["port"],
|
|
104
|
+
database=p["db_path"],
|
|
105
|
+
user=p["user"],
|
|
106
|
+
password=p["password"],
|
|
107
|
+
charset=p["charset"],
|
|
108
|
+
**p["extra"],
|
|
77
109
|
)
|
|
78
110
|
|
|
111
|
+
@classmethod
|
|
112
|
+
def _is_dead_connection(cls, exc: BaseException) -> bool:
|
|
113
|
+
"""Match dead-socket error messages from firebird-driver / fdb.
|
|
114
|
+
Substring + case-insensitive so we catch both driver wording variants.
|
|
115
|
+
"""
|
|
116
|
+
msg = str(exc).lower()
|
|
117
|
+
return any(m in msg for m in cls._DEAD_CONN_MARKERS)
|
|
118
|
+
|
|
119
|
+
def _reconnect(self) -> None:
|
|
120
|
+
"""Force-close any stale handle and reopen. Safe to call repeatedly;
|
|
121
|
+
idempotent on a dead connection."""
|
|
122
|
+
try:
|
|
123
|
+
if self._conn is not None:
|
|
124
|
+
self._conn.close()
|
|
125
|
+
except Exception:
|
|
126
|
+
pass # connection already gone — nothing to clean up
|
|
127
|
+
self._conn = None
|
|
128
|
+
self._in_transaction = False
|
|
129
|
+
self._open()
|
|
130
|
+
|
|
131
|
+
def _safe_cursor_execute(self, cursor, sql: str, params: list | None):
|
|
132
|
+
"""Execute on a cursor with one transparent reconnect+retry on
|
|
133
|
+
dead-connection errors. Skipped inside an explicit transaction —
|
|
134
|
+
atomicity beats resilience there; the caller handles rollback.
|
|
135
|
+
|
|
136
|
+
Returns the cursor (possibly a fresh one after reconnect) so the
|
|
137
|
+
caller can fetch results from it.
|
|
138
|
+
"""
|
|
139
|
+
try:
|
|
140
|
+
cursor.execute(sql, params or [])
|
|
141
|
+
return cursor
|
|
142
|
+
except Exception as e:
|
|
143
|
+
if not self._is_dead_connection(e) or self._in_transaction:
|
|
144
|
+
raise
|
|
145
|
+
self._reconnect()
|
|
146
|
+
cursor = self._conn.cursor()
|
|
147
|
+
cursor.execute(sql, params or [])
|
|
148
|
+
return cursor
|
|
149
|
+
|
|
79
150
|
def close(self):
|
|
80
151
|
if self._conn:
|
|
81
152
|
self._conn.close()
|
|
@@ -92,7 +163,7 @@ class FirebirdAdapter(DatabaseAdapter):
|
|
|
92
163
|
sql = sql[:returning_match.start()]
|
|
93
164
|
|
|
94
165
|
cursor = self._conn.cursor()
|
|
95
|
-
cursor.
|
|
166
|
+
cursor = self._safe_cursor_execute(cursor, sql, params)
|
|
96
167
|
|
|
97
168
|
records = []
|
|
98
169
|
last_id = None
|
|
@@ -145,16 +216,19 @@ class FirebirdAdapter(DatabaseAdapter):
|
|
|
145
216
|
# Count total rows
|
|
146
217
|
count_sql = f"SELECT COUNT(*) FROM ({sql})"
|
|
147
218
|
try:
|
|
148
|
-
cursor.
|
|
219
|
+
cursor = self._safe_cursor_execute(cursor, count_sql, params)
|
|
149
220
|
total = cursor.fetchone()[0]
|
|
150
221
|
except Exception:
|
|
151
222
|
total = 0
|
|
223
|
+
# Reconnect may have just happened — get a fresh cursor for the
|
|
224
|
+
# paginated query below regardless of whether count succeeded.
|
|
225
|
+
cursor = self._conn.cursor()
|
|
152
226
|
|
|
153
227
|
# Apply Firebird pagination — ROWS start TO end
|
|
154
228
|
start = offset + 1
|
|
155
229
|
end = offset + limit
|
|
156
230
|
paginated_sql = f"{sql} ROWS {start} TO {end}"
|
|
157
|
-
cursor.
|
|
231
|
+
cursor = self._safe_cursor_execute(cursor, paginated_sql, params)
|
|
158
232
|
|
|
159
233
|
desc = cursor.description
|
|
160
234
|
col_names = [d[0].strip().lower() for d in desc] if desc else []
|
|
@@ -165,7 +239,7 @@ class FirebirdAdapter(DatabaseAdapter):
|
|
|
165
239
|
def fetch_one(self, sql: str, params: list = None) -> dict | None:
|
|
166
240
|
sql = self._translate_sql(sql)
|
|
167
241
|
cursor = self._conn.cursor()
|
|
168
|
-
cursor.
|
|
242
|
+
cursor = self._safe_cursor_execute(cursor, sql, params)
|
|
169
243
|
desc = cursor.description
|
|
170
244
|
row = cursor.fetchone()
|
|
171
245
|
if row is None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/public/swagger/oauth2-redirect.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/session_handlers/mongodb_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/templates/docker/distroless/Dockerfile
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/af/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/af/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/en/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/en/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/es/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/es/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/fr/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/fr/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/ja/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/ja/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/zh/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.12.0 → tina4_python-3.12.1}/tina4_python/translations/zh/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|