From 50905ff253e5e1164b377ad5f285d1c439e7bdb7 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 7 May 2013 22:32:26 +0200 Subject: [PATCH 1/6] Adding lazy services documentation as of symfony/symfony#7890 --- components/dependency_injection/index.rst | 1 + .../dependency_injection/lazy_services.rst | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 components/dependency_injection/lazy_services.rst diff --git a/components/dependency_injection/index.rst b/components/dependency_injection/index.rst index e1d6b0eab8d..b3960eb8e00 100644 --- a/components/dependency_injection/index.rst +++ b/components/dependency_injection/index.rst @@ -14,5 +14,6 @@ configurators parentservices advanced + lazy_services workflow diff --git a/components/dependency_injection/lazy_services.rst b/components/dependency_injection/lazy_services.rst new file mode 100644 index 00000000000..ca97b5cad24 --- /dev/null +++ b/components/dependency_injection/lazy_services.rst @@ -0,0 +1,68 @@ +.. index:: + single: Dependency Injection; Lazy Services + +Lazy Services +============= + +.. versionadded:: 2.3 + Lazy services were added in Symfony 2.3. + +Configuring lazy services +------------------------- + +In some particular cases where a very heavy service is always requested, +but not always used, you may want to mark it as ``lazy`` to delay its instantiation. + +In order to have services to lazily instantiate, you will first need to install +the `ProxyManager bridge`_:: + + php composer.phar require symfony/proxy-manager-bridge:2.3.* + +You can mark the service as ``lazy`` by manipulating its definitions: + + +.. configuration-block:: + + .. code-block:: yaml + + services: + foo: + class: Example\Foo + lazy: true + + .. code-block:: xml + + + + .. code-block:: php + + $definition = new Definition('Example\Foo'); + $definition->setLazy(true); + $container->setDefinition('foo', $definition); + +You can then require the service from the container:: + + $service = $container->get($serviceId); + +At this point the retrieved ``$service`` should be a virtual `proxy`_ with the same +signature of the class representing the service. + +.. note:: + + If you don't install the `ProxyManager bridge`_, the container will just skip + over the ``lazy`` flag and simply instantiate the service as it would normally do. + +The proxy gets initialized and the actual service is instantiated as soon as you interact +in any way with this object. + +Additional resources +-------------------- + + +You can read more about how proxies are instantiated, generated and initialized in +the `documentation of ProxyManager`_. + + +.. _`ProxyManager bridge`: https://github.com/symfony/symfony/tree/2.3/src/Symfony/Bridge/ProxyManager +.. _`proxy`: http://en.wikipedia.org/wiki/Proxy_pattern +.. _`documentation of ProxyManager`: https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-value-holder.md \ No newline at end of file From c3c3e98bab34427db516ab391bca73dbd0b04a3a Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Wed, 8 May 2013 18:35:49 +0200 Subject: [PATCH 2/6] [Components][Console] Fixed typos for table helper --- components/console/helpers/tablehelper.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/console/helpers/tablehelper.rst b/components/console/helpers/tablehelper.rst index 04301af5048..1145dd7b603 100644 --- a/components/console/helpers/tablehelper.rst +++ b/components/console/helpers/tablehelper.rst @@ -48,8 +48,8 @@ You can also control table rendering by setting custom rendering option values: * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setPaddingChar` * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setHorizontalBorderChar` * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVerticalBorderChar` -* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVrossingChar` -* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVellHeaderFormat` -* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVellRowFormat` +* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCrossingChar` +* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCellHeaderFormat` +* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCellRowFormat` * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setBorderFormat` * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setPadType` From 931091d8e3aa0b9d4f1393d313388d5ee1a5d47d Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 May 2013 20:18:51 +0200 Subject: [PATCH 3/6] Applying changes suggested by @WouterJ, adding lazy_services to components map --- .../dependency_injection/lazy_services.rst | 17 ++++++++--------- components/map.rst.inc | 1 + 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/components/dependency_injection/lazy_services.rst b/components/dependency_injection/lazy_services.rst index ca97b5cad24..599d503f7e6 100644 --- a/components/dependency_injection/lazy_services.rst +++ b/components/dependency_injection/lazy_services.rst @@ -14,35 +14,35 @@ In some particular cases where a very heavy service is always requested, but not always used, you may want to mark it as ``lazy`` to delay its instantiation. In order to have services to lazily instantiate, you will first need to install -the `ProxyManager bridge`_:: +the `ProxyManager bridge`_: - php composer.phar require symfony/proxy-manager-bridge:2.3.* +.. code-block:: bash + $ php composer.phar require symfony/proxy-manager-bridge:2.3.* You can mark the service as ``lazy`` by manipulating its definitions: - .. configuration-block:: .. code-block:: yaml services: foo: - class: Example\Foo + class: Acme\Foo lazy: true .. code-block:: xml - + .. code-block:: php - $definition = new Definition('Example\Foo'); + $definition = new Definition('Acme\Foo'); $definition->setLazy(true); $container->setDefinition('foo', $definition); You can then require the service from the container:: - $service = $container->get($serviceId); + $service = $container->get('foo'); At this point the retrieved ``$service`` should be a virtual `proxy`_ with the same signature of the class representing the service. @@ -55,10 +55,9 @@ signature of the class representing the service. The proxy gets initialized and the actual service is instantiated as soon as you interact in any way with this object. -Additional resources +Additional Resources -------------------- - You can read more about how proxies are instantiated, generated and initialized in the `documentation of ProxyManager`_. diff --git a/components/map.rst.inc b/components/map.rst.inc index e29df506e55..d360c65a706 100644 --- a/components/map.rst.inc +++ b/components/map.rst.inc @@ -39,6 +39,7 @@ * :doc:`/components/dependency_injection/configurators` * :doc:`/components/dependency_injection/parentservices` * :doc:`/components/dependency_injection/advanced` + * :doc:`/components/dependency_injection/lazy_services` * :doc:`/components/dependency_injection/workflow` * **DOM Crawler** From 438c8244e04e8c9ad818d93f22699ab5c8aa0289 Mon Sep 17 00:00:00 2001 From: Bernhard Schussek Date: Wed, 15 May 2013 13:01:26 +0200 Subject: [PATCH 4/6] Made the Icu component compatible with ICU 3.8 --- components/intl.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/intl.rst b/components/intl.rst index cf42b9778d5..e9c5028d4c2 100644 --- a/components/intl.rst +++ b/components/intl.rst @@ -72,7 +72,7 @@ expose them manually by adding the following lines to your autoload code:: but usually Composer does this for you automatically: * 1.0.*: when the intl extension is not available - * 1.1.*: when intl is compiled with ICU 4.0 or higher + * 1.1.*: when intl is compiled with ICU 3.8 or higher * 1.2.*: when intl is compiled with ICU 4.4 or higher These versions are important when you deploy your application to a **server with From d7ea3a540a5dc425bf1d16f4113746975404da38 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Wed, 15 May 2013 22:04:52 -0500 Subject: [PATCH 5/6] [#2619] Tweaks for new proxy/lazy services entry --- .../dependency_injection/lazy_services.rst | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/components/dependency_injection/lazy_services.rst b/components/dependency_injection/lazy_services.rst index 599d503f7e6..88ad0c51f59 100644 --- a/components/dependency_injection/lazy_services.rst +++ b/components/dependency_injection/lazy_services.rst @@ -7,19 +7,41 @@ Lazy Services .. versionadded:: 2.3 Lazy services were added in Symfony 2.3. -Configuring lazy services -------------------------- +Why Lazy Services? +------------------ -In some particular cases where a very heavy service is always requested, -but not always used, you may want to mark it as ``lazy`` to delay its instantiation. +In some cases, you may want to inject a service that is a bit heavy to instantiate, +but is not always used inside your object. For example, imagine you have +a ``NewsletterManager`` and you inject a ``mailer`` service into it. Only +a few methods on your ``NewsletterManager`` actually use the ``mailer``, +but even when you don't need it, a ``mailer`` service is always instantiated +in order to construct your ``NewsletterManager``. -In order to have services to lazily instantiate, you will first need to install +Configuring lazy services is one answer to this. With a lazy service, a "proxy" +of the ``mailer`` service is actually injected. It looks and acts just like +the ``mailer``, except that the ``mailer`` isn't actually instantiated until +you interact with the proxy in some way. + +Installation +------------ + +In order to use the lazy service instantiation, you will first need to install the `ProxyManager bridge`_: .. code-block:: bash + $ php composer.phar require symfony/proxy-manager-bridge:2.3.* -You can mark the service as ``lazy`` by manipulating its definitions: +.. note:: + + If you're using the full-stack framework, this package is not included + and needs to be added to ``composer.json`` and installed (which is what + the above command does). + +Configuration +------------- + +You can mark the service as ``lazy`` by manipulating its definition: .. configuration-block:: @@ -44,24 +66,27 @@ You can then require the service from the container:: $service = $container->get('foo'); -At this point the retrieved ``$service`` should be a virtual `proxy`_ with the same -signature of the class representing the service. +At this point the retrieved ``$service`` should be a virtual `proxy`_ with +the same signature of the class representing the service. You can also inject +the service just like normal into other services. The object that's actually +injected will be the proxy. .. note:: - If you don't install the `ProxyManager bridge`_, the container will just skip - over the ``lazy`` flag and simply instantiate the service as it would normally do. + If you don't install the `ProxyManager bridge`_, the container will just + skip over the ``lazy`` flag and simply instantiate the service as it would + normally do. -The proxy gets initialized and the actual service is instantiated as soon as you interact -in any way with this object. +The proxy gets initialized and the actual service is instantiated as soon +as you interact in any way with this object. Additional Resources -------------------- -You can read more about how proxies are instantiated, generated and initialized in -the `documentation of ProxyManager`_. +You can read more about how proxies are instantiated, generated and initialized +in the `documentation of ProxyManager`_. -.. _`ProxyManager bridge`: https://github.com/symfony/symfony/tree/2.3/src/Symfony/Bridge/ProxyManager +.. _`ProxyManager bridge`: https://github.com/symfony/symfony/tree/master/src/Symfony/Bridge/ProxyManager .. _`proxy`: http://en.wikipedia.org/wiki/Proxy_pattern .. _`documentation of ProxyManager`: https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-value-holder.md \ No newline at end of file From 26215a787adb71e4228418bd7cffeb181e75a4d7 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Wed, 12 Jun 2013 08:21:14 -0500 Subject: [PATCH 6/6] Fixing Security Entity Provider tutorial for more info see #2756 --- book/doctrine.rst | 4 + contributing/community/releases.rst | 14 ++- cookbook/security/entity_provider.rst | 172 +++++++++++++------------- 3 files changed, 104 insertions(+), 86 deletions(-) diff --git a/book/doctrine.rst b/book/doctrine.rst index e9d09d5b784..4db46fe69dd 100644 --- a/book/doctrine.rst +++ b/book/doctrine.rst @@ -363,6 +363,8 @@ see the :ref:`book-doctrine-field-types` section. class Product // ... +.. _book-doctrine-generating-getters-and-setters: + Generating Getters and Setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -425,6 +427,8 @@ mapping information) of a bundle or an entire namespace: The getters and setters are generated here only because you'll need them to interact with your PHP object. +.. _book-doctrine-creating-the-database-tables-schema: + Creating the Database Tables/Schema ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/contributing/community/releases.rst b/contributing/community/releases.rst index 80fc38ef3b6..9825a01e7a5 100644 --- a/contributing/community/releases.rst +++ b/contributing/community/releases.rst @@ -75,18 +75,30 @@ Below is the schedule for the first few versions that use this release model: This results in very predictable dates and maintenance periods: + ++---------+---------+---------------------+-------------+ | Version | Release | End of Maintenance | End of Life | -| ------- | ------- | ------------------- | ----------- | ++=========+=========+=====================+=============+ | 2.0 | 07/2011 | 03/2013 (20 months) | 09/2013 | ++---------+---------+---------------------+-------------+ | 2.1 | 09/2012 | 05/2013 (9 months) | 11/2013 | ++---------+---------+---------------------+-------------+ | 2.2 | 03/2013 | 11/2013 (8 months) | 05/2014 | ++---------+---------+---------------------+-------------+ | **2.3** | 05/2013 | 05/2016 (36 months) | 05/2017 | ++---------+---------+---------------------+-------------+ | 2.4 | 11/2013 | 07/2014 (8 months) | 01/2015 | ++---------+---------+---------------------+-------------+ | 2.5 | 05/2014 | 01/2015 (8 months) | 07/2016 | ++---------+---------+---------------------+-------------+ | 2.6 | 11/2014 | 07/2015 (8 months) | 01/2016 | ++---------+---------+---------------------+-------------+ | **2.7** | 05/2015 | 05/2018 (36 months) | 05/2019 | ++---------+---------+---------------------+-------------+ | 2.8 | 11/2015 | 07/2016 (8 months) | 01/2017 | ++---------+---------+---------------------+-------------+ | ... | ... | ... | ... | ++---------+---------+---------------------+-------------+ .. tip:: diff --git a/cookbook/security/entity_provider.rst b/cookbook/security/entity_provider.rst index be9f36f897b..a1ecdd6e91e 100644 --- a/cookbook/security/entity_provider.rst +++ b/cookbook/security/entity_provider.rst @@ -167,21 +167,6 @@ interface forces the class to implement the five following methods: For more details on each of these, see :class:`Symfony\\Component\\Security\\Core\\User\\UserInterface`. -.. code-block:: php - - // src/Acme/UserBundle/Entity/User.php - - namespace Acme\UserBundle\Entity; - - use Symfony\Component\Security\Core\User\EquatableInterface; - - // ... - - public function isEqualTo(UserInterface $user) - { - return $this->id === $user->getId(); - } - .. note:: The :phpclass:`Serializable` interface and its ``serialize`` and ``unserialize`` @@ -191,24 +176,32 @@ For more details on each of these, see :class:`Symfony\\Component\\Security\\Cor because the :method:`Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider::refreshUser` method reloads the user on each request by using the ``id``. -Below is an export of my ``User`` table from MySQL. For details on how to -create user records and encode their password, see :ref:`book-security-encoding-user-password`. +.. tip:: + + To generate missing setters and getters for your ``User`` entity, you + can use ``php app/console doctrine:generate:entities Acme/UserBundle/Entity/User``. + For more details, see Doctrine's :ref:`book-doctrine-generating-getters-and-setters`. + +Below is an export of my ``User`` table from MySQL with user `admin` +and password `admin`. For details on how to create user records and +encode their password, see :ref:`book-security-encoding-user-password`. .. code-block:: bash - $ mysql> select * from user; - +----+----------+----------------------------------+------------------------------------------+--------------------+-----------+ - | id | username | salt | password | email | is_active | - +----+----------+----------------------------------+------------------------------------------+--------------------+-----------+ - | 1 | hhamon | 7308e59b97f6957fb42d66f894793079 | 09610f61637408828a35d7debee5b38a8350eebe | hhamon@example.com | 1 | - | 2 | jsmith | ce617a6cca9126bf4036ca0c02e82dee | 8390105917f3a3d533815250ed7c64b4594d7ebf | jsmith@example.com | 1 | - | 3 | maxime | cd01749bb995dc658fa56ed45458d807 | 9764731e5f7fb944de5fd8efad4949b995b72a3c | maxime@example.com | 0 | - | 4 | donald | 6683c2bfd90c0426088402930cadd0f8 | 5c3bcec385f59edcc04490d1db95fdb8673bf612 | donald@example.com | 1 | - +----+----------+----------------------------------+------------------------------------------+--------------------+-----------+ - 4 rows in set (0.00 sec) - -The database now contains four users with different usernames, emails and -statuses. The next part will focus on how to authenticate one of these users + $ mysql> select * from acme_users; + +----+----------+------+------------------------------------------+--------------------+-----------+ + | id | username | salt | password | email | is_active | + +----+----------+------+------------------------------------------+--------------------+-----------+ + | 1 | admin | | d033e22ae348aeb5660fc2140aec35850c4da997 | admin@example.com | 1 | + +----+----------+------+------------------------------------------+--------------------+-----------+ + +.. tip:: + + To generate database table from your ``User`` entity, you can run + ``php app/console doctrine:schema:update --force``. + For mor details, see Doctrine's :ref:`book-doctrine-creating-the-database-tables-schema`. + +The next part will focus on how to authenticate one of these users thanks to the Doctrine entity user provider and a couple of lines of configuration. @@ -323,9 +316,8 @@ entity user provider to load User entity objects from the database by using the ``username`` unique field. In other words, this tells Symfony how to fetch the user from the database before checking the password validity. -This code and configuration works but it's not enough to secure the application -for **active** users. As of now, you can still authenticate with ``maxime``. The -next section explains how to forbid non active users. +This code is not enough to secure the application for **active** users. +The next section explains how to forbid non active users. Forbid non Active Users ----------------------- @@ -355,10 +347,10 @@ For this example, the first three methods will return ``true`` whereas the // src/Acme/UserBundle/Entity/User.php namespace Acme\UserBundle\Entity; - // ... + use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Security\Core\User\AdvancedUserInterface; - class User implements AdvancedUserInterface + class User implements AdvancedUserInterface, \Serializable { // ... @@ -383,10 +375,8 @@ For this example, the first three methods will return ``true`` whereas the } } -If you try to authenticate as ``maxime``, the access is now forbidden as this -user does not have an enabled account. The next session will focus on how -to write a custom entity provider to authenticate a user with his username -or his email address. +The next session will focus on how to write a custom entity provider +to authenticate a user with his username or his email address. Authenticating Someone with a Custom Entity Provider ---------------------------------------------------- @@ -428,8 +418,7 @@ The code below shows the implementation of the ->where('u.username = :username OR u.email = :email') ->setParameter('username', $username) ->setParameter('email', $username) - ->getQuery() - ; + ->getQuery(); try { // The Query::getSingleResult() method throws an exception @@ -537,10 +526,11 @@ about in this section. authenticated at all. In this example, the ``AcmeUserBundle:User`` entity class defines a -many-to-many relationship with a ``AcmeUserBundle:Group`` entity class. A user -can be related to several groups and a group can be composed of one or -more users. As a group is also a role, the previous ``getRoles()`` method now -returns the list of related groups:: +many-to-many relationship with a ``AcmeUserBundle:Role`` entity class. +A user can be related to several roles and a role can be composed of +one or more users. The previous ``getRoles()`` method now returns +the list of related roles. +Notice that methods ``__construcotor()`` and ``getRoles()`` had changed:: // src/Acme/UserBundle/Entity/User.php namespace Acme\UserBundle\Entity; @@ -550,63 +540,46 @@ returns the list of related groups:: class User implements AdvancedUserInterface, \Serializable { + //... + /** - * @ORM\ManyToMany(targetEntity="Group", inversedBy="users") + * @ORM\ManyToMany(targetEntity="Role", inversedBy="users") * */ - private $groups; + private $roles; public function __construct() { - $this->groups = new ArrayCollection(); + $this->roles = new ArrayCollection(); } - // ... - public function getRoles() { - return $this->groups->toArray(); - } - - /** - * @see \Serializable::serialize() - */ - public function serialize() - { - return serialize(array( - $this->id, - )); + return $this->roles->toArray(); } + + // ... - /** - * @see \Serializable::unserialize() - */ - public function unserialize($serialized) - { - list ( - $this->id, - ) = unserialize($serialized); - } } -The ``AcmeUserBundle:Group`` entity class defines three table fields (``id``, +The ``AcmeUserBundle:Role`` entity class defines three table fields (``id``, ``name`` and ``role``). The unique ``role`` field contains the role name used by the Symfony security layer to secure parts of the application. The most -important thing to notice is that the ``AcmeUserBundle:Group`` entity class +important thing to notice is that the ``AcmeUserBundle:Role`` entity class extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`:: - // src/Acme/Bundle/UserBundle/Entity/Group.php + // src/Acme/Bundle/UserBundle/Entity/Role.php namespace Acme\UserBundle\Entity; - use Symfony\Component\Security\Core\Role\Role; + use Symfony\Component\Security\Core\Role\RoleInterface; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; /** - * @ORM\Table(name="acme_groups") + * @ORM\Table(name="acme_roles") * @ORM\Entity() */ - class Group extends Role + class Role implements RoleInterface { /** * @ORM\Column(name="id", type="integer") @@ -626,7 +599,7 @@ extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`:: private $role; /** - * @ORM\ManyToMany(targetEntity="User", mappedBy="groups") + * @ORM\ManyToMany(targetEntity="User", mappedBy="roles") */ private $users; @@ -635,8 +608,6 @@ extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`:: $this->users = new ArrayCollection(); } - // ... getters and setters for each property - /** * @see RoleInterface */ @@ -644,12 +615,20 @@ extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`:: { return $this->role; } + + // ... getters and setters for each property } -To improve performances and avoid lazy loading of groups when retrieving a user -from the custom entity provider, the best solution is to join the groups +.. tip:: + + To generate missing setters and getters for your ``Role`` entity, you + can use ``php app/console doctrine:generate:entities Acme/UserBundle/Entity/User``. + For more details, see Doctrine's :ref:`book-doctrine-generating-getters-and-setters`. + +To improve performances and avoid lazy loading of roles when retrieving a user +from the custom entity provider, the best solution is to join the roles relationship in the ``UserRepository::loadUserByUsername()`` method. This will -fetch the user and his associated roles / groups with a single query:: +fetch the user and his associated roles with a single query:: // src/Acme/UserBundle/Entity/UserRepository.php namespace Acme\UserBundle\Entity; @@ -662,8 +641,8 @@ fetch the user and his associated roles / groups with a single query:: { $q = $this ->createQueryBuilder('u') - ->select('u, g') - ->leftJoin('u.groups', 'g') + ->select('u, r') + ->leftJoin('u.roles', 'r') ->where('u.username = :username OR u.email = :email') ->setParameter('username', $username) ->setParameter('email', $username) @@ -675,6 +654,29 @@ fetch the user and his associated roles / groups with a single query:: // ... } -The ``QueryBuilder::leftJoin()`` method joins and fetches related groups from +The ``QueryBuilder::leftJoin()`` method joins and fetches related roles from the ``AcmeUserBundle:User`` model class when a user is retrieved with his email address or username. + +To re-generate all database tables, you can run ``php app/console doctrine:schema:update --force``. +This will also create additional table ``user_role`` what holds +relations between users and roles. +For mor details, see Doctrine's :ref:`book-doctrine-creating-the-database-tables-schema`. + +Below is an export of my ``Roles`` and ``user_role`` tables from MySQL: + +.. code-block:: bash + + $ mysql> select * from acme_users; + +----+-------+------------+ + | id | name | role | + +----+-------+------------+ + | 1 | admin | ROLE_ADMIN | + +----+-------+------------+ + + mysql> select * from user_role; + +---------+---------+ + | user_id | role_id | + +---------+---------+ + | 1 | 1 | + +---------+---------+ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy