src/org/objectweb/cjdbc/controller/loadbalancer/singledb/SingleDB.java

説明を見る。
00001 00025 package org.objectweb.cjdbc.controller.loadbalancer.singledb; 00026 00027 import java.sql.Connection; 00028 import java.sql.SQLException; 00029 00030 import org.objectweb.cjdbc.common.exceptions.BadConnectionException; 00031 import org.objectweb.cjdbc.common.exceptions.UnreachableBackendException; 00032 import org.objectweb.cjdbc.common.i18n.Translate; 00033 import org.objectweb.cjdbc.common.log.Trace; 00034 import org.objectweb.cjdbc.common.sql.AbstractWriteRequest; 00035 import org.objectweb.cjdbc.common.sql.ParsingGranularities; 00036 import org.objectweb.cjdbc.common.sql.SelectRequest; 00037 import org.objectweb.cjdbc.common.sql.StoredProcedure; 00038 import org.objectweb.cjdbc.common.xml.DatabasesXmlTags; 00039 import org.objectweb.cjdbc.controller.backend.DatabaseBackend; 00040 import org.objectweb.cjdbc.controller.cache.metadata.MetadataCache; 00041 import org.objectweb.cjdbc.controller.connection.AbstractConnectionManager; 00042 import org.objectweb.cjdbc.controller.loadbalancer.AbstractLoadBalancer; 00043 import org.objectweb.cjdbc.controller.requestmanager.RAIDbLevels; 00044 import org.objectweb.cjdbc.controller.requestmanager.TransactionMarkerMetaData; 00045 import org.objectweb.cjdbc.controller.virtualdatabase.ControllerResultSet; 00046 import org.objectweb.cjdbc.controller.virtualdatabase.VirtualDatabase; 00047 00059 public class SingleDB extends AbstractLoadBalancer 00060 { 00061 /* 00062 * How the code is organized ? 1. Member variables 2. Constructor(s) 3. 00063 * Request handling 4. Transaction handling 5. Backend management 6. 00064 * Debug/Monitoring 00065 */ 00066 00067 private DatabaseBackend backend; 00068 00069 private static Trace logger = Trace 00070 .getLogger("org.objectweb.cjdbc.controller.loadbalancer.SingleDB"); 00071 00072 /* 00073 * Constructors 00074 */ 00075 00083 public SingleDB(VirtualDatabase vdb) throws SQLException 00084 { 00085 // We don't need to parse the requests, just send them to the backend 00086 super(vdb, RAIDbLevels.SingleDB, ParsingGranularities.NO_PARSING); 00087 } 00088 00089 /* 00090 * Request Handling 00091 */ 00092 00102 public ControllerResultSet execReadRequest(SelectRequest request, 00103 MetadataCache metadataCache) throws SQLException 00104 { 00105 if (backend == null) 00106 throw new SQLException(Translate.get( 00107 "loadbalancer.execute.no.backend.available", request.getId())); 00108 00109 try 00110 { 00111 AbstractConnectionManager cm = backend.getConnectionManager(request 00112 .getLogin()); 00113 if (request.isAutoCommit()) 00114 { 00115 ControllerResultSet rs = null; 00116 boolean badConnection; 00117 do 00118 { 00119 badConnection = false; 00120 // Use a connection just for this request 00121 Connection c = null; 00122 try 00123 { 00124 c = cm.getConnection(); 00125 } 00126 catch (UnreachableBackendException e1) 00127 { 00128 String backendName = backend.getName(); 00129 logger.error(Translate.get( 00130 "loadbalancer.backend.disabling.unreachable", backendName)); 00131 backend.disable(); 00132 backend = null; 00133 throw new SQLException(Translate.get( 00134 "loadbalancer.backend.unreacheable", backendName)); 00135 } 00136 00137 // Sanity check 00138 if (c == null) 00139 throw new SQLException(Translate.get( 00140 "loadbalancer.backend.no.connection", backend.getName())); 00141 00142 // Execute Query 00143 try 00144 { 00145 rs = executeSelectRequestOnBackend(request, backend, c, 00146 metadataCache); 00147 cm.releaseConnection(c); 00148 } 00149 catch (SQLException e) 00150 { 00151 cm.releaseConnection(c); 00152 throw new SQLException(Translate.get( 00153 "loadbalancer.request.failed.on.backend", new String[]{ 00154 request.getSQLShortForm(vdb.getSQLShortFormLength()), 00155 backend.getName(), e.getMessage()})); 00156 } 00157 catch (BadConnectionException e) 00158 { // Get rid of the bad connection 00159 cm.deleteConnection(c); 00160 badConnection = true; 00161 } 00162 } 00163 while (badConnection); 00164 return rs; 00165 } 00166 else 00167 { 00168 long tid = request.getTransactionId(); 00169 // Re-use the connection used by this transaction 00170 Connection c = cm.retrieveConnection(tid); 00171 00172 // Sanity check 00173 if (c == null) 00174 throw new SQLException(Translate.get( 00175 "loadbalancer.unable.retrieve.connection", new String[]{ 00176 String.valueOf(tid), backend.getName()})); 00177 00178 // Execute Query 00179 ControllerResultSet rs = null; 00180 try 00181 { 00182 rs = executeSelectRequestOnBackend(request, backend, c, metadataCache); 00183 } 00184 catch (SQLException e) 00185 { 00186 throw new SQLException(Translate.get( 00187 "loadbalancer.request.failed.on.backend", new String[]{ 00188 request.getSQLShortForm(vdb.getSQLShortFormLength()), 00189 backend.getName(), e.getMessage()})); 00190 } 00191 catch (BadConnectionException e) 00192 { // Get rid of the bad connection 00193 cm.deleteConnection(tid); 00194 throw new SQLException(Translate.get( 00195 "loadbalancer.connection.failed", new String[]{ 00196 String.valueOf(tid), backend.getName(), e.getMessage()})); 00197 } 00198 return rs; 00199 } 00200 } 00201 catch (RuntimeException e) 00202 { 00203 String msg = "Request '" 00204 + request.getSQLShortForm(vdb.getSQLShortFormLength()) 00205 + "' failed on backend " + backend.getURL() + " (" + e + ")"; 00206 logger.fatal(msg, e); 00207 throw new SQLException(msg); 00208 } 00209 } 00210 00218 public int execWriteRequest(AbstractWriteRequest request) throws SQLException 00219 { 00220 if (backend == null) 00221 throw new SQLException(Translate.get( 00222 "loadbalancer.execute.no.backend.available", request.getId())); 00223 00224 try 00225 { 00226 AbstractConnectionManager cm = backend.getConnectionManager(request 00227 .getLogin()); 00228 if (request.isAutoCommit()) 00229 { 00230 // We do not execute request outside the already open transactions if we 00231 // are disabling the backend. 00232 if (backend.isDisabling()) 00233 throw new SQLException(Translate.get( 00234 "loadbalancer.backend.is.disabling", new String[]{ 00235 request.getSQLShortForm(vdb.getSQLShortFormLength()), 00236 backend.getName()})); 00237 00238 // Use a connection just for this request 00239 Connection c = null; 00240 try 00241 { 00242 c = cm.getConnection(); 00243 } 00244 catch (UnreachableBackendException e1) 00245 { 00246 String backendName = backend.getName(); 00247 logger.error(Translate.get( 00248 "loadbalancer.backend.disabling.unreachable", backendName)); 00249 backend.disable(); 00250 backend = null; 00251 throw new SQLException(Translate.get( 00252 "loadbalancer.backend.unreacheable", backendName)); 00253 } 00254 00255 // Sanity check 00256 if (c == null) 00257 throw new SQLException(Translate.get( 00258 "loadbalancer.backend.no.connection", backend.getName())); 00259 00260 // Execute Query 00261 int result; 00262 try 00263 { 00264 result = executeUpdateRequestOnBackend(request, backend, c); 00265 } 00266 catch (Exception e) 00267 { 00268 throw new SQLException(Translate.get( 00269 "loadbalancer.request.failed.on.backend", new String[]{ 00270 request.getSQLShortForm(vdb.getSQLShortFormLength()), 00271 backend.getName(), e.getMessage()})); 00272 } 00273 finally 00274 { 00275 cm.releaseConnection(c); 00276 } 00277 return result; 00278 } 00279 else 00280 { // Re-use the connection used by this transaction 00281 Connection c = cm.retrieveConnection(request.getTransactionId()); 00282 00283 // Sanity check 00284 if (c == null) 00285 throw new SQLException(Translate.get( 00286 "loadbalancer.unable.retrieve.connection", 00287 new String[]{String.valueOf(request.getTransactionId()), 00288 backend.getName()})); 00289 00290 // Execute Query 00291 try 00292 { 00293 return executeUpdateRequestOnBackend(request, backend, c); 00294 } 00295 catch (Exception e) 00296 { 00297 throw new SQLException(Translate.get( 00298 "loadbalancer.request.failed.on.backend", new String[]{ 00299 request.getSQLShortForm(vdb.getSQLShortFormLength()), 00300 backend.getName(), e.getMessage()})); 00301 } 00302 } 00303 } 00304 catch (RuntimeException e) 00305 { 00306 String msg = Translate.get("loadbalancer.request.failed.on.backend", 00307 new String[]{request.getSQLShortForm(vdb.getSQLShortFormLength()), 00308 backend.getName(), e.getMessage()}); 00309 logger.fatal(msg, e); 00310 throw new SQLException(msg); 00311 } 00312 } 00313 00318 public ControllerResultSet execWriteRequestWithKeys( 00319 AbstractWriteRequest request, MetadataCache metadataCache) 00320 throws SQLException 00321 { 00322 if (backend == null) 00323 throw new SQLException(Translate.get( 00324 "loadbalancer.execute.no.backend.available", request.getId())); 00325 00326 if (!backend.getDriverCompliance().supportGetGeneratedKeys()) 00327 throw new SQLException(Translate.get( 00328 "loadbalancer.backend.autogeneratedkeys.unsupported", backend 00329 .getName())); 00330 00331 try 00332 { 00333 AbstractConnectionManager cm = backend.getConnectionManager(request 00334 .getLogin()); 00335 if (request.isAutoCommit()) 00336 { 00337 // We do not execute request outside the already open transactions if we 00338 // are disabling the backend. 00339 if (backend.isDisabling()) 00340 throw new SQLException(Translate.get( 00341 "loadbalancer.backend.is.disabling", new String[]{ 00342 request.getSQLShortForm(vdb.getSQLShortFormLength()), 00343 backend.getName()})); 00344 00345 // Use a connection just for this request 00346 Connection c = null; 00347 try 00348 { 00349 c = cm.getConnection(); 00350 } 00351 catch (UnreachableBackendException e1) 00352 { 00353 String backendName = backend.getName(); 00354 logger.error(Translate.get( 00355 "loadbalancer.backend.disabling.unreachable", backendName)); 00356 backend.disable(); 00357 backend = null; 00358 throw new SQLException(Translate.get( 00359 "loadbalancer.backend.unreacheable", backendName)); 00360 } 00361 00362 // Sanity check 00363 if (c == null) 00364 throw new SQLException(Translate.get( 00365 "loadbalancer.backend.no.connection", backend.getName())); 00366 00367 // Execute Query 00368 ControllerResultSet result; 00369 try 00370 { 00371 result = new ControllerResultSet(request, 00372 executeUpdateRequestOnBackendWithKeys(request, backend, c), 00373 metadataCache); 00374 } 00375 catch (Exception e) 00376 { 00377 throw new SQLException(Translate.get( 00378 "loadbalancer.request.failed.on.backend", new String[]{ 00379 request.getSQLShortForm(vdb.getSQLShortFormLength()), 00380 backend.getName(), e.getMessage()})); 00381 } 00382 finally 00383 { 00384 cm.releaseConnection(c); 00385 } 00386 return result; 00387 } 00388 else 00389 { 00390 // Re-use the connection used by this transaction 00391 Connection c = cm.retrieveConnection(request.getTransactionId()); 00392 00393 // Sanity check 00394 if (c == null) 00395 throw new SQLException(Translate.get( 00396 "loadbalancer.unable.retrieve.connection", 00397 new String[]{String.valueOf(request.getTransactionId()), 00398 backend.getName()})); 00399 00400 // Execute Query 00401 try 00402 { 00403 return new ControllerResultSet(request, 00404 executeUpdateRequestOnBackendWithKeys(request, backend, c), 00405 metadataCache); 00406 } 00407 catch (Exception e) 00408 { 00409 throw new SQLException(Translate.get( 00410 "loadbalancer.request.failed.on.backend", new String[]{ 00411 request.getSQLShortForm(vdb.getSQLShortFormLength()), 00412 backend.getName(), e.getMessage()})); 00413 } 00414 finally 00415 { 00416 backend.removePendingRequest(request); 00417 } 00418 } 00419 } 00420 catch (RuntimeException e) 00421 { 00422 String msg = Translate.get("loadbalancer.request.failed.on.backend", 00423 new String[]{request.getSQLShortForm(vdb.getSQLShortFormLength()), 00424 backend.getName(), e.getMessage()}); 00425 logger.fatal(msg, e); 00426 throw new SQLException(msg); 00427 } 00428 } 00429 00434 public ControllerResultSet execReadOnlyReadStoredProcedure( 00435 StoredProcedure proc, MetadataCache metadataCache) throws SQLException 00436 { 00437 return execReadStoredProcedure(proc, metadataCache); 00438 } 00439 00444 public ControllerResultSet execReadStoredProcedure(StoredProcedure proc, 00445 MetadataCache metadataCache) throws SQLException 00446 { 00447 if (backend == null) 00448 throw new SQLException( 00449 "No available backend to execute stored procedure " + proc.getId()); 00450 00451 try 00452 { 00453 AbstractConnectionManager cm = backend.getConnectionManager(proc 00454 .getLogin()); 00455 if (proc.isAutoCommit()) 00456 { // Use a connection just for this request 00457 Connection c = null; 00458 try 00459 { 00460 c = cm.getConnection(); 00461 } 00462 catch (UnreachableBackendException e1) 00463 { 00464 String backendName = backend.getName(); 00465 logger.error(Translate.get( 00466 "loadbalancer.backend.disabling.unreachable", backendName)); 00467 backend.disable(); 00468 backend = null; 00469 throw new SQLException(Translate.get( 00470 "loadbalancer.backend.unreacheable", backendName)); 00471 } 00472 00473 // Sanity check 00474 if (c == null) 00475 throw new SQLException(Translate.get( 00476 "loadbalancer.backend.no.connection", backend.getName())); 00477 00478 // Execute Query 00479 ControllerResultSet rs = null; 00480 try 00481 { 00482 rs = AbstractLoadBalancer.executeReadStoredProcedureOnBackend(proc, 00483 backend, c, metadataCache); 00484 } 00485 catch (Exception e) 00486 { 00487 throw new SQLException(Translate.get( 00488 "loadbalancer.storedprocedure.failed.on.backend", new String[]{ 00489 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 00490 backend.getName(), e.getMessage()})); 00491 } 00492 finally 00493 { 00494 cm.releaseConnection(c); 00495 } 00496 return rs; 00497 } 00498 else 00499 { // Re-use the connection used by this transaction 00500 Connection c = cm.retrieveConnection(proc.getTransactionId()); 00501 00502 // Sanity check 00503 if (c == null) 00504 throw new SQLException(Translate.get( 00505 "loadbalancer.unable.retrieve.connection", new String[]{ 00506 String.valueOf(proc.getTransactionId()), backend.getName()})); 00507 00508 // Execute Query 00509 try 00510 { 00511 return AbstractLoadBalancer.executeReadStoredProcedureOnBackend(proc, 00512 backend, c, metadataCache); 00513 } 00514 catch (Exception e) 00515 { 00516 throw new SQLException(Translate.get( 00517 "loadbalancer.storedprocedure.failed.on.backend", new String[]{ 00518 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 00519 backend.getName(), e.getMessage()})); 00520 } 00521 } 00522 } 00523 catch (RuntimeException e) 00524 { 00525 String msg = Translate.get( 00526 "loadbalancer.storedprocedure.failed.on.backend", new String[]{ 00527 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 00528 backend.getName(), e.getMessage()}); 00529 logger.fatal(msg, e); 00530 throw new SQLException(msg); 00531 } 00532 } 00533 00537 public int execWriteStoredProcedure(StoredProcedure proc) throws SQLException 00538 { 00539 if (backend == null) 00540 throw new SQLException( 00541 "No available backend to execute stored procedure " + proc.getId()); 00542 00543 try 00544 { 00545 AbstractConnectionManager cm = backend.getConnectionManager(proc 00546 .getLogin()); 00547 if (proc.isAutoCommit()) 00548 { // Use a connection just for this request 00549 Connection c = null; 00550 try 00551 { 00552 c = cm.getConnection(); 00553 } 00554 catch (UnreachableBackendException e1) 00555 { 00556 String backendName = backend.getName(); 00557 logger.error(Translate.get( 00558 "loadbalancer.backend.disabling.unreachable", backendName)); 00559 backend.disable(); 00560 backend = null; 00561 throw new SQLException(Translate.get( 00562 "loadbalancer.backend.unreacheable", backendName)); 00563 } 00564 00565 // Sanity check 00566 if (c == null) 00567 throw new SQLException(Translate.get( 00568 "loadbalancer.backend.no.connection", backend.getName())); 00569 00570 // Execute Query 00571 int result; 00572 try 00573 { 00574 result = AbstractLoadBalancer.executeWriteStoredProcedureOnBackend( 00575 proc, backend, c); 00576 } 00577 catch (Exception e) 00578 { 00579 throw new SQLException(Translate.get( 00580 "loadbalancer.storedprocedure.failed.on.backend", new String[]{ 00581 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 00582 backend.getName(), e.getMessage()})); 00583 } 00584 finally 00585 { 00586 cm.releaseConnection(c); 00587 } 00588 return result; 00589 } 00590 else 00591 { // Re-use the connection used by this transaction 00592 Connection c = cm.retrieveConnection(proc.getTransactionId()); 00593 00594 // Sanity check 00595 if (c == null) 00596 throw new SQLException(Translate.get( 00597 "loadbalancer.unable.retrieve.connection", new String[]{ 00598 String.valueOf(proc.getTransactionId()), backend.getName()})); 00599 00600 // Execute Query 00601 try 00602 { 00603 return AbstractLoadBalancer.executeWriteStoredProcedureOnBackend( 00604 proc, backend, c); 00605 } 00606 catch (Exception e) 00607 { 00608 throw new SQLException(Translate.get( 00609 "loadbalancer.storedprocedure.failed.on.backend", new String[]{ 00610 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 00611 backend.getName(), e.getMessage()})); 00612 } 00613 } 00614 } 00615 catch (RuntimeException e) 00616 { 00617 String msg = Translate.get( 00618 "loadbalancer.storedprocedure.failed.on.backend", new String[]{ 00619 proc.getSQLShortForm(vdb.getSQLShortFormLength()), 00620 backend.getName(), e.getMessage()}); 00621 logger.fatal(msg, e); 00622 throw new SQLException(msg); 00623 } 00624 } 00625 00626 /* 00627 * Transaction management 00628 */ 00629 00636 public void begin(TransactionMarkerMetaData tm) throws SQLException 00637 { 00638 if (backend == null) 00639 throw new SQLException("No available backend to begin transaction " 00640 + tm.getTransactionId()); 00641 00642 // We do not accept new transactions if we are disabling the backend 00643 if (backend.isDisabling()) 00644 throw new SQLException(Translate.get("loadbalancer.backend.is.disabling", 00645 new String[]{"begin transaction " + tm.getTransactionId(), 00646 backend.getName()})); 00647 00648 try 00649 { 00650 Connection c = backend.getConnectionManager(tm.getLogin()).getConnection( 00651 tm.getTransactionId()); 00652 00653 if (c == null) 00654 throw new SQLException(Translate.get( 00655 "loadbalancer.backend.no.connection", backend.getName())); 00656 00657 c.setAutoCommit(false); 00658 } 00659 catch (Exception e) 00660 { 00661 throw new SQLException("Begin of transaction " + tm.getTransactionId() 00662 + " failed on backend " + backend.getURL() + " (" + e + ")"); 00663 } 00664 } 00665 00672 public void commit(TransactionMarkerMetaData tm) throws SQLException 00673 { 00674 if (backend == null) 00675 throw new SQLException("No available backend to commit transaction " 00676 + tm.getTransactionId()); 00677 00678 try 00679 { 00680 AbstractConnectionManager cm = backend 00681 .getConnectionManager(tm.getLogin()); 00682 Connection c = cm.retrieveConnection(tm.getTransactionId()); 00683 00684 if (c == null) 00685 throw new SQLException("No connection found for transaction " 00686 + tm.getTransactionId()); 00687 00688 try 00689 { 00690 c.commit(); 00691 c.setAutoCommit(true); 00692 } 00693 catch (SQLException e) 00694 { 00695 throw new SQLException(Translate.get("loadbalancer.commit.failed", 00696 new String[]{String.valueOf(tm.getTransactionId()), 00697 backend.getName(), e.getMessage()})); 00698 } 00699 finally 00700 { 00701 cm.releaseConnection(tm.getTransactionId()); 00702 } 00703 } 00704 catch (RuntimeException e) 00705 { 00706 String msg = Translate.get("loadbalancer.commit.failed", new String[]{ 00707 String.valueOf(tm.getTransactionId()), backend.getName(), 00708 e.getMessage()}); 00709 logger.fatal(msg, e); 00710 throw new SQLException(msg); 00711 } 00712 } 00713 00720 public void rollback(TransactionMarkerMetaData tm) throws SQLException 00721 { 00722 if (backend == null) 00723 throw new SQLException("No available backend to rollback transaction " 00724 + tm.getTransactionId()); 00725 00726 try 00727 { 00728 AbstractConnectionManager cm = backend 00729 .getConnectionManager(tm.getLogin()); 00730 Connection c = cm.retrieveConnection(tm.getTransactionId()); 00731 00732 if (c == null) 00733 throw new SQLException("No connection found for transaction " 00734 + tm.getTransactionId()); 00735 00736 try 00737 { 00738 c.rollback(); 00739 c.setAutoCommit(true); 00740 } 00741 catch (SQLException e) 00742 { 00743 throw new SQLException(Translate.get("loadbalancer.rollback.failed", 00744 new String[]{String.valueOf(tm.getTransactionId()), 00745 backend.getName(), e.getMessage()})); 00746 } 00747 finally 00748 { 00749 cm.releaseConnection(tm.getTransactionId()); 00750 } 00751 } 00752 catch (RuntimeException e) 00753 { 00754 String msg = Translate.get("loadbalancer.rollback.failed", new String[]{ 00755 String.valueOf(tm.getTransactionId()), backend.getName(), 00756 e.getMessage()}); 00757 logger.fatal(msg, e); 00758 throw new SQLException(msg); 00759 } 00760 } 00761 00762 /* 00763 * Backends management 00764 */ 00765 00774 public void enableBackend(DatabaseBackend db, boolean writeEnabled) 00775 throws SQLException 00776 { 00777 if (backend != null) 00778 { 00779 if (backend.isReadEnabled()) 00780 throw new SQLException( 00781 "SingleDB load balancer accepts only one backend and " 00782 + backend.getName() + " is already enabled. Skipping " 00783 + db.getName() + " initialization."); 00784 } 00785 backend = db; 00786 logger.info(Translate.get("loadbalancer.backend.enabling", db.getName())); 00787 if (!backend.isInitialized()) 00788 backend.initializeConnections(); 00789 backend.enableRead(); 00790 if (writeEnabled) 00791 backend.enableWrite(); 00792 } 00793 00801 public void disableBackend(DatabaseBackend db) throws SQLException 00802 { 00803 if (backend.equals(db)) 00804 { 00805 logger 00806 .info(Translate.get("loadbalancer.backend.disabling", db.getName())); 00807 backend.disable(); 00808 if (backend.isInitialized()) 00809 backend.finalizeConnections(); 00810 backend = null; 00811 } 00812 else 00813 { 00814 String msg = "Trying to disable a non-existing backend " + db.getName(); 00815 logger.warn(msg); 00816 throw new SQLException(msg); 00817 } 00818 } 00819 00824 public void setWeight(String name, int w) throws SQLException 00825 { 00826 throw new SQLException("Weight is not supported with this load balancer"); 00827 } 00828 00829 /* 00830 * Debug/Monitoring 00831 */ 00832 00838 public String getInformation() 00839 { 00840 if (backend == null) 00841 return "SingleDB Request load balancer: !!!Warning!!! No enabled backend node found\n"; 00842 else 00843 return "SingleDB Request load balancer using " + backend.getURL() + "\n"; 00844 } 00845 00849 public String getXmlImpl() 00850 { 00851 return "<" + DatabasesXmlTags.ELT_SingleDB + "/>"; 00852 } 00853 00854 }

CJDBCversion1.0.4に対してTue Oct 12 15:16:02 2004に生成されました。 doxygen 1.3.8