I try to manage 2 databases in my symfony3 installation.
I want to have two connections and not two managers because the second database is just for loading external data and not to use with the orm.
my conf.yml
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
dbsync:
driver: pdo_mysql
host: "%database_sync_host%"
port: "%database_sync_port%"
dbname: "%database_sync_name%"
user: "%database_sync_user%"
password: "%database_sync_password%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
In a Controller i can use my second database for sql select with :
...->getManager()->getConnection('dbsync');
But I would like to use it in a service and I don't know how to use getConnection('dbsync') in this case ...
my service MajUsers.php
<?php
namespace EntBundle\Service;
use Doctrine\ORM\EntityManager;
use EntBundle\Entity\User\User;
class MajUsers {
private $em;
/**
* #param EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->em = $em;
}
public function runUpdate()
{
$conn = $this->em->getManager('dbsync')->getConnection('dbsync');
$personnels_sync = $conn->fetchAll("SELECT * FROM xxxxx WHERE etat = 1 AND login !='' ORDER BY xxx, yyyyLIMIT 10");
.....
.....
}
}
my service.yml
ent.maj_users:
class: EntBundle\Service\MajUsers
arguments:
- '#doctrine.orm.entity_manager'
I use the em for some repository in my code and it's working fine but the getConnection('dbsync') part is not working.
I suppose that I need to inject a container (doctrine?) in the __construct but I don't know witch one, all my test failed :c/
Thanks for any help
UPDATED:
In your __construct type hint against \Doctrine\DBAL\Connection and define service like follows:
ent.maj_users:
class: EntBundle\Service\MajUsers
arguments:
- '#doctrine.dbal.dbsync_connection'
Thanks to #Cerad for pointing out my mistake
OLD:
You can find it in docs here
Basically, you should define service like this:
ent.maj_users:
class: EntBundle\Service\MajUsers
arguments:
- '#doctrine.orm.dbsync_entity_manager'
Related
I am usgin Laravel 9 test tool.
I dropped the database, recreated and imported using SQL statement.
With all the database set, I used the browser to log in with my user, and everything worded just fine.
Then I ran the php artisan test --filter HomeControllerTest and all the database was deleted! HOW COME?????
here is the test code:
<?php
namespace Tests\Feature;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class HomeControllerTest extends TestCase
{
use RefreshDatabase;
public function test_home_view_requires_authentication()
{
// Log in as the created user and try to access the home page
$response = $this->postJson('/login', [
'email' => 'test#example.com',
'password' => 'password',
]);
$response->assertStatus(302);
$response->assertRedirect(route('home'));
$response = $this->get(route('home'));
$response->assertOk();
$response->assertViewIs('home');
$response->assertViewHasAll(['corretora', 'propostas']);
}
/**
* Test if home page can be accessed by a guest user.
*
* #return void
*/
public function test_home_view_requires_guest()
{
$response = $this->get(route('home'));
$response->assertStatus(302);
$response->assertRedirect(route('login'));
}
}
Why my database was deleted? i do have a backup, of course, but should test do it?
There was not an error. The use of the use RefreshDatabase; do the erasing.
I remove it and now is working good.
I already found few informations like
Symfony2 access private services in tests
or
Replace Symfony service in tests for php 7.2
But I dont know why its not working.
I have an autowiring service.
class MailService {
public function __construct(\Swift_Mailer $mailer, Environment $twig)
{
$this->mailer = $mailer;
$this->twig = $twig;
}
}
config/services_test.yaml
services:
# default configuration for services in *this* file
_defaults:
#autowire: true # Automatically injects dependencies in your services.
#autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: true
test.swiftmailer.transport: '#Swift_Mailer'
And when I try to replace.
$mailer = $this->getMockBuilder(\Swift_Mailer::class)
->disableOriginalConstructor()
->getMock();
$mailer->expects($this->once())->method('send')->willReturn(1);
self::$container->set('swiftmailer.mailer.default', $mailer);
self::$container->set('swiftmailer.default', $mailer);
self::$container->set('swiftmailer.mailers', [$mailer]);
But I dont know why its not working.
Any ideas? :)
I have created a new Grails 3.1.4 angular project along with a few domain objects and controllers extending RestfulController. I have created the Integration test below. When I run grails test-app -integration I get the error
java.lang.IllegalStateException: No transactionManager was specified. Using #Transactional or #Rollback requires a valid configured transaction manager. If you are running in a unit test ensure the test has been properly configured and that you run the test suite not an individual test method.
at grails.transaction.GrailsTransactionTemplate.<init>(GrailsTransactionTemplate.groovy:60)
at com.waldoware.invoicer.BillingEntityRestControllerIntegrationSpec.$tt__$spock_feature_0_0(BillingEntityRestControllerIntegrationSpec.groovy:29)
at com.waldoware.invoicer.BillingEntityRestControllerIntegrationSpec.test all entities_closure2(BillingEntityRestControllerIntegrationSpec.groovy)
at groovy.lang.Closure.call(Closure.java:426)
at groovy.lang.Closure.call(Closure.java:442)
at grails.transaction.GrailsTransactionTemplate$1.doInTransaction(GrailsTransactionTemplate.groovy:70)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.executeAndRollback(GrailsTransactionTemplate.groovy:67)
at com.waldoware.invoicer.BillingEntityRestControllerIntegrationSpec.test all entities(BillingEntityRestControllerIntegrationSpec.groovy)
Test class:
package com.waldoware.invoicer
import grails.test.mixin.integration.Integration
import grails.transaction.*
import spock.lang.*
#Integration
#Rollback
class BillingEntityRestControllerIntegrationSpec extends Specification {
def setupData() {
def biller = new BillingEntity()
biller.with {
companyName = "Acme, Inc."
}
def ledger = new Ledger(name: "My Ledger", billingEntity: biller).save(failOnError: true, flush: true)
}
void 'test all entities'() {
when:
setupData()
new BillingEntityRestController().index()
then:
response.contentType == 'application/json;charset=UTF-8'
response.status == HttpServletResponse.SC_OK
response.text == "[{}]"
}
}
I do have a datasource set up in application.yml:
environments:
development:
dataSource:
dbCreate: none
url: jdbc:h2:./devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
test:
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
production:
dataSource:
dbCreate: update
url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
properties:
jmxEnabled: true
initialSize: 5
maxActive: 50
minIdle: 5
maxIdle: 25
maxWait: 10000
maxAge: 600000
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1
validationQueryTimeout: 3
validationInterval: 15000
testOnBorrow: true
testWhileIdle: true
testOnReturn: false
jdbcInterceptors: ConnectionState
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
This can help if you do not have a persistence plugin configured in your build.gradle that sets up a transaction manager (examples include hibernate4, mongodb, neo4j etc. or you do not have a dataSource configured in grails-app/conf/application.yml.
If this is the case, simply remove the #Rollback annotation and that should fix the problem.
Ran across this while troubleshooting my own integration test. I resolved my problem by deleting the out directory.
delete project-folder/out/
Now you'll also need to clean and rebuild a war file. This must run some extra steps in the build process and resolves some issues
./grailsw clean
./grailsw war
Now when you run your tests you shouldn't see the error message.
How I can access to DB from bootstrap using official DoctrineORMModule ?
for example, in my controller:
$allusers = $this->getEntityManager()->getRepository('Users\Entity\User')->findAll();
but I can't access to getEntityManager() and getRepository() when i'm in bootstrap.
I follow up this guide: http://ivangospodinow.com/zend-framework-2-acl-setup-in-5-minutes-tutorial/
but I'm stuck when trying to connect to db
public function getDbRoles(MvcEvent $e){
// I take it that your adapter is already configured
$dbAdapter = $e->getApplication()->getServiceManager()->get('Zend\Db\Adapter\Adapter');
...
}
Using doctrine you would need to fetch the EntityManager with
$entityManager = $e->getApplication()->getServiceManager()->get('Doctrine\ORM\EntityManager');
//in my case:
var_dump( $entityManager->getRepository('Users\Entity\User') );
My question is related to PassportJS - Using multiple passports within Express application topic.
So as long as I already have two separate passport instances, I realized that they both share the same cookie, created here:
application.use(session({ secret: 'my secret cookie', key: 'usid' }));
I can add one more cookie with different name using this:
app.use(connect.session({ secret: 'keyboard cat', key: 'rsid' }))
However, it is not clear to me how to instruct each passport to use its own cookie.
I figured out temporary solution for passport 0.4.0 via
passport._key = passport._sm._key = 'customPassportSessionKey'
You can solve it by making from the router and not from the app. I've solved the same issue by developing something like an AuthBuilder which receives certain parameters, each instance generates a new passport that way.
class AuthBuilderService {
constructor() {
this.passport = new Passport();
this.registerSerializers(); // Multiple serializers
this.registerStrategies(); // Multiple strategies
}
Then you can register multiple routers with the same passport and key (or just one) by calling the authbuilder.addRouter(...)
addRouter(router, loginFileName, failureUrl, successUrl) {
router.use('/login', express.static(`${__dirname}/../views/whatever`, {
index: loginFileName,
fallthrough: true,
}));
router.use(session({
secret: 'any secret',
key: (_isRouterA()) ? 'a' : 'b',
resave: true,
saveUninitialized: true
}));
router.use(this.passport.initialize());
router.use(this.passport.session());
this._configureRouter(router, failureUrl, successUrl); // There I'm handling login, logout and some middleware.
return this;
}
From the routers you want to protect:
routerUsers_1.get('something_1', method)
routerUsers_2.get('something_2', method2)
let authBuilder = new AuthBuilderService();
authBuilder.addRouter(routerUsers_1, 'login_users_vip.html', '/path/failure_vip/', '/path/success_vip');
authBuilder.addRouter(routerUsers_2, 'login_users.html', '/path/failure/', '/path/success');
routerAdmins.get('something', methodAdmin)
new AuthBuilderService().addRouter(routerAdmins, 'login_admins.html', '/path2/failure/', '/path2/success');
Then express app just use each router.
app.use('path-client-vip', routerUsers_1)
app.use('path-client', routerUsers_2)
app.use('path-admin', routerAdmin)
I'm working with 2 webapps (with different users, logins and content) in the same express app server, each webapp uses different instances of this AuthBuilderService for multiple routers using different passport, sessions, strategies and serializers between each AuthBuilderService instance.
Hope it will help somebody.