fix up the webdb_create update stuff
[mir.git] / source / mir / storage / Database.java
index 1ed463c..c3a6e93 100755 (executable)
@@ -7,6 +7,8 @@ import  java.sql.*;
 import  java.lang.*;
 import  java.io.*;
 import  java.util.*;
+import  java.text.SimpleDateFormat;
+import  java.text.ParseException;
 import  freemarker.template.*;
 import  com.codestudio.sql.*;
 import  com.codestudio.util.*;
@@ -25,8 +27,23 @@ import  mir.misc.*;
  * Treiber, Host, User und Passwort, ueber den der Zugriff auf die
  * Datenbank erfolgt.
  *
- * @author RK
- * @version 16.7.1999
+ * @version $Revision: 1.21 $ $Date: 2002/08/04 23:38:22 $
+ * @author $Author: mh $
+ *
+ * $Log: Database.java,v $
+ * Revision 1.21  2002/08/04 23:38:22  mh
+ * fix up the webdb_create update stuff
+ *
+ * Revision 1.20  2002/07/21 22:32:25  mh
+ * on insert, the "webdb_lastchange" field should get a value
+ *
+ * Revision 1.19  2002/06/29 15:44:46  mh
+ * make the webdb_create update be called webdb_create_update. it breaks things otherwise. a fixme case I know..
+ *
+ * Revision 1.18  2002/06/28 20:42:13  mh
+ * added necessary bits in templates and Database.java to make webdb_create modifiable. make the conversion from sql/Timestamp to String more robust
+ *
+ *
  */
 public class Database implements StorageObject {
 
@@ -52,12 +69,20 @@ public class Database implements StorageObject {
                                       STORABLE_OBJECT_ENTITY_CLASS=null;
   private static SimpleHash           POPUP_EMTYLINE=new SimpleHash();
   protected static final ObjectStore  o_store=ObjectStore.getInstance();
+  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();
+
+  private static final int _millisPerHour = 60 * 60 * 1000;
+  private static final int _millisPerMinute = 60 * 1000;
 
        static {
                // always same object saves a little space
                POPUP_EMTYLINE.put("key", ""); POPUP_EMTYLINE.put("value", "--");
     try {
-      GENERIC_ENTITY_CLASS = Class.forName("mir.entity.GenericEntity");
+      GENERIC_ENTITY_CLASS = Class.forName("mir.entity.StorableObjectEntity");
       STORABLE_OBJECT_ENTITY_CLASS = Class.forName("mir.entity.StorableObjectEntity");
     }
     catch (Exception e) {
@@ -249,13 +274,24 @@ public class Database implements StorageObject {
                                        case java.sql.Types.LONGVARBINARY:
                                                outValue = rs.getString(valueIndex);
                                                //if (outValue != null)
-                                                       //outValue = StringUtil.encodeHtml(StringUtil.unquote(outValue));
+                                               //outValue = StringUtil.encodeHtml(StringUtil.unquote(outValue));
                                                break;
                                        case java.sql.Types.TIMESTAMP:
-                                               Timestamp timestamp = (rs.getTimestamp(valueIndex));
-                                               if (!rs.wasNull()) {
-                                                       outValue = timestamp.toString();
-                                               }
+            // it's important to use Timestamp here as getting it
+            // as a string is undefined and is only there for debugging
+            // according to the API. we can make it a string through formatting.
+            // -mh
+                                         Timestamp timestamp = (rs.getTimestamp(valueIndex));
+            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;
+            }
                                                break;
                                        default:
                                                outValue = "<unsupported value>";
@@ -433,7 +469,7 @@ public class Database implements StorageObject {
       StoreIdentifier search_sid =
         new StoreIdentifier( theEntityClass,
                              StoreContainerType.STOC_TYPE_ENTITYLIST,
-                             StoreUtil.getEntityListUniqueIdentifierFor(wc,ob,offset,limit) );
+                             StoreUtil.getEntityListUniqueIdentifierFor(theTable,wc,ob,offset,limit) );
       EntityList hit = (EntityList)o_store.use(search_sid);
       if ( hit!=null ) {
         theLog.printDebugInfo("CACHE (hit): " + search_sid.toString());
@@ -518,7 +554,7 @@ public class Database implements StorageObject {
                                theReturnList.setOffset(offset);
                                theReturnList.setWhere(wc);
                                theReturnList.setOrder(ob);
-        theReturnList.setEntityClass(theEntityClass);
+        theReturnList.setStorage(this);
         theReturnList.setLimit(limit);
                                if ( offset >= limit )
                                        theReturnList.setPrevBatch(offset - limit);
@@ -558,9 +594,8 @@ public class Database implements StorageObject {
                                // alle durchlaufen bis nix mehr da
                                theType = metadataTypes[i];
                                if (theType == java.sql.Types.LONGVARBINARY) {
-                                       InputStream us = rs.getAsciiStream(i + 1);
-                                       if (us != null) {
-                                               InputStreamReader is = new InputStreamReader(us);
+                                       InputStreamReader is = (InputStreamReader)rs.getCharacterStream(i + 1);
+                                       if (is != null) {
                                                char[] data = new char[32768];
                                                StringBuffer theResultString = new StringBuffer();
                                                int len;
@@ -613,14 +648,21 @@ public class Database implements StorageObject {
         * @return der Wert des Primary-keys der eingefügten Entity
         */
        public String insert (Entity theEntity) throws StorageObjectException {
-               String returnId = null;
-               Connection con = null;
-               PreparedStatement pstmt = null;
                //cache
                invalidatePopupCache();
-               /** @todo OS: if Entity is StorableObject, invalidate in ObjectStore
-                *  careful: Entity has no id yet! */
-               try {
+
+    // invalidating all EntityLists corresponding with theEntityClass
+    if ( StoreUtil.implementsStorableObject(theEntityClass) ) {
+      StoreContainerType stoc_type =
+        StoreContainerType.valueOf( theEntityClass,
+                                    StoreContainerType.STOC_TYPE_ENTITYLIST);
+      o_store.invalidate(stoc_type);
+    }
+
+               String returnId = null;
+               Connection con = null; PreparedStatement pstmt = null;
+
+    try {
                        ArrayList streamedInput = theEntity.streamedInput();
                        StringBuffer f = new StringBuffer();
                        StringBuffer v = new StringBuffer();
@@ -632,7 +674,8 @@ public class Database implements StorageObject {
                                if (!aField.equals(thePKeyName)) {
                                        aValue = null;
                                        // sonderfaelle
-                                       if (aField.equals("webdb_create")) {
+                                       if (aField.equals("webdb_create") ||
+              aField.equals("webdb_lastchange")) {
                                                aValue = "NOW()";
                                        }
                                        else {
@@ -693,6 +736,7 @@ public class Database implements StorageObject {
                        }
                        freeConnection(con, pstmt);
                }
+    /** @todo store entity in o_store */
                return  returnId;
        }
 
@@ -712,8 +756,16 @@ public class Database implements StorageObject {
                 *  have a primary key in the entity. i don't know if we
                 *  still need the streamed input fields. // rk  */
 
-               /** @todo extension: check if Entity did change, otherwise we don't need */
-               /** @todo OS: invalidate in Ostore if Entity is StorableObject */
+               /** @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) ) {
+      StoreContainerType stoc_type =
+        StoreContainerType.valueOf( theEntityClass,
+                                    StoreContainerType.STOC_TYPE_ENTITYLIST);
+      o_store.invalidate(stoc_type);
+    }
 
                ArrayList streamedInput = theEntity.streamedInput();
                String id = theEntity.getId();
@@ -744,6 +796,27 @@ public class Database implements StorageObject {
                if (metadataFields.contains("webdb_lastchange")) {
                        sql.append(",webdb_lastchange=NOW()");
                }
+    // special case: the webdb_create requires the field in yyyy-mm-dd HH:mm
+    // format so anything extra will be ignored. -mh
+               if (metadataFields.contains("webdb_create") &&
+        theEntity.hasValueForField("webdb_create")) {
+      // minimum of 10 (yyyy-mm-dd)...
+      if (theEntity.getValue("webdb_create").length() >= 10) {
+        String dateString = theEntity.getValue("webdb_create");
+        // if only 10, then add 00:00 so it doesn't throw a ParseException
+        if (dateString.length() == 10)
+          dateString=dateString+" 00:00";
+
+        // 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) {
+          throw new StorageObjectException(e.toString());
+        }
+      }
+               }
                if (streamedInput != null) {
                        for (int i = 0; i < streamedInput.size(); i++) {
                                sql.append(",").append(streamedInput.get(i)).append("=?");
@@ -784,10 +857,13 @@ public class Database implements StorageObject {
 
                invalidatePopupCache();
     // ostore send notification
-    if (StoreUtil.implementsStorableObject(theEntityClass) ) {
+    if ( StoreUtil.implementsStorableObject(theEntityClass) ) {
+      String uniqueId = id;
+      if ( theEntityClass.equals(StorableObjectEntity.class) )
+        uniqueId+="@"+theTable;
                        theLog.printInfo("CACHE: (del) " + id);
                        StoreIdentifier search_sid =
-        new StoreIdentifier(theEntityClass, StoreContainerType.STOC_TYPE_ENTITY, id);
+        new StoreIdentifier(theEntityClass, StoreContainerType.STOC_TYPE_ENTITY, uniqueId);
       o_store.invalidate(search_sid);
                }