Jump to content

Specifying a DBMS at Runtime


Jesdisciple

Recommended Posts

I'm developing an AJAX database application, and I want it to be at least pseudo-cross-platform. I'm trying to implement it in multiple database managers so the developer can choose which DBMS to use upon "installation."Yes, I'm trying to use an installer of sorts for this. It's a Web page, but it's only for the developer's one-time (per installation) use. The developer selects a link to indicate which DBMS he would prefer to use and I set up a database on it... Or that's the idea.I get stuck where I have to act on the data I've obtained and tell PHP that I want to speak to, e.g., Derby. Once the DBMS starts to listen, I can take it from there. Here's the page:

<?phpfunction selfURL(){// from [url="http://dev.kanngard.net/Permalinks/ID_20050507183447.html"]http://dev.kanngard.net/Permalinks/ID_20050507183447.html[/url]	$s = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";	$protocol = strleft(strtolower($_SERVER["SERVER_PROTOCOL"]), "/").$s;	$port = ($_SERVER["SERVER_PORT"] == "80") ? "" : (":" . $_SERVER["SERVER_PORT"]);	return $protocol . "://" . $_SERVER['SERVER_NAME'] . $port . $_SERVER['REQUEST_URI'];}function strleft($s1, $s2){	return substr($s1, 0, strpos($s1, $s2));}function appendPOST($query, array $newParams){	$newParams = array_unshift($query, $newParams);	preg_replace('/^(.*)&++$/', '$1', $query);	return implode('&', $newParams);}function appendGET($url, array $newParams){	$question = strpos($url, '?');	if($question !== false){		$hash = strpos($url, '#');		$query = appendPOST(substr($url, $question + 1, ($hash !== false ? $hash : strlen($url))), $newParams);		$url = substr($url, 0, $question);	}else{		$query = implode('&', $newParams);	}	return $url . '?' . $query;}$manager = &$_REQUEST['database'];if(isset($manager)){	switch($manager){		case 'MySQL': case 'Apache Derby':			$old = file_exists('config.xml');			fwrite(				fopen('config.xml', 'a+b'),				($old ? '' : '<?xml version="1.0" encoding="ISO-8859-1"?>' . PHP_EOL) .				'<database>' . PHP_EOL .				'	<manager>' . $manager . '</manager>' . PHP_EOL .				'	<created>' . time() . '</created>' . PHP_EOL .				'</database>' . PHP_EOL			);			break;/* To be supported.		case 'Oracle':						break;*/	}}else{	?><html>	<head>		<title>Installation: Please Specify a Database Manager</title>	</head>	<body>		The below table lists all supported database managers.  Please select		one which this PHP installation can access and onto which you wish to		install.		<table width="100%" border="1">			<thead>				<tr>					<th colspan="2">						Supported Databases					</th>				</tr>			</thead>			<tbody>				<tr>					<td align="center">						<a href="<?php echo appendGET(selfURL(), array('database=MySQL')); ?>">MySQL</a>					</td>					<td align="center">						<a href="<?php echo appendGET(selfURL(), array('database=Apache Derby')); ?>">Apache Derby</a>					</td><!-- To be supported					<td align="center">						<a href="<?php echo appendGET(selfURL(), array('database=Oracle')); ?>">Oracle</a>					</td>-->				</tr>			</tbody>		</table>	</body></html>	<?php	}?>

So does anyone know of a function for this? Thanks!

Link to comment
Share on other sites

If you can use PEAR's MDB2, you can bundle it with your app with all drivers, and upon installation, remove the stuff that is not needed, and adjust a few string variables that will present the database info.

Link to comment
Share on other sites

If you don't use an existing database abstraction class then you'll need to make your own and implement it for each database you want to use. So you would define something like a class interface with certain methods, something like this:

class database{  function query...  function get_row...  function get_last_id...}

etc, then you would need to implement those methods for each database type. When you figure out which database they want to use you would just include the appropriate class definition file for that database.More about interfaces:http://www.php.net/manual/en/language.oop5.interfaces.php

Link to comment
Share on other sites

Oh, wow... I think my project just got a lot bigger, lol.I finally got PEAR and MDB2 installed (after increasing the memory_limit in php.ini for MDB2). I guess I should install all applicable "optional features" (drivers)... I see MySQL and Oracle listed but no Derby; does that mean I have to abandon that implementation or write the driver myself?Thanks!

Link to comment
Share on other sites

I'm betting MDB2's maintainers would love it if you can create a driver for Derby and contribute it to them and they'll be sure to credit you as a helper or developer if you fix bugs along the way as reported.And besides, relying on a third party for better MySQL(i), MS SQL and Oracle support is, I think, far better, as those databse engines are more used than Derby, and because of all that, there'll be less bugs to fix in the future.

Link to comment
Share on other sites

I'm betting MDB2's maintainers would love it if you can create a driver for Derby and contribute it to them and they'll be sure to credit you as a helper or developer if you fix bugs along the way as reported.
Well, I wonder if you could help me understand this article? (How) should I apply this to my project?
And besides, relying on a third party for better MySQL(i), MS SQL and Oracle support is, I think, far better, as those databse engines are more used than Derby, and because of all that, there'll be less bugs to fix in the future.
Yes, I give Derby the lowest priority of the three, but I still want to make it compatible - and I was hoping it would be much simpler than this.
Link to comment
Share on other sites

Well, I wonder if you could help me understand this article? (How) should I apply this to my project?Yes, I give Derby the lowest priority of the three, but I still want to make it compatible - and I was hoping it would be much simpler than this.
As far as I can see, Derby is used via ODBC. And PHP already supports this. You can use PHP's ODBC functions to try to implement such a driver for MDB2.What I find curious now that you mentioned it is that PEAR's DB, a predecessor to MDB2, implements this AND it says it does. If MDB2 does too, it sure doesn't say so in the documentation.You could use DB's code as a start to creating an MDB2 driver. This article explains how to migrate from DB to MDB2, which may provide a good start for you into actually understanding what you need to change.If Derby and Access are with a higher priority, you may consider using DB instead of MDB2 altogether, but be aware that MDB2 implements more database compatibility features (i.e. it normalizes queries better) than DB2.
Link to comment
Share on other sites

As far as I can see, Derby is used via ODBC. And PHP already supports this. You can use PHP's ODBC functions to try to implement such a driver for MDB2.
Yeah, that's what I was thinking... Except I don't know the first thing about how to build a driver, and now I wonder if I need to.
What I find curious now that you mentioned it is that PEAR's DB, a predecessor to MDB2, implements this AND it says it does. If MDB2 does too, it sure doesn't say so in the documentation.
I think the answer is right here:
In addition to normal ODBC support, the Unified ODBC functions in PHP allow you to access several databases that have borrowed the semantics of the ODBC API to implement their own API. Instead of maintaining multiple database drivers that were all nearly identical, these drivers have been unified into a single set of ODBC functions.
I guess DB was before this, and MDB2 finds ODBC drivers unnecessary.
You could use DB's code as a start to creating an MDB2 driver. This article explains how to migrate from DB to MDB2, which may provide a good start for you into actually understanding what you need to change.
What would be the practical difference between using the ODBC functions and using a Derby driver?
If Derby and Access are with a higher priority, you may consider using DB instead of MDB2 altogether, but be aware that MDB2 implements more database compatibility features (i.e. it normalizes queries better) than DB2.
I don't have Access... Doesn't it only come as part of MS Office (for a price)?
Link to comment
Share on other sites

I don't have Access... Doesn't it only come as part of MS Office (for a price)?
Yes, but that was not the point. ODBC is a unified method for accessing databases. Derby and Access both use it, so if you have ODBC support, you support both of those databases.
Yeah, that's what I was thinking... Except I don't know the first thing about how to build a driver, and now I wonder if I need to.
If you want Derby and Access support, you'll either have to, or use PEAR DB instead of PEAR MDB2. Whether you really need to - that's for you to decide. I wouldn't put myself on pressure for it though. Requiring any other DB engine doesn't seem like it would do much harm.
I think the answer is right here:I guess DB was before this, and MDB2 finds ODBC drivers unnecessary.
I don't know about that. MDB2 implements all databases, and the ODBC functions just implement the ODBC databases. The ODBC functions don't allow you MySQL/Oracle/MS SQL acess after all. Maybe they never got anyone requesting ODBC implementation in MDB2? I don't know... you can ask the developers yourself.
What would be the practical difference between using the ODBC functions and using a Derby driver?
There isn't. Derby implements ODBC, so using ODBC means you're also using Derby. A native Derby extension (*.dll) would likely be a little faster though. But there isn't, so ODBC remains the next best option.
Link to comment
Share on other sites

I'm confused... Isn't the PHP set of ODBC functions equivalent to a driver for all ODBC databases? If so, why do I need to write a driver or use DB?

Link to comment
Share on other sites

I'm confused... Isn't the PHP set of ODBC functions equivalent to a driver for all ODBC databases? If so, why do I need to write a driver or use DB?
Yes, the set of ODBC functions is equivalent for all ODBC databases. However, MDB2 doesn't include an ODBC driver. That is, it doesn't map the ODBC function to its own functions.The idea behind MDB2 and DB alike is that you specify the dabase you want to use and its credidentials at the top, and do everything else in the same way for all databases. For example:
<?phprequire 'MDB2.php';require 'config.php';//$dsn is defined there$mdb2 =& MDB2::factory($dsn);$res =& $mdb2->query('SELECT * FROM clients');//Rest of the code here?>

In this example, $dns can be anything like

'pgsql://usr:pw@localhost/dbnam''mysql://usr:pw@localhost/dbnam''oracle://usr:pw@localhost/dbnam'

which would mean the same query could be performed, but on a different DB engine. If you had to use the built in functions and without an abstraction class like MDB2, you'll have to constantly check what the database type is, and use the appropriate function. MDB2 avoids this by only requiring you give the DB type and credidentials at the factory(), and then reusing that information along the way. You don't have to do any checks, and you don't have to make any ensurances a query will work the same across all engines. You just perform the queries in your application and act accordingly from the result, as you'd usually do if your application supported only one type of a database.ODBC is just another type of database that MDB2 happens not to support. If you write a driver for it, you can use ODBC + everything MDB2 supports already.

Link to comment
Share on other sites

PHP is going to need access to Derby then. But my Derby installation is in my ColdFusion Developer's Edition. Can PHP get to it, or do I need another Derby installation?

Link to comment
Share on other sites

I'm still in the process of making sure Derby is installed correctly, but I'm trying to understand how MDB2 works. How do I specify which driver to use?

Link to comment
Share on other sites

How do I specify which driver to use?
You specify the databse at the MDB2::factory() method, but how do you select the driver to load - That you'll have to reverse engineer from the source code of MDB2 to find out.But if you want to ensure your Derby installation would work with PHP, I'd suggest you frist try to connect to your DB with plain ODBC functions and only once you ensure PHP can actually use it, start reverse engineering.Or better yet, ask the MDB2 developers for assistance.
Link to comment
Share on other sites

Maybe I need to modify the name of the database for each driver... I was going to call every database "error-logger" but it looks like that makes the factory method ambiguous.What Microsoft driver should I use? I don't see anything with "Derby" in it...And I'm trying to get help at the PEAR mailing list.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...