EMMA Coverage Report (generated Mon Jul 24 20:22:52 CDT 2006)
[all classes][com.mysql.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [ReplicationConnection.java]

nameclass, %method, %block, %line, %
ReplicationConnection.java100% (1/1)26%  (11/43)52%  (186/359)56%  (55/98)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ReplicationConnection100% (1/1)26%  (11/43)52%  (186/359)56%  (55/98)
clearWarnings (): void 0%   (0/1)0%   (0/4)0%   (0/2)
commit (): void 0%   (0/1)0%   (0/4)0%   (0/2)
createStatement (int, int): Statement 0%   (0/1)0%   (0/6)0%   (0/1)
createStatement (int, int, int): Statement 0%   (0/1)0%   (0/7)0%   (0/1)
getAutoCommit (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
getCurrentConnection (): Connection 0%   (0/1)0%   (0/3)0%   (0/1)
getHoldability (): int 0%   (0/1)0%   (0/4)0%   (0/1)
getMetaData (): DatabaseMetaData 0%   (0/1)0%   (0/4)0%   (0/1)
getTransactionIsolation (): int 0%   (0/1)0%   (0/4)0%   (0/1)
getTypeMap (): Map 0%   (0/1)0%   (0/4)0%   (0/1)
getWarnings (): SQLWarning 0%   (0/1)0%   (0/4)0%   (0/1)
isClosed (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
isReadOnly (): boolean 0%   (0/1)0%   (0/9)0%   (0/1)
nativeSQL (String): String 0%   (0/1)0%   (0/5)0%   (0/1)
prepareCall (String): CallableStatement 0%   (0/1)0%   (0/5)0%   (0/1)
prepareCall (String, int, int): CallableStatement 0%   (0/1)0%   (0/7)0%   (0/1)
prepareCall (String, int, int, int): CallableStatement 0%   (0/1)0%   (0/8)0%   (0/1)
prepareStatement (String): PreparedStatement 0%   (0/1)0%   (0/5)0%   (0/1)
prepareStatement (String, String []): PreparedStatement 0%   (0/1)0%   (0/6)0%   (0/1)
prepareStatement (String, int []): PreparedStatement 0%   (0/1)0%   (0/6)0%   (0/1)
prepareStatement (String, int): PreparedStatement 0%   (0/1)0%   (0/6)0%   (0/1)
prepareStatement (String, int, int): PreparedStatement 0%   (0/1)0%   (0/7)0%   (0/1)
prepareStatement (String, int, int, int): PreparedStatement 0%   (0/1)0%   (0/8)0%   (0/1)
releaseSavepoint (Savepoint): void 0%   (0/1)0%   (0/5)0%   (0/2)
rollback (): void 0%   (0/1)0%   (0/4)0%   (0/2)
rollback (Savepoint): void 0%   (0/1)0%   (0/5)0%   (0/2)
setAutoCommit (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
setHoldability (int): void 0%   (0/1)0%   (0/5)0%   (0/2)
setSavepoint (): Savepoint 0%   (0/1)0%   (0/4)0%   (0/1)
setSavepoint (String): Savepoint 0%   (0/1)0%   (0/5)0%   (0/1)
setTransactionIsolation (int): void 0%   (0/1)0%   (0/5)0%   (0/2)
setTypeMap (Map): void 0%   (0/1)0%   (0/5)0%   (0/2)
swapConnections (Connection, Connection): void 100% (1/1)88%  (43/49)88%  (14/16)
ReplicationConnection (Properties, Properties): void 100% (1/1)100% (85/85)100% (22/22)
close (): void 100% (1/1)100% (7/7)100% (3/3)
createStatement (): Statement 100% (1/1)100% (4/4)100% (1/1)
getCatalog (): String 100% (1/1)100% (4/4)100% (1/1)
getMasterConnection (): Connection 100% (1/1)100% (3/3)100% (1/1)
getSlavesConnection (): Connection 100% (1/1)100% (3/3)100% (1/1)
setCatalog (String): void 100% (1/1)100% (5/5)100% (2/2)
setReadOnly (boolean): void 100% (1/1)100% (18/18)100% (6/6)
switchToMasterConnection (): void 100% (1/1)100% (7/7)100% (2/2)
switchToSlavesConnection (): void 100% (1/1)100% (7/7)100% (2/2)

1/*
2 Copyright (C) 2004 MySQL AB
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of version 2 of the GNU General Public License as 
6 published by the Free Software Foundation.
7 
8 There are special exceptions to the terms and conditions of the GPL 
9 as it is applied to this software. View the full text of the 
10 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
11 software distribution.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 */
22package com.mysql.jdbc;
23 
24import java.sql.CallableStatement;
25import java.sql.DatabaseMetaData;
26import java.sql.PreparedStatement;
27import java.sql.SQLException;
28import java.sql.SQLWarning;
29import java.sql.Savepoint;
30import java.sql.Statement;
31import java.util.Map;
32import java.util.Properties;
33 
34/**
35 * Connection that opens two connections, one two a replication master, and
36 * another to one or more slaves, and decides to use master when the connection
37 * is not read-only, and use slave(s) when the connection is read-only.
38 * 
39 * @version $Id: ReplicationConnection.java,v 1.1.2.1 2005/05/13 18:58:38
40 *          mmatthews Exp $
41 */
42public class ReplicationConnection implements java.sql.Connection {
43        private Connection currentConnection;
44 
45        private Connection masterConnection;
46 
47        private Connection slavesConnection;
48 
49        public ReplicationConnection(Properties masterProperties,
50                        Properties slaveProperties) throws SQLException {
51                Driver driver = new Driver();
52 
53                StringBuffer masterUrl = new StringBuffer("jdbc:mysql://");
54        StringBuffer slaveUrl = new StringBuffer("jdbc:mysql://");
55 
56        String masterHost = masterProperties
57                .getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY);
58        
59        if (masterHost != null) {
60                masterUrl.append(masterHost);
61        }
62 
63        String slaveHost = slaveProperties
64                .getProperty(NonRegisteringDriver.HOST_PROPERTY_KEY);
65                
66        if (slaveHost != null) {
67                slaveUrl.append(slaveHost);
68        }
69        
70        String masterDb = masterProperties
71                .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
72 
73        masterUrl.append("/");
74        
75        if (masterDb != null) {
76                masterUrl.append(masterDb);
77        }
78        
79        String slaveDb = slaveProperties
80                .getProperty(NonRegisteringDriver.DBNAME_PROPERTY_KEY);
81        
82        slaveUrl.append("/");
83        
84        if (slaveDb != null) {
85                slaveUrl.append(slaveDb);
86        }
87        
88        this.masterConnection = (com.mysql.jdbc.Connection) driver.connect(
89                masterUrl.toString(), masterProperties);
90        this.slavesConnection = (com.mysql.jdbc.Connection) driver.connect(
91                slaveUrl.toString(), slaveProperties);
92        
93                this.currentConnection = this.masterConnection;
94        }
95 
96        /*
97         * (non-Javadoc)
98         * 
99         * @see java.sql.Connection#clearWarnings()
100         */
101        public synchronized void clearWarnings() throws SQLException {
102                this.currentConnection.clearWarnings();
103        }
104 
105        /*
106         * (non-Javadoc)
107         * 
108         * @see java.sql.Connection#close()
109         */
110        public synchronized void close() throws SQLException {
111                this.masterConnection.close();
112                this.slavesConnection.close();
113        }
114 
115        /*
116         * (non-Javadoc)
117         * 
118         * @see java.sql.Connection#commit()
119         */
120        public synchronized void commit() throws SQLException {
121                this.currentConnection.commit();
122        }
123 
124        /*
125         * (non-Javadoc)
126         * 
127         * @see java.sql.Connection#createStatement()
128         */
129        public Statement createStatement() throws SQLException {
130                return this.currentConnection.createStatement();
131        }
132 
133        /*
134         * (non-Javadoc)
135         * 
136         * @see java.sql.Connection#createStatement(int, int)
137         */
138        public synchronized Statement createStatement(int resultSetType,
139                        int resultSetConcurrency) throws SQLException {
140                return this.currentConnection.createStatement(resultSetType,
141                                resultSetConcurrency);
142        }
143 
144        /*
145         * (non-Javadoc)
146         * 
147         * @see java.sql.Connection#createStatement(int, int, int)
148         */
149        public synchronized Statement createStatement(int resultSetType,
150                        int resultSetConcurrency, int resultSetHoldability)
151                        throws SQLException {
152                return this.currentConnection.createStatement(resultSetType,
153                                resultSetConcurrency, resultSetHoldability);
154        }
155 
156        /*
157         * (non-Javadoc)
158         * 
159         * @see java.sql.Connection#getAutoCommit()
160         */
161        public synchronized boolean getAutoCommit() throws SQLException {
162                return this.currentConnection.getAutoCommit();
163        }
164 
165        /*
166         * (non-Javadoc)
167         * 
168         * @see java.sql.Connection#getCatalog()
169         */
170        public synchronized String getCatalog() throws SQLException {
171                return this.currentConnection.getCatalog();
172        }
173 
174        public synchronized Connection getCurrentConnection() {
175                return this.currentConnection;
176        }
177 
178        /*
179         * (non-Javadoc)
180         * 
181         * @see java.sql.Connection#getHoldability()
182         */
183        public synchronized int getHoldability() throws SQLException {
184                return this.currentConnection.getHoldability();
185        }
186 
187        public synchronized Connection getMasterConnection() {
188                return this.masterConnection;
189        }
190 
191        /*
192         * (non-Javadoc)
193         * 
194         * @see java.sql.Connection#getMetaData()
195         */
196        public synchronized DatabaseMetaData getMetaData() throws SQLException {
197                return this.currentConnection.getMetaData();
198        }
199 
200        public synchronized Connection getSlavesConnection() {
201                return this.slavesConnection;
202        }
203 
204        /*
205         * (non-Javadoc)
206         * 
207         * @see java.sql.Connection#getTransactionIsolation()
208         */
209        public synchronized int getTransactionIsolation() throws SQLException {
210                return this.currentConnection.getTransactionIsolation();
211        }
212 
213        /*
214         * (non-Javadoc)
215         * 
216         * @see java.sql.Connection#getTypeMap()
217         */
218        public synchronized Map getTypeMap() throws SQLException {
219                return this.currentConnection.getTypeMap();
220        }
221 
222        /*
223         * (non-Javadoc)
224         * 
225         * @see java.sql.Connection#getWarnings()
226         */
227        public synchronized SQLWarning getWarnings() throws SQLException {
228                return this.currentConnection.getWarnings();
229        }
230 
231        /*
232         * (non-Javadoc)
233         * 
234         * @see java.sql.Connection#isClosed()
235         */
236        public synchronized boolean isClosed() throws SQLException {
237                return this.currentConnection.isClosed();
238        }
239 
240        /*
241         * (non-Javadoc)
242         * 
243         * @see java.sql.Connection#isReadOnly()
244         */
245        public synchronized boolean isReadOnly() throws SQLException {
246                return this.currentConnection == this.slavesConnection;
247        }
248 
249        /*
250         * (non-Javadoc)
251         * 
252         * @see java.sql.Connection#nativeSQL(java.lang.String)
253         */
254        public synchronized String nativeSQL(String sql) throws SQLException {
255                return this.currentConnection.nativeSQL(sql);
256        }
257 
258        /*
259         * (non-Javadoc)
260         * 
261         * @see java.sql.Connection#prepareCall(java.lang.String)
262         */
263        public CallableStatement prepareCall(String sql) throws SQLException {
264                return this.currentConnection.prepareCall(sql);
265        }
266 
267        /*
268         * (non-Javadoc)
269         * 
270         * @see java.sql.Connection#prepareCall(java.lang.String, int, int)
271         */
272        public synchronized CallableStatement prepareCall(String sql,
273                        int resultSetType, int resultSetConcurrency) throws SQLException {
274                return this.currentConnection.prepareCall(sql, resultSetType,
275                                resultSetConcurrency);
276        }
277 
278        /*
279         * (non-Javadoc)
280         * 
281         * @see java.sql.Connection#prepareCall(java.lang.String, int, int, int)
282         */
283        public synchronized CallableStatement prepareCall(String sql,
284                        int resultSetType, int resultSetConcurrency,
285                        int resultSetHoldability) throws SQLException {
286                return this.currentConnection.prepareCall(sql, resultSetType,
287                                resultSetConcurrency, resultSetHoldability);
288        }
289 
290        /*
291         * (non-Javadoc)
292         * 
293         * @see java.sql.Connection#prepareStatement(java.lang.String)
294         */
295        public PreparedStatement prepareStatement(String sql) throws SQLException {
296                return this.currentConnection.prepareStatement(sql);
297        }
298 
299        /*
300         * (non-Javadoc)
301         * 
302         * @see java.sql.Connection#prepareStatement(java.lang.String, int)
303         */
304        public synchronized PreparedStatement prepareStatement(String sql,
305                        int autoGeneratedKeys) throws SQLException {
306                return this.currentConnection.prepareStatement(sql, autoGeneratedKeys);
307        }
308 
309        /*
310         * (non-Javadoc)
311         * 
312         * @see java.sql.Connection#prepareStatement(java.lang.String, int, int)
313         */
314        public synchronized PreparedStatement prepareStatement(String sql,
315                        int resultSetType, int resultSetConcurrency) throws SQLException {
316                return this.currentConnection.prepareStatement(sql, resultSetType,
317                                resultSetConcurrency);
318        }
319 
320        /*
321         * (non-Javadoc)
322         * 
323         * @see java.sql.Connection#prepareStatement(java.lang.String, int, int,
324         *      int)
325         */
326        public synchronized PreparedStatement prepareStatement(String sql,
327                        int resultSetType, int resultSetConcurrency,
328                        int resultSetHoldability) throws SQLException {
329                return this.currentConnection.prepareStatement(sql, resultSetType,
330                                resultSetConcurrency, resultSetHoldability);
331        }
332 
333        /*
334         * (non-Javadoc)
335         * 
336         * @see java.sql.Connection#prepareStatement(java.lang.String, int[])
337         */
338        public synchronized PreparedStatement prepareStatement(String sql,
339                        int[] columnIndexes) throws SQLException {
340                return this.currentConnection.prepareStatement(sql, columnIndexes);
341        }
342 
343        /*
344         * (non-Javadoc)
345         * 
346         * @see java.sql.Connection#prepareStatement(java.lang.String,
347         *      java.lang.String[])
348         */
349        public synchronized PreparedStatement prepareStatement(String sql,
350                        String[] columnNames) throws SQLException {
351                return this.currentConnection.prepareStatement(sql, columnNames);
352        }
353 
354        /*
355         * (non-Javadoc)
356         * 
357         * @see java.sql.Connection#releaseSavepoint(java.sql.Savepoint)
358         */
359        public synchronized void releaseSavepoint(Savepoint savepoint)
360                        throws SQLException {
361                this.currentConnection.releaseSavepoint(savepoint);
362        }
363 
364        /*
365         * (non-Javadoc)
366         * 
367         * @see java.sql.Connection#rollback()
368         */
369        public synchronized void rollback() throws SQLException {
370                this.currentConnection.rollback();
371        }
372 
373        /*
374         * (non-Javadoc)
375         * 
376         * @see java.sql.Connection#rollback(java.sql.Savepoint)
377         */
378        public synchronized void rollback(Savepoint savepoint) throws SQLException {
379                this.currentConnection.rollback(savepoint);
380        }
381 
382        /*
383         * (non-Javadoc)
384         * 
385         * @see java.sql.Connection#setAutoCommit(boolean)
386         */
387        public synchronized void setAutoCommit(boolean autoCommit)
388                        throws SQLException {
389                this.currentConnection.setAutoCommit(autoCommit);
390        }
391 
392        /*
393         * (non-Javadoc)
394         * 
395         * @see java.sql.Connection#setCatalog(java.lang.String)
396         */
397        public synchronized void setCatalog(String catalog) throws SQLException {
398                this.currentConnection.setCatalog(catalog);
399        }
400 
401        /*
402         * (non-Javadoc)
403         * 
404         * @see java.sql.Connection#setHoldability(int)
405         */
406        public synchronized void setHoldability(int holdability)
407                        throws SQLException {
408                this.currentConnection.setHoldability(holdability);
409        }
410 
411        /*
412         * (non-Javadoc)
413         * 
414         * @see java.sql.Connection#setReadOnly(boolean)
415         */
416        public synchronized void setReadOnly(boolean readOnly) throws SQLException {
417                if (readOnly) {
418                        if (currentConnection != slavesConnection) {
419                                switchToSlavesConnection();
420                        }
421                } else {
422                        if (currentConnection != masterConnection) {
423                                switchToMasterConnection();
424                        }
425                }
426        }
427 
428        /*
429         * (non-Javadoc)
430         * 
431         * @see java.sql.Connection#setSavepoint()
432         */
433        public synchronized Savepoint setSavepoint() throws SQLException {
434                return this.currentConnection.setSavepoint();
435        }
436 
437        /*
438         * (non-Javadoc)
439         * 
440         * @see java.sql.Connection#setSavepoint(java.lang.String)
441         */
442        public synchronized Savepoint setSavepoint(String name) throws SQLException {
443                return this.currentConnection.setSavepoint(name);
444        }
445 
446        /*
447         * (non-Javadoc)
448         * 
449         * @see java.sql.Connection#setTransactionIsolation(int)
450         */
451        public synchronized void setTransactionIsolation(int level)
452                        throws SQLException {
453                this.currentConnection.setTransactionIsolation(level);
454        }
455 
456        // For testing
457 
458        /*
459         * (non-Javadoc)
460         * 
461         * @see java.sql.Connection#setTypeMap(java.util.Map)
462         */
463        public synchronized void setTypeMap(Map arg0) throws SQLException {
464                this.currentConnection.setTypeMap(arg0);
465        }
466 
467        private synchronized void switchToMasterConnection() throws SQLException {
468                swapConnections(this.masterConnection, this.slavesConnection);
469        }
470 
471        private synchronized void switchToSlavesConnection() throws SQLException {
472                swapConnections(this.slavesConnection, this.masterConnection);
473        }
474        
475        /**
476         * Swaps current context (catalog, autocommit and txn_isolation) from
477         * sourceConnection to targetConnection, and makes targetConnection
478         * the "current" connection that will be used for queries.
479         * 
480         * @param switchToConnection the connection to swap from
481         * @param switchFromConnection the connection to swap to
482         * 
483         * @throws SQLException if an error occurs
484         */
485        private synchronized void swapConnections(Connection switchToConnection, 
486                        Connection switchFromConnection) throws SQLException {
487                String switchFromCatalog = switchFromConnection.getCatalog();
488                String switchToCatalog = switchToConnection.getCatalog();
489 
490                if (switchToCatalog != null && !switchToCatalog.equals(switchFromCatalog)) {
491                        switchToConnection.setCatalog(switchFromCatalog);
492                } else if (switchFromCatalog != null) {
493                        switchToConnection.setCatalog(switchFromCatalog);
494                }
495 
496                boolean switchToAutoCommit = switchToConnection.getAutoCommit();
497                boolean switchFromConnectionAutoCommit = switchFromConnection.getAutoCommit();
498                
499                if (switchFromConnectionAutoCommit != switchToAutoCommit) {
500                        switchToConnection.setAutoCommit(switchFromConnectionAutoCommit);
501                }
502 
503                int switchToIsolation = switchToConnection
504                                .getTransactionIsolation();
505 
506                int switchFromIsolation = switchFromConnection.getTransactionIsolation();
507                
508                if (switchFromIsolation != switchToIsolation) {
509                        switchToConnection
510                                        .setTransactionIsolation(switchFromIsolation);
511                }
512                
513                this.currentConnection = switchToConnection;
514        }
515}

[all classes][com.mysql.jdbc]
EMMA 2.0.4217 (C) Vladimir Roubtsov