15 * You should have received a copy of the GNU General Public License |
15 * You should have received a copy of the GNU General Public License |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 */ |
17 */ |
18 package info.globalcode.sql.dk; |
18 package info.globalcode.sql.dk; |
19 |
19 |
20 import static info.globalcode.sql.dk.Functions.notNull; |
|
21 import static info.globalcode.sql.dk.Functions.findByName; |
20 import static info.globalcode.sql.dk.Functions.findByName; |
22 import java.sql.Connection; |
21 import java.sql.Connection; |
23 import java.sql.PreparedStatement; |
22 import java.sql.PreparedStatement; |
24 import java.sql.SQLException; |
23 import java.sql.SQLException; |
25 import java.util.ArrayList; |
24 import java.util.ArrayList; |
41 private String nameSuffix; |
40 private String nameSuffix; |
42 private List<NamedParameter> parameters; |
41 private List<NamedParameter> parameters; |
43 private List<NamedParameter> parametersUsed = new ArrayList<>(); |
42 private List<NamedParameter> parametersUsed = new ArrayList<>(); |
44 private StringBuilder updatedQuery; |
43 private StringBuilder updatedQuery; |
45 private Pattern pattern; |
44 private Pattern pattern; |
|
45 private SQLCommandNumbered numbered; |
46 |
46 |
47 public SQLCommandNamed(String query, List<NamedParameter> parameters, String namePrefix, String nameSuffix) { |
47 public SQLCommandNamed(String query, List<NamedParameter> parameters, String namePrefix, String nameSuffix) { |
48 super(query); |
48 super(query); |
49 this.updatedQuery = new StringBuilder(query.length()); |
49 this.updatedQuery = new StringBuilder(query.length()); |
50 this.parameters = parameters; |
50 this.parameters = parameters; |
52 this.nameSuffix = nameSuffix; |
52 this.nameSuffix = nameSuffix; |
53 } |
53 } |
54 |
54 |
55 @Override |
55 @Override |
56 public PreparedStatement prepareStatement(Connection c) throws SQLException { |
56 public PreparedStatement prepareStatement(Connection c) throws SQLException { |
|
57 return getSQLCommandNumbered().prepareStatement(c); |
|
58 } |
|
59 |
|
60 @Override |
|
61 public void parametrize(PreparedStatement ps) throws SQLException { |
|
62 getSQLCommandNumbered().parametrize(ps); |
|
63 } |
|
64 |
|
65 private void prepare() throws SQLException { |
57 try { |
66 try { |
58 buildPattern(); |
67 buildPattern(); |
59 placeParametersAndUpdateQuery(); |
68 placeParametersAndUpdateQuery(); |
60 logPossiblyMissingParameters(); |
69 logPossiblyMissingParameters(); |
61 } catch (PatternSyntaxException e) { |
70 } catch (PatternSyntaxException e) { |
62 throw new SQLException("Name prefix „" + namePrefix + "“ or suffix „" + nameSuffix + "“ contain a wrong regular expression. " + e.getLocalizedMessage(), e); |
71 throw new SQLException("Name prefix „" + namePrefix + "“ or suffix „" + nameSuffix + "“ contain a wrong regular expression. " + e.getLocalizedMessage(), e); |
63 } |
72 } |
64 return c.prepareStatement(updatedQuery.toString()); |
|
65 } |
73 } |
66 |
74 |
67 @Override |
75 /** |
68 public void parametrize(PreparedStatement ps) throws SQLException { |
76 * @return SQL command with named parameters converted to SQL command with numbered parameters |
69 int i = 1; |
77 */ |
70 for (Parameter p : notNull(parametersUsed)) { |
78 public SQLCommandNumbered getSQLCommandNumbered() throws SQLException { |
71 ps.setObject(i++, p.getValue(), p.getType().getCode()); |
79 if (numbered == null) { |
|
80 prepare(); |
|
81 numbered = new SQLCommandNumbered(updatedQuery.toString(), parametersUsed); |
72 } |
82 } |
|
83 |
|
84 return numbered; |
73 } |
85 } |
74 |
86 |
75 /** |
87 /** |
76 * Builds a regexp pattern that matches all parameter names (with prefix/suffix) and which has |
88 * Builds a regexp pattern that matches all parameter names (with prefix/suffix) and which has |
77 * one group: parameter name (without prefix/suffix) |
89 * one group: parameter name (without prefix/suffix) |
78 */ |
90 */ |
79 private void buildPattern() { |
91 private void buildPattern() throws PatternSyntaxException { |
80 StringBuilder patternString = new StringBuilder(); |
92 StringBuilder patternString = new StringBuilder(); |
81 |
93 |
82 patternString.append(namePrefix); |
94 patternString.append(namePrefix); |
83 patternString.append("(?<paramName>"); |
95 patternString.append("(?<paramName>"); |
84 for (int i = 0; i < parameters.size(); i++) { |
96 for (int i = 0; i < parameters.size(); i++) { |
91 patternString.append(nameSuffix); |
103 patternString.append(nameSuffix); |
92 |
104 |
93 pattern = Pattern.compile(patternString.toString()); |
105 pattern = Pattern.compile(patternString.toString()); |
94 } |
106 } |
95 |
107 |
96 private void placeParametersAndUpdateQuery() throws SQLException { |
108 private void placeParametersAndUpdateQuery() { |
97 final String originalQuery = getQuery(); |
109 final String originalQuery = getQuery(); |
98 Matcher m = pattern.matcher(originalQuery); |
110 Matcher m = pattern.matcher(originalQuery); |
99 |
111 |
100 int lastPosition = 0; |
112 int lastPosition = 0; |
101 while (m.find(lastPosition)) { |
113 while (m.find(lastPosition)) { |