1 package com.quadcap.sql.tools; 2 3 40 41 import java.io.BufferedInputStream ; 42 import java.io.BufferedReader ; 43 import java.io.FileInputStream ; 44 import java.io.FileReader ; 45 import java.io.InputStream ; 46 import java.io.InputStreamReader ; 47 import java.io.IOException ; 48 import java.io.OutputStream ; 49 import java.io.PrintWriter ; 50 import java.io.Reader ; 51 52 import java.math.BigDecimal ; 53 54 import java.sql.Connection ; 63 import java.sql.DatabaseMetaData ; 64 import java.sql.ResultSet ; 65 import java.sql.ResultSetMetaData ; 66 import java.sql.Statement ; 67 69 import java.sql.SQLException ; 70 import java.sql.Types ; 71 72 import java.util.zip.GZIPInputStream ; 73 74 import org.xml.sax.AttributeList ; 75 import org.xml.sax.DocumentHandler ; 76 import org.xml.sax.ErrorHandler ; 77 import org.xml.sax.InputSource ; 78 import org.xml.sax.Parser ; 79 import org.xml.sax.Locator ; 80 import org.xml.sax.SAXException ; 81 import org.xml.sax.SAXParseException ; 82 83 import org.xml.sax.helpers.ParserFactory ; 84 85 91 public class XmlLoad implements DocumentHandler , ErrorHandler { 92 Connection conn; 93 ResultSet rs; 94 ResultSetMetaData rm; 95 Statement stmt; 96 String tableName = ""; 97 String columnName = ""; 98 StringBuffer data = new StringBuffer (); 99 100 static final int XML = 0; 101 static final int DATABASE = 1; 102 static final int DDL = 2; 103 static final int DML = 3; 104 static final int TABLE = 4; 105 static final int COLUMN = 5; 106 107 int state = XML; 108 109 Parser parser; 110 Locator locator; 111 112 119 public XmlLoad() throws Exception { 120 parser = ParserFactory.makeParser("com.quadcap.text.sax.Parser"); 121 parser.setDocumentHandler(this); 122 parser.setErrorHandler(this); 123 } 124 125 134 public XmlLoad(Connection conn) throws Exception { 135 this(); 136 setConnection(conn); 137 } 138 139 145 public void setConnection(Connection conn) throws SQLException { 146 if (stmt != null) { 147 if (rs != null) { 148 rs.close(); 149 } 150 stmt.close(); 151 } 152 this.conn = conn; 153 this.stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 157 ResultSet.CONCUR_UPDATABLE); 158 } 160 161 166 public Connection getConnection() { 167 return conn; 168 } 169 170 181 public void load(InputStream is) throws Exception { 182 parser.parse(new InputSource (is)); 183 } 184 185 196 public void load(Reader r) throws Exception { 197 parser.parse(new InputSource (r)); 198 } 199 200 207 public void error(SAXParseException exception) { 208 System.err.println("error"); 209 exception.printStackTrace(System.err); 210 } 211 212 219 public void fatalError(SAXParseException exception) { 220 System.err.println("fatal error"); 221 exception.printStackTrace(System.err); 222 } 223 224 231 public void warning(SAXParseException exception) { 232 System.err.println("warning"); 233 exception.printStackTrace(System.err); 234 } 235 236 249 public void characters(char[] ch, int start, int length) 250 throws SAXException 251 { 252 data.append(ch, start, length); 253 } 254 255 259 public void endDocument() { 260 } 261 262 273 public void endElement(String name) throws SAXException { 274 try { 275 switch (state) { 276 case DATABASE: 277 if (rs != null) { 279 rs.close(); 280 rs = null; 281 } 282 if (stmt != null) { 283 stmt.close(); 284 stmt = null; 285 } 286 state = XML; 287 break; 288 case TABLE: 289 try { 291 rs.insertRow(); 292 } catch (Throwable ex) { 293 System.err.println(locator.getSystemId() + ":" + 294 locator.getLineNumber() + ":" + 295 locator.getColumnNumber() + ": " + 296 ex.toString()); 297 } 298 state = DML; 299 break; 300 case DDL: 301 try { 302 stmt.execute(data.toString()); 303 } catch (Throwable ex) { 304 System.err.println(locator.getSystemId() + ":" + 305 locator.getLineNumber() + ":" + 306 locator.getColumnNumber() + ": " + 307 ex.toString()); 308 } 309 state = DATABASE; 310 break; 311 case DML: 312 state = DATABASE; 313 break; 314 case COLUMN: 315 int type = rm.getColumnType(rs.findColumn(columnName)); 316 rs.updateObject(columnName, 317 makeObject(type, data.toString())); 318 state = TABLE; 319 break; 320 default: 321 throw makeException("endElement: bad state: " + state); 322 } 323 } catch (Throwable e) { 324 System.err.println(locator.getSystemId() + ":" + 325 locator.getLineNumber() + ":" + 326 locator.getColumnNumber() + ": " + 327 e.toString()); 328 System.err.println("[" + data + "]"); 329 printException(e); 330 throw makeException(e.toString()); 331 } 332 } 333 334 public SAXException makeException(String s) { 335 return new SAXException (locator.getSystemId() + ":" + 336 locator.getLineNumber() + ":" + 337 locator.getColumnNumber() + ": " + s); 338 } 339 340 347 public void ignorableWhitespace(char[] ch, int start, int length) { 348 } 349 350 357 public void processingInstruction(String target, String data) { 358 } 359 360 365 public void setDocumentLocator(Locator locator) { 366 this.locator = locator; 367 } 368 369 373 public void startDocument() { 374 } 375 376 390 public void startElement(String name, AttributeList attrs) 391 throws SAXException 392 { 393 data.setLength(0); 394 try { 395 switch (state) { 396 case XML: 397 if (!name.equals("database")) { 398 throw makeException("Outer tag must be 'database'"); 399 } 400 state = DATABASE; 401 break; 402 case DATABASE: 403 if (name.equals("ddl")) { 404 state = DDL; 405 } else if (name.equals("dml")) { 406 state = DML; 407 } else { 408 throw makeException("Bad tag: " + name + 409 ", expected 'ddl' or 'dml'"); 410 } 411 break; 412 case DDL: 413 throw makeException("Nested elements (" + name + 414 ") not allowed in 'ddl' element"); 415 case DML: 416 if (!tableName.equals(name)) { 417 if (rs != null) rs.close(); 418 rs = (ResultSet )stmt.executeQuery("select * from " + name + 419 " for update"); 420 rm = (ResultSetMetaData )rs.getMetaData(); 421 } 422 rs.moveToInsertRow(); 423 tableName = name; 424 state = TABLE; 425 break; 426 case TABLE: 427 columnName = name; 428 state = COLUMN; 429 break; 430 case COLUMN: 431 throw makeException("Nested elements not allowed in column element"); 432 default: 433 throw makeException("bad state: " + state); 434 } 435 } catch (SQLException e) { 436 printException(e); 437 throw makeException(e.toString()); 438 } 439 } 440 441 static byte[] hexMap = new byte[256]; 442 static { 443 for (int i = 0; i < XmlDump.hexBytes.length; i++) { 444 hexMap[XmlDump.hexBytes[i]] = (byte)i; 445 } 446 } 447 448 byte[] makeBytes(String val) { 449 byte[] buf = new byte[val.length() / 2]; 450 int pos = 0; 451 for (int i = 0; i < buf.length; i++) { 452 buf[i] = (byte)(hexMap[val.charAt(pos++)] << 4); 453 buf[i] += hexMap[val.charAt(pos++)]; 454 } 455 return buf; 456 } 457 458 459 Object makeObject(int jdbcType, String val) 460 throws SAXException 461 { 462 switch (jdbcType) { 463 case Types.BIT: 464 return new Boolean (val); 465 case Types.TINYINT: 466 return new Byte (val); 467 case Types.SMALLINT: 468 return new Short (val); 469 case Types.INTEGER: 470 return new Integer (val); 471 case Types.BIGINT: 472 return new Long (val); 473 case Types.FLOAT: 474 case Types.REAL: 475 case Types.DOUBLE: 476 return new Double (val); 477 case Types.NUMERIC: 478 case Types.DECIMAL: 479 return new BigDecimal (val); 480 case Types.CHAR: 481 case Types.VARCHAR: 482 case Types.LONGVARCHAR: 483 case Types.OTHER: 484 case Types.CLOB: 488 return val; 490 case Types.DATE: 491 case Types.TIME: 492 case Types.TIMESTAMP: 493 return val; 494 case Types.BINARY: 495 case Types.VARBINARY: 496 case Types.LONGVARBINARY: 497 case Types.BLOB: 501 return makeBytes(val); 503 case Types.NULL: 504 return null; 505 case Types.JAVA_OBJECT: 507 case Types.DISTINCT: 508 case Types.STRUCT: 509 case Types.ARRAY: 510 case Types.REF: 511 default: 513 throw makeException("not implemented, jdbc type: " + jdbcType); 514 } 515 } 516 517 final static void printException(Throwable t) { 518 if (t != null) { 519 com.quadcap.util.Debug.print(t); 521 if (t instanceof SAXException ) { 522 printException(((SAXException )t).getException()); 523 } 524 } 525 } 526 527 544 public static void main(String [] args) { 545 try { 546 Connection xconn = XmlDump.makeConnection(); 547 try { 548 for (int i = 0; i < args.length; i++) { 549 String f = args[i]; 550 if (f.endsWith(".sql")) { 551 Loader load = new Loader(xconn); 552 PrintWriter pw = new PrintWriter (System.out); 553 load.setWriter(pw); 554 load.loadFile(f); 555 pw.flush(); 556 } else if (f.endsWith(".xml")) { 557 XmlLoad load = new XmlLoad(xconn); 558 FileReader fr = new FileReader (f); 559 BufferedReader br = new BufferedReader (fr); 560 load.load(br); 561 br.close(); 562 } else if (f.endsWith(".xml.gz")) { 563 XmlLoad load = new XmlLoad(xconn); 564 FileInputStream fis = new FileInputStream (f); 565 BufferedInputStream bis = new BufferedInputStream (fis); 566 GZIPInputStream gis = new GZIPInputStream (bis); 567 InputStreamReader ir = new InputStreamReader (gis); 568 load.load(ir); 569 ir.close(); 570 } 571 } 572 } finally { 573 xconn.close(); 574 } 575 } catch (Exception e) { 576 printException(e); 577 } 578 } 579 } 580 | Popular Tags |