KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > sql > StmtInsert


1 package com.quadcap.sql;
2
3 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.util.Vector JavaDoc;
42
43 import java.io.IOException JavaDoc;
44
45 import java.sql.SQLException JavaDoc;
46
47 import com.quadcap.sql.types.Value;
48 import com.quadcap.sql.types.ValueDefault;
49 import com.quadcap.sql.types.ValueNull;
50
51
52 /**
53  * Implementation of the SQL <b>INSERT</b> statement.
54  *
55  * @author Stan Bailes
56  */

57
58 public class StmtInsert implements Stmt {
59     String JavaDoc tableName;
60     Vector JavaDoc columns;
61     Expression values;
62
63     boolean defaultValues = false;
64     VectorExpression ve = null;
65     Row tempRow = null;
66
67     Relation table = null;
68
69     public StmtInsert() {}
70     
71     public StmtInsert(String JavaDoc tableName) {
72     this.tableName = tableName;
73     }
74
75     public void setDefaultValue() {
76     this.defaultValues = true;
77     }
78
79     public void setColumns(Vector JavaDoc v) {
80     this.columns = v;
81     }
82
83     public void setValues(Expression e) {
84     this.values = e;
85     }
86
87     final Value getDefault(Session session, Cursor cursor, Column c)
88     throws SQLException JavaDoc
89     {
90     Value dflt = ValueNull.valueNull;
91     Expression e = c.getDefault();
92     if (e != null) {
93         dflt = e.getValue(session, cursor);
94     }
95     return dflt;
96     }
97
98     public void setVrow(Session session, VectorExpression ve)
99         throws IOException JavaDoc, SQLException JavaDoc
100     {
101         if (ve.size() != tempRow.size()) {
102             throw new SQLException JavaDoc("Incorrect number of columns: " +
103                                    ve.size() +
104                                    "; expecting " +
105                                    tempRow.size());
106         }
107         for (int col = 1; col <= tempRow.size(); col++) {
108             Value v = ve.get(col-1).getValue(session, null);
109             if (v instanceof ValueDefault) {
110                 Column c = table.getColumn(col);
111                 v = getDefault(session, null, c);
112             }
113             tempRow.set(col, v);
114         }
115         table.insertRow(session, tempRow);
116     }
117
118     public void execute(Session session) throws IOException JavaDoc, SQLException JavaDoc {
119         Database db = session.getDatabase();
120         if (table == null) {
121             table = db.getRelation(tableName);
122             if (table == null) {
123                 throw new SQLException JavaDoc("No table: " + tableName, "42000");
124             }
125         }
126         if (columns == null) {
127             if (ve != null || values instanceof VectorExpression) {
128                 // we can do something optimal here....
129
if (ve == null) ve = (VectorExpression)values;
130                 if (tempRow == null) tempRow = new Row(table.getColumnCount());
131                 if (ve.rank() == 1) {
132                     setVrow(session, ve);
133                     return;
134                 } else if (ve.rank() == 2) {
135                     for (int row = 0; row < ve.size(); row++) {
136                         VectorExpression vr = (VectorExpression)ve.get(row);
137                         setVrow(session, vr);
138                     }
139                     return;
140                 }
141             }
142         }
143
144         // less-than-optimal but full-featured insert implementation
145
Cursor cursor = null;
146         if (values != null) {
147             cursor = values.getCursor(session, null);
148         }
149
150         if (isSelfInsert()) {
151             DistinctCursor dc = new DistinctCursor(session, cursor);
152             dc.setDistinct(false);
153             cursor = dc;
154         }
155         try {
156             if (defaultValues) {
157                 if (tempRow == null) tempRow = new Row(table.getColumnCount());
158                 for (int col = 1; col <= tempRow.size(); col++) {
159                     Column c = table.getColumn(col);
160                     Value dflt = getDefault(session, cursor, c);
161                     tempRow.set(col, dflt);
162                 }
163                 table.insertRow(session, tempRow);
164             } else if (columns == null) {
165                 if (cursor.getColumnCount() != table.getColumnCount()) {
166                     throw new SQLException JavaDoc("Incorrect number of columns: " +
167                                            cursor.getColumnCount() +
168                                            "; expecting " +
169                                            table.getColumnCount());
170                 }
171                 if (cursor instanceof StaticCursor) {
172                     // XXX is this right? Can defaults show up in other
173
// XXX cursor types?
174
while (cursor.next()) {
175                         Row r = cursor.getRow();
176                         for (int i = 1; i <= r.size(); i++) {
177                             Value v = r.item(i);
178                             if (v instanceof ValueDefault) {
179                                 Column c = table.getColumn(i);
180                                 v = getDefault(session, cursor, c);
181                                 r.set(i, v);
182                             }
183                         }
184                         table.insertRow(session, r);
185                     }
186                 } else if (table.hasBlobs()) {
187                     // We may have to passivate the blobs, but it's possible
188
// that the rows that we get back aren't updateable
189
// (e.g., insert into TAB select from TAB2, TAB3)
190
if (tempRow == null) {
191                         tempRow = new Row(table.getColumnCount());
192                     }
193                     while (cursor.next()) {
194                         Row r = cursor.getRow();
195                         for (int i = 1; i <= table.getColumnCount(); i++) {
196                             tempRow.set(i, r.item(i));
197                         }
198                         table.insertRow(session, tempRow);
199                     }
200                 } else {
201                     while (cursor.next()) {
202                         Row r = cursor.getRow();
203                         table.insertRow(session, r);
204                     }
205                 }
206             } else {
207                 if (tempRow == null) {
208                     tempRow = new Row(table.getColumnCount());
209                 }
210                 int[] map = table.mapColumns(columns);
211                 int[] nmap = null;
212                 // make a map to quickly find columns that need defaults
213
if (map.length < table.getColumnCount()) {
214                     int[] cmap = new int[table.getColumnCount()];
215                     for (int i = 0; i < map.length; i++) {
216                         cmap[map[i]-1] = 1;
217                     }
218                     nmap = new int[cmap.length - map.length];
219                     int ncnt = 0;
220                     for (int i = 0; i < cmap.length; i++) {
221                         if (cmap[i] == 0) {
222                             nmap[ncnt++] = i+1;
223                         }
224                     }
225                 }
226                 while (cursor.next()) {
227                     Row row = cursor.getRow();
228                     for (int i = 0; i < map.length; i++) {
229                         Value v = row.item(i+1);
230                         if (v instanceof ValueDefault) {
231                             Column c = table.getColumn(map[i]);
232                             v = getDefault(session, cursor, c);
233                         }
234                         tempRow.set(map[i], v);
235                     }
236                     if (nmap != null) {
237                         // fill in null/default values
238
for (int i = 0; i < nmap.length; i++) {
239                             int col = nmap[i];
240                             Column c = table.getColumn(col);
241                             Value dflt = getDefault(session, cursor, c);
242                             tempRow.set(col, dflt);
243                         }
244                     }
245                     table.insertRow(session, tempRow);
246                 }
247             }
248         } finally {
249             if (cursor != null) cursor.close();
250         }
251     }
252
253     class IsSelfInsert implements ExpressionVisitor {
254         boolean isit = false;
255
256         public void visit(Expression sub) {
257             if (!isit) {
258                 if (sub instanceof SelectExpression) {
259                     Vector JavaDoc v = new Vector JavaDoc();
260                     SelectExpression se = (SelectExpression)sub;
261                     se.getBaseTables(v);
262                     for (int i = 0; !isit && i < v.size(); i++) {
263                         String JavaDoc name = v.get(i).toString();
264                         isit = name.equalsIgnoreCase(tableName);
265                     }
266                 } else {
267                     sub.visitSubExpressions(this);
268                 }
269             }
270         }
271     }
272
273     boolean isSelfInsert() {
274         boolean ret = false;
275         if (values != null) {
276             IsSelfInsert is = new IsSelfInsert();
277             is.visit(values);
278             ret = is.isit;
279         }
280         return ret;
281     }
282 }
283
284
Popular Tags