001: /*
002: * sqlc 1
003: * SQL Compiler
004: * Copyright (C) 2003 Hammurapi Group
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.hammurapi.biz/products/sqlc/index.html
021: * e-Mail: support@hammurapi.biz
022: */
023: package biz.hammurapi.sqlc;
024:
025: import java.sql.SQLException;
026: import java.util.Collection;
027: import java.util.Iterator;
028:
029: import org.apache.bcel.Constants;
030: import org.apache.bcel.generic.ACONST_NULL;
031: import org.apache.bcel.generic.ALOAD;
032: import org.apache.bcel.generic.BranchInstruction;
033: import org.apache.bcel.generic.DUP;
034: import org.apache.bcel.generic.IFEQ;
035: import org.apache.bcel.generic.IRETURN;
036: import org.apache.bcel.generic.InstructionHandle;
037: import org.apache.bcel.generic.InstructionList;
038: import org.apache.bcel.generic.LDC;
039: import org.apache.bcel.generic.ReferenceType;
040:
041: import biz.hammurapi.codegen.Class;
042: import biz.hammurapi.codegen.ClassGeneratorBase;
043: import biz.hammurapi.codegen.GenerationException;
044: import biz.hammurapi.codegen.MethodPrototype;
045: import biz.hammurapi.sql.DatabaseObject;
046: import biz.hammurapi.sql.Parameterizer;
047: import biz.hammurapi.sql.SQLProcessor;
048: import biz.hammurapi.sql.metadata.ColumnDescriptor;
049: import biz.hammurapi.sql.metadata.ParameterDescriptor;
050:
051: /**
052: * Executes update using parameter object instead of individual parameters.
053: * @author Pavel Vlasov
054: * @version $Revision: 1.5 $
055: */
056: public class NamedParameterObjectUpdate extends
057: NamedInterfaceGeneratingStatement {
058:
059: private String tableName;
060:
061: /**
062: * @return
063: */
064: protected boolean isToBeGenerated() {
065: Iterator it = parameterDescriptors.iterator();
066: int count = 0;
067: while (it.hasNext()) {
068: Object o = it.next();
069: if (!(o instanceof ColumnDescriptor && isSkipColumn((ColumnDescriptor) o))) {
070: count++;
071: }
072: }
073: return count > 1;
074: }
075:
076: /**
077: * @param name
078: * @param description
079: * @param sql
080: * @param parameterDescriptors
081: * @param parameterDescriptors2 TODO
082: */
083: public NamedParameterObjectUpdate(String name, String description,
084: String sql, Collection parameterDescriptors,
085: Collection parameterDescriptors2, boolean generateMutators) {
086: super (name, description, sql, parameterDescriptors,
087: parameterDescriptors2, generateMutators);
088: }
089:
090: protected void generateEngineMethods(String packageName, Class c)
091: throws GenerationException {
092: MethodPrototype mp = new MethodPrototype(
093: c,
094: getEngineMethodsVisibility()
095: + " int "
096: + (Character.toLowerCase(name.charAt(0)) + (name
097: .length() == 1 ? "" : name.substring(1)))
098: + "(" + getInterfaceName(packageName)
099: + " rowInterface) throws "
100: + SQLException.class.getName(), null);
101: InstructionList il = new InstructionList();
102:
103: BranchInstruction bi = null;
104:
105: if (getMode() == MODE_INSERT || getMode() == MODE_UPDATE) {
106: //* 0 0:aload_1
107: il.append(new ALOAD(1));
108: //* 1 1:instanceof #4 <Class DatabaseObject>
109: ReferenceType referenceType = (ReferenceType) ClassGeneratorBase
110: .java2BcelType(DatabaseObject.class.getName());
111: il.append(c.getInstructionFactory().createInstanceOf(
112: referenceType));
113: //* 2 4:ifeq 21
114: bi = new IFEQ(null);
115: il.append(bi);
116:
117: // 3 7:aload_1
118: il.append(new ALOAD(1));
119: // 4 8:checkcast #4 <Class DatabaseObject>
120: il.append(c.getInstructionFactory().createCheckCast(
121: referenceType));
122: // 4 8:aload_0
123: il.append(new ALOAD(0));
124: // 5 9:getfield #107 <Field SQLProcessor _processor>
125: il.append(c.createGetField("_processor"));
126: // 6 12:ldc1 #109 <String "TEST_TABLE">
127: il.append(new LDC(c.getClassGen().getConstantPool()
128: .addString(tableName)));
129: // 7 14:invokevirtual #112 <Method int DatabaseObject.update(SQLProcessor, String)>
130: il.append(c.createInvoke(DatabaseObject.class.getName(),
131: "int "
132: + (getMode() == MODE_INSERT ? "insert"
133: : "update") + "("
134: + SQLProcessor.class.getName()
135: + ",java.lang.String)", null,
136: Constants.INVOKEVIRTUAL));
137:
138: il.append(new IRETURN());
139: }
140:
141: // 0: aload_0
142: InstructionHandle handle = il.append(new ALOAD(0));
143: if (bi != null) {
144: bi.setTarget(handle);
145: }
146: // 1: getfield org.jincarnate.util.SampleClass.processor Lcom/pavelvlasov/sql/SQLProcessor; (52)
147: il.append(c.createGetField("_processor"));
148: // 4: ldc "ABC" (61)
149: il.append(new LDC(c.getClassGen().getConstantPool().addString(
150: getSql())));
151: if (parameterDescriptors.isEmpty()) {
152: il.append(new ACONST_NULL());
153: } else {
154: // 6: new <org.jincarnate.util.SampleClass$PackageQueryParameterizer> (63)
155: String parameterizerClass = generateParameterizerName(c
156: .getClassGen().getClassName());
157: il.append(c.getInstructionFactory().createNew(
158: parameterizerClass));
159: // 9: dup
160: il.append(new DUP());
161: // 5 10:aload_1
162: // 6 11:invokeinterface #32 <Method String CacheEntry.getEntryKey()>
163: // 7 16:aload_1
164: // 8 17:invokeinterface #35 <Method String CacheEntry.getValueFile()>
165: // 9 22:aload_1
166: // 10 23:invokeinterface #39 <Method long CacheEntry.getEntryExpires()>
167: // 11 28:aload_1
168: // 12 29:invokeinterface #42 <Method long CacheEntry.getLastAccess()>
169: Iterator it = parameterDescriptors.iterator();
170: for (int k = 0; it.hasNext(); k++) {
171: il.append(new ALOAD(1));
172: ColumnDescriptor parameter = (ColumnDescriptor) it
173: .next();
174: final String javaType = getColumnType(parameter,
175: parameter.isNullable() ? parameter.getType()
176: : ParameterDescriptor
177: .toPrimitive(parameter
178: .getType()));
179: if (javaType != null) {
180: il.append(c.createInvoke(
181: getInterfaceName(packageName), javaType
182: + " get" + parameter.getName()
183: + "()", null,
184: Constants.INVOKEINTERFACE));
185: }
186: }
187: // 13: invokespecial org.jincarnate.util.SampleClass$PackageQueryParameterizer.<init> (Ljava/lang/String;SI)V (66)
188: il.append(c.createInvoke(parameterizerClass,
189: "void <init>()", parameterDescriptors,
190: Constants.INVOKESPECIAL));
191: }
192: // 16: invokevirtual biz.hammurapi.sql.SQLProcessor.processUpdate (Ljava/lang/String;Lcom/pavelvlasov/sql/Parameterizer;)I (72)
193: il.append(c.createInvoke(SQLProcessor.class.getName(),
194: "int processUpdate(java.lang.String, "
195: + Parameterizer.class.getName() + ")", null,
196: Constants.INVOKEVIRTUAL));
197: // 19: ireturn
198: il.append(new IRETURN());
199:
200: mp.addMethod(il, null,
201: "Executes update and returns number of affected rows. "
202: + getDescription());
203: }
204:
205: protected Collection getInterfaceProperties() {
206: return parameterDescriptors;
207: }
208:
209: /**
210: * @return Returns the tableName.
211: */
212: public String getTableName() {
213: return tableName;
214: }
215:
216: /**
217: * @param tableName The tableName to set.
218: */
219: public void setTableName(String tableName) {
220: this.tableName = tableName;
221: }
222: }
|