Update of /cvsroot/squirrel-sql/sql12/fw/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv588
Modified Files:
DataTypeClob.java
Log Message:
changes to handle nulls andupdates
Index: DataTypeClob.java
===================================================================
RCS file: /cvsroot/squirrel-sql/sql12/fw/src/net/sourceforge/squirrel_sql/fw/datasetviewer/cellcomponent/DataTypeClob.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** DataTypeClob.java 25 Feb 2004 13:41:34 -0000 1.4
--- DataTypeClob.java 6 Apr 2004 20:04:18 -0000 1.5
***************
*** 26,30 ****
import java.io.IOException;
- import javax.swing.DefaultCellEditor;
import javax.swing.JTable;
import javax.swing.JTextField;
--- 26,29 ----
***************
*** 35,38 ****
--- 34,38 ----
import java.sql.ResultSet;
import java.sql.Clob;
+ import java.io.StringBufferInputStream;
import net.sourceforge.squirrel_sql.fw.datasetviewer.CellDataPopup;
***************
*** 112,116 ****
*/
public boolean areEqual(Object obj1, Object obj2) {
! return ((ClobDescriptor)obj1).equals(obj2);
}
--- 112,127 ----
*/
public boolean areEqual(Object obj1, Object obj2) {
! if (obj1 == obj2)
! return true;
!
! // if both objs are null, then they matched in the previous test,
! // so at this point we know that at least one of them (or both) is not null.
! // However, one of them may still be null, and we cannot call equals() on
! // the null object, so make sure that the one we call it on is not null.
! // The equals() method handles the other one being null, if it is.
! if (obj1 != null)
! return ((ClobDescriptor)obj1).equals((ClobDescriptor)obj2);
! else
! return ((ClobDescriptor)obj2).equals((ClobDescriptor)obj1);
}
***************
*** 138,141 ****
--- 149,159 ----
* Therefore we use a call to this function as a trigger to make sure
* that we have all of the CLOB data, if that is possible.
+ * <P>
+ * If the data includes newlines, the user must not be allowed to edit it
+ * in the cell because the CellEditor uses a JTextField which filters out newlines.
+ * If we try to use anything other than a JTextField, or use a JTextField with no
+ * newline filtering, the text is not visible in the cell, so the user cannot even read
+ * the text, much less edit it. The simplest solution is to allow editing of multi-line
+ * text only in the Popup window.
*/
public boolean isEditableInCell(Object originalValue) {
***************
*** 143,173 ****
ClobDescriptor cdesc = (ClobDescriptor)originalValue;
! // data is editable if the CLOB has been read and either
! // the size was not limited by the user, or the data is shorter
! // than the user's limit.
! if (cdesc.getClobRead() &&
! (cdesc.getUserSetClobLimit() == 0 ||
! cdesc.getUserSetClobLimit() < cdesc.getData().length()) )
! return true;
!
! // data was not fully read in before, so try to do that now
! try {
! //????????????????????????????????????????????????????????????????
! String data = cdesc.getClob().getSubString(1, (int)cdesc.getClob().length());
!
! // read succeeded, so reset the ClobDescriptor to match
! cdesc.setClobRead(true);
! cdesc.setData(data);
! cdesc.setWholeClobRead(true);
! cdesc.setUserSetClobLimit(0);
!
! return true;
}
! catch (Exception ex) {
! cdesc.setClobRead(true);
! cdesc.setWholeClobRead(false);
! cdesc.setData("Sorry Colin, could not read the data. Error was: "+ex.getMessage());
! return false;
! }
}
--- 161,174 ----
ClobDescriptor cdesc = (ClobDescriptor)originalValue;
! if (wholeClobRead(cdesc)) {
! // all the data from the clob has been read.
! // make sure there are no newlines in it
! if ( cdesc != null && cdesc.getData() != null && cdesc.getData().indexOf('\n') > -1)
! return false;
! else return true;
}
!
! // since we do not have all of the data from the clob, we cannot allow editing
! return false;
}
***************
*** 215,239 ****
public Object validateAndConvert(String value, Object originalValue, StringBuffer messageBuffer) {
// handle null, which is shown as the special string "<null>"
! if (value.equals("<null>") || value.equals(""))
return null;
- // Sprcial case: when reading/writing data from/to files, this function is
- // called to verify that the string is in a valid format. If we are able to
- // correctly convert the string to the CLOB internal format, there is no error,
- // so just return without creating/changing a ClobDescriptor.
- if (originalValue == null)
- return null; // for CLOB, the internal data type is String, so it is ok.
-
// Do the conversion into the object in a safe manner
- // Reuse the original java.sql.Clob object, but reset all of the
- // fields to indicate that this is the entire value of the CLOB field.
! // for convenience, cast the object
! ClobDescriptor cdesc = (ClobDescriptor)originalValue;
! cdesc.setData(value);
! cdesc.setClobRead(true);
! cdesc.setWholeClobRead(true);
! cdesc.setUserSetClobLimit(0);
! return originalValue;
}
--- 216,243 ----
public Object validateAndConvert(String value, Object originalValue, StringBuffer messageBuffer) {
// handle null, which is shown as the special string "<null>"
! if (value.equals("<null>"))
return null;
// Do the conversion into the object in a safe manner
! // if the original object is not null, then it contains a Clob object
! // that we need to re-use, since that is the DBs reference to the clob data area.
! // Otherwise, we set the original Clob to null, and the write method needs to
! // know to set the field to null.
! ClobDescriptor cdesc;
! if (originalValue == null) {
! // no existing clob to re-use
! cdesc = new ClobDescriptor(null, value, true, true, 0);
! }
! else {
! // for convenience, cast the existing object
! cdesc = (ClobDescriptor)originalValue;
!
! // create new object to hold the different value, but use the same internal CLOB pointer
! // as the original
! cdesc = new ClobDescriptor(cdesc.getClob(),value,
! true, true, 0);
! }
! return cdesc;
}
***************
*** 266,271 ****
*/
public boolean isEditableInPopup(Object originalValue) {
! // use same algorithm as for cell
! return isEditableInCell(originalValue);
}
--- 270,276 ----
*/
public boolean isEditableInPopup(Object originalValue) {
! // If all of the data has been read, then the clob can be edited in the Popup,
! // otherwise it cannot
! return wholeClobRead((ClobDescriptor)originalValue);
}
***************
*** 363,367 ****
--- 368,404 ----
}
+ /*
+ * Make sure the entire CLOB data is read in.
+ * Return true if it has been read successfully, and false if not.
+ */
+ private boolean wholeClobRead(ClobDescriptor cdesc) {
+ if (cdesc == null)
+ return true; // can use an empty clob for editing
+
+ if (cdesc.getWholeClobRead())
+ return true; // the whole clob has been previously read in
+ // data was not fully read in before, so try to do that now
+ try {
+ String data = cdesc.getClob().getSubString(1, (int)cdesc.getClob().length());
+
+ // read succeeded, so reset the ClobDescriptor to match
+ cdesc.setClobRead(true);
+ cdesc.setData(data);
+ cdesc.setWholeClobRead(true);
+ cdesc.setUserSetClobLimit(0);
+
+ // we successfully read the whole thing
+ return true;
+ }
+ catch (Exception ex) {
+ cdesc.setClobRead(false);
+ cdesc.setWholeClobRead(false);
+ cdesc.setData(null);
+ //?? What to do with this error?
+ //?? error message = "Could not read the complete data. Error was: "+ex.getMessage());
+ return false;
+ }
+ }
/*
***************
*** 397,402 ****
if (len > 0)
{
-
- //?????????????????????????????????????????????????????????????????????????
int charsToRead = len;
if (!largeObjInfo.getReadCompleteClobs())
--- 434,437 ----
***************
*** 411,414 ****
--- 446,450 ----
}
}
+
// determine whether we read all there was in the clob or not
boolean wholeClobRead = false;
***************
*** 442,446 ****
*/
public String getWhereClauseValue(Object value) {
! if (value == null || value.toString() == null || value.toString().length() == 0)
return _colDef.getLabel() + " IS NULL";
else
--- 478,482 ----
*/
public String getWhereClauseValue(Object value) {
! if (value == null || ((ClobDescriptor)value).getData() == null)
return _colDef.getLabel() + " IS NULL";
else
***************
*** 455,459 ****
public void setPreparedStatementValue(PreparedStatement pstmt, Object value, int position)
throws java.sql.SQLException {
! if (value == null) {
pstmt.setNull(position, _colDef.getSqlType());
}
--- 491,495 ----
public void setPreparedStatementValue(PreparedStatement pstmt, Object value, int position)
throws java.sql.SQLException {
! if (value == null || ((ClobDescriptor)value).getData() == null) {
pstmt.setNull(position, _colDef.getSqlType());
}
***************
*** 461,473 ****
// for convenience cast the object to ClobDescriptor
ClobDescriptor cdesc = (ClobDescriptor)value;
! // I'm not sure whether I need to do both of the following.
!
! // first put the data into the Clob
! //???????????????????????????????????????????????????????????????????????????????????
! cdesc.getClob().setString(0, cdesc.getData());
!
! // now put the clob back into the DB
! pstmt.setClob(position, cdesc.getClob());
}
}
--- 497,508 ----
// for convenience cast the object to ClobDescriptor
ClobDescriptor cdesc = (ClobDescriptor)value;
+ //?? Any problem if no previous clob??
! // There are a couple of possible ways to update the data in the DB.
! // The first is to use setString like this:
! // cdesc.getClob().setString(0, cdesc.getData());
! // However, the DB2 driver throws an exception saying that that function
! // is not implemented, so we have to use the other method, which is to use a stream.
! pstmt.setAsciiStream(position, new StringBufferInputStream(cdesc.getData()), cdesc.getData().length());
}
}
|