package nl.anchormen.sql4es.jdbc; import java.net.URI; import java.net.URISyntaxException; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; import java.sql.DriverPropertyInfo; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.Map; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import nl.anchormen.sql4es.model.Utils; /** * Basic {@link Driver} implementation used to get {@link ESConnection}. * * @author cversloot * */ public class ESDriver implements Driver{ private static final Logger logger = LoggerFactory.getLogger(ESDriver.class.getName()); /** * Register this driver with the driver manager */ static{ try { DriverManager.registerDriver(new ESDriver()); } catch (SQLException sqle) { logger.error("Unable to register Driver", sqle); } } @Override public Connection connect(String url, Properties info) throws SQLException { Object[] conInfo = parseURL(url, info); String host = (String)conInfo[0]; int port = (int)conInfo[1]; String index = (String)conInfo[2]; Properties props = (Properties)conInfo[3]; return new ESConnection(host, port, index, props); } /** * Parses the url and returns information required to create a connection. Properties * in the url are added to the provided properties and returned in the object array * @param url * @param info * @return {String:host, int:port, String:index, Properties:info} * @throws SQLException */ private Object[] parseURL(String url, Properties info) throws SQLException{ if(!acceptsURL(url)) throw new SQLException("Invalid url"); try { URI uri = new URI(url.substring(12)); String host = uri.getHost(); int port = (uri.getPort() < 0 ? Utils.PORT : uri.getPort()); String index = uri.getPath().length() <= 1 ? null : uri.getPath().split("/")[1]; Properties props = Utils.defaultProps(); if(info != null) { props.putAll(info); } info = props; if(uri.getQuery() != null) for(String keyValue : uri.getQuery().split("&")){ String[] parts = keyValue.split("="); if(parts.length > 1) info.setProperty(parts[0].trim(), parts[1].trim()); else info.setProperty(parts[0], ""); } return new Object[]{host, port, index, info}; } catch (URISyntaxException e) { throw new SQLException("Unable to parse URL. Pleas use '"+Utils.PREFIX+"//host:port/schema?{0,1}(param=value&)*'", e); }catch(ArrayIndexOutOfBoundsException e){ throw new SQLException("No shema (index) specified. Pleas use '"+Utils.PREFIX+"//host:port/schema?{0,1}(param=value&)*'"); }catch(Exception e){ throw new SQLException("Unable to connect to database due to: "+e.getClass().getName(), e); } } @Override public boolean acceptsURL(String url) throws SQLException { if(!url.startsWith(Utils.PREFIX)) return false; try { URI uri = new URI(url.substring(5)); if(uri.getHost() == null) throw new SQLException("Invalid URL, no host specified"); if(uri.getPath() == null) throw new SQLException("Invalid URL, no index specified"); if(uri.getPath().split("/").length > 2) throw new SQLException("Invalid URL, "+uri.getPath()+" is not a valid index"); } catch (URISyntaxException e) { throw new SQLException("Unable to parse URL", e); } return true; } @Override public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { Properties props = (Properties)parseURL(url, info)[3]; DriverPropertyInfo[] result = new DriverPropertyInfo[props.size()]; int index = 0; for(Map.Entry<Object,Object> entry : props.entrySet()){ result[index] = new DriverPropertyInfo((String)entry.getKey(), entry.getValue().toString()); index++; } return result; } @Override public int getMajorVersion() { return Utils.ES_MAJOR_VERSION; } @Override public int getMinorVersion() { return Utils.ES_MINOR_VERSION; } @Override public boolean jdbcCompliant() { return false; } @Override public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException { throw new SQLFeatureNotSupportedException(Utils.getLoggingInfo()); } }