Skip to content
Snippets Groups Projects
Commit f57cc7a96371 authored by François Ferry's avatar François Ferry
Browse files

feat!: drop old transaction api since it's not working properly when we have several process

parent 2c3080a89e96
No related branches found
No related tags found
1 merge request!51Add a new API for transactions
# copyright 2022-2023 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact https://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from typing import cast, Dict
from cubicweb.entities.authobjs import CWUser
from cubicweb.server.repository import Repository
from cubicweb.server.session import Connection
class ApiTransaction:
def __init__(self, repo: Repository, user: CWUser):
"""
Class defining transactions.
A transaction allows to make several request which only take effect
when the changes are committed.
:param repo: The CubicWeb repository
:param user: The user initiating the transaction
"""
self.cnx = Connection(repo, user)
self.cnx.__enter__()
self._uuid = cast(str, self.cnx.transaction_uuid(set=True))
@property
def uuid(self) -> str:
"""
:return: The unique identifier for this transaction
"""
return self._uuid
def execute(self, rql: str, params: Dict[str, any]):
"""
Executes the given rql query on this transaction.
:param rql: The RQL query string
:param params: The parameters for the RQL query
:return: The result from executing the query
"""
return self.cnx.execute(rql, params)
def commit(self):
"""
Commits the current transaction to apply all changes.
"""
self.cnx.commit()
def rollback(self):
"""
Rollback the current transaction to cancel all changes.
"""
self.cnx.rollback()
def end(self):
self.cnx.__exit__(None, None, None)
class ApiTransactionsRepository:
def __init__(self, repo: Repository):
"""
Class holding all active transactions from all users.
:param repo: The CubicWeb repository
"""
self._transactions: Dict[str, ApiTransaction] = dict()
self._repo = repo
def begin_transaction(self, user: CWUser) -> str:
"""
Starts a new transaction for the given user.
:param user: The user initiating the transaction
:return: The transaction uuid
"""
transaction = ApiTransaction(self._repo, user)
self._transactions[transaction.uuid] = transaction
return transaction.uuid
def end_transaction(self, uuid: str):
"""
Ends a transaction identified by its uuid.
:param uuid: The id of the transaction to end.
"""
transaction = self._transactions.pop(uuid)
transaction.end()
def __getitem__(self, uuid: str) -> ApiTransaction:
return self._transactions[uuid]
...@@ -85,65 +85,6 @@ ...@@ -85,65 +85,6 @@
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/CurrentUser' $ref: '#/components/schemas/CurrentUser'
/transaction/begin:
x-pyramid-route-name: transaction/begin
post:
description: Starts a new transaction
responses:
'200':
description: The transaction's uuid
content:
application/json:
schema:
type: string
/transaction/execute:
x-pyramid-route-name: transaction/execute
post:
description: Executes the given rql query as part of a transaction
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TransactionExecuteParams'
responses:
'200':
description: The RQL result set
content:
application/json:
schema:
type: array
items:
type: object
'400':
description: The given RQL was badly formatted
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorSchema'
/transaction/commit:
x-pyramid-route-name: transaction/commit
post:
description: Commits a transaction
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TransactionParams'
responses:
'200':
description: The transaction was successful
/transaction/rollback:
x-pyramid-route-name: transaction/rollback
post:
description: Rollback a transaction
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TransactionParams'
responses:
'200':
description: The transaction rollback was successful
openapi: 3.0.3 openapi: 3.0.3
components: components:
schemas: schemas:
...@@ -209,31 +150,6 @@ ...@@ -209,31 +150,6 @@
required: required:
- login - login
- password - password
TransactionParams:
type: object
properties:
uuid:
type: string
minLength: 32
required:
- uuid
TransactionExecuteParams:
type: object
properties:
query:
type: string
minLength: 1
params:
type: object
default: {}
additionalProperties:
nullable: true
uuid:
type: string
minLength: 32
required:
- query
- uuid
ErrorSchema: ErrorSchema:
type: object type: object
properties: properties:
......
...@@ -24,9 +24,8 @@ ...@@ -24,9 +24,8 @@
from pyramid.security import remember from pyramid.security import remember
from pyramid.view import view_config, view_defaults from pyramid.view import view_config, view_defaults
from cubicweb_api.api_transaction import ApiTransactionsRepository
from cubicweb_api.auth.jwt_auth import setup_jwt from cubicweb_api.auth.jwt_auth import setup_jwt
from cubicweb_api.constants import ( from cubicweb_api.constants import (
API_ROUTE_NAME_PREFIX, API_ROUTE_NAME_PREFIX,
) )
from cubicweb_api.openapi.openapi import setup_openapi from cubicweb_api.openapi.openapi import setup_openapi
...@@ -28,9 +27,9 @@ ...@@ -28,9 +27,9 @@
from cubicweb_api.auth.jwt_auth import setup_jwt from cubicweb_api.auth.jwt_auth import setup_jwt
from cubicweb_api.constants import ( from cubicweb_api.constants import (
API_ROUTE_NAME_PREFIX, API_ROUTE_NAME_PREFIX,
) )
from cubicweb_api.openapi.openapi import setup_openapi from cubicweb_api.openapi.openapi import setup_openapi
from cubicweb_api.util import get_cw_repo, get_transactions_repository from cubicweb_api.util import get_cw_repo
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -44,10 +43,6 @@ ...@@ -44,10 +43,6 @@
rql = "rql" rql = "rql"
login = "login" login = "login"
current_user = "current_user" current_user = "current_user"
transaction_begin = "transaction/begin"
transaction_execute = "transaction/execute"
transaction_commit = "transaction/commit"
transaction_rollback = "transaction/rollback"
help = "help" help = "help"
...@@ -135,61 +130,6 @@ ...@@ -135,61 +130,6 @@
user = self.request.cw_cnx.user user = self.request.cw_cnx.user
return {"eid": user.eid, "login": user.login, "dcTitle": user.dc_title()} return {"eid": user.eid, "login": user.login, "dcTitle": user.dc_title()}
@view_config(
route_name=get_route_name(ApiRoutes.transaction_begin),
anonymous_or_connected=True,
)
def transaction_begin_route(self):
"""
See the openapi/openapi_template.yml file for more information on this route.
"""
transactions = get_transactions_repository(self.request)
user = self.request.cw_cnx.user
return transactions.begin_transaction(user)
@view_config(
route_name=get_route_name(ApiRoutes.transaction_execute),
anonymous_or_connected=True,
)
def transaction_execute_route(self):
"""
See the openapi/openapi_template.yml file for more information on this route.
"""
transactions = get_transactions_repository(self.request)
request_params = self.request.openapi_validated.body
uuid: str = request_params["uuid"]
query: str = request_params["query"]
params: dict = request_params["params"]
return transactions[uuid].execute(query, params).rows
@view_config(
route_name=get_route_name(ApiRoutes.transaction_commit),
anonymous_or_connected=True,
)
def transaction_commit_route(self):
"""
See the openapi/openapi_template.yml file for more information on this route.
"""
transactions = get_transactions_repository(self.request)
request_params = self.request.openapi_validated.body
uuid: str = request_params["uuid"]
return transactions[uuid].commit()
@view_config(
route_name=get_route_name(ApiRoutes.transaction_rollback),
anonymous_or_connected=True,
)
def transaction_rollback_route(self):
"""
See the openapi/openapi_template.yml file for more information on this route.
"""
transactions = get_transactions_repository(self.request)
request_params = self.request.openapi_validated.body
uuid: str = request_params["uuid"]
rollback_result = transactions[uuid].rollback()
transactions.end_transaction(uuid)
return rollback_result
def includeme(config: Configurator): def includeme(config: Configurator):
setup_jwt(config) setup_jwt(config)
...@@ -193,8 +133,6 @@ ...@@ -193,8 +133,6 @@
def includeme(config: Configurator): def includeme(config: Configurator):
setup_jwt(config) setup_jwt(config)
repo = get_cw_repo(config)
repo.api_transactions = ApiTransactionsRepository(repo)
setup_openapi(config) setup_openapi(config)
config.pyramid_openapi3_register_routes() config.pyramid_openapi3_register_routes()
config.scan() config.scan()
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
from pyramid.config import Configurator from pyramid.config import Configurator
from pyramid.request import Request from pyramid.request import Request
from cubicweb_api.api_transaction import ApiTransactionsRepository
from cubicweb_api.constants import API_PATH_DEFAULT_PREFIX from cubicweb_api.constants import API_PATH_DEFAULT_PREFIX
...@@ -48,16 +47,6 @@ ...@@ -48,16 +47,6 @@
return config.registry["cubicweb.config"] return config.registry["cubicweb.config"]
def get_transactions_repository(request: Request) -> ApiTransactionsRepository:
"""
Helper used to have typing on the api transaction repository.
:param request: The pyramid request containing the transaction repository
:return: An ApiTransactionsRepository object
"""
return get_cw_repo(request).api_transactions
def get_openapi_spec_server_url(config: Configurator) -> str: def get_openapi_spec_server_url(config: Configurator) -> str:
""" """
Gets the server base url from the configuration. Gets the server base url from the configuration.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment