001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2002-2004 French National Institute For Research In Computer
004: * Science And Control (INRIA).
005: * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
006: * Contact: sequoia@continuent.org
007: *
008: * Licensed under the Apache License, Version 2.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: * Initial developer(s): Emmanuel Cecchet.
021: * Contributor(s): Nicolas Modrzyk, Marc Herbert.
022: */package org.continuent.sequoia.common.protocol;
023:
024: import java.io.IOException;
025: import java.io.Serializable;
026:
027: import org.continuent.sequoia.common.stream.DriverBufferedInputStream;
028: import org.continuent.sequoia.common.stream.DriverBufferedOutputStream;
029: import org.continuent.sequoia.driver.ResultSetMetaData;
030:
031: /**
032: * Field is our private implementation of <code>ResultSetMetaData</code>,
033: * holding the information for one column.
034: * <p>
035: * The first version was inspired from the MM MySQL driver by Mark Matthews.
036: *
037: * @see org.continuent.sequoia.driver.DriverResultSet
038: * @see org.continuent.sequoia.controller.backend.result.ControllerResultSet
039: * @author <a href="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet </a>
040: * @author <a href="mailto:Nicolas.Modrzyk@inria.fr">Nicolas Modrzyk </a>
041: * @author <a href="mailto:Marc.Herbert@emicnetworks.com">Marc Herbert </a>
042: * @version 1.0
043: */
044: public class Field implements Serializable {
045: //
046: // This object is manually (de-)serialized below for compatibility with C.
047: // It also implements Serializable for the convenience of Java-Java
048: // communication (typically between controllers).
049: //
050: // Ideally:
051: // (1) unneeded fields for Java-Java communication are all tagged as
052: // "transient"
053: // (2) C-Java and Java-Java need to send the exact same fields.
054: // And so:
055: // (3) keeping up-to-date manual serialization below is easy: just check
056: // "transient" tags.
057:
058: private static final long serialVersionUID = 1050843622547803111L;
059:
060: private String tableName;
061: private String fieldName;
062: private String fieldLabel;
063: private int columnDisplaySize;
064: private int sqlType;
065: private String typeName;
066: private String columnClassName;
067: private boolean isAutoIncrement;
068: private boolean isCaseSensitive;
069: private boolean isCurrency;
070: private int isNullable;
071: private boolean isReadOnly;
072: private boolean isWritable;
073: private boolean isDefinitelyWritable;
074: private boolean isSearchable;
075: private boolean isSigned;
076: private int precision;
077: private int scale;
078: private String encoding;
079:
080: /**
081: * Create a new field with some default common values.
082: *
083: * @param table the table name
084: * @param columnName the field name
085: * @param columnDisplaySize the column display size
086: * @param sqlType the SQL type
087: * @param typeName the type name
088: * @param columnClassName the column class name
089: */
090: public Field(String table, String columnName,
091: int columnDisplaySize, int sqlType, String typeName,
092: String columnClassName) {
093: this (table, columnName, columnName, columnDisplaySize, sqlType,
094: typeName, columnClassName, false, true, false,
095: ResultSetMetaData.columnNullable, true, false, false,
096: false, false, 0, 0, null);
097: }
098:
099: /**
100: * Creates a new <code>Field</code> instance using the reference arguments
101: * (arguments are NOT cloned).
102: *
103: * @param table the table name
104: * @param columnName the field name
105: * @param columnLabel the field label
106: * @param columnDisplaySize the column display size
107: * @param sqlType the SQL type
108: * @param typeName the type name
109: * @param columnClassName the column class name
110: * @param isAutoIncrement true if field is auto incremented
111: * @param isCaseSensitive true if field is case sensitive
112: * @param isCurrency true if field is currency
113: * @param isNullable indicates the nullability of the field
114: * @param isReadOnly true if field is read only
115: * @param isWritable true if field is writable
116: * @param isDefinitelyWritable true if field is definetly writable
117: * @param isSearchable true if field is searchable
118: * @param isSigned true if field is signed
119: * @param precision decimal precision
120: * @param scale number of digits to right of decimal point
121: * @param encoding the encoding of this field, if any
122: */
123: public Field(String table, String columnName, String columnLabel,
124: int columnDisplaySize, int sqlType, String typeName,
125: String columnClassName, boolean isAutoIncrement,
126: boolean isCaseSensitive, boolean isCurrency,
127: int isNullable, boolean isReadOnly, boolean isWritable,
128: boolean isDefinitelyWritable, boolean isSearchable,
129: boolean isSigned, int precision, int scale, String encoding) {
130: this .tableName = table;
131: this .fieldName = columnName;
132: this .fieldLabel = columnLabel;
133: this .columnDisplaySize = columnDisplaySize;
134: this .sqlType = sqlType;
135: this .typeName = typeName;
136: this .columnClassName = columnClassName;
137: this .isAutoIncrement = isAutoIncrement;
138: this .isCaseSensitive = isCaseSensitive;
139: this .isCurrency = isCurrency;
140: this .isNullable = isNullable;
141: this .isReadOnly = isReadOnly;
142: this .isWritable = isWritable;
143: this .isDefinitelyWritable = isDefinitelyWritable;
144: this .isSearchable = isSearchable;
145: this .isSigned = isSigned;
146: this .precision = precision;
147: this .scale = scale;
148: this .encoding = encoding;
149: }
150:
151: /**
152: * Creates a new <code>Field</code> object, deserializing it from an input
153: * stream. Has to mirror the serialization method below.
154: *
155: * @param in input stream
156: * @throws IOException if a stream error occurs
157: */
158: public Field(DriverBufferedInputStream in) throws IOException {
159: if (in.readBoolean())
160: this .tableName = in.readLongUTF();
161: else
162: this .tableName = null;
163:
164: this .fieldName = in.readLongUTF();
165: this .fieldLabel = in.readLongUTF();
166: this .columnDisplaySize = in.readInt();
167: this .sqlType = in.readInt();
168: this .typeName = in.readLongUTF();
169: this .columnClassName = in.readLongUTF();
170: this .isAutoIncrement = in.readBoolean();
171: this .isCaseSensitive = in.readBoolean();
172: this .isCurrency = in.readBoolean();
173: this .isNullable = in.readInt();
174: this .isReadOnly = in.readBoolean();
175: this .isWritable = in.readBoolean();
176: this .isDefinitelyWritable = in.readBoolean();
177: this .isSearchable = in.readBoolean();
178: this .isSigned = in.readBoolean();
179: this .precision = in.readInt();
180: this .scale = in.readInt();
181: this .encoding = in.readLongUTF();
182: }
183:
184: /**
185: * Serialize the <code>Field</code> on the output stream by sending only the
186: * needed parameters to reconstruct it on the controller. Has to mirror the
187: * deserialization method above.
188: *
189: * @param out destination stream
190: * @throws IOException if a stream error occurs
191: */
192: public void sendToStream(DriverBufferedOutputStream out)
193: throws IOException {
194: if (null == this .tableName)
195: out.writeBoolean(false);
196: else {
197: out.writeBoolean(true);
198: out.writeLongUTF(this .tableName);
199: }
200:
201: out.writeLongUTF(this .fieldName);
202: out.writeLongUTF(this .fieldLabel);
203: out.writeInt(this .columnDisplaySize);
204: out.writeInt(this .sqlType);
205: out.writeLongUTF(this .typeName);
206: out.writeLongUTF(this .columnClassName);
207: out.writeBoolean(this .isAutoIncrement);
208: out.writeBoolean(this .isCaseSensitive);
209: out.writeBoolean(this .isCurrency);
210: out.writeInt(this .isNullable);
211: out.writeBoolean(this .isReadOnly);
212: out.writeBoolean(this .isWritable);
213: out.writeBoolean(this .isDefinitelyWritable);
214: out.writeBoolean(this .isSearchable);
215: out.writeBoolean(this .isSigned);
216: out.writeInt(this .precision);
217: out.writeInt(this .scale);
218: out.writeLongUTF(this .encoding);
219:
220: }
221:
222: /**
223: * Returns the fieldLabel value.
224: *
225: * @return Returns the fieldLabel.
226: */
227: public final String getFieldLabel() {
228: return fieldLabel;
229: }
230:
231: /**
232: * Gets the field name.
233: *
234: * @return a <code>String</code> value
235: */
236: public String getFieldName() {
237: return fieldName;
238: }
239:
240: /**
241: * Gets the full name: "tableName.fieldName"
242: *
243: * @return a <code>String</code> value
244: */
245: public String getFullName() {
246: return tableName + "." + fieldName;
247: }
248:
249: /**
250: * @see java.sql.ResultSetMetaData#getPrecision(int)
251: */
252: public int getPrecision() {
253: return precision;
254: }
255:
256: /**
257: * @see java.sql.ResultSetMetaData#getScale(int)
258: */
259: public int getScale() {
260: return scale;
261: }
262:
263: /**
264: * Returns the JDBC type code.
265: *
266: * @return int Type according to {@link java.sql.Types}
267: * @see java.sql.ResultSetMetaData#getColumnType(int)
268: */
269: public int getSqlType() {
270: return sqlType;
271: }
272:
273: /**
274: * Gets the table name.
275: *
276: * @return a <code>String</code> value
277: */
278: public String getTableName() {
279: return tableName;
280: }
281:
282: /**
283: * Returns the SQL type name used by the database.
284: *
285: * @return the SQL type name
286: * @see java.sql.ResultSetMetaData#getColumnTypeName(int)
287: */
288: public String getTypeName() {
289: return typeName;
290: }
291:
292: /**
293: * Returns the Java class used by the mapping.
294: *
295: * @see java.sql.ResultSetMetaData#getColumnClassName(int)
296: */
297: public String getColumnClassName() {
298: return columnClassName;
299: }
300:
301: /**
302: * @see java.sql.ResultSetMetaData#getColumnDisplaySize(int)
303: */
304: public int getColumnDisplaySize() {
305: return columnDisplaySize;
306: }
307:
308: /**
309: * @return the encoding used for this field
310: */
311: public String getEncoding() {
312: return encoding;
313: }
314:
315: /**
316: * @see java.sql.ResultSetMetaData#isAutoIncrement(int)
317: */
318: public boolean isAutoIncrement() {
319: return isAutoIncrement;
320: }
321:
322: /**
323: * @see java.sql.ResultSetMetaData#isCaseSensitive(int)
324: */
325: public boolean isCaseSensitive() {
326: return isCaseSensitive;
327: }
328:
329: /**
330: * @see java.sql.ResultSetMetaData#isCurrency(int)
331: */
332: public boolean isCurrency() {
333: return isCurrency;
334: }
335:
336: /**
337: * @see java.sql.ResultSetMetaData#isDefinitelyWritable(int)
338: */
339: public boolean isDefinitelyWritable() {
340: return isDefinitelyWritable;
341: }
342:
343: /**
344: * @see java.sql.ResultSetMetaData#isNullable(int)
345: */
346: public int isNullable() {
347: return isNullable;
348: }
349:
350: /**
351: * @see java.sql.ResultSetMetaData#isReadOnly(int)
352: */
353: public boolean isReadOnly() {
354: return isReadOnly;
355: }
356:
357: /**
358: * @see java.sql.ResultSetMetaData#isSearchable(int)
359: */
360: public boolean isSearchable() {
361: return isSearchable;
362: }
363:
364: /**
365: * @see java.sql.ResultSetMetaData#isSigned(int)
366: */
367: public boolean isSigned() {
368: return isSigned;
369: }
370:
371: /**
372: * @see java.sql.ResultSetMetaData#isWritable(int)
373: */
374: public boolean isWritable() {
375: return isWritable;
376: }
377:
378: /**
379: * Returns the full name.
380: *
381: * @return <code>String</code> value
382: * @see #getFullName()
383: */
384: public String toString() {
385: return getFullName();
386: }
387:
388: }
|