diff --git a/db/apichanges.xml b/db/apichanges.xml --- a/db/apichanges.xml +++ b/db/apichanges.xml @@ -105,6 +105,19 @@ + + + Add support for always quoting and for unquoting SQL identifiers. + + + + + + Add support for always quoting and for unquoting SQL identifiers. + + + + Add ability to get the underlying JDBC Driver instance for a JDBCDriver diff --git a/db/nbproject/project.properties b/db/nbproject/project.properties --- a/db/nbproject/project.properties +++ b/db/nbproject/project.properties @@ -42,7 +42,7 @@ javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml -spec.version.base=1.28.0 +spec.version.base=1.29.0 extra.module.files=modules/ext/ddl.jar diff --git a/db/src/org/netbeans/api/db/sql/support/SQLIdentifiers.java b/db/src/org/netbeans/api/db/sql/support/SQLIdentifiers.java --- a/db/src/org/netbeans/api/db/sql/support/SQLIdentifiers.java +++ b/db/src/org/netbeans/api/db/sql/support/SQLIdentifiers.java @@ -95,6 +95,56 @@ */ public abstract String quoteIfNeeded(String identifier); + /** + * Quotes an SQL identifier, even if the {@link #quoteIfNeeded} method + * would not have quoted it. + * + * @param identifier a SQL identifier. Can not be null. + * + * @return the quoted identifier. + * + * @since 1.29 + */ + public abstract String quoteAlways(String identifier); + + /** + * Unquotes an identifier if it is quoted. + * + * @param identifier a SQL identifier. Can not be null. + * + * @return the unquoted identifier. + * + * @since 1.29 + */ + public String unquote(String identifier) { + Parameters.notNull("identifier", identifier); + + int start = 0; + while (identifier.regionMatches(start, quoteString, 0, quoteString.length())) { + start += quoteString.length(); + } + int end = identifier.length(); + if (end > start) { + for (;;) { + int offset = end - quoteString.length(); + if (identifier.regionMatches(offset, quoteString, 0, quoteString.length())) { + end = offset; + } else { + break; + } + } + } + String result = ""; + if (start < end) { + result = identifier.substring(start, end); + } + return result; + } + + public String getQuoteString() { + return quoteString; + } + boolean alreadyQuoted(String identifier) { return (identifier.startsWith(quoteString) && identifier.endsWith(quoteString)); } @@ -128,6 +178,16 @@ Parameters.notNull("identifier", identifier); if ( needToQuote(identifier) ) { + return doQuote(identifier); + } + + return identifier; + } + + public final String quoteAlways(String identifier) { + Parameters.notNull("identifier", identifier); + + if ( !alreadyQuoted(identifier) ) { return doQuote(identifier); } diff --git a/db/test/unit/src/org/netbeans/api/db/sql/support/NonASCIIQuoter.java b/db/test/unit/src/org/netbeans/api/db/sql/support/NonASCIIQuoter.java --- a/db/test/unit/src/org/netbeans/api/db/sql/support/NonASCIIQuoter.java +++ b/db/test/unit/src/org/netbeans/api/db/sql/support/NonASCIIQuoter.java @@ -62,4 +62,13 @@ return identifier; } } + + @Override + public String quoteAlways(String identifier) { + if (!alreadyQuoted(identifier)) { + return quoteString + identifier + quoteString; + } else { + return identifier; + } + } } diff --git a/db/test/unit/src/org/netbeans/api/db/sql/support/NonASCIIQuoterTest.java b/db/test/unit/src/org/netbeans/api/db/sql/support/NonASCIIQuoterTest.java --- a/db/test/unit/src/org/netbeans/api/db/sql/support/NonASCIIQuoterTest.java +++ b/db/test/unit/src/org/netbeans/api/db/sql/support/NonASCIIQuoterTest.java @@ -40,7 +40,7 @@ super(name); } - public void testBasic() { + public void testQuoteIfNeeded() { Quoter quoter = new NonASCIIQuoter("\""); assertEquals("foo", quoter.quoteIfNeeded("foo")); @@ -51,4 +51,11 @@ assertEquals("\"foo bar\"", quoter.quoteIfNeeded("\"foo bar\"")); } + + public void testQuoteAlways() { + Quoter quoter = new NonASCIIQuoter("\""); + + assertEquals("\"foo\"", quoter.quoteAlways("foo")); + assertEquals("\"foo bar\"", quoter.quoteAlways("\"foo bar\"")); + } } diff --git a/db/test/unit/src/org/netbeans/api/db/sql/support/QuoterTest.java b/db/test/unit/src/org/netbeans/api/db/sql/support/QuoterTest.java --- a/db/test/unit/src/org/netbeans/api/db/sql/support/QuoterTest.java +++ b/db/test/unit/src/org/netbeans/api/db/sql/support/QuoterTest.java @@ -123,6 +123,18 @@ } catch ( NullPointerException npe ) { // expected } + try { + quoter.quoteAlways(null); + fail("Expected a NullPointerException"); + } catch ( NullPointerException npe ) { + // expected + } + try { + quoter.unquote(null); + fail("Expected a NullPointerException"); + } catch ( NullPointerException npe ) { + // expected + } } public void testFirstCharIsUnderbar() throws Exception { @@ -144,4 +156,13 @@ assertEquals(expResult, result); } + + public void testUnquote() { + assertEquals("", quoter.unquote("")); + assertEquals("", quoter.unquote("\"\"")); + assertEquals("id", quoter.unquote("id")); + assertEquals("id", quoter.unquote("\"id")); + assertEquals("id", quoter.unquote("id\"")); + assertEquals("id", quoter.unquote("\"id")); + } }