1   package net.sourceforge.backpedal.impl.core;
2   
3   import net.sourceforge.backpedal.api.core.BackpedalStatementEssentials;
4   import net.sourceforge.backpedal.api.core.ParsedStatement;
5   import net.sourceforge.backpedal.api.db.BindVariable;
6   import net.sourceforge.backpedal.api.db.BindVariableSet;
7   import net.sourceforge.backpedal.impl.AbstractComponent;
8   import org.apache.commons.lang.builder.ToStringBuilder;
9   
10  import java.sql.Connection;
11  import java.sql.PreparedStatement;
12  import java.sql.SQLException;
13  import java.util.Collection;
14  import java.util.Iterator;
15  
16  public class PreparedStatementEssentials extends AbstractComponent implements BackpedalStatementEssentials {
17      private final ParsedStatement forwardPedalSql;
18      private final Collection backpedalBindVariableSets;
19  
20      PreparedStatementEssentials(final ParsedStatement forwardPedalSql, final Collection backpedalBindVariableSets) {
21          this.backpedalBindVariableSets = backpedalBindVariableSets;
22          this.forwardPedalSql = forwardPedalSql;
23      }
24  
25      public void backpedal(Connection connection) throws SQLException {
26          for(Iterator i=backpedalBindVariableSets.iterator();i.hasNext();) {
27              final BindVariableSet bindVariableSet = (BindVariableSet) i.next();
28              final String backpedalSql = computeBackpedalSql(bindVariableSet);
29              final PreparedStatement preparedStatement = connection.prepareStatement(backpedalSql);
30  
31              backpedal(preparedStatement,bindVariableSet);
32              preparedStatement.close();
33          }
34      }
35  
36      private String computeBackpedalSql(BindVariableSet set) {
37          final String result;
38          final String forwardPedalKeyword = forwardPedalSql.getSqlKeyword();
39          if ( BackpedalStatementEssentials.INSERT.equals(forwardPedalKeyword)) {
40              result = computeBackpedalDeleteSql(set);
41          } else if ( BackpedalStatementEssentials.DELETE.equals(forwardPedalKeyword)) {
42              result = computeBackpedalInsertSql(set);
43          } else if ( BackpedalStatementEssentials.UPDATE.equals(forwardPedalKeyword)) {
44              result = computeBackpedalUpdateSql(set);
45          } else {
46              throw new IllegalStateException("Got a SQL keyword that I do not understand: " + forwardPedalKeyword);
47          }
48          return result;
49      }
50  
51      private String computeBackpedalUpdateSql(BindVariableSet set) {
52          final StringBuffer buffer = new StringBuffer("UPDATE ");
53          buffer.append(forwardPedalSql.getTableName());
54          buffer.append(" SET ");
55          final Iterator bindVariableIterator = set.iterator();
56          final String [] changedColumnNames = forwardPedalSql.getChangedColumnNames();
57          for(int i=0;i<changedColumnNames.length;i++) {
58              if ( i > 0 ) {
59                  buffer.append(",");
60              }
61              appendColumnClauses(buffer,changedColumnNames,bindVariableIterator,",");
62          }
63          if ( forwardPedalSql.getWhereColumnNames().length > 0 ) {
64              buffer.append(" WHERE ");
65              appendColumnClauses(buffer,forwardPedalSql.getWhereColumnNames(),bindVariableIterator," AND ");
66          }
67          return buffer.toString();
68      }
69  
70      private String computeBackpedalDeleteSql(BindVariableSet set) {
71          final StringBuffer buffer = new StringBuffer("DELETE FROM ");
72          buffer.append(forwardPedalSql.getTableName()).append(" ");
73          if ( forwardPedalSql.getChangedColumnNames().length > 0 ) {
74              buffer.append("WHERE ");
75              appendColumnClauses(buffer,forwardPedalSql.getChangedColumnNames(),set.iterator()," AND ");
76          }
77          return buffer.toString();
78      }
79  
80      private void appendColumnClauses(StringBuffer buffer, String [] columnNames, Iterator bindVariableIterator, String conjunction) {
81          for(int i=0;i<columnNames.length;i++) {
82              final BindVariable bindVariable = (BindVariable) bindVariableIterator.next();
83              if ( i > 0 ) {
84                  buffer.append(conjunction);
85              }
86              buffer.append(columnNames[i]);
87              if ( bindVariable.isNull()) {
88                  buffer.append(" IS NULL");
89              } else {
90                  buffer.append(" = ?");
91              }
92          }
93      }
94  
95      private String computeBackpedalInsertSql(final BindVariableSet set) {
96          final StringBuffer buffer = new StringBuffer("INSERT INTO ");
97          buffer.append(forwardPedalSql.getTableName());
98          buffer.append(" (");
99          iterateBindVariables(buffer,set,new IterateHookPoint(){
100             public String getConjunction() {
101                 return ",";
102             }
103         });
104         buffer.append(") VALUES(");
105         iterateBindVariables(buffer,set,new IterateHookPoint() {
106             public String filterColumnName(String columnName) {
107                 return "?";
108             }
109 
110             public String getConjunction() {
111                 return ",";
112             }
113         });
114         buffer.append(")");
115         return buffer.toString();
116     }
117 
118     private void iterateBindVariables(StringBuffer buffer,BindVariableSet bindVariableSet, IterateHookPoint iterateHookPoint) {
119         int index = 0;
120         for(Iterator i=bindVariableSet.iterator();i.hasNext();) {
121             final BindVariable bindVariable = (BindVariable) i.next();
122             if ( index > 0) {
123                 buffer.append(iterateHookPoint.getConjunction());
124             }
125             buffer.append(iterateHookPoint.filterColumnName(bindVariable.getColumnName()));
126             final String appendString = iterateHookPoint.getBindVariableAppendString();
127             buffer.append(appendString == null ? "" : appendString);
128             index++;
129         }
130     }
131 
132     private static abstract class IterateHookPoint {
133         public String filterColumnName(final String columnName) {
134             return columnName;
135         }
136 
137         public String getBindVariableAppendString() {
138             return null;
139         }
140 
141         public String getConjunction() {
142             return "";
143         }
144     }
145 
146     private void backpedal(PreparedStatement preparedStatement, BindVariableSet bindVariableSet) throws SQLException {
147         int index = 1;
148         for(Iterator i=bindVariableSet.iterator();i.hasNext();) {
149             final BindVariable bindVariable = (BindVariable)i.next();
150             if ( ! bindVariable.isNull() || BackpedalStatementEssentials.DELETE.equals(forwardPedalSql.getSqlKeyword())) {
151                 bindVariable.setInto(index++, preparedStatement);
152             }
153         }
154         preparedStatement.executeUpdate();
155     }
156 
157     public String toString() {
158         return new ToStringBuilder(this).
159                 append("forwardPedalSql",forwardPedalSql).
160                 append("backpedalBindVariableSets",backpedalBindVariableSets).
161                 toString();
162     }
163 
164 }
This page was automatically generated by Maven