4.x to 5.x
==========

Guillotina 5 changes focus around the following features:

- Python 3.7 with context vars
- Decoupling request with a lot of APIs in favor of using context vars instead
- Being able to control database and transactions more easily without needing a "request" object
- Normalizing naming across platform and no longer using romantic naming for things(no more `_p_` methods)


API Removals/changes
--------------------

- `__local__properties__` no longer necessary `ContextProperty` on behaviors
- Removed `IInteraction`. Use `guillotina.utils.get_security_policy()`
- `ISecurityPolicy`: instead of adapting request, it now adapter a principal
  - Move `ISecurityPolicy.cached_principals` to module level function `guillotina.security.policy.cached_principals`
  - Moved `ISecurityPolicy.cached_roles` to module level function `guillotina.security.policy.cached_roles`
- `utils.get_authenticated_user_id` no longer accepts `request` param
- `utils.get_authenticated_user` no longer accepts `request` param
- Removed `guillotina.exceptions.NoInteraction`
- Removed `guillotina.interfaces.IInteraction`
- `auth_user_identifiers` no longer accept `IRequest` in the constructor. Use `utils.get_current_request`
- `auth_user_identifiers` no longer accept `IRequest` in constructor. Use `utils.get_current_request`
- Remove `Request._db_write_enabled`, `Transaction` now has `read_only` property
- Remove `Request._db_id`, Use `guillotina.task_vars.db.get().id`
- Remove `Request.container_settings`, Use `guillotina.utils.get_registry()`
- Remove `Request._container_id`, use `guillotina.task_vars.container.get().id`
- Remove `Request.container`, Use `guillotina.task_vars.container.get()`
- Remove `Request.add_future`. Use `guillotina.utils.execute.add_future`
- Add `guillotina.utils.find_container`
- Rename `guillotina.catalog.index.RequestIndexer` to `guillotina.catalog.index.Indexer`
- Rename `IWriter.parent_id` to `IWriter.parent_uid`
- Rename `guillotina.db.oid` to `guillotina.db.uid`
- Rename `oid_generate` setting to `uid_generator`
- Rename `BaseObject._p_register` -> `BaseObject.register`
- Rename `BaseObject._p_serial` -> `BaseObject.__serial__`
- Rename `BaseObject._p_oid` -> `BaseObject.__uuid__`
- Rename `BaseObject._p_jar` -> `BaseObject.__txn__`
- rename `guillotina.transactions.managed_transaction` to `guillotina.transactions.transaction`
- Default catalog interface removes the following methods: `get_by_uuid`, `get_by_type`, `get_by_path`,
  `get_folder_contents`.


Settings changes
----------------

Application(json/yaml) settings changes.

- Rename `request_indexer` to `indexer`
- Remove `utilities` support. Use `load_utilities`


Command changes
---------------

Commands no longer automatically setup a fake request object. If you need one, you'll need to create it
yourself in the command.


Open API Changes
----------------

Guillotina 5 is now Open API 3 compliant. This document will not go over all the implications of this so
please refer to the Open API docs for questions: https://swagger.io/docs/specification/about/

The most important changes that you'll notice are no long putting validation into `parameters` for services
and using the `#/components/schemas` prefix instead of `#/definitions`.


Catalog interface changes
-------------------------

Guillotina has introduced the ability to provide your own query parsers now.

A simple parser looks like this::

    from guillotina import configure
    from guillotina.interfaces import ICatalogUtility, IResource, ISearchParser
    from guillotina.catalog.parser import BaseParser
    @configure.adapter(
        for_=(ICatalogUtility, IResource),
        provides=ISearchParser,
        name='myparser')
    class MyParser(BaseParser):
        def __init__(self, util, context):
            self.util = util
            self.context = context
        
        def __call__(self, params):
            # transform query
            return {...}

Then, to activate your custom parser, change your settings with::

    {
        "search_parser": "myparser"
    }


The `ICatalogUtility.query` method is used for "raw" queries coming in. The default base catalog will
use the configured parser and use the `ICatalogUtility.search` with the parsed query.

Individual catalog implementations can decide then override this functionality.


Gotchas
-------

- Context vars do not work in executors!
- Default field values are now enforced. If you do not define default on fields, you will get AttributeError
  if the data hasn't been set yet.
- Beware of TransactionClosedException and TransactionNotFound exceptions. If you do not have a valid
  transaction setup while you are interacting with objects to write to the database, you will get errors now.
  This is to prevent you from making mistakes and expecting data to be written when it will not be.
