Databázový layer
Představuji k volnému použití (licence GNU GPL) jednoduchý dababázový layer, který je určen pro MySQL 3.23 až 4.0 (mysql), MySQL 4.1 (mysqli), SQLite a PostgreSQL.
Tento layer je záměrně psán neobjektově. Proč? Je určen pro úpravu starých skriptů, které jsou natvrdo psány pro MySQL 4.0, aby co nejdříve fungovaly s DB-layerem (na libovolné open-source databázi).
Názvy funkcí layeru jsou navrženy tak, aby byly shodné se syntaxí MySQL funkcí,
jen místo mysql
budete psát sql
, tedy například místo mysql_connect
budete
psát sql_connect
. Teoreticky je tak možné na Vašem skriptu udělat
hromadný search-and-replace slov mysql_
na sql_
,
a Vaše aplikace by měla fungovat s DB-layerem.
Pro nový vývoj je samozřejmě vhodnější použít DB-layer objektový, uvedu jej zde zítra.
Zdrojové kódy layeru jsou zde.
Použití layeru pro MySQL:
Typické použití pro MySQL 4.1 bude spočívat ve vytvoření souboru config.php
s
tímto obsahem:
Příklad pro SQLite:
Prefix tabulek:
Uvedený skript počítá rovněž s prefixem tabulek. Ten je velice důležitý, typicky máte na web-hostingu povolenou jen jednu MySQL/PGSQL databázi, a potom je nezbytně nutné jednotlivé instalace stejné aplikace odlišit právě prefixem v názvech tabulek.
Použití tohoto skriptu?
Náš index.php
může vypadat například takto, a bude fungovat na
MySQL 4.0, MySQL 4.1, SQLite a PostgreSQL:
Tvuj strukturalne programovany db layer me konecne prinutil, abych si naprogramoval vlastni db layer objektovy.
Tak schvalne, jestli je lepsi, nez ten tvuj, co uverejnis zitra ;) Pak hodim linky.
Z manualu:
mysql_fetch_assoc() is equivalent to calling mysql_fetch_array() with MYSQL_ASSOC for the optional second parameter.
Nevidim u tebe potom rozdil ve funkcich
sql_fetch_array a sql_fetch_assoc
Dale kdyz uz tam mas escapovani, nema sqlite escapovane apostrofy?
Opravdu chces uzivatelum pri chybe v query vypisovat, jaky dotaz se nepovedl? :-)
[2] sql_fetch_array udělá asociativní pol epodle názvů položek v SELECTu a sql_fetch_assoc podle názvů i podle čísel.. Chce to číst lépe dokumentaci.
Ohledně chyb v SQL - není důvod, aby aplikace dělala při běhu chyby v SQL, takže ano, je tam výpis natvrdo, a může se objevit jen tehdy, když to programuji..
Hmm... kdybych nemel se svym projektem komercni zamery, hned bych to bral, ale ta GNU me odrazuje... takze si budu muset napsat vlastni :D
Btw: jaky mate kdo nazor na GNU/GPL? Pomaha svobodne tvorbe programu jak byl jeji zamer a nebo skodi? Pac muj nazor je takovy (a nemam ho sam), ze firmy si stejne musi ta reseni napsat samy, pokud nechteji porusit ty licence, takze to trosku ztraci smysl...
[3] Nemůžu si pomoct, ale v manuálu php pro mysql funkce to čtu přesně obráceně, než to říkáš.
To escapování sglite tam máš, toho jsem si nevšim, promiň.
[5] máš pravdu, moje chyba, děkuji, opravil jsem to
Chtěl bych doporučit ADODB - něco podobného, podpora větší sady databází. Používám již několik let a díky tomu že pracuji s různými databázemi jsem si ušetřil dost času, přemýšlením nad názvy potřebných funkcí :-) Cache výsledků dotazů také není od věci.
Díky licenci je možné vkládat do komerčních projektů bez nutnosti zveřejnit zdrojové kódy.
http://adodb.sourceforge.net/
[3] Chyba je treba i poruseni IO treba UNIQUE (no na MySQL asi nic jinyho ne) a to se imo stavat muze a mela by to zpracovat aplikace (takhle nemuze). Ten SELECT navic by byl casto zbitecny.
[7] ADODB je pekny ale trochu jinde uz jen tech ~400kB kodu :)
fetch_field by alespon priblizne slo i posgres
function sql_fetch_field(&$resource, $field_number=0){
//pgsql $i = pg_num_fields($resource);
if($field_number<$i)
{
$field = array();
$field['name'] = $name = pg_field_name($resource, $j);
$field['type'] = pg_field_type($resource, $j);
$field['max_length'] = pg_field_size($resource, $j); //priblizne ;) return $field;
}
else
{
return array();
}
a pouzivat pro indexy OID mi prijde min prakticke nez tohle :)
sql_insert_id()
_PGSQL:
$result = @pg_query($activedb,$query)
or
die ("Invalid query: ".htmlspecialchars($query)." <br><br>Error: <b>".sql_error()."</b>");
if(preg_match("/^\s*INSERT\s+INTO\s+(\w*)/i",$query, $matches))
{
global $_pg;
$_pg = $matches[ 1 ];
}
break;
sql_insert_id(){
_PGSQL:
global $_pg; if(!empty($_pg))
{ $result = @pg_query('SELECT currval(\''.$_pg.'_id_'.$_pg.'_seq\')');
if(empty($result)) return 0;
else
{
$row=pg_fetch_row($result);
return $row[ 0 ];
}
}
break;
mysql_fetch_array() je i s parametrem MYSQL_ASSOC o 40% pomalejší než mysql_fetch_assoc()
Takže používejte pouze mysql_fetch_row() nebo mysql_fetch_assoc()
Benchmark on a table with 38567 rows:
mysql_fetch_array:
MYSQL_BOTH: 6.01940000057 secs
MYSQL_NUM: 3.22173595428 secs
MYSQL_ASSOC: 3.92950594425 secs
mysql_fetch_row: 2.35096800327 secs
mysql_fetch_assoc: 2.92349803448 secs
[9] ale ta čísla neříkají naprosto nic..
V PHP 5 jsou ty rozdíly už menší, když budeme brát mysql_fetch_row jako 100%:
mysql_fetch_row - 100%
mysql_fetch_array(MYSQL_NUM) - 113%
mysql_fetch_assoc - 118%
mysql_fetch_array(MYSQL_ASSOC) - 127%
mysql_fetch_array - 150%
Čili není to už tak výrazné, ale proč nepoužít rychlejší funkci...
[11] chtěl jsem říci, že alespoň bez znalosti STD a testovacího skriptu, jsou ta čísla jen "vycucaná z prstu"...
Upozorňuji na drobnost v ukázkovém config.php souboru. Je zde uvedeno:
$SQL_USERNAME;
Kdežto v definovaných funkcích se používá
global $SQL_USER;
Zdravim,
jen jsem se chtel zeptat, jak to vypada s tim objektovym resenim DB layer;-)? Najek jsem ho nenasel.
Diky
[14] chytrý student si dodělá za domácí úkol ;-)
Mohl bych se zeptat, kde je ten slibovany objektovy layer? Nejak ho nemuzu mezi novejsimi clanky najit...
[16] udělat z toho objekt je práce na 10 minut, proto se mi do toho moc nechce, to zvládne každý sám..
Tak jsem si to zkušebně převedl a teď bych se chtel podívat, ja to udělá profík, abych zjistil, co musím ještě dohnat... Jinak by to chtělo odstranit ten slib: ", uvedu jej zde zítra".