Project

General

Profile

« Previous | Next » 

Revision 457

Added by bojilova over 23 years ago

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.

View differences:

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