View Javadoc
1 // 2 // Copyright 1998 CDS Networks, Inc., Medford Oregon 3 // 4 // All rights reserved. 5 // 6 // Redistribution and use in source and binary forms, with or without 7 // modification, are permitted provided that the following conditions are met: 8 // 1. Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // 3. All advertising materials mentioning features or use of this software 14 // must display the following acknowledgement: 15 // This product includes software developed by CDS Networks, Inc. 16 // 4. The name of CDS Networks, Inc. may not be used to endorse or promote 17 // products derived from this software without specific prior 18 // written permission. 19 // 20 // THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND 21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 // ARE DISCLAIMED. IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE 24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 // SUCH DAMAGE. 31 // 32 33 34 35 package com.internetcds.jdbc.tds; 36 37 38 import java.sql.*; 39 import java.util.*; 40 import com.internetcds.jdbc.tds.TdsException; 41 42 43 44 /*** 45 * <P>The Java SQL framework allows for multiple database drivers. 46 * 47 * <P>Each driver should supply a class that implements 48 * the Driver interface. 49 * 50 * <P>The DriverManager will try to load as many drivers as it can 51 * find and then for any given connection request, it will ask each 52 * driver in turn to try to connect to the target URL. 53 * 54 * <P>It is strongly recommended that each Driver class should be 55 * small and standalone so that the Driver class can be loaded and 56 * queried without bringing in vast quantities of supporting code. 57 * 58 * <P>When a Driver class is loaded, it should create an instance of 59 * itself and register it with the DriverManager. This means that a 60 * user can load and register a driver by doing 61 * Class.forName("foo.bah.Driver"). 62 * 63 * @author Craig Spannring 64 * @author Igor Petrovski 65 * @version $Id: Driver.html,v 1.1 2003/05/12 16:19:44 sinisa Exp $ 66 * 67 * @see DriverManager 68 * @see Connection 69 */ 70 public class Driver implements java.sql.Driver 71 { 72 public static final String cvsVersion = "$Id: Driver.html,v 1.1 2003/05/12 16:19:44 sinisa Exp $"; 73 74 75 // 76 // Register ourselves with the DriverManager 77 // 78 static 79 { 80 try { 81 java.sql.DriverManager.registerDriver(new Driver()); 82 } 83 catch (SQLException E) { 84 E.printStackTrace(); 85 } 86 } 87 88 89 static final boolean debug = false; 90 static final String oldSQLServerUrlPrefix = "jdbc:freetds://"; 91 static final String newSQLServerUrlPrefix = "jdbc:freetds:sqlserver://"; 92 static final String sybaseUrlPrefix = "jdbc:freetds:sybase://"; 93 static final String defaultSQLServerPort = "1433"; 94 static final String defaultSybasePort = "7100"; 95 96 97 98 private boolean isValidHostname(String host) 99 { 100 return true; // XXX 101 } 102 103 /*** 104 * Parses the properties specified in <i>url</i> and adds them to 105 * <i>result</i>. 106 * 107 * @return true if the URL could be parsed successfully. 108 */ 109 protected boolean parseUrl(String url, Properties result) 110 { 111 String tmpUrl = url; 112 int serverType = -1; 113 114 if (tmpUrl.startsWith(oldSQLServerUrlPrefix) || 115 tmpUrl.startsWith(newSQLServerUrlPrefix) || 116 tmpUrl.startsWith(sybaseUrlPrefix)) 117 { 118 if (tmpUrl.startsWith(oldSQLServerUrlPrefix)) 119 { 120 serverType = Tds.SQLSERVER; 121 tmpUrl = tmpUrl.substring(oldSQLServerUrlPrefix.length()); 122 } 123 else if (tmpUrl.startsWith(newSQLServerUrlPrefix)) 124 { 125 serverType = Tds.SQLSERVER; 126 tmpUrl = tmpUrl.substring(newSQLServerUrlPrefix.length()); 127 } 128 else if (tmpUrl.startsWith(sybaseUrlPrefix)) 129 { 130 serverType = Tds.SYBASE; 131 tmpUrl = url.substring(sybaseUrlPrefix.length()); 132 } 133 134 135 try 136 { 137 StringTokenizer tokenizer = new StringTokenizer(tmpUrl, ":/;", 138 true); 139 String tmp; 140 String host = null; 141 String port = (serverType==Tds.SYBASE 142 ? defaultSybasePort 143 : defaultSQLServerPort); 144 String database = null; 145 // String tdsVer = "42"; 146 //Sinisa 147 String tdsVer = "7.0"; 148 149 // Get the hostname 150 host = tokenizer.nextToken(); 151 152 153 // Find the port if it has one. 154 tmp = tokenizer.nextToken(); 155 if (tmp.equals(":")) 156 { 157 port = tokenizer.nextToken(); 158 // Skip the '/' character 159 tmp = tokenizer.nextToken(); 160 } 161 162 if (tmp.equals("/")) 163 { 164 // find the database name 165 database = tokenizer.nextToken(); 166 if (tokenizer.hasMoreTokens()) 167 tmp = tokenizer.nextToken(); 168 } 169 170 171 // XXX The next loop is a bit too permisive. 172 while (tmp.equals(";")) 173 { 174 // Extract the additional attribute. 175 String extra = tokenizer.nextToken(); 176 StringTokenizer tok2 = new StringTokenizer(extra, "=", false); 177 String key = tok2.nextToken().toUpperCase(); 178 if (tok2.hasMoreTokens()) 179 { 180 result.put(key, tok2.nextToken()); 181 } 182 183 if (tokenizer.hasMoreTokens()) 184 { 185 tmp = tokenizer.nextToken(); 186 } 187 else 188 { 189 break; 190 } 191 } 192 193 // if there are anymore tokens then don't recognoze this URL 194 if ((! tokenizer.hasMoreTokens()) 195 && isValidHostname(host) 196 && database!=null) 197 { 198 result.put("HOST", host); 199 result.put("SERVERTYPE", "" + serverType); 200 result.put("PORT", port); 201 result.put("DBNAME", database); 202 } 203 else 204 { 205 return false; 206 } 207 } 208 catch (NoSuchElementException e) 209 { 210 return false; 211 } 212 } 213 else 214 { 215 return false; 216 } 217 218 return true; 219 } 220 221 222 /*** 223 * Construct a new driver and register it with DriverManager 224 * 225 * @exception SQLException 226 */ 227 public Driver() throws SQLException 228 { 229 } 230 231 232 /*** 233 * Try to make a database connection to the given URL. The driver 234 * should return "null" if it realizes it is the wrong kind of 235 * driver to connect to the given URL. This will be common, as 236 * when the JDBC driverManager is asked to connect to a given URL, 237 * it passes the URL to each loaded driver in turn. 238 * 239 * <p>The driver should raise an SQLException if it is the right driver 240 * to connect to the given URL, but has trouble connecting to the 241 * database. 242 * 243 * <p>The java.util.Properties argument can be used to pass arbitrary 244 * string tag/value pairs as connection arguments. 245 * 246 * This driver handles URLs of the form: 247 * <PRE> 248 * jdbc:freetds://servername/database 249 * jdbc:freetds://servername:port/database 250 * jdbc:freetds:sqlserver://servername/database 251 * jdbc:freetds:sqlserver://servername:port/database 252 * jdbc:freetds:sybase://servername/database 253 * jdbc:freetds:sybase://servername:port/database 254 * </PRE> 255 * <p> 256 * 257 * <table><thead>Recognized Properties</thead> 258 * <tbody> 259 * <tr><td>PROGNAME<td>Send this name to server to identify the program</tr> 260 * <tr><td>APPNAME<td>Send this name to server to identify the app</tr> 261 * </tbody> 262 * </table> 263 * 264 * @param url the URL of the database to connect to 265 * @param info a list of arbitrary tag/value pairs as connection 266 * arguments 267 * @return a connection to the URL or null if it isnt us 268 * @exception SQLException if a database access error occurs 269 * @see java.sql.Driver#connect 270 */ 271 public java.sql.Connection connect(String Url, Properties info) 272 throws SQLException 273 { 274 java.sql.Connection result = null; 275 276 if (!parseUrl(Url, info)) 277 { 278 return null; 279 } 280 else 281 { 282 try 283 { 284 result = Constructors.newConnection(info); 285 } 286 catch(NumberFormatException e) 287 { 288 throw new SQLException("NumberFormatException converting port number"); 289 } 290 catch(com.internetcds.jdbc.tds.TdsException e) 291 { 292 throw new SQLException(e.getMessage()); 293 } 294 } 295 return result; 296 } 297 298 /*** 299 * Returns true if the driver thinks it can open a connection to the 300 * given URL. Typically, drivers will return true if they understand 301 * the subprotocol specified in the URL and false if they don't. This 302 * driver's protocols start with jdbc:freetds: 303 * 304 * This driver handles URLs of the form: 305 * <PRE> 306 * jdbc:freetds://host:port/database 307 * </PRE> 308 * or 309 * <PRE> 310 * jdbc:freetds://host/database 311 * </PRE> 312 * <PRE> 313 * jdbc:freetds:sqlserver://host:port/database 314 * </PRE> 315 * or 316 * <PRE> 317 * jdbc:freetds:sqlserver://host/database 318 * </PRE> 319 * <PRE> 320 * jdbc:freetds:sybase://host:port/database 321 * </PRE> 322 * or 323 * <PRE> 324 * jdbc:freetds:sybase://host/database 325 * </PRE> 326 * 327 * @see java.sql.Driver#acceptsURL 328 * @param url the URL of the driver 329 * @return true if this driver accepts the given URL 330 * @exception SQLException if a database-access error occurs 331 */ 332 public boolean acceptsURL(String url) throws SQLException 333 { 334 boolean result = parseUrl(url, new Properties()); 335 return result; 336 } 337 338 /*** 339 * <p>The getPropertyInfo method is intended to allow a generic GUI tool to 340 * discover what properties it should prompt a human for in order to get 341 * enough information to connect to a database. Note that depending on 342 * the values the human has supplied so far, additional values may become 343 * necessary, so it may be necessary to iterate though several calls 344 * to getPropertyInfo. 345 * 346 * @param url The URL of the database to connect to. 347 * @param info A proposed list of tag/value pairs that will be sent on 348 * connect open. 349 * @return An array of DriverPropertyInfo objects describing possible 350 * properties. This array may be an empty array if no properties 351 * are required. 352 * @exception SQLException if a database-access error occurs. 353 */ 354 public DriverPropertyInfo[] getPropertyInfo(String Url, Properties Info) 355 throws SQLException 356 { 357 DriverPropertyInfo result[] = new DriverPropertyInfo[0]; 358 359 return result; 360 } 361 362 /*** 363 * Gets the drivers major version number 364 * 365 * @return the drivers major version number 366 */ 367 public int getMajorVersion() 368 { 369 return DriverVersion.getDriverMajorVersion(); 370 } 371 372 373 /*** 374 * Get the driver's minor version number. Initially this should be 0. 375 */ 376 public int getMinorVersion() 377 { 378 return DriverVersion.getDriverMinorVersion(); 379 } 380 381 382 /*** 383 * Report whether the Driver is a genuine JDBC COMPLIANT (tm) driver. 384 * A driver may only report "true" here if it passes the JDBC compliance 385 * tests, otherwise it is required to return false. 386 * 387 * JDBC compliance requires full support for the JDBC API and full support 388 * for SQL 92 Entry Level. It is expected that JDBC compliant drivers will 389 * be available for all the major commercial databases. 390 * 391 * This method is not intended to encourage the development of non-JDBC 392 * compliant drivers, but is a recognition of the fact that some vendors 393 * are interested in using the JDBC API and framework for lightweight 394 * databases that do not support full database functionality, or for 395 * special databases such as document information retrieval where a SQL 396 * implementation may not be feasible. 397 */ 398 public boolean jdbcCompliant() 399 { 400 // :-( MS SQLServer 6.5 doesn't provide what JDBC wants. 401 // See DatabaseMetaData.nullPlusNonNullIsNull() for more details. 402 // XXX Need to check if Sybase could be jdbcCompliant 403 return false; 404 } 405 406 }

This page automatically generated by Maven