VVContactRepository::mailingLabels
Now that the construction of the VVContactRepository instance is complete, the next step in the main routine program was to call the mailingLabels() member function. Here is the source code for VVContactRepository::mailingLabels() from the file conrep.cpp and the description of the code:
 
VVContactRepository&
VVContactRepository::mailingLabels(ostream& o) { //1
RWDBSelector select = aDB_.selector(); //2
select << table_; //3
select.orderBy(nameColumn_); //4
RWDBReader aReader = select.reader(); //5
VVContact aContact; //6
while (aReader()) { //7
aReader >> aContact; //8
aContact.mailingLabel(o); //9
o << endl << endl; //10
}
 
return *this; //11
}
//1 This line defines the mailingLabels() member function for the class VVContactRepository, which receives an output stream as its argument.
//2 The class VVContactRepository kept an associated database named aDB_ in the VVContactRepository constructor. On this line, it uses the database to create an instance of RWDBSelector, which is an object used to select data from a database.
//3 An associated RWDBTable, called table_, was also kept by the constructor. Here the selector is asked to select all the data from table_. In SQL terms, this is like SELECT * from the table.
//4 We would like our mailing labels sorted into alphabetical order, so the selector is instructed to orderBy the column in which the customer’s name is stored. This column was stored by the constructor in the nameColumn_ variable. This is analogous to the SQL ORDER BY NAME.
//5 Here the table is used to create an instance of RWDBReader. A reader can be thought of as both an iterator and a stream. It iterates through the rows of the table that created it, and can stream out the values of the columns in each row. If we had not been concerned with ordering the results, //2-//5 could have been replaced with the single statement RWDBReader aReader = table_.reader();.
//6 The table in the database in this tutorial has fields that match the instance variables in the class VVContact. This routine is about to start reading data from the table, and an instance of VVContact is a made-to-order place to store information from that table. This line creates an instance of VVContact to serve as a temporary variable for a single row from the table.
//7 A reader is like an iterator. It must be advanced to the next row. Invoking the reader with the operator() member function advances the reader to the next row. If there are no more rows, then operator() returns a zero value and the loop terminates.
//8 A reader is also like a stream. Here an entire row of data flows from the reader into the instance of VVContact. An explanation of this can be found in operator>>() for VVContact.
//9 Since the instance of VVContact is now complete, its own member functions can be called. The mailingLabel() member function simply outputs the instance variables for this customer in a form acceptable to the U.S. Postal Service.
//10 The mailing labels need to be delimited in some manner, so we add two blank lines.
//11 This routine needs to return an instance of VVContactRepository, so it returns itself. At this point, destructors for the VVContact instance, RWDBSelector instance, and the RWDBReader instance are called. There are no pending rows from the RWDBReader. If there were, they would have been quietly and automatically discarded here.