X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=source%2Fmir%2Fstorage%2FDatabase.java;h=599af40b8bd4cc5e985fede8372ffe6c8a0175dc;hb=aa507bfd18e723d21e63454a26af3320bb8c27f2;hp=4c4ac94d8eb8e196a330615063d46dbede9dfc96;hpb=decccfaa1048522b2d751ae01046f4b92b521920;p=mir.git diff --git a/source/mir/storage/Database.java b/source/mir/storage/Database.java index 4c4ac94d..599af40b 100755 --- a/source/mir/storage/Database.java +++ b/source/mir/storage/Database.java @@ -44,13 +44,11 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; -import java.util.*; +import java.util.Iterator; +import java.util.List; import java.util.Map; - -import com.codestudio.util.SQLManager; - -import freemarker.template.SimpleHash; -import freemarker.template.SimpleList; +import java.util.TimeZone; +import java.util.Vector; import mir.config.MirPropertiesConfiguration; import mir.config.MirPropertiesConfiguration.PropertiesConfigExc; @@ -58,7 +56,6 @@ import mir.entity.Entity; import mir.entity.EntityList; import mir.entity.StorableObjectEntity; import mir.log.LoggerWrapper; -import mir.misc.HTMLTemplateProcessor; import mir.misc.StringUtil; import mir.storage.store.ObjectStore; import mir.storage.store.StorableObject; @@ -67,6 +64,8 @@ import mir.storage.store.StoreIdentifier; import mir.storage.store.StoreUtil; import mir.util.JDBCStringRoutines; +import com.codestudio.util.SQLManager; + /** * Diese Klasse implementiert die Zugriffsschicht auf die Datenbank. @@ -76,7 +75,7 @@ import mir.util.JDBCStringRoutines; * Treiber, Host, User und Passwort, ueber den der Zugriff auf die * Datenbank erfolgt. * - * @version $Id: Database.java,v 1.44.2.1 2003/05/22 19:45:06 zapata Exp $ + * @version $Id: Database.java,v 1.44.2.20 2003/11/28 17:21:50 rk Exp $ * @author rk * */ @@ -85,7 +84,7 @@ public class Database implements StorageObject { private static Class STORABLE_OBJECT_ENTITY_CLASS = mir.entity.StorableObjectEntity.class; - private static SimpleHash POPUP_EMPTYLINE = new SimpleHash(); + private static Map POPUP_EMPTYLINE = new HashMap(); protected static final ObjectStore o_store = ObjectStore.getInstance(); private static final int _millisPerHour = 60 * 60 * 1000; private static final int _millisPerMinute = 60 * 1000; @@ -109,19 +108,23 @@ public class Database implements StorageObject { protected ArrayList metadataNotNullFields; protected int[] metadataTypes; protected Class theEntityClass; - protected SimpleList popupCache = null; + protected List popupCache = null; protected boolean hasPopupCache = false; - protected SimpleHash hashCache = null; + protected Map hashCache = null; protected boolean hasTimestamp = true; private String database_driver; private String database_url; private int defaultLimit; - protected DatabaseAdaptor theAdaptor; - private SimpleDateFormat _dateFormatterOut = - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - private SimpleDateFormat _dateFormatterIn = - new SimpleDateFormat("yyyy-MM-dd HH:mm"); - private Calendar _cal = new GregorianCalendar(); + + TimeZone timezone; + SimpleDateFormat internalDateFormat; + SimpleDateFormat userInputDateFormat; +/* + private SimpleDateFormat _dateFormatterOut; + private SimpleDateFormat _dateFormatterIn; + _dateFormatterOut = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + _dateFormatterIn = new SimpleDateFormat("yyyy-MM-dd HH:mm"); +*/ /** * Kontruktor bekommt den Filenamen des Konfigurationsfiles ?bergeben. @@ -141,13 +144,19 @@ public class Database implements StorageObject { throw new StorageObjectFailure(e); } logger = new LoggerWrapper("Database"); + timezone = TimeZone.getTimeZone(configuration.getString("Mir.DefaultTimezone")); + internalDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + internalDateFormat.setTimeZone(timezone); + + userInputDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + userInputDateFormat.setTimeZone(timezone); + String theAdaptorName = configuration.getString("Database.Adaptor"); defaultLimit = Integer.parseInt(configuration.getString("Database.Limit")); try { theEntityClass = GENERIC_ENTITY_CLASS; - theAdaptor = (DatabaseAdaptor) Class.forName(theAdaptorName).newInstance(); } catch (Throwable e) { logger.error("Error in Database() constructor with " + theAdaptorName + " -- " + e.getMessage()); @@ -249,12 +258,13 @@ public class Database implements StorageObject { return metadataFields; } - /* - * Gets value out of ResultSet according to type and converts to String - * @param inValue Wert aus ResultSet. - * @param aType Datenbanktyp. - * @return liefert den Wert als String zurueck. Wenn keine Umwandlung moeglich - * dann /unsupported value/ + /** + * Gets value out of ResultSet according to type and converts to String + * @param rs ResultSet. + * @param aType a type from java.sql.Types.* + * @param index index in ResultSet + * @return returns the value as String. If no conversion is possible + * /unsupported value/ is returned */ private String getValueAsString(ResultSet rs, int valueIndex, int aType) throws StorageObjectFailure { @@ -349,14 +359,20 @@ public class Database implements StorageObject { if (!rs.wasNull()) { java.util.Date date = new java.util.Date(timestamp.getTime()); - outValue = _dateFormatterOut.format(date); - _cal.setTime(date); - - int offset = - _cal.get(Calendar.ZONE_OFFSET) + _cal.get(Calendar.DST_OFFSET); - String tzOffset = - StringUtil.zeroPaddingNumber(offset / _millisPerHour, 2, 2); - outValue = outValue + "+" + tzOffset; + + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + calendar.setTimeZone(timezone); + outValue = internalDateFormat.format(date); + + int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET); + String tzOffset = StringUtil.zeroPaddingNumber(Math.abs(offset) / _millisPerHour, 2, 2); + + if (offset<0) + outValue = outValue + "-"; + else + outValue = outValue + "+"; + outValue = outValue + tzOffset; } break; @@ -374,10 +390,10 @@ public class Database implements StorageObject { return outValue; } - /* - * select-Operator um einen Datensatz zu bekommen. - * @param id Primaerschluessel des Datensatzes. - * @return liefert EntityObject des gefundenen Datensatzes oder null. + /** + * select-Operator um einen Datensatz zu bekommen. + * @param id Primaerschluessel des Datensatzes. + * @return liefert EntityObject des gefundenen Datensatzes oder null. */ public Entity selectById(String id) throws StorageObjectExc { if ((id == null) || id.equals("")) { @@ -385,7 +401,7 @@ public class Database implements StorageObject { } // ask object store for object - if (StoreUtil.implementsStorableObject(theEntityClass)) { + if (StoreUtil.extendsStorableEntity(theEntityClass)) { String uniqueId = id; if (theEntityClass.equals(StorableObjectEntity.class)) { @@ -424,13 +440,13 @@ public class Database implements StorageObject { returnEntity = makeEntityFromResultSet(rs); } else { - logger.debug("No data for id: " + id + " in table " + theTable); + logger.warn("No data for id: " + id + " in table " + theTable); } rs.close(); } else { - logger.debug("No Data for Id " + id + " in Table " + theTable); + logger.warn("No Data for Id " + id + " in Table " + theTable); } } catch (SQLException sqe) { @@ -448,6 +464,22 @@ public class Database implements StorageObject { } /** + * This method makes it possible to make selects across multiple tables + * + * @param mainTablePrefix prefix for the mainTable + * @param extraTables a vector of tables for relational select + * @param aWhereClause whereClause + * @return EntityList of selected Objects + * @throws StorageObjectFailure + */ + + public EntityList selectByWhereClauseWithExtraTables(String mainTablePrefix, + List extraTables, String aWhereClause ) + throws StorageObjectFailure { + return selectByWhereClause( mainTablePrefix, extraTables, aWhereClause, "", 0, defaultLimit); + } + + /** * select-Operator um Datensaetze zu bekommen, die key = value erfuellen. * @param key Datenbankfeld der Bedingung. * @param value Wert die der key anehmen muss. @@ -507,6 +539,10 @@ public class Database implements StorageObject { return selectByWhereClause(where, order, 0); } + public EntityList selectByWhereClause(String mainTablePrefix, List extraTables, String where, String order) throws StorageObjectFailure { + return selectByWhereClause(mainTablePrefix, extraTables, where, order, 0, defaultLimit); + } + /** * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. * Als maximale Anzahl wird das Limit auf der Konfiguration genommen. @@ -522,7 +558,7 @@ public class Database implements StorageObject { } /** - * select-Operator liefert eine EntityListe mit den gematchten Datens?tzen zur?ck. + * select-Operator returns EntityList with matching rows in Database. * @param aWhereClause where-Clause * @param anOrderByClause orderBy-Clause * @param offset ab welchem Datensatz @@ -532,19 +568,52 @@ public class Database implements StorageObject { */ public EntityList selectByWhereClause(String aWhereClause, String anOrderByClause, int offset, int limit) throws StorageObjectFailure { + return selectByWhereClause("", null, aWhereClause, anOrderByClause, offset, limit); + } - // check o_store for entitylist - if (StoreUtil.implementsStorableObject(theEntityClass)) { - StoreIdentifier search_sid = - new StoreIdentifier( - theEntityClass, StoreContainerType.STOC_TYPE_ENTITYLIST, - StoreUtil.getEntityListUniqueIdentifierFor(theTable, aWhereClause, anOrderByClause, offset, limit)); - EntityList hit = (EntityList) o_store.use(search_sid); - - if (hit != null) { - logger.debug("CACHE (hit): " + search_sid.toString()); - return hit; + /** + * select-Operator returns EntityList with matching rows in Database. + * @param aWhereClause where-Clause + * @param anOrderByClause orderBy-Clause + * @param offset ab welchem Datensatz + * @param limit wieviele Datens?tze + * @return EntityList mit den gematchten Entities + * @exception StorageObjectException + */ + public EntityList selectByWhereClause(String mainTablePrefix, List extraTables, + String aWhereClause, String anOrderByClause, + int offset, int limit) throws StorageObjectFailure { + + // TODO get rid of emtpy Strings in extraTables + // make extraTables null, if single empty String in it + // cause StringUtil.splitString puts in emptyString + if (extraTables != null && ((String)extraTables.get(0)).trim().equals("")) + { + logger.debug("+++ made extraTables to null!"); + extraTables=null; + } + + String useTable = theTable; + String selectStar = "*"; + if (mainTablePrefix!=null && mainTablePrefix.trim().length()>0) { + useTable+=" "+mainTablePrefix; + selectStar=mainTablePrefix.trim() + ".*"; + } + + // check o_store for entitylist + // only if no relational select + if (extraTables==null) { + if (StoreUtil.extendsStorableEntity(theEntityClass)) { + StoreIdentifier searchSid = new StoreIdentifier(theEntityClass, + StoreContainerType.STOC_TYPE_ENTITYLIST, + StoreUtil.getEntityListUniqueIdentifierFor(theTable, + aWhereClause, anOrderByClause, offset, limit)); + EntityList hit = (EntityList) o_store.use(searchSid); + + if (hit != null) { + return hit; + } } } @@ -558,17 +627,25 @@ public class Database implements StorageObject { // build sql-statement - /** @todo count sql string should only be assembled if we really count - * see below at the end of method //rk */ if ((aWhereClause != null) && (aWhereClause.trim().length() == 0)) { aWhereClause = null; } StringBuffer countSql = - new StringBuffer("select count(*) from ").append(theTable); + new StringBuffer("select count(*) from ").append(useTable); StringBuffer selectSql = - new StringBuffer("select * from ").append(theTable); - + new StringBuffer("select "+selectStar+" from ").append(useTable); + + // append extratables, if necessary + if (extraTables!=null) { + for (int i=0;i < extraTables.size();i++) { + if (!extraTables.get(i).equals("")) { + countSql.append( ", " + extraTables.get(i)); + selectSql.append( ", " + extraTables.get(i)); + } + } + } + if (aWhereClause != null) { selectSql.append(" where ").append(aWhereClause); countSql.append(" where ").append(aWhereClause); @@ -578,10 +655,8 @@ public class Database implements StorageObject { selectSql.append(" order by ").append(anOrderByClause); } - if (theAdaptor.hasLimit()) { - if ((limit > -1) && (offset > -1)) { - selectSql.append(" LIMIT ").append(limit).append(" OFFSET ").append(offset); - } + if ((limit > -1) && (offset > -1)) { + selectSql.append(" LIMIT ").append(limit).append(" OFFSET ").append(offset); } // execute sql @@ -598,22 +673,17 @@ public class Database implements StorageObject { } theReturnList = new EntityList(); - Entity theResultEntity; - while (rs.next()) { theResultEntity = makeEntityFromResultSet(rs); theReturnList.add(theResultEntity); offsetCount++; } - rs.close(); } // making entitylist infos - if (!(theAdaptor.hasLimit())) { - count = offsetCount; - } + count = offsetCount; if (theReturnList != null) { // now we decide if we have to know an overall count... @@ -621,8 +691,6 @@ public class Database implements StorageObject { if ((limit > -1) && (offset > -1)) { if (offsetCount == limit) { - /** @todo counting should be deffered to entitylist - * getSize() should be used */ rs = executeSql(stmt, countSql.toString()); if (rs != null) { @@ -653,7 +721,7 @@ public class Database implements StorageObject { theReturnList.setNextBatch(offset + limit); } - if (StoreUtil.implementsStorableObject(theEntityClass)) { + if (extraTables==null && StoreUtil.extendsStorableEntity(theEntityClass)) { StoreIdentifier sid = theReturnList.getStoreIdentifier(); logger.debug("CACHE (add): " + sid.toString()); o_store.add(sid); @@ -683,13 +751,21 @@ public class Database implements StorageObject { */ private Entity makeEntityFromResultSet(ResultSet rs) throws StorageObjectFailure { - /** @todo OS: get Pkey from ResultSet and consult ObjectStore */ Map theResultHash = new HashMap(); String theResult = null; int theType; Entity returnEntity = null; try { + // ask object store for object @ thePKeyIndex + if (StoreUtil.extendsStorableEntity(theEntityClass)) { + StoreIdentifier searchSid = StorableObjectEntity.getStoreIdentifier(this, + theEntityClass, rs); + Entity hit = (Entity) o_store.use(searchSid); + if (hit != null) return hit; + } + + int size = metadataFields.size(); for (int i = 0; i < size; i++) { @@ -765,7 +841,7 @@ public class Database implements StorageObject { invalidatePopupCache(); // invalidating all EntityLists corresponding with theEntityClass - if (StoreUtil.implementsStorableObject(theEntityClass)) { + if (StoreUtil.extendsStorableEntity(theEntityClass)) { StoreContainerType stoc_type = StoreContainerType.valueOf(theEntityClass, StoreContainerType.STOC_TYPE_ENTITYLIST); @@ -792,19 +868,20 @@ public class Database implements StorageObject { aValue = null; // exceptions - if (aField.equals("webdb_create") || - aField.equals("webdb_lastchange")) { + if (!theEntity.hasValueForField(aField) && ( + aField.equals("webdb_create") || + aField.equals("webdb_lastchange"))) { aValue = "NOW()"; } else { if ((streamedInput != null) && streamedInput.contains(aField)) { aValue = "?"; - } else { + } + else { if (theEntity.hasValueForField(aField)) { aValue = "'" + - JDBCStringRoutines.escapeStringLiteral((String) theEntity.getValue( - aField)) + "'"; + JDBCStringRoutines.escapeStringLiteral((String) theEntity.getValue(aField)) + "'"; } } } @@ -832,7 +909,7 @@ public class Database implements StorageObject { .append(") values (").append(v).append(")"); String sql = sqlBuf.toString(); - logger.debug("INSERT: " + sql); + logger.info("INSERT: " + sql); con = getPooledCon(); con.setAutoCommit(false); pstmt = con.prepareStatement(sql); @@ -852,7 +929,7 @@ public class Database implements StorageObject { return null; } - pstmt = con.prepareStatement(theAdaptor.getLastInsertSQL(this)); + pstmt = con.prepareStatement("select currval('" + getCoreTable() + "_id_seq')"); ResultSet rs = pstmt.executeQuery(); rs.next(); @@ -894,7 +971,7 @@ public class Database implements StorageObject { /** @todo extension: check if Entity did change, otherwise we don't need * the roundtrip to the database */ /** invalidating corresponding entitylists in o_store*/ - if (StoreUtil.implementsStorableObject(theEntityClass)) { + if (StoreUtil.extendsStorableEntity(theEntityClass)) { StoreContainerType stoc_type = StoreContainerType.valueOf(theEntityClass, StoreContainerType.STOC_TYPE_ENTITYLIST); @@ -957,10 +1034,11 @@ public class Database implements StorageObject { // TimeStamp stuff try { - java.util.Date d = _dateFormatterIn.parse(dateString); - Timestamp tStamp = new Timestamp(d.getTime()); - sql.append(",webdb_create='" + tStamp.toString() + "'"); - } catch (ParseException e) { + java.util.Date d = userInputDateFormat.parse(dateString); +// Timestamp tStamp = new Timestamp(d.getTime()); + sql.append(",webdb_create='" + JDBCStringRoutines.formatDate(d) + "'"); + } + catch (ParseException e) { throw new StorageObjectFailure(e); } } @@ -973,7 +1051,7 @@ public class Database implements StorageObject { } sql.append(" where id=").append(id); - logger.debug("UPDATE: " + sql); + logger.info("UPDATE: " + sql); try { con = getPooledCon(); @@ -1014,7 +1092,7 @@ public class Database implements StorageObject { invalidatePopupCache(); // ostore send notification - if (StoreUtil.implementsStorableObject(theEntityClass)) { + if (StoreUtil.extendsStorableEntity(theEntityClass)) { String uniqueId = id; if (theEntityClass.equals(StorableObjectEntity.class)) { @@ -1050,153 +1128,49 @@ public class Database implements StorageObject { return (res > 0) ? true : false; } - /* noch nicht implementiert. - * @return immer false - */ - public boolean delete(EntityList theEntityList) { - invalidatePopupCache(); - - return false; - } - - /** - * Diese Methode sollte ueberschrieben werden, wenn fuer die abgeleitete Database-Klasse - * eine SimpleList mit Standard-Popupdaten erzeugt werden koennen soll. - * @return null - */ - public SimpleList getPopupData() throws StorageObjectFailure { - return null; - } - - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. - */ - public SimpleList getPopupData(String name, boolean hasNullValue) - throws StorageObjectFailure { - return getPopupData(name, hasNullValue, null); - } - - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @param where Schraenkt die Selektion der Datensaetze ein. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. - */ - public SimpleList getPopupData(String name, boolean hasNullValue, String where) - throws StorageObjectFailure { - return getPopupData(name, hasNullValue, where, null); - } - /** - * Holt Daten fuer Popups. - * @param name Name des Feldes. - * @param hasNullValue Wenn true wird eine leerer Eintrag fuer die Popups erzeugt. - * @param where Schraenkt die Selektion der Datensaetze ein. - * @param order Gibt ein Feld als Sortierkriterium an. - * @return SimpleList Gibt freemarker.template.SimpleList zurueck. + * Deletes entities based on a where clause + * + * @param aWhereClause + * @return + * @throws StorageObjectFailure */ - public SimpleList getPopupData(String name, boolean hasNullValue, - String where, String order) throws StorageObjectFailure { - // caching - if (hasPopupCache && (popupCache != null)) { - return popupCache; + public int deleteByWhereClause(String aWhereClause) throws StorageObjectFailure { + invalidatePopupCache(); + if (StoreUtil.extendsStorableEntity(theEntityClass)) { + StoreContainerType stoc_type = StoreContainerType.valueOf(theEntityClass, StoreContainerType.STOC_TYPE_ENTITYLIST); + o_store.invalidate(stoc_type); } - SimpleList simpleList = null; - Connection con = null; Statement stmt = null; + Connection con = null; + int res = 0; + String sql = + "delete from " + theTable + " where " + aWhereClause; - // build sql - StringBuffer sql = - new StringBuffer("select ").append(thePKeyName).append(",").append(name) - .append(" from ").append(theTable); - - if ((where != null) && !(where.length() == 0)) { - sql.append(" where ").append(where); - } - - sql.append(" order by "); - - if ((order != null) && !(order.length() == 0)) { - sql.append(order); - } else { - sql.append(name); - } - - // execute sql + //theLog.printInfo("DELETE " + sql); try { con = getPooledCon(); - } catch (Exception e) { - throw new StorageObjectFailure(e); - } - - try { stmt = con.createStatement(); - - ResultSet rs = executeSql(stmt, sql.toString()); - - if (rs != null) { - if (!evaluatedMetaData) { - get_meta_data(); - } - - simpleList = new SimpleList(); - - // if popup has null-selector - if (hasNullValue) { - simpleList.add(POPUP_EMPTYLINE); - } - - SimpleHash popupDict; - - while (rs.next()) { - popupDict = new SimpleHash(); - popupDict.put("key", getValueAsString(rs, 1, thePKeyType)); - popupDict.put("value", rs.getString(2)); - simpleList.add(popupDict); - } - - rs.close(); - } + res = stmt.executeUpdate(sql); } - catch (Exception e) { - logger.error("getPopupData: " + e.getMessage()); - throw new StorageObjectFailure(e); - } finally { - freeConnection(con, stmt); + catch (SQLException sqe) { + throwSQLException(sqe, "delete"); } - - if (hasPopupCache) { - popupCache = simpleList; + finally { + freeConnection(con, stmt); } - return simpleList; + return res; } - /** - * Liefert alle Daten der Tabelle als SimpleHash zurueck. Dies wird verwandt, - * wenn in den Templates ein Lookup-Table benoetigt wird. Sollte nur bei kleinen - * Tabellen Verwendung finden. - * @return SimpleHash mit den Tabellezeilen. + /* noch nicht implementiert. + * @return immer false */ - public SimpleHash getHashData() { - /** @todo dangerous! this should have a flag to be enabled, otherwise - * very big Hashes could be returned */ - if (hashCache == null) { - try { - hashCache = - HTMLTemplateProcessor.makeSimpleHash(selectByWhereClause("", -1)); - } - catch (StorageObjectFailure e) { - logger.debug(e.getMessage()); - } - } + public boolean delete(EntityList theEntityList) { + invalidatePopupCache(); - return hashCache; + return false; } /* invalidates the popupCache @@ -1222,7 +1196,7 @@ public class Database implements StorageObject { try { rs = stmt.executeQuery(sql); - logger.debug((System.currentTimeMillis() - startTime) + "ms. for: " + sql); + logger.info((System.currentTimeMillis() - startTime) + "ms. for: " + sql); } catch (SQLException e) { logger.error(e.getMessage() +"\n" + (System.currentTimeMillis() - startTime) + "ms. for: " + sql); @@ -1231,33 +1205,7 @@ public class Database implements StorageObject { return rs; } -/* - public ResultSet executeSql(String sql) throws StorageObjectFailure, SQLException { - long startTime = System.currentTimeMillis(); - Connection connection = null; - Statement statement = null; - - try { - connection = getPooledCon(); - statement = connection.createStatement(); - ResultSet result; - - result = statement.executeQuery(sql); - logger.debug((System.currentTimeMillis() - startTime) + "ms. for: " + sql); - return result; - } - catch (Throwable e) { - logger.error(e.getMessage() +"\n" + (System.currentTimeMillis() - startTime) + "ms. for: " + sql); - throw new StorageObjectFailure(e); - } - finally { - if (connection!=null) { - freeConnection(connection, statement); - } - } - } -*/ private Map processRow(ResultSet aResultSet) throws StorageObjectFailure, StorageObjectExc { try { Map result = new HashMap(); @@ -1333,15 +1281,33 @@ public class Database implements StorageObject { return null; }; + public int getSize(String where) throws SQLException, StorageObjectFailure { + return getSize("", null, where); + } /** * returns the number of rows in the table */ - public int getSize(String where) throws SQLException, StorageObjectFailure { + public int getSize(String mainTablePrefix, List extraTables, String where) throws SQLException, StorageObjectFailure { + long startTime = System.currentTimeMillis(); - String sql = "SELECT Count(*) FROM " + theTable; + + String useTable = theTable; + if (mainTablePrefix!=null && mainTablePrefix.trim().length()>0) { + useTable+=" "+mainTablePrefix; + } + StringBuffer countSql = + new StringBuffer("select count(*) from ").append(useTable); + // append extratables, if necessary + if (extraTables!=null) { + for (int i=0;i < extraTables.size();i++) { + if (!extraTables.get(i).equals("")) { + countSql.append( ", " + extraTables.get(i)); + } + } + } if ((where != null) && (where.length() != 0)) { - sql = sql + " where " + where; + countSql.append( " where " + where); } Connection con = null; @@ -1352,7 +1318,7 @@ public class Database implements StorageObject { con = getPooledCon(); stmt = con.createStatement(); - ResultSet rs = executeSql(stmt, sql); + ResultSet rs = executeSql(stmt, countSql.toString()); while (rs.next()) { result = rs.getInt(1); @@ -1364,9 +1330,7 @@ public class Database implements StorageObject { finally { freeConnection(con, stmt); } - - //theLog.printInfo(theTable + " has "+ result +" rows where " + where); - logger.debug((System.currentTimeMillis() - startTime) + "ms. for: " + sql); + logger.info((System.currentTimeMillis() - startTime) + "ms. for: " + countSql); return result; } @@ -1379,7 +1343,7 @@ public class Database implements StorageObject { try { rs = stmt.executeUpdate(sql); - logger.debug((System.currentTimeMillis() - startTime) + "ms. for: " + sql); + logger.info((System.currentTimeMillis() - startTime) + "ms. for: " + sql); } catch (SQLException e) { logger.error("Failed: " + (System.currentTimeMillis() - startTime) + "ms. for: " + sql); @@ -1409,7 +1373,7 @@ public class Database implements StorageObject { freeConnection(con, pstmt); } - logger.debug((System.currentTimeMillis() - startTime) + "ms. for: " + sql); + logger.info((System.currentTimeMillis() - startTime) + "ms. for: " + sql); return result; }