View Javadoc
1   // wurblet generated by Wurbelizer 25.7.0.0, see https://wurbelizer.org
2   
3   package org.tentackle.persist.wurblet;
4   
5   import org.tentackle.wurblet.*;
6   import org.tentackle.buildsupport.*;
7   import java.util.*;
8   import java.io.*;
9   import org.tentackle.common.*;
10  import org.wurbelizer.wurbel.*;
11  import org.tentackle.sql.*;
12  import org.tentackle.model.*;
13  import org.wurbelizer.wurblet.*;
14  
15  /**
16   * <strong>({@code @wurblet})</strong> Generate code to delete low-level persistent objects.
17   * <p>
18   * usage:<br>
19   * &#064;wurblet &lt;tag&gt; DbDeleteBy [--private] [--append=&lt;sqltext&gt;] [--classvar=&lt;classvariables&gt;] &lt;expression&gt;
20   * <p>
21   * arguments:
22   * <ul>
23   * <li><em>--private:</em> makes the method private (default is public).</li>
24   * <li><em>--append=&lt;sqltext&gt;:</em> appends an sql-string.</li>
25   * <li><em>--classvar=&lt;classvariables&gt;:</em> reference to classvariables, if pick the statement-IDs from there.</li>
26   * <li><em>&lt;expression&gt;:</em> see {@link WurbletArgumentParser}.</li>
27   * </ul>
28   * For more options, see {@link DbModelWurblet}.
29   */
30  public class DbDeleteBy extends DbModelWurblet {
31  
32    @Override
33    public void run() throws WurbelException {
34      super.run();
35      try {
36        wurbel();
37      }
38      catch (Throwable t) {
39        if (t instanceof WurbelException) {
40          throw (WurbelException) t;
41        }
42        throw new WurbelException("wurblet " + this + " failed", t);
43      }
44    }
45  
46    // ----------------- begin wurblet code -----------------
47  
48    private void wurbel() throws WurbelException, ModelException {
49  
50      assertNoOptionalArguments();    // the prepared statement is cached, i.e. the SQL text must be fixed
51  
52      String className = getClassName();
53      String methodName = getMethodName();
54  
55      String  classVar    = null;
56      String  append      = null;
57      String  scope       = "public";
58  
59      for (String arg: getOptionArgs())  {
60        if (arg.equals("private")) {
61          scope = "private";
62          setRemote(false);
63        }
64        else if (arg.startsWith("append=")) {
65          append = arg.substring(7);
66        }
67        else if (arg.startsWith("classvar="))  {
68          classVar = arg.substring(9);
69        }
70      }
71  
72      if (classVar == null) {
73        classVar = "";
74      }
75      else  {
76        classVar += ".";    // add dot to access class var
77      }
78  
79      String params = buildMethodParameters();
80      String iparms = buildInvocationParameters();
81      String statementId = createStatementId();
82  
83      out.print(source[0]); // 53:2 = "  "
84      out.print(scope);
85      out.print(source[1]); // 54:11 = " int "
86      out.print(methodName);
87      out.print(source[2]); // 54:30 = "("
88      out.print(params);
89      out.print(source[3]); // 54:41 = ") {"
90      if (isRemote()) {
91        // create includes
92        RemoteIncludes genInc = new RemoteIncludes(this);
93        PrintStream implOut   = genInc.getImplementationStream();
94        PrintStream remoteOut = genInc.getInterfaceStream();
95        out.print(source[4]); // 61:2 = "    if (getSession().isRemote())  {"
96        remoteOut.print(source[5]); // 63:16 = "  int "
97        remoteOut.print(methodName);
98        remoteOut.print(source[6]); // 64:20 = "("
99        remoteOut.print(params);
100       remoteOut.print(source[7]); // 64:31 = ");"
101       implOut.print(source[8]); // 65:14 = "  @Override  public int "
102       implOut.print(methodName);
103       implOut.print(source[9]); // 68:27 = "("
104       implOut.print(params);
105       implOut.print(source[10]); // 68:38 = ") {"
106       implOut.print(source[11]); // 69:14 = "    return dbObject."
107       implOut.print(methodName);
108       implOut.print(source[12]); // 70:34 = "("
109       implOut.print(iparms);
110       implOut.print(source[13]); // 70:45 = ");  }"
111       out.print(source[14]); // 72:6 = "      return getRemoteDelegate()."
112       out.print(methodName);
113       out.print(source[15]); // 73:47 = "("
114       out.print(iparms);
115       out.print(source[16]); // 73:58 = ");    }    // else: local mode"
116     } // end if remote
117      out.print(source[17]); // 78:2 = "    PreparedStatementWrapper st = getPre..."
118      out.print(classVar);
119      out.print(statementId);
120      out.print(source[18]); // 79:82 = ",      b -> {        StringBuilder sql..."
121     if (getEntity().getSuperEntity() != null && getEntity().getHierarchyInheritanceType() == InheritanceType.SINGLE) {
122       out.print(source[19]); // genwhere.incl:3:2 = "        sql.append(getSqlClassIdConditio..."
123     }
124 
125     boolean andPrepended = false;
126     if (getContextAttribute() != null) {
127         andPrepended = true;
128         out.print(source[20]); // genwhere.incl:11:2 = "        sql.append(Backend.SQL_AND)    ..."
129         out.print(getColumnNameConstant(getContextAttribute(), 0));
130         out.print(source[21]); // genwhere.incl:13:70 = ")           .append(Backend.SQL_EQUAL_P..."
131     }
132 
133     boolean needParentheses = false;
134 
135     if (!getExpressionArguments().isEmpty()) {
136       needParentheses = getExpression().needParenthesesAfterAndOperator();
137       if (andPrepended || needParentheses) {
138         out.print(source[22]); // genwhere.incl:23:2 = "        sql.append(Backend.SQL_AND).appe..."
139       }
140       else {
141         out.print(source[23]); // genwhere.incl:28:2 = "        sql.append(Backend.SQL_AND);"
142         if (needParentheses && getEntity().getHierarchyInheritanceType() == InheritanceType.SINGLE) {
143           out.print(source[24]); // genwhere.incl:32:2 = "        if (classIdRequired) {         ..."
144         }
145       }
146 
147       // generate the where expressions
148       String code = getExpression().toCode(new WhereClauseGenerator(this));
149       out.print(StringHelper.trimRight(code, '\n'));
150       out.print(source[25]); // genwhere.incl:43:38 = ""
151 
152       if (andPrepended || needParentheses) {
153         out.print(source[26]); // genwhere.incl:47:2 = "        sql.append(Backend.SQL_RIGHT_PAR..."
154       }
155       else if (needParentheses && getEntity().getHierarchyInheritanceType() == InheritanceType.SINGLE) {
156         out.print(source[27]); // genwhere.incl:52:2 = "        if (classIdRequired) {         ..."
157       }
158 
159       if (isWithOptionalArguments()) {
160         // skipped conditions may leave empty sub-expressions and dangling operators behind.
161         // must be applied before any trailing clause is appended.
162         out.print(source[28]); // genwhere.incl:62:2 = "        b.reduceSql(sql);"
163       }
164     }
165 
166     String orderByStr = createOrderBy();
167     if (orderByStr != null) {
168       out.print(source[29]); // genwhere.incl:70:2 = "        sql.append(Backend.SQL_ORDERBY)..."
169       out.print(orderByStr);
170       out.print(source[30]); // genwhere.incl:72:25 = ";"
171     }
172     if (append != null) {
173       out.print(source[31]); // 85:2 = "        sql.append("
174       out.print(append);
175       out.print(source[32]); // 86:29 = ");"
176     }
177     out.print(source[33]); // 89:2 = "        return sql.toString();      } ..."
178     if (isWithJoins()) {
179       out.print(createJoinSetPars());
180     }
181 
182     if (getContextAttribute() != null) {
183       out.print(source[34]); // gensetpar.incl:7:2 = "    st."
184       out.print(createJdbcSetterName(getContextAttribute().getDataType()));
185       out.print(source[35]); // gensetpar.incl:8:68 = "(ndx++, "
186       out.print(getContextAttribute().getName());
187       out.print(source[36]); // gensetpar.incl:8:111 = ");"
188     }
189     for (WurbletArgument par: getMethodArguments())  {
190       // the values of the EXISTS clause are set only if the clause is part of the query
191       String clauseCondition = par.getExistsArguments() == null ? null :
192                                  createOptionalCondition(par.getExistsArguments());
193       String indent = clauseCondition == null ? "" : "  ";
194       if (par.isPath()) {
195         // check for additional value-args in relations
196         Set<Relation> existsRels = par.getExistsRelations();
197         boolean withValueArgs = false;
198         if (existsRels != null) {
199           for (Relation rel: existsRels) {
200             List<MethodArgument> methodArgs = rel.getMethodArgs();
201             for (MethodArgument methodArg: methodArgs.subList(1, methodArgs.size())) {
202               if (methodArg.isValue()) {
203                 withValueArgs = true;
204               }
205             }
206           }
207         }
208         if (withValueArgs) {
209           if (clauseCondition != null) {
210             out.print(source[37]); // gensetpar.incl:32:2 = "    if ("
211             out.print(clauseCondition);
212             out.print(source[38]); // gensetpar.incl:33:27 = ") {"
213           }
214           for (Relation rel: existsRels) {
215             List<MethodArgument> methodArgs = rel.getMethodArgs();
216             for (MethodArgument methodArg: methodArgs.subList(1, methodArgs.size())) {
217               if (methodArg.isValue()) {
218                 Attribute attr = methodArg.getForeignAttribute();
219                 out.print(source[39]); // gensetpar.incl:41:2 = "    "
220                 out.print(indent);
221                 out.print(createWhereSetPars(attr, attr.toMethodArgument(methodArg.getValue())));
222                 out.print(source[40]); // gensetpar.incl:42:87 = ";"
223               }
224             }
225           }
226           if (clauseCondition != null) {
227             out.print(source[41]); // gensetpar.incl:48:2 = "    }"
228           }
229         }
230       }
231 
232       if (!par.isValueLiterally()) {
233         // the parameters of an optional condition are set only if the condition is part of the query
234         String optCondition = par.isOptional() ? par.getOptionalName() : null;
235         indent = optCondition == null ? "" : "  ";
236         if (optCondition != null) {
237           out.print(source[42]); // gensetpar.incl:60:2 = "    if ("
238           out.print(optCondition);
239           out.print(source[43]); // gensetpar.incl:61:24 = ") {"
240         }
241         out.print(source[44]); // gensetpar.incl:64:2 = "    "
242         out.print(indent);
243         out.print(createWhereSetPars(par));
244         out.print(source[45]); // gensetpar.incl:65:41 = ";"
245         if (optCondition != null) {
246           out.print(source[46]); // gensetpar.incl:68:2 = "    }"
247         }
248       }
249     }
250     out.print(source[47]); // 94:38 = "    return st.executeUpdate();  }"
251     if (classVar.isEmpty()) {
252       out.print(source[48]); // 99:2 = "  private static final StatementId "
253       out.print(statementId);
254       out.print(source[49]); // 101:50 = " = new StatementId();"
255     }
256   }
257 
258   // ----------------- end wurblet code -----------------
259 
260   @Override
261   public String process(String code) {
262     if (isWithOptionalArguments()) {
263       // the last set parameter may be skipped at runtime: keep all increments
264       return code;
265     }
266     int ref = code.lastIndexOf("ndx");
267     int pos = code.lastIndexOf("(ndx++,");
268     if (pos >= 0 && ref == pos + 1) {
269       // remove unnecessary last ++
270       code = code.substring(0, pos + 4) + code.substring(pos + 6);
271     }
272     else {
273       // remove unnecessary last ndx +=
274       pos = code.lastIndexOf("ndx += st.set(");   // ndx += st.set(DT_POSITION3D, ndx, dropPosition, false, null);
275       if (pos >= 0 && ref > pos) {
276         code = code.substring(0, pos) + code.substring(pos + 7);
277       }
278       else {
279         pos = code.lastIndexOf(", ndx++, ");   // st.set(SqlType....., ndx++, value.get...)
280         if (pos >= 0 && ref > pos) {
281           code = code.substring(0, pos + 5) + code.substring(pos + 7);
282         }
283       }
284     }
285     return code;
286   }
287 }