[server] refactor cleanup() code used by "cubicweb-ctl delete"
Try to make each logical step (i.e. "delete database" and "delete user")
a bit more visible and explicit.
This is a preparatory work to easily plug the "delete namespace" feature.
What's new in CubicWeb 3.19?
============================
New functionalities
--------------------
* implement Cross Origin Resource Sharing (CORS)
(see `#2491768 <http://www.cubicweb.org/2491768>`_)
* system_source.create_eid can get a range of IDs, to reduce overhead of batch
entity creation
Behaviour Changes
-----------------
* The anonymous property of Session and Connection are now computed from the
related user login. If it matches the ``anonymous-user`` in the config the
connection is anonymous. Beware that the ``anonymous-user`` config is web
specific. Therefore, no session may be anonymous in a repository only setup.
New Repository Access API
-------------------------
Connection replaces Session
~~~~~~~~~~~~~~~~~~~~~~~~~~~
A new explicit Connection object replaces Session as the main repository entry
point. Connection holds all the necessary methods to be used server-side
(``execute``, ``commit``, ``rollback``, ``call_service``, ``entity_from_eid``,
etc...). One obtains a new Connection object using ``session.new_cnx()``.
Connection objects need to have an explicit begin and end. Use them as a context
manager to never miss an end::
with session.new_cnx() as cnx:
cnx.execute('INSERT Elephant E, E name "Babar"')
cnx.commit()
cnx.execute('INSERT Elephant E, E name "Celeste"')
cnx.commit()
# Once you get out of the "with" clause, the connection is closed.
Using the same Connection object in multiple threads will give you access to the
same Transaction. However, Connection objects are not thread safe (hence at your
own risks).
``repository.internal_session`` is deprecated in favor of
``repository.internal_cnx``. Note that internal connections are now `safe` by default,
i.e. the integrity hooks are enabled.
Backward compatibility is preserved on Session.
dbapi vs repoapi
~~~~~~~~~~~~~~~~
A new API has been introduced to replace the dbapi. It is called `repoapi`.
There are three relevant functions for now:
* ``repoapi.get_repository`` returns a Repository object either from an
URI when used as ``repoapi.get_repository(uri)`` or from a config
when used as ``repoapi.get_repository(config=config)``.
* ``repoapi.connect(repo, login, **credentials)`` returns a ClientConnection
associated with the user identified by the credentials. The
ClientConnection is associated with its own Session that is closed
when the ClientConnection is closed. A ClientConnection is a
Connection-like object to be used client side.
* ``repoapi.anonymous_cnx(repo)`` returns a ClientConnection associated
with the anonymous user if described in the config.
repoapi.ClientConnection replace dbapi.Connection and company
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
On the client/web side, the Request is now using a ``repoapi.ClientConnection``
instead of a ``dbapi.connection``. The ``ClientConnection`` has multiple backward
compatible methods to make it look like a ``dbapi.Cursor`` and ``dbapi.Connection``.
Session used on the Web side are now the same than the one used Server side.
Some backward compatibility methods have been installed on the server side Session
to ease the transition.
The authentication stack has been altered to use the ``repoapi`` instead of
the ``dbapi``. Cubes adding new element to this stack are likely to break.
Session data can be accessed using the cnx.data dictionary, while
transaction data is available through cnx.transaction_data. These
replace the [gs]et_shared_data methods with optional txid kwarg.
New API in tests
~~~~~~~~~~~~~~~~
All current methods and attributes used to access the repo on ``CubicWebTC`` are
deprecated. You may now use a ``RepoAccess`` object. A ``RepoAccess`` object is
linked to a new ``Session`` for a specified user. It is able to create
``Connection``, ``ClientConnection`` and web side requests linked to this
session::
access = self.new_access('babar') # create a new RepoAccess for user babar
with access.repo_cnx() as cnx:
# some work with server side cnx
cnx.execute(...)
cnx.commit()
cnx.execute(...)
cnx.commit()
with access.client_cnx() as cnx:
# some work with client side cnx
cnx.execute(...)
cnx.commit()
with access.web_request(elephant='babar') as req:
# some work with client side cnx
elephant_name = req.form['elephant']
req.execute(...)
req.cnx.commit()
By default ``testcase.admin_access`` contains a ``RepoAccess`` object for the
default admin session.
API changes
-----------
* ``RepositorySessionManager.postlogin`` is now called with two arguments,
request and session. And this now happens before the session is linked to the
request.
* ``SessionManager`` and ``AuthenticationManager`` now take a repo object at
initialization time instead of a vreg.
* The ``async`` argument of ``_cw.call_service`` has been dropped. All calls are
now synchronous. The zmq notification bus looks like a good replacement for
most async use cases.
* ``repo.stats()`` is now deprecated. The same information is available through
a service (``_cw.call_service('repo_stats')``).
* ``repo.gc_stats()`` is now deprecated. The same information is available through
a service (``_cw.call_service('repo_gc_stats')``).
* ``repo.register_user()`` is now deprecated. The functionality is now
available through a service (``_cw.call_service('register_user')``).
* ``request.set_session`` no longer takes an optional ``user`` argument.
* CubicwebTC does not have repo and cnx as class attributes anymore. They are
standard instance attributes. ``set_cnx`` and ``_init_repo`` class methods
become instance methods.
* ``set_cnxset`` and ``free_cnxset`` are deprecated. cnxset are now
automatically managed.
* The implementation of cascading deletion when deleting `composite`
entities has changed. There comes a semantic change: merely deleting
a composite relation does not entail any more the deletion of the
component side of the relation.
* ``_cw.user_callback`` and ``_cw.user_rql_callback`` are deprecated. Users
are encouraged to write an actual controller (e.g. using ``ajaxfunc``)
instead of storing a closure in the session data.
* A new ``entity.cw_linkable_rql`` method provides the rql to fetch all entities
that are already or may be related to the current entity using the given
relation.
Deprecated Code Drops
----------------------
* session.hijack_user mechanism has been dropped.
* EtypeRestrictionComponent has been removed, its functionality has been
replaced by facets a while ago.
* the old multi-source support has been removed. Only copy-based sources
remain, such as datafeed or ldapfeed.