|
4100 - in trunk/EventLogDatabaseTiein: . src/writers tests/writers tests/wr: msg#00270web.ezcomponents.cvs
Author: Alexandru Stanoi Date: 2006-11-28 11:22:05 +0100 (Tue, 28 Nov 2006) New Revision: 4100 Log: - Implemented task #9604: using sql abstraction instead of hard-coded sql queries. - Removed the unmap() function from ezcLogDatabaseWriter (not implemented yet). Added: trunk/EventLogDatabaseTiein/tests/writers/testfiles/ trunk/EventLogDatabaseTiein/tests/writers/testfiles/audits_db_schema.xml trunk/EventLogDatabaseTiein/tests/writers/testfiles/log_db_schema.xml Modified: trunk/EventLogDatabaseTiein/ChangeLog trunk/EventLogDatabaseTiein/src/writers/writer_database.php trunk/EventLogDatabaseTiein/tests/writers/writer_database_test.php Modified: trunk/EventLogDatabaseTiein/ChangeLog =================================================================== --- trunk/EventLogDatabaseTiein/ChangeLog 2006-11-28 10:13:15 UTC (rev 4099) +++ trunk/EventLogDatabaseTiein/ChangeLog 2006-11-28 10:22:05 UTC (rev 4100) @@ -1,3 +1,10 @@ +1.0.1 - [RELEASEDATE] +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Implemented task #9604: using sql abstraction instead of hard-coded sql + queries. + + 1.0 - Monday 30 January 2006 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Modified: trunk/EventLogDatabaseTiein/src/writers/writer_database.php =================================================================== --- trunk/EventLogDatabaseTiein/src/writers/writer_database.php 2006-11-28 10:13:15 UTC (rev 4099) +++ trunk/EventLogDatabaseTiein/src/writers/writer_database.php 2006-11-28 10:22:05 UTC (rev 4100) @@ -11,23 +11,60 @@ /** * The ezcLogDatabaseWriter provides an implementation to write log messages to the database. * - * table - * message - * datetime - * severity - * source - * category + * Example to use the ezcLogDatabaseWriter: + * <code> + * // Get the database instance + * $db = ezcDbInstance::get(); * + * // Create a new ezcLogDatabaseWriter object based on the database instance + * // and with the default table name "log". + * // The "log" table must exist already in the database, and must have a compatible structure, + * // with any additional fields that you may require, eg. you can use this example schema, + * // where the default fields are: id, category, message, severity, source, time + * // and the additional fields are: file, line + * // DROP TABLE IF EXISTS log; + * // CREATE TABLE log ( + * // category varchar(255) NOT NULL, + * // file varchar(255), + * // id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY, + * // line bigint, + * // message varchar(255) NOT NULL, + * // severity varchar(255) NOT NULL, + * // source varchar(255) NOT NULL, + * // time timestamp NOT NULL + * // ); + * $log = new ezcLogDatabaseWriter( $db, "log" ); * + * // Write a log entry ( message, severity, source, category ) + * $log->writeLogMessage( "File /images/spacer.gif does not exist.", ezcLog::WARNING, "Application", "Design" ); + * + * // Write a log entry ( message, severity, source, category, file, line ) + * $log->writeLogMessage( "File /images/spacer.gif does not exist.", ezcLog::WARNING, "Application", "Design", array( "file" => "/index.php", "line" => 123 ) ); + * </code> + * + * @property string $table + * The table name. + * @property string $message + * The name of the column message. + * @property string $datetime + * The name of the column datetime. + * @property string $severity + * The name of the column severity. + * @property string $source + * The name of the column source. + * @property string $category + * The name of the column category. + * * @package EventLogDatabaseTiein * @version //autogentag// + * @mainclass */ class ezcLogDatabaseWriter implements ezcLogWriter { - /** - * Instance to the database handler. + /** + * Holds the instance to the database handler. * - * @var ezcDBHandler + * @var ezcDBHandler */ private $db = null; @@ -38,10 +75,32 @@ */ private $properties = array(); + /** + * Holds the default column names in the log tables. + * + * @var array(string=>mixed) + */ private $defaultColumns = array(); + + /** + * Holds additional column names in the log tables. + * + * @var array(string=>mixed) + */ private $additionalColumns = array(); + /** + * Maps tables to ezcLogFilter messages. + * + * @var ezcLogFilterSet + */ private $map; + + /** + * Holds the default table name. + * + * @var string + */ private $defaultTable = false; /** @@ -52,8 +111,8 @@ * * This constructor is a tie-in. * + * @param ezcDbHandler $databaseInstance * @param string $defaultTable - * @param ezcDbHandler $databaseInstance */ public function __construct( ezcDbHandler $databaseInstance, $defaultTable = false ) { @@ -72,18 +131,18 @@ /** * Sets the property $name to $value. * - * @throws ezcBasePropertyNotFoundException if the property does not exist. * @param string $name * @param mixed $value - * @return void + * @ignore */ public function __set( $name, $value ) { switch ( $name ) { case 'table': - $this->properties['table'] = $value; + $this->properties[$name] = $value; break; + case 'message': case 'datetime': case 'severity': @@ -91,6 +150,7 @@ case 'category': $this->defaultColumns[$name] = $value; break; + default: $this->additionalColumns[$name] = $value; break; @@ -100,32 +160,64 @@ /** * Returns the property $name. * - * @throws ezcBasePropertyNotFoundException if the property does not exist. + * @throws ezcBasePropertyNotFoundException + * If the property $name does not exist * @param string $name * @return mixed + * @ignore */ public function __get( $name ) { switch ( $name ) { case 'table': - return $this->properties['table']; - break; + return $this->properties[$name]; + case 'message': case 'datetime': case 'severity': case 'source': case 'category': return $this->defaultColumns[$name]; - break; default: - return $this->additionalColumns[$name]; - break; + if ( isset( $this->additionalColumns[$name] ) ) + { + return $this->additionalColumns[$name]; + } + else + { + throw new ezcBasePropertyNotFoundException( $name ); + } } } /** + * Returns true if the property $name is set, otherwise false. + * + * @param string $name + * @return bool + * @ignore + */ + public function __isset( $name ) + { + switch ( $name ) + { + case 'table': + return isset( $this->properties[$name] ); + case 'message': + case 'datetime': + case 'severity': + case 'source': + case 'category': + return isset( $this->defaultColumns[$name] ); + + default: + return isset( $this->additionalColumns[$name] ); + } + } + + /** * Writes the message $message to the log. * * The writer can use the severity, source, and category to filter the @@ -135,44 +227,41 @@ * $optional may contain extra information that can be added to the log. For example: * line numbers, file names, usernames, etc. * - * @throws ezcLogWriterException when the log writer was unable to write the log message. + * @throws ezcLogWriterException + * If the log writer was unable to write the log message * @param string $message * @param int $severity * ezcLog:: DEBUG, SUCCES_AUDIT, FAILED_AUDIT, INFO, NOTICE, WARNING, ERROR or FATAL. - * * $param string $source * @param string $category * @param array(string=>string) $optional - * @return void */ public function writeLogMessage( $message, $severity, $source, $category, $optional = array() ) { $severityName = ezcLog::translateSeverityName( $severity ); - - $colStr = ""; - $valStr = ""; - - if ( is_array( $optional ) ) - { - foreach ( $optional as $key => $val ) - { - $colStr .= ", " . ( isset( $this->additionalColumns[$key] ) ? $this->additionalColumns[$key] : $key ); - $valStr .= ", " . $this->db->quote( $val ); - } - } - $tables = $this->map->get( $severity, $source, $category ); + $query = $this->db->createSelectQuery(); - $query = $this->db->createSelectQuery(); - if ( count( $tables ) > 0) + if ( count( $tables ) > 0 ) { foreach ( $tables as $t ) { try { - $this->db->exec( "INSERT INTO `{$t}` ( {$this->message}, {$this->severity}, {$this->source}, {$this->category}, {$this->datetime} $colStr ) ". - "VALUES( ".$this->db->quote( $message ).", ".$this->db->quote( $severityName ).", ".$this->db->quote( $source ).", ". - $this->db->quote( $category ).", ".$query->expr->now()." $valStr )" ); + $q = $this->db->createInsertQuery(); + $q->insertInto( $t ) + ->set( $this->message, $q->bindValue( $message ) ) + ->set( $this->severity, $q->bindValue( $severityName ) ) + ->set( $this->source, $q->bindValue( $source ) ) + ->set( $this->category, $q->bindValue( $category ) ) + ->set( $this->datetime, $query->expr->now() ); + foreach ( $optional as $key => $val ) + { + $q->set( ( isset( $this->additionalColumns[$key] ) ? $this->additionalColumns[$key] : $key ), $q->bindValue( $val ) ); + } + $stmt = $q->prepare(); + $stmt->execute(); + } catch ( PDOException $e ) { @@ -186,9 +275,19 @@ { try { - $this->db->exec( "INSERT INTO `{$this->defaultTable}` ( {$this->message}, {$this->severity}, {$this->source}, {$this->category}, {$this->datetime} $colStr ) ". - "VALUES( ".$this->db->quote( $message ).", ".$this->db->quote( $severityName ).", ".$this->db->quote( $source ).", ". - $this->db->quote( $category ).", ".$query->expr->now()." $valStr )" ); + $q = $this->db->createInsertQuery(); + $q->insertInto( $this->defaultTable ) + ->set( $this->message, $q->bindValue( $message ) ) + ->set( $this->severity, $q->bindValue( $severityName ) ) + ->set( $this->source, $q->bindValue( $source ) ) + ->set( $this->category, $q->bindValue( $category ) ) + ->set( $this->datetime, $query->expr->now() ); + foreach ( $optional as $key => $val ) + { + $q->set( ( isset( $this->additionalColumns[$key] ) ? $this->additionalColumns[$key] : $key ), $q->bindValue( $val ) ); + } + $stmt = $q->prepare(); + $stmt->execute(); } catch ( PDOException $e ) { @@ -209,7 +308,6 @@ return array_merge( $this->defaultColumns, $this->additionalColumns ); } - /** * Maps the table $tableName to the messages specified by the {@link ezcLogFilter} $logFilter. * @@ -218,27 +316,10 @@ * * @param ezcLogFilter $logFilter * @param string $tableName - * @return void */ public function setTable( ezcLogFilter $logFilter, $tableName ) { $this->map->appendRule( new ezcLogFilterRule( $logFilter, $tableName, true ) ); } - - /** - * Unmaps the table $tableName from the messages specified by the {@link ezcLogFilter} $logFilter. - * - * Log messages that matches with the filter are no longer written to the table $tableName. - * This method works the same as {@link ezclog::unmap()}. - * - * @param ezcLogFilter $logFilter - * @param string $fileName - * @return void - */ - public function unmap( ezcLogFilter $logFilter, $tableName ) - { - $this->map->unmap( $logFilter->severity, $logFilter->source, $logFilter->category, $tableName ); - } } - ?> Added: trunk/EventLogDatabaseTiein/tests/writers/testfiles/audits_db_schema.xml =================================================================== --- trunk/EventLogDatabaseTiein/tests/writers/testfiles/audits_db_schema.xml 2006-11-28 10:13:15 UTC (rev 4099) +++ trunk/EventLogDatabaseTiein/tests/writers/testfiles/audits_db_schema.xml 2006-11-28 10:22:05 UTC (rev 4100) @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<database> + <table> + <name>audits</name> + <declaration> + <field> + <name>id</name> + <type>integer</type> + <autoincrement>true</autoincrement> + <notnull>true</notnull> + </field> + <field> + <name>time</name> + <type>timestamp</type> + <notnull>true</notnull> + </field> + <field> + <name>message</name> + <type>text</type> + <notnull>true</notnull> + </field> + <field> + <name>severity</name> + <type>text</type> + <notnull>true</notnull> + </field> + <field> + <name>source</name> + <type>text</type> + <notnull>true</notnull> + </field> + <field> + <name>category</name> + <type>text</type> + <notnull>true</notnull> + </field> + <field> + <name>name</name> + <type>text</type> + </field> + <index> + <name>primary</name> + <primary>true</primary> + <unique>true</unique> + <field> + <name>id</name> + </field> + </index> + </declaration> + </table> +</database> Added: trunk/EventLogDatabaseTiein/tests/writers/testfiles/log_db_schema.xml =================================================================== --- trunk/EventLogDatabaseTiein/tests/writers/testfiles/log_db_schema.xml 2006-11-28 10:13:15 UTC (rev 4099) +++ trunk/EventLogDatabaseTiein/tests/writers/testfiles/log_db_schema.xml 2006-11-28 10:22:05 UTC (rev 4100) @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8"?> +<database> + <table> + <name>log</name> + <declaration> + <field> + <name>id</name> + <type>integer</type> + <autoincrement>true</autoincrement> + <notnull>true</notnull> + </field> + <field> + <name>time</name> + <type>timestamp</type> + <notnull>true</notnull> + </field> + <field> + <name>message</name> + <type>text</type> + <notnull>true</notnull> + </field> + <field> + <name>severity</name> + <type>text</type> + <notnull>true</notnull> + </field> + <field> + <name>source</name> + <type>text</type> + <notnull>true</notnull> + </field> + <field> + <name>category</name> + <type>text</type> + <notnull>true</notnull> + </field> + <field> + <name>file</name> + <type>text</type> + </field> + <field> + <name>line</name> + <type>integer</type> + </field> + <index> + <name>primary</name> + <primary>true</primary> + <unique>true</unique> + <field> + <name>id</name> + </field> + </index> + </declaration> + </table> +</database> Modified: trunk/EventLogDatabaseTiein/tests/writers/writer_database_test.php =================================================================== --- trunk/EventLogDatabaseTiein/tests/writers/writer_database_test.php 2006-11-28 10:13:15 UTC (rev 4099) +++ trunk/EventLogDatabaseTiein/tests/writers/writer_database_test.php 2006-11-28 10:22:05 UTC (rev 4100) @@ -1,46 +1,70 @@ <?php +/** + * @copyright Copyright (C) 2005, 2006 eZ systems as. All rights reserved. + * @license http://ez.no/licenses/new_bsd New BSD License + * @version //autogentag// + * @filesource + * @package EventLogDatabaseTieIn + * @subpackage Tests + */ +/** + * @package EventLogDatabaseTieIn + * @subpackage Tests + */ class ezcLogDatabaseWriterTest extends ezcTestCase { protected function setUp() { try { - $db = ezcDbInstance::get(); + $this->db = ezcDbInstance::get(); } catch ( Exception $e ) { $this->markTestSkipped(); } - $this->writer = new ezcLogDatabaseWriter( $db, "log" ); + $this->command = array(); + $schema = ezcDbSchema::createFromFile( 'xml', dirname( __FILE__ ) . '/testfiles/log_db_schema.xml' ); + foreach ( $schema->convertToDDL( $this->db ) as $statement ) + { + $this->command[] = $statement; + } - $this->assertNotNull( $db, 'Database instance is not initialized.' ); + try + { + $this->db->exec( $this->command[0] ); + } + catch ( Exception $e ) + { + } try { - $db->exec( "DROP TABLE `log`" ); + $this->db->exec( $this->command[1] ); } - catch ( Exception $e) + catch ( Exception $e ) { } - - $db->exec("CREATE TABLE `log` ( `id` INT NOT NULL AUTO_INCREMENT , `time` DATETIME NOT NULL ,". - "`message` VARCHAR( 255 ) NOT NULL , `severity` VARCHAR( 40 ) NOT NULL , `source` VARCHAR( 100 ) NOT NULL ,". - "`category` VARCHAR( 100 ) NOT NULL , `file` VARCHAR( 100 ) NOT NULL , `line` INT NOT NULL , PRIMARY KEY ( `id` ))"); + $this->assertNotNull( $this->db, 'Database instance is not initialized.' ); + $this->writer = new ezcLogDatabaseWriter( $this->db, "log" ); } protected function tearDown() { - $db = ezcDbInstance::get(); - $db->exec("DROP TABLE `log`"); + try + { + $this->db->exec( $this->command[0] ); + } + catch ( Exception $e ) + { + } } - public function testWriteNotDefault() { - $db = ezcDbInstance::get(); - $writer = new ezcLogDatabaseWriter( $db, "logtable" ); + $writer = new ezcLogDatabaseWriter( $this->db, "logtable" ); $log = ezcLog::getInstance(); $log->getMapper()->appendRule( new ezcLogFilterRule( new ezcLogFilter, $writer, true ) ); try @@ -50,7 +74,22 @@ } catch ( ezcLogWriterException $e ) { - $this->assertEquals( "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'ezc.logtable' doesn't exist", $e->getMessage() ); + if ( $this->db instanceof ezcDbHandlerPgsql ) + { + $this->assertEquals( "SQLSTATE[42P01]: Undefined table: 7 ERROR: relation \"logtable\" does not exist", $e->getMessage() ); + } + if ( $this->db instanceof ezcDbHandlerMysql ) + { + $this->assertEquals( "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'ezc.logtable' doesn't exist", $e->getMessage() ); + } + if ( $this->db instanceof ezcDbHandlerSqlite ) + { + $this->assertEquals( "SQLSTATE[HY000]: General error: 1 no such table: logtable", $e->getMessage() ); + } + if ( $this->db instanceof ezcDbHandlerOracle ) + { + $this->markTestIncomplete(); + } } } @@ -58,8 +97,10 @@ { $this->writer->writeLogMessage("Hello world", ezcLog::WARNING, "MySource", "MyCategory"); - $db = ezcDbInstance::get(); - $a = $db->query("SELECT * FROM `log`")->fetch(); + $q = $this->db->createSelectQuery(); + $q->select( '*' )->from( 'log' ); + $stmt = $this->db->query( $q->getQuery() ); + $a = $stmt->fetch(); $this->assertEquals("Hello world", $a["message"], "Message doesn't match"); $this->assertEquals("MySource", $a["source"], "Source doesn't match"); @@ -72,8 +113,10 @@ { $this->writer->writeLogMessage("Hello world", ezcLog::WARNING, "MySource", "MyCategory", array("file" => "/usr/share/dott/", "line" => 123) ); - $db = ezcDbInstance::get(); - $a = $db->query("SELECT * FROM `log`")->fetch(); + $q = $this->db->createSelectQuery(); + $q->select( '*' )->from( 'log' ); + $stmt = $this->db->query( $q->getQuery() ); + $a = $stmt->fetch(); $this->assertEquals("Hello world", $a["message"], "Message doesn't match"); $this->assertEquals("MySource", $a["source"], "Source doesn't match"); @@ -99,8 +142,10 @@ $this->writer->LineNumbers = "line"; $this->writer->writeLogMessage("Hello world", ezcLog::WARNING, "MySource", "MyCategory", array( "myFileName" => "/usr/share/dott/", "LineNumbers" => 123) ); - $db = ezcDbInstance::get(); - $a = $db->query("SELECT * FROM `log`")->fetch(); + $q = $this->db->createSelectQuery(); + $q->select( '*' )->from( 'log' ); + $stmt = $this->db->query( $q->getQuery() ); + $a = $stmt->fetch(); $this->assertEquals("Hello world", $a["message"], "Message doesn't match"); $this->assertEquals("MySource", $a["source"], "Source doesn't match"); @@ -126,18 +171,21 @@ public function testAdditionalTables() { - $db = ezcDbInstance::get(); - + $command = array(); + $schema = ezcDbSchema::createFromFile( 'xml', dirname( __FILE__ ) . '/testfiles/audits_db_schema.xml' ); + foreach ( $schema->convertToDDL( $this->db ) as $statement ) + { + $command[] = $statement; + } + try { - $db->exec("DROP TABLE `audits`"); + $this->db->exec( $command[0] ); } catch ( Exception $e) { } - $db->exec("CREATE TABLE `audits` ( `id` INT NOT NULL AUTO_INCREMENT , `time` DATETIME NOT NULL ,". - "`message` VARCHAR( 255 ) NOT NULL , `severity` VARCHAR( 40 ) NOT NULL , `source` VARCHAR( 100 ) NOT NULL ,". - "`category` VARCHAR( 100 ) NOT NULL , `name` VARCHAR( 100 ) NOT NULL, PRIMARY KEY ( `id` ))"); + $this->db->exec( $command[1] ); // Only the FAILED and SUCCESS audits from every type. $filter = new ezcLogFilter(); @@ -146,7 +194,10 @@ $this->writer->setTable( $filter, "audits" ); $this->writer->writeLogMessage("Hoagie logged in.", ezcLog::SUCCESS_AUDIT, "administration interface", "security", array("name" => "Hoagie")); - $a = $db->query("SELECT * FROM `audits`")->fetch(); + $q = $this->db->createSelectQuery(); + $q->select( '*' )->from( 'audits' ); + $stmt = $this->db->query( $q->getQuery() ); + $a = $stmt->fetch(); $this->assertEquals("Hoagie logged in.", $a["message"], "Message doesn't match"); $this->assertEquals("administration interface", $a["source"], "Source doesn't match"); @@ -154,16 +205,56 @@ $this->assertEquals("Success audit", $a["severity"], "Severity doesn't match"); $this->assertEquals("Hoagie", $a["name"], "Extra info doesn't match"); - $db->exec("DROP TABLE `audits`"); + try + { + $this->db->exec( $command[0] ); + } + catch ( Exception $e) + { + } } + public function testProperties() + { + $this->writer->table = 'logger'; + $this->assertEquals( 'logger', $this->writer->table ); + $this->writer->myFileName = "file"; + $this->assertEquals( "file", $this->writer->myFileName ); + + try + { + $val = $this->writer->no_such_property; + } + catch ( ezcBasePropertyNotFoundException $e ) + { + $this->assertEquals( "No such property name 'no_such_property'.", $e->getMessage() ); + } + } + + public function testIsSet() + { + // test isset table name + $this->assertEquals( false, isset( $this->writer->table ) ); + $this->writer->table = 'logger'; + $this->assertEquals( true, isset( $this->writer->table ) ); + + // test isset default column names + $this->assertEquals( true, isset( $this->writer->message ) ); + $this->assertEquals( true, isset( $this->writer->severity ) ); + $this->assertEquals( true, isset( $this->writer->source ) ); + $this->assertEquals( true, isset( $this->writer->category ) ); + $this->assertEquals( true, isset( $this->writer->datetime ) ); + + // test isset additional column names + $this->assertEquals( false, isset( $this->writer->myFileName ) ); + $this->writer->myFileName = "file"; + $this->assertEquals( true, isset( $this->writer->myFileName ) ); + } + public static function suite() { return new PHPUnit_Framework_TestSuite("ezcLogDatabaseWriterTest"); } } - - - ?> |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| News | FAQ | advertise |