KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > common > sql > InsertRequest


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2005 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Emmanuel Cecchet.
22  * Contributor(s): Mathieu Peltier, Sara Bouchenak.
23  */

24
25 package org.objectweb.cjdbc.common.sql;
26
27 import java.io.IOException JavaDoc;
28 import java.io.Serializable JavaDoc;
29 import java.sql.SQLException JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32
33 import org.objectweb.cjdbc.common.sql.schema.DatabaseColumn;
34 import org.objectweb.cjdbc.common.sql.schema.DatabaseSchema;
35 import org.objectweb.cjdbc.common.sql.schema.DatabaseTable;
36 import org.objectweb.cjdbc.common.sql.schema.TableColumn;
37 import org.objectweb.cjdbc.common.stream.CJDBCInputStream;
38 import org.objectweb.cjdbc.common.stream.CJDBCOutputStream;
39
40 /**
41  * An <code>InsertRequest</code> is an SQL request of the following syntax:
42  *
43  * <pre>
44  * INSERT INTO table-name [(column-name[,column-name]*)] {VALUES (constant|null[,constant|null]*)}|{SELECT query}
45  * </pre>
46  * <code>VALUES<code> are ignored.
47  * *
48  * @author <a HREF="mailto:Emmanuel.Cecchet@inria.fr">Emmanuel Cecchet</a>
49  * @version 1.0
50  */

51 public class InsertRequest extends AbstractWriteRequest implements Serializable JavaDoc
52 {
53   private static final long serialVersionUID = 4184570467338568383L;
54
55   private final boolean returnsRS; // blank
56
// final for
57
// safety
58

59   /**
60    * Creates a new <code>InsertRequest</code> instance. The caller must give
61    * an SQL request, without any leading or trailing spaces and beginning with
62    * 'insert into ' (it will not be checked).
63    * <p>
64    * If the syntax is incorrect an exception is thrown.
65    *
66    * @param sqlQuery the SQL query
67    * @param escapeProcessing should the driver to escape processing before
68    * sending to the database ?
69    * @param timeout an <code>int</code> value
70    * @param lineSeparator the line separator used in the query
71    * @param schema a <code>DatabaseSchema</code> value
72    * @param granularity parsing granularity as defined in
73    * <code>ParsingGranularities</code>
74    * @param isCaseSensitive true if parsing is case sensitive
75    * @param isRead does the request expect a ResultSet ?
76    * @exception SQLException if an error occurs
77    */

78   public InsertRequest(String JavaDoc sqlQuery, boolean escapeProcessing, int timeout,
79       String JavaDoc lineSeparator, DatabaseSchema schema, int granularity,
80       boolean isCaseSensitive, boolean isRead) throws SQLException JavaDoc
81   {
82     this(sqlQuery, escapeProcessing, timeout, lineSeparator, isRead);
83     parse(schema, granularity, isCaseSensitive);
84   }
85
86   /**
87    * Creates a new <code>InsertRequest</code> instance. The caller must give
88    * an SQL request, without any leading or trailing spaces and beginning with
89    * 'create table ' (it will not be checked).
90    * <p>
91    * The request is not parsed but it can be done later by a call to
92    * {@link #parse(DatabaseSchema, int, boolean)}.
93    *
94    * @param sqlQuery the SQL request
95    * @param escapeProcessing should the driver to escape processing before
96    * sending to the database ?
97    * @param timeout an <code>int</code> value
98    * @param lineSeparator the line separator used in the query
99    * @param isRead does the request expects a ResultSet with the auto-generated
100    * keys?
101    * @see #parse
102    */

103   public InsertRequest(String JavaDoc sqlQuery, boolean escapeProcessing, int timeout,
104       String JavaDoc lineSeparator, boolean isRead)
105   {
106     super(sqlQuery, escapeProcessing, timeout, lineSeparator,
107         RequestType.INSERT);
108     this.returnsRS = isRead;
109   }
110
111   /**
112    * @see AbstractWriteRequest
113    */

114   public InsertRequest(CJDBCInputStream in) throws IOException JavaDoc
115   {
116     super(in, RequestType.INSERT);
117     returnsRS = in.readBoolean();
118     if (returnsRS)
119       receiveResultSetParams(in);
120
121   }
122
123   /**
124    * @see org.objectweb.cjdbc.common.sql.AbstractRequest#sendToStream(org.objectweb.cjdbc.common.stream.CJDBCOutputStream,
125    * boolean)
126    */

127   public void sendToStream(CJDBCOutputStream out, boolean needSkeleton)
128       throws IOException JavaDoc
129   {
130     super.sendToStream(out, needSkeleton);
131     out.writeBoolean(returnsRS);
132     if (returnsRS)
133       sendResultSetParams(out);
134   }
135
136   /**
137    * Parse the query to know which table is affected. Also checks for the
138    * columns if the parsing granularity requires it.
139    *
140    * @see org.objectweb.cjdbc.common.sql.AbstractRequest#parse(org.objectweb.cjdbc.common.sql.schema.DatabaseSchema,
141    * int, boolean)
142    */

143   public void parse(DatabaseSchema schema, int granularity,
144       boolean isCaseSensitive) throws SQLException JavaDoc
145   {
146     if (granularity == ParsingGranularities.NO_PARSING)
147     {
148       isParsed = true;
149       return;
150     }
151
152     // Sanity check
153
if (schema == null)
154       throw new SQLException JavaDoc(
155           "Unable to parse request with an undefined database schema");
156
157     String JavaDoc originalSQL = this.trimCarriageReturnAndTabs();
158     String JavaDoc sql = originalSQL.toLowerCase();
159
160     // Strip 'insert into '
161
sql = sql.substring(7).trim().substring(5).trim();
162
163     // Look for the VALUES or SELECT clause
164
int endIdx = sql.indexOf(" values ");
165     if (endIdx == -1)
166     {
167       endIdx = sql.indexOf(" values(");
168       if (endIdx == -1)
169       {
170         endIdx = sql.indexOf("select ");
171         if (endIdx == -1)
172           throw new SQLException JavaDoc(
173               "Unable to find the VALUES or SELECT keyword in this INSERT statement: '"
174                   + sqlQuery + "'");
175       }
176     }
177
178     if (isCaseSensitive)
179     {
180       int shift = originalSQL.length() - sql.length();
181       sql = originalSQL.substring(shift, shift + endIdx).trim();
182     }
183     else
184       sql = sql.substring(0, endIdx).trim();
185
186     int openParenthesisIdx = sql.indexOf("(");
187
188     // Get the table on which INSERT occurs
189
String JavaDoc insertTable;
190     if (openParenthesisIdx == -1)
191       // Query like INSERT INTO table VALUES(...)
192
insertTable = sql;
193     else
194       // Query of the form INSERT INTO table(column1, ...) VALUES(...)
195
insertTable = sql.substring(0, openParenthesisIdx).trim();
196
197     DatabaseTable t = schema.getTable(insertTable, isCaseSensitive);
198     if (t == null)
199       throw new SQLException JavaDoc("Unknown table '" + insertTable
200           + "' in this INSERT statement: '" + sqlQuery + "'");
201     else
202       tableName = t.getName();
203
204     if ((granularity == ParsingGranularities.COLUMN)
205         || (granularity == ParsingGranularities.COLUMN_UNIQUE))
206     {
207       if (openParenthesisIdx != -1)
208       {
209         // Fetch the affected columns
210
int closingParenthesisIdx = sql.indexOf(")");
211         if ((closingParenthesisIdx == -1) || (closingParenthesisIdx > endIdx))
212         {
213           tableName = null;
214           columns = null;
215           throw new SQLException JavaDoc(
216               "Syntax error in columns definition for this INSERT statement: '"
217                   + sqlQuery + "'");
218         }
219
220         // Column names are separated by comas
221
StringTokenizer JavaDoc columnTokens = new StringTokenizer JavaDoc(sql.substring(
222             openParenthesisIdx + 1, closingParenthesisIdx), ",");
223         columns = new ArrayList JavaDoc();
224         DatabaseColumn col = null;
225         while (columnTokens.hasMoreTokens())
226         {
227           String JavaDoc token = columnTokens.nextToken().trim();
228           if ((col = t.getColumn(token)) == null)
229           {
230             tableName = null;
231             columns = null;
232             throw new SQLException JavaDoc("Unknown column name '" + token
233                 + "' in this INSERT statement: '" + sqlQuery + "'");
234           }
235           else
236           {
237             columns.add(new TableColumn(tableName, col.getName()));
238           }
239         }
240       }
241       else
242       {
243         // All columns are affected
244
columns = new ArrayList JavaDoc();
245         ArrayList JavaDoc cols = t.getColumns();
246         int size = cols.size();
247         for (int j = 0; j < size; j++)
248         {
249           columns.add(new TableColumn(tableName, ((DatabaseColumn) cols.get(j))
250               .getName()));
251         }
252       }
253     }
254
255     isParsed = true;
256   }
257
258   /**
259    * @see AbstractRequest#cloneParsing(AbstractRequest)
260    */

261   public void cloneParsing(AbstractRequest request)
262   {
263     if (!request.isParsed())
264       return;
265     cloneTableNameAndColumns((AbstractWriteRequest) request);
266     isParsed = true;
267   }
268
269   /**
270    * @see org.objectweb.cjdbc.common.sql.AbstractRequest#needsMacroProcessing()
271    */

272   public boolean needsMacroProcessing()
273   {
274     return true;
275   }
276
277   /**
278    * @see org.objectweb.cjdbc.common.sql.AbstractRequest#returnsResultSet()
279    */

280   public boolean returnsResultSet()
281   {
282     return returnsRS;
283   }
284
285   /**
286    * Displays some debugging information about this request.
287    */

288   public void debug()
289   {
290     super.debug();
291     if (tableName != null)
292       System.out.println("Inserted table: " + tableName);
293     else
294       System.out.println("No information about inserted table");
295
296     if (columns != null)
297     {
298       System.out.println("Inserted columns:");
299       for (int i = 0; i < columns.size(); i++)
300         System.out.println(" "
301             + ((TableColumn) columns.get(i)).getColumnName());
302     }
303     else
304       System.out.println("No information about inserted columns");
305
306     System.out.println("");
307   }
308
309 }
Popular Tags