The Main Routine
The following is the main routine for the tutorial. The line numbers correspond to the comments that follow the code.
 
#include <rw/db/db.h> //1
#include "tututil.h" //2
#include "invoice.h" //3
 
int main(int argc, char** argv) //4
{
associateStreams("t7in.dat", "t7out.txt", "t7err.txt"); //5
RWDBManager::setErrorHandler(outputStatus); //6
 
RWCString serverType, serverName, userName,
password, databaseName, pstring; //7
 
initializeDatabaseArguments(argc, argv, serverType,
serverName, userName, password,
databaseName, pstring); //8
 
RWDBDatabase aDB = RWDBManager::database(serverType, serverName,
userName, password,
databaseName,pstring); //9
if( aDB.isValid() )
{
unsigned long aCustomerID; //10
unsigned long aVideoID; //11
while (!inStream.eof()
&& !inStream.bad() && !inStream.fail()) { //12
inStream >> aCustomerID; //13
if (!inStream.eof()
&& !inStream.bad() && !inStream.fail()) //14
// create an invoice
VVInvoice aInvoice(aCustomerID, aDB); //15
// add each video rental
do { //16
inStream >> aVideoID; //17
if (aVideoID) { //18
aInvoice.addRental(aVideoID); //19
}
} while (aVideoID); //20
// print the invoice
aInvoice.print(); //21
}
}
}
closeStreams("t7in.dat", "t7out.txt", "t7err.txt");
return 0; //22
} //23
 
Here is a line-by-line description of the program:
//1 Include the declarations for the DB Interface Module classes used in this program.
//2 Include the declarations for the utility routines commonly used by all the tutorials.
//3 Include the declaration of the VVInvoice class used only by this tutorial.
//4-8 These lines are for initialization. They are common to all the tutorials and are explained in the comments in The Main Routine.
//9 Here an actual connection to a database server is established. The variable aDB serves as a handle to the database defined by arguments to the RWDBManager::database() function.
//10-11 These are definitions for the customer ID and video ID. These will contain the actual data read in from the stream. The values will be passed to the VVInvoice constructor and the addRental()member function.
//12 This is the start of the main processing loop, which reads the data from the stream and passes the data to the two processing routines. The condition of the stream is tested to determine if all the data was processed.
//13 The first value in the stream is read into a customer ID.
//14 This line tests the stream for end-of-file, which is only read when a customer ID is read, so the extra statement is needed.
//15 A VVInvoice object is constructed with the customer ID fetched on //14.
//16 This is the start of the video rental processing loop. Each line of the stream contains a customer ID followed by a series of video IDs. The series of videos is ended by a video ID equal to zero. If a valid video ID is read, a rental transaction is added to the invoice.
//17 The next value in the stream is read into a video ID.
//18 The video ID is checked to determine if the end of the video list was read. If the video ID is valid, a rental transaction is added to the invoice.
//19 A rental is added to the invoice using the video ID obtained above via a call to the VVInvoice addRental() function. Further explanation of addRental() is in VVInvoice::addRental.
//20 End of the video rental processing loop, which checks the video ID for a zero value that marks the end of the series.
//21 After all the rentals for a customer have been added, the invoice is printed. An invoice retains all knowledge of customer ID, invoice ID, and rentals, so no parameters are needed for the print() member function. Because most of the code in print() deals with output formatting, and the database lookup routines were featured in previous tutorials, there is no line-by-line explanation in this tutorial.
//22 Normal program exit.
//23 Destructors for all the objects are called here. The database closes automatically when its destructor is called.