001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdbc.metadata;
012:
013: import com.versant.core.jdbc.sql.JdbcNameGenerator;
014: import com.versant.core.jdbc.sql.SqlDriver;
015: import com.versant.core.jdbc.sql.exp.ColumnExp;
016: import com.versant.core.jdbc.sql.exp.SelectExp;
017: import com.versant.core.jdbc.JdbcUtils;
018: import com.versant.core.jdbc.JdbcConverter;
019: import com.versant.core.util.CharBuf;
020: import com.versant.core.common.State;
021:
022: import java.util.ArrayList;
023: import java.sql.PreparedStatement;
024: import java.sql.SQLException;
025:
026: import com.versant.core.common.BindingSupportImpl;
027:
028: /**
029: * A field that fits into a single logical column. Note that this includes
030: * embedded fields like primitive arrays[] (byte[], int[], Integer[] etc.).
031: */
032: public class JdbcSimpleField extends JdbcField {
033:
034: /**
035: * The column used to store this field.
036: */
037: public JdbcColumn col;
038:
039: private boolean oracleStyleLOB;
040: private String oracleStyleLOBNotNullString;
041:
042: /**
043: * Set the table field on all our main table columns.
044: */
045: public void setMainTable(JdbcTable table) {
046: super .setMainTable(table);
047: col.setTable(table);
048: }
049:
050: /**
051: * Make sure all of this fields main table columns have names.
052: */
053: public void nameColumns(String tableName, JdbcNameGenerator nameGen) {
054: if (col.name == null) {
055: col.name = nameGen.generateFieldColumnName(tableName,
056: fmd.name, false);
057: } else if (!nameGen.isColumnInTable(tableName, col.name)) {
058: try {
059: nameGen.addColumnName(tableName, col.name);
060: } catch (IllegalArgumentException e) {
061: throw BindingSupportImpl.getInstance().runtime(
062: "Invalid jdbc-column-name for field "
063: + fmd.name + ": " + e.getMessage()
064: + "\n" + getContext());
065: }
066: }
067: }
068:
069: /**
070: * Init the mainTableCols field to all our main table columns.
071: */
072: public void initMainTableCols() {
073: mainTableCols = new JdbcColumn[] { col };
074: JdbcConverter converter = col.converter;
075: if (converter != null) {
076: oracleStyleLOB = converter.isOracleStyleLOB();
077: oracleStyleLOBNotNullString = converter
078: .getOracleStyleLOBNotNullString();
079: } else {
080: oracleStyleLOB = false;
081: }
082: super .initMainTableCols();
083: }
084:
085: /**
086: * Flatten all of this fields main table columns to a.
087: */
088: public void addMainTableCols(ArrayList a) {
089: a.add(col);
090: }
091:
092: /**
093: * Append part of an update statement for us to s (e.g col = ?).
094: */
095: public boolean appendUpdate(CharBuf s, State state) {
096: s.append(col.name);
097: s.append('=');
098: if (oracleStyleLOB) {
099: if (state.isNull(stateFieldNo)) {
100: s.append("null");
101: } else {
102: s.append(oracleStyleLOBNotNullString);
103: }
104: return true;
105: } else {
106: s.append('?');
107: return false;
108: }
109: }
110:
111: /**
112: * Append part of a where clause for us to s (e.g cola = ? and colb = ?).
113: * This is used for generating the where clause for changed locking.
114: */
115: public void appendWhere(CharBuf s, SqlDriver sqlDriver) {
116: s.append(col.name);
117: s.append("=");
118: sqlDriver.appendWhereParam(s, col);
119: }
120:
121: /**
122: * Append part of a is null where clause for us to s (e.g cola is null
123: * and colb is null).
124: * This is used for generating the where clause for changed locking.
125: */
126: public void appendWhereIsNull(CharBuf s, SqlDriver sqlDriver) {
127: s.append(col.name);
128: s.append(" is null");
129: }
130:
131: /**
132: * Append part of the insert list for us to s (e.g. cola, colb)).
133: */
134: public void appendInsertColumnList(CharBuf s) {
135: s.append(col.name);
136: }
137:
138: /**
139: * Append part of the insert value list for us to s (e.g. ?, ?)). This
140: * must return true if a replacable parameter was <b>not</b> added (e.g.
141: * columns using Oracle LOBs which put in empty_clob() or whatever).
142: */
143: public boolean appendInsertValueList(CharBuf s, State state) {
144: if (oracleStyleLOB) {
145: if (state.isNull(stateFieldNo))
146: s.append("null");
147: else
148: s.append(oracleStyleLOBNotNullString);
149: return true;
150: } else {
151: s.append('?');
152: return false;
153: }
154: }
155:
156: /**
157: * Convert this field into a list of ColumnExp's or null if this is
158: * not possible.
159: */
160: public ColumnExp toColumnExp(SelectExp se, boolean joinToSuper) {
161: if (joinToSuper)
162: return new ColumnExp(col, SelectExp.createJoinToSuperTable(
163: se, this ), this );
164: else
165: return new ColumnExp(col, se, this );
166: }
167:
168: public ColumnExp createOwningTableColumnExpList(SelectExp se) {
169: return new ColumnExp(col, se, this );
170: }
171:
172: /**
173: * Set this field on a PreparedStatement. This is used to set parameters
174: * for queries.
175: * @return Index of the parameter after the last one we set in ps
176: */
177: public int setQueryParam(PreparedStatement ps, int firstParam,
178: Object value) throws SQLException {
179: if (col.converter != null) {
180: col.converter.set(ps, firstParam++, col, value);
181: } else {
182: JdbcUtils.set(ps, firstParam++, value, col.javaTypeCode,
183: col.jdbcType);
184: }
185: return firstParam;
186: }
187:
188: /**
189: * Does this field require the sucky Oracle LOB support on insert/update?
190: */
191: public boolean isOracleStyleLOB() {
192: return oracleStyleLOB;
193: }
194:
195: }
|