1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/java/jdbc-dk-driver/conf/META-INF/services/java.sql.Driver Sun May 17 00:27:56 2015 +0200
1.3 @@ -0,0 +1,1 @@
1.4 +info.globalcode.sql.dk.jdbc.Driver
2.1 --- a/java/jdbc-dk-driver/nbproject/build-impl.xml Sat May 16 23:58:06 2015 +0200
2.2 +++ b/java/jdbc-dk-driver/nbproject/build-impl.xml Sun May 17 00:27:56 2015 +0200
2.3 @@ -127,6 +127,7 @@
2.4 </condition>
2.5 <condition property="have.sources">
2.6 <or>
2.7 + <available file="${src.conf.dir}"/>
2.8 <available file="${src.dir}"/>
2.9 <available file="${src.sql-dk.dir}"/>
2.10 </or>
2.11 @@ -224,6 +225,7 @@
2.12 <!-- You can override this target in the ../build.xml file. -->
2.13 </target>
2.14 <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
2.15 + <fail unless="src.conf.dir">Must set src.conf.dir</fail>
2.16 <fail unless="src.dir">Must set src.dir</fail>
2.17 <fail unless="src.sql-dk.dir">Must set src.sql-dk.dir</fail>
2.18 <fail unless="test.src.dir">Must set test.src.dir</fail>
2.19 @@ -247,7 +249,7 @@
2.20 </target>
2.21 <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
2.22 <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
2.23 - <attribute default="${src.dir}:${src.sql-dk.dir}" name="srcdir"/>
2.24 + <attribute default="${src.conf.dir}:${src.dir}:${src.sql-dk.dir}" name="srcdir"/>
2.25 <attribute default="${build.classes.dir}" name="destdir"/>
2.26 <attribute default="${javac.classpath}" name="classpath"/>
2.27 <attribute default="${javac.processorpath}" name="processorpath"/>
2.28 @@ -288,7 +290,7 @@
2.29 </target>
2.30 <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
2.31 <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
2.32 - <attribute default="${src.dir}:${src.sql-dk.dir}" name="srcdir"/>
2.33 + <attribute default="${src.conf.dir}:${src.dir}:${src.sql-dk.dir}" name="srcdir"/>
2.34 <attribute default="${build.classes.dir}" name="destdir"/>
2.35 <attribute default="${javac.classpath}" name="classpath"/>
2.36 <attribute default="${javac.processorpath}" name="processorpath"/>
2.37 @@ -321,7 +323,7 @@
2.38 </target>
2.39 <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
2.40 <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
2.41 - <attribute default="${src.dir}:${src.sql-dk.dir}" name="srcdir"/>
2.42 + <attribute default="${src.conf.dir}:${src.dir}:${src.sql-dk.dir}" name="srcdir"/>
2.43 <attribute default="${build.classes.dir}" name="destdir"/>
2.44 <attribute default="${javac.classpath}" name="classpath"/>
2.45 <sequential>
2.46 @@ -919,11 +921,12 @@
2.47 <include name="*"/>
2.48 </dirset>
2.49 </pathconvert>
2.50 - <j2seproject3:depend srcdir="${src.dir}:${src.sql-dk.dir}:${build.generated.subdirs}"/>
2.51 + <j2seproject3:depend srcdir="${src.conf.dir}:${src.dir}:${src.sql-dk.dir}:${build.generated.subdirs}"/>
2.52 </target>
2.53 <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
2.54 <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
2.55 <copy todir="${build.classes.dir}">
2.56 + <fileset dir="${src.conf.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
2.57 <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
2.58 <fileset dir="${src.sql-dk.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
2.59 </copy>
2.60 @@ -946,7 +949,7 @@
2.61 <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
2.62 <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
2.63 <j2seproject3:force-recompile/>
2.64 - <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}:${src.sql-dk.dir}"/>
2.65 + <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.conf.dir}:${src.dir}:${src.sql-dk.dir}"/>
2.66 </target>
2.67 <target name="-post-compile-single">
2.68 <!-- Empty placeholder for easier customization. -->
2.69 @@ -1212,6 +1215,9 @@
2.70 <classpath>
2.71 <path path="${javac.classpath}"/>
2.72 </classpath>
2.73 + <fileset dir="${src.conf.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
2.74 + <filename name="**/*.java"/>
2.75 + </fileset>
2.76 <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
2.77 <filename name="**/*.java"/>
2.78 </fileset>
2.79 @@ -1225,6 +1231,9 @@
2.80 <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
2.81 </javadoc>
2.82 <copy todir="${dist.javadoc.dir}">
2.83 + <fileset dir="${src.conf.dir}" excludes="${excludes}" includes="${includes}">
2.84 + <filename name="**/doc-files/**"/>
2.85 + </fileset>
2.86 <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
2.87 <filename name="**/doc-files/**"/>
2.88 </fileset>
3.1 --- a/java/jdbc-dk-driver/nbproject/genfiles.properties Sat May 16 23:58:06 2015 +0200
3.2 +++ b/java/jdbc-dk-driver/nbproject/genfiles.properties Sun May 17 00:27:56 2015 +0200
3.3 @@ -1,8 +1,8 @@
3.4 -build.xml.data.CRC32=64e20838
3.5 +build.xml.data.CRC32=50d83c90
3.6 build.xml.script.CRC32=3b53b17c
3.7 build.xml.stylesheet.CRC32=8064a381@1.75.2.48
3.8 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
3.9 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
3.10 -nbproject/build-impl.xml.data.CRC32=64e20838
3.11 -nbproject/build-impl.xml.script.CRC32=01f7bc2f
3.12 +nbproject/build-impl.xml.data.CRC32=50d83c90
3.13 +nbproject/build-impl.xml.script.CRC32=0d479eb1
3.14 nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48
4.1 --- a/java/jdbc-dk-driver/nbproject/project.properties Sat May 16 23:58:06 2015 +0200
4.2 +++ b/java/jdbc-dk-driver/nbproject/project.properties Sun May 17 00:27:56 2015 +0200
4.3 @@ -37,8 +37,8 @@
4.4 javac.deprecation=false
4.5 javac.processorpath=\
4.6 ${javac.classpath}
4.7 -javac.source=1.8
4.8 -javac.target=1.8
4.9 +javac.source=1.7
4.10 +javac.target=1.7
4.11 javac.test.classpath=\
4.12 ${javac.classpath}:\
4.13 ${build.classes.dir}
4.14 @@ -69,6 +69,7 @@
4.15 ${javac.test.classpath}:\
4.16 ${build.test.classes.dir}
4.17 source.encoding=UTF-8
4.18 +src.conf.dir=conf
4.19 src.dir=src
4.20 src.sql-dk.dir=libs/sql-dk
4.21 test.src.dir=test
5.1 --- a/java/jdbc-dk-driver/nbproject/project.xml Sat May 16 23:58:06 2015 +0200
5.2 +++ b/java/jdbc-dk-driver/nbproject/project.xml Sun May 17 00:27:56 2015 +0200
5.3 @@ -5,6 +5,7 @@
5.4 <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
5.5 <name>jdbc-dk-driver</name>
5.6 <source-roots>
5.7 + <root id="src.conf.dir" name="Config"/>
5.8 <root id="src.dir"/>
5.9 <root id="src.sql-dk.dir"/>
5.10 </source-roots>
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/java/jdbc-dk-driver/src/info/globalcode/sql/dk/jdbc/Driver.java Sun May 17 00:27:56 2015 +0200
6.3 @@ -0,0 +1,156 @@
6.4 +/**
6.5 + * SQL-DK
6.6 + * Copyright © 2015 František Kučera (frantovo.cz)
6.7 + *
6.8 + * This program is free software: you can redistribute it and/or modify
6.9 + * it under the terms of the GNU General Public License as published by
6.10 + * the Free Software Foundation, either version 3 of the License, or
6.11 + * (at your option) any later version.
6.12 + *
6.13 + * This program is distributed in the hope that it will be useful,
6.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.16 + * GNU General Public License for more details.
6.17 + *
6.18 + * You should have received a copy of the GNU General Public License
6.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
6.20 + */
6.21 +package info.globalcode.sql.dk.jdbc;
6.22 +
6.23 +import info.globalcode.sql.dk.Constants;
6.24 +import info.globalcode.sql.dk.configuration.Configuration;
6.25 +import info.globalcode.sql.dk.configuration.ConfigurationException;
6.26 +import info.globalcode.sql.dk.configuration.DatabaseDefinition;
6.27 +import info.globalcode.sql.dk.configuration.Loader;
6.28 +import info.globalcode.sql.dk.configuration.Properties;
6.29 +import info.globalcode.sql.dk.configuration.Property;
6.30 +import java.sql.Connection;
6.31 +import java.sql.DriverManager;
6.32 +import java.sql.DriverPropertyInfo;
6.33 +import java.sql.SQLException;
6.34 +import java.sql.SQLFeatureNotSupportedException;
6.35 +import java.util.logging.Level;
6.36 +import java.util.logging.Logger;
6.37 +
6.38 +/**
6.39 + * <p>
6.40 + * Meta JDBC driver that works as redirector/router. It loads SQL-DK's configuration file and
6.41 + * instantiates a real JDBC connection (PostgreSQL, MariDB etc.) of given name.
6.42 + * </p>
6.43 + *
6.44 + * <p>
6.45 + * Raison d'être: user can define his/her database connections just once (in SQL-DK's configuration)
6.46 + * and use them in many other programs – there is no need to define the connection (hostname,
6.47 + * username, password, properties…) in each application again and again. User will simply connect to
6.48 + * e.g. <code>jdbc:sql-dk://my-connection</code> and this driver reads parameters of
6.49 + * <code>my-connection</code> from SQL-DK's configuration and returns real driver implementation.
6.50 + * </p>
6.51 + *
6.52 + * <p>
6.53 + * Of course, the real JDBC driver for given database is still needed on the class path.
6.54 + * </p>
6.55 + *
6.56 + * <p>
6.57 + * TODO: current version is quite heavy-weight, because it includes whole SQL-DK source tree. Some
6.58 + * refactoring and separation is desired to provide more light-weight JDBC driver. Although the
6.59 + * public interface and behavior of this driver should remain same.
6.60 + * </p>
6.61 + *
6.62 + * @author Ing. František Kučera (frantovo.cz)
6.63 + */
6.64 +public class Driver implements java.sql.Driver {
6.65 +
6.66 + private static final Logger log = Logger.getLogger(Driver.class.getName());
6.67 +
6.68 + private final Loader loader = new Loader();
6.69 +
6.70 + static {
6.71 + try {
6.72 + DriverManager.registerDriver(new Driver());
6.73 + } catch (SQLException e) {
6.74 + log.log(Level.SEVERE, "Unable to register JDBC driver", e);
6.75 + }
6.76 + }
6.77 +
6.78 + @Override
6.79 + public Connection connect(String url, java.util.Properties info) throws SQLException {
6.80 + if (acceptsURL(url)) {
6.81 + log.log(Level.FINER, "Loading SQL-DK configuration for URL: {0}", url);
6.82 + String name = extractDatabaseName(url);
6.83 + log.log(Level.FINE, "Loading SQL-DK configuration for name: {0}", name);
6.84 +
6.85 + try {
6.86 + return getConnection(name, info);
6.87 + } catch (ConfigurationException e) {
6.88 + log.log(Level.SEVERE, "Unable to load SQL-DK configuration for name: {0}. Is it defined in {1}?", new Object[]{name, Constants.CONFIG_FILE});
6.89 + throw new SQLException("Unable to load SQL-DK configuration for name: " + name, e);
6.90 + }
6.91 + } else {
6.92 + throw new SQLException("Unsupported URL: " + url);
6.93 + }
6.94 + }
6.95 +
6.96 + private Connection getConnection(String connectionName, java.util.Properties info) throws SQLException, ConfigurationException {
6.97 + Configuration c = loader.loadConfiguration();
6.98 + DatabaseDefinition dd = c.getDatabase(connectionName);
6.99 +
6.100 + if (acceptsURL(dd.getUrl())) {
6.101 + log.log(Level.SEVERE, "SQL-DK meta JDBC driver loops to itself: {0} → {1} Please check {2}", new Object[]{connectionName, dd.getUrl(), Constants.CONFIG_FILE});
6.102 + throw new ConfigurationException("SQL-DK meta JDBC driver loops to itself.");
6.103 + } else {
6.104 + return Loader.jdbcConnect(dd, translate(info));
6.105 + }
6.106 + }
6.107 +
6.108 + private String extractDatabaseName(String url) {
6.109 + return url.split("//", 2)[1];
6.110 + }
6.111 +
6.112 + /**
6.113 + * TODO: refactor/move, reuse
6.114 + *
6.115 + * @param info
6.116 + * @return
6.117 + */
6.118 + private Properties translate(java.util.Properties info) {
6.119 + Properties properties = new Properties();
6.120 +
6.121 + for (String name : info.stringPropertyNames()) {
6.122 + String value = info.getProperty(name);
6.123 + properties.add(new Property(name, value));
6.124 + }
6.125 +
6.126 + return properties;
6.127 + }
6.128 +
6.129 + @Override
6.130 + public boolean acceptsURL(String url) throws SQLException {
6.131 + return url != null && url.startsWith("jdbc:sql-dk://");
6.132 + }
6.133 +
6.134 + @Override
6.135 + public DriverPropertyInfo[] getPropertyInfo(String url, java.util.Properties info) throws SQLException {
6.136 + return new DriverPropertyInfo[0];
6.137 + }
6.138 +
6.139 + @Override
6.140 + public int getMajorVersion() {
6.141 + return 0;
6.142 + }
6.143 +
6.144 + @Override
6.145 + public int getMinorVersion() {
6.146 + return 1;
6.147 + }
6.148 +
6.149 + @Override
6.150 + public boolean jdbcCompliant() {
6.151 + return false;
6.152 + }
6.153 +
6.154 + @Override
6.155 + public Logger getParentLogger() throws SQLFeatureNotSupportedException {
6.156 + throw new SQLFeatureNotSupportedException("Not supported yet.");
6.157 + }
6.158 +
6.159 +}
7.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Sat May 16 23:58:06 2015 +0200
7.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/DatabaseConnection.java Sun May 17 00:27:56 2015 +0200
7.3 @@ -22,14 +22,13 @@
7.4 import info.globalcode.sql.dk.batch.Batch;
7.5 import info.globalcode.sql.dk.batch.BatchException;
7.6 import info.globalcode.sql.dk.configuration.DatabaseDefinition;
7.7 +import info.globalcode.sql.dk.configuration.Loader;
7.8 import info.globalcode.sql.dk.configuration.Properties;
7.9 -import info.globalcode.sql.dk.configuration.Property;
7.10 import info.globalcode.sql.dk.formatting.ColumnsHeader;
7.11 import info.globalcode.sql.dk.formatting.Formatter;
7.12 import info.globalcode.sql.dk.jmx.ConnectionManagement;
7.13 import info.globalcode.sql.dk.jmx.ConnectionManagement.COUNTER;
7.14 import java.sql.Connection;
7.15 -import java.sql.DriverManager;
7.16 import java.sql.PreparedStatement;
7.17 import java.sql.ResultSet;
7.18 import java.sql.SQLException;
7.19 @@ -49,7 +48,7 @@
7.20 public class DatabaseConnection implements AutoCloseable {
7.21
7.22 private static final Logger log = Logger.getLogger(DatabaseConnection.class.getName());
7.23 - private static final String JDBC_PROPERTY_USER = "user";
7.24 + public static final String JDBC_PROPERTY_USER = "user";
7.25 public static final String JDBC_PROPERTY_PASSWORD = "password";
7.26 private final DatabaseDefinition databaseDefinition;
7.27 private final Connection connection;
7.28 @@ -71,19 +70,7 @@
7.29 this.databaseDefinition = databaseDefinition;
7.30 this.properties = properties;
7.31 this.connectionMBean = connectionMBean;
7.32 -
7.33 - if (properties.hasProperty(JDBC_PROPERTY_PASSWORD)) {
7.34 - log.log(Level.WARNING, "Passing DB password as CLI parameter is insecure!");
7.35 - }
7.36 -
7.37 - Properties credentials = new Properties();
7.38 - credentials.add(new Property(JDBC_PROPERTY_USER, databaseDefinition.getUserName()));
7.39 - credentials.add(new Property(JDBC_PROPERTY_PASSWORD, databaseDefinition.getPassword()));
7.40 - credentials.setDefaults(databaseDefinition.getProperties());
7.41 - properties.setDefaults(credentials);
7.42 - java.util.Properties javaProperties = properties.getJavaProperties();
7.43 -
7.44 - connection = DriverManager.getConnection(databaseDefinition.getUrl(), javaProperties);
7.45 + this.connection = Loader.jdbcConnect(databaseDefinition, properties);
7.46 }
7.47
7.48 public void executeQuery(SQLCommand sqlCommand, Formatter formatter) throws SQLException {
7.49 @@ -116,7 +103,7 @@
7.50 private void processCommand(SQLCommand sqlCommand, Formatter formatter) throws SQLException {
7.51 incrementCounter(connectionMBean, COUNTER.COMMAND);
7.52 resetCounter(connectionMBean, COUNTER.RECORD_CURRENT);
7.53 -
7.54 +
7.55 try (PreparedStatement ps = sqlCommand.prepareStatement(connection)) {
7.56 log.log(Level.FINE, "Statement prepared");
7.57 sqlCommand.parametrize(ps);
7.58 @@ -157,7 +144,7 @@
7.59 while (rs.next()) {
7.60 incrementCounter(connectionMBean, COUNTER.RECORD_CURRENT);
7.61 incrementCounter(connectionMBean, COUNTER.RECORD_TOTAL);
7.62 -
7.63 +
7.64 formatter.writeStartRow();
7.65
7.66 for (int i = 1; i <= columnCount; i++) {
8.1 --- a/java/sql-dk/src/info/globalcode/sql/dk/configuration/Loader.java Sat May 16 23:58:06 2015 +0200
8.2 +++ b/java/sql-dk/src/info/globalcode/sql/dk/configuration/Loader.java Sun May 17 00:27:56 2015 +0200
8.3 @@ -18,6 +18,13 @@
8.4 package info.globalcode.sql.dk.configuration;
8.5
8.6 import info.globalcode.sql.dk.*;
8.7 +import static info.globalcode.sql.dk.DatabaseConnection.JDBC_PROPERTY_USER;
8.8 +import static info.globalcode.sql.dk.DatabaseConnection.JDBC_PROPERTY_PASSWORD;
8.9 +import java.sql.Connection;
8.10 +import java.sql.DriverManager;
8.11 +import java.sql.SQLException;
8.12 +import java.util.logging.Level;
8.13 +import java.util.logging.Logger;
8.14 import javax.xml.bind.JAXBContext;
8.15 import javax.xml.bind.Unmarshaller;
8.16
8.17 @@ -28,6 +35,8 @@
8.18 */
8.19 public class Loader {
8.20
8.21 + private static final Logger log = Logger.getLogger(Loader.class.getName());
8.22 +
8.23 public Configuration loadConfiguration() throws ConfigurationException {
8.24 try {
8.25 JAXBContext jaxb = JAXBContext.newInstance(Configuration.class);
8.26 @@ -38,4 +47,26 @@
8.27 }
8.28 }
8.29
8.30 + /**
8.31 + * JDBC connection should not be used directly in SQL-DK.
8.32 + *
8.33 + * @see DatabaseDefinition#connect(info.globalcode.sql.dk.configuration.Properties)
8.34 + * @param properties
8.35 + * @param databaseDefinition
8.36 + * @return
8.37 + * @throws java.sql.SQLException
8.38 + */
8.39 + public static Connection jdbcConnect(DatabaseDefinition databaseDefinition, Properties properties) throws SQLException {
8.40 + if (properties.hasProperty(JDBC_PROPERTY_PASSWORD)) {
8.41 + log.log(Level.WARNING, "Passing DB password as CLI parameter is insecure!");
8.42 + }
8.43 + Properties credentials = new Properties();
8.44 + credentials.add(new Property(JDBC_PROPERTY_USER, databaseDefinition.getUserName()));
8.45 + credentials.add(new Property(JDBC_PROPERTY_PASSWORD, databaseDefinition.getPassword()));
8.46 + credentials.setDefaults(databaseDefinition.getProperties());
8.47 + properties.setDefaults(credentials);
8.48 + java.util.Properties javaProperties = properties.getJavaProperties();
8.49 + return DriverManager.getConnection(databaseDefinition.getUrl(), javaProperties);
8.50 + }
8.51 +
8.52 }