88import com .codingapi .dbstream .scanner .DBMetaContext ;
99import com .codingapi .dbstream .scanner .DBMetaData ;
1010import com .codingapi .dbstream .scanner .DBScanner ;
11+ import com .codingapi .dbstream .utils .JDBCPropertyUtils ;
1112
1213import java .sql .*;
1314import java .util .Enumeration ;
1415import java .util .Properties ;
16+ import java .util .concurrent .ConcurrentHashMap ;
17+ import java .util .concurrent .ConcurrentMap ;
1518import java .util .logging .Logger ;
19+ import java .util .logging .Level ;
1620
1721public class DBStreamProxyDriver implements Driver {
1822
19- private Driver driver ;
23+ private static final ConcurrentMap <String , Driver > DRIVER_CACHE = new ConcurrentHashMap <>();
24+ private static final Logger LOGGER = Logger .getLogger (DBStreamProxyDriver .class .getName ());
2025
2126 static {
2227 try {
2328 DriverManager .registerDriver (new DBStreamProxyDriver ());
24- }catch (Exception e ){
25- throw new RuntimeException (e );
29+ } catch (Exception e ) {
30+ LOGGER .log (Level .SEVERE , "Failed to register DBStreamProxyDriver" , e );
31+ throw new RuntimeException ("Failed to register DBStreamProxyDriver" , e );
2632 }
2733 SQLRunningContext .getInstance ().addListener (new SQLDeleteExecuteListener ());
2834 SQLRunningContext .getInstance ().addListener (new SQLInsertExecuteListener ());
2935 SQLRunningContext .getInstance ().addListener (new SQLUpdateExecuteListener ());
30- System . out . println ("DBStreamProxyDriver init register... " );
36+ LOGGER . info ("DBStreamProxyDriver initialized and registered " );
3137 }
3238
39+ /**
40+ * 查找接受指定 URL 的真实 JDBC 驱动
41+ *
42+ * @param url JDBC URL
43+ * @return 真实的 JDBC 驱动,如果未找到则返回 null
44+ */
45+ private Driver findDriver (String url ) throws SQLException {
46+ if (url == null ) {
47+ return null ;
48+ }
49+
50+ // 从缓存中查找(使用 URL 前缀作为 key)
51+ Driver cachedDriver = DRIVER_CACHE .get (url );
52+ if (cachedDriver != null ) {
53+ try {
54+ // 验证缓存的驱动仍然接受该 URL
55+ if (cachedDriver .acceptsURL (url )) {
56+ return cachedDriver ;
57+ } else {
58+ // 如果缓存的驱动不再接受该 URL,从缓存中移除
59+ DRIVER_CACHE .remove (url , cachedDriver );
60+ }
61+ } catch (SQLException e ) {
62+ // 如果验证失败,从缓存中移除并继续查找
63+ DRIVER_CACHE .remove (url , cachedDriver );
64+ LOGGER .log (Level .FINE , "Cached driver no longer accepts URL: " + url , e );
65+ }
66+ }
67+
68+ // 遍历所有已注册的驱动
69+ Enumeration <Driver > drivers = DriverManager .getDrivers ();
70+ while (drivers .hasMoreElements ()) {
71+ Driver driver = drivers .nextElement ();
72+ if (driver .getClass ().equals (DBStreamProxyDriver .class )) {
73+ continue ;
74+ }
75+ try {
76+ if (driver .acceptsURL (url )) {
77+ // 缓存驱动(使用 URL 的前缀作为 key,因为同一个数据库类型的 URL 前缀相同)
78+ DRIVER_CACHE .putIfAbsent (url , driver );
79+ return driver ;
80+ }
81+ } catch (SQLException e ) {
82+ // 忽略单个驱动的异常,继续查找
83+ LOGGER .log (Level .FINE , "Driver " + driver .getClass ().getName () + " does not accept URL: " + url , e );
84+ }
85+ }
86+ return null ;
87+ }
88+
89+
3390 @ Override
3491 public Connection connect (String url , Properties info ) throws SQLException {
35- if (this .driver == null ) {
36- this .acceptsURL (url );
92+ if (url == null ) {
93+ throw new SQLException ("URL cannot be null" );
94+ }
95+
96+ Driver driver = findDriver (url );
97+ if (driver == null ) {
98+ throw new SQLException ("No suitable driver found for " + url );
3799 }
100+
38101 Connection connection = driver .connect (url , info );
102+ if (connection == null ) {
103+ throw new SQLException ("Driver returned null connection for URL: " + url );
104+ }
39105 info .setProperty (DBMetaData .KEY_JDBC_URL , url );
40- String jdbcKey = info . getProperty ( DBMetaData . KEY_JDBC_KEY );
106+ String jdbcKey = JDBCPropertyUtils . getJdbcKey ( info , connection . getSchema () );
41107 DBMetaData metaData = DBMetaContext .getInstance ().getMetaData (jdbcKey );
42108 if (metaData == null ) {
43109 DBScanner scanner = new DBScanner (connection , info );
@@ -49,42 +115,42 @@ public Connection connect(String url, Properties info) throws SQLException {
49115
50116 @ Override
51117 public boolean acceptsURL (String url ) throws SQLException {
52- Enumeration <Driver > drivers = DriverManager .getDrivers ();
53- while (drivers .hasMoreElements ()) {
54- Driver driver = drivers .nextElement ();
55- if (driver .getClass ().equals (DBStreamProxyDriver .class )){
56- continue ;
57- }
58- if (driver .acceptsURL (url )) {
59- this .driver = driver ;
60- return true ;
61- }
118+ if (url == null ) {
119+ return false ;
62120 }
63- return false ;
121+ Driver driver = findDriver (url );
122+ return driver != null ;
64123 }
65124
66125 @ Override
67126 public DriverPropertyInfo [] getPropertyInfo (String url , Properties info ) throws SQLException {
127+ Driver driver = findDriver (url );
128+ if (driver == null ) {
129+ throw new SQLException ("No suitable driver found for " + url );
130+ }
68131 return driver .getPropertyInfo (url , info );
69132 }
70133
71134 @ Override
72135 public int getMajorVersion () {
73- return driver .getMajorVersion ();
136+ // 返回代理驱动的主版本号
137+ return 1 ;
74138 }
75139
76140 @ Override
77141 public int getMinorVersion () {
78- return driver .getMinorVersion ();
142+ // 返回代理驱动的次版本号
143+ return 0 ;
79144 }
80145
81146 @ Override
82147 public boolean jdbcCompliant () {
83- return driver .jdbcCompliant ();
148+ // 代理驱动本身不直接兼容 JDBC,它依赖于底层驱动
149+ return false ;
84150 }
85151
86152 @ Override
87153 public Logger getParentLogger () throws SQLFeatureNotSupportedException {
88- return driver . getParentLogger () ;
154+ return LOGGER ;
89155 }
90156}
0 commit comments