001 /** 002 * Copyright (c) 2003 Daffodil Software Ltd all rights reserved, 003 * Modifications Copyright (c) 2008 Regiscope Digital Imaging Co, LLC, All rights reserved. 004 * This program is free software; you can redistribute it and/or modify 005 * it under the terms of version 2 of the GNU General Public License as 006 * published by the Free Software Foundation. 007 * There are special exceptions to the terms and conditions of the GPL 008 * as it is applied to this software. See the GNU General Public License for more details. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018 */ 019 020 package org.dbreplicator.replication; 021 022 import java.io.*; 023 import java.net.*; 024 import java.net.UnknownHostException; 025 import java.rmi.*; 026 import java.rmi.server.*; 027 import java.sql.*; 028 import java.util.*; 029 import javax.xml.parsers.*; 030 031 import org.xml.sax.*; 032 import org.xml.sax.ContentHandler; 033 import org.dbreplicator.replication.DBHandler.*; 034 import org.dbreplicator.replication.xml.*; 035 import org.dbreplicator.replication.zip.*; 036 import java.util.ArrayList; 037 import java.io.FileOutputStream; 038 import org.dbreplicator.replication.synchronize.AbstractSynchronize; 039 import org.apache.log4j.Logger; 040 041 /** 042 * The Publication class holds all the methods which are required for the physical 043 * creation of the publication(i.e system tables) and which are used at the time 044 * of synchronization at publisher's end. It implements three interfaces, 045 * <p> 046 * _PubImpl : It makes this class to implement all the remote methods which are 047 * called by the subscriber, at the time of subscribing, taking snapshot, 048 * synchronizing and for different tasks related to synchronization. 049 * <p> 050 * _Publication : It makes this class to implement all the methods which are 051 * called by the user, at the time of publishing, and for different tasks 052 * related to publishing. 053 * <p> 054 * _Replicator : It makes this class to implement all the methods which are called 055 * at the time of synchronization to get the publisher's information. 056 * 057 */ 058 059 public class Publication 060 extends UnicastRemoteObject implements _PubImpl, _Publication, _Replicator { 061 /** 062 * name of publication 063 */ 064 private String pubName; 065 066 /** 067 * connection of server side 068 */ 069 private ConnectionPool connectionPool; 070 071 /** 072 * conflict resolver 073 */ 074 private String conflictResolver; 075 076 /** 077 * tables included in publication 078 */ 079 private ArrayList pubRepTables; 080 081 /** 082 * server side database handler 083 */ 084 private AbstractDataBaseHandler dbh; 085 086 /** 087 * number of tables included in publication 088 */ 089 public int noOfPubTables; 090 091 /** 092 * connection of server side 093 */ 094 // public Connection pubConnection; 095 096 /** 097 * handler for syncronisation 098 */ 099 SyncXMLCreator syncXMLCreator; 100 /** 101 * Tables in which updations are required during synchronisation. 102 */ 103 ArrayList usedActualTables; 104 // for locking synchronization or snapshot operations 105 // for thread safety 106 private static boolean isLocked = false; 107 private ReplicationServer localServer; 108 private static final boolean LOCK = true; 109 private static final boolean UNLOCK = false; 110 //Kept for multiple subsriber case trying to get lock 111 ArrayList listOfWaitingSubcription = new ArrayList(); 112 HashMap syncIdMap; 113 protected static Logger log = Logger.getLogger(Publication.class.getName()); 114 private boolean isPublicationCyclic; 115 String localAddress = null; 116 117 public Publication() throws RemoteException { 118 } 119 120 public Publication(ConnectionPool connectionPool0, String pubName0, 121 String serverName0, ReplicationServer localServer0) throws 122 RemoteException, RepException { 123 pubName = pubName0; 124 connectionPool = connectionPool0; 125 // make sure whether you need this connection statement or not 126 dbh = Utility.getDatabaseHandler(connectionPool, pubName); 127 dbh.setLocalServerName(serverName0); 128 //String databaseName = pubConnection.getMetaData().getDatabaseProductName(); 129 syncXMLCreator = new SyncXMLCreator(pubName, connectionPool, dbh); 130 localServer = localServer0; 131 try{ 132 //localAddress = InetAddress.getLocalHost().getHostAddress(); 133 // bjt - fix address 134 localAddress = InetAddress.getLocalHost().getHostName(); 135 } 136 catch (UnknownHostException ex) { 137 RepConstants.writeERROR_FILE(ex); 138 RepException rex = new RepException("REP056", new Object[] {pubName,ex.getMessage()}); 139 rex.setStackTrace(ex.getStackTrace()); 140 throw rex; 141 } 142 143 } 144 145 /** 146 * Sets the conflict resolver for publication. This can be one of: 147 * 148 * <ul> 149 * <li>publisher_wins</li> 150 * <li>subscriber_wins</li> 151 * </ul> 152 * 153 * @param conflictReolver0 conflict resolver 154 * @throws RepException 155 */ 156 public void setConflictResolver(String conflictReolver0) throws RepException { 157 if (! (conflictReolver0.equalsIgnoreCase(_Publication.publisher_wins) || 158 conflictReolver0.equalsIgnoreCase(_Publication.subscriber_wins))) { 159 throw new RepException("REP016", null); 160 } 161 conflictResolver = conflictReolver0; 162 log.info("conflictResolver " + conflictResolver); 163 } 164 165 /** 166 * Set the replication tables for the publication 167 * @param repTables0 list of tables 168 */ 169 public void setPublicationTables(ArrayList repTables0) { 170 pubRepTables = repTables0; 171 noOfPubTables = repTables0.size(); 172 } 173 174 public void setCyclic(boolean isCyclic){ 175 isPublicationCyclic = isCyclic; 176 for (int i = 0; i < pubRepTables.size() ; i++) { 177 ((RepTable)pubRepTables.get(i) ).setCyclicDependency(isPublicationCyclic ? "Y" : "N") ; 178 } 179 } 180 181 public boolean isPublicationCyclic(){ 182 return isPublicationCyclic; 183 } 184 185 public String getConflictResolver() throws RemoteException { 186 log.info("Returning conflictResolver " + conflictResolver); 187 return conflictResolver; 188 } 189 190 /** 191 * Set the given filter clause for the given table 192 * <p>A filter clause is simply the end of a where clause in an SQL statement. For example, to determine if your 193 * filterclause will work, insert it into this statement, where tablename is the table to which the filter is being 194 * applied:</p> 195 * <code>select * from <tablename> where <filterclause></code> 196 * <p>As you can see, the filterclause can be almost anything, including subselects.</p> 197 * 198 * @param tableName0 for which filter clause is to be added 199 * @param filterClause0 filter clause to be set 200 * @throws RepException if table does not exist or if filter clause is invalid 201 */ 202 public void setFilter(String tableName0, String filterClause0) throws RepException { 203 setFilter(tableName0, filterClause0, 0); 204 } 205 206 public void setFilter(String tableName0, String filterClause0, int paramCount0) throws RepException { 207 Connection pubConnection = null; 208 Statement stmt = null; 209 ResultSet rs = null; 210 try { 211 pubConnection = connectionPool.getConnection(pubName); 212 MetaDataInfo mdi = Utility.getDatabaseMataData(pubConnection); 213 SchemaQualifiedName sname = new SchemaQualifiedName(mdi, tableName0); 214 if (tableName0.indexOf('.') == -1) { 215 mdi.checkTableExistance(sname); 216 } 217 log.debug("Table name : " + tableName0); 218 log.debug("pubRepTables : " + pubRepTables); 219 log.info("Set the filter : " + filterClause0 + " for table " + tableName0); 220 for (int i = 0, size = pubRepTables.size(); i < size; i++) { 221 RepTable repTable = (RepTable) pubRepTables.get(i); 222 String sqname = repTable.getSchemaQualifiedName().toString(); 223 if (sqname.equalsIgnoreCase(sname.toString())) { 224 String query = "Select * from " + sqname + " where " + filterClause0; 225 try { 226 PreparedStatement st = pubConnection.prepareStatement(query); 227 if (paramCount0 > 0) { 228 for (int j = 1; j <= paramCount0; j++) { 229 st.setString(j, null); 230 } 231 } 232 rs = st.executeQuery(); 233 rs.next(); 234 } 235 catch (SQLException ex1) { 236 RepConstants.writeERROR_FILE(ex1); 237 RepException rex = new RepException("REP019",new Object[] {filterClause0}); 238 rex.setStackTrace(ex1.getStackTrace()); 239 throw rex; 240 } 241 repTable.setFilterClause(filterClause0); 242 log.debug("Filter clause set successfully "); 243 return; 244 } 245 } 246 throw new RepException("REP017", new Object[] {tableName0}); 247 } 248 finally { 249 connectionPool.removeSubPubFromMap(pubName); 250 try { 251 if (rs != null) { 252 rs.close(); 253 if (stmt != null) 254 stmt.close(); 255 } 256 } 257 catch (SQLException ex) { 258 //Ignore the Exception 259 } 260 connectionPool.returnConnection(pubConnection); 261 } 262 } 263 264 265 /** 266 * This method come in use if tables in a publications are refering to 267 * each other and It is required to 268 * 269 * @param tableName0 String 270 * @param createShadowTable boolean 271 * @throws RepException 272 */ 273 public void setCreateShadowTable(String tableName0, boolean createShadowTable) throws 274 RepException { 275 Connection connection = null; 276 try { 277 connection = connectionPool.getConnection(pubName); 278 MetaDataInfo mdi = Utility.getDatabaseMataData(connection); 279 SchemaQualifiedName sname = new SchemaQualifiedName(mdi, tableName0); 280 if (tableName0.indexOf('.') == -1) { 281 mdi.checkTableExistance(sname); 282 } 283 RepTable repTable = getRepTable(sname.toString()); 284 repTable.setCreateShadowTable(createShadowTable ? RepConstants.YES :RepConstants.NO); 285 } 286 finally { 287 connectionPool.returnConnection(connection); 288 } 289 } 290 291 292 /** 293 * This method is responsible for creating required system tables in publication database 294 * and shadow tables and triggers on tables to be published. It is required for replication 295 * and saves data into system tables about the publication. 296 * 297 * @throws RepException 298 */ 299 public void publish() throws RepException { 300 Connection connection = null; 301 Statement stmt =null; 302 try { 303 //Creates Publication Table 304 //Creates BookMark Table 305 //Creates Super Log Table 306 //Creates Rep Table 307 connection = connectionPool.getConnection(pubName); 308 stmt = connection.createStatement(); 309 dbh.createRemoteSystemTables(pubName); 310 SchemaQualifiedName[] tableNames = getSchemaQualifiedTableNames(); 311 MetaDataInfo mdi = Utility.getDatabaseMataData(connection); 312 for (int i = 0; i < tableNames.length; i++) { 313 RepTable repTable = getRepTable(tableNames[i].toString()); 314 if (repTable.getCreateShadowTable().equalsIgnoreCase(RepConstants.NO)) 315 continue; 316 String schema = tableNames[i].getSchemaName(); 317 String table = tableNames[i].getTableName(); 318 ArrayList colInfoList = mdi.getColumnDataTypeInfo(dbh, schema, table); 319 //Searches pubRepTables by the tablename and returns the corresponding object of RepTable and calls function 320 String[] primCols = getRepTable(tableNames[i].toString()).getPrimaryColumns(); 321 //We will get a sequence of columns and there datatypes along with primary columns and there datatypes. 322 //as " col1 number(10),col2 varchar2(24),old_col1 number(10) " 323 String allColSequence = dbh.getShadowTableColumnDataTypeSequence(colInfoList, primCols,repTable); 324 //Creates Shadow Tables For all the participating tables 325 dbh.createShadowTable(pubName, tableNames[i].toString(), allColSequence,primCols); 326 dbh.makeProvisionForLOBDataTypes(colInfoList); 327 dbh.createShadowTableTriggers(pubName, tableNames[i].toString(),colInfoList, primCols); 328 } 329 //Add an entry in Publication table And Rep Table 330 savePublicationData(dbh,connection,stmt); 331 } 332 catch (SQLException ex) { 333 RepConstants.writeERROR_FILE(ex); 334 throw new RepException("REP020", new Object[] {ex.getMessage()}); 335 } 336 catch (Throwable ex) { 337 log.error(ex, ex); 338 throw new RepException("REP020", new Object[] {ex.getMessage()}); 339 } 340 finally { 341 connectionPool.removeSubPubFromMap(pubName); 342 try { 343 if (stmt != null) { 344 stmt.close(); 345 } 346 } 347 catch (SQLException ex1) { 348 } 349 connectionPool.returnConnection(connection); 350 } 351 } 352 353 /** 354 * Saves the publication name and its tables into server side replication 355 * system tables. 356 * @param dbh database handler for server side 357 * @throws RepException 358 */ 359 private void savePublicationData(AbstractDataBaseHandler dbh,Connection connection,Statement stmt) throws 360 RepException { 361 try { 362 log.info("conflictResolver " + conflictResolver); 363 if (conflictResolver == null) { 364 log.info("setting conflictResolver " + publisher_wins + " by default"); 365 conflictResolver = RepConstants.publisher_wins; 366 // Insert Into Pulication Table 367 } 368 StringBuffer insertquery = new StringBuffer(); 369 insertquery.append("insert into " + dbh.getPublicationTableName() +" values ( '") 370 .append(pubName).append("' ,'").append(conflictResolver) 371 .append("','").append(dbh.getLocalServerName()).append("' )"); 372 stmt.execute(insertquery.toString()); 373 log.info("Query exceuted:" + insertquery.toString()); 374 375 // Insert Into Rep Table, for all tables in publication 376 for (int i = 0; i < noOfPubTables; i++) { 377 RepTable repTable = (RepTable) pubRepTables.get(i); 378 repTable.setConflictResolver(conflictResolver); 379 dbh.saveRepTableData(connection, pubName, repTable); 380 // NEW REP TABLE VIOLATION SACHIN 381 } 382 } 383 catch (SQLException ex) { 384 RepConstants.writeERROR_FILE(ex); 385 throw new RepException("REP035", new Object[] {pubName}); 386 } 387 388 } 389 390 private void appendValue(StringBuffer sb, Object value) { 391 if (value == null) { 392 sb.append(value); 393 } 394 else { 395 sb.append("'" + value + "'"); 396 } 397 } 398 399 /** 400 * This method is responsible to assist to subscribe a subscription. This 401 * method creates a XML file to get all the tables involved in the publication 402 * and makes an entry in bookmark table of serverside to save the publication 403 * name with the subscription. 404 * @param clientVendorType0 client database type i.e. oracle or sql server 405 * @param subName Subscription Name 406 * @param address IP Address 407 * @param isSchemaSupported True/False (boolean) 408 * @param fileUpload 409 * @param remoteMachineAddress IP Address 410 * @throws RemoteException 411 * @throws RepException 412 */ 413 public void createStructure(int clientVendorType0, String subName,String address, boolean isSchemaSupported,_FileUpload fileUpload,String remoteMachineAddress) throws 414 RemoteException, RepException { 415 FileOutputStream fos = null; 416 OutputStreamWriter os = null; 417 try { 418 if (pubRepTables == null) { 419 return; 420 } 421 //Do entry in the BookMark Table of publication for each 422 //participatig tables in the publication with subscription detail 423 int srcVendorType = Utility.getVendorType(connectionPool, pubName); 424 Connection connection = null; 425 try { 426 String filePath = PathHandler.getDefaultFilePathForCreateStructure("struct_" + pubName + "_" +subName); 427 fos = new FileOutputStream(filePath); 428 os = new OutputStreamWriter(fos); 429 os.write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"); 430 os.write("<Database>\r\n"); 431 connection = connectionPool.getConnection(pubName); 432 TreeMap primCons = new TreeMap(String.CASE_INSENSITIVE_ORDER); 433 MetaDataInfo mdi = Utility.getDatabaseMataData(connection); 434 AbstractDataBaseHandler dbh = Utility.getDatabaseHandler(connectionPool,pubName); 435 ArrayList foreignKeyQueries = new ArrayList(); 436 for (int i = 0; i < noOfPubTables; i++) { 437 RepTable repTable = (RepTable) pubRepTables.get(i); 438 SchemaQualifiedName sname = repTable.getSchemaQualifiedName(); 439 StringBuffer createTableQuery = new StringBuffer(); 440 String schema = sname.getSchemaName(); 441 String table = sname.getTableName(); 442 if(isSchemaSupported){ 443 createTableQuery.append(" Create Table ").append(schema + "." +table) 444 .append(" ( ").append(mdi.generateColumnsQueryForClientNode(dbh,srcVendorType, schema, table, clientVendorType0)) 445 .append(mdi.getAppliedConstraints(schema, table, primCons)).append(")"); 446 }else{ 447 createTableQuery.append(" Create Table ").append(table) 448 .append(" ( ").append(mdi.generateColumnsQueryForClientNode(dbh,srcVendorType, schema, table, clientVendorType0)) 449 .append(mdi.getAppliedConstraints(schema, table, primCons)).append(")"); 450 } 451 if (isSchemaSupported) { 452 os.write("<SchemaName>"); 453 os.write(schema); 454 os.write("</SchemaName>"); 455 } 456 os.write("<Table>"); 457 os.write("<Query>"); 458 os.write(createTableQuery.toString()); 459 os.write("</Query>\n"); 460 os.write("<TableName>"); 461 if (isSchemaSupported) { 462 os.write(sname.toString()); 463 } else { 464 os.write(table); 465 } 466 os.write("</TableName>\r\n"); 467 os.write("<PrimaryColumns>\r\n"); 468 String[] primCols = repTable.getPrimaryColumns(); 469 for (int j = 0; j < primCols.length; j++) { 470 os.write("<ColumnName>"); 471 os.write(primCols[j]); 472 os.write("</ColumnName>"); 473 } 474 os.write("</PrimaryColumns>\r\n"); 475 os.write("<ForeignKeyColumns>\r\n"); 476 String[] foreignKeyCols = repTable.getForeignKeyCols(); 477 if (foreignKeyCols != null) { 478 for (int j = 0, size = foreignKeyCols.length; j < size; j++) { 479 os.write("<FKColumnName>"); 480 os.write(foreignKeyCols[j]); 481 os.write("</FKColumnName>"); 482 } 483 } 484 os.write("</ForeignKeyColumns>\r\n"); 485 String[] columnstoBeIgnored = repTable.getColumnsToBeIgnored(); 486 os.write("<IgnoredColumns>\r\n"); 487 if (columnstoBeIgnored != null) { 488 for (int j = 0, size = columnstoBeIgnored.length; j < size; j++) { 489 os.write("<IgnoredColumnName>"); 490 os.write(columnstoBeIgnored[j]); 491 os.write("</IgnoredColumnName>"); 492 } 493 } 494 os.write("</IgnoredColumns>\r\n"); 495 os.write("<FilterClause>"); 496 if (repTable.getFilterClause() == null) { 497 os.write("NO_DATA"); 498 } 499 else { 500 os.write("<![CDATA["); 501 os.write(repTable.getFilterClause()); 502 os.write("]]>"); 503 } 504 os.write("</FilterClause>"); 505 506 os.write("<CreateShadowTable>"); 507 os.write(repTable.getCreateShadowTable()); 508 os.write("</CreateShadowTable>"); 509 os.write("<CyclicDependency>"); 510 os.write(repTable.getCyclicDependency()); 511 os.write("</CyclicDependency>"); 512 os.write("</Table>\r\n"); 513 } 514 515 for (int i = 0; i < noOfPubTables; i++) { 516 RepTable repTable = (RepTable) pubRepTables.get(i); 517 SchemaQualifiedName sname = repTable.getSchemaQualifiedName(); 518 ArrayList alterTabelStatements = mdi.getForeignKeyConstraints(sname.getSchemaName(), sname.getTableName()); 519 if (alterTabelStatements != null && alterTabelStatements.size() > 0) { 520 foreignKeyQueries.addAll(alterTabelStatements); 521 } 522 } 523 for (int i = 0, size = foreignKeyQueries.size(); i < size; i++) { 524 os.write("<AlterTableForeignKeyStatement>"); 525 os.write( (String) foreignKeyQueries.get(i)); 526 os.write("</AlterTableForeignKeyStatement>"); 527 } 528 529 os.write("</Database>\r\n"); 530 os.close(); 531 String localMachineAddress = InetAddress.getLocalHost().getHostName(); 532 if(!localMachineAddress.equalsIgnoreCase(remoteMachineAddress)) { 533 String zipFilePath = PathHandler.getDefaultZIPFilePathForCreateStructure("struct_" + pubName + "_" +subName); 534 ZipHandler.makeStructZip(zipFilePath, filePath,"struct_" + pubName + "_" + subName); 535 WriteOnSocket writeOnSocket = new WriteOnSocket(zipFilePath, filePath,Publication.xmlAndShadow_entries,"struct_" + pubName + "_" + subName, fileUpload, false); 536 writeOnSocket.start(); 537 writeOnSocket.join(); 538 } 539 log.debug("wrote XMLFile ClientSocket "); 540 } 541 catch (IOException ex) { 542 RepConstants.writeERROR_FILE(ex); 543 RemoteException rem = new RemoteException(ex.getMessage()); 544 rem.setStackTrace(ex.getStackTrace()); 545 RepConstants.writeERROR_FILE(rem); 546 throw rem; 547 } 548 catch (InterruptedException ex) { 549 RepConstants.writeERROR_FILE(ex); 550 RemoteException rem = new RemoteException(ex.getMessage()); 551 rem.setStackTrace(ex.getStackTrace()); 552 RepConstants.writeERROR_FILE(rem); 553 throw rem; 554 555 } 556 finally { 557 connectionPool.returnConnection(connection); 558 } 559 } 560 finally { 561 try { 562 os.close(); 563 fos.close(); 564 } 565 catch (IOException ex1) { 566 // Ignore the Exception 567 } 568 } 569 } 570 571 public Object[] getPublisherAddressAndPort() throws 572 RemoteException, RepException { 573 try { 574 Integer portNumber = null; 575 ServerSocket serverSocket = connectionPool.startServerSocket(); 576 portNumber = new Integer(serverSocket.getLocalPort()); 577 syncXMLCreator.serverSocket = serverSocket; 578 return new Object[] {localAddress, portNumber}; 579 } 580 finally { 581 connectionPool.removeSubPubFromMap(pubName); 582 } 583 584 } 585 586 587 /** 588 * Inserts a row into bookmark table of server side to put a matching pair of 589 * publication name and subscription name. 590 * @param subName sub name 591 * @throws RepException 592 */ 593 public void saveSubscriptionData(String subName) throws RemoteException { 594 Connection connection = null; 595 Statement stt = null; 596 try { 597 connection = connectionPool.getConnection(pubName); 598 stt = connection.createStatement(); 599 for (int i = 0; i < noOfPubTables; i++) { 600 RepTable repTable = (RepTable) pubRepTables.get(i); 601 StringBuffer sb0 = new StringBuffer(); 602 sb0.append(" Insert into ").append(dbh.getBookMarkTableName()).append( 603 " values ( '").append(pubName).append("','").append(subName).append( 604 "','").append(repTable.getSchemaQualifiedName()).append("',0,0,'N')"); 605 stt.execute(sb0.toString()); 606 } 607 } 608 catch (SQLException ex) { 609 RepConstants.writeERROR_FILE(ex); 610 throw new RemoteException(ex.getMessage()); 611 } 612 catch (RepException ex) { 613 RepConstants.writeERROR_FILE(ex); 614 throw new RemoteException(ex.getMessage()); 615 } 616 finally { 617 connectionPool.removeSubPubFromMap(pubName); 618 try { 619 if (stt != null) 620 stt.close(); 621 try { 622 connectionPool.returnConnection(connection); 623 } 624 catch (RepException ex) { 625 // Ignore the exception 626 } 627 } 628 catch (SQLException ex1) { 629 // Ignore the exception 630 } 631 } 632 } 633 634 /** 635 * creates an XMl file for getting Snapshot on clients side. 636 * Do entry in the server side bookmark table. 637 * Deletes all records from the server side log table. 638 * 639 * @param subName String 640 * @param isSchemaSupported True/False (boolean) 641 * @param fileUpload 642 * @param remoteMachineAddress IP Address 643 * @throws SQLException 644 * @throws RemoteException 645 * @throws RepException 646 */ 647 public void createSnapShot(String subName,boolean isSchemaSupported,_FileUpload fileUpload,String remoteMachineAddress) throws SQLException, RemoteException, RepException { 648 Connection pubConnection = null; 649 Statement stmt = null; 650 ResultSet rows = null, shadowResult = null; 651 try { 652 FileOutputStream fos = new FileOutputStream(PathHandler.getDefaultFilePathForClient("snapshot_" + pubName + "_" +subName)); 653 OutputStreamWriter os = new OutputStreamWriter(fos); 654 BufferedWriter bw = new BufferedWriter(os); 655 pubConnection = connectionPool.getConnection(pubName); 656 stmt =pubConnection.createStatement(); 657 /* Leave for debugging/timing purposes */ 658 /* long startTime=System.currentTimeMillis(); */ 659 XMLWriter xmlWriter = new XMLWriter(bw, dbh, pubConnection); 660 bw.write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"); 661 bw.write("<root_snapshot>"); 662 String tableName; 663 SchemaQualifiedName sname; 664 String[] primaryKeyColumns; 665 stmt = pubConnection.createStatement(); 666 for (int i = 0; i < noOfPubTables; i++) { 667 RepTable repTable = (RepTable) pubRepTables.get(i); 668 primaryKeyColumns =repTable.getPrimaryColumns(); 669 if (repTable.getCreateShadowTable().equalsIgnoreCase(RepConstants.NO)) 670 continue; 671 sname = (repTable).getSchemaQualifiedName(); 672 tableName = isSchemaSupported ? sname.toString() : sname.getTableName(); 673 ArrayList encodedCols = PathHandler.getEncodedColumns(tableName); 674 bw.write("<tableName>"); 675 bw.write(tableName); 676 String query; 677 String[] parameters = null; 678 if (repTable.getFilterClause() == null || repTable.getFilterClause().equalsIgnoreCase("")) { 679 query = "Select * from " + repTable.getRepTableQualifiedIdentifier(); 680 } 681 else { 682 query = "Select * from " + repTable.getRepTableQualifiedIdentifier() + " where " + repTable.getFilterClause(); 683 } 684 685 /** @todo comment the method getResultSet and create the statement 686 * outside the loop as anywhere as require.*/ 687 688 log.debug("running " + query); 689 pubConnection.setAutoCommit(false); 690 Statement st = pubConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY); 691 st.setFetchSize(1000); 692 rows = st.executeQuery(query); // Query 693 log.debug("getting metadata"); 694 ResultSetMetaData rsmt = rows.getMetaData(); 695 log.debug("getting column count"); 696 int noOfColumns = rsmt.getColumnCount(); 697 log.debug("getting PrimaryKeyResultSet"); 698 ResultSet primayKeyResultSet =getPrimaryKeyResultSet(stmt,tableName,repTable.getPrimaryColumns()); 699 log.debug("Starting to loop through rows"); 700 while (rows.next()) { 701 bw.write("<operation>"); 702 bw.write("I"); 703 bw.write("<row>"); 704 for (int c = 1; c <= noOfColumns; c++) { 705 String columnName = rsmt.getColumnName(c); 706 if (!encodedCols.contains(columnName.toUpperCase())) { 707 bw.write("<c" + c + ">"); 708 } 709 else { 710 bw.write("<c" + c + " Encode=\"y\">"); 711 } 712 // Special Handelling for Blob Clob Case 713 xmlWriter.write(rows, c, encodedCols, columnName); 714 bw.write("</c" + c + ">\r\n"); 715 } 716 bw.write("</row>\r\n"); 717 xmlWriter.writePrimaryKeyElement(primaryKeyColumns,primayKeyResultSet,encodedCols); 718 bw.write("</operation>\r\n"); 719 primayKeyResultSet.next(); 720 bw.flush(); 721 } 722 // Close the resultset because new instance of resultset has been created for each table. 723 pubConnection.commit(); 724 rows.close(); 725 bw.write("</tableName>\r\n"); 726 // updating values for bookmark table 727 String selectMaxSyncID= " select " + RepConstants.shadow_sync_id1 + " from " + 728 RepConstants.shadow_Table(tableName) + " order by " + 729 RepConstants.shadow_sync_id1 + " desc limit 1"; 730 log.debug(selectMaxSyncID); 731 pubConnection.setAutoCommit(true); 732 shadowResult = stmt.executeQuery(selectMaxSyncID); 733 Object maxvalue = null; 734 if (shadowResult.next()) { 735 maxvalue = shadowResult.getObject(1); 736 } 737 if (maxvalue == null) { 738 maxvalue = new Long(0); 739 } 740 log.debug("max(" + RepConstants.shadow_sync_id1 + ")=" + maxvalue); 741 StringBuffer updateBookmarkQuery = new StringBuffer("update " +dbh.getBookMarkTableName() + " set "); 742 updateBookmarkQuery.append(RepConstants.bookmark_lastSyncId4 + " = " +maxvalue + ", "); 743 updateBookmarkQuery.append(RepConstants.bookmark_ConisderedId5 + " = " +maxvalue + " "); 744 updateBookmarkQuery.append(" where " + RepConstants.bookmark_LocalName1 +" ='" + pubName + "' "); 745 updateBookmarkQuery.append(" and " + RepConstants.bookmark_RemoteName2 +" ='" + subName + "' "); 746 updateBookmarkQuery.append(" and " + RepConstants.bookmark_TableName3 +" ='" + tableName + "'"); 747 stmt.executeUpdate(updateBookmarkQuery.toString()); 748 log.debug(updateBookmarkQuery.toString()); 749 } 750 bw.write("</root_snapshot>\r\n"); 751 /* Keep for debugging / timing */ 752 /* System.out.println("TIME TAKEN IN CREATING XML FOR SNAPSHOT:::"+(System.currentTimeMillis()-startTime)); */ 753 if(bw!=null) 754 bw.close(); 755 fos.close(); 756 757 localAddress = InetAddress.getLocalHost().getHostName(); 758 if(!localAddress.equalsIgnoreCase(remoteMachineAddress)) { 759 // making zip file from xml file 760 ZipHandler.makeZip(PathHandler.getDefaultZIPFilePathForClient("snapshot_" +pubName + "_" + subName), 761 PathHandler.getDefaultFilePathForClient("snapshot_" +pubName + "_" + subName), 762 "snapshot_" + pubName + "_" + subName /*+ ".xml"*/); 763 // writing zip file on socket 764 WriteOnSocket writeOnSocket = new WriteOnSocket(PathHandler.getDefaultZIPFilePathForClient("snapshot_" + pubName + "_" +subName), 765 PathHandler.getDefaultFilePathForClient("snapshot_" + pubName + "_" + subName),_Publication.xmlAndShadow_entries, 766 "snapshot_" + pubName + "_" + subName, fileUpload, true); 767 writeOnSocket.start(); 768 writeOnSocket.join(); 769 } 770 dbh.deleteRecordsFromSuperLogTable(stmt); 771 } 772 773 catch (FileNotFoundException ex) { 774 RepConstants.writeERROR_FILE(ex); 775 throw new RepException("REP085", null); 776 } //Temporary Snapshot File Can not created. 777 catch (IOException ex) { 778 RepConstants.writeERROR_FILE(ex); 779 RepException rex = new RepException("REP086", new Object[] {ex.getMessage()}); 780 rex.setStackTrace(ex.getStackTrace()); 781 throw rex; 782 } 783 catch (SQLException ex) { 784 RepConstants.writeERROR_FILE(ex); 785 RepException rex = new RepException("REP055", new Object[] {pubName,ex.getMessage()}); 786 rex.setStackTrace(ex.getStackTrace()); 787 throw rex; 788 } 789 catch (RepException ex) { 790 RepConstants.writeERROR_FILE(ex); 791 throw ex; 792 } 793 catch (InterruptedException ex) { 794 RepConstants.writeERROR_FILE(ex); 795 RepException rex = new RepException("REP055", new Object[] {pubName,ex.getMessage()}); 796 rex.setStackTrace(ex.getStackTrace()); 797 throw rex; 798 } 799 finally { 800 // bjt 801 // connectionPool.removeSubPubFromMap(pubName); 802 /** @todo Close the statement */ 803 if (shadowResult != null) 804 shadowResult.close(); 805 if (stmt != null) 806 stmt.close(); 807 isLocked = UNLOCK; 808 pubConnection.setAutoCommit(true); 809 connectionPool.returnConnection(pubConnection); 810 } 811 812 } 813 814 /** 815 * Creates an XML file for synchronization purpose and send it to subscriber's 816 * socket. 817 * Creates a server socket and send's it's information to the subscriber, 818 * so that subscriber can transfer file over it. 819 * 820 * @param subName String 821 * @param clientServerName String 822 * @param isSchemaSupported boolean 823 * @param fileUpload 824 * @param remoteMachineAddress String 825 * @return Object[] 826 * @throws RemoteException 827 * @throws RepException 828 */ 829 830 public Object[] createXMLForClient(String subName, String clientServerName,boolean isSchemaSupported, _FileUpload fileUpload,String remoteMachineAddress) throws 831 RemoteException, RepException { 832 Object[] usedActualTablesLastSyncId; 833 Object[] LastSyncId = null; 834 String localAddress = null; 835 Integer portNumber = null; 836 try { 837 localAddress = InetAddress.getLocalHost().getHostName(); 838 if (noOfPubTables > 0) { 839 usedActualTablesLastSyncId = syncXMLCreator.createXMLFile(PathHandler. 840 getDefaultFilePathForClient("server_" + pubName + "_" +subName) // xml file path 841 , PathHandler.getDefaultZIPFilePathForClient("server_" + pubName + "_" +subName) // zip file path 842 , "server_" + pubName + "_" +subName//+ ".xml" // xml file name 843 , subName, pubRepTables, clientServerName, 844 noOfPubTables,_Publication.xmlAndShadow_entries, pubName,isSchemaSupported,fileUpload,localAddress,remoteMachineAddress); 845 846 usedActualTables = (ArrayList) usedActualTablesLastSyncId[0]; 847 LastSyncId = (Object[]) usedActualTablesLastSyncId[1]; 848 } 849 850 ServerSocket serverSocket = connectionPool.startServerSocket(); 851 localAddress = null; 852 try { 853 //localAddress = InetAddress.getLocalHost().getHostAddress(); 854 // bjt - fix address 855 localAddress = InetAddress.getLocalHost().getHostName(); 856 } 857 catch (UnknownHostException ex) { 858 RepConstants.writeERROR_FILE(ex); 859 RepException rex = new RepException("REP056", new Object[] {pubName,ex.getMessage()}); 860 rex.setStackTrace(ex.getStackTrace()); 861 throw rex; 862 } 863 portNumber = new Integer(serverSocket.getLocalPort()); 864 syncXMLCreator.serverSocket = serverSocket; 865 } 866 catch (RepException ex1) { 867 ex1.printStackTrace(); 868 RepConstants.writeERROR_FILE(ex1); 869 throw ex1; 870 } 871 catch (Exception ex1) { 872 ex1.printStackTrace(); 873 RepConstants.writeERROR_FILE(ex1); 874 throw new RepException("REP054", new Object[] {subName, ex1.getMessage()}); 875 } 876 catch (Throwable ex1) { 877 ex1.printStackTrace(); 878 log.error(ex1.getMessage(), ex1); 879 throw new RepException("REP054", new Object[] {subName, ex1.getMessage()}); 880 }finally { 881 connectionPool.removeSubPubFromMap(pubName); 882 } 883 return new Object[] {localAddress, portNumber, LastSyncId}; 884 } 885 886 887 888 889 private ResultSet getResultSet(String preparedQuery, String[] parameters) throws 890 SQLException,RepException { 891 Connection pubConnection = null; 892 try 893 { 894 pubConnection = connectionPool.getConnection(pubName); 895 //PreparedStatement pst = pubConnection.prepareStatement(preparedQuery); 896 // bjt - below *seems* to work 897 PreparedStatement pst = pubConnection.prepareStatement(preparedQuery,ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY); 898 if (parameters != null) { 899 for (int i = 0, size = parameters.length; i < size; i++) { 900 pst.setString(i + 1, parameters[i]); 901 } 902 } 903 // bjt - attempt to tell postgres to not hold the whole resultset in memory 904 pst.setFetchSize(1); 905 return pst.executeQuery(); 906 } finally { 907 connectionPool.returnConnection(pubConnection); 908 // bjt 909 //connectionPool.removeSubPubFromMap(pubName); 910 } 911 } 912 913 /** 914 * merges the data between the client side and server side. 915 * @param subName 916 * @param remoteServerName 917 * @throws RemoteException 918 * @throws RepException 919 */ 920 public synchronized void synchronize(String subName, String remoteServerName,boolean isCreateTransactionLogFile,String remoteMachineAddress) throws 921 RemoteException, RepException { 922 BufferedWriter bw = null; 923 Connection pubConnection = null; 924 Connection subConnection = null; 925 Statement stmt = null; 926 ResultSet rs = null; 927 boolean isCurrentTableCyclic =false; 928 String localMachineAddress=null; 929 try { 930 Utility.createTransactionLogFile = isCreateTransactionLogFile; 931 localMachineAddress =InetAddress.getLocalHost().getHostName(); 932 933 // unzipping zip file from client 934 if(!localMachineAddress.equalsIgnoreCase(remoteMachineAddress)) { 935 ZipHandler.unZip(PathHandler.getDefaultZIPFilePathForClient("client_" +subName + "_" + pubName),PathHandler.getDefaultFilePathForClient("client_" +subName + "_" + pubName)); 936 } 937 SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); 938 XMLReader reader = saxParser.getXMLReader(); 939 subConnection = connectionPool.getConnection(subName); 940 pubConnection = connectionPool.getConnection(pubName); 941 MergeHandler mg = new MergeHandler(true, subConnection, this, 942 remoteServerName, dbh, bw, 943 "MERGE REPLICATION", 944 PathHandler. 945 fullOrPartialTransactionLogFile(),Utility.getDatabaseMataData(pubConnection)); 946 mg.setLocalName(pubName); 947 mg.setRemoteName(subName); 948 ContentHandler ch = mg; 949 reader.setContentHandler(ch); 950 951 //initializing hashmap for maxSyncId for updating consideredId of bookMarkTable further 952 syncIdMap = new HashMap(); 953 RepTable repTable=null; 954 for (int i = 0; i < pubRepTables.size(); i++) { 955 repTable =(RepTable) pubRepTables.get(i); 956 String tableName = repTable.getSchemaQualifiedName().toString(); 957 isCurrentTableCyclic = repTable.getCyclicDependency().equalsIgnoreCase(RepConstants.YES); 958 StringBuffer query = new StringBuffer(); 959 stmt = pubConnection.createStatement(); 960 query.append(" select ").append(RepConstants.shadow_sync_id1). 961 append(" from ").append(RepConstants.shadow_Table(tableName)). 962 append(" order by ").append(RepConstants.shadow_sync_id1). 963 append(" desc limit 1"); 964 rs = stmt.executeQuery(query.toString()); 965 long syncIdValue = new Long(0); 966 if(rs.next()) { 967 syncIdValue = rs.getLong(1); 968 } 969 syncIdMap.put(tableName, syncIdValue); 970 long maxSynId = syncIdValue; 971 syncIdMap.put(tableName, new Long(maxSynId)); 972 } 973 reader.parse(PathHandler.getDefaultFilePathForClient("client_" + subName + "_" +pubName)); 974 makePublicationTransactionLogFile(pubName,mg,bw); 975 mg.closeAllStatementAndResultset(); 976 977 /** 978 * Following code has been written to handle the case of cyclic table and update the value of all the columns that are set to null in first pass. 979 */ 980 if(isCurrentTableCyclic){ 981 982 MergeHandler mg1 = new MergeHandler(false, subConnection, this, 983 remoteServerName, dbh, bw, 984 "MERGE REPLICATION", 985 PathHandler. 986 fullOrPartialTransactionLogFile(),Utility.getDatabaseMataData(pubConnection)); 987 mg1.setLocalName(pubName); 988 mg1.setRemoteName(subName); 989 ContentHandler ch1 = mg1; 990 reader.setContentHandler(ch1); 991 reader.parse(PathHandler.getDefaultFilePathForClient("client_" + subName + "_" +pubName)); 992 makePublicationTransactionLogFile(pubName,mg,bw); 993 mg1.closeAllStatementAndResultset(); 994 } 995 996 if (_Publication.xmlAndShadow_entries) { 997 // deleting XML file 998 deleteFile(PathHandler.getDefaultFilePathForClient("client_" + subName + "_" +pubName)); 999 // deleting zip file 1000 deleteFile(PathHandler.getDefaultZIPFilePathForClient("client_" +subName + "_" +pubName)); 1001 } 1002 deleteRecordsFromSuperLogTable(stmt); 1003 for (int i = 0; i < pubRepTables.size(); i++) { 1004 repTable = (RepTable) pubRepTables.get(i); 1005 if (repTable.getCreateShadowTable().equalsIgnoreCase(RepConstants.NO)) 1006 continue; 1007 String tableName = ( (RepTable) pubRepTables.get(i)).getSchemaQualifiedName().toString(); 1008 // we have updated last sync id at the time of creating xml file too beacause of any power failure or other reasons 1009 // we are also updating Coincederd Id as well as Last Sync Id so that we do not 1010 // get last record while making xml file previously from shadow table in next cycle of synchronisation 1011 // as client changes can also occur at server whihc are not to be sent back to client. 1012 UpdateConisdered_LastsyncIdForBookMarksTable(pubName, subName,tableName, ((Number) syncIdMap.get(tableName)).toString(),stmt); 1013 } 1014 1015 syncIdMap.clear(); 1016 if (_Publication.xmlAndShadow_entries) { 1017 deleteRecordsFromShadowTable(stmt); 1018 } 1019 1020 } 1021 catch (Exception ex) { 1022 if(Utility.createTransactionLogFile) { 1023 AbstractSynchronize.writeUnsuccessfullOperationInTransaction(bw); 1024 } 1025 RepConstants.writeERROR_FILE(ex); 1026 RepException rex = null; 1027 if (ex instanceof SAXException) { 1028 Exception e = ( (SAXException) ex).getException(); 1029 if (e instanceof RepException) { 1030 throw (RepException) e; 1031 } 1032 else { 1033 rex = new RepException("REP056", new Object[] {pubName, e.getMessage()}); 1034 rex.setStackTrace(e.getStackTrace()); 1035 throw rex; 1036 } 1037 } 1038 else { 1039 rex = new RepException("REP056", new Object[] {pubName, ex.getMessage()}); 1040 rex.setStackTrace(ex.getStackTrace()); 1041 } 1042 throw rex; 1043 } 1044 finally { 1045 connectionPool.removeSubPubFromMap(pubName); 1046 try { 1047 if (rs != null) { 1048 rs.close(); 1049 } 1050 if (stmt != null) { 1051 stmt.close(); 1052 } 1053 } 1054 catch (SQLException ex1) { 1055 } 1056 try { 1057 if(bw!=null) 1058 bw.close(); 1059 } 1060 catch (IOException ex2) { 1061 } 1062 connectionPool.returnConnection(subConnection); 1063 connectionPool.returnConnection(pubConnection); 1064 } 1065 } 1066 1067 /** 1068 * It handle the push replication operation in publication data source. 1069 * @param subName String 1070 * @param remoteServerName String 1071 * @throws RemoteException 1072 * @throws RepException 1073 */ 1074 1075 public synchronized void push(String subName, String remoteServerName,boolean isCreateTransactionLogFile,String remoteMachineAddress) throws 1076 RemoteException, RepException { 1077 BufferedWriter bw = null; 1078 Statement stmt = null; 1079 ResultSet rs = null; 1080 Connection pubConnection =null; 1081 Connection subConnection =null; 1082 boolean isCurrentTableCyclic =false; 1083 Utility.createTransactionLogFile = isCreateTransactionLogFile; 1084 String localMachineAddress =null; 1085 try { 1086 1087 // unzipping zip file from client 1088 localMachineAddress = InetAddress.getLocalHost().getHostName(); 1089 if(!localMachineAddress.equalsIgnoreCase(remoteMachineAddress)) { 1090 ZipHandler.unZip(PathHandler.getDefaultZIPFilePathForClient("client_" +subName + "_" + pubName),PathHandler.getDefaultFilePathForClient("client_" +subName + "_" + pubName)); 1091 } 1092 SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); 1093 XMLReader reader = saxParser.getXMLReader(); 1094 subConnection = connectionPool.getConnection(subName); 1095 pubConnection = connectionPool.getConnection(pubName); 1096 MergeHandler mg = new MergeHandler(true, subConnection, this, 1097 remoteServerName, dbh, bw, 1098 "PUSH REPLICATION",PathHandler.fullOrPartialTransactionLogFile(), 1099 Utility.getDatabaseMataData(pubConnection)); 1100 mg.setLocalName(pubName); 1101 mg.setRemoteName(subName); 1102 ContentHandler ch = mg; 1103 reader.setContentHandler(ch); 1104 // initializing hashmap for maxSyncId for updating consideredId of bookMarkTable further 1105 syncIdMap = new HashMap(); 1106 1107 1108 syncIdMap = new HashMap(); 1109 for (int i = 0; i < pubRepTables.size(); i++) { 1110 RepTable repTable =( (RepTable) pubRepTables.get(i)); 1111 String tableName = repTable.getSchemaQualifiedName().toString(); 1112 1113 isCurrentTableCyclic = repTable.getCyclicDependency().equalsIgnoreCase(RepConstants.YES); 1114 StringBuffer query = new StringBuffer(); 1115 1116 stmt = pubConnection.createStatement(); 1117 query.append(" select ").append(RepConstants.shadow_sync_id1). 1118 append(" from ").append(RepConstants.shadow_Table(tableName)). 1119 append(" order by ").append(RepConstants.shadow_sync_id1). 1120 append(" desc limit 1"); 1121 rs = stmt.executeQuery(query.toString()); 1122 if (rs.next()) { 1123 syncIdMap.put(tableName,new Long(rs.getLong(1))); 1124 long maxSynId =rs.getLong(1); 1125 syncIdMap.put(tableName,new Long(maxSynId)); 1126 } else { 1127 syncIdMap.put(tableName, new Long(0)); 1128 } 1129 } 1130 reader.parse(PathHandler.getDefaultFilePathForClient("client_" + subName + "_" +pubName)); 1131 mg.closeAllStatementAndResultset(); 1132 1133 makePublicationTransactionLogFile(pubName,mg,bw); 1134 if(isCurrentTableCyclic){ 1135 MergeHandler mg1 = new MergeHandler(false, subConnection, this, 1136 remoteServerName, dbh, bw, 1137 "PUSH REPLICATION", 1138 PathHandler.fullOrPartialTransactionLogFile(), 1139 Utility.getDatabaseMataData(pubConnection)); 1140 mg1.setLocalName(subName); 1141 mg1.setRemoteName(pubName); 1142 ContentHandler ch1 = mg1; 1143 reader.setContentHandler(ch1); 1144 AbstractSynchronize.writeDateInTransactionLogFile(bw); 1145 reader.parse(PathHandler.getDefaultFilePathForClient("client_" +subName)); 1146 makePublicationTransactionLogFile(pubName,mg,bw); 1147 mg1.closeAllStatementAndResultset(); 1148 } 1149 if (_Publication.xmlAndShadow_entries) { 1150 // deleting XML file 1151 deleteFile(PathHandler.getDefaultFilePathForClient("client_" + subName + "_" +pubName)); 1152 // deleting zip file 1153 deleteFile(PathHandler.getDefaultZIPFilePathForClient("client_" +subName + "_" +pubName)); 1154 } 1155 1156 deleteRecordsFromSuperLogTable(stmt); 1157 for (int i = 0; i < pubRepTables.size(); i++) { 1158 String tableName = ( (RepTable) pubRepTables.get(i)).getSchemaQualifiedName().toString(); 1159 // we have updated last sync id at the time of creating xml file too beacause of any power failure or other reasons 1160 // we are also updating Coinsiderd Id as well as Last Sync Id so that we do not 1161 // get last record while making xml file previously from shadow table in next cycle of synchronisation 1162 // as client changes can also occur at server whihc are not to be sent back to client. 1163 UpdateConisdered_LastsyncIdForBookMarksTable(pubName, subName,tableName, ((Number) syncIdMap.get(tableName)).toString(),stmt); 1164 } 1165 syncIdMap.clear(); 1166 if (_Publication.xmlAndShadow_entries) { 1167 deleteRecordsFromShadowTable(stmt); 1168 } 1169 } 1170 catch (Exception ex) { 1171 if(Utility.createTransactionLogFile) 1172 AbstractSynchronize.writeUnsuccessfullOperationInTransaction(bw); 1173 RepConstants.writeERROR_FILE(ex); 1174 RepException rex = null; 1175 if (ex instanceof SAXException) { 1176 Exception e = ( (SAXException) ex).getException(); 1177 if (e instanceof RepException) { 1178 throw (RepException) e; 1179 } 1180 else { 1181 rex = new RepException("REP056", new Object[] {pubName, e.getMessage()}); 1182 rex.setStackTrace(e.getStackTrace()); 1183 throw rex; 1184 } 1185 } 1186 else { 1187 rex = new RepException("REP056", new Object[] {pubName, ex.getMessage()}); 1188 rex.setStackTrace(ex.getStackTrace()); 1189 } 1190 throw rex; 1191 } 1192 finally { 1193 connectionPool.removeSubPubFromMap(pubName); 1194 try { 1195 if(bw!=null) 1196 bw.close(); 1197 if (rs != null) { 1198 rs.close(); 1199 } 1200 if (stmt != null) { 1201 stmt.close(); 1202 } 1203 } 1204 catch (SQLException ex1) { 1205 } 1206 catch (IOException ex2) { 1207 } 1208 connectionPool.returnConnection(pubConnection); 1209 connectionPool.returnConnection(subConnection); 1210 } 1211 } 1212 1213 private ArrayList getUsedActualtable() { 1214 ArrayList includedTables = new ArrayList(); 1215 for (int i = 0; i < noOfPubTables; i++) { 1216 SchemaQualifiedName sname = ( (RepTable) pubRepTables.get(i)).getSchemaQualifiedName(); 1217 includedTables.add(sname.toString()); 1218 } 1219 return includedTables; 1220 } 1221 1222 /** 1223 * writes the zip file on client socket 1224 * @param address 1225 * @param portNo 1226 * @param xmlFilePath 1227 * @throws IOException 1228 */ 1229 private void writeXMLFileOnClientSocket(String address, int portNo,String xmlFilePath) throws IOException { 1230 log.debug("write XMLFile ClientSocket on address " + address + ",portNo " + portNo + " xmlFilePath " + xmlFilePath); 1231 Socket s = new Socket(address, portNo); 1232 s.setKeepAlive(true); /* bjt */ 1233 FileInputStream fis = new FileInputStream(xmlFilePath); 1234 s.setSendBufferSize(Integer.MAX_VALUE); 1235 OutputStream sos = s.getOutputStream(); 1236 BufferedOutputStream bos = new BufferedOutputStream(sos); 1237 byte[] buf = new byte[1024]; 1238 int len = 0; 1239 while ( (len = fis.read(buf)) > 0) { 1240 bos.write(buf, 0, len); 1241 } 1242 bos.flush(); 1243 bos.close(); 1244 sos.close(); 1245 fis.close(); 1246 s.close(); 1247 } 1248 1249 private SchemaQualifiedName[] getSchemaQualifiedTableNames() { 1250 SchemaQualifiedName[] tableNames = new SchemaQualifiedName[noOfPubTables]; 1251 for (int i = 0; i < noOfPubTables; i++) { 1252 RepTable repTable = (RepTable) pubRepTables.get(i); 1253 tableNames[i] = repTable.getSchemaQualifiedName(); 1254 } 1255 return tableNames; 1256 } 1257 1258 public String getServerName() throws RemoteException { 1259 return dbh.getLocalServerName(); 1260 } 1261 1262 public String getFilterClause(SchemaQualifiedName tableName) throws RemoteException { 1263 for (int i = 0; i < noOfPubTables; i++) { 1264 RepTable repTable = (RepTable) pubRepTables.get(i); 1265 if (repTable.getSchemaQualifiedName().equals(tableName)) { 1266 return repTable.getFilterClause(); 1267 } 1268 } 1269 throw new RemoteException("Invalid table name " + tableName); 1270 } 1271 1272 public AbstractDataBaseHandler getDBDataTypeHandler() { 1273 return dbh; 1274 } 1275 1276 public String getPub_SubName() { 1277 return pubName; 1278 } 1279 1280 public RepTable getRepTable(String tableName) throws RepException { 1281 log.debug("Number of tables " + pubRepTables.size()); 1282 SchemaQualifiedName sname; 1283 String tabNames; 1284 for (int i = 0; i < pubRepTables.size(); i++) { 1285 log.debug(" Qualified Names " +( (RepTable) pubRepTables.get(i)).getSchemaQualifiedName()); 1286 sname =( (RepTable) pubRepTables.get(i)).getSchemaQualifiedName(); 1287 tabNames = tableName.indexOf(".") !=-1 ? sname.toString() : sname.getTableName(); 1288 if (tabNames.equalsIgnoreCase(tableName)) { 1289 return (RepTable) pubRepTables.get(i); 1290 } 1291 } 1292 RepException rep = new RepException("REP033", new Object[] {tableName}); 1293 RepConstants.writeERROR_FILE(rep); 1294 throw rep; 1295 } 1296 1297 private void deleteFile(String fileName) { 1298 File f = new File(fileName); 1299 boolean deleted = f.delete(); 1300 } 1301 1302 private void deleteRecordsFromSuperLogTable(Statement stmt) throws 1303 SQLException { 1304 // insert one record in superLogTable 1305 ResultSet rs=null; 1306 try { 1307 StringBuffer query = new StringBuffer(); 1308 query.append("insert into ").append(dbh.getLogTableName()).append(" ("). 1309 append(RepConstants.logTable_tableName2) 1310 .append(") values ('$$$$$$')"); 1311 stmt.execute(query.toString()); 1312 1313 query = new StringBuffer(); 1314 query.append("Select max(").append(RepConstants.logTable_commonId1). 1315 append(") from ").append(dbh.getLogTableName()); 1316 rs= stmt.executeQuery(query.toString()); 1317 rs.next(); 1318 long maxCID = rs.getLong(1); 1319 1320 query = new StringBuffer(); 1321 query.append("delete from ").append(dbh.getLogTableName()).append(" where ") 1322 .append(RepConstants.logTable_commonId1).append(" !=").append(maxCID); 1323 stmt.executeUpdate(query.toString()); 1324 log.debug(query.toString()); 1325 } 1326 finally { 1327 if(rs!=null) 1328 rs.close(); 1329 } 1330 } 1331 1332 /** 1333 * deletes the unwanted reocrds from shadow table. 1334 * @throws SQLException 1335 */ 1336 private void deleteRecordsFromShadowTable(Statement stmt) throws SQLException, RepException { 1337 if (usedActualTables == null) { 1338 usedActualTables = getUsedActualtable(); 1339 } 1340 int noofTables = usedActualTables.size(); 1341 if (noofTables > 0) { 1342 StringBuffer query; 1343 for (int i = 0; i < noofTables; i++) { 1344 // // selecting min of syncid or concideredId from bookmarks table for one table 1345 Object minValue= dbh.getMinValOfSyncIdTodeleteRecordsFromShadowTable((String) 1346 usedActualTables.get(i),stmt); 1347 if (minValue instanceof Number) { 1348 minValue = new Long(((Number)minValue).longValue()); 1349 } else { 1350 minValue = new Long(Long.parseLong((String)minValue)); 1351 } 1352 // deleting records from shadow table for that table 1353 query = new StringBuffer(); 1354 query.append("delete from ").append(RepConstants.shadow_Table( (String) 1355 usedActualTables.get(i))) 1356 .append(" where ").append(RepConstants.shadow_sync_id1).append( 1357 " < ").append(minValue); 1358 stmt.executeUpdate(query.toString()); 1359 log.debug(query.toString()); 1360 } 1361 } 1362 } 1363 1364 1365 /** 1366 * updates the bookmarks table with the considered Id for all tables. 1367 * @param pubName 1368 * @param subName 1369 * @param tableName 1370 * @throws SQLException 1371 */ 1372 1373 private void UpdateConisdered_LastsyncIdForBookMarksTable(String pubName, 1374 String subName, String tableName, Object syncId,Statement stmt) throws SQLException, 1375 RepException { 1376 StringBuffer query = new StringBuffer(); 1377 Connection pubConnection = connectionPool.getConnection(pubName); 1378 stmt = pubConnection.createStatement(); 1379 1380 Object maxSyncId = syncId; 1381 1382 log.debug("maxSyncId" + maxSyncId); 1383 1384 // appened updation of LastSyncId in Bookmarks Table 1385 query.append(" UPDATE ").append(dbh.getBookMarkTableName()).append( 1386 " set ").append(RepConstants.bookmark_ConisderedId5) 1387 .append(" = ").append(maxSyncId).append(" where ").append( 1388 RepConstants.bookmark_LocalName1).append( 1389 " = '").append(pubName).append("' and ").append(RepConstants. 1390 bookmark_RemoteName2) 1391 .append(" = '").append(subName).append("' and ") 1392 .append(RepConstants.bookmark_TableName3).append(" = '").append( 1393 tableName).append("'"); 1394 stmt.executeUpdate(query.toString()); 1395 log.debug(query.toString()); 1396 stmt.close(); 1397 connectionPool.returnConnection(pubConnection); 1398 } 1399 1400 private void UpdateConisdered_LastsyncIdForBookMarksTable_old(String pubName, 1401 String subName, String tableName) throws SQLException, RepException { 1402 Connection pubConnection = null; 1403 Statement stmt = null; 1404 try { 1405 StringBuffer query = new StringBuffer(); 1406 pubConnection = connectionPool.getConnection(pubName); 1407 stmt = pubConnection.createStatement(); 1408 query.append(" select ").append(RepConstants.shadow_sync_id1). 1409 append(" from ").append(RepConstants.shadow_Table(tableName)). 1410 append(" order by ").append(RepConstants.shadow_sync_id1). 1411 append(" desc limit 1"); 1412 ResultSet rs = stmt.executeQuery(query.toString()); 1413 rs.next(); 1414 long maxSyncId = rs.getLong(1); 1415 1416 query = new StringBuffer(); 1417 // appened updation of LastSyncId in Bookmarks Table 1418 query.append(" UPDATE ").append(dbh.getBookMarkTableName()).append( 1419 " set ").append(RepConstants.bookmark_ConisderedId5) 1420 .append(" = ").append(maxSyncId).append(" , ").append(RepConstants. 1421 bookmark_lastSyncId4).append(" = ").append(maxSyncId) 1422 .append(" where ").append(RepConstants.bookmark_LocalName1).append( 1423 " = '").append(pubName).append("' and ").append(RepConstants. 1424 bookmark_RemoteName2) 1425 .append(" = '").append(subName).append("' and ") 1426 .append(RepConstants.bookmark_TableName3).append(" = '").append( 1427 tableName).append("'"); 1428 stmt.executeUpdate(query.toString()); 1429 } 1430 finally { 1431 connectionPool.removeSubPubFromMap(pubName); 1432 try { 1433 if (stmt != null) 1434 stmt.close(); 1435 } 1436 catch (SQLException ex) { 1437 } 1438 connectionPool.returnConnection(pubConnection); 1439 } 1440 } 1441 1442 public void unpublish() throws RepException { 1443 Connection con = null; 1444 Statement stmt = null; 1445 try { 1446 con = connectionPool.getConnection(pubName); 1447 stmt = con.createStatement(); 1448 checkDependingSubscriptions(stmt); 1449 try { 1450 String query = " delete from " + dbh.getPublicationTableName() + 1451 " where " + RepConstants.publication_pubName1 + " = '" +pubName + "'"; 1452 stmt.execute(query); 1453 log.debug("Unpublish query :"+query); 1454 } 1455 catch (SQLException ex) { 1456 RepConstants.writeERROR_FILE(ex); 1457 throw new RepException("REP036", new Object[] {pubName}); 1458 } 1459 deleteNonSharedPublishedSubscribedTables(con, pubName,stmt); 1460 localServer.refershPublication(pubName); 1461 } 1462 catch (SQLException ex) { 1463 log.error(ex.getMessage(), ex); 1464 RepConstants.writeERROR_FILE(ex); 1465 } 1466 finally { 1467 connectionPool.removeSubPubFromMap(pubName); 1468 try { 1469 if (stmt != null) 1470 stmt.close(); 1471 } 1472 catch (SQLException ex1) { 1473 } 1474 connectionPool.returnConnection(con); 1475 } 1476 } 1477 1478 private void deleteNonSharedPublishedSubscribedTables(Connection con, String pubsubName,Statement stmt) throws SQLException, RepException { 1479 1480 //" Select Table_Name from RepTable Where PubSub_Name = '"+pubName+"' and Table_Name Not In " 1481 //"( Select Distinct Table_Name from RepTable Where PubSub_Name <> '"+pubName+"') "; 1482 1483 ResultSet rs = null; 1484 ResultSet rsSub=null; 1485 try { 1486 StringBuffer tablesToDelete = new StringBuffer(); 1487 tablesToDelete.append(" Select ").append(RepConstants.repTable_tableName2) 1488 .append(" from ").append(dbh.getRepTableName()).append(" where ") 1489 .append(RepConstants.repTable_pubsubName1).append(" = '") 1490 .append(pubsubName).append("' and ").append(RepConstants. 1491 repTable_tableName2) 1492 .append(" not in ( Select Distinct ").append(RepConstants. 1493 repTable_tableName2).append(" from ").append(dbh.getRepTableName()) 1494 .append(" Where ").append(RepConstants.repTable_pubsubName1) 1495 .append(" <> '").append(pubsubName).append("') "); 1496 rs = stmt.executeQuery(tablesToDelete.toString()); 1497 Connection pubsubConnection = null; 1498 try 1499 { 1500 pubsubConnection = connectionPool.getConnection(pubsubName); 1501 while (rs.next()) { 1502 MetaDataInfo mdi = Utility.getDatabaseMataData(pubsubConnection); 1503 SchemaQualifiedName sname = new SchemaQualifiedName(mdi, 1504 rs.getString(RepConstants.repTable_tableName2)); 1505 deleteAll(con, pubsubName, sname.toString()); 1506 } 1507 } 1508 finally { 1509 connectionPool.returnConnection(pubsubConnection); 1510 } 1511 1512 String deleteQuery = " delete from " + dbh.getRepTableName() + " where " +RepConstants.repTable_pubsubName1 + " = '" + pubsubName + "'"; 1513 stmt.execute(deleteQuery); 1514 log.debug(deleteQuery); 1515 deleteQuery =" delete from " + dbh.getBookMarkTableName() + " where " +RepConstants.bookmark_LocalName1 + " = '" + pubsubName + "'"; 1516 stmt.execute(deleteQuery); 1517 log.debug(deleteQuery); 1518 rs = stmt.executeQuery("select * from " + dbh.getPublicationTableName()); 1519 boolean ispubTableExist = rs != null ? rs.next() ? true : false : false; 1520 try { 1521 rsSub = stmt.executeQuery("select * from " +dbh.getSubscriptionTableName()); 1522 String query = " delete from " + dbh.getRepTableName() + " where " +RepConstants.repTable_pubsubName1 + " = '" + pubsubName + "'"; 1523 stmt.execute(query); 1524 log.debug(query); 1525 query = " delete from " + dbh.getBookMarkTableName() + " where " +RepConstants.bookmark_LocalName1 + " = '" + pubsubName + "'"; 1526 stmt.execute(query); 1527 log.debug(query); 1528 rs = stmt.executeQuery("select * from " + dbh.getPublicationTableName()); 1529 if (!rs.next()) { 1530 dbh.dropPublisherSystemTables(con); 1531 } 1532 } 1533 catch (SQLException ex) { 1534 /** 1535 * Ignore the exception becuase Sublication table 1536 * does not exist in Publisher Database. It is the 1537 * case when table is published and subscribed in 1538 * same database. 1539 */ 1540 } 1541 boolean issubTableExist = rsSub != null ? rsSub.next() ? true : false : false; 1542 if(!ispubTableExist&& !issubTableExist) 1543 dbh.dropPublisherSystemTables(con); 1544 } 1545 finally { 1546 if (rs != null) 1547 rs.close(); 1548 if (rsSub != null) 1549 rsSub.close(); 1550 } 1551 1552 } 1553 1554 private void deleteAll(Connection connection, String pubsubName, String table) throws SQLException, RepException { 1555 dbh.dropTriggersAndShadowTable(connection, table, pubsubName); 1556 } 1557 1558 1559 1560 public void dropSubscription(String subName) throws RemoteException, RepException { 1561 Connection con = null; 1562 Statement stmt = null; 1563 try { 1564 con = connectionPool.getConnection(pubName); 1565 stmt = con.createStatement(); 1566 String query = "Delete from " + dbh.getBookMarkTableName() + 1567 " where " + RepConstants.bookmark_RemoteName2 + " = '" + subName +"'"; 1568 stmt.execute(query); 1569 log.debug(query); 1570 } 1571 catch (SQLException ex) { 1572 RepConstants.writeERROR_FILE(ex); 1573 throw new RepException("REP034", new Object[] {ex.getMessage()}); 1574 } 1575 catch (RepException ex) { 1576 RepConstants.writeERROR_FILE(ex); 1577 throw ex; 1578 } 1579 finally { 1580 connectionPool.removeSubPubFromMap(pubName); 1581 try { 1582 if (stmt != null) 1583 stmt.close(); 1584 } 1585 catch (SQLException ex1) { 1586 } 1587 connectionPool.returnConnection(con); 1588 } 1589 } 1590 1591 1592 synchronized public void checkForLock(String pubSubName) throws RepException, RemoteException { 1593 if( listOfWaitingSubcription.size() > 0){ 1594 if(listOfWaitingSubcription.contains(pubSubName) ){ 1595 if(isLocked) { 1596 /* bjt - test socket to make sure it's still active */ 1597 throw new RepException("REP052", null); 1598 } 1599 log.debug("locking for subscription::"+pubSubName); 1600 listOfWaitingSubcription.remove(pubSubName); 1601 isLocked = LOCK; 1602 return; 1603 } 1604 listOfWaitingSubcription.add(pubSubName); 1605 throw new RepException("REP052", null); 1606 } 1607 if (isLocked) { 1608 /* bjt - test socket to make sure it's still active */ 1609 listOfWaitingSubcription.add(pubSubName); 1610 throw new RepException("REP052", null); 1611 } 1612 log.debug("locking for subscription::"+pubSubName); 1613 isLocked = LOCK; 1614 } 1615 1616 private void checkDependingSubscriptions(Statement stmt) throws RepException { 1617 StringBuffer sb = new StringBuffer(); 1618 sb.append(" Select * From ").append(dbh.getBookMarkTableName()) 1619 .append(" where ").append(RepConstants.bookmark_LocalName1) 1620 .append(" = '").append(pubName).append("'"); 1621 ResultSet rs = null; 1622 try { 1623 rs = stmt.executeQuery(sb.toString()); 1624 if (rs.next()) { 1625 do { 1626 log.debug("Subscriber " + rs.getString(2) + " exists"); 1627 } while (rs.next()); 1628 throw new RepException("REP047", new Object[] {pubName}); 1629 } 1630 } 1631 catch (RepException ex) { 1632 RepConstants.writeERROR_FILE(ex); 1633 throw ex; 1634 } 1635 catch (SQLException ex) { 1636 RepConstants.writeERROR_FILE(ex); 1637 throw new RepException("REP045", new Object[] {pubName, ex.getMessage()}); 1638 } 1639 finally { 1640 try { 1641 if(rs!=null) 1642 rs.close(); 1643 } 1644 catch (SQLException ex1) { 1645 } 1646 } 1647 } 1648 1649 public void releaseLOCK() throws RemoteException { 1650 isLocked = UNLOCK; 1651 log.debug("isLocked :" + isLocked); 1652 } 1653 1654 public int getPubVendorName() throws RepException { 1655 int pubVendor = Utility.getVendorType(connectionPool, pubName); 1656 return pubVendor; 1657 } 1658 1659 1660 public void updateBookMarkLastSyncId(String remote_Pub_Sub_Name, Object[] lastId) throws RemoteException, 1661 SQLException, RepException { 1662 Connection pubConnection = null; 1663 Statement stmt = null; 1664 try { 1665 pubConnection = connectionPool.getConnection(pubName); 1666 stmt = pubConnection.createStatement(); 1667 for (int i = 0; i < pubRepTables.size(); i++) { 1668 String tableName = ( (RepTable) pubRepTables.get(i)).getSchemaQualifiedName().toString(); 1669 String updateQuery = "update " + dbh.getBookMarkTableName() + " set " + 1670 RepConstants.bookmark_lastSyncId4 + "=" + lastId[i] + " where " + 1671 RepConstants.bookmark_LocalName1 + " = '" + pubName + "' and " + 1672 RepConstants.bookmark_RemoteName2 + " = '" + remote_Pub_Sub_Name +"' and " + 1673 RepConstants.bookmark_TableName3 + " = '" + tableName + "' "; 1674 stmt.executeUpdate(updateQuery); 1675 } 1676 } 1677 finally { 1678 connectionPool.removeSubPubFromMap(pubName); 1679 if (stmt != null) 1680 stmt.close(); 1681 connectionPool.returnConnection(pubConnection); 1682 } 1683 } 1684 1685 1686 public void addTableToPublication(String[] newTableList,String[] filterClauses) throws 1687 RepException { 1688 Connection pubConnection=null; 1689 Statement stmt=null; 1690 boolean islockedTaken=false; 1691 try { 1692 checkForLock(pubName); 1693 islockedTaken=true; 1694 pubConnection = connectionPool.getConnection(pubName); 1695 stmt=pubConnection.createStatement(); 1696 checkTableNameIfNull(newTableList); 1697 //check if user is passing null instead of string array else check filter clause syntax 1698 if (filterClauses == null) { 1699 filterClauses = new String[newTableList.length]; 1700 for (int i = 0; i < filterClauses.length; i++) 1701 filterClauses[i] = null; 1702 } 1703 else { 1704 checkFilter(stmt,newTableList, filterClauses); 1705 } 1706 localServer.addTableToPublication(pubName, newTableList,filterClauses,pubRepTables, this); 1707 SchemaQualifiedName[] tableNames = getSchemaQualifiedTableNames(); 1708 MetaDataInfo mdi = Utility.getDatabaseMataData(pubConnection); 1709 for (int i = 0; i < tableNames.length; i++) { 1710 String schema = tableNames[i].getSchemaName(); 1711 String table = tableNames[i].getTableName(); 1712 ArrayList colInfoList = mdi.getColumnDataTypeInfo(dbh, schema, table); 1713 //Searches pubRepTables by the tablename and returns the corresponding object of RepTable and calls function 1714 RepTable repTable=getRepTable(tableNames[i].toString()); 1715 String[] primCols =repTable.getPrimaryColumns(); 1716 //We will get a sequence of columns and there datatypes along with primary columns and there datatypes. 1717 //as " col1 number(10),col2 varchar2(24),old_col1 number(10) " 1718 String allColSequence = dbh.getShadowTableColumnDataTypeSequence(colInfoList, primCols,repTable); 1719 //Creates Shadow Tables For all the participating tables 1720 dbh.createShadowTable(pubName, tableNames[i].toString(), allColSequence,primCols); 1721 dbh.makeProvisionForLOBDataTypes(colInfoList); 1722 dbh.createShadowTableTriggers(pubName, tableNames[i].toString(),colInfoList, primCols); 1723 } 1724 savePublicationNewTables(pubConnection,stmt,pubRepTables); 1725 } 1726 catch (SQLException ex) { 1727 RepConstants.writeERROR_FILE(ex); 1728 throw new RepException("REP311", new Object[] {pubName, ex.getMessage()}); 1729 } 1730 catch (Throwable ex) { 1731 throw new RepException("REP311", new Object[] {pubName, ex.getMessage()}); 1732 } 1733 finally { 1734 connectionPool.removeSubPubFromMap(pubName); 1735 if (islockedTaken) 1736 isLocked = UNLOCK; 1737 if(stmt!=null) 1738 try { 1739 stmt.close(); 1740 } 1741 catch (SQLException ex1) { 1742 } 1743 connectionPool.returnConnection(pubConnection); 1744 } 1745 1746 } 1747 1748 /** 1749 * Saves the publication name and its tables into server side replication 1750 * system tables. 1751 * @param dbh database handler for server side 1752 * @throws RepException 1753 */ 1754 private void savePublicationNewTables( Connection connection ,Statement stmt,ArrayList tablesList) throws 1755 RepException { 1756 try { 1757 //Delete all entries from Rep_table 1758 StringBuffer sb = new StringBuffer(); 1759 sb.append("delete from ").append(dbh.getRepTableName()).append(" where ") 1760 .append(RepConstants.repTable_pubsubName1).append(" = '") 1761 .append(pubName).append("'"); 1762 log.debug(sb.toString()); 1763 stmt.execute(sb.toString()); 1764 // Insert Into Rep Table, for all tables in publication 1765 for (int i = 0; i < tablesList.size(); i++) { 1766 RepTable repTable = (RepTable) tablesList.get(i); 1767 repTable.setConflictResolver(conflictResolver); 1768 dbh.saveRepTableData(connection, pubName, repTable); 1769 } 1770 } 1771 catch (SQLException ex) { 1772 RepConstants.writeERROR_FILE(ex); 1773 throw new RepException("REP0202", new Object[] {pubName,ex.getMessage()}); 1774 } 1775 } 1776 1777 /** 1778 * Inserts a row into bookmark table of server side to put a matching pair of 1779 * publication name and subscription name. 1780 * @param subName sub name 1781 * @throws RepException 1782 */ 1783 public void saveSubscriptionNewData(String subName) throws RemoteException { 1784 Connection connection = null; 1785 Statement stt = null; 1786 ResultSet rs = null; 1787 try { 1788 connection = connectionPool.getConnection(pubName); 1789 MetaDataInfo mdi = Utility.getDatabaseMataData(connection); 1790 ArrayList dropTableFromBookMarkList = new ArrayList(); 1791 ArrayList insertTableToBookMarkList = new ArrayList(); 1792 ArrayList wrongPubRepTableList = new ArrayList(); 1793 ArrayList correctPubRepTableList = new ArrayList(); 1794 stt = connection.createStatement(); 1795 for (int i = 0; i < noOfPubTables; i++) { 1796 RepTable repTable = (RepTable) pubRepTables.get(i); 1797 StringBuffer sb0 = new StringBuffer(); 1798 sb0.append(" Insert into ").append(dbh.getBookMarkTableName()).append( 1799 " values ( '").append(pubName).append("','").append(subName).append( 1800 "','").append(repTable.getSchemaQualifiedName()).append("',0,0,'N')"); 1801 try { 1802 log.debug(sb0.toString()); 1803 stt.execute(sb0.toString()); 1804 } 1805 catch (SQLException ex2) { 1806 //ignore the Exception 1807 } 1808 } 1809 StringBuffer updatewithN = new StringBuffer(); 1810 updatewithN.append("Update ") 1811 .append(dbh.getBookMarkTableName()).append(" set ") 1812 .append(RepConstants.bookmark_IsDeletedTable).append(" ='N' " ); 1813 log.debug("upadting IsDeletedTable to 'N' :"+updatewithN.toString()); 1814 stt.execute(updatewithN.toString()); 1815 1816 //get correct pubReptable list 1817 for (int i = 0; i < pubRepTables.size(); i++) { 1818 RepTable repTable = (RepTable) pubRepTables.get(i); 1819 correctPubRepTableList.add(repTable.getSchemaQualifiedName()); 1820 } 1821 //get wrong pubReptable list 1822 StringBuffer sb = new StringBuffer(); 1823 sb.append("select ").append(RepConstants.bookmark_TableName3).append( 1824 " from ").append(dbh.getBookMarkTableName()).append(" where ") 1825 .append(RepConstants.bookmark_LocalName1).append(" = '") 1826 .append(pubName).append("'").append(" and ").append(RepConstants. 1827 bookmark_RemoteName2).append(" = '") 1828 .append(subName).append("'"); ; 1829 rs = stt.executeQuery(sb.toString()); 1830 1831 while (rs.next()) { 1832 SchemaQualifiedName sname = new SchemaQualifiedName(mdi, rs.getString(1)); 1833 String schema = sname.getSchemaName(); 1834 String table = sname.getTableName(); 1835 RepTable repTable = new RepTable(sname, RepConstants.publisher); 1836 //Sets Sorted primary key columns in repTable. 1837 mdi.setPrimaryColumns(repTable, schema, table); 1838 wrongPubRepTableList.add(repTable.getSchemaQualifiedName()); 1839 } 1840 //get list of tables whose entry to be dropped from bookmarktable 1841 for (int j = 0; j < correctPubRepTableList.size(); j++) { 1842 if (!wrongPubRepTableList.contains(correctPubRepTableList.get(j))) { 1843 insertTableToBookMarkList.add(correctPubRepTableList.get(j)); 1844 } 1845 } 1846 //get list of tables whose entry to be inserted into bookmarktable 1847 for (int j = 0; j < wrongPubRepTableList.size(); j++) { 1848 if (!correctPubRepTableList.contains(wrongPubRepTableList.get(j))) { 1849 dropTableFromBookMarkList.add(wrongPubRepTableList.get(j)); 1850 } 1851 } 1852 for (int j = 0; j < dropTableFromBookMarkList.size(); j++) { 1853 StringBuffer deleteQuery = new StringBuffer(); 1854 deleteQuery.append(" delete from ").append(dbh.getBookMarkTableName()). 1855 append(" where ").append(RepConstants.bookmark_LocalName1).append( 1856 " = '").append(pubName) 1857 .append("'").append(" and ").append(RepConstants.bookmark_TableName3).append( 1858 " ='").append(dropTableFromBookMarkList.get(j).toString()).append( 1859 " '").append( 1860 " and ").append(RepConstants.bookmark_RemoteName2).append(" ='"). 1861 append(subName).append(" '"); 1862 log.debug("dropTableFromBookMarkList ::"+deleteQuery.toString()); 1863 stt.execute(deleteQuery.toString()); 1864 } 1865 for (int j = 0; j < insertTableToBookMarkList.size(); j++) { 1866 StringBuffer insertQuery = new StringBuffer(); 1867 insertQuery.append(" Insert into ").append(dbh.getBookMarkTableName()). 1868 append(" values ( '").append(pubName).append("','").append(subName).append( 1869 "','").append(insertTableToBookMarkList.get(j).toString()).append( 1870 "',0,0,'N')"); 1871 log.debug("insertTableToBookMarkList ::"+insertQuery.toString()); 1872 stt.execute(insertQuery.toString()); 1873 } 1874 } 1875 catch (SQLException ex) { 1876 } 1877 catch (RepException ex) { 1878 RepConstants.writeERROR_FILE(ex); 1879 throw new RemoteException(ex.getMessage()); 1880 } 1881 finally { 1882 connectionPool.removeSubPubFromMap(pubName); 1883 try { 1884 if(rs!=null) 1885 rs.close(); 1886 if (stt != null) 1887 stt.close(); 1888 try { 1889 connectionPool.returnConnection(connection); 1890 } 1891 catch (RepException ex) { 1892 // Ignore the exception 1893 } 1894 } 1895 catch (SQLException ex1) { 1896 // Ignore the exception 1897 } 1898 } 1899 } 1900 1901 public void dropTableFromPublication(String[] dropTableList) throws RepException { 1902 Connection connection = null; 1903 Statement stt = null; 1904 boolean islockedTaken=false; 1905 try { 1906 checkForLock(pubName); 1907 islockedTaken=true; 1908 checkTableNameIfNull(dropTableList); 1909 ArrayList dropRepTableList = new ArrayList(); 1910 ArrayList repTableList = localServer.dropTableFromPublication(pubName,dropTableList, this, pubRepTables); 1911 for (int i = 0; i < repTableList.size(); i++) { 1912 RepTable repTable = (RepTable) repTableList.get(i); 1913 dropRepTableList.add(repTable.getSchemaQualifiedName()); 1914 } 1915 connection = connectionPool.getConnection(pubName); 1916 stt = connection.createStatement(); 1917 //drop triggers,shadow tables,delete from logtable 1918 for (int i = 0; i < dropRepTableList.size(); i++) { 1919 1920 StringBuffer query = new StringBuffer(); 1921 //delete entry from reptable 1922 query.append(" DELETE " +" FROM " +dbh.getRepTableName()+ " WHERE "); 1923 query.append(RepConstants.repTable_pubsubName1); 1924 query.append(" = '"); 1925 query.append(pubName); 1926 query.append("' and "); 1927 query.append(RepConstants.repTable_tableName2); 1928 query.append(" ='"); 1929 query.append(dropRepTableList.get(i).toString()); 1930 query.append("'"); 1931 log.debug(query.toString()); 1932 stt.execute(query.toString()); 1933 StringBuffer updateQuery = new StringBuffer(); 1934 updateQuery.append(" update ").append(dbh.getBookMarkTableName()). 1935 append(" set ").append(RepConstants.bookmark_ConisderedId5). 1936 append(" = 0 ,").append(RepConstants.bookmark_lastSyncId4). 1937 append(" = 0 ,").append(RepConstants.bookmark_IsDeletedTable).append(" = 'Y' "). 1938 append(" where ").append(RepConstants.bookmark_LocalName1).append(" = '"). 1939 append(pubName).append("'").append(" and ").append(RepConstants.bookmark_TableName3). 1940 append(" ='").append(dropRepTableList.get(i).toString()).append("'"); 1941 log.debug("updating bookmarktable lstsyncid,consideredId and isDeletedTable : "+updateQuery.toString()); 1942 stt.execute(updateQuery.toString()); 1943 dbh.dropTriggersAndShadowTable(connection,dropRepTableList.get(i).toString(),pubName); 1944 } 1945 //modifying the pubRepTablesList 1946 for (int i = 0; i < repTableList.size(); i++) { 1947 RepTable repTable = (RepTable) repTableList.get(i); 1948 for (int j = 0; j < pubRepTables.size(); j++) { 1949 RepTable pRepTable = (RepTable) pubRepTables.get(j); 1950 if (pRepTable.getRepTableQualifiedIdentifier().toString().equals( 1951 repTable.getRepTableQualifiedIdentifier().toString())) { 1952 pubRepTables.remove(pubRepTables.get(j)); 1953 noOfPubTables--; 1954 } 1955 } 1956 } 1957 } 1958 catch (Exception ex) { 1959 RepConstants.writeERROR_FILE(ex); 1960 if (ex instanceof RepException) { 1961 throw (RepException) ex; 1962 } 1963 RepException rex = new RepException("REP311", new Object[] {ex.getMessage()}); 1964 rex.setStackTrace(ex.getStackTrace()); 1965 throw rex; 1966 } 1967 finally { 1968 connectionPool.removeSubPubFromMap(pubName); 1969 if (islockedTaken) 1970 isLocked = UNLOCK; 1971 try { 1972 if (stt != null) { 1973 stt.close(); 1974 } 1975 } 1976 catch (SQLException ex1) { 1977 } 1978 connectionPool.returnConnection(connection); 1979 } 1980 } 1981 1982 public ConnectionPool getConnectionPool() { 1983 return connectionPool; 1984 } 1985 //check filter in case of add tables to publisher. 1986 // This method does early checking of filter clauses 1987 public void checkFilter(Statement stmt,String[] tableName0, String[] filterClause0) throws 1988 RepException { 1989 Connection pubConnection = null; 1990 ResultSet rs = null; 1991 try { 1992 if(tableName0.length!=filterClause0.length){ 1993 throw new RepException("REP319",null); 1994 } 1995 pubConnection = connectionPool.getConnection(pubName); 1996 MetaDataInfo mdi = Utility.getDatabaseMataData(pubConnection); 1997 for (int i = 0; i < tableName0.length; i++) { 1998 SchemaQualifiedName sname = new SchemaQualifiedName(mdi, tableName0[i]); 1999 if (tableName0[i].indexOf('.') == -1) { 2000 mdi.checkTableExistance(sname); 2001 } 2002 log.debug("Table name : " + tableName0[i]); 2003 log.info("check the filter : " + filterClause0[i] + " for table " +tableName0[i]); 2004 if (filterClause0[i]!=null) { 2005 try { 2006 String query = "Select * from " + sname + " where " +filterClause0[i]; 2007 log.debug("check filter query : " + query); 2008 rs = stmt.executeQuery(query); 2009 rs.next(); 2010 } 2011 catch (SQLException ex1) { 2012 RepConstants.writeERROR_FILE(ex1); 2013 RepException rex = new RepException("REP019",new Object[] {filterClause0[i]}); 2014 rex.setStackTrace(ex1.getStackTrace()); 2015 throw rex; 2016 } 2017 } 2018 } 2019 } 2020 finally { 2021 try { 2022 if (rs != null) { 2023 rs.close(); 2024 } 2025 } 2026 catch (SQLException ex) { 2027 } 2028 connectionPool.returnConnection(pubConnection); 2029 } 2030 } 2031 2032 2033 public void checkTableNameIfNull(String[] tableNames) throws RepException { 2034 if (tableNames == null) { 2035 throw new RepException("REP316", null); 2036 } 2037 for (int i = 0; i < tableNames.length; i++) { 2038 if (tableNames[i] == null) { 2039 throw new RepException("REP320", null); 2040 } 2041 } 2042 } 2043 /** 2044 * creates an XMl file for getting Snapshot on clients side. 2045 * Do entry in the server side bookmark table. 2046 * Deletes all records from the server side log table. 2047 * 2048 * @param address 2049 * @param portNo 2050 * @param subName 2051 * @throws SQLException 2052 * @throws RemoteException 2053 * @throws RepException 2054 */ 2055 public void createSnapShotAfterUpdateSub(String address, int portNo, String subName,ArrayList tablesForSnapShot,boolean isSchemaSupported,_FileUpload fileUpload,String remoteMachineAddress) throws 2056 SQLException, RemoteException, RepException { 2057 Connection pubConnection = null; 2058 Statement stmt = null; 2059 ResultSet rows = null, shadowResult = null; 2060 try { 2061 FileOutputStream fos = new FileOutputStream(PathHandler.getDefaultFilePathForClient("snapshot_" + pubName+ "_" +subName)); 2062 OutputStreamWriter os = new OutputStreamWriter(fos); 2063 BufferedWriter bw = new BufferedWriter(os); 2064 pubConnection = connectionPool.getConnection(pubName); 2065 XMLWriter xmlWriter = new XMLWriter(bw, dbh, pubConnection); 2066 bw.write("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"); 2067 bw.write("<root_snapshot>"); 2068 String tableName; 2069 SchemaQualifiedName sname; 2070 stmt = pubConnection.createStatement(); 2071 for (int i = 0; i < noOfPubTables; i++) { 2072 RepTable repTable = (RepTable) pubRepTables.get(i); 2073 sname =(repTable).getSchemaQualifiedName(); 2074 tableName = isSchemaSupported ? sname.toString() : sname.getTableName() ; 2075 //compare for new table list 2076 if(tablesForSnapShot.contains(tableName.toLowerCase())){ 2077 ArrayList encodedCols = PathHandler.getEncodedColumns(tableName); 2078 bw.write("<tableName>"); 2079 bw.write(tableName); 2080 String query; 2081 if (repTable.getFilterClause() == null || repTable.getFilterClause().equalsIgnoreCase("")) { 2082 query = "Select * from " + repTable.getRepTableQualifiedIdentifier(); 2083 } 2084 else { 2085 query = "Select * from " + repTable.getRepTableQualifiedIdentifier() +" where " + repTable.getFilterClause(); 2086 } 2087 rows = stmt.executeQuery(query); 2088 ResultSetMetaData rsmt = rows.getMetaData(); 2089 int noOfColumns = rsmt.getColumnCount(); 2090 while (rows.next()) { 2091 bw.write("<row>"); 2092 for (int c = 1; c <= noOfColumns; c++) { 2093 String columnName = rsmt.getColumnName(c); 2094 if (!encodedCols.contains(columnName.toUpperCase())) { 2095 bw.write("<" + columnName + ">"); 2096 } 2097 else { 2098 bw.write("<" + columnName + " Encode=\"y\">"); 2099 } 2100 // Special Handelling for Blob Clob Case 2101 xmlWriter.write(rows, c, encodedCols, columnName); 2102 bw.write("</" + columnName + ">\r\n"); 2103 } 2104 bw.write("</row>\r\n"); 2105 bw.flush(); 2106 } 2107 bw.write("</tableName>\r\n"); 2108 // updating values for bookmark table 2109 stmt.execute(" select " + RepConstants.shadow_sync_id1 + 2110 " from " +RepConstants.shadow_Table(tableName) + 2111 " order by " + RepConstants.shadow_sync_id1 + 2112 " desc limit 1"); 2113 log.debug(" select " + RepConstants.shadow_sync_id1 + 2114 " from " +RepConstants.shadow_Table(tableName) + 2115 " order by " + RepConstants.shadow_sync_id1 + 2116 " desc limit 1"); 2117 shadowResult = stmt.getResultSet(); 2118 boolean value = shadowResult.next(); 2119 Object maxvalue = null; 2120 if (value) { 2121 maxvalue = shadowResult.getObject(1); 2122 } 2123 if (maxvalue == null) { 2124 maxvalue = new Long(0); 2125 } 2126 2127 log.debug("max(" + RepConstants.shadow_sync_id1 + ")=" + maxvalue); 2128 StringBuffer updateBookmarkQuery = new StringBuffer("update " +dbh.getBookMarkTableName() + " set "); 2129 updateBookmarkQuery.append(RepConstants.bookmark_lastSyncId4 + " = " +maxvalue + ", "); 2130 updateBookmarkQuery.append(RepConstants.bookmark_ConisderedId5 + " = " +maxvalue + " "); 2131 updateBookmarkQuery.append(" where " + RepConstants.bookmark_LocalName1 +" ='" + pubName + "' "); 2132 updateBookmarkQuery.append(" and " + RepConstants.bookmark_RemoteName2 +" ='" + subName + "' "); 2133 updateBookmarkQuery.append(" and " + RepConstants.bookmark_TableName3 +" ='" + tableName + "'"); 2134 stmt.executeUpdate(updateBookmarkQuery.toString()); 2135 log.debug(updateBookmarkQuery.toString()); 2136 } 2137 } 2138 bw.write("</root_snapshot>\r\n"); 2139 if(bw!=null) 2140 bw.close(); 2141 fos.close(); 2142 2143 // making zip file from xml file 2144 if(!localAddress.equalsIgnoreCase(remoteMachineAddress)) { 2145 ZipHandler.makeZip(PathHandler.getDefaultZIPFilePathForClient("snapshot_" + pubName + "_" + subName),PathHandler.getDefaultFilePathForClient("snapshot_" + pubName +"_" + subName), "snapshot_" + pubName + "_" + subName + ".xml"); 2146 // writing zip file on socket 2147 WriteOnSocket writeOnSocket = new WriteOnSocket(PathHandler.getDefaultZIPFilePathForClient("snapshot_" + pubName),PathHandler.getDefaultFilePathForClient("snapshot_" + pubName),_Publication.xmlAndShadow_entries, "snapshot_" + pubName,fileUpload, true); 2148 writeOnSocket.start(); 2149 writeOnSocket.join(); 2150 } 2151 deleteRecordsFromSuperLogTable(stmt); 2152 } 2153 catch (FileNotFoundException ex) { 2154 RepConstants.writeERROR_FILE(ex); 2155 throw new RepException("REP085", null); 2156 } //Temporary Snapshot File Can not created. 2157 catch (IOException ex) { 2158 RepConstants.writeERROR_FILE(ex); 2159 RepException rex = new RepException("REP086", new Object[] {ex.getMessage()}); 2160 rex.setStackTrace(ex.getStackTrace()); 2161 throw rex; 2162 } 2163 catch (SQLException ex) { 2164 RepConstants.writeERROR_FILE(ex); 2165 RepException rex = new RepException("REP055", new Object[] {pubName,ex.getMessage()}); 2166 rex.setStackTrace(ex.getStackTrace()); 2167 throw rex; 2168 } 2169 catch (InterruptedException ex) { 2170 RepConstants.writeERROR_FILE(ex); 2171 RepException rex = new RepException("REP055", new Object[] {pubName,ex.getMessage()}); 2172 rex.setStackTrace(ex.getStackTrace()); 2173 throw rex; 2174 2175 } 2176 catch (RepException ex) { 2177 RepConstants.writeERROR_FILE(ex); 2178 throw ex; 2179 } 2180 finally { 2181 connectionPool.removeSubPubFromMap(pubName); 2182 /** @todo Close the statement */ 2183 if (rows != null) 2184 rows.close(); 2185 if (shadowResult != null) 2186 shadowResult.close(); 2187 if (stmt != null) 2188 stmt.close(); 2189 connectionPool.returnConnection(pubConnection); 2190 } 2191 } 2192 public ArrayList dropTableListForSub(String subName) throws RepException, 2193 SQLException ,RemoteException{ 2194 Connection con = null; 2195 ResultSet rs=null; 2196 Statement stt=null; 2197 ArrayList dropTableFromSub=new ArrayList(); 2198 try{ 2199 con = connectionPool.getConnection(pubName); 2200 stt = con.createStatement(); 2201 StringBuffer sb = new StringBuffer(); 2202 sb.append("select ").append(RepConstants.bookmark_TableName3) 2203 .append(" from ").append(dbh.getBookMarkTableName()).append(" where ") 2204 .append(RepConstants.bookmark_LocalName1).append(" = '") 2205 .append(pubName).append("'").append(" and ") 2206 .append(RepConstants.bookmark_RemoteName2).append(" = '") 2207 .append(subName).append("'").append(" and ") 2208 .append(RepConstants.bookmark_IsDeletedTable).append(" ='Y'"); 2209 rs = stt.executeQuery(sb.toString()); 2210 while(rs.next()){ 2211 dropTableFromSub.add(rs.getString(RepConstants.bookmark_TableName3)); 2212 } 2213 return dropTableFromSub; 2214 }finally{ 2215 connectionPool.removeSubPubFromMap(pubName); 2216 try { 2217 if (rs != null) { 2218 rs.close(); 2219 } 2220 if (stt != null) { 2221 stt.close(); 2222 } 2223 } 2224 catch (SQLException ex) { 2225 } 2226 connectionPool.returnConnection(con); 2227 } 2228 } 2229 2230 public void updatePublisherShadowAndBookmarkTableAfterPullOnSubscriber(String remote_Pub_Sub_Name, 2231 Object[] lastId) throws RemoteException, SQLException, RepException { 2232 Connection pubConnection = null; 2233 Statement stmt = null; 2234 try { 2235 updateBookMarkLastSyncId(remote_Pub_Sub_Name, lastId); 2236 pubConnection = connectionPool.getConnection(pubName); 2237 stmt = pubConnection.createStatement(); 2238 for (int i = 0; i < pubRepTables.size(); i++) { 2239 String tableName = ( (RepTable) pubRepTables.get(i)).getSchemaQualifiedName().toString(); 2240 UpdateConisdered_LastsyncIdForBookMarksTable(pubName,remote_Pub_Sub_Name,tableName, lastId[i], stmt); 2241 } 2242 deleteRecordsFromShadowTable(stmt); 2243 } 2244 finally { 2245 connectionPool.removeSubPubFromMap(pubName); 2246 try { 2247 if (stmt != null) { 2248 stmt.close(); 2249 } 2250 } 2251 catch (SQLException ex) { 2252 } 2253 connectionPool.returnConnection(pubConnection); 2254 } 2255 } 2256 2257 public void setIgnoredColumns(String tableName, 2258 String[] columnNamesToBeIgnored) throws RepException { 2259 Connection connection = null; 2260 try { 2261 connection = connectionPool.getConnection(pubName); 2262 MetaDataInfo mdi = Utility.getDatabaseMataData(connection); 2263 SchemaQualifiedName sname = new SchemaQualifiedName(mdi, tableName); 2264 if (tableName.indexOf('.') == -1) { 2265 mdi.checkTableExistance(sname); 2266 } 2267 getRepTable(tableName).setColumnsToBeIgnored(columnNamesToBeIgnored); 2268 } 2269 finally { 2270 connectionPool.returnConnection(connection); 2271 } 2272 } 2273 2274 /** 2275 * To get the result of primary columns to write its value in XML 2276 * file during snapshot. 2277 * @param connection Connection 2278 * @param tableName String 2279 * @param primaryColumnNames String[] 2280 * @throws SQLException 2281 * @return ResultSet 2282 */ 2283 private ResultSet getPrimaryKeyResultSet(Statement stmt,String tableName, String[] primaryColumnNames) throws SQLException{ 2284 StringBuffer sb =new StringBuffer(); 2285 sb.append("SELECT "); 2286 for (int i = 0; i < primaryColumnNames.length; i++) { 2287 if(i!=0) 2288 sb.append(","); 2289 sb.append(primaryColumnNames[i]); 2290 } 2291 sb.append(" FROM ").append(tableName); 2292 stmt.setFetchSize(1); 2293 ResultSet resultSetPrimaryKey = stmt.executeQuery(sb.toString()); 2294 resultSetPrimaryKey.next(); 2295 return resultSetPrimaryKey; 2296 } 2297 2298 private void makePublicationTransactionLogFile(String subName,MergeHandler mg ,BufferedWriter bw ) throws Exception { 2299 if(Utility.createTransactionLogFile) { 2300 String transactionLogURL = PathHandler.getDefaultTransactionLogFilePathForPublisher(pubName); 2301 FileOutputStream fos1 = new FileOutputStream(transactionLogURL, true); 2302 OutputStreamWriter os = new OutputStreamWriter(fos1); 2303 bw = new BufferedWriter(os); 2304 AbstractSynchronize.writeDateInTransactionLogFile(bw); 2305 AbstractSynchronize.writeOperationInTransactionLogFile(bw, mg.insert,mg.update, mg.delete, "MERGE"); 2306 bw.flush(); 2307 } 2308 } 2309 2310 private boolean isSchemaSupported() { 2311 return dbh.isSchemaSupported(); 2312 } 2313 2314 /** 2315 * getFileUploader 2316 * 2317 * @return ArrayList 2318 */ 2319 public _FileUpload getFileUploader()throws RepException, 2320 SQLException,RemoteException { 2321 return new FileUpload(); 2322 } 2323 2324 }

