001/* Implementation of provenance query interface for SQL v8. 002 003 Copyright (c) 2009-2010 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024*/ 025 026package org.kepler.provenance.sql; 027 028import java.sql.PreparedStatement; 029import java.sql.ResultSet; 030import java.sql.SQLException; 031import java.sql.Statement; 032import java.sql.Timestamp; 033import java.util.ArrayList; 034import java.util.Arrays; 035import java.util.Date; 036import java.util.HashMap; 037import java.util.Iterator; 038import java.util.LinkedHashMap; 039import java.util.LinkedList; 040import java.util.List; 041import java.util.ListIterator; 042import java.util.Map; 043import java.util.regex.Matcher; 044 045import org.jdom.Document; 046import org.jdom.Element; 047import org.jdom.input.DOMBuilder; 048import org.jdom.output.XMLOutputter; 049import org.kepler.moml.NamedObjId; 050import org.kepler.objectmanager.lsid.KeplerLSID; 051import org.kepler.provenance.DefaultQuery; 052import org.kepler.provenance.QueryException; 053import org.kepler.sms.NamedOntClass; 054import org.kepler.util.RenameUtil; 055import org.kepler.util.WorkflowRun; 056import org.kepler.util.sql.DatabaseFactory; 057import org.kepler.util.sql.DatabaseType; 058import org.kepler.util.sql.Schema; 059 060import ptolemy.data.expr.XMLParser; 061 062/** 063 * Implementation of query interface for SQL v8. 064 * 065 * @author Daniel Crawl, Derik Barseghian, Ben Leinfelder 066 * @version $Id: SQLQueryV8.java 34619 2017-08-23 20:27:50Z crawl $ 067 * 068 */ 069public class SQLQueryV8 extends DefaultQuery 070{ 071 /** Construct a new SQLQueryV8 and connect to a database. */ 072 public SQLQueryV8(Map<String,String> parameters) throws QueryException 073 { 074 try 075 { 076 _dbType = DatabaseFactory.getConnectedDatabaseType(parameters, "provenance"); 077 } 078 catch(SQLException e) 079 { 080 e.printStackTrace(); 081 throw new QueryException("Unable to connect or initialize " + 082 "database connection: ", e); 083 } 084 085 _init(); 086 } 087 088 /** Disconnect from provenance store. */ 089 @Override 090 public void disconnect() throws QueryException 091 { 092 if(_dbType != null) 093 { 094 try 095 { 096 _dbType.disconnect(); 097 } 098 catch(SQLException e) 099 { 100 throw new QueryException("Unable to disconnect: ", e); 101 } 102 103 _dbType = null; 104 } 105 } 106 107 /** Get a list of workflow names. */ 108 @Override 109 public List<String> getWorkflows() throws QueryException 110 { 111 try 112 { 113 List<String> retval = new LinkedList<String>(); 114 115 ResultSet result = null; 116 try 117 { 118 result = _psWorkflows.executeQuery(); 119 while(result.next()) 120 { 121 retval.add(result.getString("name")); 122 } 123 return retval; 124 } 125 finally 126 { 127 if(result != null) 128 { 129 result.close(); 130 } 131 } 132 } 133 catch(SQLException e) 134 { 135 throw new QueryException("Unable to query workflow names: ", e); 136 } 137 } 138 139 /** Get a workflow name. 140 * 141 * @param lsid the workflow's LSID. 142 * @return the workflow name if found, otherwise null. 143 */ 144 @Override 145 public String getWorkflowName(KeplerLSID lsid) throws QueryException 146 { 147 String retval = null; 148 149 try 150 { 151 _psWorkflowNameForLSID.setString(1, lsid.toStringWithoutRevision()); 152 ResultSet result = null; 153 try 154 { 155 result = _psWorkflowNameForLSID.executeQuery(); 156 if(result.next()) 157 { 158 retval = result.getString(1); 159 } 160 } 161 finally 162 { 163 if(result != null) 164 { 165 result.close(); 166 } 167 } 168 } 169 catch(SQLException e) 170 { 171 throw new QueryException("Error querying workflow name: ", e); 172 } 173 174 return retval; 175 } 176 177 /** Get a workflow name for an execution LSID. 178 * @param lsid the execution LSID. 179 * @return the workflow name if found, otherwise null. 180 */ 181 @Override 182 public String getWorkflowNameForExecution(KeplerLSID lsid) throws QueryException { 183 184 synchronized(_psWorkflowNameForExecutionLSID) { 185 try { 186 _psWorkflowNameForExecutionLSID.setString(1, lsid.toString()); 187 try(ResultSet result = _psWorkflowNameForExecutionLSID.executeQuery();) { 188 if(result.next()) { 189 String retval = result.getString(1); 190 if(result.next()) { 191 System.err.println("WARNING: more than one workflow execution with LSID " + lsid); 192 } 193 return retval; 194 } 195 } 196 } 197 catch(SQLException e) { 198 throw new QueryException("Error querying workflow name: ", e); 199 } 200 } 201 return null; 202 } 203 204 /** Get changes within a timespan. */ 205 public List<Integer> getChangesForTimespan(Date start, Date end) 206 throws QueryException 207 { 208 return _getChangesForTimespan(start, end, null, null); 209 } 210 211 /** Get a list of all executions. */ 212 @Override 213 public List<Integer> getExecutions() throws QueryException 214 { 215 try 216 { 217 return _getIntResults(_psExecutions, 1); 218 } 219 catch(SQLException e) 220 { 221 throw new QueryException("Unable to query executions: ", e); 222 } 223 } 224 225 /** Get a list of all execution LSIDs. */ 226 @Override 227 public List<KeplerLSID> getExecutionLSIDs() throws QueryException { 228 List<KeplerLSID> execLsids = new ArrayList<KeplerLSID>(); 229 try 230 { 231 synchronized(_psExecutionLSIDs) 232 { 233 ResultSet result = null; 234 try 235 { 236 result = _psExecutionLSIDs.executeQuery(); 237 while (result.next()) 238 { 239 try { 240 KeplerLSID execLSID = new KeplerLSID(result.getString("lsid")); 241 if (!execLsids.contains(execLSID)){ 242 execLsids.add(execLSID); 243 } 244 } catch (Exception e) { 245 // TODO Auto-generated catch block 246 e.printStackTrace(); 247 } 248 } 249 } 250 finally 251 { 252 if(result != null) 253 { 254 result.close(); 255 } 256 } 257 } 258 } 259 catch(SQLException e) 260 { 261 throw new QueryException("Unable to query for execution LSIDs"); 262 } 263 return execLsids; 264 } 265 266 /** Get a list of executions for workflow(s) with tags that contain tagsSearchString 267 * (case insensitive) 268 */ 269 @Override 270 public List<Integer> getExecutionIdsForTags(String tagsSearchString) throws QueryException { 271 List<Integer> execIds = new ArrayList<Integer>(); 272 try 273 { 274 synchronized(_psExecutionIdsForTags) 275 { 276 tagsSearchString = tagsSearchString.toLowerCase(); 277 _psExecutionIdsForTags.setString(1, "%" + tagsSearchString + "%"); 278 ResultSet result = null; 279 try 280 { 281 result = _psExecutionIdsForTags.executeQuery(); 282 while (result.next()) 283 { 284 try { 285 int execId = result.getInt("wf_exec_id"); 286 if (!execIds.contains(execId)){ 287 execIds.add(execId); 288 } 289 } catch (Exception e) { 290 // TODO Auto-generated catch block 291 e.printStackTrace(); 292 } 293 } 294 } 295 finally 296 { 297 if(result != null) 298 { 299 result.close(); 300 } 301 } 302 } 303 } 304 catch(SQLException e) 305 { 306 throw new QueryException("Unable to query for execution ids for Tags:"+tagsSearchString); 307 } 308 return execIds; 309 } 310 311 @Override 312 public Map<NamedOntClass, String> getTagClassesForExecutionId(int execId) throws QueryException { 313 Map<NamedOntClass, String> tags = new HashMap<NamedOntClass, String>(); 314 try 315 { 316 synchronized(_psTagURNsForExecutionId) 317 { 318 _psTagURNsForExecutionId.setInt(1, execId); 319 ResultSet result = null; 320 try 321 { 322 result = _psTagURNsForExecutionId.executeQuery(); 323 while (result.next()) 324 { 325 try { 326 String type = result.getString("type"); //FIXME hardcoded col names 327 boolean isRemovable = (WorkflowRun.TAG_TYPE_RUN).equals(type); 328 String tagURI = result.getString("urn"); 329 // String ontologyURI = result.getString("ontology_uri"); 330 NamedOntClass cls = NamedOntClass.createNamedOntClassFromURI(tagURI); 331 cls.setRemovable(isRemovable); 332 if (!tags.containsKey(cls)) { 333 tags.put(cls, type); 334 } 335 } catch (Exception e) { 336 // TODO Auto-generated catch block 337 e.printStackTrace(); 338 } 339 } 340 } 341 finally 342 { 343 if(result != null) 344 { 345 result.close(); 346 } 347 } 348 } 349 } 350 catch(SQLException e) 351 { 352 throw new QueryException("Unable to query for tags for execution id:"+execId); 353 } 354 return tags; 355 } 356 357 /** Get the type of a tag, null if none */ 358 @Override 359 public String getTypeForTag(String conceptId) { 360 String type = null; 361 362 try{ 363 synchronized(_psTypeForTag) 364 { 365 _psTypeForTag.setString(1, conceptId); 366 ResultSet result = null; 367 try 368 { 369 result = _psTypeForTag.executeQuery(); 370 while (result.next()) 371 { 372 type = result.getString("type"); 373 } 374 } 375 finally 376 { 377 if(result != null) 378 { 379 result.close(); 380 } 381 } 382 } 383 } catch (SQLException e) { 384 // TODO Auto-generated catch block 385 e.printStackTrace(); 386 } 387 388 return type; 389 } 390 391 392 @Override 393 public List<String> getTagsForExecutionId(int execId) throws QueryException { 394 List<String> tags = new ArrayList<String>(); 395 try 396 { 397 synchronized(_psTagsForExecutionId) 398 { 399 _psTagsForExecutionId.setInt(1, execId); 400 ResultSet result = null; 401 try 402 { 403 result = _psTagsForExecutionId.executeQuery(); 404 while (result.next()) 405 { 406 try { 407 if (!tags.contains(result.getString("searchstring"))){ 408 tags.add(result.getString("searchstring")); 409 } 410 } catch (Exception e) { 411 // TODO Auto-generated catch block 412 e.printStackTrace(); 413 } 414 } 415 } 416 finally 417 { 418 if(result != null) 419 { 420 result.close(); 421 } 422 } 423 } 424 } 425 catch(SQLException e) 426 { 427 throw new QueryException("Unable to query for tags for execution id:"+execId); 428 } 429 return tags; 430 } 431 432 public List<String> getTagURNsForExecutionLSID(KeplerLSID execLSID) throws QueryException { 433 List<String> tags = new ArrayList<String>(); 434 try 435 { 436 synchronized(_psTagURNsForExecutionId) 437 { 438 _psTagURNsForExecutionId.setString(1, execLSID.toString()); 439 ResultSet result = null; 440 try 441 { 442 result = _psTagURNsForExecutionId.executeQuery(); 443 while (result.next()) 444 { 445 try { 446 if (!tags.contains(result.getString("urn"))) { 447 tags.add(result.getString("urn")); 448 } 449 } catch (Exception e) { 450 // TODO Auto-generated catch block 451 e.printStackTrace(); 452 } 453 } 454 } 455 finally 456 { 457 if(result != null) 458 { 459 result.close(); 460 } 461 } 462 } 463 } 464 catch(SQLException e) 465 { 466 throw new QueryException("Unable to query for tags for execution LSID:"+execLSID.toString()); 467 } 468 return tags; 469 } 470 471 /** Get workflow MoML for an execution, using execution id */ 472 @Override 473 public String getMoMLForExecution(int execId) throws QueryException 474 { 475 try 476 { 477 synchronized(_psMomlForExecutionId) 478 { 479 _psMomlForExecutionId.setInt(1, execId); 480 ResultSet result = null; 481 482 try 483 { 484 result = _psMomlForExecutionId.executeQuery(); 485 486 if(!result.next()) 487 { 488 throw new QueryException("No MoML found for execution " + 489 execId); 490 } 491 492 byte[] data = result.getBytes(1); 493 return _changeUnnamedWorkflow(new String(data)); 494 } 495 finally 496 { 497 if(result != null) 498 { 499 result.close(); 500 } 501 } 502 } 503 } 504 catch(SQLException e) 505 { 506 throw new QueryException("Unable to query for moml: ", e); 507 } 508 } 509 510 /** Get workflow MoML for an execution, using execution lsid. */ 511 @Override 512 public String getMoMLForExecution(KeplerLSID lsid) throws QueryException 513 { 514 try 515 { 516 synchronized(_psMomlForExecutionLSID) 517 { 518 _psMomlForExecutionLSID.setString(1, lsid.toString()); 519 ResultSet result = null; 520 521 try 522 { 523 result = _psMomlForExecutionLSID.executeQuery(); 524 525 if(!result.next()) 526 { 527 throw new QueryException("No Workflow MoML found for Run with KeplerLSID " + 528 lsid.toString()); 529 } 530 531 byte[] data = result.getBytes(1); 532 return _changeUnnamedWorkflow(new String(data)); 533 } 534 finally 535 { 536 if(result != null) 537 { 538 result.close(); 539 } 540 } 541 } 542 } 543 catch(SQLException e) 544 { 545 throw new QueryException("Unable to query for moml associated with run lsid: ", e); 546 } 547 } 548 549 //TODO revisit when putting runs in diff dirs, where each dir might 550 // want a separate copy of the same wf. 551 /** Get workflow MoMLs for a list of execution lsids. Only returns one copy 552 * of any duplicates. 553 */ 554 @Override 555 public ArrayList<String> getMoMLForExecutionLSIDs(List<KeplerLSID> lsids) 556 { 557 //Note that we don't return duplicates (i.e. e.g. 2 runs using 1 wf) 558 ListIterator<KeplerLSID> i = lsids.listIterator(); 559 ArrayList<String> momls = new ArrayList<String>(); 560 while (i.hasNext()) 561 { 562 KeplerLSID j = i.next(); 563 try 564 { 565 String moml = getMoMLForExecution(j); 566 if (!momls.contains(moml)) 567 { 568 momls.add(moml); 569 } 570 571 } 572 catch(QueryException qe) 573 { 574 System.out.println("ERROR trying to getMoMLForExecution("+j+"): "+qe); 575 } 576 } 577 return momls; 578 } 579 580 581 /** Get executions within a timespan. */ 582 @Override 583 public List<Integer> getExecutionsForTimespan(Date start, Date end) 584 throws QueryException 585 { 586 return _getExecutionsForTimespan(start, end, null, null); 587 } 588 589 590 /** 591 * Get WorkflowRuns for a list of execution LSIDs 592 */ 593 @Override 594 public Map<KeplerLSID, WorkflowRun> getWorkflowRunsForExecutionLSIDs(List<KeplerLSID> executionLSIDs) 595 throws QueryException 596 { 597 //FIXME: hardcoded references to row names 598 599 Statement statement = null; 600 try 601 { 602 Map<KeplerLSID, WorkflowRun> workflowRuns = new LinkedHashMap<KeplerLSID, WorkflowRun>(); 603 604 if(executionLSIDs.isEmpty()) { 605 return workflowRuns; 606 } 607 608 // __psWorkflowRunsForExecutionLSIDs.setArray(1, execIds); 609 // Note1: Manually setting up this query since java.sql.Array is not designed for this. 610 // To solve such issues it's suggested setting up prepared statement with more ?'s 611 // than you think you'll ever need, set them all null, then set as many as you need. 612 // Not sure if that would really be better, so I'm not doing it currently. 613 // Could also instead just iterate across a number queries, but that 614 // seems less efficient. 615 StringBuilder execLSIDs = new StringBuilder(); 616 for (Iterator<KeplerLSID> i=executionLSIDs.iterator(); i.hasNext(); ) 617 { 618 execLSIDs.append("'"+i.next().toString()+"'"); 619 if(i.hasNext()) 620 { 621 execLSIDs.append(","); 622 } 623 } 624 String workflowStr = _dbType.getTableName("workflow"); 625 String wfExecStr = _dbType.getTableName("workflow_exec"); 626 String errorStr = _dbType.getTableName("error"); 627 628 // NOTE: user is a reserved column name in some RDBMS. 629 String userColumnStr = _dbType.getColumnName("user"); 630 631 String queryStr = 632 "SELECT wf.name as wf_name, wfexec.wf_full_lsid as wf_lsid," + 633 "wfexec." + userColumnStr + " as user, " + 634 "wfexec.id as wfexec_id, wfexec.start_time, " + 635 "wfexec.end_time, wfexec.lsid as exec_lsid, wfexec.host_id as host_id, " + 636 "wfexec.annotation as annotation, wfexec.derived_from as derived_from, " + 637 "wfexec.module_dependencies as module_dependencies, " + 638 "wfexec.type as type, " + 639 "err.id as error_id, err.message as error_message " + 640 "FROM " + workflowStr + " wf, " + wfExecStr + " wfexec " + 641 "LEFT JOIN " + errorStr + " err ON wfexec.id=err.exec_id " + 642 "WHERE wf.id=wfexec.wf_id AND wfexec.lsid in (" + execLSIDs + ")"; 643 644 statement = _dbType.getStatement(); 645 646 LinkedHashMap<Integer, String> errorMsgs = new LinkedHashMap<Integer, String>(); 647 648 ResultSet result = null; 649 try 650 { 651 result = statement.executeQuery(queryStr); 652 KeplerLSID lastExecLSID = null; 653 while(result.next()) 654 { 655 KeplerLSID execLSID = null; 656 try 657 { 658 execLSID = new KeplerLSID(result.getString("exec_lsid")); 659 } 660 catch(Exception e) 661 { 662 throw new QueryException("Error creating KeplerLSID for execution: ", e); 663 } 664 665 KeplerLSID wfLSID = null; 666 try 667 { 668 wfLSID = new KeplerLSID(result.getString("wf_lsid")); 669 } 670 catch(Exception e) 671 { 672 throw new QueryException("Error creating KeplerLSID for workflow: ", e); 673 } 674 675 int errorId; 676 677 if (!execLSID.equals(lastExecLSID)) 678 { 679 errorMsgs = new LinkedHashMap<Integer, String>(); 680 } 681 682 if (result.getString("error_message") != null) 683 { 684 errorId = Integer.parseInt(result.getString("error_id")); 685 errorMsgs.put(errorId, result.getString("error_message")); 686 } 687 688 Date startTime = result.getTimestamp("start_time"); 689 Date endTime = result.getTimestamp("end_time"); 690 691 // endTime may be null if not set 692 if(endTime == null) 693 { 694 endTime = new Date(0); 695 } 696 697 Long duration = (endTime.getTime() - startTime.getTime()) / numMillisecondsInASecond; 698 if (endTime.compareTo(startTime) < 0) 699 { 700 duration = -1L; 701 } 702 703 int execId = Integer.parseInt(result.getString("wfexec_id")); 704 // Note: in the case of resultSet that has multiple rows per exec, we just overwrite the entry in 705 // workflowRuns each time, each time with a more complete version of errorMessages. 706 // a cleaner soln would be to look-ahead and then use result.previous, but not all dbs support result.previous 707 // (e.g. hsqldb) 708 WorkflowRun run = null; 709 try 710 { 711 run = new WorkflowRun(execLSID, 712 result.getString("derived_from"), 713 result.getString("user"), 714 result.getString("wf_name"), 715 wfLSID, startTime, duration, execId, errorMsgs, 716 result.getString("host_id"), 717 result.getString("annotation"), 718 result.getString("module_dependencies"), 719 result.getString("type"), 720 getTagClassesForExecutionId(execId)); 721 } 722 catch(Exception e) 723 { 724 e.printStackTrace(); 725 throw new QueryException("Error creating WorkflowRun: ", e); 726 } 727 728 // note it's important to use run.getExecLSID() instead of execLSID here 729 // since WorkflowRun constructor may change the execLSID revision. 730 workflowRuns.put(run.getExecLSID(), run); 731 732 lastExecLSID = execLSID; 733 } 734 } 735 finally 736 { 737 if(result != null) 738 { 739 result.close(); 740 } 741 } 742 743 return workflowRuns; 744 } 745 catch(SQLException e) 746 { 747 e.printStackTrace(); 748 throw new QueryException("Unable to query workflow runs: ", e); 749 } 750 finally 751 { 752 if(statement != null) 753 { 754 try 755 { 756 statement.close(); 757 } 758 catch (SQLException e) 759 { 760 throw new QueryException("Unable to close statement: ", e); 761 } 762 } 763 } 764 } 765 766 @Override 767 public List<WorkflowRun> getWorkflowRunsForUser(String user) throws QueryException { 768 769 List<WorkflowRun> workflowRuns = new LinkedList<WorkflowRun>(); 770 771 String workflowStr = _dbType.getTableName("workflow"); 772 String wfExecStr = _dbType.getTableName("workflow_exec"); 773 String errorStr = _dbType.getTableName("error"); 774 775 // NOTE: user is a reserved column name in some RDBMS. 776 String userColumnStr = _dbType.getColumnName("user"); 777 778 String queryStr = 779 "SELECT wf.name as wf_name, wfexec.wf_full_lsid as wf_lsid," + 780 "wfexec." + userColumnStr + " as user, " + 781 "wfexec.id as wfexec_id, wfexec.start_time, " + 782 "wfexec.end_time, wfexec.lsid as exec_lsid, wfexec.host_id as host_id, " + 783 "wfexec.annotation as annotation, wfexec.derived_from as derived_from, " + 784 "wfexec.module_dependencies as module_dependencies, " + 785 "wfexec.type as type, " + 786 "err.id as error_id, err.message as error_message " + 787 "FROM " + workflowStr + " wf, " + wfExecStr + " wfexec " + 788 "LEFT JOIN " + errorStr + " err ON wfexec.id=err.exec_id " + 789 "WHERE wf.id=wfexec.wf_id AND wfexec.user = ?"; 790 791 try(PreparedStatement statement = _dbType.getPrepStatement(queryStr)) 792 { 793 statement.setString(1, user); 794 795 LinkedHashMap<Integer, String> errorMsgs = new LinkedHashMap<Integer, String>(); 796 797 try(ResultSet result = statement.executeQuery()) 798 { 799 KeplerLSID lastExecLSID = null; 800 while(result.next()) 801 { 802 KeplerLSID execLSID = null; 803 try 804 { 805 execLSID = new KeplerLSID(result.getString("exec_lsid")); 806 } 807 catch(Exception e) 808 { 809 throw new QueryException("Error creating KeplerLSID for execution: ", e); 810 } 811 812 KeplerLSID wfLSID = null; 813 try 814 { 815 wfLSID = new KeplerLSID(result.getString("wf_lsid")); 816 } 817 catch(Exception e) 818 { 819 throw new QueryException("Error creating KeplerLSID for workflow: ", e); 820 } 821 822 int errorId; 823 824 if (!execLSID.equals(lastExecLSID)) 825 { 826 errorMsgs = new LinkedHashMap<Integer, String>(); 827 } 828 829 if (result.getString("error_message") != null) 830 { 831 errorId = Integer.parseInt(result.getString("error_id")); 832 errorMsgs.put(errorId, result.getString("error_message")); 833 } 834 835 Date startTime = result.getTimestamp("start_time"); 836 Date endTime = result.getTimestamp("end_time"); 837 838 // endTime may be null if not set 839 if(endTime == null) 840 { 841 endTime = new Date(0); 842 } 843 844 Long duration = (endTime.getTime() - startTime.getTime()) / numMillisecondsInASecond; 845 if (endTime.compareTo(startTime) < 0) 846 { 847 duration = -1L; 848 } 849 850 int execId = Integer.parseInt(result.getString("wfexec_id")); 851 // Note: in the case of resultSet that has multiple rows per exec, we just overwrite the entry in 852 // workflowRuns each time, each time with a more complete version of errorMessages. 853 // a cleaner soln would be to look-ahead and then use result.previous, but not all dbs support result.previous 854 // (e.g. hsqldb) 855 WorkflowRun run = null; 856 try 857 { 858 run = new WorkflowRun(execLSID, 859 result.getString("derived_from"), 860 result.getString("user"), 861 result.getString("wf_name"), 862 wfLSID, startTime, duration, execId, errorMsgs, 863 result.getString("host_id"), 864 result.getString("annotation"), 865 result.getString("module_dependencies"), 866 result.getString("type"), 867 getTagClassesForExecutionId(execId)); 868 } 869 catch(Exception e) 870 { 871 e.printStackTrace(); 872 throw new QueryException("Error creating WorkflowRun: ", e); 873 } 874 875 // note it's important to use run.getExecLSID() instead of execLSID here 876 // since WorkflowRun constructor may change the execLSID revision. 877 workflowRuns.add(run); 878 879 lastExecLSID = execLSID; 880 } 881 } 882 883 return workflowRuns; 884 } 885 catch(SQLException e) 886 { 887 e.printStackTrace(); 888 throw new QueryException("Unable to query workflow runs: ", e); 889 } 890 } 891 892 /** Get a list of executions for a specific workflow. */ 893 @Override 894 public List<Integer> getExecutionsForWorkflow(String workflow) 895 throws QueryException 896 { 897 try 898 { 899 _psExecutionsForWorkflow.setString(1, workflow); 900 return _getIntResults(_psExecutionsForWorkflow, 1); 901 } 902 catch(SQLException e) 903 { 904 throw new QueryException("Unable to query executions for " + 905 "workflow " + workflow + ": ", e); 906 } 907 } 908 909 /** Get the execution ids for a specific exec LSID. If no execution 910 * exists, returns null. 911 */ 912 @Override 913 public Integer getExecutionForExecutionLSID(KeplerLSID execLSID) 914 throws QueryException 915 { 916 try 917 { 918 _psExecutionForExecutionLSID.setString(1, execLSID.toString()); 919 ResultSet result = null; 920 try 921 { 922 int retval; 923 result = _psExecutionForExecutionLSID.executeQuery(); 924 if(! result.next() || (retval = result.getInt(1)) == 0) 925 { 926 return null; 927 } 928 return retval; 929 } 930 finally 931 { 932 if(result != null) 933 { 934 result.close(); 935 } 936 } 937 } 938 catch(SQLException e) 939 { 940 throw new QueryException("Unable to query executions for " + 941 "run " + execLSID + ": ", e); 942 } 943 } 944 945 /** Get execution id for an execution LSID without revision. 946 * If no execution exists, returns null. 947 */ 948 @Override 949 public Integer getExecutionForExecutionLSIDWithoutRevision( 950 String execLSIDWithoutRevision) throws QueryException { 951 try 952 { 953 _psExecutionForExecutionLSIDWithoutRevision.setString(1, execLSIDWithoutRevision+":%"); 954 ResultSet result = null; 955 try 956 { 957 int retval; 958 result = _psExecutionForExecutionLSIDWithoutRevision.executeQuery(); 959 if(! result.next() || (retval = result.getInt(1)) == 0) 960 { 961 return null; 962 } 963 return retval; 964 } 965 finally 966 { 967 if(result != null) 968 { 969 result.close(); 970 } 971 } 972 } 973 catch(SQLException e) 974 { 975 throw new QueryException("Unable to query executions for " + 976 "run " + execLSIDWithoutRevision + ": ", e); 977 } 978 } 979 980 /** Get execution id for execution that has the given LSID as its 981 * oldest referral. 982 */ 983 @Override 984 public Integer getExecutionForOldestReferralExecutionLSIDWithoutRevision( 985 String execLSIDWithoutRevision) throws QueryException 986 { 987 try 988 { 989 990 // Even though what we really want to match on is 991 // the last and this could potentially match on one 992 // in the middle, that state is currently possible, so this regex should be ok: 993 _psExecutionForOldestReferralExecutionLSIDWithoutRevision.setString(1, "%"+execLSIDWithoutRevision+":%"); 994 ResultSet result = null; 995 try 996 { 997 int retval; 998 result = _psExecutionForOldestReferralExecutionLSIDWithoutRevision.executeQuery(); 999 if(! result.next() || (retval = result.getInt(1)) == 0) 1000 { 1001 return null; 1002 } 1003 return retval; 1004 } 1005 finally 1006 { 1007 if(result != null) 1008 { 1009 result.close(); 1010 } 1011 } 1012 } 1013 catch(SQLException e) 1014 { 1015 throw new QueryException("Unable to query executions for " + 1016 "run " + execLSIDWithoutRevision + ": ", e); 1017 } 1018 } 1019 1020 /** Get the execution LSID for a specific execution id. If no execution 1021 * exists, returns null. 1022 */ 1023 @Override 1024 public KeplerLSID getExecutionLSIDForExecution(Integer execId) 1025 throws QueryException 1026 { 1027 synchronized(_psExecutionLSIDForExecution) { 1028 try 1029 { 1030 _psExecutionLSIDForExecution.setInt(1, execId); 1031 try(ResultSet result = _psExecutionLSIDForExecution.executeQuery();) 1032 { 1033 if(!result.next()) 1034 { 1035 return null; 1036 } 1037 KeplerLSID executionLSID = new KeplerLSID(result.getString("lsid")); 1038 return executionLSID; 1039 } catch (Exception e) { 1040 // TODO Auto-generated catch block 1041 e.printStackTrace(); 1042 } 1043 } 1044 catch(SQLException e) 1045 { 1046 throw new QueryException("Unable to query execution lsids for " + 1047 "execution id " + execId + ": ", e); 1048 } 1049 } 1050 return null; 1051 } 1052 1053 /** Get a list of executions for workflow(s) with names that contain text (case insensitive). */ 1054 public List<Integer> getExecutionsForWorkflowNameContains(String text) 1055 throws QueryException 1056 { 1057 try 1058 { 1059 text = text.toLowerCase(); 1060 _psExecutionsForWorkflowNameContains.setString(1, "%" + text + "%"); 1061 return _getIntResults(_psExecutionsForWorkflowNameContains, 1); 1062 } 1063 catch(SQLException e) 1064 { 1065 throw new QueryException("Unable to query executions for " + 1066 "workflows with names that contain: " + text + ": ", e); 1067 } 1068 } 1069 1070 /** Get a list of executions for workflow(s) that match Workflow Run Manager (WRM) search criteria.*/ 1071 @Override 1072 public List<Integer> getExecutionsForWorkflowRuns(String workflowName, String userName) 1073 throws QueryException 1074 { 1075 try 1076 { 1077 workflowName = workflowName.toLowerCase(); 1078 _psExecutionsForWorkflowRuns.setString(1, "%" + workflowName + "%"); 1079 userName = userName.toLowerCase(); 1080 _psExecutionsForWorkflowRuns.setString(2, "%" + userName + "%"); 1081 return _getIntResults(_psExecutionsForWorkflowRuns, 1); 1082 } 1083 catch(SQLException e) 1084 { 1085 throw new QueryException("Unable to query executions for " + 1086 "workflows with names that contain: " + workflowName + 1087 ", usernames that contain: + "+ userName + ": ", e); 1088 } 1089 } 1090 1091 /** Get a list of executions for workflow(s) that match Workflow Run Manager (WRM) search criteria.*/ 1092 @Override 1093 public List<Integer> getExecutionsForWorkflowRuns(String workflowName, 1094 String userName, Date after, Date before, int execIdAfter, 1095 int execIdBefore) 1096 throws QueryException 1097 { 1098 try 1099 { 1100 workflowName = workflowName.toLowerCase(); 1101 _psExecutionsForWorkflowRuns2.setString(1, "%" + workflowName + "%"); 1102 userName = userName.toLowerCase(); 1103 _psExecutionsForWorkflowRuns2.setString(2, "%" + userName + "%"); 1104 _psExecutionsForWorkflowRuns2.setTimestamp(3, 1105 new Timestamp(after.getTime())); 1106 _psExecutionsForWorkflowRuns2.setTimestamp(4, 1107 new Timestamp(before.getTime())); 1108 _psExecutionsForWorkflowRuns2.setInt(5, execIdAfter); 1109 _psExecutionsForWorkflowRuns2.setInt(6, execIdBefore); 1110 1111 return _getIntResults(_psExecutionsForWorkflowRuns2, 1); 1112 } 1113 catch(SQLException e) 1114 { 1115 throw new QueryException("Unable to query executions for " + 1116 "workflows with names that contain: " + workflowName + 1117 ", usernames that contain: + "+ userName + 1118 ", between " + after + " and "+ before + 1119 ", with execId between "+execIdAfter + " and " + execIdBefore+": ", e); 1120 } 1121 } 1122 1123 /** Get a list of executions for workflow(s) that match Workflow Run Manager (WRM) search criteria.*/ 1124 @Override 1125 public List<KeplerLSID> getExecutionLSIDsForWorkflowRuns( 1126 String workflowName, String userName, Date after, Date before, 1127 int execIdAfter, int execIdBefore) throws QueryException { 1128 List<KeplerLSID> execLSIDs = new ArrayList<KeplerLSID>(); 1129 1130 try{ 1131 workflowName = workflowName.toLowerCase(); 1132 _psExecutionLSIDsForWorkflowRuns.setString(1, "%" + workflowName + "%"); 1133 userName = userName.toLowerCase(); 1134 _psExecutionLSIDsForWorkflowRuns.setString(2, "%" + userName + "%"); 1135 _psExecutionLSIDsForWorkflowRuns.setTimestamp(3, 1136 new Timestamp(after.getTime())); 1137 _psExecutionLSIDsForWorkflowRuns.setTimestamp(4, 1138 new Timestamp(before.getTime())); 1139 _psExecutionLSIDsForWorkflowRuns.setInt(5, execIdAfter); 1140 _psExecutionLSIDsForWorkflowRuns.setInt(6, execIdBefore); 1141 1142 ResultSet result = null; 1143 try 1144 { 1145 result = _psExecutionLSIDsForWorkflowRuns.executeQuery(); 1146 while (result.next()) 1147 { 1148 try { 1149 KeplerLSID execLSID = new KeplerLSID(result.getString("lsid")); 1150 if (!execLSIDs.contains(execLSID)){ 1151 execLSIDs.add(execLSID); 1152 } 1153 } catch (Exception e) { 1154 e.printStackTrace(); 1155 } 1156 } 1157 } 1158 finally 1159 { 1160 if(result != null) 1161 { 1162 result.close(); 1163 } 1164 } 1165 } 1166 catch(SQLException e) 1167 { 1168 throw new QueryException("Unable to query executions for " + 1169 "workflows with names that contain: " + workflowName + 1170 ", usernames that contain: + "+ userName + 1171 ", between " + after + " and "+ before + 1172 ", with execId between "+execIdAfter + " and " + execIdBefore+": ", e); 1173 } 1174 1175 return execLSIDs; 1176 } 1177 1178 /** Get a list of executions for workflow(s) that match Workflow Run Manager (WRM) search criteria 1179 * before a date. 1180 * */ 1181 @Override 1182 public List<Integer> getExecutionsForWorkflowRunsBefore(String workflowName, String userName, Date before) 1183 throws QueryException 1184 { 1185 try 1186 { 1187 workflowName = workflowName.toLowerCase(); 1188 _psExecutionsForWorkflowRunsBefore.setString(1, "%" + workflowName + "%"); 1189 userName = userName.toLowerCase(); 1190 _psExecutionsForWorkflowRunsBefore.setString(2, "%" + userName + "%"); 1191 _psExecutionsForWorkflowRunsBefore.setTimestamp(3, 1192 new Timestamp(before.getTime())); 1193 return _getIntResults(_psExecutionsForWorkflowRunsBefore, 1); 1194 } 1195 catch(SQLException e) 1196 { 1197 throw new QueryException("Unable to query executions for " + 1198 "workflows with names that contain: " + workflowName + 1199 ", usernames that contain: + "+ userName + 1200 ", before " + before + ": ", e); 1201 } 1202 } 1203 1204 /** Get a list of executions for workflow(s) that match Workflow Run Manager (WRM) search criteria 1205 * after a date. 1206 * */ 1207 @Override 1208 public List<Integer> getExecutionsForWorkflowRunsAfter(String workflowName, String userName, Date after) 1209 throws QueryException 1210 { 1211 try 1212 { 1213 workflowName = workflowName.toLowerCase(); 1214 _psExecutionsForWorkflowRunsAfter.setString(1, "%" + workflowName + "%"); 1215 userName = userName.toLowerCase(); 1216 _psExecutionsForWorkflowRunsAfter.setString(2, "%" + userName + "%"); 1217 _psExecutionsForWorkflowRunsAfter.setTimestamp(3, 1218 new Timestamp(after.getTime())); 1219 return _getIntResults(_psExecutionsForWorkflowRunsAfter, 1); 1220 } 1221 catch(SQLException e) 1222 { 1223 throw new QueryException("Unable to query executions for " + 1224 "workflows with names that contain: " + workflowName + 1225 ", usernames that contain: + "+ userName + 1226 ", after " + after + ": ", e); 1227 } 1228 } 1229 1230 /** Get a list of executions for workflow(s) that match Workflow Run Manager (WRM) search criteria 1231 * "at" a date. We treat this date as a string so we can match using LIKE 'date%'. 1232 * */ 1233 public List<Integer> getExecutionsForWorkflowRunsAt(String workflowName, String userName, String date) 1234 throws QueryException 1235 { 1236 try 1237 { 1238 workflowName = workflowName.toLowerCase(); 1239 _psExecutionsForWorkflowRunsAt.setString(1, "%" + workflowName + "%"); 1240 userName = userName.toLowerCase(); 1241 _psExecutionsForWorkflowRunsAt.setString(2, "%" + userName + "%"); 1242 _psExecutionsForWorkflowRunsAt.setString(3, date + "%"); //TODO fix this 1243 return _getIntResults(_psExecutionsForWorkflowRunsAt, 1); 1244 } 1245 catch(SQLException e) 1246 { 1247 throw new QueryException("Unable to query executions for " + 1248 "workflows with names that contain: " + workflowName + 1249 ", usernames that contain: + "+ userName + 1250 ", at " + date + ": ", e); 1251 } 1252 } 1253 1254 /** Get a list of executions for a specific execution annotation. */ 1255 @Override 1256 public List<Integer> getExecutionsForAnnotation(String annotation) 1257 throws QueryException 1258 { 1259 try 1260 { 1261 _psExecutionsForAnnotation.setString(1, annotation); 1262 return _getIntResults(_psExecutionsForAnnotation, 1); 1263 } 1264 catch(SQLException e) 1265 { 1266 throw new QueryException("Unable to query executions for " + 1267 "annotation " + annotation + ": ", e); 1268 } 1269 } 1270 1271 /** Get the start and end timestamps of an execution. 1272 * @param execId the execution id 1273 * @return a two-element array: the first entry is the start timestamp, 1274 * and the second is the end timestamp. If the execution id is not found, 1275 * returns null. 1276 */ 1277 @Override 1278 public Date[] getTimestampsForExecution(int execId) 1279 throws QueryException 1280 { 1281 synchronized(_psTimestampsForExecution) { 1282 try 1283 { 1284 _psTimestampsForExecution.setInt(1, execId); 1285 try(ResultSet result = _psTimestampsForExecution.executeQuery();) 1286 { 1287 if(result.next()) 1288 { 1289 Date[] retval = new Date[2]; 1290 retval[0] = result.getTimestamp("start_time"); 1291 retval[1] = result.getTimestamp("end_time"); 1292 return retval; 1293 } 1294 } 1295 } 1296 catch(SQLException e) 1297 { 1298 throw new QueryException("Error querying timestampts for execution " + execId, e); 1299 } 1300 } 1301 return null; 1302 } 1303 1304 /** Get the last execution for a workflow. NOTE: the LSID revision 1305 * is ignored. 1306 * @param lsid the workflow lsid. 1307 * @return if workflow has been executed, the last execution id. 1308 * otherwise, returns null. 1309 */ 1310 @Override 1311 public Integer getLastExecutionForWorkflow(KeplerLSID lsid) 1312 throws QueryException 1313 { 1314 synchronized(_psLastExecutionForWorkflowLSID) { 1315 try 1316 { 1317 _psLastExecutionForWorkflowLSID.setString(1, 1318 lsid.toStringWithoutRevision()); 1319 try(ResultSet result = _psLastExecutionForWorkflowLSID.executeQuery();) 1320 { 1321 if(!result.next()) { 1322 return null; 1323 } 1324 int retval = result.getInt(1); 1325 if(retval == 0) { 1326 return null; 1327 } 1328 return Integer.valueOf(retval); 1329 } 1330 } 1331 catch(SQLException e) 1332 { 1333 throw new QueryException("Unable to query last workflow " + 1334 "execution: ", e); 1335 } 1336 } 1337 } 1338 1339 /** Get the last execution for a workflow. 1340 * @param workflow the workflow name 1341 * @return if workflow has been executed, the last execution id. 1342 * otherwise, returns null. 1343 */ 1344 @Override 1345 public Integer getLastExecutionForWorkflow(String workflow) 1346 throws QueryException 1347 { 1348 try 1349 { 1350 _psLastExecutionForWorkflow.setString(1, workflow); 1351 ResultSet result = null; 1352 try 1353 { 1354 int retval; 1355 result = _psLastExecutionForWorkflow.executeQuery(); 1356 if(! result.next() || (retval = result.getInt(1))== 0) 1357 { 1358 return null; 1359 } 1360 return retval; 1361 } 1362 finally 1363 { 1364 if(result != null) 1365 { 1366 result.close(); 1367 } 1368 } 1369 } 1370 catch(SQLException e) 1371 { 1372 throw new QueryException("Unable to query last workflow " + 1373 "execution: ", e); 1374 } 1375 } 1376 1377 /** Get the last execution LSID for a workflow. 1378 * @param workflow the workflow name. 1379 * @return execution lsid 1380 */ 1381 @Override 1382 public KeplerLSID getLastExecutionLSIDForWorkflow(String workflow) 1383 throws QueryException 1384 { 1385 try 1386 { 1387 _psLastExecutionLSIDForWorkflowName.setString(1, workflow); 1388 ResultSet result = null; 1389 try 1390 { 1391 result = _psLastExecutionLSIDForWorkflowName.executeQuery(); 1392 if(! result.next()) 1393 { 1394 throw new QueryException("No executions found for " + 1395 "workflow " + workflow); 1396 } 1397 String lsidStr = result.getString(1); 1398 return new KeplerLSID(lsidStr); 1399 } 1400 finally 1401 { 1402 if(result != null) 1403 { 1404 result.close(); 1405 } 1406 } 1407 } 1408 catch(Exception e) 1409 { 1410 throw new QueryException("Unable to query last workflow " + 1411 "execution: ", e); 1412 } 1413 } 1414 1415 /** Get the last execution LSID for a workflow. 1416 * @param lsid the workflow lsid. 1417 * @return execution lsid 1418 */ 1419 @Override 1420 public KeplerLSID getLastExecutionLSIDForWorkflow(KeplerLSID lsid) 1421 throws QueryException 1422 { 1423 try 1424 { 1425 _psLastExecutionLSIDForWorkflowLSID.setString(1, lsid.toStringWithoutRevision()); 1426 ResultSet result = null; 1427 try 1428 { 1429 result = _psLastExecutionLSIDForWorkflowLSID.executeQuery(); 1430 if(! result.next()) 1431 { 1432 throw new QueryException("No executions found for " + 1433 "workflow LSID " + lsid); 1434 } 1435 String lsidStr = result.getString(1); 1436 return new KeplerLSID(lsidStr); 1437 } 1438 finally 1439 { 1440 if(result != null) 1441 { 1442 result.close(); 1443 } 1444 } 1445 } 1446 catch(Exception e) 1447 { 1448 throw new QueryException("Unable to query last workflow " + 1449 "execution: ", e); 1450 } 1451 } 1452 1453 1454 /** Get the error for an execution. Returns null if no error message 1455 * was found. NOTE: returning null is not an indication if the 1456 * execution had an error. 1457 * @see isErrorForExecution 1458 * @param lsid the workflow execution lsid. 1459 */ 1460 @Override 1461 public String getErrorForExecution(KeplerLSID lsid) throws QueryException 1462 { 1463 String retval = null; 1464 1465 try 1466 { 1467 _psErrorForExecution.setString(1, lsid.toString()); 1468 ResultSet result = null; 1469 1470 try 1471 { 1472 result = _psErrorForExecution.executeQuery(); 1473 if(result.next()) 1474 { 1475 retval = result.getString(1); 1476 } 1477 } 1478 finally 1479 { 1480 if(result != null) 1481 { 1482 result.close(); 1483 } 1484 } 1485 } 1486 catch(SQLException e) 1487 { 1488 throw new QueryException("Error querying workflow error: ", e); 1489 } 1490 1491 return retval; 1492 } 1493 1494 /** Returns true if the execution had an error. */ 1495 @Override 1496 public boolean isErrorForExecution(KeplerLSID executionLSID) throws QueryException 1497 { 1498 try 1499 { 1500 ResultSet result = null; 1501 try 1502 { 1503 _psDoesExecutionHaveError.setString(1, executionLSID.toString()); 1504 result = _psDoesExecutionHaveError.executeQuery(); 1505 return result.next(); 1506 } 1507 finally 1508 { 1509 if(result != null) 1510 { 1511 result.close(); 1512 } 1513 } 1514 } 1515 catch(SQLException e) 1516 { 1517 throw new QueryException("Unable to query if execution has an error: ", e); 1518 } 1519 } 1520 1521 /** See if an execution appears to be imported. */ 1522 @Override 1523 public boolean isImportedExecution(KeplerLSID executionLSID) throws QueryException 1524 { 1525 try 1526 { 1527 ResultSet result = null; 1528 try 1529 { 1530 _psIsExecutionImported.setString(1, executionLSID.toString()); 1531 result = _psIsExecutionImported.executeQuery(); 1532 // if there are rows in the query, then the run was not 1533 // imported 1534 return (!result.next()); 1535 } 1536 finally 1537 { 1538 if(result != null) 1539 { 1540 result.close(); 1541 } 1542 } 1543 } 1544 catch(SQLException e) 1545 { 1546 throw new QueryException("Unable to query if execution was imported:", e); 1547 } 1548 } 1549 1550 /** Get a list of executions corresponding to a specific type. */ 1551 @Override 1552 public List<KeplerLSID> getExecutionsForType(WorkflowRun.type type) throws QueryException 1553 { 1554 ResultSet result = null; 1555 try 1556 { 1557 try 1558 { 1559 List<KeplerLSID> retval = new LinkedList<KeplerLSID>(); 1560 _psExecutionsForType.setString(1, type.toString()); 1561 result = _psExecutionsForType.executeQuery(); 1562 while(result.next()) 1563 { 1564 retval.add(new KeplerLSID(result.getString(1))); 1565 } 1566 return retval; 1567 } 1568 finally 1569 { 1570 if(result != null) 1571 { 1572 result.close(); 1573 } 1574 } 1575 } 1576 catch(Exception e) 1577 { 1578 throw new QueryException("Unable to query executions for type: ", e); 1579 } 1580 } 1581 1582 /** Get an sequence of tokens for an execution. 1583 * @param execId the execution id 1584 * @param portId the port id. If null, returns the ids of 1585 * tokens read in entire execution. 1586 * @param last if true, the sequence starts at the last token created 1587 * and goes backwards to the first; otherwise the sequence starts at 1588 * the first. 1589 */ 1590 @Override 1591 public List<Integer> getTokensForExecution(int execId, Integer portId, boolean last) 1592 throws QueryException 1593 { 1594 List<Integer> list = new LinkedList<Integer>(); 1595 1596 try 1597 { 1598 ResultSet result = null; 1599 try 1600 { 1601 if (portId != null) 1602 { 1603 _psEntityTokensForExecution.setInt(1, execId); 1604 _psEntityTokensForExecution.setInt(2, portId); 1605 _psEntityTokensForExecution.setInt(3, execId); 1606 _psEntityTokensForExecution.setInt(4, portId); 1607 result = _psEntityTokensForExecution.executeQuery(); 1608 } 1609 else 1610 { 1611 _psTokensForExecution.setInt(1, execId); 1612 result = _psTokensForExecution.executeQuery(); 1613 } 1614 while(result.next()) 1615 { 1616 list.add(result.getInt(1)); 1617 } 1618 } 1619 finally 1620 { 1621 if(result != null) 1622 { 1623 result.close(); 1624 } 1625 } 1626 } 1627 catch(SQLException e) 1628 { 1629 throw new QueryException("Unable to retrieve for tokens: ", e); 1630 } 1631 1632 /* 1633 if(list.size() == 0) 1634 { 1635 throw new QueryException("No tokens found for execution " + execId); 1636 } 1637 */ 1638 1639 Integer[] array = list.toArray(new Integer[0]); 1640 Arrays.sort(array); 1641 1642 LinkedList<Integer> retval = new LinkedList<Integer>(); 1643 1644 for(int i = 0; i < array.length; i++) 1645 { 1646 if(last) 1647 { 1648 retval.addFirst(array[i]); 1649 } 1650 else 1651 { 1652 retval.addLast(array[i]); 1653 } 1654 } 1655 return retval; 1656 } 1657 1658 /** Get the firing id(s) of the actor(s) that read or wrote a token. 1659 * @param tokenId the token id 1660 * @param read If true, return the actor(s) firing id(s) that read 1661 * the token. Otherwise, return the actor firing that wrote the token. 1662 * */ 1663 @Override 1664 public List<Integer> getActorFiringForToken(int tokenId, boolean read) 1665 throws QueryException 1666 { 1667 try 1668 { 1669 List<Integer> retval; 1670 1671 if(read) 1672 { 1673 synchronized(_psActorFiringsForTokenRead) 1674 { 1675 _psActorFiringsForTokenRead.setInt(1, tokenId); 1676 retval = _getIntResults(_psActorFiringsForTokenRead, 1); 1677 } 1678 } 1679 else 1680 { 1681 retval = new LinkedList<Integer>(); 1682 1683 synchronized(_psActorFiringForTokenWrite) 1684 { 1685 _psActorFiringForTokenWrite.setInt(1, tokenId); 1686 ResultSet result = null; 1687 1688 try 1689 { 1690 result = 1691 _psActorFiringForTokenWrite.executeQuery(); 1692 1693 // make sure a firing produced this token 1694 if(!result.next()) 1695 { 1696 throw new QueryException("No firing produced token " + 1697 tokenId); 1698 } 1699 1700 retval.add(result.getInt(1)); 1701 } 1702 finally 1703 { 1704 if(result != null) 1705 { 1706 result.close(); 1707 } 1708 } 1709 } 1710 } 1711 1712 return retval; 1713 } 1714 catch(SQLException e) 1715 { 1716 throw new QueryException("Unable to query for actor firing: ", e); 1717 } 1718 } 1719 1720 /** Get tokens for a firing. 1721 * @param fireId the firing id 1722 * @param read if true, get the tokens read; otherwise get the tokens 1723 * written. 1724 */ 1725 @Override 1726 public List<Integer> getTokensForFiring(int fireId, boolean read) 1727 throws QueryException 1728 { 1729 PreparedStatement prep; 1730 if(read) 1731 { 1732 prep = _psTokensReadForFiring; 1733 } 1734 else 1735 { 1736 prep = _psTokensWrittenForFiring; 1737 } 1738 1739 synchronized(prep) { 1740 try 1741 { 1742 prep.setInt(1, fireId); 1743 return _getIntResults(prep, 1); 1744 } 1745 catch(SQLException e) 1746 { 1747 throw new QueryException("Unable to query tokens for firing id: ", e); 1748 } 1749 } 1750 } 1751 1752 /** Get the value of a token. */ 1753 @Override 1754 public String getTokenValue(int tokenId) throws QueryException 1755 { 1756 String dataId = null; 1757 String tokenValue; 1758 synchronized(_psPortEventData) { 1759 try 1760 { 1761 _psPortEventData.setInt(1, tokenId); 1762 try(ResultSet result = _psPortEventData.executeQuery();) 1763 { 1764 if(!result.next()) { 1765 throw new QueryException("Token not found: " + tokenId); 1766 } 1767 tokenValue = result.getString(1); 1768 if(tokenValue == null) { 1769 dataId = result.getString(2); 1770 } 1771 } 1772 } 1773 catch(SQLException e) 1774 { 1775 throw new QueryException("Unable to query token value from port_event table: ", e); 1776 } 1777 } 1778 1779 if(dataId == null) { 1780 if(tokenValue == null) { 1781 throw new QueryException("No value found for token " + tokenId); 1782 } 1783 return tokenValue; 1784 } else { 1785 synchronized(_psDataContents) { 1786 //System.out.println("querying from data"); 1787 try { 1788 _psDataContents.setString(1, dataId); 1789 try(ResultSet result = _psDataContents.executeQuery();) { 1790 if(!result.next()) { 1791 throw new QueryException("Data md5 not found: " + dataId); 1792 } 1793 return new String(result.getBytes(1)); 1794 } 1795 } catch(SQLException e) { 1796 throw new QueryException("Unable to query token value from data table: ", e); 1797 } 1798 } 1799 } 1800 } 1801 1802 /** Get the type of a token. */ 1803 @Override 1804 public String getTokenType(int tokenId) throws QueryException 1805 { 1806 synchronized(_psTokenType) { 1807 try 1808 { 1809 _psTokenType.setInt(1, tokenId); 1810 try(ResultSet result = _psTokenType.executeQuery();) 1811 { 1812 if(!result.next()) 1813 { 1814 throw new QueryException("Token not found: " + tokenId); 1815 } 1816 return result.getString(1); 1817 } 1818 } 1819 catch(SQLException e) 1820 { 1821 throw new QueryException("Unable to query token type: ", e); 1822 } 1823 } 1824 } 1825 1826 /** Get the channel that a token was read or written on. 1827 * @param tokenId the token id 1828 * @param read if true, return the channel the token was read on. 1829 * otherwise, return the channel the token was written on. 1830 * @param fireId the actor firing id. can be null for writes, but 1831 * must be specified for reads. 1832 * @return the channel the token was read or written on. 1833 */ 1834 @Override 1835 public Integer getChannelForToken(int tokenId, boolean read, Integer fireId) 1836 throws QueryException { 1837 1838 PreparedStatement preparedStatement; 1839 if(read) { 1840 preparedStatement = _psChannelForTokenRead; 1841 } else { 1842 preparedStatement = _psChannelForTokenWrite; 1843 } 1844 1845 synchronized(preparedStatement) { 1846 try { 1847 preparedStatement.setInt(1, tokenId); 1848 if(read) { 1849 preparedStatement.setInt(2, fireId); 1850 } 1851 try(ResultSet result = preparedStatement.executeQuery();) { 1852 if(result.next()) { 1853 return result.getInt(1); 1854 } 1855 } 1856 } catch (SQLException e) { 1857 throw new QueryException("Error querying read/write channel.", e); 1858 } 1859 } 1860 return null; 1861 } 1862 1863 /** Get the id of entity. If workflow or entity is not found, returns null. 1864 * @param entityName name of entity. 1865 * @param lsid the workflow LSID. NOTE: the revision is ignored. 1866 */ 1867 @Override 1868 public Integer getEntityId(String entityName, KeplerLSID lsid) 1869 throws QueryException 1870 { 1871 try 1872 { 1873 _psEntityIdLSID.setString(1, entityName); 1874 _psEntityIdLSID.setString(2, lsid.toStringWithoutRevision()); 1875 ResultSet result = null; 1876 try 1877 { 1878 int retval; 1879 result = _psEntityIdLSID.executeQuery(); 1880 if(!result.next() || (retval = result.getInt(1)) == 0) 1881 { 1882 return null; 1883 } 1884 return retval; 1885 } 1886 finally 1887 { 1888 if(result != null) 1889 { 1890 result.close(); 1891 } 1892 } 1893 } 1894 catch(SQLException e) 1895 { 1896 throw new QueryException("Unable to query entity id: ", e); 1897 } 1898 } 1899 1900 /** Get the id of entity. If workflow or entity is not found, returns null. 1901 * @param entityName the name of the entity. 1902 * @param workflowName the name of the workflow. 1903 */ 1904 @Override 1905 public Integer getEntityId(String entityName, String workflowName) 1906 throws QueryException 1907 { 1908 try 1909 { 1910 _psEntityId.setString(1, entityName); 1911 _psEntityId.setString(2, workflowName); 1912 ResultSet result = null; 1913 try 1914 { 1915 int retval; 1916 result = _psEntityId.executeQuery(); 1917 if(!result.next() || (retval = result.getInt(1)) == 0) 1918 { 1919 return null; 1920 } 1921 1922 return retval; 1923 } 1924 finally 1925 { 1926 if(result != null) 1927 { 1928 result.close(); 1929 } 1930 } 1931 } 1932 catch(SQLException e) 1933 { 1934 throw new QueryException("Unable to query entity id: ", e); 1935 } 1936 } 1937 1938 @Override 1939 public String getEntityType(Integer entityId) throws QueryException 1940 { 1941 try 1942 { 1943 _psEntityType.setInt(1, entityId); 1944 ResultSet result = null; 1945 try 1946 { 1947 result = _psEntityType.executeQuery(); 1948 if(!result.next()) 1949 { 1950 throw new QueryException("Entity not found: " + entityId); 1951 } 1952 1953 return result.getString(1); 1954 } 1955 finally 1956 { 1957 if(result != null) 1958 { 1959 result.close(); 1960 } 1961 } 1962 } 1963 catch(SQLException e) 1964 { 1965 throw new QueryException("Unable to query entity type: ", e); 1966 } 1967 } 1968 1969 1970 @Override 1971 public Integer getEntityWorkflowId(Integer entityId) throws QueryException 1972 { 1973 try 1974 { 1975 _psEntityWorkflowId.setInt(1, entityId); 1976 ResultSet result = null; 1977 try 1978 { 1979 result = _psEntityWorkflowId.executeQuery(); 1980 if(!result.next()) 1981 { 1982 throw new QueryException("Entity not found: " + entityId); 1983 } 1984 1985 return result.getInt(1); 1986 } 1987 finally 1988 { 1989 if(result != null) 1990 { 1991 result.close(); 1992 } 1993 } 1994 } 1995 catch(SQLException e) 1996 { 1997 throw new QueryException("Unable to query entity type: ", e); 1998 } 1999 } 2000 2001 /** Get an actor's name for a firing id. */ 2002 @Override 2003 public String getActorName(int fireId) throws QueryException 2004 { 2005 synchronized(_psActorNameForFiring) { 2006 try 2007 { 2008 _psActorNameForFiring.setInt(1, fireId); 2009 try(ResultSet result = _psActorNameForFiring.executeQuery();) 2010 { 2011 if(!result.next()) 2012 { 2013 throw new QueryException("No actor for firing id."); 2014 } 2015 return result.getString("name"); 2016 } 2017 } 2018 catch(SQLException e) 2019 { 2020 throw new QueryException("Unable to get actor name: ", e); 2021 } 2022 } 2023 } 2024 2025 /** Get an actor's type for a firing id. */ 2026 @Override 2027 public String getActorType(int fireId) throws QueryException 2028 { 2029 try 2030 { 2031 _psActorTypeForFiring.setInt(1, fireId); 2032 ResultSet result = null; 2033 try 2034 { 2035 result = _psActorTypeForFiring.executeQuery(); 2036 if(!result.next()) 2037 { 2038 throw new QueryException("No actor for firing id."); 2039 } 2040 2041 return result.getString("class"); 2042 } 2043 finally 2044 { 2045 if(result != null) 2046 { 2047 result.close(); 2048 } 2049 } 2050 } 2051 catch(SQLException e) 2052 { 2053 throw new QueryException("Unable to get actor type: ", e); 2054 } 2055 } 2056 2057 /** Get an actor's parameter name value pairs for a firing id. 2058 * NOTE: Parameter values may change during a firing; this method 2059 * returns the values at the <b>start</b> of the firing. 2060 */ 2061 @Override 2062 public Map<String,String> getParameterNameValuesForFiring(int fireId) 2063 throws QueryException 2064 { 2065 try 2066 { 2067 String actorName = getActorName(fireId); 2068 _psParamNameValuesForFiring.setString(1, actorName + ".%"); 2069 _psParamNameValuesForFiring.setInt(2, fireId); 2070 Map<String,String> nameValuesMap = _getParameterNameValues(_psParamNameValuesForFiring); 2071 2072 // use a different map to remove components (see below) to avoid 2073 // ConcurrentModificationExceptions 2074 Map<String,String> retval = new LinkedHashMap<String,String>(nameValuesMap); 2075 2076 // remove the components that are not direct parameters 2077 // e.g., parameters of the actors ports. 2078 for(String name : nameValuesMap.keySet()) 2079 { 2080 if(name.lastIndexOf('.') > actorName.length()) 2081 { 2082 retval.remove(name); 2083 } 2084 } 2085 2086 return retval; 2087 } 2088 catch(SQLException e) 2089 { 2090 throw new QueryException("Unable to get name value pairs: ", e); 2091 } 2092 } 2093 2094 /** Get the parameter name value pairs for an execution. NOTE: Parameter 2095 * values may change during an execution; this method returns the 2096 * values at the <b>start</b> of the execution. 2097 */ 2098 @Override 2099 public Map<String,String> getParameterNameValuesForExecution(int execId) 2100 throws QueryException 2101 { 2102 try 2103 { 2104 _psParamNameValuesForExecution.setInt(1, execId); 2105 return _getParameterNameValues(_psParamNameValuesForExecution); 2106 } 2107 catch(SQLException e) 2108 { 2109 throw new QueryException("Unable to get name value pairs: ", e); 2110 } 2111 } 2112 2113 /** Get the latest value of a parameter. 2114 * @param parameter the parameter name. 2115 * @param lsid the workflow lsid 2116 * @return the latest value of the parameter. If the workflow LSID or 2117 * parameter name cannot be found, returns null. 2118 */ 2119 @Override 2120 public String getParameterValueLatest(String parameter, KeplerLSID lsid) 2121 throws QueryException 2122 { 2123 return getParameterValueAtTime(new Date(Long.MAX_VALUE), parameter, 2124 lsid); 2125 } 2126 2127 2128 /** Get the value of a parameter at a specific time. 2129 * @param timestamp the time 2130 * @param parameter the parameter name 2131 * @param lsid the workflow lsid 2132 * @return the value of the parameter at the specified time. If the 2133 * workflow LSID or parameter name cannot be found, returns null. 2134 */ 2135 @Override 2136 public String getParameterValueAtTime(Date timestamp, String parameter, 2137 KeplerLSID lsid) throws QueryException 2138 { 2139 try 2140 { 2141 String paramName = _getEntityName(parameter); 2142 2143 //System.out.println("look for parameter name = " + paramName); 2144 2145 _psParamValueAtTimeForWorkflowLSID.setString(1, paramName); 2146 _psParamValueAtTimeForWorkflowLSID.setString(2, lsid.toStringWithoutRevision()); 2147 _psParamValueAtTimeForWorkflowLSID.setTimestamp(3, 2148 new Timestamp(timestamp.getTime())); 2149 2150 //System.out.println("query " + _psParamValueAtTimeForWorkflowLSID); 2151 2152 ResultSet result = null; 2153 2154 try 2155 { 2156 result = _psParamValueAtTimeForWorkflowLSID.executeQuery(); 2157 if(result.next()) 2158 { 2159 return result.getString("value"); 2160 } 2161 } 2162 finally 2163 { 2164 if(result != null) 2165 { 2166 result.close(); 2167 } 2168 } 2169 } 2170 catch(SQLException e) 2171 { 2172 throw new QueryException("Error querying parameter value: ", e); 2173 } 2174 2175 return null; 2176 } 2177 2178 /** Given a fully-qualified entity name, return the name as it would 2179 * appear in the entity table. 2180 */ 2181 protected String _getEntityName(String name) 2182 { 2183 int index = name.indexOf('.', 1); 2184 if(index > -1) 2185 { 2186 return name.substring(index); 2187 } 2188 return ""; 2189 } 2190 2191 /** Given a name from the entity table, return the fully-qualified name. */ 2192 protected String _getFullNameFromEntityName(String entity, String full) 2193 { 2194 int index = full.indexOf('.', 1); 2195 if(index == -1) 2196 { 2197 return full + entity; 2198 } 2199 else 2200 { 2201 return full.substring(0, index) + entity; 2202 } 2203 } 2204 2205 /** Get the immediate tokens that generated a token. */ 2206 @Override 2207 public List<Integer> getImmediateDependencies(int tokenId) 2208 throws QueryException 2209 { 2210 // get the firing id that generated this token 2211 List<Integer> firingsList = getActorFiringForToken(tokenId, false); 2212 int fireId; 2213 2214 if(firingsList.size() == 0) 2215 { 2216 throw new QueryException("No firing generated token " + tokenId + 2217 "."); 2218 } 2219 else if(firingsList.size() == 1) 2220 { 2221 fireId = firingsList.get(0); 2222 } 2223 else // firingsList.size() > 1 2224 { 2225 throw new QueryException("Multiple firings produced token " + 2226 tokenId + "."); 2227 } 2228 2229 // get the tokens read for that firing id 2230 return getTokensForFiring(fireId, true); 2231 } 2232 2233 /** Get a file associated with an execution. */ 2234 @Override 2235 public List<byte[]> getAssociatedDataForExecution(int execId, 2236 Map<String,String> metadataMap, boolean matchAny) 2237 throws QueryException 2238 { 2239 List<byte[]> retList = new ArrayList<byte[]>(); 2240 2241 try 2242 { 2243 //construct the SQL string 2244 String data = _dbType.getTableName("data"); 2245 String assocDataStr = _dbType.getTableName("associated_data"); 2246 StringBuffer queryBuf = new StringBuffer( 2247 // XXX can't distinct() on blob in oracle 2248 "SELECT data.contents " + 2249 "FROM " 2250 + assocDataStr + " ad, " 2251 + data + " data " + 2252 "WHERE data.md5 = ad.data_id AND ad.wf_exec_id = ? "); 2253 2254 String operator = "AND"; 2255 if (matchAny) 2256 { 2257 operator = "OR"; 2258 } 2259 2260 for(int i = 0; i < metadataMap.size(); i++) 2261 { 2262 queryBuf.append(operator); 2263 queryBuf.append(" (name = ? AND val = ?)"); 2264 } 2265 2266 try(PreparedStatement psAssociatedData = 2267 _dbType.getConnection().prepareStatement(queryBuf.toString())) 2268 { 2269 psAssociatedData.setInt(1, execId); 2270 int paramCounter = 2; 2271 2272 for(Map.Entry<String,String> entry : metadataMap.entrySet()) 2273 { 2274 //select distinct(file) where (name = ? and value = ?) or (name = ? and value = ?) or (name = ? and value = ?) 2275 psAssociatedData.setString(paramCounter++, entry.getKey()); 2276 psAssociatedData.setString(paramCounter++, entry.getValue()); 2277 } 2278 2279 //execute 2280 try(ResultSet result = psAssociatedData.executeQuery()) 2281 { 2282 while (result.next()) 2283 { 2284 retList.add(result.getBytes(1)); 2285 } 2286 } 2287 } 2288 } 2289 catch(SQLException e) 2290 { 2291 throw new QueryException("Error querying associated data: ", e); 2292 } 2293 return retList; 2294 } 2295 2296 /** Get any associated keys-values for an execution. */ 2297 @Override 2298 public Map<String,String> getAssociatedKeysValuesForExecution(int execId) 2299 throws QueryException { 2300 2301 Map<String,String> retval = new HashMap<String,String>(); 2302 2303 synchronized(_psAssociatedKeysValuesForExecution) { 2304 try { 2305 _psAssociatedKeysValuesForExecution.setInt(1, execId); 2306 2307 try(ResultSet rs = _psAssociatedKeysValuesForExecution.executeQuery()) { 2308 while(rs.next()) { 2309 retval.put(rs.getString(1), rs.getString(2)); 2310 } 2311 } 2312 2313 } catch(SQLException e) { 2314 throw new QueryException("Error querying keys values.", e); 2315 } 2316 } 2317 2318 return retval; 2319 2320 } 2321 2322 /** Get a list of files saved in the database. */ 2323 public List<String> getSavedFilenames() throws QueryException 2324 { 2325 List<String> retval = new LinkedList<String>(); 2326 2327 Statement statement = null; 2328 ResultSet result = null; 2329 try 2330 { 2331 try 2332 { 2333 statement = _dbType.getStatement(); 2334 // XXX change to prepared statement 2335 result = statement.executeQuery("select contents from data " + 2336 "where md5 in (select data_id from port_event where " + 2337 "file_id != '')"); 2338 while(result.next()) 2339 { 2340 retval.add(new String(result.getBytes(1))); 2341 } 2342 } 2343 finally 2344 { 2345 if(result != null) 2346 { 2347 result.close(); 2348 } 2349 2350 if(statement != null) 2351 { 2352 statement.close(); 2353 } 2354 } 2355 } 2356 catch(SQLException e) 2357 { 2358 throw new QueryException("Error querying filenames: ", e); 2359 } 2360 2361 return retval; 2362 } 2363 2364 /** Get the ports for an actor. 2365 * @param workflow the LSID of the workflow 2366 * @param actor the fully-qualified name of the actor 2367 * @return a list of fully-qualified names of ports of the actor 2368 */ 2369 @Override 2370 public List<String> getPortsForActor(KeplerLSID workflow, String actor) 2371 throws QueryException 2372 { 2373 try 2374 { 2375 _psPortsForActor.setString(1, workflow.toStringWithoutRevision()); 2376 // the names of the ports are prefixed with the actor name and . 2377 _psPortsForActor.setString(2, _getEntityName(actor) + ".%"); 2378 2379 //System.out.println("actor = " + _getEntityName(actor)); 2380 2381 ResultSet result = null; 2382 try 2383 { 2384 List<String> retval = new LinkedList<String>(); 2385 result = _psPortsForActor.executeQuery(); 2386 while(result.next()) 2387 { 2388 String name = result.getString(1); 2389 //System.out.println("name = " + name); 2390 String fullName = _getFullNameFromEntityName(name, actor); 2391 retval.add(fullName); 2392 } 2393 return retval; 2394 } 2395 finally 2396 { 2397 if(result != null) 2398 { 2399 result.close(); 2400 } 2401 } 2402 } 2403 catch(SQLException e) 2404 { 2405 throw new QueryException("Error querying ports for actor: ", e); 2406 } 2407 } 2408 2409 /** Get the host id for a specific execution id. If no execution 2410 * exists, returns null. 2411 */ 2412 @Override 2413 public String getHostIdForExecution(Integer execId) throws QueryException 2414 { 2415 try 2416 { 2417 _psHostIdForExecution.setInt(1, execId); 2418 ResultSet result = null; 2419 try 2420 { 2421 result = _psHostIdForExecution.executeQuery(); 2422 if(!result.next()) 2423 { 2424 return null; 2425 } 2426 return result.getString(1); 2427 } 2428 finally 2429 { 2430 if(result != null) 2431 { 2432 result.close(); 2433 } 2434 } 2435 } 2436 catch(SQLException e) 2437 { 2438 throw new QueryException("Unable to query host id for " + 2439 "execution id " + execId + ": ", e); 2440 } 2441 } 2442 2443 /** Get the user for a specific execution LSID. */ 2444 @Override 2445 public String getUserForExecution(KeplerLSID execLSID) throws QueryException { 2446 2447 synchronized(_psUserForExecutionLSID) { 2448 try { 2449 _psUserForExecutionLSID.setString(1, execLSID.toString()); 2450 try(ResultSet result = _psUserForExecutionLSID.executeQuery()) { 2451 if(result.next()) { 2452 return result.getString(1); 2453 } 2454 } 2455 } catch(SQLException e) { 2456 throw new QueryException("Unable to query user for " + 2457 "execution lsid " + execLSID + ": ", e); 2458 } 2459 } 2460 return null; 2461 } 2462 2463 /** Get the user for a specific execution id. If no execution 2464 * exists, returns null. 2465 */ 2466 @Override 2467 public String getUserForExecution(Integer execId) throws QueryException 2468 { 2469 try 2470 { 2471 _psUserForExecution.setInt(1, execId); 2472 ResultSet result = null; 2473 try 2474 { 2475 result = _psUserForExecution.executeQuery(); 2476 if(!result.next()) 2477 { 2478 return null; 2479 } 2480 return result.getString(1); 2481 } 2482 finally 2483 { 2484 if(result != null) 2485 { 2486 result.close(); 2487 } 2488 } 2489 } 2490 catch(SQLException e) 2491 { 2492 throw new QueryException("Unable to query user for " + 2493 "execution id " + execId + ": ", e); 2494 } 2495 } 2496 2497 2498 /** Get the output role (port name) of a token. */ 2499 @Override 2500 public String getOutputRoleToken(int tokenId) throws QueryException 2501 { 2502 synchronized(_psOutputRoleToken) { 2503 try 2504 { 2505 _psOutputRoleToken.setInt(1, tokenId); 2506 try(ResultSet result = _psOutputRoleToken.executeQuery();) { 2507 if(! result.next()) 2508 { 2509 throw new QueryException("Token not found: " + tokenId); 2510 } 2511 return result.getString(1); 2512 } 2513 } 2514 catch(SQLException e) 2515 { 2516 throw new QueryException("Unable to query output role: ", e); 2517 } 2518 } 2519 } 2520 2521 2522 /** Get the input role (port name) of a token. */ 2523 @Override 2524 public String getInputRoleForTokenAndFireId(int tokenId, int fireId) throws QueryException 2525 { 2526 synchronized(_psInputRoleToken) { 2527 try 2528 { 2529 _psInputRoleToken.setInt(1, tokenId); 2530 _psInputRoleToken.setInt(2, fireId); 2531 2532 try(ResultSet result = _psInputRoleToken.executeQuery();) { 2533 if(! result.next()) 2534 { 2535 throw new QueryException("Token not found: " + tokenId); 2536 } 2537 return result.getString(1); 2538 } 2539 } 2540 catch(SQLException e) 2541 { 2542 throw new QueryException("Unable to query input role: ", e); 2543 } 2544 } 2545 } 2546 2547 /** Get the parameter name value pairs for an execution, whose parameter type is 2548 * either '.Parameter' or '.StringParameter' 2549 */ 2550 @Override 2551 public Map<String,String> getParameterNameValuesOfSpecificTypeForExecution(int execId) 2552 throws QueryException 2553 { 2554 try 2555 { 2556 _psParamNameValuesOfSpecificTypeForExecution.setInt(1, execId); 2557 return _getParameterNameValues(_psParamNameValuesOfSpecificTypeForExecution); 2558 } 2559 catch(SQLException e) 2560 { 2561 throw new QueryException("Unable to get name value pairs: ", e); 2562 } 2563 } 2564 2565 /** Get the start and end timestamps of an actor firing. */ 2566 @Override 2567 public Date[] getTimestampsForActorFiring(int fireId) 2568 throws QueryException 2569 { 2570 synchronized(_psTimestampsForActorFiring) { 2571 try 2572 { 2573 _psTimestampsForActorFiring.setInt(1, fireId); 2574 try(ResultSet result = _psTimestampsForActorFiring.executeQuery();) 2575 { 2576 if(result.next()) 2577 { 2578 Date[] retval = new Date[2]; 2579 retval[0] = result.getTimestamp("start_time"); 2580 retval[1] = result.getTimestamp("end_time"); 2581 return retval; 2582 } 2583 } 2584 } 2585 catch(SQLException e) 2586 { 2587 throw new QueryException("Error querying timestamps for actor firing:", e); 2588 } 2589 } 2590 return null; 2591 } 2592 2593 /** Get actor fire ids based on its full name and workflow exec ID. */ 2594 @Override 2595 public List<Integer> getActorFiringIds(String actorName, Integer wfExecId) 2596 throws QueryException 2597 { 2598 try 2599 { 2600 _psActorFireId.setInt(1, wfExecId); 2601 _psActorFireId.setString(2, _getEntityName(actorName)); 2602 return _getIntResults(_psActorFireId, 1); 2603 } 2604 catch(SQLException e) 2605 { 2606 throw new QueryException("Error querying timestamps for actor firing:", e); 2607 } 2608 } 2609 2610 /** Get an actor's parameter and port parameter name value pairs for a firing id. 2611 * NOTE: Parameter values may change during a firing; this method 2612 * returns the values at the <b>start</b> of the firing. 2613 */ 2614 @Override 2615 public Map<String,String> getParameterAndPortParameterNameValuesForFiring(int fireId) 2616 throws QueryException 2617 { 2618 try 2619 { 2620 String actorName = getActorName(fireId); 2621 _psParamAndPortParamNameValuesForFiring.setString(1, actorName + ".%"); 2622 _psParamAndPortParamNameValuesForFiring.setInt(2, fireId); 2623 Map<String,String> nameValuesMap = _getParameterNameValues(_psParamAndPortParamNameValuesForFiring); 2624 2625 // use a different map to remove components (see below) to avoid 2626 // ConcurrentModificationExceptions 2627 Map<String,String> retval = new LinkedHashMap<String,String>(nameValuesMap); 2628 2629 // remove the components that are not direct parameters 2630 // e.g., parameters of the actors ports. 2631 for(String name : nameValuesMap.keySet()) 2632 { 2633 if(name.lastIndexOf('.') > actorName.length()) 2634 { 2635 retval.remove(name); 2636 } 2637 } 2638 2639 return retval; 2640 } 2641 catch(SQLException e) 2642 { 2643 throw new QueryException("Unable to get name value pairs: ", e); 2644 } 2645 } 2646 2647 /** Get all actor fire ids for a workflow exec ID. */ 2648 @Override 2649 public List<Integer> getActorFirings(int wfExecId) throws QueryException { 2650 2651 synchronized(_psActorFirings) { 2652 try { 2653 _psActorFirings.setInt(1, wfExecId); 2654 return _getIntResults(_psActorFirings, 1); 2655 } catch(SQLException e) { 2656 throw new QueryException("Error getting actor firings: ", e); 2657 } 2658 } 2659 } 2660 2661 /** Get the execution times for an actor. 2662 * 2663 * @param workflow the workflow LSID. If null, must specify execution id. 2664 * @param execLSID the execution LSID. If null, the last execution of the workflow 2665 * is used. 2666 * @param actor the full actor name. 2667 * @return a map of actor fire id to execution time pairs. if a firing does not 2668 * have a valid start or stop time, the firing is not included in the result. 2669 */ 2670 @Override 2671 public Map<String,Long> getExecutionTimesForActor(KeplerLSID workflow, 2672 KeplerLSID execLSID, String actor) throws QueryException 2673 { 2674 int runId; 2675 2676 // see if the execution id is specified 2677 if(execLSID == null) 2678 { 2679 runId = _getLastExecutionId(workflow); 2680 } 2681 else 2682 { 2683 runId = getExecutionForExecutionLSID(execLSID); 2684 } 2685 2686 try 2687 { 2688 //System.out.println(actor + " --> " + _getEntityName(actor)); 2689 2690 _psActorExecutionTimes.setString(1, _getEntityName(actor)); 2691 _psActorExecutionTimes.setInt(2, runId); 2692 2693 //System.out.println(_psActorExecutionTimes); 2694 2695 // use a LinkedHashMap for predictable iteration order. 2696 Map<String,Long> retval = new LinkedHashMap<String,Long>(); 2697 2698 try(ResultSet result = _psActorExecutionTimes.executeQuery();) 2699 { 2700 while(result.next()) 2701 { 2702 Timestamp start = result.getTimestamp(2); 2703 long startVal; 2704 if(start == null) { 2705 System.err.println("WARNING: missing start time for " + actor); 2706 continue; 2707 } else { 2708 startVal = start.getTime(); 2709 } 2710 2711 Timestamp end = result.getTimestamp(3); 2712 long endVal; 2713 if(end == null) { 2714 System.err.println("WARNING: missing stop time for " + actor); 2715 continue; 2716 } else { 2717 endVal = end.getTime(); 2718 } 2719 2720 long duration = endVal - startVal; 2721 2722 retval.put(result.getString(1), duration); 2723 //System.out.println("fire time for " + actor + " id " + result.getString(1) + " duration " + duration); 2724 } 2725 return retval; 2726 } 2727 } 2728 catch(SQLException e) 2729 { 2730 throw new QueryException("Error querying actor execution times: ", e); 2731 } 2732 } 2733 2734 /** Get the number of bytes read or written by a port. 2735 * 2736 * @param workflow the workflow LSID. If null, must specify execution id. 2737 * @param execId the execution id. If null, the last execution of the workflow 2738 * is used. 2739 * @param port the full port name. 2740 * @param read If true, get the bytes read. Otherwise, get the bytes written. 2741 * @return a map of port event id to bytes read/written. 2742 */ 2743 @Override 2744 public Map<Integer,Integer> getIOBytesForPort(KeplerLSID workflow, Integer execId, 2745 String port, boolean read) throws QueryException 2746 { 2747 2748 // FIXME queries need updating after addition of port_event.data 2749 // 2750 2751 if(execId == null) 2752 { 2753 execId = _getLastExecutionId(workflow); 2754 } 2755 2756 try 2757 { 2758 PreparedStatement ps; 2759 2760 if(read) 2761 { 2762 ps = _psPortIOBytesRead; 2763 } 2764 else 2765 { 2766 ps = _psPortIOBytesWrite; 2767 } 2768 2769 ps.setString(1, _getEntityName(port)); 2770 ps.setInt(2, execId); 2771 2772 Map<Integer,Integer> retval = new HashMap<Integer,Integer>(); 2773 2774 try(ResultSet result = ps.executeQuery();) 2775 { 2776 while(result.next()) 2777 { 2778 int id = result.getInt(1); 2779 byte[] data = result.getBytes(2); 2780 retval.put(id, data.length); 2781 } 2782 2783 return retval; 2784 } 2785 } 2786 catch(SQLException e) 2787 { 2788 throw new QueryException("Error querying port IO bytes: ", e); 2789 } 2790 } 2791 2792 /* 2793 @Override 2794 public List<LinkIO> getLinksIO(KeplerLSID workflow, Integer execId) throws QueryException 2795 { 2796 if(execId == null) 2797 { 2798 execId = _getLastExecutionId(workflow); 2799 } 2800 2801 try 2802 { 2803 _psIOLinkRead.setInt(1, execId); 2804 2805 Map<Integer, LinkIO> map = new HashMap<Integer, LinkIO>(); 2806 2807 try(ResultSet result = _psIOLinkRead.executeQuery();) 2808 { 2809 //System.out.println(_psIOLinkRead); 2810 2811 while(result.next()) 2812 { 2813 // reading actor name, id of port of event of writer, data 2814 LinkIO io = new LinkIO(); 2815 io.dest = result.getString(1); 2816 io.source_id = result.getInt(2); 2817 io.data = result.getBytes(3); 2818 map.put(io.source_id, io); 2819 //System.out.println(io); 2820 } 2821 2822 } 2823 2824 Statement sIOLinkWrite = _dbType.getStatement(); 2825 String actorFireStr = _dbType.getTableName("actor_fire"); 2826 String entityStr = _dbType.getTableName("entity"); 2827 String portEventStr = _dbType.getTableName("port_event"); 2828 2829 StringBuilder queryStr = new StringBuilder("SELECT ent.name, pe.id " + 2830 "FROM " + portEventStr + " pe, " + actorFireStr + " af, " + 2831 entityStr + " ent " + 2832 "WHERE pe.id IN ("); 2833 2834 int i = 0; 2835 for(LinkIO io : map.values()) 2836 { 2837 queryStr.append(" " + io.source_id); 2838 if(i < map.size() - 1) 2839 { 2840 queryStr.append(", "); 2841 } 2842 i++; 2843 } 2844 2845 queryStr.append(" ) AND pe.fire_id = af.id AND af.actor_id = ent.id"); 2846 2847 //System.out.println(queryStr); 2848 2849 try(ResultSet result = sIOLinkWrite.executeQuery(queryStr.toString());) 2850 { 2851 while(result.next()) 2852 { 2853 int portEventId = result.getInt(2); 2854 LinkIO io = map.get(portEventId); 2855 io.source = result.getString(1); 2856 } 2857 2858 sIOLinkWrite.close(); 2859 return new LinkedList<LinkIO>(map.values()); 2860 2861 } 2862 } 2863 catch(SQLException e) 2864 { 2865 throw new QueryException("Error querying link IO: ", e); 2866 } 2867 } 2868 */ 2869 2870 /** Get the timestamp(s) when a token was read. If a token was 2871 * never read, this can return null or an empty array. 2872 */ 2873 @Override 2874 public Date[] getTimestampsForTokenRead(Integer tokenId) throws QueryException { 2875 synchronized(_psTimestampsForTokenRead) { 2876 try { 2877 _psTimestampsForTokenRead.setInt(1, tokenId); 2878 try(ResultSet result = _psTimestampsForTokenRead.executeQuery();) { 2879 List<Date> timestamps = new ArrayList<Date>(); 2880 while(result.next()) { 2881 timestamps.add(result.getTimestamp(1)); 2882 } 2883 return timestamps.toArray(new Date[timestamps.size()]); 2884 } 2885 } 2886 catch(SQLException e) { 2887 throw new QueryException("Error querying timestamps for token read.", e); 2888 } 2889 } 2890 } 2891 2892 /** Get the timestamp when a token was written. */ 2893 @Override 2894 public Date getTimestampForTokenWrite(Integer tokenId) throws QueryException { 2895 synchronized(_psTimestampForTokenWrite) { 2896 try { 2897 _psTimestampForTokenWrite.setInt(1, tokenId); 2898 try(ResultSet result = _psTimestampForTokenWrite.executeQuery();) { 2899 if(result.next()) { 2900 return result.getTimestamp(1); 2901 } 2902 } 2903 } 2904 catch(SQLException e) { 2905 throw new QueryException("Error querying timestamps for token write.", e); 2906 } 2907 } 2908 return null; 2909 } 2910 2911 /////////////////////////////////////////////////////////////////////// 2912 //// protected methods //// 2913 2914 /** Construct a new SQLQueryV8 from a connected DatabaseType. */ 2915 protected SQLQueryV8(DatabaseType dbType) throws QueryException 2916 { 2917 _dbType = dbType; 2918 2919 try 2920 { 2921 _createPreparedStatements(); 2922 } 2923 catch(SQLException e) 2924 { 2925 throw new QueryException("Error creating prepared statements: ", e); 2926 } 2927 } 2928 2929 /** Check the schema version and initialize the prepared statements. */ 2930 protected void _init() 2931 throws QueryException 2932 { 2933 try 2934 { 2935 Schema schema = Schemas.createSchemaV8(); 2936 Schemas.checkVersion(_dbType, schema); 2937 _createPreparedStatements(); 2938 } 2939 catch(SQLException e) 2940 { 2941 e.printStackTrace(); 2942 throw new QueryException("Unable to connect or initialize " + 2943 "database connection: ", e); 2944 } 2945 } 2946 2947 /** Initialize the prepared statements. */ 2948 protected void _createPreparedStatements() throws SQLException 2949 { 2950 // get the table table names 2951 String actorFireStr = _dbType.getTableName("actor_fire"); 2952 String actorStr = _dbType.getTableName("actor"); 2953 String associatedDataStr = _dbType.getTableName("associated_data"); 2954 String dataStr = _dbType.getTableName("data"); 2955 String entityStr = _dbType.getTableName("entity"); 2956 String errorStr = _dbType.getTableName("error"); 2957 String parameterStr = _dbType.getTableName("parameter"); 2958 String parameterExecStr = _dbType.getTableName("parameter_exec"); 2959 String portEventStr = _dbType.getTableName("port_event"); 2960 String wfChangeStr = _dbType.getTableName("workflow_change"); 2961 String wfExecStr = _dbType.getTableName("workflow_exec"); 2962 String wfStr = _dbType.getTableName("workflow"); 2963 String tagStr = _dbType.getTableName("tag"); 2964 2965 // NOTE: user is a reserved column name in oracle 2966 String userColumnStr = _dbType.getColumnName("user"); 2967 2968 2969 if(_psWorkflows == null) 2970 { 2971 _psWorkflows = _dbType.getSQLSelect("workflow", "*"); 2972 } 2973 2974 if(_psWorkflowNameForLSID == null) 2975 { 2976 _psWorkflowNameForLSID = _dbType.getSQLSelect("workflow", "name", 2977 "lsid = ?"); 2978 } 2979 2980 if(_psWorkflowNameForExecutionLSID == null) { 2981 _psWorkflowNameForExecutionLSID = _dbType.getPrepStatement( 2982 "SELECT wf.name " + 2983 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 2984 "WHERE wfExec.wf_id = wf.id AND wfexec.lsid = ?"); 2985 } 2986 2987 if(_psExecutions == null) 2988 { 2989 _psExecutions = _dbType.getSQLSelect("workflow_exec", "id"); 2990 } 2991 2992 if(_psExecutionsForTimespan == null) 2993 { 2994 _psExecutionsForTimespan = _dbType.getSQLSelect("workflow_exec", 2995 "id", "start_time >= ? AND end_time <= ?"); 2996 } 2997 2998 if(_psExecutionsForTimespanOnHost == null) 2999 { 3000 _psExecutionsForTimespanOnHost = _dbType.getPrepStatement( 3001 "SELECT wfexec.id " + 3002 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3003 "WHERE wfexec.start_time >= ? AND wfexec.end_time <= ? AND " + 3004 "wfexec.host_id = ? AND wf.id = wfexec.wf_id AND wf.name = ?"); 3005 } 3006 3007 if(_psTimestampsForExecution == null) 3008 { 3009 _psTimestampsForExecution = _dbType.getSQLSelect("workflow_exec", 3010 "start_time, end_time", "id = ?"); 3011 } 3012 3013 if(_psEntitiesForChange == null) 3014 { 3015 _psEntitiesForChange = _dbType.getSQLSelect("entity", "id", 3016 "wf_change_id = ?"); 3017 } 3018 3019 if(_psChangesForTimespan == null) 3020 { 3021 _psChangesForTimespan = _dbType.getSQLSelect("workflow_change", 3022 "id", "time >= ? AND time <= ?"); 3023 } 3024 3025 if(_psChangesForTimespanOnHost == null) 3026 { 3027 _psChangesForTimespanOnHost = _dbType.getPrepStatement( 3028 "SELECT id " + 3029 "FROM " + wfStr + " wf, " + wfChangeStr + " wfchange " + 3030 "WHERE wfchange.time >= ? AND wfchange.time <= ? AND " + 3031 "wfchange.host_id = ? AND wf.id = wfchange.wf_id AND " + 3032 "wf.name = ?"); 3033 } 3034 3035 if(_psExecutionsForWorkflow == null) 3036 { 3037 String queryStr = "SELECT wfexec.id " + 3038 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3039 "WHERE wf.id = wfexec.wf_id AND wf.name = ?"; 3040 _psExecutionsForWorkflow = _dbType.getPrepStatement(queryStr); 3041 } 3042 3043 if(_psExecutionForExecutionLSID == null) 3044 { 3045 String queryStr = "SELECT wfexec.id " + 3046 "FROM " + wfExecStr + " wfexec " + 3047 "WHERE wfexec.lsid = ?"; 3048 _psExecutionForExecutionLSID = _dbType.getPrepStatement(queryStr); 3049 } 3050 3051 if(_psExecutionForExecutionLSIDWithoutRevision == null) 3052 { 3053 String queryStr = "SELECT wfexec.id " + 3054 "FROM " + wfExecStr + " wfexec " + 3055 "WHERE wfexec.lsid LIKE ?"; 3056 _psExecutionForExecutionLSIDWithoutRevision = _dbType.getPrepStatement(queryStr); 3057 } 3058 3059 if(_psExecutionForOldestReferralExecutionLSIDWithoutRevision == null) 3060 { 3061 String queryStr = "SELECT wfexec.id " + 3062 "FROM " + wfExecStr + " wfexec " + 3063 "WHERE wfexec.derived_from LIKE ?"; 3064 _psExecutionForOldestReferralExecutionLSIDWithoutRevision = _dbType.getPrepStatement(queryStr); 3065 } 3066 3067 if(_psExecutionLSIDForExecution == null) 3068 { 3069 String queryStr = "SELECT wfexec.lsid " + 3070 "FROM " + wfExecStr + " wfexec " + 3071 "WHERE wfexec.id = ?"; 3072 _psExecutionLSIDForExecution = _dbType.getPrepStatement(queryStr); 3073 } 3074 3075 if(_psExecutionsForWorkflowNameContains == null) 3076 { 3077 String queryStr = "SELECT wfexec.id " + 3078 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3079 "WHERE wf.id = wfexec.wf_id AND LOWER(wf.name) LIKE ?"; 3080 _psExecutionsForWorkflowNameContains = _dbType.getPrepStatement(queryStr); 3081 } 3082 3083 if(_psExecutionsForWorkflowRuns == null) 3084 { 3085 String queryStr = "SELECT wfexec.id " + 3086 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3087 "WHERE wf.id = wfexec.wf_id AND LOWER(wf.name) LIKE ? " + 3088 "AND LOWER(wfexec." + userColumnStr + ") LIKE ?"; 3089 _psExecutionsForWorkflowRuns = _dbType.getPrepStatement(queryStr); 3090 } 3091 3092 if(_psExecutionsForWorkflowRunsAfter == null) 3093 { 3094 String queryStr = "SELECT wfexec.id " + 3095 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3096 "WHERE wf.id = wfexec.wf_id AND LOWER(wf.name) LIKE ? " + 3097 "AND LOWER(wfexec. " + userColumnStr + ") LIKE ? " + 3098 "AND wfexec.start_time > ?"; 3099 _psExecutionsForWorkflowRunsAfter = _dbType.getPrepStatement(queryStr); 3100 } 3101 3102 if(_psExecutionsForWorkflowRunsAt == null) 3103 { 3104 String queryStr = "SELECT wfexec.id " + 3105 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3106 "WHERE wf.id = wfexec.wf_id AND LOWER(wf.name) LIKE ? " + 3107 "AND LOWER(wfexec." + userColumnStr + ") LIKE ? " + 3108 "AND wfexec.start_time LIKE ?"; //TODO implement. 3109 _psExecutionsForWorkflowRunsAt = _dbType.getPrepStatement(queryStr); 3110 } 3111 3112 if(_psExecutionsForWorkflowRunsBefore == null) 3113 { 3114 String queryStr = "SELECT wfexec.id " + 3115 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3116 "WHERE wf.id = wfexec.wf_id AND LOWER(wf.name) LIKE ? " + 3117 "AND LOWER(wfexec." + userColumnStr + ") LIKE ? " + 3118 "AND wfexec.start_time < ?"; 3119 _psExecutionsForWorkflowRunsBefore = _dbType.getPrepStatement(queryStr); 3120 } 3121 3122 if(_psExecutionsForWorkflowRuns2 == null) //inclusive 3123 { 3124 String queryStr = "SELECT wfexec.id " + 3125 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3126 "WHERE wf.id = wfexec.wf_id " + 3127 "AND LOWER(wf.name) LIKE ? " + 3128 "AND LOWER(wfexec." + userColumnStr + ") LIKE ? " + 3129 "AND wfexec.start_time >= ? " + 3130 "AND wfexec.start_time <= ? " + 3131 "AND wfexec.id >= ? " + 3132 "AND wfexec.id <= ?"; 3133 _psExecutionsForWorkflowRuns2 = _dbType.getPrepStatement(queryStr); 3134 } 3135 3136 if(_psExecutionLSIDsForWorkflowRuns == null) //inclusive 3137 { 3138 String queryStr = "SELECT wfexec.lsid " + 3139 "FROM " + wfStr + " wf, " + wfExecStr + " wfexec " + 3140 "WHERE wf.id = wfexec.wf_id " + 3141 "AND LOWER(wf.name) LIKE ? " + 3142 "AND LOWER(wfexec." + userColumnStr + ") LIKE ? " + 3143 "AND wfexec.start_time >= ? " + 3144 "AND wfexec.start_time <= ? " + 3145 "AND wfexec.id >= ? " + 3146 "AND wfexec.id <= ?"; 3147 _psExecutionLSIDsForWorkflowRuns = _dbType.getPrepStatement(queryStr); 3148 } 3149 3150 if(_psExecutionIdsForTags == null) 3151 { 3152 String queryStr = "SELECT tag.wf_exec_id " + 3153 "FROM " + tagStr + " tag " + 3154 "WHERE LOWER(tag.searchstring) LIKE ?"; 3155 _psExecutionIdsForTags = _dbType.getPrepStatement(queryStr); 3156 } 3157 3158 if(_psExecutionLSIDs == null) 3159 { 3160 _psExecutionLSIDs = _dbType.getPrepStatement("SELECT lsid " + 3161 "FROM " + wfExecStr + 3162 " ORDER BY lsid ASC"); 3163 3164 //_psExecutionLSIDs = _dbType.getSQLSelect("workflow_exec", "lsid"); 3165 } 3166 3167 if(_psTagsForExecutionId == null) 3168 { 3169 String queryStr = "SELECT tag.searchstring " + 3170 "FROM " + tagStr + " tag " + 3171 "WHERE tag.wf_exec_id = ?"; 3172 _psTagsForExecutionId = _dbType.getPrepStatement(queryStr); 3173 } 3174 3175 if (_psTagURNsForExecutionId == null) { 3176 String queryStr = "SELECT tag.type, tag.urn FROM " + tagStr + " tag WHERE tag.wf_exec_id = ?"; 3177 _psTagURNsForExecutionId = _dbType.getPrepStatement(queryStr); 3178 } 3179 3180 if (_psTypeForTag == null) { 3181 String queryStr = "SELECT tag.type FROM " + tagStr + " tag WHERE tag.urn = ?"; 3182 _psTypeForTag = _dbType.getPrepStatement(queryStr); 3183 } 3184 3185 if(_psExecutionsForAnnotation == null) 3186 { 3187 _psExecutionsForAnnotation = _dbType.getSQLSelect("workflow_exec", 3188 "id", "annotation = ?"); 3189 } 3190 3191 // read port events have write_id = id of port event that generated 3192 // the token, i.e. != -1. 3193 if(_psTokensReadForFiring == null) 3194 { 3195 _psTokensReadForFiring = _dbType.getSQLSelect("port_event", 3196 "write_event_id", "write_event_id != -1 AND fire_id = ?"); 3197 } 3198 3199 // write port events have write_id = -1 3200 if(_psTokensWrittenForFiring == null) 3201 { 3202 _psTokensWrittenForFiring = _dbType.getSQLSelect("port_event", 3203 "id", "write_event_id = -1 AND fire_id = ?"); 3204 } 3205 3206 if(_psActorNameForFiring == null) 3207 { 3208 String queryStr = "SELECT e.name " + 3209 "FROM " + actorFireStr + " af, " + entityStr + " e " + 3210 "WHERE af.actor_id = e.id AND af.id = ?"; 3211 _psActorNameForFiring = _dbType.getPrepStatement(queryStr); 3212 } 3213 3214 if(_psActorTypeForFiring == null) 3215 { 3216 String queryStr = "SELECT a.class " + 3217 "FROM " + actorFireStr + " af, " + actorStr + " a " + 3218 "WHERE af.actor_id = a.id AND af.id = ?"; 3219 _psActorTypeForFiring = _dbType.getPrepStatement(queryStr); 3220 } 3221 3222 if(_psParamNameValuesForFiring == null) 3223 { 3224 String queryStr = "SELECT name, value " + 3225 "FROM " + entityStr + " e, " + parameterStr + " p, " + 3226 parameterExecStr + " pe, " + actorFireStr + " af " + 3227 "WHERE e.type = 'parameter' AND e.id = p.id AND " + 3228 "e.name LIKE ? AND e.id = pe.parameter_id AND pe.wf_exec_id = af.wf_exec_id AND af.id = ?"; 3229 _psParamNameValuesForFiring = 3230 _dbType.getPrepStatement(queryStr); 3231 } 3232 3233 if(_psParamNameValuesForExecution == null) 3234 { 3235 String queryStr = "SELECT name, value " + 3236 "FROM " + entityStr + " e, " + parameterStr + " p, " + 3237 parameterExecStr + " pe " + 3238 "WHERE pe.wf_exec_id = ? AND pe.parameter_id = e.id AND " + 3239 "pe.parameter_id = p.id"; 3240 _psParamNameValuesForExecution = 3241 _dbType.getPrepStatement(queryStr); 3242 } 3243 3244 if(_psParamValueAtTimeForWorkflowLSID == null) 3245 { 3246 String queryStr = 3247 "SELECT p.value, chg.time " + 3248 "FROM " + entityStr + " e, " + wfChangeStr + " chg, " + 3249 wfStr + " wf, " + parameterStr + " p " + 3250 "WHERE p.id = e.id AND e.name = ? AND " + 3251 "e.wf_change_id = chg.id AND wf.lsid = ? AND " + 3252 "wf.id = chg.wf_id AND chg.time <= ? " + 3253 "ORDER BY chg.time DESC"; 3254 _psParamValueAtTimeForWorkflowLSID = _dbType.getPrepStatement(queryStr); 3255 } 3256 3257 if(_psTokensForExecution == null) 3258 { 3259 // this returns all the tokens written for an execution. 3260 String queryStr = "SELECT DISTINCT(pe.write_event_id) " + 3261 "FROM " + portEventStr + " pe, " + actorFireStr + " af " + 3262 "WHERE pe.write_event_id != -1 AND pe.fire_id = af.id AND " + 3263 "af.wf_exec_id = ?"; 3264 _psTokensForExecution = _dbType.getPrepStatement(queryStr); 3265 } 3266 3267 if(_psTokensForFiring == null) 3268 { 3269 _psTokensForFiring = _dbType.getSQLSelect("port_event", "id", 3270 "fire_id = ?"); 3271 } 3272 3273 if(_psEntityTokensForExecution == null) 3274 { 3275 String readQueryStr = "SELECT pe.write_event_id " + 3276 "FROM " + portEventStr + " pe, " + actorFireStr + " af " + 3277 "WHERE pe.write_event_id != -1 AND pe.fire_id = af.id AND " + 3278 "af.wf_exec_id = ? and pe.port_id = ?"; 3279 String writeQueryStr = "SELECT pe.id " + 3280 "FROM " + portEventStr + " pe, " + actorFireStr + " af " + 3281 "WHERE pe.write_event_id = -1 AND pe.fire_id = af.id AND " + 3282 "af.wf_exec_id = ? and pe.port_id = ?"; 3283 _psEntityTokensForExecution = _dbType.getPrepStatement(readQueryStr + " UNION ALL " + writeQueryStr); 3284 } 3285 3286 if(_psLastExecutionForWorkflow == null) 3287 { 3288 String queryStr = "SELECT MAX(wfe.id) " + 3289 "FROM " + wfStr + " wf, " + wfExecStr + " wfe " + 3290 "WHERE wf.id = wfe.wf_id AND wf.name = ?"; 3291 _psLastExecutionForWorkflow = _dbType.getPrepStatement(queryStr); 3292 } 3293 3294 if(_psLastExecutionForWorkflowLSID == null) 3295 { 3296 String queryStr = "SELECT MAX(wfe.id) " + 3297 "FROM " + wfStr + " wf, " + wfExecStr + " wfe " + 3298 "WHERE wf.id = wfe.wf_id AND wf.lsid = ?"; 3299 _psLastExecutionForWorkflowLSID = _dbType.getPrepStatement(queryStr); 3300 } 3301 3302 if(_psLastExecutionLSIDForWorkflowName == null) 3303 { 3304 String queryStr = "SELECT wfe.lsid " + 3305 "FROM " + wfStr + " wf, " + wfExecStr + " wfe " + 3306 "WHERE wf.id = wfe.wf_id and wf.name = ? " + 3307 "ORDER BY wfe.id DESC"; 3308 _psLastExecutionLSIDForWorkflowName = _dbType.getPrepStatement(queryStr); 3309 } 3310 3311 if(_psLastExecutionLSIDForWorkflowLSID == null) 3312 { 3313 String queryStr = "SELECT wfe.lsid " + 3314 "FROM " + wfStr + " wf, " + wfExecStr + " wfe " + 3315 "WHERE wf.id = wfe.wf_id and wf.lsid = ? " + 3316 "ORDER BY wfe.id DESC"; 3317 _psLastExecutionLSIDForWorkflowLSID = _dbType.getPrepStatement(queryStr); 3318 } 3319 3320 if(_psLastExecutionStartTime == null) 3321 { 3322 _psLastExecutionStartTime = _dbType.getPrepStatement( 3323 "SELECT MAX(wfe.start_time) " + 3324 "FROM " + wfExecStr + " wfe, " + wfStr + " wf " + 3325 "WHERE wf.id = wfe.wf_id AND wf.name = ? AND wfe.host_id = ?"); 3326 } 3327 3328 if(_psLastExecutionStartTimeForWorkflowId == null) 3329 { 3330 _psLastExecutionStartTimeForWorkflowId = 3331 _dbType.getSQLSelect("workflow_exec", "MAX(start_time)", 3332 "wf_id = ? AND host_id = ?"); 3333 } 3334 3335 if(_psLastChangeTime == null) 3336 { 3337 _psLastChangeTime = _dbType.getPrepStatement( 3338 "SELECT MAX(wfchange.time) " + 3339 "FROM " + wfChangeStr + " wfchange, " + wfStr + " wf " + 3340 "WHERE wf.id = wfchange.wf_id AND wf.name = ? AND " + 3341 "wfchange.host_id = ?"); 3342 } 3343 3344 if(_psLastChangeTimeForWorkflowId == null) 3345 { 3346 _psLastChangeTimeForWorkflowId = 3347 _dbType.getSQLSelect("workflow_change", "MAX(time)", 3348 "wf_id = ? AND host_id = ?"); 3349 } 3350 3351 if(_psPortEventData == null) { 3352 3353 _psPortEventData = _dbType.getSQLSelect(portEventStr, 3354 "data, data_id", "id = ?"); 3355 } 3356 3357 if(_psDataContents == null) 3358 { 3359 _psDataContents = _dbType.getSQLSelect(dataStr, "contents", "md5 = ?"); 3360 } 3361 3362 if(_psTokenType == null) 3363 { 3364 _psTokenType = _dbType.getSQLSelect("port_event", 3365 "type", "id = ?"); 3366 } 3367 3368 if(_psChannelForTokenRead == null) { 3369 _psChannelForTokenRead = _dbType.getSQLSelect("port_event", 3370 "channel", "write_event_id = ? AND fire_id = ?"); 3371 } 3372 3373 if(_psChannelForTokenWrite == null) { 3374 _psChannelForTokenWrite = _dbType.getSQLSelect("port_event", 3375 "channel", "id = ?"); 3376 } 3377 3378 if(_psActorFiringsForTokenRead == null) 3379 { 3380 _psActorFiringsForTokenRead = 3381 _dbType.getSQLSelect("port_event", "fire_id", 3382 "write_event_id = ?"); 3383 } 3384 3385 if(_psActorFiringForTokenWrite == null) 3386 { 3387 _psActorFiringForTokenWrite = 3388 _dbType.getSQLSelect("port_event", "fire_id", "id = ?"); 3389 } 3390 3391 if(_psActorFiringsForExecution == null) 3392 { 3393 _psActorFiringsForExecution = _dbType.getSQLSelect("actor_fire", 3394 "id", "wf_exec_id = ?"); 3395 } 3396 3397 if(_psMomlForExecutionId == null) 3398 { 3399 String queryStr = "SELECT d.contents " + 3400 "FROM " + dataStr + " d, " + wfExecStr + " wfe " + 3401 "WHERE wfe.id = ? AND d.md5 = wfe.wf_contents_id"; 3402 _psMomlForExecutionId = _dbType.getPrepStatement(queryStr); 3403 } 3404 3405 if(_psMomlForExecutionLSID == null) 3406 { 3407 String queryStr = "SELECT d.contents " + 3408 "FROM " + dataStr + " d, " + wfExecStr + " wfe " + 3409 "WHERE wfe.lsid = ? AND d.md5 = wfe.wf_contents_id"; 3410 _psMomlForExecutionLSID = _dbType.getPrepStatement(queryStr); 3411 } 3412 3413 /* XXX no arrays for hsql 1.7.2 3414 if(_psMoMLMD5sForExecutions == null) 3415 { 3416 _psMoMLMD5sForExecutions = _dbType.getPrepStatement( 3417 "SELECT d.md5 " + 3418 "FROM " + dataStr + " d, " + wfExecStr + " wfexec " + 3419 "WHERE wfexec.wf_contents_id = d.id AND wfexec.id IN ( ? )"); 3420 } 3421*/ 3422 _psMoMLMD5sForExecutions = _dbType.getStatement(); 3423 3424 //if(_psWorkflowRunsForExecutions == null) 3425 //{ 3426 // String queryStr = "SELECT wf.name, wfexec.user, wfexec.id, wfexec.start_time, wfexec.end_time FROM " + 3427 // wfStr + " wf INNER JOIN " + wfExecStr + " wfexec " + 3428 // "ON wf.id=wfexec.wf_id WHERE wfexec.id in (?)"; 3429 // _psWorkflowRunsForExecutions = _dbType.getPrepStatement(queryStr); 3430 //} 3431 3432 //if(_psWorkflowRunsForExecutionLSIDs == null) 3433 //{ 3434 // String queryStr = "SELECT wf.name, wfexec.user, wfexec.id, wfexec.start_time, wfexec.end_time FROM " + 3435 // wfStr + " wf INNER JOIN " + wfExecStr + " wfexec " + 3436 // "ON wf.id=wfexec.wf_id WHERE wfexec.lsid in (?)"; 3437 // _psWorkflowRunsForExecutionLSIDs = _dbType.getPrepStatement(queryStr); 3438 //} 3439 3440 if(_psDataMD5s == null) 3441 { 3442 _psDataMD5s = _dbType.getSQLSelect("data", "md5"); 3443 } 3444 3445 if(_psEntityId == null) 3446 { 3447 String queryStr = "SELECT e.id FROM " 3448 + entityStr + " e, " 3449 + wfStr + " w " 3450 + "WHERE e.wf_id = w.id " 3451 + "AND deleted = 0 " 3452 + "AND e.name = ? " 3453 + "AND w.name = ?"; 3454 _psEntityId = _dbType.getPrepStatement(queryStr); 3455 } 3456 3457 if(_psEntityIdLSID == null) 3458 { 3459 String queryStr = "SELECT e.id FROM " 3460 + entityStr + " e, " 3461 + wfStr + " w " 3462 + "WHERE e.wf_id = w.id " 3463 + "AND deleted = " + _dbType.getFalseValue() 3464 + " AND e.name = ? " 3465 + "AND w.lsid = ?"; 3466 _psEntityIdLSID = _dbType.getPrepStatement(queryStr); 3467 } 3468 3469 if(_psEntityType == null) 3470 { 3471 String queryStr = "SELECT e.type FROM " 3472 + entityStr + " e " 3473 + "WHERE e.id = ? " 3474 + "AND deleted = " + _dbType.getFalseValue(); 3475 _psEntityType = _dbType.getPrepStatement(queryStr); 3476 } 3477 3478 if(_psEntityWorkflowId == null) 3479 { 3480 String queryStr = "SELECT e.wf_id FROM " 3481 + entityStr + " e " 3482 + "WHERE e.id = ? "; 3483 _psEntityWorkflowId = _dbType.getPrepStatement(queryStr); 3484 } 3485 3486 if(_psErrorForExecution == null) 3487 { 3488 String queryStr = "SELECT e.message FROM " + 3489 errorStr + " e, " + 3490 wfExecStr + " wfe " + 3491 "WHERE e.exec_id = wfe.id AND " + 3492 "wfe.lsid = ?"; 3493 _psErrorForExecution = _dbType.getPrepStatement(queryStr); 3494 } 3495 3496 if(_psExecutionsForType == null) 3497 { 3498 _psExecutionsForType = _dbType.getSQLSelect("workflow_exec", "lsid", "type = ?"); 3499 } 3500 3501 if(_psDoesExecutionHaveError == null) 3502 { 3503 String queryStr = "SELECT e.id FROM " + 3504 errorStr + " e, " + 3505 wfExecStr + " wfe " + 3506 "WHERE e.exec_id = wfe.id AND " + 3507 "wfe.lsid = ?"; 3508 _psDoesExecutionHaveError = _dbType.getPrepStatement(queryStr); 3509 } 3510 3511 if(_psIsExecutionImported == null) 3512 { 3513 String queryStr = "SELECT pe.parameter_id FROM " + 3514 parameterExecStr + " pe, " + 3515 wfExecStr + " wfe " + 3516 "WHERE pe.wf_exec_id = wfe.id AND " + 3517 "wfe.lsid = ?"; 3518 _psIsExecutionImported = _dbType.getPrepStatement(queryStr); 3519 } 3520 3521 if(_psPortsForActor == null) 3522 { 3523 String queryStr = "SELECT DISTINCT ent.name " + 3524 "FROM " + entityStr + " ent, " + wfStr + " wf " + 3525 "WHERE wf.lsid = ? AND ent.wf_id = wf.id AND " + 3526 "(ent.type = 'port' OR ent.type = 'portparameter') AND " + 3527 "ent.name LIKE ? ORDER BY ent.name ASC"; 3528 _psPortsForActor = _dbType.getPrepStatement(queryStr); 3529 } 3530 3531 if(_psHostIdForExecution == null) 3532 { 3533 String queryStr = "SELECT wfexec.host_id " + 3534 "FROM " + wfExecStr + " wfexec " + 3535 "WHERE wfexec.id = ?"; 3536 3537 //System.out.println("queryStr= "+queryStr); 3538 _psHostIdForExecution = _dbType.getPrepStatement(queryStr); 3539 } 3540 3541 if(_psUserForExecution == null) 3542 { 3543 String queryStr = "SELECT wfexec." + userColumnStr + 3544 " FROM " + wfExecStr + " wfexec " + 3545 "WHERE wfexec.id = ?"; 3546 3547 //System.out.println("queryStr= "+queryStr); 3548 _psUserForExecution = _dbType.getPrepStatement(queryStr); 3549 } 3550 3551 if(_psUserForExecutionLSID == null) { 3552 String queryStr = "SELECT wfexec." + userColumnStr + 3553 " FROM " + wfExecStr + " wfexec " + 3554 "WHERE wfexec.lsid = ?"; 3555 3556 _psUserForExecutionLSID = _dbType.getPrepStatement(queryStr); 3557 } 3558 3559 if(_psOutputRoleToken == null) 3560 { 3561 String queryStr = "SELECT e.name " + 3562 "FROM " + entityStr + " e, " + portEventStr + " pe " + 3563 "WHERE e.id = pe.port_id AND pe.id = ?"; 3564 _psOutputRoleToken = _dbType.getPrepStatement(queryStr); 3565 } 3566 3567 if(_psInputRoleToken == null) 3568 { 3569 String queryStr = "SELECT e.name " + 3570 "FROM " + entityStr + " e, " + portEventStr + " pe " + 3571 "WHERE e.id = pe.port_id AND pe.write_event_id = ? AND " + 3572 "pe.fire_id = ?"; 3573 _psInputRoleToken = _dbType.getPrepStatement(queryStr); 3574 } 3575 3576 if(_psParamNameValuesOfSpecificTypeForExecution == null) 3577 { 3578 String queryStr = "SELECT name, value " + 3579 "FROM " + entityStr + " e, " + parameterStr + " p, " + 3580 parameterExecStr + " pe " + 3581 "WHERE pe.wf_exec_id = ? AND pe.parameter_id = e.id AND " + 3582 "pe.parameter_id = p.id AND p.type LIKE '%Parameter'"; 3583 3584 _psParamNameValuesOfSpecificTypeForExecution = _dbType.getPrepStatement(queryStr); 3585 } 3586 3587 if(_psTimestampsForActorFiring == null) 3588 { 3589 _psTimestampsForActorFiring = _dbType.getSQLSelect("actor_fire", 3590 "start_time, end_time", "id = ?"); 3591 } 3592 3593 if(_psTimestampsForTokenRead == null) { 3594 _psTimestampsForTokenRead = _dbType.getSQLSelect("port_event", 3595 "time", "write_event_id = ?"); 3596 } 3597 3598 if(_psTimestampForTokenWrite == null) { 3599 _psTimestampForTokenWrite = _dbType.getSQLSelect("port_event", 3600 "time", "id = ?"); 3601 } 3602 3603 if(_psParamAndPortParamNameValuesForFiring == null) 3604 { 3605 String queryStr = "SELECT name, value " + 3606 "FROM " + entityStr + " e, " + parameterStr + " p, " + 3607 parameterExecStr + " pe, " + actorFireStr + " af " + 3608 "WHERE e.type LIKE '%parameter' AND e.id = p.id AND " + 3609 "e.name LIKE ? AND e.id = pe.parameter_id AND pe.wf_exec_id = af.wf_exec_id AND af.id = ?"; 3610 3611 _psParamAndPortParamNameValuesForFiring = _dbType.getPrepStatement(queryStr); 3612 } 3613 3614 if(_psActorFireId == null) 3615 { 3616 String queryStr = "SELECT a.id " + 3617 "FROM " + entityStr + " e, " + actorFireStr + " a " + 3618 "WHERE e.id = a.actor_id " + 3619 "AND a.wf_exec_id = ? " + 3620 "AND e.name = ?"; 3621 3622 _psActorFireId = _dbType.getPrepStatement(queryStr); 3623 } 3624 3625 if(_psActorFirings == null) { 3626 String queryStr = "SELECT a.id " + 3627 "FROM " + actorFireStr + " a " + 3628 "WHERE a.wf_exec_id = ? " + 3629 "ORDER BY a.id ASC"; 3630 _psActorFirings = _dbType.getPrepStatement(queryStr); 3631 } 3632 3633 if(_psActorExecutionTimes == null) 3634 { 3635 String queryStr = "SELECT af.id, af.start_time, af.end_time " + 3636 "FROM " + actorFireStr + " af, " + entityStr + " ent " + 3637 "WHERE ent.name = ? AND ent.id = af.actor_id AND af.wf_exec_id = ?"; 3638 _psActorExecutionTimes = _dbType.getPrepStatement(queryStr); 3639 } 3640 3641 if(_psPortIOBytesRead == null) 3642 { 3643 String queryStr = "SELECT pe.id, d.contents " + 3644 "FROM " + dataStr + " d, " + portEventStr + " pe, " + 3645 entityStr + " ent, " + actorFireStr + " af " + 3646 "WHERE ent.name = ? AND ent.id = pe.port_id AND " + 3647 "af.id = pe.fire_id AND af.wf_exec_id = ? AND " + 3648 "d.md5 = pe.data_id AND pe.write_event_id != -1"; 3649 3650 _psPortIOBytesRead = _dbType.getPrepStatement(queryStr); 3651 } 3652 3653 if(_psPortIOBytesWrite == null) 3654 { 3655 String queryStr = "SELECT pe.id, d.contents " + 3656 "FROM " + dataStr + " d, " + portEventStr + " pe, " + 3657 entityStr + " ent, " + actorFireStr + " af " + 3658 "WHERE ent.name = ? AND ent.id = pe.port_id AND " + 3659 "af.id = pe.fire_id AND af.wf_exec_id = ? AND " + 3660 "d.md5 = pe.data_id AND pe.write_event_id = -1"; 3661 3662 _psPortIOBytesWrite = _dbType.getPrepStatement(queryStr); 3663 } 3664 3665 if(_psAssociatedKeysValuesForExecution == null) { 3666 String queryStr = "SELECT name, val " + 3667 "FROM " + associatedDataStr + 3668 " WHERE data_id is NULL and wf_exec_id = ?"; 3669 _psAssociatedKeysValuesForExecution = _dbType.getPrepStatement(queryStr); 3670 } 3671 } 3672 3673 /** Get the entities for a workflow change. */ 3674 protected List<Integer> _getEntitiesForChange(int changeId) 3675 throws QueryException 3676 { 3677 try 3678 { 3679 _psEntitiesForChange.setInt(1, changeId); 3680 return _getIntResults(_psEntitiesForChange, 1); 3681 } 3682 catch(SQLException e) 3683 { 3684 throw new QueryException("Error querying entities for " + 3685 "change: ", e); 3686 } 3687 } 3688 3689 /** Get the last change time for a workflow. */ 3690 protected Date _getLastChangeTime(String workflowName, String hostName) 3691 throws QueryException 3692 { 3693 if(workflowName == null || hostName == null) 3694 { 3695 throw new QueryException("not implemented yet."); 3696 } 3697 3698 try 3699 { 3700 Date retval = null; 3701 3702 _psLastChangeTime.setString(1, workflowName); 3703 _psLastChangeTime.setString(2, hostName); 3704 3705 ResultSet result = null; 3706 try 3707 { 3708 result = _psLastChangeTime.executeQuery(); 3709 if(result.next()) 3710 { 3711 retval = result.getTimestamp(1); 3712 } 3713 } 3714 finally 3715 { 3716 if(result != null) 3717 { 3718 result.close(); 3719 } 3720 } 3721 return retval; 3722 } 3723 catch(SQLException e) 3724 { 3725 throw new QueryException("Error querying last change time: ", e); 3726 } 3727 } 3728 3729 /** Get the last change time for a workflow. */ 3730 protected Date _getLastChangeTime(int workflowId, String hostName) 3731 throws QueryException 3732 { 3733 if(hostName == null) 3734 { 3735 throw new QueryException("not implemented yet."); 3736 } 3737 3738 try 3739 { 3740 Date retval = null; 3741 3742 _psLastChangeTimeForWorkflowId.setInt(1, workflowId); 3743 _psLastChangeTimeForWorkflowId.setString(2, hostName); 3744 3745 ResultSet result = null; 3746 try 3747 { 3748 result = _psLastChangeTimeForWorkflowId.executeQuery(); 3749 if(result.next()) 3750 { 3751 retval = result.getTimestamp(1); 3752 } 3753 } 3754 finally 3755 { 3756 if(result != null) 3757 { 3758 result.close(); 3759 } 3760 } 3761 return retval; 3762 } 3763 catch(SQLException e) 3764 { 3765 throw new QueryException("Error querying last change time: ", e); 3766 } 3767 } 3768 3769 /** Get changes performed since a specific time. */ 3770 protected List<Integer> _getChangesSince(Date timeStamp, 3771 /* XXX boolean including */ String workflowName, String hostName) 3772 throws QueryException 3773 { 3774 Timestamp startTime = null; 3775 if(timeStamp != null) 3776 { 3777 startTime = new Timestamp(timeStamp.getTime()); 3778 } 3779 return _getChangesForTimespan(startTime, _maxEndTime, workflowName, 3780 hostName); 3781 } 3782 3783 /** Get changes performed on a host within a timespan. If host is null, 3784 * returns changes for all hosts. 3785 */ 3786 protected List<Integer> _getChangesForTimespan(Date start, 3787 Date end, String workflow, String host) 3788 throws QueryException 3789 { 3790 3791 // sanity checks 3792 if(start == null) 3793 { 3794 start = _minStartTime; 3795 } 3796 3797 if(end == null) 3798 { 3799 end = _maxEndTime; 3800 } 3801 3802 if(start.after(end)) 3803 { 3804 throw new QueryException("Start time " + start + " is after " + 3805 " end time " + end); 3806 } 3807 3808 try 3809 { 3810 PreparedStatement query; 3811 3812 if(host == null) 3813 { 3814 query = _psChangesForTimespan; 3815 } 3816 else if(workflow == null) 3817 { 3818 throw new QueryException("not implemented yet"); 3819 } 3820 else // host != null && workflow != null 3821 { 3822 query = _psChangesForTimespanOnHost; 3823 query.setString(3, host); 3824 query.setString(4, workflow); 3825 } 3826 3827 query.setTimestamp(1, new Timestamp(start.getTime())); 3828 query.setTimestamp(2, new Timestamp(end.getTime())); 3829 3830 return _getIntResults(query, 1); 3831 } 3832 catch(SQLException e) 3833 { 3834 throw new QueryException("Unable to query changes: ", e); 3835 } 3836 } 3837 3838 /** Get the last execution start time. */ 3839 protected Date _getLastExecutionStartTime(String workflowName, 3840 String hostName) throws QueryException 3841 { 3842 if(workflowName == null || hostName == null) 3843 { 3844 throw new QueryException("not implemented yet."); 3845 } 3846 3847 try 3848 { 3849 Timestamp retval = null; 3850 3851 _psLastExecutionStartTime.setString(1, workflowName); 3852 _psLastExecutionStartTime.setString(2, hostName); 3853 3854 ResultSet result = null; 3855 try 3856 { 3857 result = _psLastExecutionStartTime.executeQuery(); 3858 if(result.next()) 3859 { 3860 retval = result.getTimestamp(1); 3861 } 3862 } 3863 finally 3864 { 3865 if(result != null) 3866 { 3867 result.close(); 3868 } 3869 } 3870 return retval; 3871 } 3872 catch(SQLException e) 3873 { 3874 throw new QueryException("Error querying last execution start " + 3875 "time: ", e); 3876 } 3877 } 3878 3879 /** Get the last execution start time. */ 3880 protected Date _getLastExecutionStartTime(int workflowId, 3881 String hostName) throws QueryException 3882 { 3883 if(hostName == null) 3884 { 3885 throw new QueryException("not implemented yet."); 3886 } 3887 3888 try 3889 { 3890 Timestamp retval = null; 3891 3892 _psLastExecutionStartTimeForWorkflowId.setInt(1, workflowId); 3893 _psLastExecutionStartTimeForWorkflowId.setString(2, hostName); 3894 3895 ResultSet result = null; 3896 try 3897 { 3898 result = 3899 _psLastExecutionStartTimeForWorkflowId.executeQuery(); 3900 if(result.next()) 3901 { 3902 retval = result.getTimestamp(1); 3903 } 3904 } 3905 finally 3906 { 3907 if(result != null) 3908 { 3909 result.close(); 3910 } 3911 } 3912 return retval; 3913 } 3914 catch(SQLException e) 3915 { 3916 throw new QueryException("Error querying last execution start " + 3917 "time: ", e); 3918 } 3919 } 3920 3921 /** Get executions started since a specific time. 3922 * @param timeStamp get executions started after this time. 3923 * @param including if true, include executions starting at timeStamp. 3924 * if false, do not include executions starting at timeStamp. 3925 * @param workflowName get executions for a specific workflow. 3926 * @param hostName get executions for a specific host. 3927 */ 3928 protected List<Integer> _getExecutionsStartedSince(Date timeStamp, 3929 boolean including, String workflowName, String hostName) 3930 throws QueryException 3931 { 3932 Timestamp startTime = null; 3933 if(timeStamp != null) 3934 { 3935 if(including) 3936 { 3937 startTime = new Timestamp(timeStamp.getTime()); 3938 } 3939 else 3940 { 3941 startTime = new Timestamp(timeStamp.getTime() + 1); 3942 } 3943 } 3944 return _getExecutionsForTimespan(startTime, _maxEndTime, workflowName, 3945 hostName); 3946 } 3947 3948 /** Get executions for a worfkflow run on a host within a timespan. */ 3949 protected List<Integer> _getExecutionsForTimespan(Date start, 3950 Date end, String workflow, String host) throws QueryException 3951 { 3952 3953 // sanity checks 3954 if(start == null) 3955 { 3956 start = _minStartTime; 3957 //_debug("setting start time to min"); 3958 } 3959 3960 if(end == null) 3961 { 3962 end = _maxEndTime; 3963 //_debug("setting end time to max"); 3964 } 3965 3966 if(start.after(end)) 3967 { 3968 throw new QueryException("Start time " + start + " is after " + 3969 " end time " + end); 3970 } 3971 3972 //_debug("start = " + start + " | end = " + end); 3973 3974 try 3975 { 3976 PreparedStatement query; 3977 if(host == null) 3978 { 3979 query = _psExecutionsForTimespan; 3980 } 3981 else if(workflow == null) 3982 { 3983 throw new QueryException("not implemented yet"); 3984 } 3985 else // host != null && workflow != null 3986 { 3987 query = _psExecutionsForTimespanOnHost; 3988 query.setString(3, host); 3989 query.setString(4, workflow); 3990 3991 } 3992 3993 query.setTimestamp(1, new Timestamp(start.getTime())); 3994 query.setTimestamp(2, new Timestamp(end.getTime())); 3995 3996 return _getIntResults(query, 1); 3997 } 3998 catch(SQLException e) 3999 { 4000 throw new QueryException("Unable to query executions for " + 4001 "timespan " + start + " - " + end + " :", e); 4002 } 4003 } 4004 4005 /** Get actor firings for an execution. */ 4006 /* 4007 protected List<Integer> _getActorFiringsForExecution(int execId) 4008 throws QueryException 4009 { 4010 try 4011 { 4012 _psActorFiringsForExecution.setInt(1, execId); 4013 return _getIntResults(_psActorFiringsForExecution, 1); 4014 } 4015 catch(SQLException e) 4016 { 4017 throw new QueryException("Error querying actor firings for " + 4018 "execution: ", e); 4019 } 4020 } 4021 */ 4022 4023 /** Get the id for a workflow. If workflow does not exist, returns an 4024 * an integer less than 0. 4025 */ 4026 protected int _getWorkflow(String workflow) throws QueryException 4027 { 4028 int retval = -1; 4029 4030 try 4031 { 4032 ResultSet result = null; 4033 try 4034 { 4035 result = _psWorkflows.executeQuery(); 4036 while(result.next()) 4037 { 4038 if(result.getString("name").equals(workflow)) 4039 { 4040 retval = result.getInt("id"); 4041 break; 4042 } 4043 } 4044 } 4045 finally 4046 { 4047 if(result != null) 4048 { 4049 result.close(); 4050 } 4051 } 4052 } 4053 catch(SQLException e) 4054 { 4055 throw new QueryException("Unable to query workflow: ", e); 4056 } 4057 return retval; 4058 } 4059 4060 /* 4061 protected List<Integer> _getTokensForFiring(int fireId) 4062 throws QueryException 4063 { 4064 try 4065 { 4066 _psTokensForFiring.setInt(1, fireId); 4067 return _getIntResults(_psTokensForFiring, 1); 4068 } 4069 catch(SQLException e) 4070 { 4071 throw new QueryException("Error querying tokens for firing: ", e); 4072 } 4073 } 4074 */ 4075 4076 /** Get all the data MD5 checksums. */ 4077 protected List<String> _getDataMD5s() throws QueryException 4078 { 4079 try 4080 { 4081 return _getStringResults(_psDataMD5s, 1); 4082 } 4083 catch(SQLException e) 4084 { 4085 throw new QueryException("Unable to query data md5s: ", e); 4086 } 4087 } 4088 4089 /** Get a list of MoML MD5 checksums for a set of execution ids.*/ 4090 /* XXX need Arrays 4091 protected List<String> _getMoMLMD5sForExecutions(List<Integer> execList) 4092 throws QueryException 4093 { 4094 try 4095 { 4096 String dataStr = _dbType.getTableName("data"); 4097 String wfExecStr = _dbType.getTableName("workflow_exec"); 4098 String queryStr = "SELECT DISTINCT d.md5 " + 4099 "FROM " + dataStr + " d, " + wfExecStr + " wfexec " + 4100 "WHERE wfexec.wf_contents_id = d.md5 AND wfexec.id IN ( " + 4101 StringUtil.listToString(execList) + " )"; 4102 4103 //_debug(queryStr); 4104 4105 return _getStringResults(_psMoMLMD5sForExecutions, queryStr, 1); 4106 4107 // XXX no arrays 4108 // _psMoMLMD5sForExecutions.setString(1, buf.toString()); 4109 //return _getStringResults(_psMoMLMD5sForExecutions, 1); 4110 } 4111 catch(SQLException e) 4112 { 4113 throw new QueryException("Unable to query moml md5s for " + 4114 "executions: ", e); 4115 } 4116 } 4117 */ 4118 4119 /** Convenience routine to get a list of integer SQL results. 4120 * @param query the query to execute 4121 * @param index column number of result 4122 */ 4123 protected List<Integer> _getIntResults(PreparedStatement query, int index) 4124 throws SQLException 4125 { 4126 List<Integer> retval = new LinkedList<Integer>(); 4127 try(ResultSet result = query.executeQuery();) 4128 { 4129 /* 4130 java.sql.ResultSetMetaData md = result.getMetaData(); 4131 for(int i = 1; i <= md.getColumnCount(); i++) 4132 { 4133 _debug("column " + i + " = " + md.getColumnName(i)); 4134 } 4135 */ 4136 4137 while(result.next()) 4138 { 4139 //_debug("got result row; adding " + result.getInt(index)); 4140 retval.add(result.getInt(index)); 4141 } 4142 } 4143 return retval; 4144 } 4145 4146 /** A convenience method that executes a query returning parameter name 4147 * value pairs. 4148 */ 4149 protected static Map<String,String> _getParameterNameValues(PreparedStatement statement) 4150 throws QueryException, SQLException 4151 { 4152 // use a linked map for predictable iteration order 4153 Map<String,String> retval = new LinkedHashMap<String,String>(); 4154 ResultSet result = null; 4155 4156 try 4157 { 4158 result = statement.executeQuery(); 4159 while(result.next()) 4160 { 4161 String name = result.getString("name"); 4162 String value = result.getString("value"); 4163 4164 if(name == null) 4165 { 4166 throw new QueryException("No name column."); 4167 } 4168 4169 if(value == null) 4170 { 4171 // NOTE: oracle returns null for empty strings 4172 value = ""; 4173 } 4174 4175 retval.put(name, value); 4176 } 4177 } 4178 catch(SQLException e) 4179 { 4180 throw new QueryException("Unable to get name value pairs: ", e); 4181 } 4182 finally 4183 { 4184 if(result != null) 4185 { 4186 result.close(); 4187 } 4188 } 4189 4190 return retval; 4191 } 4192 4193 /** Convenience routine to get a list of string SQL results. 4194 * @param query the query to execute 4195 * @param index column number of result 4196 */ 4197 protected List<String> _getStringResults(PreparedStatement query, int index) 4198 throws SQLException 4199 { 4200 List<String> retval = new LinkedList<String>(); 4201 ResultSet result = null; 4202 try 4203 { 4204 result = query.executeQuery(); 4205 while(result.next()) 4206 { 4207 retval.add(result.getString(index)); 4208 } 4209 } 4210 finally 4211 { 4212 if(result != null) 4213 { 4214 result.close(); 4215 } 4216 } 4217 return retval; 4218 } 4219 4220 /** Convenience routine to get a list of string SQL results. 4221 * @param statement statement to execute 4222 * @param queryStr the query string to execute 4223 * @param index column number of result 4224 */ 4225 protected List<String> _getStringResults(Statement statement, 4226 String queryStr, int index) throws SQLException 4227 { 4228 List<String> retval = new LinkedList<String>(); 4229 ResultSet result = null; 4230 try 4231 { 4232 result = statement.executeQuery(queryStr); 4233 while(result.next()) 4234 { 4235 retval.add(result.getString(index)); 4236 } 4237 } 4238 finally 4239 { 4240 if(result != null) 4241 { 4242 result.close(); 4243 } 4244 } 4245 return retval; 4246 } 4247 4248 4249 /** Set our prepared statements to null. */ 4250 protected void _nullPreparedStatements() 4251 { 4252 4253 _psActorFiringForTokenWrite = null; 4254 _psActorFiringsForExecution = null; 4255 _psActorFiringsForTokenRead = null; 4256 _psActorNameForFiring = null; 4257 _psActorTypeForFiring = null; 4258 _psChangesForTimespan = null; 4259 _psChangesForTimespanOnHost = null; 4260 _psDataMD5s = null; 4261 _psEntitiesForChange = null; 4262 _psEntityId = null; 4263 _psEntityIdLSID = null; 4264 _psEntityTokensForExecution = null; 4265 _psErrorForExecution = null; 4266 _psExecutions = null; 4267 _psExecutionsForAnnotation = null; 4268 _psExecutionsForTimespan = null; 4269 _psExecutionsForTimespanOnHost = null; 4270 _psExecutionsForWorkflow = null; 4271 _psExecutionsForWorkflowNameContains = null; 4272 _psExecutionsForWorkflowRuns = null; 4273 _psExecutionsForWorkflowRunsAfter = null; 4274 _psExecutionsForWorkflowRunsAt = null; 4275 _psExecutionsForWorkflowRunsBefore = null; 4276 _psExecutionsForWorkflowRuns2 = null; 4277 _psExecutionLSIDsForWorkflowRuns = null; 4278 _psExecutionIdsForTags = null; 4279 _psExecutionLSIDs = null; 4280 _psTagsForExecutionId = null; 4281 _psTagURNsForExecutionId = null; 4282 _psTypeForTag = null; 4283 _psLastChangeTime = null; 4284 _psLastChangeTimeForWorkflowId = null; 4285 _psLastExecutionForWorkflow = null; 4286 _psLastExecutionForWorkflowLSID = null; 4287 _psLastExecutionLSIDForWorkflowName = null; 4288 _psLastExecutionStartTime = null; 4289 _psLastExecutionStartTimeForWorkflowId = null; 4290 _psMoMLMD5sForExecutions = null; 4291 _psMomlForExecutionId = null; 4292 _psParamNameValuesForExecution = null; 4293 _psParamNameValuesForFiring = null; 4294 _psParamValueAtTimeForWorkflowLSID = null; 4295 _psTimestampsForExecution = null; 4296 _psTokenType = null; 4297 _psDataContents = null; 4298 _psPortEventData = null; 4299 _psTokensForExecution = null; 4300 _psTokensForFiring = null; 4301 _psTokensReadForFiring = null; 4302 _psTokensWrittenForFiring = null; 4303 _psWorkflows = null; 4304 _psWorkflowNameForLSID = null; 4305 _psWorkflowNameForExecutionLSID = null; 4306 _psPortsForActor = null; 4307 _psDoesExecutionHaveError = null; 4308 _psExecutionsForType = null; 4309 _psIsExecutionImported = null; 4310 _psUserForExecution = null; 4311 _psUserForExecutionLSID = null; 4312 _psHostIdForExecution = null; 4313 _psOutputRoleToken = null; 4314 _psInputRoleToken = null; 4315 _psParamNameValuesOfSpecificTypeForExecution = null; 4316 _psTimestampsForActorFiring = null; 4317 _psParamAndPortParamNameValuesForFiring = null; 4318 _psActorFireId = null; 4319 _psActorFirings = null; 4320 _psActorExecutionTimes = null; 4321 _psPortIOBytesRead = null; 4322 _psPortIOBytesWrite = null; 4323 //_psIOLinkRead = null; 4324 _psTimestampsForTokenRead = null; 4325 _psTimestampForTokenWrite = null; 4326 _psAssociatedKeysValuesForExecution = null; 4327 } 4328 4329 protected void _debug(String str) 4330 { 4331 System.out.println("DEBUG: " + str); 4332 } 4333 4334 /** Returns true since SQLRecordingV8 saves StringToken values 4335 * using StringToken.toString(), which adds surrounding 4336 * double-quotes. 4337 */ 4338 @Override 4339 protected boolean _stringTokenValuesHaveSurroundingQuotes() { 4340 return true; 4341 } 4342 4343 /////////////////////////////////////////////////////////////////////// 4344 //// protected fields //// 4345 4346 /** The connection to the database. */ 4347 protected DatabaseType _dbType; 4348 4349 // jdbc prepared statements for queries 4350 4351 protected PreparedStatement _psActorFiringForTokenWrite; 4352 protected PreparedStatement _psActorFiringsForExecution; 4353 protected PreparedStatement _psActorFiringsForTokenRead; 4354 protected PreparedStatement _psActorFireId; 4355 protected PreparedStatement _psActorFirings; 4356 protected PreparedStatement _psActorNameForFiring; 4357 protected PreparedStatement _psActorTypeForFiring; 4358 protected PreparedStatement _psChannelForTokenRead; 4359 protected PreparedStatement _psChannelForTokenWrite; 4360 protected PreparedStatement _psChangesForTimespan; 4361 protected PreparedStatement _psChangesForTimespanOnHost; 4362 protected PreparedStatement _psDataMD5s; 4363 protected PreparedStatement _psDoesExecutionHaveError; 4364 protected PreparedStatement _psEntitiesForChange; 4365 protected PreparedStatement _psEntityId; 4366 protected PreparedStatement _psEntityWorkflowId; 4367 protected PreparedStatement _psEntityIdLSID; 4368 protected PreparedStatement _psEntityTokensForExecution; 4369 protected PreparedStatement _psEntityType; 4370 protected PreparedStatement _psErrorForExecution; 4371 protected PreparedStatement _psExecutions; 4372 protected PreparedStatement _psExecutionsForAnnotation; 4373 protected PreparedStatement _psExecutionsForTimespan; 4374 protected PreparedStatement _psExecutionsForTimespanOnHost; 4375 protected PreparedStatement _psExecutionsForType; 4376 protected PreparedStatement _psExecutionsForWorkflow; 4377 protected PreparedStatement _psExecutionForExecutionLSID; 4378 protected PreparedStatement _psExecutionForExecutionLSIDWithoutRevision; 4379 protected PreparedStatement _psExecutionForOldestReferralExecutionLSIDWithoutRevision; 4380 protected PreparedStatement _psExecutionLSIDForExecution; 4381 protected PreparedStatement _psExecutionsForWorkflowNameContains; 4382 protected PreparedStatement _psExecutionsForWorkflowRuns; 4383 protected PreparedStatement _psExecutionsForWorkflowRunsAfter; 4384 protected PreparedStatement _psExecutionsForWorkflowRunsAt; 4385 protected PreparedStatement _psExecutionsForWorkflowRunsBefore; 4386 protected PreparedStatement _psExecutionsForWorkflowRuns2; 4387 protected PreparedStatement _psExecutionLSIDsForWorkflowRuns; 4388 protected PreparedStatement _psExecutionIdsForTags; 4389 protected PreparedStatement _psExecutionLSIDs; 4390 protected PreparedStatement _psIsExecutionImported; 4391 protected PreparedStatement _psTagsForExecutionId; 4392 protected PreparedStatement _psTagURNsForExecutionId; 4393 protected PreparedStatement _psTypeForTag; 4394 protected PreparedStatement _psLastChangeTime; 4395 protected PreparedStatement _psLastChangeTimeForWorkflowId; 4396 protected PreparedStatement _psLastExecutionForWorkflow; 4397 protected PreparedStatement _psLastExecutionForWorkflowLSID; 4398 protected PreparedStatement _psLastExecutionLSIDForWorkflowName; 4399 protected PreparedStatement _psLastExecutionLSIDForWorkflowLSID; 4400 protected PreparedStatement _psLastExecutionStartTime; 4401 protected PreparedStatement _psLastExecutionStartTimeForWorkflowId; 4402 protected PreparedStatement _psMomlForExecutionId; 4403 protected PreparedStatement _psMomlForExecutionLSID; 4404 protected PreparedStatement _psParamNameValuesForExecution; 4405 protected PreparedStatement _psParamNameValuesForFiring; 4406 protected PreparedStatement _psParamValueAtTimeForWorkflowLSID; 4407 protected PreparedStatement _psTimestampsForExecution; 4408 protected PreparedStatement _psTimestampForTokenWrite; 4409 protected PreparedStatement _psTimestampsForTokenRead; 4410 protected PreparedStatement _psTokenType; 4411 protected PreparedStatement _psPortEventData; 4412 protected PreparedStatement _psDataContents; 4413 protected PreparedStatement _psTokensForExecution; 4414 protected PreparedStatement _psTokensForFiring; 4415 protected PreparedStatement _psTokensReadForFiring; 4416 protected PreparedStatement _psTokensWrittenForFiring; 4417 protected PreparedStatement _psWorkflowRunsForExecutions; 4418 protected PreparedStatement _psWorkflowRunsForExecutionLSIDs; 4419 protected PreparedStatement _psWorkflows; 4420 protected PreparedStatement _psWorkflowNameForLSID; 4421 protected PreparedStatement _psWorkflowNameForExecutionLSID; 4422 protected Statement _psMoMLMD5sForExecutions; 4423 protected PreparedStatement _psPortsForActor; 4424 protected PreparedStatement _psHostIdForExecution; 4425 protected PreparedStatement _psUserForExecution; 4426 protected PreparedStatement _psUserForExecutionLSID; 4427 protected PreparedStatement _psOutputRoleToken; 4428 protected PreparedStatement _psInputRoleToken; 4429 protected PreparedStatement _psParamNameValuesOfSpecificTypeForExecution; 4430 protected PreparedStatement _psTimestampsForActorFiring; 4431 protected PreparedStatement _psParamAndPortParamNameValuesForFiring; 4432 protected PreparedStatement _psActorExecutionTimes; 4433 protected PreparedStatement _psPortIOBytesRead; 4434 protected PreparedStatement _psPortIOBytesWrite; 4435 protected PreparedStatement _psAssociatedKeysValuesForExecution; 4436 4437 //protected PreparedStatement _psIOLinkRead; 4438 4439 /** The most futuristic Timestamp possible! */ 4440 protected static final Timestamp _maxEndTime = new Timestamp(Long.MAX_VALUE); 4441 4442 /** The earliest Timestamp possible. */ 4443 protected static final Timestamp _minStartTime = new Timestamp(0); 4444 4445 /////////////////////////////////////////////////////////////////////// 4446 //// private methods //// 4447 4448 /** If the name of the workflow is Unnamed, change the name to the 4449 * name stored in the workflow table. 4450 */ 4451 private String _changeUnnamedWorkflow(String workflowStr) 4452 throws QueryException 4453 { 4454 String retval = workflowStr; 4455 4456 String wfName = null; 4457 Element rootElement = null; 4458 Document jdomDoc = null; 4459 4460 try 4461 { 4462 // convert to xml and get the top level name 4463 XMLParser parser = new XMLParser(); 4464 org.w3c.dom.Document doc = parser.parser(workflowStr); 4465 jdomDoc = _domBuilder.build(doc); 4466 rootElement = jdomDoc.getRootElement(); 4467 wfName = rootElement.getAttributeValue("name"); 4468 } 4469 catch(Exception e) 4470 { 4471 throw new QueryException("XML error: ", e); 4472 } 4473 4474 if(wfName == null) 4475 { 4476 throw new QueryException("No name found in workflow."); 4477 } 4478 4479 //System.out.println("name = " + wfName); 4480 4481 Matcher matcher = RenameUtil.unnamedIdPattern.matcher(wfName); 4482 if(matcher.matches()) 4483 { 4484 //System.out.println("workflow is unnamed"); 4485 4486 // get the lsid 4487 List<Element> children = rootElement.getChildren("property"); 4488 if(children.size() == 0) 4489 { 4490 throw new QueryException("No properties in workflow."); 4491 } 4492 4493 String lsidStr = null; 4494 for(Element element : children) 4495 { 4496 String name = element.getAttributeValue("name"); 4497 if(name != null && name.equals(NamedObjId.NAME)) 4498 { 4499 lsidStr = element.getAttributeValue("value"); 4500 break; 4501 } 4502 } 4503 4504 if(lsidStr == null) 4505 { 4506 throw new QueryException("Could not find LSID in workflow."); 4507 } 4508 4509 //System.out.println("lsid = " + lsidStr); 4510 4511 KeplerLSID lsid = null; 4512 try 4513 { 4514 lsid = new KeplerLSID(lsidStr); 4515 } 4516 catch(Exception e) 4517 { 4518 throw new QueryException("Error creating LSID: " + e); 4519 } 4520 4521 // get the name from the workflow table. 4522 String newName = getWorkflowName(lsid); 4523 4524 // if it's different replace it 4525 if(!wfName.equals(newName)) 4526 { 4527 rootElement.setAttribute("name", newName); 4528 retval = _outputter.outputString(jdomDoc); 4529 } 4530 } 4531 4532 return retval; 4533 } 4534 4535 /** Used to convert w3c DOM to JDOM. */ 4536 private DOMBuilder _domBuilder = new DOMBuilder(); 4537 4538 /** Used to convert XML to string. */ 4539 private XMLOutputter _outputter = new XMLOutputter(); 4540 4541 private static final int numMillisecondsInASecond = 1000; 4542 4543}