Joomla Asked by Irata on September 5, 2021
I have a need to connect to a data source on an old unix box via ODBC, but I don’t seem to be getting far and I can’t find any examples to help me.
I have started with https://docs.joomla.org/Connecting_to_an_external_database and set up the following details:
$option['driver'] = 'pdo'; // Database driver name
$option['host'] = 'nnn.nnn.nnn.nnn:nnnn'; // Database host name
$options['dsn'] = 'Fred';
$option['user'] = 'Barney'; // User for database authentication
$option['password'] = 'Wilma'; // Password for database authentication
$option['database'] = 'dbname'; // Database name
$option['prefix'] = ''; // Database prefix (may be empty)
$dbx = JDatabaseDriver::getInstance($option);
With that configuration, I get an error message of:
Cannot instantiate abstract class JDatabaseDriverPdo E:wwwbedrocklibrariesjoomladatabasedriver.php:313
This happens because driver.php
takes the value ‘pdo’ from $option['driver'] = 'pdo';
and appends it to a class of JDatabaseDriver to be found in librariesdatabasedriverpdo.php
which is an abstract class the extends JDatabaseDriver
hence the message. It is the only abstract class in /driver
. If I replace ‘pdo’ with ‘odbc’, I get a message to say it can’t load the database driver which will be because the class JDatabaseDriverOdbc is not found.
When I look at librariesdatabasedriverpdo.php
, I can see that ‘odbc’ is the default if no other driver is specified and further down I can see the connection string set up for ‘odbc’ so it looks like it is supported.
public function __construct($options)
{
// Get some basic values from the options.
$options['driver'] = (isset($options['driver'])) ? $options['driver'] : 'odbc';
$options['dsn'] = (isset($options['dsn'])) ? $options['dsn'] : '';
$options['host'] = (isset($options['host'])) ? $options['host'] : 'localhost';
...
// Find the correct PDO DSN Format to use:
switch ($this->options['driver'])
{
..
case 'odbc':
$format = 'odbc:DSN=#DSN#;UID:#USER#;PWD=#PASSWORD#';
$replace = array('#DSN#', '#USER#', '#PASSWORD#');
$with = array($this->options['dsn'], $this->options['user'], $this->options['password']);
It seems to me that $option['driver'] =
has two different uses depending on where it is used, as either a suffix to build a class name or as a switch to set the connection string.
I have also tried to use the class directly with
`$option['driver'] = 'odbc';
...
$dbx = JDatabaseDriverPdo::getInstance($option);
however that still tries to find a class of JDatabaseDriverOdbc
from driver.php
I really could use some pointers in the right direction or an example of ODBC in use.
Some hours later…
Looking at the code in driver.php and some of the data base formats in librariesdatabasedriver
it would appear I need to create a new class that extends JDatabaseDriverPdo, eg. class JDatabaseDriverOdbc extends JDatabaseDriverPdo
and make that available to my code. So I think the Joomla answer is yes you can do it if you write your own connector.
Although I have had to put this work aside for the time being I wanted to provide some closure to this question.
The last part of my original post is approximately what was required, I had to create a /joomla/database/odbc.php
which I created from copying from one of the existing drivers and change the relevant references to 'odbc', and that extended the JDatabaseDriverPdo class.
That got me past the error message in the original Question but then I hit a problem with the next line, $query = $dbx->getQuery(true);
due to either an error in the core code or my lack of understanding but it is worth mentioning here if anyone else finds this post.
The getQuery command calls this piece of code in /joomla/database/driver.php
public function getQuery($new = false)
{
if ($new)
{
// Derive the class name from the driver.
$class = 'JDatabaseQuery' . ucfirst($this->name);
// Make sure we have a query class for this driver.
if (!class_exists($class))
{
// If it doesn't exist we are at an impasse so throw an exception.
throw new JDatabaseExceptionUnsupported('Database Query Class not found.');
}
return new $class($this);
}
else
{
return $this->sql;
}
}
However $this->name
which creates the $class is not picking up the value set in the JDatabaseDriverXxxx for $this-name
therefore it always falls out the bottom returning a value of mysqli
.
My resolution was to copy this function into my joomla/database/odbc.php so that it would receive the correct value of $this->name
, odbc.
The lack of being able to find a suitable linux ODBC driver to work with the target has put this stage of the project on hold for the time being.
Correct answer by Irata on September 5, 2021
1 Asked on January 6, 2022 by user3533235
1 Asked on December 30, 2021 by mano-meter
2 Asked on December 19, 2021
2 Asked on December 11, 2021
0 Asked on December 11, 2021 by sandro-antonucci
1 Asked on November 27, 2021
error handling extensions joomla 3 x server response time update
2 Asked on November 27, 2021 by lovntola
2 Asked on November 25, 2021
1 Asked on November 20, 2021
1 Asked on November 19, 2021 by matthiasdunkel
1 Asked on November 5, 2021 by fruit_alchemist
2 Asked on September 5, 2021 by user2363969
3 Asked on September 5, 2021 by jamesmandatory
0 Asked on September 5, 2021 by kaballo
1 Asked on September 5, 2021 by gart
1 Asked on September 5, 2021 by user1616338
1 Asked on September 5, 2021 by ygiorgos
2 Asked on September 5, 2021 by okisan
Get help from others!
Recent Answers
Recent Questions
© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP