1 | package org.sqlorm.querybuilder; |
2 | |
3 | import java.util.List; |
4 | |
5 | /** |
6 | * A general helper class to be used when generating dynamic queries |
7 | * |
8 | * @author Kasper B. Graversen, (c) 2007-2008 |
9 | */ |
10 | public class QueryBuilderHelper { |
11 | static final char EXPAND_TOKEN = '#'; |
12 | |
13 | /** |
14 | * Format a string. Very similar but simpler than <code>String.format()</code>. Use the char <code>#</code> to |
15 | * denote a marker on which to insert code by the formatter. You can insret as many <code>#</code> as long as you have |
16 | * an equal number of <code>args</code> matching. |
17 | * <p> |
18 | * e.g. |
19 | * |
20 | * <pre> |
21 | * QueryBuilderHelper.format("a#a", 1)) => "a1a" |
22 | * </pre> |
23 | * |
24 | * or |
25 | * |
26 | * <pre> |
27 | * QueryBuilderHelper.format("a##a", 1,1)) => "a11a" |
28 | * </pre> |
29 | * |
30 | * @param fmtString |
31 | * @param args |
32 | * @return |
33 | */ |
34 | public static String format(final String fmtString, final Object... args) { |
35 | if(fmtString == null) { |
36 | throw new IllegalArgumentException("argument fmtString cannot be null"); |
37 | } |
38 | if(args == null) { |
39 | throw new IllegalArgumentException("argument args cannot be null"); |
40 | } |
41 | |
42 | final StringBuilder sb = new StringBuilder(); |
43 | int argpos = 0; |
44 | for(int strPos = 0; strPos < fmtString.length(); strPos++) { |
45 | final char c = fmtString.charAt(strPos); |
46 | // expand tokens |
47 | if(c == EXPAND_TOKEN) { |
48 | if(argpos < args.length) { |
49 | if(args[argpos] instanceof IExpr) { |
50 | ((IExpr) args[argpos++]).toSql(sb, ""); |
51 | // sb.append(((IExpr) args[argpos++]).toSql(""));// TODO remove this quick hack by storing iexpr in |
52 | // expr |
53 | } |
54 | else { |
55 | sb.append(args[argpos++]); |
56 | } |
57 | } |
58 | else { |
59 | throw new IllegalArgumentException("Cannot properly format string \"" + fmtString |
60 | + "\" too few formatting arguments provided."); |
61 | } |
62 | } |
63 | else { |
64 | // normal character |
65 | sb.append(c); |
66 | } |
67 | } |
68 | |
69 | // arg sanity check |
70 | if(args.length != argpos) { |
71 | throw new IllegalArgumentException("Cannot properly format string \"" + fmtString |
72 | + "\" too many formatting arguments provided."); |
73 | } |
74 | |
75 | return sb.toString(); |
76 | } |
77 | |
78 | public static String longs(final Object... args) { |
79 | if(args == null) { |
80 | return ""; |
81 | } |
82 | if(args.length == 0) { |
83 | return ""; |
84 | } |
85 | final StringBuilder sb = new StringBuilder(); |
86 | |
87 | for(int i = 0; i < args.length; i++) { |
88 | if(!(args[i] instanceof Integer || args[i] instanceof Long)) { |
89 | final String s = args[i].toString(); |
90 | Long.parseLong(s); // check the input is of the correct type, but convert to output |
91 | sb.append(s); |
92 | } |
93 | else { |
94 | sb.append(args[i]); |
95 | } |
96 | sb.append(","); |
97 | } |
98 | // remove last delimiter |
99 | final int bufLen = sb.length(); |
100 | sb.delete(bufLen - 1, bufLen); |
101 | return sb.toString(); |
102 | } |
103 | |
104 | public static <T> String numbers(final List<T> args) { |
105 | return numbers(args.toArray()); |
106 | } |
107 | |
108 | public static String numbers(final Object... args) { |
109 | if(args == null) { |
110 | return ""; |
111 | } |
112 | if(args.length == 0) { |
113 | return ""; |
114 | } |
115 | final StringBuilder sb = new StringBuilder(); |
116 | |
117 | for(int i = 0; i < args.length; i++) { |
118 | if(args[i] instanceof Number == false) { |
119 | final String s = args[i].toString(); |
120 | Double.parseDouble(s); // check the input is of the correct type, but convert to output |
121 | sb.append(s); |
122 | } |
123 | else { |
124 | sb.append(args[i]); |
125 | } |
126 | sb.append(","); |
127 | } |
128 | |
129 | // remove last delimiter |
130 | final int bufLen = sb.length(); |
131 | sb.delete(bufLen - 1, bufLen); |
132 | return sb.toString(); |
133 | } |
134 | |
135 | public static String numbers(final long[] args) { |
136 | if(args == null) { |
137 | return ""; |
138 | } |
139 | if(args.length == 0) { |
140 | return ""; |
141 | } |
142 | final StringBuilder sb = new StringBuilder(); |
143 | for(int i = 0; i < args.length; i++) { |
144 | sb.append(args[i]); |
145 | sb.append(","); |
146 | } |
147 | // remove last delimiter |
148 | final int bufLen = sb.length(); |
149 | sb.delete(bufLen - 1, bufLen); |
150 | return sb.toString(); |
151 | } |
152 | |
153 | public static String numbers(final int[] args) { |
154 | if(args == null) { |
155 | return ""; |
156 | } |
157 | if(args.length == 0) { |
158 | return ""; |
159 | } |
160 | final StringBuilder sb = new StringBuilder(); |
161 | for(int i = 0; i < args.length; i++) { |
162 | sb.append(args[i]); |
163 | sb.append(","); |
164 | } |
165 | // remove last delimiter |
166 | final int bufLen = sb.length(); |
167 | sb.delete(bufLen - 1, bufLen); |
168 | return sb.toString(); |
169 | } |
170 | |
171 | // TODO Implementation: Use vigorous white-list style checking on any user input that may be used in an SQL command. |
172 | // Rather than escape meta-characters, it is safest to disallow them entirely. Reason: Later use of data that has been |
173 | // entered in the database may neglect to escape meta-characters before use. |
174 | public static String strings(final Object... args) { |
175 | if(args == null) { |
176 | return ""; |
177 | } |
178 | if(args.length == 0) { |
179 | return ""; |
180 | } |
181 | final StringBuilder sb = new StringBuilder(); |
182 | |
183 | for(final Object element : args) { |
184 | sb.append(element.toString().replaceAll("'", "''")); |
185 | sb.append(","); |
186 | } |
187 | // remove last delimiter |
188 | final int bufLen = sb.length(); |
189 | |
190 | sb.delete(bufLen - 1, bufLen); |
191 | |
192 | return sb.toString(); |
193 | } |
194 | |
195 | } |