1 24 25 package com.mckoi.database.jdbc; 26 27 import java.io.*; 28 import java.sql.SQLException ; 29 import com.mckoi.database.global.ObjectTransfer; 30 import com.mckoi.database.global.ObjectTranslator; 31 import com.mckoi.database.global.ByteLongObject; 32 33 42 43 public final class SQLQuery { 44 45 48 private String query; 49 50 53 private boolean prepared; 54 55 59 private Object [] parameters; 60 private int parameters_index; 61 private int parameter_count; 62 63 64 67 private SQLQuery() { 68 } 69 70 73 public SQLQuery(String query) { 74 this.query = query; 75 parameters = new Object [8]; 76 parameters_index = 0; 77 parameter_count = 0; 78 prepared = false; 79 } 80 81 84 private void growParametersList(int new_size) { 85 Object [] new_list = new Object [new_size]; 87 System.arraycopy(parameters, 0, new_list, 0, parameters.length); 89 parameters = new_list; 91 } 92 93 96 private Object translateObjectType(Object ob) { 97 return ObjectTranslator.translate(ob); 98 } 99 100 106 public void addVar(Object ob) { 107 ob = translateObjectType(ob); 108 parameters[parameters_index] = ob; 109 ++parameters_index; 110 ++parameter_count; 111 if (parameters_index >= parameters.length) { 112 growParametersList(parameters_index + 8); 113 } 114 } 115 116 122 public void setVar(int i, Object ob) { 123 ob = translateObjectType(ob); 124 if (i >= parameters.length) { 125 growParametersList(i + 8); 126 } 127 parameters[i] = ob; 128 parameters_index = i + 1; 129 parameter_count = Math.max(parameters_index, parameter_count); 130 } 131 132 135 public void clear() { 136 parameters_index = 0; 137 parameter_count = 0; 138 for (int i = 0; i < parameters.length; ++i) { 139 parameters[i] = null; 140 } 141 } 142 143 144 147 public String getQuery() { 148 return query; 149 } 150 151 157 public Object [] getVars() { 158 return parameters; 159 } 160 161 165 private String escapeJDBCSubstitution(String jdbc_code) 166 throws SQLException { 167 String code = jdbc_code.substring(1, jdbc_code.length() - 1); 168 int kp_delim = code.indexOf(' '); 169 if (kp_delim != -1) { 170 String keyword = code.substring(0, kp_delim); 171 String body = code.substring(kp_delim).trim(); 172 173 if (keyword.equals("d")) { return "DATE " + body; 175 } 176 if (keyword.equals("t")) { return "TIME " + body; 178 } 179 if (keyword.equals("ts")) { return "TIMESTAMP " + body; 181 } 182 if (keyword.equals("fn")) { return body; 184 } 185 if (keyword.equals("call") || keyword.equals("?=")) { 186 throw new MSQLException("Stored procedures not supported."); 187 } 188 if (keyword.equals("oj")) { return body; 190 } 191 192 throw new MSQLException("Do not understand JDBC substitution keyword '" + 193 keyword + "' of " + jdbc_code); 194 } 195 else { 196 throw new MSQLException("Malformed JDBC escape code: " + jdbc_code); 197 } 198 199 } 200 201 205 private void doEscapeSubstitutions() throws SQLException { 206 211 if (query.indexOf('{') == -1) { 213 return; 214 } 215 216 StringBuffer buf = new StringBuffer (); 217 StringBuffer jdbc_escape = null; 218 219 int i = 0; 220 int sz = query.length(); 221 int state = 0; 222 boolean ignore_next = false; 223 224 while (i < sz) { 225 char c = query.charAt(i); 226 227 if (state == 0) { if (c == '\'' || c == '\"') { 229 state = c; } 231 else if (c == '{') { 232 jdbc_escape = new StringBuffer (); 233 state = '}'; 234 } 235 } 236 else if (state != 0) { if (!ignore_next) { 238 if (c == '\\') { 239 ignore_next = true; 240 } 241 else { 242 if (c == (char) state) { 244 state = 0; 245 if (c == '}') { 246 jdbc_escape.append('}'); 247 buf.append(escapeJDBCSubstitution(new String (jdbc_escape))); 248 jdbc_escape = null; 249 c = ' '; 250 } 251 } 252 } 253 } 254 else { 255 ignore_next = false; 256 } 257 } 258 259 if (state != '}') { 260 buf.append(c); 262 } 263 else { 264 jdbc_escape.append(c); 265 } 266 267 ++i; 268 } 269 270 if (state == '}') { 271 throw new SQLException ("Unterminated JDBC escape code in query: " + 272 new String (jdbc_escape)); 273 } 274 275 query = new String (buf); 276 } 277 278 283 public void prepare(boolean do_escape_processing) throws SQLException { 284 if (do_escape_processing) { 285 doEscapeSubstitutions(); 286 } 287 prepared = true; 288 } 289 290 293 public boolean equals(Object ob) { 294 SQLQuery q2 = (SQLQuery) ob; 295 if (query.equals(q2.query)) { 298 if (parameter_count == q2.parameter_count) { 299 for (int i = 0; i < parameter_count; ++i) { 300 if (parameters[i] != q2.parameters[i]) { 301 return false; 302 } 303 } 304 return true; 305 } 306 } 307 return false; 308 } 309 310 313 public SQLQuery copy() { 314 SQLQuery q = new SQLQuery(); 315 q.query = query; 316 q.parameters = (Object []) parameters.clone(); 317 q.parameters_index = parameters_index; 318 q.parameter_count = parameter_count; 319 q.prepared = prepared; 320 return q; 321 } 322 323 326 public String toString() { 327 StringBuffer buf = new StringBuffer (); 328 buf.append("[ Query:\n[ "); 329 buf.append(getQuery()); 330 buf.append(" ]\n"); 331 if (parameter_count > 0) { 332 buf.append("\nParams:\n[ "); 333 for (int i = 0; i < parameter_count; ++i) { 334 Object ob = parameters[i]; 335 if (ob == null) { 336 buf.append("NULL"); 337 } 338 else { 339 buf.append(parameters[i].toString()); 340 } 341 buf.append(", "); 342 } 343 buf.append(" ]"); 344 } 345 buf.append("\n]"); 346 return new String (buf); 347 } 348 349 351 354 public void writeTo(DataOutputStream out) throws IOException { 355 out.writeUTF(query); 356 out.writeInt(parameter_count); 357 for (int i = 0; i < parameter_count; ++i) { 358 ObjectTransfer.writeTo(out, parameters[i]); 359 } 360 } 361 362 365 public static SQLQuery readFrom(DataInputStream in) throws IOException { 366 String query_string = in.readUTF(); 367 SQLQuery query = new SQLQuery(query_string); 368 int arg_length = in.readInt(); 369 for (int i = 0; i < arg_length; ++i) { 370 query.addVar(ObjectTransfer.readFrom(in)); 371 } 372 return query; 373 } 374 375 378 public ByteLongObject serializeToBlob() { 379 380 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 381 DataOutputStream out = new DataOutputStream(bout); 382 try { 383 writeTo(out); 384 out.flush(); 385 return new ByteLongObject(bout.toByteArray()); 386 } 387 catch (IOException e) { 388 throw new Error ("IO Error: " + e.getMessage()); 389 } 390 } 391 392 395 public static SQLQuery deserializeFromBlob(ByteLongObject ob) { 396 DataInputStream in = new DataInputStream( 397 new ByteArrayInputStream(ob.getByteArray())); 398 try { 399 return readFrom(in); 400 } 401 catch (IOException e) { 402 throw new Error ("IO Error: " + e.getMessage()); 403 } 404 } 405 406 407 } 408 | Popular Tags |