org.firebirdsql.util.FirebirdSupportInfo Maven / Gradle / Ivy
Show all versions of jaybird-jdk18 Show documentation
/*
* Firebird Open Source JavaEE Connector - JDBC Driver
*
* Distributable under LGPL license.
* You may obtain a copy of the License at http://www.gnu.org/copyleft/lgpl.html
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* LGPL License for more details.
*
* This file was created by members of the firebird development team.
* All individual contributions remain the Copyright (C) of those
* individuals. Contributors to this file are either listed here or
* can be obtained from a source control history command.
*
* All rights reserved.
*/
package org.firebirdsql.util;
import org.firebirdsql.gds.impl.GDSServerVersion;
import org.firebirdsql.gds.ng.FbAttachment;
import org.firebirdsql.jdbc.FirebirdConnection;
import org.firebirdsql.management.PageSizeConstants;
import java.sql.SQLException;
/**
* Helper class that reports if a Firebird version supports a specific feature.
*
* Intended as a repository for Jaybird to check for functionality support, or tests to check their assumptions, or
* decide on test or application behavior based on functionality support.
*
*
* Primary reason for existence of this class is to support version dependent functionality in Jaybird or
* version dependent tests in the Jaybird test suite, so feature checks are only added when they are necessary for
* Jaybird or the test suite. That said: if you miss feature checks, don't hesitate to create an issue in
* the Jaybird tracker.
*
*
* @author Mark Rotteveel
* @since 3.0
*/
public final class FirebirdSupportInfo {
private final GDSServerVersion serverVersion;
private FirebirdSupportInfo(GDSServerVersion serverVersion) {
if (serverVersion == null) {
throw new NullPointerException("serverVersion");
}
if (serverVersion.equals(GDSServerVersion.INVALID_VERSION)) {
throw new IllegalArgumentException("serverVersion is an invalid version (GDSServerVersion.INVALID_VERSION)");
}
this.serverVersion = serverVersion;
}
/**
* Check if the major.minor of this version is equal to or larger than the specified version.
*
* @param majorVersion
* Major version
* @param minorVersion
* Minor version
* @return {@code true} when current major is larger than required, or major is same and minor is equal to or
* larger than required
*/
public boolean isVersionEqualOrAbove(int majorVersion, int minorVersion) {
return serverVersion.isEqualOrAbove(majorVersion, minorVersion);
}
/**
* Check if the major.minor of this version is below the specified version.
*
* Equivalent to {@code !isVersionEqualOrAbove(majorVersion, minorVersion)}.
*
*
* @param majorVersion
* Major version
* @param minorVersion
* Minor version
* @return {@code true} when current major is smaller than the specified major, or major is same and minor is
* smaller than the specified minor
*/
public boolean isVersionBelow(int majorVersion, int minorVersion) {
return !isVersionEqualOrAbove(majorVersion, minorVersion);
}
/**
* Checks if BIGINT is supported.
*
* Low level this feature was added in Interbase 6.0 / Firebird 1.0, but it was never surfaced in DDL
*
*
* @return true
when the data type BIGINT is supported
*/
public boolean supportsBigint() {
return isVersionEqualOrAbove(1, 5);
}
/**
* @return true
when the data type BOOLEAN is supported
*/
public boolean supportsBoolean() {
return isVersionEqualOrAbove(3, 0);
}
/**
* @return true
when the COMMENT statement is supported
*/
public boolean supportsComment() {
return isVersionEqualOrAbove(2, 0);
}
/**
* @return true
when RDB$GET_CONTEXT and RDB$SET_CONTEXT are supported
*/
public boolean supportsGetSetContext() {
return isVersionEqualOrAbove(2, 0);
}
/**
* @return true
when CASE (simple or searched) is supported
*/
public boolean supportsCase() {
return isVersionEqualOrAbove(1, 5);
}
/**
* @return true
when the blob character set is reported in the scale of the field descriptor
*/
public boolean reportsBlobCharSetInDescriptor() {
return isVersionEqualOrAbove(2, 1);
}
/**
* TODO: Check if this is for all types or only for metadata.
*
* @return true
when the length of the field descriptor reports the byte length (max byte per char *
* char length)
*/
public boolean reportsByteLengthInDescriptor() {
return isVersionEqualOrAbove(1, 5);
}
/**
* TODO: Add methods for other RETURNING types?
*
* @return true
when INSERT ... RETURNING ... is supported
*/
public boolean supportsInsertReturning() {
return isVersionEqualOrAbove(2, 0);
}
/**
* @return true
when UPDATE ... RETURNING ... is supported
*/
public boolean supportsUpdateReturning() {
return isVersionEqualOrAbove(2, 1);
}
/**
* @return true
when the server knows the UTF8 character set (NOTE: For firebird 1.5 it is an alias for
* UNICODE_FSS)
*/
public boolean supportsUtf8() {
return isVersionEqualOrAbove(1, 5);
}
/**
* @return true
when SAVEPOINT is supported
*/
public boolean supportsSavepoint() {
return isVersionEqualOrAbove(1, 5);
}
/**
* @return true
when EXECUTE BLOCK is supported
*/
public boolean supportsExecuteBlock() {
return isVersionEqualOrAbove(2, 0);
}
/**
* @return true
when CREATE/ALTER/DROP USER is supported
*/
public boolean supportsSqlUserManagement() {
return isVersionEqualOrAbove(2, 5);
}
/**
* @return true
when fb_cancel_operation is supported
*/
public boolean supportsCancelOperation() {
return isVersionEqualOrAbove(2, 5);
}
/**
* @return {@code true} when field descriptors contain table alias information
*/
public boolean supportsTableAlias() {
return isVersionEqualOrAbove(2, 0);
}
/**
* @return {@code true} when the {@code NULL} data type and {@code ? IS NULL} is supported
*/
public boolean supportsNullDataType() {
return isVersionEqualOrAbove(2, 5);
}
/**
* @return {@code true} when {@code isc_spb_sec_userid} and {@code isc_spb_sec_groupid} are supported.
*/
public boolean supportsUserAndGroupIdInUser() {
return serverVersion.getMajorVersion() < 3;
}
/**
* Checks support for protocol versions. The check is limited to those protocol versions supported by Jaybird
* (10-13 at this time).
*
* @param protocolVersion
* Protocol version number
* @return {@code true} when the database supports the specified protocol
*/
public boolean supportsProtocol(int protocolVersion) {
switch (protocolVersion) {
case 10:
return true;
case 11:
return isVersionEqualOrAbove(2, 1);
case 12:
return isVersionEqualOrAbove(2, 5);
case 13:
return isVersionEqualOrAbove(3, 0);
default:
return false;
}
}
/**
* @return {@code true} when custom exception messages are supported.
*/
public boolean supportsCustomExceptionMessages() {
return isVersionEqualOrAbove(1, 5);
}
/**
* @return {@code true} when parametrized exceptions are supported.
*/
public boolean supportsParametrizedExceptions() {
return isVersionEqualOrAbove(3, 0);
}
/**
* @return {@code true} when monitoring tables are supported.
*/
public boolean supportsMonitoringTables() {
return isVersionEqualOrAbove(2, 1);
}
/**
* @return {@code true} when global temporary tables (GTTs) are supported.
*/
public boolean supportsGlobalTemporaryTables() {
return isVersionEqualOrAbove(2, 5);
}
/**
* @return {@code true} when blobs are fully searchable (eg using `LIKE`).
*/
public boolean supportsFullSearchableBlobs() {
return isVersionEqualOrAbove(2, 1);
}
/**
* @return {@code true} when identity columns are supported.
*/
public boolean supportsIdentityColumns() {
return isVersionEqualOrAbove(3, 0);
}
/**
* @return The maximum number of characters in an identifier.
*/
public int maxIdentifierLengthCharacters() {
if (isVersionEqualOrAbove(4, 0)) {
// Technically this is configurable
return 63;
} else {
return 31;
}
}
/**
* @return The maximum number of bytes in an identifier.
* @see #maxReportedIdentifierLengthBytes()
*/
public int maxIdentifierLengthBytes() {
if (isVersionEqualOrAbove(4, 0)) {
// Technically this is configurable
return 4 * 63;
} else {
// Firebird 3 and below
return 31;
}
}
/**
* @return The maximum number of bytes reported in parameter metadata for an identifier
* @see #maxIdentifierLengthBytes()
*/
public int maxReportedIdentifierLengthBytes() {
if (isVersionEqualOrAbove(4, 0)) {
// Technically this is configurable
return 4 * 63;
} else if (reportsByteLengthInDescriptor()) {
// Firebird 1.5 ... 3 use unicode_fss and report 3 * identifier length, but actually store max 31 bytes(!)
return 3 * 31;
} else {
return 31;
}
}
/**
* @return The character set id of system metadata
*/
public int reportedMetadataCharacterSetId() {
if (isVersionEqualOrAbove(4, 0)) {
return 4; // UTF8
} else {
return 3; // UNICODE_FSS
}
}
public boolean supportsPageSize(int pageSize) {
switch (pageSize) {
case PageSizeConstants.SIZE_1K:
return !isVersionEqualOrAbove(2, 1);
case PageSizeConstants.SIZE_2K:
return !isVersionEqualOrAbove(2, 1);
case PageSizeConstants.SIZE_4K:
return true;
case PageSizeConstants.SIZE_8K:
return true;
case PageSizeConstants.SIZE_16K:
// TODO check
return isVersionEqualOrAbove(2, 0);
case PageSizeConstants.SIZE_32K:
return isVersionEqualOrAbove(4, 0);
}
return false;
}
public boolean supportsWireEncryption() {
return isVersionEqualOrAbove(3, 0);
}
/**
* @return {@code true} when UDFs (User Defined Functions) - backed by a native library - are supported
*/
public boolean supportsNativeUserDefinedFunctions() {
return isVersionBelow(4, 0);
}
/**
* @return {@code true} when this Firebird version supports case sensitive user names.
*/
public boolean supportsCaseSensitiveUserNames() {
return isVersionEqualOrAbove(3, 0);
}
/**
* @param serverVersion
* Server version
* @return FirebirdVersionSupport instance
*/
public static FirebirdSupportInfo supportInfoFor(GDSServerVersion serverVersion) {
return new FirebirdSupportInfo(serverVersion);
}
/**
* @param attachment
* Low level attachment object
* @return FirebirdVersionSupport instance
*/
public static FirebirdSupportInfo supportInfoFor(FbAttachment attachment) {
return supportInfoFor(attachment.getServerVersion());
}
/**
* @param connection
* A database connection (NOTE: {@link java.sql.Connection} is used, but it must be or unwrap to a
* {@link org.firebirdsql.jdbc.FirebirdConnection}.
* @return FirebirdVersionSupport instance
* @throws java.lang.IllegalArgumentException
* When the provided connection is not an instance of or wrapper for
* {@link org.firebirdsql.jdbc.FirebirdConnection}
* @throws java.lang.IllegalStateException
* When an SQLException occurs unwrapping the connection, or creating
* the {@link org.firebirdsql.util.FirebirdSupportInfo} instance
*/
public static FirebirdSupportInfo supportInfoFor(java.sql.Connection connection) {
try {
if (connection.isWrapperFor(FirebirdConnection.class)) {
return supportInfoFor(connection.unwrap(FirebirdConnection.class).getFbDatabase());
} else {
throw new IllegalArgumentException(
"connection needs to be (or unwrap to) an org.firebirdsql.jdbc.FBConnection");
}
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
}