Revision 457
Added by bojilova about 24 years ago
src/edu/ucsb/nceas/metacat/DBSAXHandler.java | ||
---|---|---|
85 | 85 |
MetaCatUtil.debugMessage("start Document"); |
86 | 86 |
|
87 | 87 |
// Create the document node representation as root |
88 |
rootNode = new DBSAXNode(conn); |
|
88 |
rootNode = new DBSAXNode(conn, this.docid);
|
|
89 | 89 |
// Add the node to the stack, so that any text data can be |
90 | 90 |
// added as it is encountered |
91 | 91 |
nodeStack.push(rootNode); |
... | ... | |
95 | 95 |
public void endDocument() throws SAXException { |
96 | 96 |
currentDocument.setTitleFromChildElement(); |
97 | 97 |
MetaCatUtil.debugMessage("end Document"); |
98 |
if ((docid != null) && (!docid.equals(currentDocument.getDocID()))) { |
|
99 |
throw (new SAXException("New document ID generated:", |
|
100 |
new AccessionNumberGeneratedException(currentDocument.getDocID()))); |
|
101 |
} else { |
|
102 |
throw (new SAXException("New document ID generated:", |
|
103 |
new AccessionNumberGeneratedException(currentDocument.getDocID()))); |
|
104 |
} |
|
98 |
// if ((docid != null) && (!docid.equals(currentDocument.getDocID()))) {
|
|
99 |
// throw (new SAXException("New document ID generated:",
|
|
100 |
// new AccessionNumberGeneratedException(currentDocument.getDocID())));
|
|
101 |
// } else {
|
|
102 |
// throw (new SAXException("New document ID generated:",
|
|
103 |
// new AccessionNumberGeneratedException(currentDocument.getDocID())));
|
|
104 |
// }
|
|
105 | 105 |
} |
106 | 106 |
|
107 | 107 |
/** SAX Handler that is called at the start of each XML element */ |
... | ... | |
137 | 137 |
try { |
138 | 138 |
currentDocument = new DocumentImpl(conn, rootNode.getNodeID(), |
139 | 139 |
docname, doctype, docid, action, user); |
140 |
} catch (AccessionNumberException ane) {
|
|
140 |
} catch (Exception ane) { |
|
141 | 141 |
throw (new SAXException("Error with " + action, ane)); |
142 | 142 |
} |
143 |
rootNode.writeDocID(currentDocument.getDocID()); |
|
143 |
// not needed any more |
|
144 |
//rootNode.writeDocID(currentDocument.getDocID()); |
|
144 | 145 |
} |
145 | 146 |
|
146 | 147 |
// Create the current node representation |
147 |
currentNode = new DBSAXNode(conn, localName, parentNode, currentDocument); |
|
148 |
currentNode = new DBSAXNode(conn, localName, parentNode, |
|
149 |
currentDocument.getRootNodeID(),docid, |
|
150 |
currentDocument.getDoctype()); |
|
148 | 151 |
|
149 | 152 |
// Add all of the attributes |
150 | 153 |
for (int i=0; i<atts.getLength(); i++) { |
151 |
currentNode.setAttribute(atts.getLocalName(i), atts.getValue(i)); |
|
154 |
currentNode.setAttribute(atts.getLocalName(i), atts.getValue(i), docid);
|
|
152 | 155 |
} |
153 | 156 |
|
154 | 157 |
// Add the node to the stack, so that any text data can be |
... | ... | |
181 | 184 |
} |
182 | 185 |
|
183 | 186 |
// Write the content of the node to the database |
184 |
currentNode.writeChildNodeToDB("TEXT", null, data); |
|
187 |
currentNode.writeChildNodeToDB("TEXT", null, data, docid);
|
|
185 | 188 |
} |
186 | 189 |
} |
187 | 190 |
|
... | ... | |
201 | 204 |
throws SAXException { |
202 | 205 |
MetaCatUtil.debugMessage("PI"); |
203 | 206 |
DBSAXNode currentNode = (DBSAXNode)nodeStack.peek(); |
204 |
currentNode.writeChildNodeToDB("PI", target, data); |
|
207 |
currentNode.writeChildNodeToDB("PI", target, data, docid);
|
|
205 | 208 |
} |
206 | 209 |
|
207 | 210 |
/** SAX Handler that is called at the end of each XML element */ |
... | ... | |
243 | 246 |
public void comment(char[] ch, int start, int length) throws SAXException { |
244 | 247 |
MetaCatUtil.debugMessage("COMMENT"); |
245 | 248 |
DBSAXNode currentNode = (DBSAXNode)nodeStack.peek(); |
246 |
currentNode.writeChildNodeToDB("COMMENT", null, new String(ch)); |
|
249 |
currentNode.writeChildNodeToDB("COMMENT", null, new String(ch), docid);
|
|
247 | 250 |
} |
248 | 251 |
|
249 | 252 |
/** |
src/edu/ucsb/nceas/metacat/DocumentImpl.java | ||
---|---|---|
107 | 107 |
*/ |
108 | 108 |
public DocumentImpl(Connection conn, long rootnodeid, String docname, |
109 | 109 |
String doctype, String docid, String action, String user) |
110 |
throws AccessionNumberException
|
|
110 |
throws SQLException, Exception
|
|
111 | 111 |
{ |
112 | 112 |
this.conn = conn; |
113 | 113 |
this.rootnodeid = rootnodeid; |
... | ... | |
451 | 451 |
*/ |
452 | 452 |
public static String write( Connection conn, String filename, String action, |
453 | 453 |
String docid, String user, String group ) |
454 |
throws IOException, SQLException, ClassNotFoundException, |
|
455 |
SAXException, SAXParseException, Exception { |
|
454 |
throws Exception { |
|
456 | 455 |
|
457 | 456 |
return write(conn, new FileReader(new File(filename).toString()), |
458 | 457 |
action, docid, user, group); |
... | ... | |
468 | 467 |
*/ |
469 | 468 |
public static String write( Connection conn, Reader xml, String action, |
470 | 469 |
String docid, String user, String group ) |
471 |
throws IOException, SQLException, ClassNotFoundException, |
|
472 |
SAXException, SAXParseException, Exception { |
|
470 |
throws Exception { |
|
473 | 471 |
|
472 |
// Determine if the docid is OK for INSERT or UPDATE |
|
473 |
AccessionNumber ac = new AccessionNumber(); |
|
474 |
String newdocid = ac.generate(docid, action); |
|
475 |
|
|
474 | 476 |
if ( action.equals("UPDATE") ) { |
475 |
// Determine if the docid is OK for UPDATE |
|
476 |
AccessionNumber ac = new AccessionNumber(); |
|
477 |
String newdocid = ac.generate(docid, "UPDATE"); |
|
478 |
|
|
479 | 477 |
// check for 'write' permission for 'user' to update this document |
480 | 478 |
if ( !hasWritePermission(conn, docid, user, group) ) { |
481 | 479 |
throw new Exception("User " + user + |
... | ... | |
484 | 482 |
} |
485 | 483 |
|
486 | 484 |
try { |
487 |
XMLReader parser = initializeParser(conn, action, docid, user); |
|
485 |
XMLReader parser = initializeParser(conn, action, newdocid, user);
|
|
488 | 486 |
conn.setAutoCommit(false); |
489 | 487 |
parser.parse(new InputSource(xml)); |
490 | 488 |
conn.commit(); |
491 | 489 |
conn.setAutoCommit(true); |
492 |
return docid;
|
|
490 |
//return newdocid;
|
|
493 | 491 |
} catch (SAXParseException e) { |
494 | 492 |
conn.rollback(); |
493 |
conn.setAutoCommit(true); |
|
495 | 494 |
throw e; |
496 | 495 |
} catch (SAXException e) { |
497 |
|
|
496 |
conn.rollback(); |
|
497 |
conn.setAutoCommit(true); |
|
498 |
throw e; |
|
499 |
/* |
|
498 | 500 |
// If its a problem with the accession number its ok, just the |
499 | 501 |
// accession number was regenerated |
500 | 502 |
AccessionNumberGeneratedException ang = null; |
... | ... | |
515 | 517 |
conn.rollback(); |
516 | 518 |
throw e; |
517 | 519 |
} |
520 |
*/ |
|
518 | 521 |
} catch (Exception e) { |
519 | 522 |
conn.rollback(); |
523 |
conn.setAutoCommit(true); |
|
520 | 524 |
throw e; |
521 | 525 |
} |
526 |
|
|
527 |
if ( (docid != null) && !(newdocid.equals(docid)) ) { |
|
528 |
return new String("New document ID generated:" + newdocid); |
|
529 |
} else { |
|
530 |
return newdocid; |
|
531 |
} |
|
522 | 532 |
} |
523 | 533 |
|
524 | 534 |
/** |
... | ... | |
529 | 539 |
*/ |
530 | 540 |
public static void delete( Connection conn, String docid, |
531 | 541 |
String user, String group ) |
532 |
throws IOException, SQLException, ClassNotFoundException, |
|
533 |
AccessionNumberException, Exception { |
|
542 |
throws Exception { |
|
534 | 543 |
|
535 | 544 |
// Determine if the docid is OK for DELETE |
536 | 545 |
AccessionNumber ac = new AccessionNumber(); |
... | ... | |
552 | 561 |
stmt.execute("DELETE FROM xml_documents WHERE docid = '" + docid + "'"); |
553 | 562 |
stmt.close(); |
554 | 563 |
conn.commit(); |
564 |
conn.setAutoCommit(true); |
|
555 | 565 |
} |
556 | 566 |
|
557 | 567 |
/** Check for "write" permissions from DB connection */ |
... | ... | |
632 | 642 |
|
633 | 643 |
/** creates SQL code and inserts new document into DB connection */ |
634 | 644 |
private void writeDocumentToDB(String action, String user) |
635 |
throws AccessionNumberException {
|
|
645 |
throws SQLException, Exception {
|
|
636 | 646 |
try { |
637 | 647 |
PreparedStatement pstmt = null; |
638 | 648 |
|
639 | 649 |
if (action.equals("INSERT")) { |
640 |
AccessionNumber ac = new AccessionNumber(); |
|
641 |
this.docid = ac.generate(docid, "INSERT"); |
|
650 |
//AccessionNumber ac = new AccessionNumber();
|
|
651 |
//this.docid = ac.generate(docid, "INSERT");
|
|
642 | 652 |
pstmt = conn.prepareStatement( |
643 | 653 |
"INSERT INTO xml_documents " + |
644 | 654 |
"(docid, rootnodeid, docname, doctype, " + |
... | ... | |
682 | 692 |
pstmt.execute(); |
683 | 693 |
pstmt.close(); |
684 | 694 |
|
685 |
} catch (SQLException e) { |
|
686 |
System.out.println(e.getMessage());
|
|
687 |
} catch (AccessionNumberException ane) { |
|
688 |
MetaCatUtil.debugMessage("Invalid accession number."); |
|
689 |
MetaCatUtil.debugMessage(ane.getMessage()); |
|
690 |
throw ane; |
|
695 |
} catch (SQLException sqle) {
|
|
696 |
throw sqle;
|
|
697 |
// } catch (AccessionNumberException ane) {
|
|
698 |
// MetaCatUtil.debugMessage("Invalid accession number.");
|
|
699 |
// MetaCatUtil.debugMessage(ane.getMessage());
|
|
700 |
// throw ane;
|
|
691 | 701 |
} catch (Exception e) { |
692 |
System.out.println(e.getMessage());
|
|
702 |
throw e;
|
|
693 | 703 |
} |
694 | 704 |
} |
695 | 705 |
|
... | ... | |
804 | 814 |
|
805 | 815 |
} |
806 | 816 |
|
807 |
/** Save a document entry in the xml_revisions table */ |
|
808 |
/* |
|
809 |
private static void archiveDocRevision(Connection conn, String docid, |
|
810 |
String user) throws SQLException { |
|
811 |
// First get all of the values we need |
|
812 |
long rnodeid = -1; |
|
813 |
String docname = null; |
|
814 |
String doctype = null; |
|
815 |
String doctitle = null; |
|
816 |
String user_owner = null; |
|
817 |
Date date_created = null; |
|
818 |
PreparedStatement pstmt = conn.prepareStatement( |
|
819 |
"SELECT rootnodeid,docname,doctype,doctitle,user_owner,date_created " + |
|
820 |
"FROM xml_documents " + |
|
821 |
"WHERE docid = ?"); |
|
822 |
// Bind the values to the query and execute it |
|
823 |
pstmt.setString(1, docid); |
|
824 |
pstmt.execute(); |
|
825 |
|
|
826 |
ResultSet rs = pstmt.getResultSet(); |
|
827 |
boolean tableHasRows = rs.next(); |
|
828 |
if (tableHasRows) { |
|
829 |
rnodeid = rs.getLong(1); |
|
830 |
docname = rs.getString(2); |
|
831 |
doctype = rs.getString(3); |
|
832 |
doctitle = rs.getString(4); |
|
833 |
user_owner = rs.getString(5); |
|
834 |
date_created = rs.getDate(6); |
|
835 |
} |
|
836 |
pstmt.close(); |
|
837 |
|
|
838 |
MetaCatUtil.debugMessage(new Long(rnodeid).toString()); |
|
839 |
MetaCatUtil.debugMessage(docname); |
|
840 |
MetaCatUtil.debugMessage(doctitle); |
|
841 |
//MetaCatUtil.debugMessage(date_created.toString()); |
|
842 |
|
|
843 |
// Next create the new record in the other table using the values selected |
|
844 |
pstmt = conn.prepareStatement( |
|
845 |
"INSERT INTO xml_revisions " + |
|
846 |
"(revisionid, docid, rootnodeid, docname, doctype, doctitle, " + |
|
847 |
"user_owner, user_updated, date_created, date_updated) " + |
|
848 |
"VALUES (null, ?, ?, ?, ?, ?, ?, ?, sysdate, sysdate)"); |
|
849 |
// Bind the values to the query and execute it |
|
850 |
pstmt.setString(1, docid); |
|
851 |
pstmt.setLong(2, rnodeid); |
|
852 |
pstmt.setString(3, docname); |
|
853 |
pstmt.setString(4, doctype); |
|
854 |
pstmt.setString(5, doctitle); |
|
855 |
pstmt.setString(6, user_owner); |
|
856 |
pstmt.setString(7, user); |
|
857 |
//pstmt.setDate(6, date_created); |
|
858 |
pstmt.execute(); |
|
859 |
pstmt.close(); |
|
860 |
} |
|
861 |
*/ |
|
862 | 817 |
/** |
863 | 818 |
* Set up the parser handlers for writing the document to the database |
864 | 819 |
*/ |
865 | 820 |
private static XMLReader initializeParser(Connection conn, |
866 |
String action, String docid, String user) { |
|
821 |
String action, String docid, String user) |
|
822 |
throws Exception { |
|
867 | 823 |
XMLReader parser = null; |
868 | 824 |
// |
869 | 825 |
// Set up the SAX document handlers for parsing |
... | ... | |
893 | 849 |
parser.setErrorHandler((ErrorHandler)chandler); |
894 | 850 |
|
895 | 851 |
} catch (Exception e) { |
896 |
System.err.println(e.toString());
|
|
852 |
throw e;
|
|
897 | 853 |
} |
898 | 854 |
|
899 | 855 |
return parser; |
src/edu/ucsb/nceas/metacat/DBSAXNode.java | ||
---|---|---|
17 | 17 |
import java.io.IOException; |
18 | 18 |
import java.util.Hashtable; |
19 | 19 |
import java.util.Enumeration; |
20 |
import oracle.jdbc.driver.*; |
|
20 | 21 |
|
21 | 22 |
/** |
22 | 23 |
* A Class that represents an XML node and its contents and |
... | ... | |
32 | 33 |
* |
33 | 34 |
* @param conn the JDBC Connection to which all information is written |
34 | 35 |
*/ |
35 |
public DBSAXNode (Connection conn) { |
|
36 |
public DBSAXNode (Connection conn, String docid) {
|
|
36 | 37 |
super(); |
37 | 38 |
this.conn = conn; |
38 | 39 |
this.parentNode = null; |
39 |
writeChildNodeToDB("DOCUMENT", null, null); |
|
40 |
writeChildNodeToDB("DOCUMENT", null, null, docid);
|
|
40 | 41 |
} |
41 | 42 |
|
42 | 43 |
/** |
... | ... | |
47 | 48 |
* @param parentNode the parent node for this node being created |
48 | 49 |
*/ |
49 | 50 |
public DBSAXNode (Connection conn, String tagname, DBSAXNode parentNode, |
50 |
DocumentImpl currentDocument) {
|
|
51 |
long rootnodeid, String docid, String doctype) {
|
|
51 | 52 |
|
52 | 53 |
super(tagname); |
53 | 54 |
setParentID(parentNode.getNodeID()); |
54 |
setRootNodeID(currentDocument.getRootNodeID());
|
|
55 |
setDocID(currentDocument.getDocID());
|
|
55 |
setRootNodeID(rootnodeid);
|
|
56 |
setDocID(docid);
|
|
56 | 57 |
setNodeIndex(parentNode.incChildNum()); |
57 | 58 |
this.conn = conn; |
58 | 59 |
this.parentNode = parentNode; |
59 |
writeChildNodeToDB("ELEMENT", getTagName(), null); |
|
60 |
updateNodeIndex(currentDocument.getDocID(), currentDocument.getDoctype());
|
|
60 |
writeChildNodeToDB("ELEMENT", getTagName(), null, docid);
|
|
61 |
updateNodeIndex(docid, doctype);
|
|
61 | 62 |
} |
62 | 63 |
|
63 | 64 |
/** creates SQL code and inserts new node into DB connection */ |
64 | 65 |
public void writeChildNodeToDB(String nodetype, String nodename, |
65 |
String data) { |
|
66 |
String data, String docid) {
|
|
66 | 67 |
try { |
67 | 68 |
PreparedStatement pstmt; |
68 | 69 |
if (nodetype == "DOCUMENT") { |
69 | 70 |
pstmt = conn.prepareStatement( |
70 | 71 |
"INSERT INTO xml_nodes " + |
71 |
"(nodeid, nodetype, nodename, rootnodeid) " + |
|
72 |
"VALUES (?, ?, ?, ?)"); |
|
72 |
"(nodeid, nodetype, nodename, docid, rootnodeid) " +
|
|
73 |
"VALUES (?, ?, ?, ?, ?)");
|
|
73 | 74 |
MetaCatUtil.debugMessage("INSERTING DOCNAME: " + nodename); |
74 | 75 |
} else { |
75 | 76 |
pstmt = conn.prepareStatement( |
76 | 77 |
"INSERT INTO xml_nodes " + |
77 |
"(nodeid, nodetype, nodename, " + |
|
78 |
"rootnodeid, parentnodeid, docid, nodedata, nodeindex) " +
|
|
78 |
"(nodeid, nodetype, nodename, docid, " +
|
|
79 |
"rootnodeid, parentnodeid, nodedata, nodeindex) " + |
|
79 | 80 |
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); |
80 | 81 |
} |
81 | 82 |
|
... | ... | |
84 | 85 |
pstmt.setLong(1, nid); |
85 | 86 |
pstmt.setString(2, nodetype); |
86 | 87 |
pstmt.setString(3, nodename); |
88 |
pstmt.setString(4, docid); |
|
87 | 89 |
if (nodetype == "DOCUMENT") { |
88 |
pstmt.setLong(4, nid);
|
|
90 |
pstmt.setLong(5, nid);
|
|
89 | 91 |
} else { |
90 | 92 |
if (nodetype == "ELEMENT") { |
91 |
pstmt.setLong(4, getRootNodeID()); |
|
92 |
pstmt.setLong(5, getParentID()); |
|
93 |
pstmt.setString(6, getDocID()); |
|
93 |
pstmt.setLong(5, getRootNodeID()); |
|
94 |
pstmt.setLong(6, getParentID()); |
|
94 | 95 |
pstmt.setString(7, data); |
95 | 96 |
pstmt.setInt(8, getNodeIndex()); |
96 | 97 |
} else { |
97 |
pstmt.setLong(4, getRootNodeID()); |
|
98 |
pstmt.setLong(5, getNodeID()); |
|
99 |
pstmt.setString(6, getDocID()); |
|
98 |
pstmt.setLong(5, getRootNodeID()); |
|
99 |
pstmt.setLong(6, getNodeID()); |
|
100 | 100 |
if ( nodetype == "TEXT" && getTagName().equals("meta_file_id") ) { |
101 | 101 |
pstmt.setString(7, getDocID()); |
102 | 102 |
} else { |
... | ... | |
208 | 208 |
} |
209 | 209 |
|
210 | 210 |
/** Add a new attribute to this node, or set its value */ |
211 |
public void setAttribute(String attName, String attValue) { |
|
211 |
public void setAttribute(String attName, String attValue, String docid) {
|
|
212 | 212 |
if (attName != null) { |
213 | 213 |
// Enter the attribute in the hash table |
214 | 214 |
super.setAttribute(attName, attValue); |
215 | 215 |
|
216 | 216 |
// And enter the attribute in the database |
217 |
writeChildNodeToDB("ATTRIBUTE", attName, attValue); |
|
217 |
writeChildNodeToDB("ATTRIBUTE", attName, attValue, docid);
|
|
218 | 218 |
} else { |
219 | 219 |
System.err.println("Attribute name must not be null!"); |
220 | 220 |
} |
... | ... | |
231 | 231 |
boolean atRootDocumentNode = false; |
232 | 232 |
DBSAXNode nodePointer = this; |
233 | 233 |
StringBuffer currentPath = new StringBuffer(); |
234 |
int counter = 0; |
|
234 | 235 |
|
235 | 236 |
// Create a Hashtable of all of the paths to reach this node |
236 | 237 |
// including absolute paths and relative paths |
... | ... | |
238 | 239 |
if (atStartingNode) { |
239 | 240 |
currentPath.insert(0, nodePointer.getTagName()); |
240 | 241 |
pathlist.put(currentPath.toString(), new Long(getNodeID())); |
242 |
counter++; |
|
241 | 243 |
atStartingNode = false; |
242 | 244 |
} else { |
243 | 245 |
currentPath.insert(0, "/"); |
244 | 246 |
currentPath.insert(0, nodePointer.getTagName()); |
245 | 247 |
pathlist.put(currentPath.toString(), new Long(getNodeID())); |
248 |
counter++; |
|
246 | 249 |
} |
247 | 250 |
|
248 | 251 |
// advance to the next parent node |
... | ... | |
253 | 256 |
if (nodePointer.getNodeType().equals("DOCUMENT")) { |
254 | 257 |
currentPath.insert(0, "/"); |
255 | 258 |
pathlist.put(currentPath.toString(), new Long(getNodeID())); |
259 |
counter++; |
|
256 | 260 |
atRootDocumentNode = true; |
257 | 261 |
} |
258 | 262 |
} |
... | ... | |
263 | 267 |
"INSERT INTO xml_index (nodeid, path, docid, doctype, " + |
264 | 268 |
"parentnodeid) " + |
265 | 269 |
"VALUES (?, ?, ?, ?, ?)"); |
270 |
((OraclePreparedStatement)pstmt).setExecuteBatch(counter); |
|
266 | 271 |
|
267 | 272 |
pstmt.setString(3, docid); |
268 | 273 |
pstmt.setString(4, doctype); |
... | ... | |
275 | 280 |
Long nodeid = (Long)pathlist.get(path); |
276 | 281 |
pstmt.setLong(1, nodeid.longValue()); |
277 | 282 |
pstmt.setString(2, path); |
278 |
pstmt.execute(); |
|
283 |
pstmt.executeUpdate();
|
|
279 | 284 |
|
280 | 285 |
//System.out.println(nodeid + " ==> " + path); |
281 | 286 |
} |
Also available in: Unified diff
changes related to decrease the time of INSERT of document.
With these changes I inserted 200KB file for 3 minutes, 50KB for 50sec.
This is mainly simplifing the DBSAXNode class and
using batching feature of Oracle JDBC driver.