/*
* CatalogItem.java
*/
import java.sql.*;
/** A CatalogItem object represents one record in the
* catalog
table.
A record in the
* catalog
table is a description of a book. It does
* not represent the physical existence of a book.
* (The inventory
table contains records of the
* actual books that have been acquired by the Library system.)
* @author Timothy Paul Fox
* @version August 09, 2004, 3:27 PM
*/
public class CatalogItem {
private CatalogID catalogID;
private String itemTitle;
private String itemAuthor;
private String itemPublisher;
private String itemYear;
private String ISBN;
private String other;
private String keyWords;
private Statement userStmt;
private Connection dbWire;
private ResultSet rowRS;
private boolean isNewRow;
private String fieldInsertList;
private String valueInsertList;
private String updateList;
private boolean titleChanged;
private boolean authorChanged;
private boolean publisherChanged;
private boolean yearChanged;
private boolean isbnChanged;
private boolean otherChanged;
private boolean keywordsChanged;
{
catalogID = null;
itemTitle = itemAuthor = itemPublisher = itemYear = ISBN =
other = keyWords = null;
userStmt = null;
dbWire = null;
rowRS = null;
isNewRow = false;
resetAllChangeFlags();
}
private void resetAllChangeFlags() {
titleChanged = authorChanged = publisherChanged =
yearChanged = isbnChanged = otherChanged =
keywordsChanged = false;
} // end resetAllChangeFlags
private String quoteForSQL(String s) {
StringBuffer sb = new StringBuffer(s);
int qPos = -1;
int lastQPos = 0;
do { // escape any internal apostrophes
// O'Reilly --> O''Reilly
qPos = sb.indexOf("'", lastQPos);
if (qPos >= 0) {
sb.insert(qPos,'\'');
lastQPos = qPos + 2;
}
} while (qPos >= 0);
sb.insert(0, '\'');
sb.append('\'');
return sb.toString();
} // end quoteForSQL
private void makeUpdateList(boolean changeAll) {
int fieldCount = 0;
StringBuffer sb = new StringBuffer("");
if ((itemTitle != null) && (changeAll || titleChanged)) {
sb.append("title = " + quoteForSQL(itemTitle));
fieldCount++;
}
if ((itemAuthor != null) && (changeAll || authorChanged)) {
if (fieldCount > 0)
sb.append(", ");
sb.append("author = " + quoteForSQL(itemAuthor) );
fieldCount++;
}
if ((itemPublisher != null) && (changeAll || publisherChanged)){
if (fieldCount > 0)
sb.append(", ");
sb.append("publisher = " + quoteForSQL(itemPublisher) );
fieldCount++;
}
if ((itemYear != null) && (changeAll || yearChanged)){
if (fieldCount > 0) {
sb.append(", ");
}
sb.append("pub_year = " + quoteForSQL(itemYear) );
fieldCount++;
}
if ((ISBN != null) && (changeAll || isbnChanged)) {
if (fieldCount > 0)
sb.append(", ");
sb.append("isbn = " + quoteForSQL(ISBN) );
fieldCount++;
}
if ((other != null) && (changeAll || otherChanged)) {
if (fieldCount > 0)
sb.append(", ");
sb.append("other_key = " + quoteForSQL(other) );
fieldCount++;
}
if ((keyWords != null) && (changeAll || keywordsChanged)){
if (fieldCount > 0)
sb.append(", ");
sb.append("keywords = " + quoteForSQL(keyWords) );
fieldCount++;
}
updateList = sb.toString();
} // end makeUpdateList
private void makeInsertLists() {
StringBuffer fieldList = new StringBuffer("(");
StringBuffer valueList = new StringBuffer("(");
fieldList.append("catalog_id");
valueList.append(quoteForSQL(catalogID.toString()));
fieldList.append(", ");
valueList.append(", ");
fieldList.append("title");
valueList.append(quoteForSQL(itemTitle));
fieldList.append(", ");
valueList.append(", ");
fieldList.append("author");
valueList.append(quoteForSQL(itemAuthor));
fieldList.append(", ");
valueList.append(", ");
fieldList.append("publisher");
valueList.append(quoteForSQL(itemPublisher));
fieldList.append(")");
valueList.append(")");
fieldInsertList = fieldList.toString();
valueInsertList = valueList.toString();
} // end makeInsertLists
/** Creates a new instance of CatalogItem, and a record in the
* catalog
table.
* The record created includes a new CatalogID.
* @param title the title of the book (item) being added to the catalog.
* Must be non-null and non-blank. Maximum storable length is
* 55 characters.
* @param author the author of the book. Must be non-null and non-blank.
* Maximum storable length is 32 characters.
* @param publisher the publisher of the book. Must be non-null and
* non-blank. Maximum storable length is 20 characters.
* @throws Exception generally SQLException from a JDBC access attempt,
* also IllegalArgumentException for null or empty args
*/
public CatalogItem(String title, String author, String publisher)
throws Exception {
isNewRow = true;
catalogID = new CatalogID();
if ((null == title) || (title.length() < 1))
throw new IllegalArgumentException(
"CatalogItem(): Bad title arg");
if ((null == author) || (author.length() < 1))
throw new IllegalArgumentException(
"CatalogItem(): Bad author arg");
if ((null == publisher) || (publisher.length() < 1))
throw new IllegalArgumentException(
"CatalogItem(): Bad publisher arg");
itemTitle = title;
itemAuthor = author;
itemPublisher = publisher;
makeInsertLists();
try {
makeDbConnection("root"); // opens dbWire, userStmt
int result = putToRow(
"INSERT INTO catalog " + fieldInsertList +
" VALUES " + valueInsertList );
if (result != 1)
throw new SQLException(
"CatalogItem:new record not written");
}
finally {
if (userStmt != null) userStmt.close();
if (dbWire != null) dbWire.close();
}
} // end ContactInfo -- new record constructor
/** writes any pending changes to the catalog
* table.
* @throws Exception whatever JDBC throws interacting with the database
*/
public void update() throws Exception {
makeUpdateList(false); // make lists for changed fields only
try {
makeDbConnection("root"); // opens dbWire, userStmt
int result = putToRow(
"UPDATE catalog " +
"SET " + updateList +
" WHERE (catalog_id = " +
quoteForSQL(catalogID.toString()) + ")");
if (result != 1)
throw new SQLException(
"CatalogItem:update() error");
resetAllChangeFlags();
}
finally {
if (userStmt != null) userStmt.close();
if (dbWire != null) dbWire.close();
}
} // end update()
/** Creates a CatalogItem object that represents a record that already
* exists in the catalog
table.
* Finds a record in the catalog
table whose
* primary key matches knownID, then creates a CatalogItem object
* and copies the record's data to it.
* @param knownID the primary key (ItemID) in an
* catalog
record
* @throws Exception from not contacting the database,
* or not finding a matching record
*/
public CatalogItem(String knownID) throws Exception {
catalogID = new CatalogID(knownID);
try {
makeDbConnection("root");
getFromRow("SELECT * from catalog " +
"WHERE (catalog_id = " +
quoteForSQL(catalogID.toString()) + ")");
rowRS.first();
itemTitle = rowRS.getString("title");
itemAuthor = rowRS.getString("author");
itemPublisher = rowRS.getString("publisher");
itemYear = rowRS.getString("pub_year");
ISBN = rowRS.getString("isbn");
other = rowRS.getString("other_key");
keyWords = rowRS.getString("keywords");
}
finally {
if (userStmt != null) userStmt.close();
if (dbWire != null) dbWire.close();
}
} // end CatalogItem -- initializer to find existing record
private void getFromRow(String query) throws Exception {
rowRS = userStmt.executeQuery(query);
}
private void makeDbConnection(String user) throws Exception {
LibManDbConnection plug;
if (userStmt != null) userStmt.close();
if (dbWire != null) dbWire.close();
plug = new LibManDbConnection(user);
dbWire = plug.connect();
userStmt = dbWire.createStatement();
} // end makeDbConnection
private int putToRow(String updateSpec) throws Exception{
return userStmt.executeUpdate(updateSpec);
}
/** shows the contents of the CatalogItem object.
* @return The output will be formatted as
* (title), (author), (publisher) (pubYear)
* (ISBN)
* (keywords)
*
* NOTE: the (pubYear) (ISBN) and (keywords) data may be blank.
*/
public String toString() {
StringBuffer sb = new StringBuffer("CatalogItem(");
sb.append(catalogID.toString() + "): \n");
sb.append(getTitle() + ", ");
sb.append(getAuthor() + ", ");
sb.append(getPublisher() + " ");
sb.append(getPubYear() + "\n");
sb.append(getISBN() + "\n");
sb.append(getKeywords() + "\n");
sb.append("\n");
return sb.toString();
} // end toString()
/** gets the CatalogID
* @return The primary key value for this item's record in the
* catalog
tables.
*/
public String getCatalogID() {
return catalogID.toString();
}
/** gets the title
* @return the title of the book
*/
public String getTitle() {
return (itemTitle == null)? "" : itemTitle;
}
/** gets the author name
* @return the author of the book
*/
public String getAuthor() {
return (itemAuthor == null)? "" : itemAuthor;
}
/** gets the publisher name
* @return the publisher of the book
*/
public String getPublisher() {
return (itemPublisher == null)? "" : itemPublisher;
}
/** gets the item's publication year
* @return the year of publication, a four character string, if its
* value has been set. Otherwise returns the empty string "".
*/
public String getPubYear() {
return (itemYear == null)? "" : itemYear;
}
/** gets the item's ISBN
* @return the ISBN if its value has been set.
* Otherwise returns the empty string "".
*/
public String getISBN() {
return ( ISBN == null)? "" : ISBN;
}
/** gets the item's 'other' key
* @return the 'other' key if its value has been set.
* Otherwise returns the empty string "".
*/
public String getOtherKey() {
return (other == null)? "" : other;
}
/** gets the item's searchable key words
* @return the words that indicate the genre or topic of the book,
* if this property has been set.
* Otherwise returns the empty string "".
*/
public String getKeywords() {
return (keyWords == null)? "" : keyWords;
}
/** rewrites the title property of the item. Use this method to correct
* mistakes in the item's title.
* @param newS the title of the book. Must be non-blank
* to be stored. Maximum storable length is 55 characters.
* @param immediate If this is set true
, the new
* data will be written immediately to the database.
* If false
, the database will not be updated
* until the update() method is called.
* @throws Exception passes along whatever exception the update()
* method encounters when trying to update the database.
*/
public void setTitle(String newS, boolean immediate)
throws Exception {
if (newS == null || newS.length() < 1) return;
itemTitle = newS;
titleChanged = true;
if (immediate) update();
}
/** rewrites the author property of the item. Use this method to
* correct mistakes in the item's author name.
* @param newS the name of the author the book. Must be
* non-blank to be stored. Maximum storable length is 32 characters.
* @param immediate If this is set true
, the new
* data will be written immediately to the database.
* If false
, the database will not be updated
* until the update() method is called.
* @throws Exception passes along whatever exception the update()
* method encounters when trying to update the database.
*/
public void setAuthor(String newS, boolean immediate)
throws Exception {
if (newS == null || newS.length() < 1) return;
itemAuthor = newS;
authorChanged = true;
if (immediate) update();
}
/** rewrites the publisher property of the item. Use this method to
* correct mistakes in the item's publisher name.
* @param newS the name of the publisher the book. Must be
* non-blank to be stored. Maximum storable length is 20 characters.
* @param immediate If this is set true
, the new
* data will be written immediately to the database.
* If false
, the database will not be updated
* until the update() method is called.
* @throws Exception passes along whatever exception the update()
* method encounters when trying to update the database.
*/
public void setPublisher(String newS, boolean immediate)
throws Exception {
if (newS == null || newS.length() < 1) return;
itemPublisher = newS;
publisherChanged = true;
if (immediate) update();
}
/** sets the publication year of the item.
* @param newS the year the book was published. Must be
* non-blank to be stored.
The parameter is not checked for
* being a reasonable date value or format. Maximum storable length
* is 4 characters.
* @param immediate If this is set true
, the new
* data will be written immediately to the database.
* If false
, the database will not be updated
* until the update() method is called.
* @throws Exception passes along whatever exception the update()
* method encounters when trying to update the database.
*/
public void setPubYear(String newS, boolean immediate)
throws Exception {
if (newS == null || newS.length() < 1) return;
itemYear = newS;
yearChanged = true;
if (immediate) update();
}
/** sets the ISBN property of the item.
* @param newS the book's ISBN. Must be non-blank to be stored.
*
The parameter is not checked for correctness
* versus ISBN format specification. Maximum storable length is
* 18 characters.
* @param immediate If this is set true
, the new
* data will be written immediately to the database.
* If false
, the database will not be updated
* until the update() method is called.
* @throws Exception passes along whatever exception the update()
* method encounters when trying to update the database.
*/
public void setISBN(String newS, boolean immediate)
throws Exception {
if (newS == null || newS.length() < 1) return;
ISBN = newS;
isbnChanged = true;
if (immediate) update();
}
/** sets the 'otherKey' property of the item.
* @param newS the otherKey. Must be non-blank to be stored.
* Maximum storable length is 8 characters.
* @param immediate If this is set true
, the new
* data will be written immediately to the database.
* If false
, the database will not be updated
* until the update() method is called.
* @throws Exception passes along whatever exception the update()
* method encounters when trying to update the database.
*/
public void setOtherKey(String newS, boolean immediate)
throws Exception {
if (newS == null || newS.length() < 1) return;
other = newS;
otherChanged = true;
if (immediate) update();
}
/** sets the 'keyWords' property of the item.
* @param newS the keyWords. Must be non-blank to be stored.
* Maximum storable length is 55 characters.
* @param immediate If this is set true
, the new
* data will be written immediately to the database.
* If false
, the database will not be updated
* until the update() method is called.
* @throws Exception passes along whatever exception the update()
* method encounters when trying to update the database.
*/
public void setKeywords(String newS, boolean immediate)
throws Exception {
if (newS == null || newS.length() < 1) return;
keyWords = newS;
keywordsChanged = true;
if (immediate) update();
}
} // end class CatalogItem