1 10 package com.triactive.jdo.store; 11 12 import com.triactive.jdo.PersistenceManager; 13 import com.triactive.jdo.StateManager; 14 import java.io.IOException ; 15 import java.io.InputStreamReader ; 16 import java.sql.Connection ; 17 import java.sql.PreparedStatement ; 18 import java.sql.ResultSet ; 19 import java.sql.SQLException ; 20 import java.sql.Types ; 21 import javax.jdo.JDODataStoreException; 22 import oracle.sql.CLOB; 23 import org.apache.log4j.Category; 24 25 26 public class OracleClobMapping extends StringMapping implements PostInsertProcessing, PostUpdateProcessing 27 { 28 private static final Category LOG = Category.getInstance(OracleClobMapping.class); 29 30 private final ClassBaseTable table; 31 private final int absoluteFieldNumber; 32 private ColumnMapping idMapping = null; 33 private String fetchStmt = null; 34 35 36 public OracleClobMapping(ClassBaseTable table, int relativeFieldNumber) 37 { 38 super(table.newColumn(relativeFieldNumber)); 39 40 if (col.getLengthType() != Column.UNLIMITED_LENGTH) 41 throw new ColumnDefinitionException("Invalid length specified for CLOB column " + col + ", must be 'unlimited'"); 42 43 this.table = table; 44 this.absoluteFieldNumber = relativeFieldNumber + table.getClassMetaData().getInheritedFieldCount(); 45 } 46 47 48 private synchronized void initialize() 49 { 50 if (idMapping == null) 51 { 52 idMapping = table.getIDMapping(); 53 54 FetchStatement stmt = new FetchStatement(table); 55 stmt.select(getColumn()); 56 stmt.andCondition(stmt.referenceColumn(idMapping.getColumn()) + " = ?"); 57 58 fetchStmt = stmt.toString() + " FOR UPDATE"; 59 } 60 } 61 62 63 protected TypeInfo getTypeInfo() 64 { 65 return dba.getTypeInfo(Types.CLOB); 66 } 67 68 69 public String getSQLInsertionValue() 70 { 71 return "EMPTY_CLOB()"; 72 } 73 74 75 public String getSQLUpdateValue() 76 { 77 return "EMPTY_CLOB()"; 78 } 79 80 81 public void setString(PersistenceManager pm, PreparedStatement ps, int param, String value) 82 { 83 } 85 86 87 public String getString(PersistenceManager pm, ResultSet rs, int param) 88 { 89 String value = null; 90 91 try 92 { 93 char[] cbuf = null; 94 CLOB clob = (CLOB)rs.getClob(param); 95 96 if (clob != null) 97 { 98 101 StringBuffer sbuf = new StringBuffer (); 102 InputStreamReader reader = new InputStreamReader (clob.asciiStreamValue()); 103 long size = clob.length(); 104 105 try 106 { 107 final int BUFF_SIZE = 4096; 108 cbuf = new char[BUFF_SIZE]; 109 int charsRead = reader.read(cbuf); 110 111 while (-1 != charsRead) 112 { 113 sbuf.append(cbuf, 0, charsRead ); 114 115 java.util.Arrays.fill(cbuf, (char)0); 116 charsRead = reader.read(cbuf); 117 } 118 119 } 120 catch (IOException e) 121 { 122 throw new JDODataStoreException("Error reading Oracle CLOB object: param = " + param, e); 123 } 124 125 value = sbuf.toString(); 126 127 if (value.length() == 0) 128 value = null; 129 else if (value.equals(OracleStringMapping.EMPTY_STRING_SURROGATE)) 130 value = ""; 131 } 132 } 133 catch (SQLException e) 134 { 135 throw dba.newDataStoreException("Can't get String result: param = " + param, e); 136 } 137 138 return value; 139 } 140 141 142 public void setObject(PersistenceManager pm, PreparedStatement ps, int param, Object value) 143 { 144 setString(pm, ps, param, (String )value); 145 } 146 147 148 public Object getObject(PersistenceManager pm, ResultSet rs, int param) 149 { 150 return getString(pm, rs, param); 151 } 152 153 154 public void postInsert(StateManager sm, Connection conn, Object value) 155 { 156 postUpdate(sm, conn, value); 157 } 158 159 160 164 public void postUpdate(StateManager sm, Connection conn, Object value) 165 { 166 initialize(); 167 168 String strval = (String )value; 169 170 if (strval == null) 171 strval = ""; 172 else if (strval.length() == 0) 173 strval = OracleStringMapping.EMPTY_STRING_SURROGATE; 174 175 PersistenceManager pm = sm.getPersistenceManager(); 176 177 try 178 { 179 PreparedStatement ps = conn.prepareStatement(fetchStmt); 180 181 try 182 { 183 Object id = sm.getObjectId(); 184 idMapping.setObject(pm, ps, 1, id); 185 186 long startTime = System.currentTimeMillis(); 187 188 ResultSet rs = ps.executeQuery(); 189 190 try 191 { 192 if (LOG.isDebugEnabled()) 193 LOG.debug("Time = " + (System.currentTimeMillis() - startTime) + " ms: " + fetchStmt); 194 195 if (!rs.next()) 196 throw new ObjectNotFoundException("No such database row", sm.getObject()); 197 198 CLOB clob = (CLOB)rs.getClob(1); 199 200 clob.putString(1, strval); 201 } 202 finally 203 { 204 rs.close(); 205 } 206 } 207 finally 208 { 209 ps.close(); 210 } 211 } 212 catch (SQLException e) 213 { 214 throw dba.newDataStoreException("CLOB update failed: " + fetchStmt, e); 215 } 216 } 217 } 218 | Popular Tags |