Author: ts Date: Wed Jan 30 14:18:14 2008 New Revision: 7261 Log: - Implemented enhancement #10151: Improved Database and PersistentObject datatype support (especially binary data). The object definitions allow to specify the datatype of the database column assigned to a property.
Modified: trunk/PersistentObject/ChangeLog trunk/PersistentObject/src/generators/manual_generator.php trunk/PersistentObject/src/handlers/delete_handler.php trunk/PersistentObject/src/handlers/load_handler.php trunk/PersistentObject/src/handlers/save_handler.php trunk/PersistentObject/tests/database_type_test.php trunk/PersistentObject/tests/suite.php Modified: trunk/PersistentObject/ChangeLog ============================================================================== --- trunk/PersistentObject/ChangeLog [iso-8859-1] (original) +++ trunk/PersistentObject/ChangeLog [iso-8859-1] Wed Jan 30 14:18:14 2008 @@ -6,6 +6,9 @@ PersistentObject. - Implemented enhancement #10727: Improved error messages for PersistentObject with ManualGenerator. +- Implemented enhancement #10151: Improved Database and PersistentObject + datatype support (especially binary data). The object definitions allow to + specify the datatype of the database column assigned to a property. - Fixed issue #10205: binding variables with an undeclared var doesn't throw an exception. If getState() on a persistent object does not return an array an exception is thrown now. Modified: trunk/PersistentObject/src/generators/manual_generator.php ============================================================================== --- trunk/PersistentObject/src/generators/manual_generator.php [iso-8859-1] (original) +++ trunk/PersistentObject/src/generators/manual_generator.php [iso-8859-1] Wed Jan 30 14:18:14 2008 @@ -50,7 +50,7 @@ )->where( $q->expr->eq( $db->quoteIdentifier( $def->idProperty->columnName ), - $q->bindValue( $this->id ) + $q->bindValue( $this->id, null, $def->idProperty->databaseType ) ) ); try @@ -94,7 +94,7 @@ } $q->set( $db->quoteIdentifier( $def->idProperty->columnName ), - $q->bindValue( $this->id ) + $q->bindValue( $this->id, null, $def->idProperty->databaseType ) ); } Modified: trunk/PersistentObject/src/handlers/delete_handler.php ============================================================================== --- trunk/PersistentObject/src/handlers/delete_handler.php [iso-8859-1] (original) +++ trunk/PersistentObject/src/handlers/delete_handler.php [iso-8859-1] Wed Jan 30 14:18:14 2008 @@ -87,7 +87,7 @@ ->where( $q->expr->eq( $this->database->quoteIdentifier( $def->idProperty->columnName ), - $q->bindValue( $idValue ) + $q->bindValue( $idValue, null, $def->idProperty->databaseType ) ) ); @@ -196,7 +196,9 @@ $q->bindValue( $objectState[ $def->columns[$map->sourceColumn]->propertyName - ] + ], + null, + $def->columns[$map->sourceColumn]->databaseType ) ), $q->expr->eq( @@ -206,7 +208,9 @@ $q->bindValue( $relatedObjectState[ $relatedDef->columns[$map->destinationColumn]->propertyName - ] + ], + null, + $relatedDef->columns[$map->destinationColumn]->databaseType ) ) ); Modified: trunk/PersistentObject/src/handlers/load_handler.php ============================================================================== --- trunk/PersistentObject/src/handlers/load_handler.php [iso-8859-1] (original) +++ trunk/PersistentObject/src/handlers/load_handler.php [iso-8859-1] Wed Jan 30 14:18:14 2008 @@ -99,7 +99,7 @@ )->where( $q->expr->eq( $this->database->quoteIdentifier( $def->idProperty->columnName ), - $q->bindValue( $id ) + $q->bindValue( $id, null, $def->idProperty->databaseType ) ) ); @@ -504,7 +504,9 @@ $map->destinationColumn ), $query->bindValue( - $objectState[$def->columns[$map->sourceColumn]->propertyName] + $objectState[$def->columns[$map->sourceColumn]->propertyName], + null, + $def->columns[$map->sourceColumn]->databaseType ) ) ); @@ -540,7 +542,9 @@ . "." . $this->database->quoteIdentifier( $map->relationSourceColumn ), $query->bindValue( - $objectState[$def->columns[$map->sourceColumn]->propertyName] + $objectState[$def->columns[$map->sourceColumn]->propertyName], + null, + $def->columns[$map->sourceColumn]->databaseType ) ), $query->expr->eq( Modified: trunk/PersistentObject/src/handlers/save_handler.php ============================================================================== --- trunk/PersistentObject/src/handlers/save_handler.php [iso-8859-1] (original) +++ trunk/PersistentObject/src/handlers/save_handler.php [iso-8859-1] Wed Jan 30 14:18:14 2008 @@ -325,7 +325,7 @@ $this->database->quoteIdentifier( $def->properties[$name]->columnName ), - $q->bindValue( $value ) + $q->bindValue( $value, null, $def->properties[$name]->databaseType ) ); } } @@ -423,7 +423,7 @@ $q->set( $this->database->quoteIdentifier( $def->properties[$name]->columnName ), - $q->bindValue( $value ) + $q->bindValue( $value, null, $def->properties[$name]->databaseType ) ); } } @@ -432,7 +432,7 @@ $this->database->quoteIdentifier( $def->idProperty->columnName ), - $q->bindValue( $idValue ) + $q->bindValue( $idValue, null, $def->idProperty->databaseType ) ) ); @@ -528,7 +528,9 @@ $q->bindValue( $objectState[ $def->columns[$map->sourceColumn]->propertyName - ] + ], + null, + $def->columns[$map->sourceColumn]->databaseType ) ); $insertColumns[] = $map->relationSourceColumn; @@ -542,7 +544,9 @@ $q->bindValue( $relatedObjectState[ $relatedDef->columns[$map->destinationColumn]->propertyName - ] + ], + null, + $relatedDef->columns[$map->destinationColumn]->databaseType ) ); $insertColumns[] = $map->relationDestinationColumn; Modified: trunk/PersistentObject/tests/database_type_test.php ============================================================================== --- trunk/PersistentObject/tests/database_type_test.php [iso-8859-1] (original) +++ trunk/PersistentObject/tests/database_type_test.php [iso-8859-1] Wed Jan 30 14:18:14 2008 @@ -11,7 +11,7 @@ require_once dirname( __FILE__ ) . "/data/database_type_test_object.php"; /** - * Tests ezcPersistentManyToManyRelation class. + * Tests for database type support. * * @package PersistentObject * @subpackage Tests @@ -77,13 +77,13 @@ public function testLoadCorrectPostgres() { - if ( $this->session->database->getName() !== 'pgsql' ) - { - $this->markTestSkipped( 'Will only be run with PostgreSQL.' ); + if ( $this->session->database->getName() === 'mysql' || $this->session->database->getName() === 'sqlite' ) + { + $this->markTestSkipped( 'Will only be run with databases other than MySQL and SQLite.' ); } $obj = $this->session->load( 'DatabaseTypeTestObject', 1 ); - $this->assertSame( + $this->assertEquals( '1', $obj->id ); @@ -97,7 +97,7 @@ ); $this->assertTrue( is_resource( $obj->lob ), - 'Postgre did not return a resource for a BLOB field.' + 'Database did not return a resource for a BLOB field.' ); } @@ -134,11 +134,11 @@ ); } - public function testLoadIncorrectPostgres() - { - if ( $this->session->database->getName() !== 'pgsql' ) - { - $this->markTestSkipped( 'Will only be run with PostgreSQL.' ); + public function testLoadIncorrectNonMysqlSqlite() + { + if ( $this->session->database->getName() === 'mysql' || $this->session->database->getName() === 'sqlite' ) + { + $this->markTestSkipped( 'Will only be run with databases other than MySQL and SQLite.' ); } $obj = $this->session->load( 'DatabaseTypeTestObject', 2 ); @@ -158,11 +158,266 @@ $this->assertSame( "Binary ", $obj->str, - 'Binary string not cut at null-char in Postgres text field.' + 'Binary string not cut at null-char in text field.' ); $this->assertTrue( is_resource( $obj->lob ), - 'Postgre did not return a resource for a BLOB field.' + 'Database did not return a resource for a BLOB field.' + ); + // Extract blob content + for ( $blobContent = ""; !feof( $obj->lob ); $blobContent .= fgets( $obj->lob ) ) {} + $this->assertEquals( + "Binary \x00 string", + $blobContent + ); + } + + public function testSaveCorrectMysqlSqlite() + { + if ( $this->session->database->getName() !== 'mysql' && $this->session->database->getName() !== 'sqlite' ) + { + $this->markTestSkipped( 'Will only be run with MySQL and SQLite.' ); + } + $obj = new DatabaseTypeTestObject(); + $obj->bool = true; + $obj->int = 4223; + $obj->str = "I'm a very sad non-binary string."; + $obj->lob = "I'm a funny \0 binary \x00 string."; + + $this->session->save( $obj ); + + $this->assertEquals( + 3, + $obj->id + ); + + // Refresh object from database + $this->session->refresh( $obj ); + + $this->assertEquals( + 3, + $obj->id + ); + $this->assertEquals( + 4223, + $obj->int + ); + $this->assertEquals( + "I'm a very sad non-binary string.", + $obj->str + ); + $this->assertEquals( + "I'm a funny \0 binary \x00 string.", + $obj->lob + ); + } + + public function testSaveCorrectNonMysqlSqlite() + { + if ( $this->session->database->getName() === 'mysql' || $this->session->database->getName() === 'sqlite' ) + { + $this->markTestSkipped( 'Will only be run with databases other than MySQL and SQLite.' ); + } + $obj = new DatabaseTypeTestObject(); + $obj->bool = true; + $obj->int = 4223; + $obj->str = "I'm a very sad non-binary string."; + $obj->lob = "I'm a funny \0 binary \x00 string."; + + $this->session->save( $obj ); + + $this->assertEquals( + 3, + $obj->id + ); + + // Refresh object from database + $this->session->refresh( $obj ); + + $this->assertEquals( + 3, + $obj->id + ); + $this->assertEquals( + 4223, + $obj->int + ); + $this->assertEquals( + "I'm a very sad non-binary string.", + $obj->str + ); + $this->assertTrue( + is_resource( $obj->lob ), + 'Database did not return a resource for a BLOB field.' + ); + // Extract blob content + for ( $blobContent = ""; !feof( $obj->lob ); $blobContent .= fgets( $obj->lob ) ) {} + $this->assertEquals( + "I'm a funny \0 binary \x00 string.", + $blobContent + ); + } + + public function testSaveIncorrectMysqlSqlite() + { + if ( $this->session->database->getName() !== 'mysql' && $this->session->database->getName() !== 'sqlite' ) + { + $this->markTestSkipped( 'Will only be run with MySQL and SQLite.' ); + } + $obj = new DatabaseTypeTestObject(); + $obj->bool = true; + $obj->int = 4223; + // Store binary string to string field + $obj->str = "I'm a funny \0 binary \x00 string."; + $obj->lob = "I'm a funny \0 binary \x00 string."; + + $this->session->save( $obj ); + + $this->assertEquals( + 3, + $obj->id + ); + + // Refresh object from database + $this->session->refresh( $obj ); + + $this->assertEquals( + 3, + $obj->id + ); + $this->assertEquals( + 4223, + $obj->int + ); + $this->assertEquals( + "I'm a funny \0 binary \x00 string.", + $obj->str + ); + $this->assertEquals( + "I'm a funny \0 binary \x00 string.", + $obj->lob + ); + } + + public function testSaveIncorrectNonMysqlSqlite() + { + if ( $this->session->database->getName() === 'mysql' || $this->session->database->getName() === 'sqlite' ) + { + $this->markTestSkipped( 'Will only be run with databases other than MySQL and SQLite.' ); + } + $obj = new DatabaseTypeTestObject(); + $obj->bool = true; + $obj->int = 4223; + // Store binary string to string field + $obj->str = "I'm a funny \0 binary \x00 string."; + $obj->lob = "I'm a funny \0 binary \x00 string."; + + $this->session->save( $obj ); + + $this->assertEquals( + 3, + $obj->id + ); + + // Refresh object from database + $this->session->refresh( $obj ); + + $this->assertEquals( + 3, + $obj->id + ); + $this->assertEquals( + 4223, + $obj->int + ); + $this->assertEquals( + "I'm a funny ", + $obj->str + ); + $this->assertTrue( + is_resource( $obj->lob ), + 'Database did not return a resource for a BLOB field.' + ); + // Extract blob content + for ( $blobContent = ""; !feof( $obj->lob ); $blobContent .= fgets( $obj->lob ) ) {} + $this->assertEquals( + "I'm a funny \0 binary \x00 string.", + $blobContent + ); + } + + public function testFindCorrectMysqlSqlite() + { + if ( $this->session->database->getName() !== 'mysql' && $this->session->database->getName() !== 'sqlite' ) + { + $this->markTestSkipped( 'Will only be run with MySQL and SQLite.' ); + } + $q = $this->session->createFindQuery( 'DatabaseTypeTestObject' ); + $q->where( + $q->expr->eq( + 'lob', + $q->bindValue( "Binary \x00 string", null, PDO::PARAM_LOB ) + ) + ); + $objs = $this->session->find( $q, 'DatabaseTypeTestObject' ); + $obj = $objs[0]; + + $this->assertSame( + '1', + $obj->id + ); + $this->assertSame( + '23', + $obj->int + ); + $this->assertSame( + 'Non binary string', + $obj->str + ); + $this->assertEquals( + "Binary \x00 string", + $obj->lob, + 'Binary string not returned completly from BLOB field.' + ); + } + + public function testFindCorrectNonMysqlSqlite() + { + if ( $this->session->database->getName() === 'mysql' || $this->session->database->getName() === 'sqlite' ) + { + $this->markTestSkipped( 'Will only be run with databases other than MySQL and SQLite.' ); + } + $q = $this->session->createFindQuery( 'DatabaseTypeTestObject' ); + $q->where( + $q->expr->eq( + 'lob', + $q->bindValue( "Binary \x00 string", null, PDO::PARAM_LOB ) + ) + ); + $objs = $this->session->find( $q, 'DatabaseTypeTestObject' ); + $obj = $objs[0]; + + $this->assertEquals( + '1', + $obj->id + ); + $this->assertSame( + '23', + $obj->int + ); + $this->assertSame( + 'Non binary string', + $obj->str + ); + $this->assertTrue( + is_resource( $obj->lob ), + 'Database did not return a resource for a BLOB field.' + ); + // Extract blob content + for ( $blobContent = ""; !feof( $obj->lob ); $blobContent .= fgets( $obj->lob ) ) {} + $this->assertEquals( + "Binary \x00 string", + $blobContent ); } } Modified: trunk/PersistentObject/tests/suite.php ============================================================================== --- trunk/PersistentObject/tests/suite.php [iso-8859-1] (original) +++ trunk/PersistentObject/tests/suite.php [iso-8859-1] Wed Jan 30 14:18:14 2008 @@ -39,6 +39,8 @@ require_once( 'object_columns_test.php' ); require_once 'property_date_time_converter_test.php'; +require_once 'database_type_test.php'; + /** * @package PersistentObject * @subpackage Tests @@ -75,6 +77,7 @@ $this->addTest( ezcPersistentObjectPropertiesTest::suite() ); $this->addTest( ezcPersistentObjectColumnsTest::suite() ); $this->addTest( ezcPersistentPropertyDateTimeConverterTest::suite() ); + $this->addTest( ezcPersistentDatabaseTypeTest::suite() ); } public static function suite() -- svn-components mailing list svn-components@lists.ez.no http://lists.ez.no/mailman/listinfo/svn-components