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