Topic: Handling External Database access in .8
thowden
avatar
Helper
Helper
Posts: 117

Posted:
5.Jan 2007 - 10:06

Hi All

I've searched and couldn't find enough info. I am working on connecting to an external DB from PN to implement an application within the .8 framework.

Using the DBConnection class I have run up some test code like this:

Code

$pnRender = new pnRender('extdb');
$output = '<br />Testing DBConnectionStack::getConnectionInfo<br /><br />';
DBConnectionStack::init('extdb');
$output .= 'after init extdb current is = '.DBConnectionStack::getConnectionDBName().'<br />';
$output .= 'stack is :<br />';
$output .= '0stackname= '.$GLOBALS['PNRuntime']['DB'][0]['alias'].'<br />';
$output .= '1stackname= '.$GLOBALS['PNRuntime']['DB'][1]['alias'].'<br />';
$output .= '2stackname= '.$GLOBALS['PNRuntime']['DB'][2]['alias'].'<br />';
DBConnectionStack::popConnection();
$output .= 'after pop current is = '.DBConnectionStack::getConnectionDBName().'<br />';
$output .= 'stack is :<br />';
$output .= '0stackname= '.$GLOBALS['PNRuntime']['DB'][0]['alias'].'<br />';
$output .= '1stackname= '.$GLOBALS['PNRuntime']['DB'][1]['alias'].'<br />';
$output .= '2stackname= '.$GLOBALS['PNRuntime']['DB'][2]['alias'].'<br />';
DBConnectionStack::pushConnection('extdb');
$output .= 'after push extdb current is = '.DBConnectionStack::getConnectionDBName().'<br />';
$output .= 'stack is :<br />';
$output .= '0stackname= '.$GLOBALS['PNRuntime']['DB'][0]['alias'].'<br />';
$output .= '1stackname= '.$GLOBALS['PNRuntime']['DB'][1]['alias'].'<br />';
$output .= '2stackname= '.$GLOBALS['PNRuntime']['DB'][2]['alias'].'<br />';
DBConnectionStack::popConnection();
$output .= 'after pop current is = '.DBConnectionStack::getConnectionDBName().'<br />';
$output .= 'stack is :<br />';
$output .= '0stackname= '.$GLOBALS['PNRuntime']['DB'][0]['alias'].'<br />';
$output .= '1stackname= '.$GLOBALS['PNRuntime']['DB'][1]['alias'].'<br />';
$output .= '2stackname= '.$GLOBALS['PNRuntime']['DB'][2]['alias'].'<br />';
$pnRender->assign('output', $output);
return $pnRender->fetch('dliqms_user_main.htm');


which gives ouput like this

Code

Testing DBConnectionStack::getConnectionInfo

after init extdb current is = extdb
stack is :
0stackname= default
1stackname= extdb
2stackname=
after pop current is = pn8dev
stack is :
0stackname= default
1stackname=
2stackname=
after push extdb current is = extdb
stack is :
0stackname= default
1stackname= extdb
2stackname=
after pop current is = pn8dev
stack is :
0stackname= default
1stackname=
2stackname=


So I can see that the external DB is added (pushed) on to the stack automatically during 'init' and as a result of a 'push'. To return to the default PN DB I have to 'pop' the external DB prior to pnRender closing for page presentation or I get errors as PN scripts look in the external DB for the pntables.

My questions are:

#1. Is there a method to resequence the connections so that the PN DB stays on top other than using a combination of pop and push which may get messy if we have more than 2 DB's open?

#2. Is the connection meant to be persistent so that we can pop and push as often as we like until actually closing the connection?

#3. Is there a method to close a connection?

#4. Is there an explanation of the connection stack apropos PN available ?

and I guess #5... OR am I barking up the wrong tree completely?



--
cheers
Tony

Marble Bay : PostNuke Dev Work
Wren/Maxwell : PostNuke Hosting

rgasch
avatar
Professional
Professional
Posts: 573

Posted:
12.Jan 2007 - 12:06

Hi,

sorry for the late reply; I've been away/busy ...

Quote

#1. Is there a method to resequence the connections so that the PN DB stays on top other than using a combination of pop and push which may get messy if we have more than 2 DB's open?

No. As the name suggest it implements it's connections as a stack. PN then always uses the connection on top of the stack. The reason it was written that way was to allow you to do the following (in pseudocode) without having to specify a connection all the time:

Code

function module_user_doSomething()
{
    $data1 = doSomePostNukeStuff ();
    $data2 = getDataFromExternalDB ();
    $data3 = doSomeMorePostNukeStuff ();
    $finalData = combineAllData ($data, $data2, $data3);
}

where the access (including the connection push & pop) to the external DB is handled in the getDataFromExternalDB () method. This IMHO is quite a nice programming model which also encourages modularization and separation of code which goes to different databases.

Quote

#2. Is the connection meant to be persistent so that we can pop and push as often as we like until actually closing the connection?

Whether or not your connection is persistent is determined by the 'pconnect' parameter for the particular connection you're using.

Quote

#3. Is there a method to close a connection?

Not yet. I will add a $close option to the popConnection method though. I think that should do the trick since there doesn't seem to be a reason to close a connection and leave it on top of the stack.

Quote

#4. Is there an explanation of the connection stack apropos PN available ?

Not really ...

Quote

#5... OR am I barking up the wrong tree completely?

Also not really. DBConnectionStack (along with most the stuff in pnobjlib) is my creation so whatever praise or scoff you have concerning this code should be directed at me.

Greetings
R
uheweb
avatar
Professional
Professional
Posts: 817

Posted:
7.Feb 2008 - 00:26

rgasch,

Any public modules that make use of this at all? What is the best way to handle the table defines (ie, a read-only connection that shouldn't be part of the regular pntables.php)? Should I just use like a pntables-extcnnctname.php and include it whenever I make that connection?

Any hints on best practices using this tool is appreciated icon_smile Or example code - any known modules that use it?

NCM




edited by: uheweb, Feb 06, 2008 - 12:27 PM
rgasch
avatar
Professional
Professional
Posts: 573

Posted:
7.Feb 2008 - 13:13

Hi,

AFAIK there are no public modules yet using this feature. As for handling table defines, you can just add the relevant tables to the pntables.php of the module which will be querying the external database.

Greetings
R