Can I integrate a custom PDO wrapper in Laravel

My guys are at work and I am trying to develop a web application using Laravel with a Vertica database. The only problem is that as soon as you use bindValue or bindParam with that particular database, PHP crashes with a segmentation fault. So I wrote a PDO wrapper class that redirects calls to the PHP_ODBC module and it actually works. Now I was wondering how to integrate it into Laravel, if even possible.

+1


source to share


1 answer


So, after a lot of trial and error, my colleagues and I managed to get things right. The hardest part turned out to be to assemble the wrapper. Assuming you have it, here's what you need to do to integrate it into Laravel (those steps are for Laravel 5.1 by the way). Also, my skin is called PDOVertica, so whenever you see this term you must substitute it for your own skin name.

1) Copy the shell file to the following folder:

vendor/laravel/framework/src/Illuminate/Database/Connectors

      

2) Then you need to change several files:

vendor \ laravel \ framework \ src \ light \ database \ connection.php

namespace Illuminate\Database;

use PDO;
use PDOVertica; //Add this line
use Closure;
use DateTime;
...
//Change the type of the first parameter to PDOVertica as follow

public function __construct(PDOVertica $pdo, $database = '', $tablePrefix = '', array $config = [])

      

vendor \ Laravel \ Framework \ SRC \ Light \ Database \ Connectors \ Connector.php

namespace Illuminate\Database\Connectors;
include 'clsPDOVertica.php'; //Add this line
use PDO;
use PDOVertica; //Add this line
...

public function createConnection($dsn, array $config, array $options)
{
    $username = array_get($config, 'username');
    $password = array_get($config, 'password');

    //Modify the return value to return your wrapper
    return new PDOVertica($dsn, $username, $password, $options);
}

      



vendor \ Laravel \ Framework \ SRC \ Light \ Database \ Connectors \ PostgresConnector.php

protected function getDsn(array $config)
{

    extract($config);

    $host = isset($host) ? "Server={$host};" : '';

    // Modify this line so that it creates the Vertica DSN. 
    // It should look something like this.
    $dsn = "Driver=/opt/vertica/lib64/libverticaodbc.so;{$host}Database={$database}";

    if (isset($config['port'])) {
        $dsn .= ";port={$port}";
    }

    if (isset($config['sslmode'])) {
        $dsn .= ";sslmode={$sslmode}";
    }

        return $dsn;
}

      

vendor \ laravel \ framework \ src \ light \ database \ Connectors \ ConnectionFactory.php

namespace Illuminate\Database\Connectors;

use PDO;
use PDOVertica; //Add this line
use InvalidArgumentException;
...

// Modify the header of this function so that the $connection parameter
// is of type PDOVertica
protected function createConnection($driver, PDOVertica $connection, $database, $prefix = '', array $config = [])
{
    if ($this->container->bound($key = "db.connection.{$driver}")) {
        return $this->container->make($key, [$connection, $database, $prefix, $config]);
    }

    switch ($driver) {
        case 'mysql':
            return new MySqlConnection($connection, $database, $prefix, $config);

        case 'pgsql':
            return new PostgresConnection($connection, $database, $prefix, $config);

        case 'sqlite':
            return new SQLiteConnection($connection, $database, $prefix, $config);

        case 'sqlsrv':
            return new SqlServerConnection($connection, $database, $prefix, $config);
    }

    throw new InvalidArgumentException("Unsupported driver [$driver]");
}

      

3) Once the files have been modified correctly, all you need to do is configure Laravel correctly to use your custom connection by modifying the following file:

config / database.php

/*   |--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/

'default' => 'vertica',

...

'connections' => [

    'sqlite' => [
        'driver'   => 'sqlite',
        'database' => storage_path('database.sqlite'),
        'prefix'   => '',
    ],

    'mysql' => [
        'driver'    => 'mysql',
        'host'      => env('DB_HOST', ''),
        'database'  => env('DB_DATABASE', ''),
        'username'  => env('DB_USERNAME', ''),
        'password'  => env('DB_PASSWORD', ''),
        'port'      => '5433h',
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
        'strict'    => false,
    ],

    //This is our custom connection
    'vertica' => [
        'driver'    => 'pgsql',
        'host'      => env('DB_HOST', '192.168.1.1'),
        'database'  => env('DB_DATABASE', 'mydb'),
        'username'  => env('DB_USERNAME', 'myuser'),
        'password'  => env('DB_PASSWORD', 'mypassword'),
        'port'      => '5433',
        'charset'  => 'utf8',
        'schema'  => 'myschema',
    ],

    'pgsql' => [
        'driver'   => 'pgsql',
        'host'     => env('DB_HOST', 'localhost'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'port'      => '5433',
        'charset'  => 'utf8',
        'prefix'   => '',
        'schema'   => 'public',
    ],

    'sqlsrv' => [
        'driver'   => 'sqlsrv',
        'host'     => env('DB_HOST', 'localhost'),
        'database' => env('DB_DATABASE', 'forge'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'prefix'   => '',
    ],

],

      

As far as I could tell, these were all the steps needed to get Laravel to connect to the Vertica database without crashing. Hope this helps.

+3


source







All Articles