CodeIgniter dbutil - trouble creating DB - database

Trying to make a setup for my application. However, I am having trouble getting it to create the database for me.
If I create the database manually, everything is fine.
If the database is not there, I can't do anything, and I get the following error:
A Database Error Occurred
Unable to select the specified database: my_db
Filename: core/Loader.php
Line Number: 232
I'm following the dbutil guide.
My code:
function index()
{
$db_exists = FALSE;
$this->load->dbutil();
if( $this->dbutil->database_exists( 'my_db' ) ){
$db_exists = TRUE;
}
}
As per the guide, I get my database driver running in application/config/autoload.php
$autoload['libraries'] = array( 'database', 'datamapper' );

Is your database already specified in the database.php config file?
What you will likely need to do is set your connection settings and leave the database name blank
$db['default']['database'] = '';
Then you can still autoload the database class and then load the dbutil class to check it. After checking and/or creating you would need to set the database name back in the database.php config.
Alternatively, you could remove the database class from autoload and load it on each controller needed. Then, in your installer controller you can load it without the database name using either a DSN or $config array according to the docs: http://www.codeignitor.com/user_guide/database/connecting.html
function index()
{
$dsn = 'mysql://myuser:mypass#localhost';
$this->load->database($dsn);
$this->load->dbutil();
$db_exists = FALSE;
$this->load->dbutil();
if( $this->dbutil->database_exists( 'my_db' ) ){
$db_exists = TRUE;
}
}

Related

How to load configuration after login in symfony

I have a Symfony 3.4 app that could contain multiple companies.
Each company have their own config, and their own data in db, so I need that each company have their own db.
When any user login, The application has a "core database" containing user's info.
After user login the application must change configuration for connect to user company database, that had saved in "core database".
There are necessary steps:
One user enter his user and password
the app look into central db and get user's authentication.
The app get user configuration to change.
The app change the configuration and now, sql request will be to the company's db.
It is possible? If not, is there any alternative?
Thank you so much!
You have to work here with multiple entity managers and connections and and idea is to use a subscriber that retrieves the current customer based on the user. This subscriber (or another service) will set a global variable containing the name of the entity manager.
// A subscriber (high level priority) or a service already set $customerName
// In your controller or in a service
$customerEntityManager = $this->getDoctrine()->getManager($customerName);
Check also this bundle for ideas https://github.com/vmeretail/multi-tenancy-bundle
Edit
Use and adapt to your needs this file https://github.com/vmeretail/multi-tenancy-bundle/blob/master/Service/TenantResolver.php
Here you just need to resolve tenant from the current User.
In your controller:
...
public function index(TenantResolver $tenantResolver)
{
$customerEntityManager = $this->getDoctrine()->getManager($tenantResolver->getTenant()->getName()); // or getId() or something else
}
In a service:
...
use Doctrine\Common\Persistence\ManagerRegistry;
private $tenantResolver;
private $managerRegistry;
public function__construct(TenantResolver $tenantResolver, ManagerRegistry $managerRegistry)
{
$this->tenantResolver = $tenantResolver;
$this->managerRegistry = $managerRegistry;
}
public function doSomething()
{
$this->managerRegistry->getManager($this->tenantResolver->getTenant()->getName()); // or getId() or something else
}
It's the idea, there must be something better to do here like injecting directly the right manager in the service/controller constructor.
I found the following solution for Symfony 4 and i think it should work for symfony 3.4 as well.
I created a service that copies the default entity manager in a new one connecting to another database:
namespace App\Service;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Doctrine\ORM\EntityManagerInterface;
class CustomEntityManagerHelper
{
private $em;
public function __construct(EntityManagerInterface $entityManager)
{
$this->em = $entityManager;
}
/*
* get entity manager for another database
*/
public function getManagerForDatabase($db_name): EntityManagerInterface
{
$conn = array(
'driver' => 'pdo_mysql',
'user' => 'root',
'password' => 'mypass',
'dbname' => $db_name
);
return \Doctrine\ORM\EntityManager::create(
$conn,
$this->em->getConfiguration(),
$this->em->getEventManager()
);
}
}
Until now it was very easy but the Repository class still uses the default entitymanager. So i added a method setEntityManager to the Repositories:
<?php
namespace App\Repository;
use App\Entity\Product;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
class ProductRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Product::class);
}
public function setEntityManager(EntityManagerInterface $entityManager): self
{
$this->_em = $entityManager;
return $this;
}
// custom methods here
}
Now i can use the custom entity manager AND set that to the repository:
use App\Service\CustomEntityManagerHelper;
// ...
/**
* #Route("/products", name="app_product", methods={"GET"})
*/
public function index(CustomEntityManagerHelper $helper): Response
{
$myManager = $helper->getManagerForDatabase($this->getUser()->getDatabaseName());
$products = $myManager->getRepository('App:Product')
->setEntityManager($myManager) // IMPORTANT!
->findAll();
return $this->render('product/index.html.twig', [
'products' => $products
]);
}

the database file cannot be found. check the path to the database. data source in windows phone 7

i have created the data base in windows phone 7 and it works me fine
after rebuild the application it says that
The database file cannot be found. Check the path to the database. [ Data Source = \Applications\Data\6157CB94-31D3-4E6F-BFC3-78BE1549C10A\Data\IsolatedStore\amit.sdf ]
my code for db string is
` private const string Con_String = #"isostore:/amit.sdf";`
how to solve this pls give me any suggestion to solve this problem
Have you checked this sample How to create a basic local database app for Windows Phone?
they use this path for create the db
//Specify the connection string as a static, used in main page and app.xaml.
public static string DBConnectionString = "Data Source=isostore:/ToDo.sdf";
and also don't forget to check if the db exists
//Create the database if it does not exist.
using (ToDoDataContext db = new ToDoDataContext(ToDoDataContext.DBConnectionString))
{
if (db.DatabaseExists() == false)
{
//Create the database
db.CreateDatabase();
}
}

Yii Database Failover Fail Over

I am currently working on a project for which we have chosen Yii as our new Framework of choice. I am currently trying to figure out the best way to implement some sort of automatic database fail over in Yii.
I am currently trying to over-ride the CDbConnection class - Open function. I am not sure if I am headed in the right direction though.
Basically what I am looking to do is check a DB connection and if it fails connect to another DB. Simple concept I am just not sure where to put it. I know there are better ways to do this by using mysqlnd_ms but it is not setup on the servers we are using yet so have to come up with a way to do this in Yii. Any help is greatly appreciated. -DA
This is what I have so far Thoughts?
class DaDbConnection extends CDbConnection{
public $dbConnectTries = 6;
public $numDatabases = 3;
private $_tries =0;
private $_db = 1;
/*
* Extends CDbConnection open() method
* Tries to connect to database connections setup in config/main.php up to
* the value of $dbConnectionTries or a connection is successful
* #throws CException If it can not connect to any DBs
*/
protected function open()
{
try{
//try to connect to the default DB
parent::open();
}catch(Exception $e){
if($this->_tries < $this->dbConnectTries){
//If there aren't anymore DBs to try we must start over from the first
if($this->_db >= $this->numDatabases){
$tryDb = 'db';
$this->_db = 0;
}else{
$tryDb = 'db'.$this->_db;
}
$this->_db++;
$this->_tries++;
$this->connectionString = Yii::app()->$tryDb->connectionString;
$this->username = Yii::app()->$tryDb->username;
$this->password = Yii::app()->$tryDb->password;
$this->open();
}else{
throw new CDbException('Could Not Connect to a DB.');
}
}
}
}
Sounds like the right direction. I'm not sure Yii has anything built in for that, please someone correct me if I'm wrong.
What I'd probably try, just off the top of my head, is defining the two databases in my main config file but with my own custom class;
return array(
...
'components' => array(
'db' => array(
'connectionString' => 'mysql:host=dbserver1;dbname=my1db',
...
'class' => 'MyCDbConnection',
...
),
'dbBackup' => array(
'connectionString' => 'mysql:host=dbserver2;dbname=my2db',
...
'class' => 'MyCDbConnection',
),
...
),
);
I'd then make the MyCDbConnection class extend the main CDbConnection class but include my own open method, as you suggested.
It is possible to switch between databases quite easily (e.g. Multiple-database support in Yii), and I'm sure you could integrate that into the try/catch of opening the db connection in your custom open() method?

CakePHP Logging to Live DB During Unit Testing

I'm using DB logging in Cake 2.1, which works great.
The problem I'm having is when running Unit Tests, all logs are still getting sent to the live db rather than the test database.
All other db interactions go to test, except logging.
I do have a log fixture created and imported into the test case.
Here's my Database logger (/Lib/Log/Engine/DatabaseLogger.php)
App::uses('CakeLogInterface', 'Log');
class DatabaseLogger implements CakeLogInterface
{
public function __construct($options = array() )
{
App::import('Model', 'Log');
$this->Log = new Log;
}
public function write($type, $message)
{
$this->Log->create();
$log['type'] = ucfirst($type);
$log['date'] = date('Y-m-d H:i:s');
$log['message'] = $message;
return $this->Log->save($log);
}
}
I'm sure I'm missing some basic setting here but I can't figure this out for the life of me.
Well, in my case the problem was caused because of a bad initialization of a constructor.
You can check the update solution here:
How to choose the test DB cakePHP testing
And here:
How to override model's constructor correctly in CakePHP

zend framework: models cannot interact with database on the server

I have just finished my first site built with zend framework and all works great on my local machine.
Then I uploaded it to the server (godaddy) and all works except any connection my models do with the database. I have made a connetion to the database with regular PDO with the credentials in my application.ini and it worked, and I can interact with the model if it's not returning anything from the database (and again all the models work great on my local machine).
My models looks like this:
class Default_Model_picture extends Zend_Db_Table_Abstract
{
protected $_name = 'pictures';
protected $_primary = 'id';
public function getPicturesByCategory($category)
{
$query = $this->select()->from(array('pictures'), array(
'pictures.id', 'pictures.pic_name', 'pictures.pic_desc',
'pictures.pic_category', 'pictures.pic_date_added',
'pictures.pic_larger', 'pictures.pic_url'));
$query->where('pic_category = ?', $category);
$query->order('pic_date_added ASC');
$result = $this->fetchAll($query);
return $result;
}
}
this is an example for a model, obviously i did not added lots of methods.
i have no idea what to do next.
I am assuming you set up the db connection correctly into $db. Afterwards you must set it as the default adapter for Zend_Db_Table.
Zend_Db_Table::setDefaultAdapter($db);
I am just assuming this is what went wrong. But it is a common problem, so I decided to go ahead and answer anyway.
Since your script works fine on your local machine, the first thing I check is if you have got the database connection params setup correctly in your application.ini
Try to write a test script that uses the pdo functions on itself (without zend framework). see if you get any errors at all
try {
$dbh = new PDO('mysql:host=YOURHOST;dbname=YOURDBNAME', $YOURUSERNAME, $YOURPASSWORD);
foreach($dbh->query('SELECT * from FOO') as $row) {
print_r($row);
}
$dbh = null;
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}

Resources