Archive for the 'programming' Category

Seringkali programmer pusing dengan penggunaan DBMS(Database Management System) yang lintas platform maupun lintas vendor, karena meskipun memiliki standart SQL (Structured Query Language) yang sama, namun untuk menghandle koneksi, record ataupun tipe data dan beberapa query terdapat perbedaan yang meskipun kecil tapi memaksa programmer harus merubah keseluruhan program.Namun,masalah tersebut dapat diatasi dengan menggunakan ADOdb.

ADOdb adalah salah satu library PHP (dan juga phyton) untuk abstraksi berbagai jenis database. Dengan menggunakan ADOdb, tidak lagi masalah kita menggunakan DBMS jenis maupun dari vendor apa saja.Sekali programmer membuat suatu kode program dengan menggunakan DBMS tertentu misalnya MySQL, maka code tadi masih tetap dapat digunakan meskipun suatu saat diharuskan terjadi perubahan penggunaan DBMS misalkan menjadi Oracle, SQLServer, PostgreSQL maupun DBMS yang lain. ADOdb dapat didownload secara gratis dan bersifat opensource. Saat ini sudah banyak DBMS yang disupport oleh ADOdb, diantaranya : Access,ADO,DB2,Firebird,FoxPro, FrontBase, Informix, Interbase, LDAP, MS SQL Server, MySQL, Netezza, Oracle, PostgreSQL, SAP DB, SQLIte, SyBase, Terabase, Valentina.

Bagi Anda yang sudah terbiasa menggunakan ADOdb maka tentu tau salah satu fitur ADOdb adalah kemampuannya untuk me-menage koneksi yang memungkinkan untuk melakukan koneksi ke lebih dari satu DBMS secara bersamaa. Dalam dokumentasi ADOdb dicontohkan cara untuk melakukannya sebagai berikut :

<?
include(’adodb.inc.php’);	 # load code common to ADOdb
$conn1 = &ADONewConnection(’mysql’);  # create a mysql connection
$conn2 = &ADONewConnection(’oracle’);  # create a oracle connection

$conn1->PConnect($server, $userid, $password, $database);
$conn2->PConnect(false, $ora_userid, $ora_pwd, $oraname);

$conn1->Execute(’insert …’);
$conn2->Execute(’update …’);
?>

Ok, fungsi itu akan berjalan dengan sangat baik jika digunakan untuk 2 DBMS yang berbeda, dalam contoh digunakan MySQL dan Oracle. Namun pernahkah Anda menggunakan cara tersebut untuk melakukan koneksi ke DBMS yang sama misalkan sama2 MySQL seperti berikut :

<?
include(’adodb.inc.php’);	 # load code common to ADOdb
$conn1 = &ADONewConnection(’mysql’);  # create a mysql connection
$conn2 = &ADONewConnection(’mysql’);  # create the 2nd mysql connecion

$conn1->PConnect($server, $userid, $password, $database);
$conn2->PConnect($server, $userid, $password, $database); 
$conn1->Execute(’insert …’);
$conn2->Execute(’update …’);
?>

Jika hal tersebut Anda lakukan maka ketika mencoba untuk mengeksekusi query ke database pertama maka akan terjadi error dimana hanya koneksi terakhir aja yang akan “hidup” sementara koneksi yang lain tidak terbentuk.

BAGAIMANA MEMPERBAIKI BUG ?

Error itu disebabkan oleh bug di ADOdb , baik sekarang saatnya untuk memperbaiki bug tersebut.

1. Buka file adodb\drivers\adodb-mysql.inc.php
2. Pada baris deklarasi, tambahkan baris berikut :

var $__db = array();

sehingga akan menjadi :

var $databaseType = ‘mysql’;
var $dataProvider = ‘mysql’;
var $hasInsertID = true;
var $hasAffectedRows = true;
var $metaTablesSQL = “SHOW TABLES”;
var $metaColumnsSQL = “SHOW COLUMNS FROM `%s`”;
var $fmtTimeStamp = “‘Y-m-d H:i:s’”;
var $hasLimit = true;
var $hasMoveFirst = true;
var $hasGenID = true;
var $isoDates = true; // accepts dates in ISO format
var $sysDate = ‘CURDATE()’;
var $sysTimeStamp = ‘NOW()’;
var $hasTransactions = false;
var $forceNewConnect = false;
var $poorAffectedRows = true;
var $clientFlags = 0;
var $substr = “substring”;
var $nameQuote = ‘`’; /// string to use to quote identifiers and names
var $compat323 = false; // true if compat with mysql 3.23
var $__db = array(); // Bug fixing

3. Cari fungsi SelectDB, ubah sehingga menjadi seperti berikut :

function SelectDB($dbName)
{
$this->database = $dbName;
$this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
if ($this->_connectionID) {

// Bug Fixing
@mysql_select_db($dbName,$this->_connectionID);
$this->__db[$this->_connectionID] = $dbName;
return $this->_connectionID; // end bug fixing
// end bug fix
}
else return false;
}

4. Cari fungsi _query dan ubah sehingga menjadi sebagai berikut :

function _query($sql,$inputarr)
{
//global $ADODB_COUNTRECS;
//if($ADODB_COUNTRECS)
$this->SelectDB($this->__db[$this->_connectionID]); // bug fixing
return mysql_query($sql,$this->_connectionID);
//else return @mysql_unbuffered_query($sql,$this->_connectionID); // requires PHP >= 4.0.6
}

5. Selesai, sekarang ADOdb Anda sudah dapat digunakan untuk melakukan koneksi ke beberapa Database MySQL secara bersamaan

MENGAPA BISA TERJADI ?

Bagi Anda yang masih penasaran mengapa Bug itu dapat timbul, silakan baca pembahasan berikut :

Jika Anda membuka file adodb\drivers\adodb-mysql.inc.php dan melihat pada baris akhir dari fungsi _connect() , Anda akan menemui baris sbb :

if ($argDatabasename) return $this->SelectDB($argDatabasename);
return true;

Terlihat bahwa fungsi itu akan me-return-kan $this->SelectDB($argDatabasename);

Jika Anda menelusuri lebih lanjut pada fungsi SelectDB, terlihat bahwa fungsi itu juga akan me-return-kan true atau false seperti terlihat berikut :

function SelectDB($dbName)
{
$this->database = $dbName;
if ($this->_connectionID) {
return @mysql_select_db($dbName,$this->_connectionID);
}
else return false;
}

terlihat juga dari fungsi diatas bahwa ID Koneksi dari MySQL disimpan dalam variabel $this->_connectionID.

Saya rasa sampai disini bagi Anda yang terbiasa dengan PHP cukup mengerti mengapa bug ini bisa terjadi ….
Yup benar sekali, ID Koneksi hanya ada untuk 1 buah koneksi MySQL saja, sehingga jika kita melakukan 2 koneksi ke MySQL maka ID Koneksi kedua saja yang akan muncul karena ID Koneksi pertama telah tertimpa.

Untuk mengatasinya, maka dapat dilakukan dengan membentuk array yang diinisiasi misalkan dengan nama variabel array $__db, setelah itu fungsi select DB dapat dimodifikasi sebagai berikut :

// returns true or false
function SelectDB($dbName)
{
$this->databaseName = $dbName;
if ($this->_connectionID) {
@mysql_select_db($dbName,$this->_connectionID);
$this->__db[$this->_connectionID] = $dbName;
return $this->_connectionID;
}
else return false;
}

Sehingga dapat dimungkinkan untuk menyimpan beberapa ID Koneksi dalam array yang akan memungkinkan melakukan koneksi ke beberapa DBMS MySQL secara bersamaan.

Itu ide dasarnya, selanjutnya tinggal memodifikasi beberapa fungsi yang terkait dengan koneksi.

Thats ALL