Skip to content

Commit

Permalink
User lowercases in H2.
Browse files Browse the repository at this point in the history
  • Loading branch information
wise-coders committed Feb 25, 2022
1 parent 1ccfbcf commit f96f0b3
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 98 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies {
jar {
archiveName ="dbschema-dbf-jdbc${version}.jar"
manifest {
attributes 'Main-Class': 'com.dbschema.dbf.JdbcDriver'
attributes 'Main-Class': 'com.wisecoders.dbschema.dbf.JdbcDriver'
attributes 'Specification-Version': "$version"
attributes 'Specification-Vendor': "Wise Coders"
attributes 'Implementation-Vendor-Id': "dbschema.com"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.wisecoders.dbschema.dbf;

import com.wisecoders.dbschema.dbf.io.DBFtoH2;
import com.wisecoders.dbschema.dbf.io.H2toDBF;
import com.wisecoders.dbschema.dbf.io.H2Loader;
import com.wisecoders.dbschema.dbf.io.H2Writer;
import com.wisecoders.dbschema.dbf.schema.Table;
import com.linuxense.javadbf.DBFReader;
import org.h2.jdbc.JdbcConnection;
Expand All @@ -20,7 +20,7 @@
import java.util.regex.Pattern;

import static com.wisecoders.dbschema.dbf.JdbcDriver.LOGGER;
import static com.wisecoders.dbschema.dbf.io.DBFtoH2.FILES_META_TABLE;
import static com.wisecoders.dbschema.dbf.io.H2Loader.FILES_META_TABLE;


/**
Expand All @@ -34,46 +34,19 @@
* Code modifications allowed only to GitHub repository https://github.com/wise-coders/dbf-jdbc-driver
*/

public class H2WrappedConnection implements Connection {
public class H2Connection implements Connection {

private static final Pattern SAVE_COMMAND_PATTERN = Pattern.compile( "(\\s*)save(\\s+)dbf(\\s+)to(\\s+)(.*)", Pattern.CASE_INSENSITIVE );
private static final Pattern RELOAD_PATTERN = Pattern.compile( "(\\s*)reload(\\s+)(.*)", Pattern.CASE_INSENSITIVE );

private final JdbcConnection h2Connection;
private String defaultCharset;

H2WrappedConnection(JdbcConnection h2Connection, String defaultCharset ){
H2Connection(JdbcConnection h2Connection, String defaultCharset ){
this.h2Connection = h2Connection;
this.defaultCharset = defaultCharset;
}

void transferFolder(File folder, File rootFolder, Connection h2Connection) throws SQLException {
final File[] files = folder.listFiles();
if ( files != null ) {
for (File file : files) {
if ( file.isFile() ){
if ( file.getName().toLowerCase().endsWith(".dbf") ) {
try ( DBFReader reader = new DBFReader( new FileInputStream(file))) {
final Table table = new Table(rootFolder, file);
if ( !DBFtoH2.isFileTransferred( file, h2Connection )){
DBFtoH2.transfer( table, reader, h2Connection );
DBFtoH2.saveFileTransferredInfo( file, h2Connection );
}
if (defaultCharset == null && reader.getCharset() != null ) {
defaultCharset = reader.getCharset().name();
}
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Error transferring " + file, ex);
throw new SQLException(ex.getLocalizedMessage(), ex);
}
}
} else if ( file.isDirectory() ){
transferFolder( file, rootFolder, h2Connection );
}
}
}
}

@Override
public Statement createStatement() throws SQLException {
Statement statement = h2Connection.createStatement();
Expand Down Expand Up @@ -127,12 +100,49 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
} else if ( ( matcher = RELOAD_PATTERN.matcher(args[0].toString())).matches()) {
LOGGER.info("Reload " + matcher.group(3) );
reload( matcher.group(3));
args = new String[]{""};
}
}
return method.invoke(target, args);
}
}

void transferFolder(File dbfFolder, File dbfSubFolder, Connection h2Connection) throws SQLException {
final File[] files = dbfSubFolder.listFiles();
if ( files != null ) {
for (File dbfFile : files) {
if ( dbfFile.isFile() ){
if ( dbfFile.getName().toLowerCase().endsWith(".dbf") ) {
try ( DBFReader reader = new DBFReader( new FileInputStream(dbfFile))) {
final Table table = new Table( extractTableNameFrom( dbfFolder, dbfFile));
if ( !H2Loader.isFileTransferred( dbfFile, h2Connection )){
H2Loader.transfer( table, reader, h2Connection );
H2Loader.saveFileIntoFilesMeta( table, dbfFile, h2Connection );
}
if (defaultCharset == null && reader.getCharset() != null ) {
defaultCharset = reader.getCharset().name();
}
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Error transferring " + dbfFile, ex);
throw new SQLException(ex.getLocalizedMessage(), ex);
}
}
} else if ( dbfFile.isDirectory() ){
transferFolder( dbfFolder, dbfFile, h2Connection );
}
}
}
}

private static String extractTableNameFrom(File dbfFolder, File dbfFile) {
String relativePath = dbfFolder.toURI().relativize(dbfFile.toURI()).getPath();
if ( relativePath.toLowerCase().endsWith(".dbf")){
relativePath = relativePath.substring(0, relativePath.length() - ".dbf".length());
}
return relativePath;
}


private void saveDbf( String path) throws Exception {
if ( path == null || path.trim().length() == 0 ){
throw new SQLException("Save dbf path is empty. Please specify a directory path");
Expand All @@ -143,11 +153,11 @@ private void saveDbf( String path) throws Exception {
}
File outputFolder = new File ( path );
outputFolder.mkdirs();
new H2toDBF(h2Connection, outputFolder, defaultCharset );
new H2Writer(h2Connection, outputFolder, defaultCharset );
}

private void reload( String filePath ) throws Exception {
try (PreparedStatement st = h2Connection.prepareStatement("DELETE FROM " + FILES_META_TABLE + " WHERE file_path=?")) {
try (PreparedStatement st = h2Connection.prepareStatement("DELETE FROM " + FILES_META_TABLE + " WHERE file_name=?")) {
st.setString(1, filePath);
st.executeUpdate();
}
Expand Down
22 changes: 11 additions & 11 deletions src/main/java/com/wisecoders/dbschema/dbf/JdbcDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
public class JdbcDriver implements Driver {

private static final String PREFIX = "jdbc:dbschema:dbf:";
private static final String INTERNAL_H2_LOCATION = "~/.DbSchema/jdbc-dbf-cache/";
private static final String H2_LOCATION = "~/.DbSchema/jdbc-dbf-cache/";

public static final Logger LOGGER = Logger.getLogger( JdbcDriver.class.getName() );

Expand Down Expand Up @@ -88,26 +88,26 @@ private Connection getConnection( String databasePath, String defaultCharset ) t
throw new SQLException("Expected path is not folder: '" + folder + "'");
}
final String h2DbName = md5Java( databasePath );
final String h2DatabasePath = getInternalH2DatabasePath( h2DbName );
final String h2JdbcUrl = "jdbc:h2:file:" + h2DatabasePath + ";database_to_upper=false";
final String h2DatabasePath = getH2DatabasePath( h2DbName );
final String h2JdbcUrl = "jdbc:h2:file:" + h2DatabasePath + ";database_to_lower=true";
LOGGER.log(Level.INFO, "Create H2 database '" + h2JdbcUrl + "'");

final JdbcConnection h2Connection = (JdbcConnection) (new org.h2.Driver().connect( h2JdbcUrl, new Properties() ));
final H2WrappedConnection wrappedConnection = new H2WrappedConnection( h2Connection, defaultCharset);
final JdbcConnection h2NativeConnection = (JdbcConnection) (new org.h2.Driver().connect( h2JdbcUrl, new Properties() ));
final H2Connection h2Connection = new H2Connection( h2NativeConnection, defaultCharset);
if ( !h2Databases.contains( h2DbName )){
wrappedConnection.transferFolder(folder, folder, h2Connection);
h2Connection.transferFolder(folder, folder, h2NativeConnection);
h2Databases.add(h2DbName);
}
return wrappedConnection;
return h2Connection;
}


private String getInternalH2DatabasePath(String path ){
final File h2File = new File(INTERNAL_H2_LOCATION);
private String getH2DatabasePath(String h2DbName ){
final File h2File = new File(H2_LOCATION);
if ( !h2File.exists()) {
h2File.mkdirs();
}
return INTERNAL_H2_LOCATION + path;
return H2_LOCATION + h2DbName;
}

@Override
Expand All @@ -127,7 +127,7 @@ static class ExtendedDriverPropertyInfo extends DriverPropertyInfo {
}

@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
DriverPropertyInfo[] result = new DriverPropertyInfo[1];
result[0] = new ExtendedDriverPropertyInfo("log", "true", new String[]{"true", "false"}, "Activate driver INFO logging");
return result;
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/wisecoders/dbschema/dbf/io/DBFUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.wisecoders.dbschema.dbf.io;

import com.linuxense.javadbf.DBFField;

public class DBFUtil {

public static String getFieldDescription(DBFField field) {
return field.getName().toLowerCase() + " " +
field.getType().name() + "(" +
field.getLength() + "," +
field.getDecimalCount() + ")";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import java.io.File;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import static com.wisecoders.dbschema.dbf.JdbcDriver.LOGGER;
Expand All @@ -17,15 +19,15 @@
* Free to be used by everyone.
* Code modifications allowed only to GitHub repository https://github.com/wise-coders/dbf-jdbc-driver
*/
public class DBFtoH2 {
public class H2Loader {


private final static char QUOTE_CHAR = '"';
public static final String COLUMNS_META_TABLE = "dbs_meta_columns";
private static final String INSERT_INTO_COLUMNS_META_TABLE = "insert into " + COLUMNS_META_TABLE + "( table_name, column_name, column_type, length, decimal ) values ( ?,?,?,?,? )";

public static final String FILES_META_TABLE = "dbs_meta_files";
private static final String CREATE_META_FILES = "CREATE TABLE IF NOT EXISTS " + FILES_META_TABLE + " ( file_path varchar(250) NOT NULL PRIMARY KEY, size bigint NOT NULL, last_modified bigint NOT NULL ) ";
private static final String CREATE_META_FILES = "CREATE TABLE IF NOT EXISTS " + FILES_META_TABLE + " ( file_path varchar(250) NOT NULL PRIMARY KEY, table_name varchar(2000) NOT NULL, size bigint NOT NULL, last_modified bigint NOT NULL ) ";



Expand All @@ -48,14 +50,14 @@ public static boolean isFileTransferred(File file, Connection h2Connection ) thr
return false;
}

public static void saveFileTransferredInfo( File file, Connection h2Connection ) throws SQLException {
String filePath = file.getAbsolutePath();
long fileLastModified = file.lastModified();
long fileSize = file.length();
try ( PreparedStatement st = h2Connection.prepareStatement("MERGE INTO " + FILES_META_TABLE + " ( file_path, size, last_modified ) KEY(file_path) VALUES ( ?, ?, ? )") ) {
st.setString(1, filePath);
st.setLong(2, fileSize);
st.setLong(3, fileLastModified);
public static void saveFileIntoFilesMeta(Table table, File file, Connection h2Connection ) throws SQLException {
try ( PreparedStatement st = h2Connection.prepareStatement("MERGE INTO " + FILES_META_TABLE + " ( file_path, table_name, size, last_modified ) KEY(file_path) VALUES ( ?, ?, ?, ? )") ) {
String fileName = file.getName();

st.setString(1, file.getAbsolutePath());
st.setString(2, table.name );
st.setLong(3, file.length());
st.setLong(4, file.lastModified());
st.executeUpdate();
}
}
Expand All @@ -71,23 +73,24 @@ public static void transfer(Table table, DBFReader reader, Connection h2Connecti
final StringBuilder createSb = new StringBuilder("create table ").append(QUOTE_CHAR).append(table.name).append(QUOTE_CHAR).append("(\n");
final StringBuilder insertSb = new StringBuilder("insert into ").append(QUOTE_CHAR).append(table.name).append(QUOTE_CHAR).append("(");
final StringBuilder insertValuesSb = new StringBuilder("values(");
final StringBuilder dbfInfo = new StringBuilder();
dbfInfo.append("Table ").append( table.name ).append( "\n" );
final StringBuilder logSb = new StringBuilder();
logSb.append("Table ").append( table.name ).append( "\n" );
boolean appendComma = false;
int numberOfFields = reader.getFieldCount();
final List<DBFField> dbfFieldList = new ArrayList<>();
for (int i = 0; i < numberOfFields; i++) {

final DBFField field = reader.getField(i);
dbfInfo.append( "\t").append( getFieldDescription( field )).append(" \n");
logSb.append( "\t").append( DBFUtil.getFieldDescription( field )).append(" \n");
saveFieldInMetaTable(h2Connection, table, field);
table.addField(field);
dbfFieldList.add(field);
if (appendComma) {
createSb.append(",\n");
insertSb.append(",");
insertValuesSb.append(",");
}
createSb.append("\t").append(QUOTE_CHAR).append(field.getName()).append(QUOTE_CHAR).append(" ");
insertSb.append(QUOTE_CHAR).append(field.getName()).append(QUOTE_CHAR);
createSb.append("\t").append(QUOTE_CHAR).append(field.getName().toLowerCase()).append(QUOTE_CHAR).append(" ");
insertSb.append(QUOTE_CHAR).append(field.getName().toLowerCase()).append(QUOTE_CHAR);
insertValuesSb.append("?");
createSb.append( DataTypeUtil.getH2Type( field));
appendComma = true;
Expand All @@ -96,7 +99,7 @@ public static void transfer(Table table, DBFReader reader, Connection h2Connecti
insertSb.append(")");
insertValuesSb.append(")");

LOGGER.log(Level.INFO, "Transfer " + dbfInfo );
LOGGER.log(Level.INFO, "Transfer " + logSb );

String dropTableSQL = "drop table if exists " + QUOTE_CHAR + table.name + QUOTE_CHAR;
LOGGER.log(Level.INFO, dropTableSQL);
Expand Down Expand Up @@ -125,9 +128,9 @@ public static void transfer(Table table, DBFReader reader, Connection h2Connecti
while( ( record = reader.nextRecord()) != null ){

try {
for (int i = 0; i < record.length && i < table.fields.size(); i++) {
for (int i = 0; i < record.length && i < dbfFieldList.size(); i++) {
Object value = record[i];
DBFField field = table.fields.get(i);
DBFField field = dbfFieldList.get(i);
if (value == null) {
stInsert.setNull(i + 1, DataTypeUtil.getJavaType(field));
} else {
Expand Down Expand Up @@ -195,17 +198,12 @@ private static void deleteFromH2MetaTable(Connection h2Connection, Table table )
h2Connection.commit();
}

private static String getFieldDescription(DBFField field) {
return field.getName() + " " +
field.getType().name() + "(" +
field.getLength() + "," +
field.getDecimalCount() + ")";
}


private static void saveFieldInMetaTable( Connection h2Connection, Table table, DBFField field) throws SQLException {
final PreparedStatement st = h2Connection.prepareStatement( INSERT_INTO_COLUMNS_META_TABLE );
st.setString( 1, table.name);
st.setString( 2, field.getName() );
st.setString( 2, field.getName().toLowerCase() );
st.setString( 3, field.getType().name() );
st.setInt( 4, field.getLength() );
st.setInt( 5, field.getDecimalCount() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,20 @@
* Free to be used by everyone.
* Code modifications allowed only to GitHub repository https://github.com/wise-coders/dbf-jdbc-driver
*/
public class H2toDBF {
public class H2Writer {


public H2toDBF( final Connection h2Connection, final File outputFolder, final String charset ) throws Exception {
public H2Writer(final Connection h2Connection, final File outputFolder, final String charset ) throws Exception {

Db db = new Db();

final ResultSet rsColumns = h2Connection.getMetaData().getColumns( null, null, null, null );
while( rsColumns.next() ){
String schemaName = rsColumns.getString( 2 );
String tableName = rsColumns.getString( 3 );
if ( !"INFORMATION_SCHEMA".equalsIgnoreCase(rsColumns.getString(2)) && !DataTypeUtil.isH2SystemTable(tableName ) ) { //
if ( !"INFORMATION_SCHEMA".equalsIgnoreCase( schemaName) && !DataTypeUtil.isH2SystemTable(tableName ) ) { //
String columnName = rsColumns.getString(4);
db.getOrCreateTable( tableName).createField(columnName, rsColumns.getString(6), rsColumns.getInt(7), rsColumns.getInt(9));
db.getOrCreateTable(tableName).createDBFField(columnName, rsColumns.getString(6), rsColumns.getInt(7), rsColumns.getInt(9));
}
}

Expand Down Expand Up @@ -76,7 +77,7 @@ public H2toDBF( final Connection h2Connection, final File outputFolder, final St
rs.close();
writer.close();
LOGGER.info("Saved " + table.name + " " + recCount + " records." );
DBFtoH2.saveFileTransferredInfo( outputFile, h2Connection );
H2Loader.saveFileIntoFilesMeta( table, outputFile, h2Connection );
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.wisecoders.dbschema.dbf.schema;

import com.wisecoders.dbschema.dbf.io.DBFtoH2;
import com.wisecoders.dbschema.dbf.io.H2Loader;
import com.linuxense.javadbf.DBFField;

import java.sql.Types;
Expand Down Expand Up @@ -102,7 +102,7 @@ public static String getH2Type( DBFField field ) {


public static boolean isH2SystemTable( String tableName ){
return DBFtoH2.COLUMNS_META_TABLE.equalsIgnoreCase( tableName ) || DBFtoH2.FILES_META_TABLE.equalsIgnoreCase( tableName );
return H2Loader.COLUMNS_META_TABLE.equalsIgnoreCase( tableName ) || H2Loader.FILES_META_TABLE.equalsIgnoreCase( tableName );
}

}

0 comments on commit f96f0b3

Please sign in to comment.