In this example, you’ll re-create the previously demonstrated swap meet scenario, this time using PHP. Keeping nonrelevant details to a minimum, the page would display a product and offer the user a means of adding the item to their shopping cart; it might look like this:
<p>
<strong>Abacus</strong><br />
Owner: Howard<br />
Price: $12.99<br />
Low on computing power? Use an abacus!<br />
<form action="purchase.php" method="post">
<input type="hidden" name="itemid" value="1" />
<br />
<input type="submit" value="Purchase!" />
</form>
</p>
As you may imagine, the data displayed in this page could easily be extracted from the participant and trunk tables. Rendered in the browser, this page would look like Figure 36-1.
Figure 36-1. A typical product display
Clicking the Purchase! button would take the user to the purchase.php script. One variable is passed along, namely $_POST['itemid']. By using this variable in conjunction with some hypothetical class methods for retrieving the participant and trunk item primary keys, you can use PostgreSQL transactions to add the product to the database and deduct and credit the participants’ accounts accordingly, as shown in Listing 36-1.
Listing 36-1. Swapping Items with purchase.php
<?php
session_start();
include "pgsql.class.php";
// Retrieve the participant's primary key using some ficticious // class that refers to some sort of user session table, // mapping a session ID back to a specific user.
$participant = new participant();
$buyerid = $participant->getparticipantkey();
// Give the POSTed item id a friendly variable name $itemid = $_POST['itemid'];
// Retrieve the item seller and price // using some ficticious item class.
$item = new item();
$sellerid = $item->getitemowner($itemid);
$price = $item->getprice($itemid);
// Instantiate the pgsql class
$pgsqldb = new pgsql("localhost","company","webuser","secret");
// Connect to the PostgreSQL database $pgsqldb->connect();
// Start by assuming the transaction operations will all succeed $transactionsuccess = TRUE;
// Start the transaction $pgsqldb->begintransaction();
// Debit the buyer's account
$query = "UPDATE participant SET cash=cash-$price WHERE participantid=$buyerid";
$result = $pgsqldb->query($query);
if (!$result OR $result->affectedrows() != 1) $transactionsuccess = FALSE;
// Credit seller's account
$query = "UPDATE participant SET cash=cash+$price WHERE participantid=$sellerid";
$result = $pgsqldb->query($query);
if (!$result OR $result->affectedrows() != 1) $transactionsuccess = FALSE;
// Update the trunk item ownership
$query = "UPDATE trunk SET participantid=$buyerid WHERE trunkid=$itemid";
$result = $pgsqldb->query($query);
if (!$result OR $result->affectedrows() != 1) $transactionsuccess = FALSE;
// If $transactionstatus is True, commit the transaction // Otherwise roll back the changes
if ($transactionsuccess) { $pgsqldb->commit();
echo "The swap took place! Congratulations!";
} else {
$pgsqldb->rollback();
echo "There was a problem with the swap! :-(";
}
?>
As you can see, both the status of the query and the affected rows were checked after the execution of each step of the transaction. If either failed at any time, $transactionsuccess was set to FALSE and all steps were rolled back at the conclusion of the script. Of course, you could optimize this script to start each query in lockstep, with each query taking place only after a determination has been made that the prior query has correctly executed, but that exercise is left to you to perform on your own.
Summary
Database transactions are of immense use when modeling your business processes, because they help to ensure the integrity of your organization’s most valuable asset: its information.
If you use database transactions prudently, they are a great asset when building database- driven applications.
In the next and final chapter, not only will we demonstrate just how easy it is to use PostgreSQL’s built-in utilities to both import and export large amounts of data but we’ll also take a look at how you can use simple PHP scripts to do cool things such as format forms-based information for viewing via a spreadsheet application, such as Microsoft Excel.
777
■ ■ ■
C H A P T E R 3 7
Importing and Exporting Data
Back in the Stone Age, cavemen never really had any issues with data incompatibility, as slabs of rock and one’s own memory were the only storage media. Copying data involved pulling out the old chisel and getting busy on a new piece of granite. Of course, these days the situation is much different, as hundreds of data storage solutions exist. For instance, how would one go about converting data found in a PostgreSQL table into a format suitable for viewing in a spreadsheet, or vice versa? If this is done in a non-optimal fashion, you could spend hours, and even days or weeks, massaging the converted data into a usable format. It’s unlikely the marketing department or company president is going to be willing to wait more than a few minutes for such data, much less want to put in a special request to have it prepared for them.
So how can you programmatically create mechanisms for easily importing and exporting data into other formats? In this chapter, you’ll learn how to do so with ease, using a variety of SQL commands, PostgreSQL-specific commands, and programming techniques. Specifically, this chapter introduces the following topics:
• PostgreSQL’s COPY Command: PostgreSQL’s COPY command and its PHP equivalents, pg_copy_to() and pg_copy_from(), make importing and exporting table data a snap. You’ll see how to accomplish these tasks both from the command line and from a PHP script.
• Importing and exporting data with phpPgAdmin: phpPgAdmin offer user-friendly yet powerful tools for easily importing and exporting data without having to jump through programmatic hoops.
■Note In Chapter 26, you learned about several of PostgreSQL’s backup- and recovery-related utilities, including pg_dump, pg_dumpall, and pg_restore, that are capable of helping you to eliminate these issues. However, these commands are generally most efficiently used when importing data from and restoring data to a PostgreSQL database, rather than readying it for use within another data manager or viewer.