KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > jdbc > JdbcGenericState


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.jdbc;
13
14 import com.versant.core.common.*;
15 import com.versant.core.metadata.FetchGroup;
16 import com.versant.core.metadata.FetchGroupField;
17 import com.versant.core.metadata.FieldMetaData;
18 import com.versant.core.metadata.ClassMetaData;
19 import com.versant.core.jdbc.metadata.*;
20 import com.versant.core.server.PersistGraph;
21
22 import java.sql.PreparedStatement JavaDoc;
23 import java.sql.SQLException JavaDoc;
24 import java.sql.ResultSet JavaDoc;
25
26 /**
27  * Adds JDBC specific methods to GenericState.
28  */

29 public class JdbcGenericState extends GenericState implements JdbcState {
30
31     public JdbcGenericState() {
32     }
33
34     public JdbcGenericState(ClassMetaData cmd) {
35         super(cmd);
36     }
37
38     /**
39      * Return 0 if state has the same field numbers as us, less than 0 we are
40      * less than it or greater than 0 if we are greater than it. The definition
41      * of less than and greater than is up to the state implementation but
42      * must be detirministic. For fields that are stored using Oracle style
43      * LOBs then the nullness of the value must also be considered in the
44      * comparison i.e. states with field x null and not null respectively
45      * are different.
46      *
47      * @param state State to compare to (will be for same class)
48      */

49     public int compareToPass1(State state) {
50         JdbcGenericState s = (JdbcGenericState)state;
51         checkCmd();
52         boolean[] sf = s.filled;
53         for (int i = 0; i < filled.length; i++) {
54             if (!cmd.stateFields[i].primaryField) continue;
55             boolean a = filled[i];
56             boolean b = sf[i];
57             if (a && !b) return -1;
58             if (!a && b) return +1;
59             if (a) {
60                 // both fields are filled so if the field is a LOB consider
61
// value nullness
62
JdbcField jdbcField = (JdbcField)cmd.stateFields[i].storeField;
63                 if (jdbcField.isOracleStyleLOB()) {
64                     a = isNull(i);
65                     b = s.isNull(i);
66                     if (a && !b) return -1;
67                     if (!a && b) return +1;
68                 }
69             }
70         }
71         return 0;
72     }
73
74     /**
75      * Populate this State from the given ResultSet. The firstCol parameter
76      * specifies the column index of the first column to read from rs. All
77      * persistent fields in the fetch group must be read in order.
78      */

79     public void copyPass1Fields(ResultSet JavaDoc rs, FetchGroup fetchGroup,
80             int firstCol) {
81         FetchGroupField[] a = fetchGroup.fields;
82         for (int i = 0; i < a.length; i++) {
83             try {
84                 FieldMetaData fmd = a[i].fmd;
85                 if (!fmd.primaryField) continue;
86                 JdbcField f = (JdbcField)fmd.storeField;
87                 int fieldNo = f.stateFieldNo;
88                 firstCol = getFieldData(f, rs, firstCol, fieldNo);
89                 filled[fieldNo] = true;
90             } catch (Exception JavaDoc e) {
91                 throw BindingSupportImpl.getInstance().datastore("Error reading field " + a[i].fmd.getQName() +
92                         " from ResultSet: " + e,
93                         e);
94             }
95         }
96     }
97
98     public void copyPass1Fields(ResultSet JavaDoc rs, JdbcField[] fields) {
99         JdbcField f = null;
100         for (int i = 0; i < fields.length; i++) {
101             try {
102                 f = fields[i];
103                 if (f == null) continue;
104                 //ignore fields that are not in the statefields
105
if (f.stateFieldNo < cmd.stateFields.length
106                         && cmd.stateFields[f.stateFieldNo] == f.fmd) {
107                     getFieldData(f, rs, i + 1, f.stateFieldNo);
108                     filled[f.stateFieldNo] = true;
109                 }
110             } catch (SQLException JavaDoc e) {
111                 throw BindingSupportImpl.getInstance().datastore("Error reading field "
112                         + f == null ? "" : f.fmd.getQName() +
113                         " from ResultSet: " + e, e);
114             }
115         }
116     }
117
118     private int getFieldData(JdbcField f, ResultSet JavaDoc rs, int firstCol,
119             int fieldNo) throws SQLException JavaDoc {
120         if (f instanceof JdbcSimpleField) {
121             JdbcColumn c = ((JdbcSimpleField)f).col;
122             if (Debug.DEBUG) {
123                 if (!c.name.toUpperCase().equals(
124                         rs.getMetaData().getColumnName(firstCol).toUpperCase())) {
125                     throw BindingSupportImpl.getInstance().internal(
126                             "Reading the wrong column: " + firstCol + " \nrs field = "
127                             + rs.getMetaData().getColumnName(firstCol) + "\nmetaData field = " + c.name);
128                 }
129             }
130             if (c.converter != null) {
131                 data[fieldNo] = c.converter.get(rs, firstCol++, c);
132             } else {
133                 data[fieldNo] = JdbcUtils.get(rs, firstCol++, c.javaTypeCode,
134                         c.scale);
135                 if (rs.wasNull()) {
136                     data[fieldNo] = null;
137                 }
138             }
139         } else if (f instanceof JdbcRefField) {
140             JdbcRefField rf = (JdbcRefField)f;
141             JdbcOID oid = (JdbcOID)rf.targetClass.createOID(false);
142             if (oid.copyKeyFields(rs, firstCol)) {
143                 data[fieldNo] = oid;
144             } else {
145                 data[fieldNo] = null;
146             }
147             firstCol += rf.cols.length;
148         } else if (f instanceof JdbcPolyRefField) {
149             data[fieldNo] = getPolyRefOID(f, rs, firstCol);
150             firstCol += ((JdbcPolyRefField)f).cols.length;
151         } else {
152             throw BindingSupportImpl.getInstance().internal("not implemented");
153         }
154         return firstCol;
155     }
156
157     /**
158      * Set parameters on a PrepareStatement from this State. The firstParam
159      * parameter specifies the column index of the first parameter to set.
160      * Entries in fieldNos that are less than 0 should be skipped.
161      *
162      * @param firstFieldNo The index of the first state field to set
163      * @param lastFieldNo The index of the last state field to set + 1
164      * @param tableNo Set fields with table == jdbcClass.allTables[tableNo]
165      * @return the index of the last param set + 1
166      */

167     public int setParams(PreparedStatement JavaDoc ps, int[] stateFieldNos,
168             int firstFieldNo, int lastFieldNo, int firstParam,
169             PersistGraph pGraph, int tableNo) throws SQLException JavaDoc {
170         JdbcTable table = ((JdbcClass)cmd.storeClass).allTables[tableNo];
171         for (int i = firstFieldNo; i < lastFieldNo; i++) {
172             int fieldNo = stateFieldNos[i];
173             if (fieldNo >= 0) {
174                 JdbcField field = (JdbcField)cmd.stateFields[fieldNo].storeField;
175                 if (field.mainTable == table) {
176                     firstParam = setFieldData(field, ps, firstParam, fieldNo);
177                 }
178             }
179         }
180         return firstParam;
181     }
182
183     /**
184      * Set parameters on a PrepareStatement from this State for fields that
185      * are not null. The firstParam parameter specifies the column index of
186      * the first parameter. This will not be called for classes that are not
187      * stored by the JdbcDataStore or that do not use changed optimistic
188      * locking. Entries in fieldNos that are less than 0 should be skipped.
189      *
190      * @param firstFieldNo The index of the first field to set
191      * @param lastFieldNo The index of the last field to set + 1
192      * @param tableNo
193      * @return the index of the last param set + 1
194      */

195     public int setParamsChangedAndNotNull(PreparedStatement JavaDoc ps, int[] fieldNos,
196             int firstFieldNo, int lastFieldNo, int firstParam,
197             PersistGraph pGraph, int tableNo) throws SQLException JavaDoc {
198         checkCmd();
199         JdbcTable table = ((JdbcClass)cmd.storeClass).allTables[tableNo];
200         for (int i = firstFieldNo; i < lastFieldNo; i++) {
201             int fieldNo = fieldNos[i];
202             if (fieldNo < 0 || data[fieldNo] == null) continue;
203             JdbcField field = (JdbcField)cmd.stateFields[fieldNo].storeField;
204             if (field.includeForChangedLocking && field.mainTable == table) {
205                 firstParam = setFieldData(field, ps, firstParam, fieldNo);
206             }
207         }
208         return firstParam;
209     }
210
211     /**
212      * Set parameters on a PrepareStatement from the optimistic locking field
213      * for the class for this State. The firstParam parameter specifies the
214      * column index of the first parameter to set.
215      *
216      * @return the index of the last param set + 1
217      * @throws javax.jdo.JDOFatalInternalException
218      * if there is no such field
219      * @see JdbcClass#optimisticLockingField
220      */

221     public int setOptimisticLockingParams(PreparedStatement JavaDoc ps,
222             int firstParam) throws SQLException JavaDoc {
223         checkCmd();
224         JdbcSimpleField f = ((JdbcClass)cmd.storeClass).optimisticLockingField;
225         if (f == null) {
226             throw BindingSupportImpl.getInstance().internal("setOptimisticLockingParams " +
227                     "called for non-optimistic locking class: " + cmd);
228         }
229         int fieldNo = f.stateFieldNo;
230         // carl do not put this test into generated State class
231
if (!containsField(fieldNo)) {
232             throw BindingSupportImpl.getInstance().internal("setOptimisticLockingParams " +
233                     "called for state not containing optimistic locking field: " +
234                     cmd.qname + " " + f);
235         }
236         JdbcColumn c = f.col;
237         if (c.converter != null) {
238             c.converter.set(ps, firstParam++, c, data[fieldNo]);
239         } else {
240             JdbcUtils.set(ps, firstParam++, data[fieldNo], c.javaTypeCode,
241                     c.jdbcType);
242         }
243         return firstParam;
244     }
245
246     private int setFieldData(JdbcField f, PreparedStatement JavaDoc ps, int firstParam,
247             int fieldNo) throws SQLException JavaDoc {
248         if (f instanceof JdbcSimpleField) {
249             JdbcColumn c = ((JdbcSimpleField)f).col;
250             if (c.isForUpdate()) {
251                 if (c.converter != null) {
252                     c.converter.set(ps, firstParam++, c, data[fieldNo]);
253                 } else {
254                     JdbcUtils.set(ps, firstParam++, data[fieldNo], c.javaTypeCode,
255                             c.jdbcType);
256                 }
257             }
258         } else if (f instanceof JdbcRefField) {
259             OID oid = (OID)data[fieldNo];
260             if (oid == null || (oid = oid.getRealOID()) == null) {
261                 firstParam = setRefFieldToNull(f.mainTableCols, ps, firstParam);
262             } else {
263                 firstParam = ((JdbcOID)oid).setParams(ps, firstParam, f.mainTableCols);
264             }
265         } else if (f instanceof JdbcPolyRefField) {
266             firstParam = setPolyRefData(f, (OID)data[fieldNo], cmd, ps,
267                     firstParam);
268         } else {
269             throw BindingSupportImpl.getInstance().internal("not implemented");
270         }
271         return firstParam;
272     }
273
274     /**
275      * Call the set(rs,...) method on each of the converters for the first
276      * numFieldNos entries in stateFieldNos. This is used to handle Oracle
277      * style LOB columns.
278      *
279      * @param firstCol The first column in rs to use
280      * @see com.versant.core.jdbc.JdbcConverter#set
281      */

282     public void setOracleStyleLOBs(ResultSet JavaDoc rs, int[] stateFieldNos,
283             int numFieldNos, int firstCol) throws SQLException JavaDoc {
284         for (int i = 0; i < numFieldNos; i++) {
285             int fieldNo = stateFieldNos[i];
286             JdbcField jdbcField = (JdbcField)cmd.stateFields[fieldNo].storeField;
287             JdbcColumn c = ((JdbcSimpleField)jdbcField).col;
288             c.converter.set(rs, firstCol++, c, data[fieldNo]);
289         }
290     }
291
292     private com.versant.core.common.OID getPolyRefOID(
293             com.versant.core.metadata.FieldMetaData fmd,
294             java.sql.ResultSet JavaDoc rs,
295             int firstCol) throws java.sql.SQLException JavaDoc {
296         return getPolyRefOID((JdbcField)fmd.storeField, rs, firstCol);
297     }
298
299     public static com.versant.core.common.OID getPolyRefOID(
300             com.versant.core.jdbc.metadata.JdbcField f,
301             java.sql.ResultSet JavaDoc rs,
302             int firstCol)
303             throws java.sql.SQLException JavaDoc {
304         com.versant.core.jdbc.metadata.JdbcPolyRefField pf =
305                 (com.versant.core.jdbc.metadata.JdbcPolyRefField)f;
306         return pf.getData(rs, firstCol);
307     }
308
309     private int setPolyRefData(
310             com.versant.core.metadata.FieldMetaData fmd,
311             com.versant.core.common.OID oid,
312             com.versant.core.metadata.ClassMetaData cmd,
313             java.sql.PreparedStatement JavaDoc ps,
314             int firstParam) throws java.sql.SQLException JavaDoc {
315         return setPolyRefData((JdbcField)fmd.storeField, oid, cmd, ps, firstParam);
316     }
317
318     public static int setPolyRefData(
319             com.versant.core.jdbc.metadata.JdbcField f,
320             com.versant.core.common.OID oid,
321             com.versant.core.metadata.ClassMetaData cmd,
322             java.sql.PreparedStatement JavaDoc ps,
323             int firstParam) throws java.sql.SQLException JavaDoc {
324         com.versant.core.jdbc.metadata.JdbcPolyRefField pf =
325                 (com.versant.core.jdbc.metadata.JdbcPolyRefField)f;
326         return pf.setData(ps, firstParam, oid);
327     }
328
329     public static int setRefFieldToNull(JdbcColumn[] cols,
330             PreparedStatement JavaDoc ps, int firstParam) throws SQLException JavaDoc {
331         int nc = cols.length;
332         for (int i = 0; i < nc; i++) {
333             JdbcColumn col = cols[i];
334             if (col.isForUpdate()) {
335                 ps.setNull(firstParam++, col.jdbcType);
336             }
337         }
338         return firstParam;
339     }
340
341     public boolean hasSameNullFields(State state, State mask) {
342         checkCmd();
343         JdbcClass jc = (JdbcClass)cmd.storeClass;
344         if (jc.optimisticLocking != JdbcClass.OPTIMISTIC_LOCKING_CHANGED) {
345             return true;
346         }
347         JdbcGenericState s = (JdbcGenericState)state;
348         JdbcGenericState ms = (JdbcGenericState)mask;
349         int n = filled.length;
350         for (int i = 0; i < n; i++) {
351             if (ms.filled[i]) {
352                 if ((data[i] == null) != (s.data[i] == null)) return false;
353             }
354         }
355         return true;
356     }
357
358 }
359
360
Popular Tags