Tutoriale PHP
  Comunitatea PHP Romania nou

 
Tutoriale PHP
PHP 5, SQLite in Factory?
Google Buzz
PHP 5, SQLite in Factory?
Vezi comentariiDiscuta acest articol (0 comentarii)
TiparesteTipareste
Adauga la favorite-Doar pentru membriiAdauga la favorite

aurelian
XII. SQLite?

Dupa un timp, am zis sa incerc sa mai creez inca un produs pentru factory-ul descris in postul precedent.
Mi-ar fi placut sa am posibilitatea sa logez erorile si mesajele de debug intr-un tabel al unei baze de date.
Si cum inca nu am avut posibilitatea sa lucrez cu SQLite, am decis ca acesta sa fie tipul de baza de date pe care o sa il folosesc.
Prima concluzie?
Daca vreau sa folosesc clientul SQLite din lina de comanda si apoi sa accesez baza de date creata cu acest client din PHP 5.0 trebuie sa folosesc SQLite 2.8.15, nu SQLite 3.0.8. Bazele de date create cu SQLite 3.0.8 vor putea fi accesate din viitorul PHP 5.1, deci mai am de asteptat pana in a doua jumatate a acestui an.
Ce este SQLite?

Deci, folosind clientul SQLite, versiune 2.8.15 m-am pus pe treaba, si am creat o baza de date noua:

$ sqlite logger.db

Am aflat ca imi pot scrie sql-ul linistit si apoi il pot importa intr-o baza de date SQLite.
dump.sql:

BEGIN TRANSACTION;
CREATE TABLE logger (id INTEGER PRIMARY KEY,message TEXT,timeEnter DATE);
CREATE TRIGGER insert_logger_timeEnter AFTER INSERT ON logger
BEGIN
UPDATE logger SET timeEnter = DATETIME('NOW') WHERE rowid = new.rowid;
END;
COMMIT;

Lucruri obisnuite aici:
un tabel cu numele logger, ce contine un camp id de tip INTEGER cheie primara, un camp message, unde evident voi tine mesajele si timeEnter in care voi pastra data introducerii unui mesaj nou.
In plus, am creat un TRIGGER, astfel la fiecare insert pe care il voi face, campul timeEnter se va actualiza singur (nu o sa fie nevoie sa ii mai zic insert into logger (timeEnter) values DATETIME('NOW'), insert into logger (message) values ($message) va fi destul pentru a actualiza cele 3 campuri).
Am descoperit astfel si triggeri in SQLite, dupa ce am citit si tutorialul asta.

Am importat fisierul dump.sql cu comanda:

$ sqlite logger.db < dump.sql

Binarul (fisierul .exe pe Windows) ar trebui sa fie in PATH pentru a avea comanda sqlite la prompt.

XIII. Un nou produs, SQLite

Tinand cont ca va trebui sa implementez metodele interfetei Trace si, urmand exemplul din FileTrace am scris destul de repede si usor SQLiteTrace.php:

<?php
// merge cu sqlite 2.8.15 pe php 5.0!
/*
----------> SQL DUMP
BEGIN TRANSACTION;
CREATE TABLE logger (id INTEGER PRIMARY KEY,message TEXT,timeEnter DATE);
CREATE TRIGGER insert_logger_timeEnter AFTER INSERT ON logger
BEGIN
UPDATE logger SET timeEnter = DATETIME('NOW') WHERE rowid = new.rowid;
END;
COMMIT;
<---------- SQL DUMP
*/

include_once('ITrace.php');
/**
* It logs the trace to a sqlite db
*
* @todo: implement a custom Exception class
* @package test.factory.trace
* @access public
*/
class SQLiteTrace implements Trace {

/**
* It`s the db handler
* @var handler
* @access private
*/
private $handler;

/**
* debug
* @var bool
* @access private
*/
private $debug;

/**
* The construnctor
* it opens the db handler
*
* @return void
* @access public
*/
public function __construct() {
$dbname = 'logger.db';
$this->handler = @sqlite_open($dbname, 0666, $sqliteerror);
if($this->handler===false){
throw new Exception($sqliteerror);
}
}

/**
* Sets the debug
* @param bool debug
* @return void
* @access public
*/
public function setDebug($debug) {
$this->debug = $debug;
}

/**
* It writes a debug message
* only if debug is true
* @param string message
* @return void
* @access public
*/
public function debug($message) {
if($this->debug) {
// only insert if debug is true
sqlite_query($this->handler, "INSERT INTO logger (message) VALUES (' DEBUG >>>> " . $message . "')");
}
}

/**
* It writes an error message
*
* @param string message
* @return void
* @access public
*/
public function error($message) {
// always log errors
sqlite_query($this->handler, "INSERT INTO logger (message) VALUES (' ERROR >>>> " . $message . "')");
}

/**
* Is the Destructor
* just close the handler
* @access public
* return void
*/
public function __destruct() {
@sqlite_close($this->handler);
}
}


XIV. Un nou Creator

Am reusit sa rescriu si TraceFactory.php astfel:

<?php
/**
* Is the factory
*
* @version 0.3
* @access public
* @package test.factory.trace
*/

class TraceFactory {
/**
* It trys to get a trace
*
* @access public
* @return object Trace, a trace instance
*/
public static function &getTrace() {
try {
include_once('FileTrace.php');
return new FileTrace();
} catch (Exception $ex) {
try{
include_once('SQLiteTrace.php');
$t_sqlite = new SQLiteTrace();
$t_sqlite->error("Could not instantiate FileTrace:\n" . $ex->getMessage());
return $t_sqlite;
}catch(Exception $sqlite_ex) {
include_once('StdoutTrace.php');
$t = new StdoutTrace();
$t->error("Could not instantiate SQLiteTrace:\n" . $sqlite_ex->getMessage());
return $t;

}
}
}
}

Chiar daca nu imi place prea mult blocul:

<?php
try {

} catch (Exception $ex) {
try{

}catch(Exception $sqlite_ex) {
}
?>

Tracerul meu este functional avand 3 metode distincte de a loga mesajele:
intr-un fisier,
intr-o baza de date sau
direct pe consola (nu prea o sa vad lucrul asta prea curand totusi).

XV. Neajunsuri

In momentul de fata, sincer sa fiu, nu imi dau seama unde as putea implementa acest exemplu.
As vrea sa il continui, aducad in discutie un alt procedeu: observer, mai mult, mi-ar placea sa am mai multe nivele de logare (debug/info/error/alert/emergency).
Metoda getTrace nu mi se pare pre flexibila, cum ar fi daca as vrea sa mai adaug inca un produs acolo?
Probabil ar trebui sa o rescriu astfel:

<?php
/**
* Is the factory
*
* @version 0.4
* @access public
* @package test.factory.trace
*/

class TraceFactory {
/**
* It trys to get a trace
*
* @param string driver, it can be File or SQLite
* @access public
* @return object Trace, a trace instance
*/
public static function &getTrace($driver='') {
$drivers = array('File','SQLite');
if(!in_array($driver, $drivers)) {
include_once('StdoutTrace.php');
return new StdoutTrace();
}
try {
$rs = $driver . 'Trace';
include_once($rs . '.php');
return new $rs();
} catch (Exception $ex) {
include_once('StdoutTrace.php');
$t = new StdoutTrace();
$t->error("Could not instantiate " . $driver . ":\n" . $ex->getMessage());
return $t;
}
}
}

iar testul urmator, runTrace.php mi-ar loga mesaje in fisierul text in prima parte, in baza de date SQLite in partea de mijloc si in final as afisa si ceva in consola:

<?php
include_once('TraceFactory.php');
$t = &TraceFactory::getTrace('File');
$t->error("O eroare de test!");
$t->setDebug(true);
$t->debug("Debug is true");
for($i=1;$i<10;$i++){
$t->debug("Tha lup :: " . $i);
}
unset($t);
$t = &TraceFactory::getTrace('SQLite');
$t->error("Ceva de test!");
$t->setDebug(true);
$t->debug("True Debug");

for($i=1;$i<10;$i++){
$t->debug("Za I :: " . $i);
}
$t->error("FOO IS BAR MUST DIE !!!");

unset($t);
$t = &TraceFactory::getTrace('Unknow_driver');
$t->error("Ajunge in consola!");
$t->setDebug(true);
$t->debug("True Debug a fos setat");

for($i=1;$i<10;$i++){
$t->debug("I-ul :: " . $i);
}
$t->error("Fatal!!!");

Ramane insa de discutat despre diferite niveluri de log si de introducerea unui observer care sa ma anunte in cazul in care se produce o eroare in sistem.
Pana una-alta, raman cu PEAR::Log, dar o sa continui totusi acest articol prin introducerea componentelor de mai sus, cea ce inseamna un sitem de logare a mesajelor cat de cat complet si utilizabil in productie (chiar daca constat ca SQLite nu este chiar atat de rapid :) ).

comentarii si sugestii: oancea at gmail dot com.
Sus


Trimis de : aurelianData intrarii : 17 Ianuarie 2005Nivel : incepator


[ Profil autor ]
aurelian http://amansio.blogspot.com

[ Alte articole ale acestui autor ]
PHP 5, Factory

Gazduire

Tutoriale

Discuta in forum

Parteneri

Copyright © 2001-2010 PHP Romania Add PHPRomania to Google Add PHPRomania to Del.icio.us Add PHPRomania to Stumbleupon Add PHPRomania to Yahoo! Add PHPRomania to Digg Add PHPRomania to Blink
Powered by Simplis