libretime/library/propel/test/bookstore-packaged-test.php

812 lines
22 KiB
PHP

<?php
/**
* This file is part of the Propel package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @license MIT License
*/
/**
* Simple test script for Propel drivers.
*
* This script will no do in-depth testing, but is designed to test whether drivers
* are correctly performing basic operations -- SELECT, UPDATE, DELETE, limit support,
* prepared query emulation, etc.
*
* IMPORTANT:
*
* Use this script with a clean version of the [example] bookstore database. If records
* already exist, an error will be displayed.
*
* TODO:
* A more advanced driver test system should be developed that could test capabilities
* of driver-specific things like callable statements (stored procedures), etc. Perhaps break
* functionality into class & provide ability to subclass.
*
* @author Hans Lellelid <hans@xmpl.org>
* @version $Revision: 1612 $
*/
// Setup configuration. It is expected that the bookstore-conf.php file exists in ../build/conf
//
error_reporting(E_ALL);
$conf_path = realpath(dirname(__FILE__) . '/../projects/bookstore-packaged/build/conf/bookstore-packaged-conf.php');
if (!file_exists($conf_path)) {
print "Make sure that you specify properties in conf/bookstore-packaged.properties and "
."build propel before running this script.";
exit;
}
// Add PHP_CLASSPATH, if set
if (getenv("PHP_CLASSPATH")) {
set_include_path(getenv("PHP_CLASSPATH") . PATH_SEPARATOR . get_include_path());
}
// Add build/classes/ and classes/ to path
set_include_path(
realpath(dirname(__FILE__) . '/../projects/bookstore-packaged/build/classes') . PATH_SEPARATOR .
dirname(__FILE__) . '/../../runtime/classes' . PATH_SEPARATOR .
get_include_path()
);
// Require classes.
require_once 'propel/Propel.php';
require_once 'author/Author.php';
require_once 'publisher/Publisher.php';
require_once 'book/Book.php';
require_once 'review/Review.php';
include_once 'media/Media.php';
include_once 'log/BookstoreLog.php';
include_once 'book_club_list/BookClubList.php';
include_once 'book_club_list/BookListRel.php';
include_once 'Benchmark/Timer.php';
$timer = new Benchmark_Timer;
$timer->start();
// Some utility functions
function boolTest($cond) {
if ($cond) {
return "[OK]\n";
} else {
return "[FAILED]\n";
}
}
try {
// Initialize Propel
Propel::init($conf_path);
} catch (Exception $e) {
die("Error initializing propel: ". $e->__toString());
}
function check_tables_empty() {
try {
print "\nChecking to see that tables are empty\n";
print "-------------------------------------\n\n";
print "Ensuring that there are no records in [author] table: ";
$res = AuthorPeer::doSelect(new Criteria());
print boolTest(empty($res));
print "Ensuring that there are no records in [publisher] table: ";
$res2 = PublisherPeer::doSelect(new Criteria());
print boolTest(empty($res2));
print "Ensuring that there are no records in [book] table: ";
$res3 = AuthorPeer::doSelect(new Criteria());
print boolTest(empty($res3));
print "Ensuring that there are no records in [review] table: ";
$res4 = ReviewPeer::doSelect(new Criteria());
print boolTest(empty($res4));
print "Ensuring that there are no records in [media] table: ";
$res5 = MediaPeer::doSelect(new Criteria());
print boolTest(empty($res5));
print "Ensuring that there are no records in [book_club_list] table: ";
$res6 = BookClubListPeer::doSelect(new Criteria());
print boolTest(empty($res6));
print "Ensuring that there are no records in [book_x_list] table: ";
$res7 = BookListRelPeer::doSelect(new Criteria());
print boolTest(empty($res7));
return (empty($res) && empty($res2) && empty($res3) && empty($res4) && empty($res5));
} catch (Exception $e) {
die("Error ensuring tables were empty: " . $e->__toString());
}
}
// Check to see if records already exist in any of the three tables. If so, display an error
// and exit.
if (!check_tables_empty()) {
die("Tables must be empty to perform these tests.");
}
// Add publisher records
// ---------------------
try {
print "\nAdding some new publishers to the list\n";
print "--------------------------------------\n\n";
$scholastic = new Publisher();
$scholastic->setName("Scholastic");
// do not save, will do later to test cascade
print "Added publisher \"Scholastic\" [not saved yet].\n";
$morrow = new Publisher();
$morrow->setName("William Morrow");
$morrow->save();
$morrow_id = $morrow->getId();
print "Added publisher \"William Morrow\" [id = $morrow_id].\n";
$penguin = new Publisher();
$penguin->setName("Penguin");
$penguin->save();
$penguin_id = $penguin->getId();
print "Added publisher \"Penguin\" [id = $penguin_id].\n";
$vintage = new Publisher();
$vintage->setName("Vintage");
$vintage->save();
$vintage_id = $vintage->getId();
print "Added publisher \"Vintage\" [id = $vintage_id].\n";
} catch (Exception $e) {
die("Error adding publisher: " . $e->__toString());
}
// Add author records
// ------------------
try {
print "\nAdding some new authors to the list\n";
print "--------------------------------------\n\n";
$rowling = new Author();
$rowling->setFirstName("J.K.");
$rowling->setLastName("Rowling");
// no save()
print "Added author \"J.K. Rowling\" [not saved yet].\n";
$stephenson = new Author();
$stephenson->setFirstName("Neal");
$stephenson->setLastName("Stephenson");
$stephenson->save();
$stephenson_id = $stephenson->getId();
print "Added author \"Neal Stephenson\" [id = $stephenson_id].\n";
$byron = new Author();
$byron->setFirstName("George");
$byron->setLastName("Byron");
$byron->save();
$byron_id = $byron->getId();
print "Added author \"George Byron\" [id = $byron_id].\n";
$grass = new Author();
$grass->setFirstName("Gunter");
$grass->setLastName("Grass");
$grass->save();
$grass_id = $grass->getId();
print "Added author \"Gunter Grass\" [id = $grass_id].\n";
} catch (Exception $e) {
die("Error adding author: " . $e->__toString());
}
// Add book records
// ----------------
try {
print "\nAdding some new books to the list\n";
print "-------------------------------------\n\n";
$phoenix = new Book();
$phoenix->setTitle("Harry Potter and the Order of the Phoenix");
$phoenix->setISBN("043935806X");
print "Trying cascading save (Harry Potter): ";
$phoenix->setAuthor($rowling);
$phoenix->setPublisher($scholastic);
$phoenix->save();
$phoenix_id = $phoenix->getId();
print boolTest(true);
print "Added book \"Harry Potter and the Order of the Phoenix\" [id = $phoenix_id].\n";
$qs = new Book();
$qs->setISBN("0380977427");
$qs->setTitle("Quicksilver");
$qs->setAuthor($stephenson);
$qs->setPublisher($morrow);
$qs->save();
$qs_id = $qs->getId();
print "Added book \"Quicksilver\" [id = $qs_id].\n";
$dj = new Book();
$dj->setISBN("0140422161");
$dj->setTitle("Don Juan");
$dj->setAuthor($byron);
$dj->setPublisher($penguin);
$dj->save();
$dj_id = $qs->getId();
print "Added book \"Don Juan\" [id = $dj_id].\n";
$td = new Book();
$td->setISBN("067972575X");
$td->setTitle("The Tin Drum");
$td->setAuthor($grass);
$td->setPublisher($vintage);
$td->save();
$td_id = $td->getId();
print "Added book \"The Tin Drum\" [id = $dj_id].\n";
} catch (Exception $e) {
die("Error saving book: " . $e->__toString());
}
// Add review records
// ------------------
try {
print "\nAdding some book reviews to the list\n";
print "------------------------------------\n\n";
$r1 = new Review();
$r1->setBook($phoenix);
$r1->setReviewedBy("Washington Post");
$r1->setRecommended(true);
$r1->setReviewDate(time());
$r1->save();
$r1_id = $r1->getId();
print "Added Washington Post book review [id = $r1_id].\n";
$r2 = new Review();
$r2->setBook($phoenix);
$r2->setReviewedBy("New York Times");
$r2->setRecommended(false);
$r2->setReviewDate(time());
$r2->save();
$r2_id = $r2->getId();
print "Added New York Times book review [id = $r2_id].\n";
} catch (Exception $e) {
die("Error saving book review: " . $e->__toString());
}
// Perform a "complex" search
// --------------------------
try {
print "\nDoing complex search on books\n";
print "-----------------------------\n\n";
$crit = new Criteria();
$crit->add(BookPeer::TITLE, 'Harry%', Criteria::LIKE);
print "Looking for \"Harry%\": ";
$results = BookPeer::doSelect($crit);
print boolTest(count($results) === 1);
$crit2 = new Criteria();
$crit2->add(BookPeer::ISBN, array("0380977427", "0140422161"), Criteria::IN);
$results = BookPeer::doSelect($crit2);
print "Looking for ISBN IN (\"0380977427\", \"0140422161\"): ";
print boolTest(count($results) === 2);
} catch (Exception $e) {
die("Error while performing complex query: " . $e->__toString());
}
// Perform a "limit" search
// ------------------------
try {
print "\nDoing LIMITed search on books\n";
print "-----------------------------\n\n";
$crit = new Criteria();
$crit->setLimit(2);
$crit->setOffset(1);
$crit->addAscendingOrderByColumn(BookPeer::TITLE);
print "Checking to make sure correct number returned: ";
$results = BookPeer::doSelect($crit);
print boolTest(count($results) === 2);
print "Checking to make sure correct books returned: ";
// we ordered on book title, so we expect to get
print boolTest( $results[0]->getTitle() == "Harry Potter and the Order of the Phoenix" && $results[1]->getTitle() == "Quicksilver" );
} catch (Exception $e) {
die("Error while performing LIMIT query: " . $e->__toString());
}
// Perform a lookup & update!
// --------------------------
try {
print "\nUpdating just-created book title\n";
print "--------------------------------\n\n";
print "First finding book by PK (=$qs_id) .... ";
try {
$qs_lookup = BookPeer::retrieveByPk($qs_id);
} catch (Exception $e) {
print "ERROR!\n";
die("Error retrieving by pk: " . $e->__toString());
}
if ($qs_lookup) {
print "FOUND!\n";
} else {
print "NOT FOUND :(\n";
die("Couldn't find just-created book: book_id = $qs_id");
}
try {
$new_title = "Quicksilver (".crc32(uniqid(rand())).")";
print "Attempting to update found object (".$qs_lookup->getTitle()." -> ".$new_title."): ";
$qs_lookup->setTitle($new_title);
$qs_lookup->save();
print boolTest(true);
} catch (Exception $e) {
die("Error saving (updating) book: " . $e->__toString());
}
print "Making sure object was correctly updated: ";
$qs_lookup2 = BookPeer::retrieveByPk($qs_id);
print boolTest($qs_lookup2->getTitle() == $new_title);
} catch (Exception $e) {
die("Error updating book: " . $e->__toString());
}
// Test some basic DATE / TIME stuff
// ---------------------------------
try {
print "\nTesting the DATE/TIME columns\n";
print "-----------------------------\n\n";
// that's the control timestamp.
$control = strtotime('2004-02-29 00:00:00');
// should be two in the db
$r = ReviewPeer::doSelectOne(new Criteria());
$r_id = $r->getId();
$r->setReviewDate($control);
$r->save();
$r2 = ReviewPeer::retrieveByPk($r_id);
print "Checking ability to fetch native unix timestamp: ";
print boolTest($r2->getReviewDate(null) === $control);
print "Checking ability to use date() formatter: ";
print boolTest($r2->getReviewDate('n-j-Y') === '2-29-2004');
print "[FYI] Here's the strftime() formatter for current locale: " . $r2->getReviewDate('%x') . "\n";
} catch (Exception $e) {
die("Error test date/time: " . $e->__toString());
}
// Handle BLOB/CLOB Columns
// ------------------------
try {
print "\nTesting the BLOB/CLOB columns\n";
print "-------------------------------\n\n";
$blob_path = dirname(__FILE__) . '/etc/lob/tin_drum.gif';
$blob2_path = dirname(__FILE__) . '/etc/lob/propel.gif';
$clob_path = dirname(__FILE__) . '/etc/lob/tin_drum.txt';
$m1 = new Media();
$m1->setBook($phoenix);
$m1->setCoverImage(file_get_contents($blob_path));
$m1->setExcerpt(file_get_contents($clob_path));
$m1->save();
$m1_id = $m1->getId();
print "Added Media collection [id = $m1_id].\n";
print "Looking for just-created mediat by PK (=$m1_id) .... ";
try {
$m1_lookup = MediaPeer::retrieveByPk($m1_id);
} catch (Exception $e) {
print "ERROR!\n";
die("Error retrieving media by pk: " . $e->__toString());
}
if ($m1_lookup) {
print "FOUND!\n";
} else {
print "NOT FOUND :(\n";
die("Couldn't find just-created media item: media_id = $m1_id");
}
print "Making sure BLOB was correctly updated: ";
print boolTest( $m1_lookup->getCoverImage()->getContents() === file_get_contents($blob_path));
print "Making sure CLOB was correctly updated: ";
print boolTest((string) $m1_lookup->getExcerpt()->getContents() === file_get_contents($clob_path));
// now update the BLOB column and save it & check the results
$b = $m1_lookup->getCoverImage();
$b->setContents(file_get_contents($blob2_path));
$m1_lookup->setCoverImage($b);
$m1_lookup->save();
try {
$m2_lookup = MediaPeer::retrieveByPk($m1_id);
} catch (Exception $e) {
print "ERROR!\n";
die("Error retrieving media by pk: " . $e->__toString());
}
print "Making sure BLOB was correctly overwritten: ";
print boolTest($m2_lookup->getCoverImage()->getContents() === file_get_contents($blob2_path));
} catch (Exception $e) {
die("Error doing blob/clob updates: " . $e->__toString());
}
// Test Validators
// ---------------
try {
print "\nTesting the column validators\n";
print "-----------------------------\n\n";
$bk1 = new Book();
$bk1->setTitle("12345"); // min length is 10
$ret = $bk1->validate();
print "Making sure validation failed: ";
print boolTest($ret !== true);
print "Making sure 1 validation message was returned: ";
print boolTest(count($ret) === 1);
print "Making sure expected validation message was returned: ";
$el = array_shift($ret);
print boolTest(stripos($el->getMessage(), "must be more than") !== false);
print "\n(Unique validator)\n";
$bk2 = new Book();
$bk2->setTitle("Don Juan");
$ret = $bk2->validate();
print "Making sure validation failed: ";
print boolTest($ret !== true);
print "Making sure 1 validation message was returned: ";
print boolTest(count($ret) === 1);
print "Making sure expected validation message was returned: ";
$el = array_shift($ret);
print boolTest(stripos($el->getMessage(), "Book title already in database.") !== false);
print "\n(Now trying some more complex validation.)\n";
$auth1 = new Author();
$auth1->setFirstName("Hans");
// last name required; will fail
$bk1->setAuthor($auth1);
$rev1 = new Review();
$rev1->setReviewDate("08/09/2001");
// will fail: reviewed_by column required
$bk1->addReview($rev1);
$ret2 = $bk1->validate();
print "Making sure 6 validation messages were returned: ";
print boolTest(count($ret2) === 6);
print "Making sure correct columns failed: ";
print boolTest(array_keys($ret2) === array(
AuthorPeer::LAST_NAME,
AuthorPeer::EMAIL,
AuthorPeer::AGE,
BookPeer::TITLE,
ReviewPeer::REVIEWED_BY,
ReviewPeer::STATUS
));
$bk2 = new Book();
$bk2->setTitle("12345678901"); // passes
$auth2 = new Author();
$auth2->setLastName("Blah"); //passes
$auth2->setEmail("some@body.com"); //passes
$auth2->setAge(50); //passes
$bk2->setAuthor($auth2);
$rev2 = new Review();
$rev2->setReviewedBy("Me!"); // passes
$rev2->setStatus("new"); // passes
$bk2->addReview($rev2);
$ret3 = $bk2->validate();
print "Making sure complex validation can pass: ";
print boolTest($ret3 === true);
} catch (Exception $e) {
die("Error doing validation tests: " . $e->__toString());
}
// Test doCount()
//
try {
print "\nTesting doCount() functionality\n";
print "-------------------------------\n\n";
$c = new Criteria();
$records = BookPeer::doSelect($c);
$count = BookPeer::doCount($c);
print "Making sure correct number of results: ";
print boolTest(count($records) === $count);
} catch (Exception $e) {
die("Error deleting book: " . $e->__toString());
}
// Test many-to-many relationships
// ---------------
try {
print "\nTesting many-to-many relationships\n";
print "-----------------------------\n\n";
// init book club list 1 with 2 books
$blc1 = new BookClubList();
$blc1->setGroupLeader("Crazyleggs");
$blc1->setTheme("Happiness");
$brel1 = new BookListRel();
$brel1->setBook($phoenix);
$brel2 = new BookListRel();
$brel2->setBook($dj);
$blc1->addBookListRel($brel1);
$blc1->addBookListRel($brel2);
$blc1->save();
print "Making sure BookClubList 1 was saved: ";
print boolTest(!is_null($blc1->getId()));
// init book club list 2 with 1 book
$blc2 = new BookClubList();
$blc2->setGroupLeader("John Foo");
$blc2->setTheme("Default");
$brel3 = new BookListRel();
$brel3->setBook($phoenix);
$blc2->addBookListRel($brel3);
$blc2->save();
print "Making sure BookClubList 2 was saved: ";
print boolTest(!is_null($blc2->getId()));
// re-fetch books and lists from db to be sure that nothing is cached
$crit = new Criteria();
$crit->add(BookPeer::ID, $phoenix->getId());
$phoenix = BookPeer::doSelectOne($crit);
print "Making sure book 'phoenix' has been re-fetched from db: ";
print boolTest(!empty($phoenix));
$crit = new Criteria();
$crit->add(BookClubListPeer::ID, $blc1->getId());
$blc1 = BookClubListPeer::doSelectOne($crit);
print "Making sure BookClubList 1 has been re-fetched from db: ";
print boolTest(!empty($blc1));
$crit = new Criteria();
$crit->add(BookClubListPeer::ID, $blc2->getId());
$blc2 = BookClubListPeer::doSelectOne($crit);
print "Making sure BookClubList 2 has been re-fetched from db: ";
print boolTest(!empty($blc2));
$relCount = $phoenix->countBookListRels();
print "Making sure book 'phoenix' has 2 BookListRels: ";
print boolTest($relCount == 2);
$relCount = $blc1->countBookListRels();
print "Making sure BookClubList 1 has 2 BookListRels: ";
print boolTest($relCount == 2);
$relCount = $blc2->countBookListRels();
print "Making sure BookClubList 2 has 1 BookListRel: ";
print boolTest($relCount == 1);
} catch (Exception $e) {
die("Error doing many-to-many relationships tests: " . $e->__toString());
}
// Test multiple databases
// ---------------
try {
print "\nTesting multiple databases\n";
print "-----------------------------\n\n";
$line = new BookstoreLog();
$line->setIdent('bookstore-packaged-test');
$line->setTime(time());
$line->setMessage('We are testing to write something to the log database ...');
$line->setPriority('debug');
$line->save();
$line_id = $line->getId();
print "Making sure BookstoreLog was saved: ";
print boolTest(!empty($line_id));
} catch (Exception $e) {
die("Error doing multiple databases tests: " . $e->__toString());
}
// Cleanup (tests DELETE)
// ----------------------
try {
print "\nRemoving books that were just created\n";
print "-------------------------------------\n\n";
print "First finding book by PK (=$phoenix_id) .... ";
try {
$hp = BookPeer::retrieveByPk($phoenix_id);
} catch (Exception $e) {
print "ERROR!\n";
die("Error retrieving by pk: " . $e->__toString());
}
if ($hp) {
print "FOUND!\n";
} else {
print "NOT FOUND :(\n";
die("Couldn't find just-created book: book_id = $phoenix_id");
}
print "Attempting to delete [multi-table] by found pk: ";
$c = new Criteria();
$c->add(BookPeer::ID, $hp->getId());
// The only way for cascading to work currently
// is to specify the author_id and publisher_id (i.e. the fkeys
// have to be in the criteria).
$c->add(AuthorPeer::ID, $hp->getId());
$c->add(PublisherPeer::ID, $hp->getId());
$c->setSingleRecord(true);
BookPeer::doDelete($c);
print boolTest(true);
print "Checking to make sure correct records were removed.\n";
print "\tFrom author table: ";
$res = AuthorPeer::doSelect(new Criteria());
print boolTest(count($res) === 3);
print "\tFrom publisher table: ";
$res2 = PublisherPeer::doSelect(new Criteria());
print boolTest(count($res2) === 3);
print "\tFrom book table: ";
$res3 = BookPeer::doSelect(new Criteria());
print boolTest(count($res3) === 3);
print "Attempting to delete books by complex criteria: ";
$c = new Criteria();
$cn = $c->getNewCriterion(BookPeer::ISBN, "043935806X");
$cn->addOr($c->getNewCriterion(BookPeer::ISBN, "0380977427"));
$cn->addOr($c->getNewCriterion(BookPeer::ISBN, "0140422161"));
$c->add($cn);
BookPeer::doDelete($c);
print boolTest(true);
print "Attempting to delete book [id = $td_id]: ";
$td->delete();
print boolTest(true);
print "Attempting to delete author [id = $stephenson_id]: ";
AuthorPeer::doDelete($stephenson_id);
print boolTest(true);
print "Attempting to delete author [id = $byron_id]: ";
AuthorPeer::doDelete($byron_id);
print boolTest(true);
print "Attempting to delete author [id = $grass_id]: ";
$grass->delete();
print boolTest(true);
print "Attempting to delete publisher [id = $morrow_id]: ";
PublisherPeer::doDelete($morrow_id);
print boolTest(true);
print "Attempting to delete publisher [id = $penguin_id]: ";
PublisherPeer::doDelete($penguin_id);
print boolTest(true);
print "Attempting to delete publisher [id = $vintage_id]: ";
$vintage->delete();
print boolTest(true);
// These have to be deleted manually also since we have onDelete
// set to SETNULL in the foreign keys in book. Is this correct?
print "Attempting to delete author [lastname = 'Rowling']: ";
$rowling->delete();
print boolTest(true);
print "Attempting to delete publisher [lastname = 'Scholastic']: ";
$scholastic->delete();
print boolTest(true);
print "Attempting to delete BookClubList 1: ";
$blc1->delete();
print boolTest(true);
print "Attempting to delete BookClubList 2: ";
$blc2->delete();
print boolTest(true);
} catch (Exception $e) {
die("Error deleting book: " . $e->__toString());
}
// Check again to make sure that tables are empty
// ----------------------------------------------
check_tables_empty();
$timer->stop();
print $timer->display();