Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public class GenericTableMetaDataProvider implements TableMetaDataProvider {
/** Collection of TableParameterMetaData objects. */
private List<TableParameterMetaData> tableParameterMetaData = new ArrayList<>();

/** the string used to quote SQL identifiers. */
private String identifierQuoteString = "";

/**
* Constructor used to initialize with provided database meta-data.
Expand Down Expand Up @@ -212,6 +214,15 @@ public void initializeWithMetaData(DatabaseMetaData databaseMetaData) throws SQL
logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers': " + ex.getMessage());
}
}

try {
this.identifierQuoteString = databaseMetaData.getIdentifierQuoteString();
}
catch (SQLException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Error retrieving 'DatabaseMetaData.getIdentifierQuoteString': " + ex.getMessage());
}
}
}

@Override
Expand Down Expand Up @@ -304,6 +315,14 @@ protected String getDatabaseVersion() {
return this.databaseVersion;
}

/**
* Provide access to identifier quote string.
*/
@Override
public String getIdentifierQuoteString() {
return this.identifierQuoteString;
}

/**
* Method supporting the meta-data processing for a table.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public class TableMetaDataContext {
// Are we using generated key columns
private boolean generatedKeyColumnsUsed = false;

// Are we using escaping for SQL identifiers
private boolean usingEscaping = false;


/**
* Set the name of the table for this context.
Expand Down Expand Up @@ -275,13 +278,24 @@ public String createInsertString(String... generatedKeyNames) {
for (String key : generatedKeyNames) {
keys.add(key.toUpperCase());
}
String identifierQuoteString = "";
if (this.metaDataProvider != null && this.usingEscaping) {
identifierQuoteString = this.metaDataProvider.getIdentifierQuoteString();
}
StringBuilder insertStatement = new StringBuilder();
insertStatement.append("INSERT INTO ");
if (getSchemaName() != null) {
insertStatement.append(identifierQuoteString);
insertStatement.append(getSchemaName());
insertStatement.append(".");
insertStatement.append(getTableName());
insertStatement.append(identifierQuoteString);
}
else {
insertStatement.append(identifierQuoteString);
insertStatement.append(getTableName());
insertStatement.append(identifierQuoteString);
}
insertStatement.append(getTableName());
insertStatement.append(" (");
int columnCount = 0;
for (String columnName : getTableColumns()) {
Expand All @@ -290,7 +304,9 @@ public String createInsertString(String... generatedKeyNames) {
if (columnCount > 1) {
insertStatement.append(", ");
}
insertStatement.append(identifierQuoteString);
insertStatement.append(columnName);
insertStatement.append(identifierQuoteString);
}
}
insertStatement.append(") VALUES(");
Expand Down Expand Up @@ -390,4 +406,11 @@ public boolean isGeneratedKeysColumnNameArraySupported() {
return obtainMetaDataProvider().isGeneratedKeysColumnNameArraySupported();
}

public boolean isUsingEscaping() {
return this.usingEscaping;
}

public void setUsingEscaping(boolean usingEscaping) {
this.usingEscaping = usingEscaping;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,11 @@ void initializeWithTableColumnMetaData(DatabaseMetaData databaseMetaData, @Nulla
*/
List<TableParameterMetaData> getTableParameterMetaData();

/**
* Retrieves the string used to quote SQL identifiers. This method returns a space " " if identifier quoting is not supported.
* {@link DatabaseMetaData#getIdentifierQuoteString()}
* @return database identifier quote string.
*/
String getIdentifierQuoteString();

}
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,20 @@ public int[] getInsertTypes() {
return this.insertTypes;
}

/**
* Set using using escaping.
*/
public void setUsingEscaping(boolean usingEscaping) {
this.tableMetaDataContext.setUsingEscaping(usingEscaping);
}

/**
* Get using escaping.
*/
public boolean isUsingEscaping() {
return this.tableMetaDataContext.isUsingEscaping();
}


//-------------------------------------------------------------------------
// Methods handling compilation issues
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ public SimpleJdbcInsertOperations includeSynonymsForTableColumnMetaData() {
return this;
}

@Override
public SimpleJdbcInsert usingEscaping(boolean usingEscaping) {
setUsingEscaping(usingEscaping);
return this;
}

@Override
public int execute(Map<String, ?> args) {
return doExecute(args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ public interface SimpleJdbcInsertOperations {
*/
SimpleJdbcInsertOperations includeSynonymsForTableColumnMetaData();

/**
* Specify should sql identifiers be quoted.
* @param usingEscaping should sql identifiers be quoted
* @return the instance of this SimpleJdbcInsert
*/
SimpleJdbcInsertOperations usingEscaping(boolean usingEscaping);


/**
* Execute the insert using the values passed in.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import org.springframework.dao.InvalidDataAccessApiUsageException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -81,4 +82,36 @@ public void testNoSuchTable() throws Exception {
verify(resultSet).close();
}

@Test
public void testSimpleJdbcInsert() {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("T").usingColumns("F", "S");
jdbcInsert.compile();
String expected = "INSERT INTO T (F, S) VALUES(?, ?)";
String actual = jdbcInsert.getInsertString();
assertThat(actual).isEqualTo(expected);
}

@Test
public void testSimpleJdbcInsertWithEscapingWithSchemaName() throws Exception {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(dataSource).withSchemaName("S").withTableName("T").usingColumns("F", "S").usingEscaping(true);

given(databaseMetaData.getIdentifierQuoteString()).willReturn("`");

jdbcInsert.compile();
String expected = "INSERT INTO `S.T` (`F`, `S`) VALUES(?, ?)";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
String expected = "INSERT INTO `S.T` (`F`, `S`) VALUES(?, ?)";
String expected = "INSERT INTO `S`.`T` (`F`, `S`) VALUES(?, ?)";

Just a side note: the schema and table names have to be quoted independently.

I've fixed this in my local branch and added integration tests with H2 to verify it.

String actual = jdbcInsert.getInsertString();
assertThat(actual).isEqualTo(expected);
}
@Test
public void testSimpleJdbcInsertWithEscapingWithoutSchemaName() throws Exception {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(dataSource).withTableName("T").usingColumns("F", "S").usingEscaping(true);

given(databaseMetaData.getIdentifierQuoteString()).willReturn("`");

jdbcInsert.compile();
String expected = "INSERT INTO `T` (`F`, `S`) VALUES(?, ?)";
String actual = jdbcInsert.getInsertString();
assertThat(actual).isEqualTo(expected);
}

}