private void testUnsupportedOperations() throws Exception { Connection conn = getConnection(); stat = conn.createStatement(); stat.execute("create table test(id int, c clob, b blob)"); stat.execute("insert into test values(1, 'x', x'00')"); ResultSet rs = stat.executeQuery("select * from test order by id"); rs.next(); Clob clob = rs.getClob(2); byte[] data = IOUtils.readBytesAndClose(clob.getAsciiStream(), -1); assertEquals("x", new String(data, "UTF-8")); assertTrue(clob.toString().endsWith("'x'")); clob.free(); assertTrue(clob.toString().endsWith("null")); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, clob).truncate(0); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, clob).setAsciiStream(1); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, clob).setString(1, "", 0, 1); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, clob).position("", 0); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, clob).position((Clob) null, 0); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, clob).getCharacterStream(1, 1); Blob blob = rs.getBlob(3); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, blob).truncate(0); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, blob).setBytes(1, new byte[0], 0, 0); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, blob).position(new byte[1], 0); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, blob).position((Blob) null, 0); assertThrows(ErrorCode.FEATURE_NOT_SUPPORTED_1, blob).getBinaryStream(1, 1); assertTrue(blob.toString().endsWith("X'00'")); blob.free(); assertTrue(blob.toString().endsWith("null")); stat.execute("drop table test"); conn.close(); }
@Override public void releaseResources() { log.trace("Releasing JDBC resources"); for (Map.Entry<Statement, Set<ResultSet>> entry : xref.entrySet()) { if (entry.getValue() != null) { closeAll(entry.getValue()); } close(entry.getKey()); } xref.clear(); closeAll(unassociatedResultSets); if (blobs != null) { for (Blob blob : blobs) { try { blob.free(); } catch (SQLException e) { log.debugf("Unable to free JDBC Blob reference [%s]", e.getMessage()); } } blobs.clear(); } if (clobs != null) { for (Clob clob : clobs) { try { clob.free(); } catch (SQLException e) { log.debugf("Unable to free JDBC Clob reference [%s]", e.getMessage()); } } clobs.clear(); } if (nclobs != null) { for (NClob nclob : nclobs) { try { nclob.free(); } catch (SQLException e) { log.debugf("Unable to free JDBC NClob reference [%s]", e.getMessage()); } } nclobs.clear(); } }
public SerialBlob(final Blob other) throws SQLException { InputStream is = null; try { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); is = other.getBinaryStream(); final byte[] buff = new byte[1024]; int len; while ((len = is.read(buff)) > 0) { baos.write(buff, 0, len); } data = baos.toByteArray(); other.free(); } catch (final IOException e) { throw new SQLException("Can't retrieve contents of Blob", e.toString()); } finally { StreamCloser.close(is); } }
private byte[] getBytes(Blob blob) throws SQLException { if (blob == null) { LOGGER.log(Level.FINEST, "BLOB handler called with null BLOB"); return new byte[0]; } LOGGER.log(Level.FINEST, "BLOB handler called with BLOB of length {0}", blob.length()); byte[] bytes = blob.getBytes(1, (int) blob.length()); try { blob.free(); } catch (SQLException e) { LOGGER.log(Level.WARNING, "Error freeing the BLOB", e); } catch (UnsupportedOperationException e) { // Check for JDBC drivers that don't support this JDBC 4.0 method. // This is an unusual exception to throw, but worth catching since // it's a RuntimeException that will otherwise terminate the monitor. LOGGER.log(Level.WARNING, "Error freeing the BLOB, try a newer JDBC 4.0 driver", e); } catch (LinkageError e) { // Check for JDBC drivers that were not compiled against Java 6. LOGGER.log(Level.WARNING, "Error freeing the BLOB, try a newer JDBC 4.0 driver", e); } return bytes; }
/** * Gets the job configuration from the DDBB. * * @param jobId the job identification. * @return the {@link eu.aliada.ckancreation.model.JobConfiguration} which contains the * configuration of the job. * @since 2.0 */ public JobConfiguration getJobConfiguration(final Integer jobId) { JobConfiguration jobConf = null; int datasetId = -1; int organisationId = -1; try { final Statement sta = getConnection().createStatement(); String sql = "SELECT * FROM ckancreation_job_instances WHERE job_id=" + jobId; ResultSet resultSet = sta.executeQuery(sql); jobConf = new JobConfiguration(); while (resultSet.next()) { jobConf = new JobConfiguration(); jobConf.setId(jobId); jobConf.setCkanApiURL(resultSet.getString("ckan_api_url")); jobConf.setCkanApiKey(resultSet.getString("ckan_api_key")); jobConf.setTmpDir(resultSet.getString("tmp_dir")); jobConf.setStoreIp(resultSet.getString("store_ip")); jobConf.setStoreSqlPort(resultSet.getInt("store_sql_port")); jobConf.setSqlLogin(resultSet.getString("sql_login")); jobConf.setSqlPassword(resultSet.getString("sql_password")); jobConf.setIsqlCommandPath(resultSet.getString("isql_command_path")); jobConf.setIsqlCommandsGraphDumpFilename( resultSet.getString("isql_commands_file_graph_dump")); jobConf.setVirtHttpServRoot(resultSet.getString("virtuoso_http_server_root")); jobConf.setOntologyUri(resultSet.getString("aliada_ontology")); jobConf.setOrgName(resultSet.getString("org_name")); jobConf.setOrgTitle(resultSet.getString("org_name").toUpperCase()); jobConf.setOrgDescription(resultSet.getString("org_description")); jobConf.setOrgHomePage(resultSet.getString("org_home_page")); datasetId = resultSet.getInt("datasetId"); jobConf.setDatasetId(datasetId); organisationId = resultSet.getInt("organisationId"); } resultSet.close(); // Get dataset related information sql = "SELECT * FROM dataset WHERE datasetId=" + datasetId; resultSet = sta.executeQuery(sql); while (resultSet.next()) { jobConf.setDatasetAuthor(resultSet.getString("dataset_author")); jobConf.setDatasetAuthorEmail(resultSet.getString("dataset_author_email")); jobConf.setCkanDatasetName(resultSet.getString("ckan_dataset_name")); jobConf.setDatasetDesc(resultSet.getString("dataset_desc")); jobConf.setDatasetLongDesc(resultSet.getString("dataset_long_desc")); jobConf.setDatasetSourceURL(resultSet.getString("dataset_source_url")); jobConf.setSparqlEndpointUri(resultSet.getString("sparql_endpoint_uri")); jobConf.setSparqlLogin(resultSet.getString("sparql_endpoint_login")); jobConf.setSparqlPassword(resultSet.getString("sparql_endpoint_password")); jobConf.setPublicSparqlEndpointUri(resultSet.getString("public_sparql_endpoint_uri")); jobConf.setLicenseCKANId(resultSet.getString("license_ckan_id")); jobConf.setLicenseURL(resultSet.getString("license_url")); jobConf.setDomainName(resultSet.getString("domain_name")); jobConf.setVirtualHost(resultSet.getString("virtual_host")); jobConf.setUriIdPart(resultSet.getString("uri_id_part")); jobConf.setUriDocPart(resultSet.getString("uri_doc_part")); jobConf.setUriConceptPart(resultSet.getString("uri_concept_part")); jobConf.setUriSetPart(resultSet.getString("uri_set_part")); } resultSet.close(); // Get subsets related information sql = "SELECT * FROM subset WHERE datasetId=" + datasetId; resultSet = sta.executeQuery(sql); while (resultSet.next()) { final Subset subset = new Subset(); subset.setUriConceptPart(resultSet.getString("uri_concept_part")); subset.setDescription(resultSet.getString("subset_desc")); subset.setGraph(resultSet.getString("graph_uri")); subset.setLinksGraph(resultSet.getString("links_graph_uri")); subset.setDescription(resultSet.getString("subset_desc")); jobConf.setSubset(subset); } resultSet.close(); // Get organisation LOGO from BLOB object in organisation table sql = "SELECT org_logo FROM organisation WHERE organisationId=" + organisationId; resultSet = sta.executeQuery(sql); if (resultSet.next() && resultSet.getBlob("org_logo") != null) { final Blob logo = resultSet.getBlob("org_logo"); final int blobLength = (int) logo.length(); byte[] blobAsBytes = null; blobAsBytes = logo.getBytes(1, blobLength); // Compose initial logo file name final String orgImagePathInit = jobConf.getTmpDir() + File.separator + "orgLogo" + "_" + System.currentTimeMillis() + ".jpeg"; try { final FileOutputStream fos = new FileOutputStream(orgImagePathInit); fos.write(blobAsBytes); fos.close(); jobConf.setOrgImagePath(orgImagePathInit); } catch (IOException exception) { LOGGER.error(MessageCatalog._00034_FILE_CREATION_FAILURE, exception, orgImagePathInit); } // release the blob and free up memory. (since JDBC 4.0) logo.free(); } resultSet.close(); sta.close(); } catch (SQLException exception) { LOGGER.error(MessageCatalog._00024_DATA_ACCESS_FAILURE, exception); return null; } return jobConf; }
// 1 "BibTeX.id", // 2 "BibTeX.createdBy", // 3 "BibTeX.abstract", // 4 "BibTeX.address", // 5 "BibTeX.annotation", // 6 "BibTeX.author", // 7 "BibTeX.bibType", // 8 "BibTeX.bookTitle", // 9 "BibTeX.chapter", // 10 "BibTeX.copyright", // 11 "BibTeX.crossref", // 12 "BibTeX.edition", // 13 "BibTeX.editor", // 14 "BibTeX.isbn", // 15 "BibTeX.issn", // 16 "BibTeX.journal", // 17 "BibTeX.bibkey", // 18 "BibTeX.keywords", // 19 "BibTeX.number", // 20 "BibTeX.pages", // 21 "BibTeX.series", // 22 "BibTeX.title", // 23 "BibTeX.url", // 24 "BibTeX.volume", // 25 "BibTeX.year", // 26 "uncompress(meta)" @Override public BibTeX next() throws DbException { BibTeX nextBibTeX = new BibTeX(); try { String bibtexId = rs.getString("id"); String createdBy = rs.getString("createdBy"); String abstractBib = rs.getString("abstract"); String address = rs.getString("address"); String annotation = rs.getString("annotation"); String author = rs.getString("author"); String bibType = rs.getString("bibType"); String bookTitle = rs.getString("bookTitle"); String chapter = rs.getString("chapter"); String copyright = rs.getString("copyright"); String crossref = rs.getString("crossref"); String edition = rs.getString("edition"); String editor = rs.getString("editor"); String isbn = rs.getString("isbn"); String issn = rs.getString("issn"); String journal = rs.getString("journal"); String bibkey = rs.getString("bibkey"); String keywords = rs.getString("keywords"); String pages = rs.getString("pages"); String series = rs.getString("series"); String title = rs.getString("title"); String url = rs.getString("url"); String number = rs.getString("number"); String volume = rs.getString("volume"); String year = rs.getString("year"); Blob metaInfoBlob = rs.getBlob(26); if (metaInfoBlob != null) { MetaInfoDeblobber mid = new MetaInfoDeblobber(metaInfoBlob); MetaInfo mi = mid.toMetaInfo(); nextBibTeX.setMeta(mi); metaInfoBlob.free(); } nextBibTeX.setUri(new VRI(baseUri).augment(bibtexId)); nextBibTeX.setAbstract(abstractBib); nextBibTeX.setAddress(address); nextBibTeX.setAnnotation(annotation); nextBibTeX.setAuthor(author); BibTeX.BibTYPE bibTYPE = BibTeX.BibTYPE.Entry; if (bibType != null) { bibTYPE = BibTeX.BibTYPE.valueOf(bibType); } nextBibTeX.setBibType(bibTYPE); nextBibTeX.setBookTitle(bookTitle); nextBibTeX.setChapter(chapter); nextBibTeX.setCopyright(copyright); if (createdBy != null) { User user = usersCache.get(createdBy); // try to get the user from the cache. if (user == null) { // if user is not found in cache, create it and put it there! user = new User(); user.setUid(createdBy); if (resolveUser) { FindUser fu = new FindUser(); fu.setWhere("uid='" + createdBy + "'"); IDbIterator<User> users = fu.list(); if (users.hasNext()) { user = users.next(); } users.close(); fu.close(); } usersCache.put(createdBy, user); } nextBibTeX.setCreatedBy(user); } nextBibTeX.setCrossref(crossref); nextBibTeX.setEdition(edition); nextBibTeX.setEditor(editor); nextBibTeX.setIsbn(isbn); nextBibTeX.setIssn(issn); nextBibTeX.setJournal(journal); nextBibTeX.setKey(bibkey); nextBibTeX.setKeywords(keywords); if (number == null) { nextBibTeX.setNumber(null); } else { nextBibTeX.setNumber(Integer.parseInt(number)); } if (year == null) { nextBibTeX.setYear(null); } else { nextBibTeX.setYear(Integer.parseInt(year)); } if (volume == null) { nextBibTeX.setVolume(null); } else { nextBibTeX.setVolume(Integer.parseInt(volume)); } nextBibTeX.setPages(pages); nextBibTeX.setSeries(series); nextBibTeX.setTitle(title); nextBibTeX.setUrl(url); } catch (SQLException ex) { final String msg = "SQL-related exception thrown while reading bibtex data from the database"; logger.warn(msg, ex); throw new DbException(msg, ex); } return nextBibTeX; }
/** * @param rs * @param interpretLiteralBytes * @param payloadLength * @return * @throws HttpMalformedHeaderException * @throws SQLException * @throws DatabaseException */ private List<WebSocketMessageDTO> buildMessageDTOs( ResultSet rs, boolean interpretLiteralBytes, int payloadLength) throws SQLException, DatabaseException { ArrayList<WebSocketMessageDTO> messages = new ArrayList<>(); try { while (rs.next()) { WebSocketMessageDTO message; int channelId = rs.getInt("channel_id"); WebSocketChannelDTO channel = getChannel(channelId); if (rs.getInt("fuzz_id") != 0) { WebSocketFuzzMessageDTO fuzzMessage = new WebSocketFuzzMessageDTO(channel); fuzzMessage.fuzzId = rs.getInt("fuzz_id"); fuzzMessage.state = WebSocketFuzzMessageDTO.State.valueOf(rs.getString("state")); fuzzMessage.fuzz = rs.getString("fuzz"); message = fuzzMessage; } else { message = new WebSocketMessageDTO(channel); } message.id = rs.getInt("message_id"); message.setTime(rs.getTimestamp("timestamp")); message.opcode = rs.getInt("opcode"); message.readableOpcode = WebSocketMessage.opcode2string(message.opcode); // read payload if (message.opcode == WebSocketMessage.OPCODE_BINARY) { if (payloadLength == -1) { // load all bytes message.payload = rs.getBytes("payload_bytes"); } else { Blob blob = rs.getBlob("payload_bytes"); int length = Math.min(payloadLength, (int) blob.length()); message.payload = blob.getBytes(1, length); blob.free(); } if (message.payload == null) { message.payload = new byte[0]; } } else { if (payloadLength == -1) { // load all characters message.payload = rs.getString("payload_utf8"); } else { Clob clob = rs.getClob("payload_utf8"); int length = Math.min(payloadLength, (int) clob.length()); message.payload = clob.getSubString(1, length); clob.free(); } if (message.payload == null) { message.payload = ""; } } message.isOutgoing = rs.getBoolean("is_outgoing"); message.payloadLength = rs.getInt("payload_length"); messages.add(message); } } finally { rs.close(); } messages.trimToSize(); return messages; }
public static Object parseType(ResultSet result, Integer i, int type) throws SQLException, IOException, ParseException { logger.trace("i={} type={}", i, type); switch (type) { /** * The JDBC types CHAR, VARCHAR, and LONGVARCHAR are closely related. CHAR represents a * small, fixed-length character string, VARCHAR represents a small, variable-length * character string, and LONGVARCHAR represents a large, variable-length character string. */ case Types.CHAR: case Types.VARCHAR: case Types.LONGVARCHAR: { return result.getString(i); } case Types.NCHAR: case Types.NVARCHAR: case Types.LONGNVARCHAR: { return result.getNString(i); } /** * The JDBC types BINARY, VARBINARY, and LONGVARBINARY are closely related. BINARY * represents a small, fixed-length binary value, VARBINARY represents a small, * variable-length binary value, and LONGVARBINARY represents a large, variable-length * binary value */ case Types.BINARY: case Types.VARBINARY: case Types.LONGVARBINARY: { byte[] b = result.getBytes(i); return b; } /** * The JDBC type ARRAY represents the SQL3 type ARRAY. * * <p>An ARRAY value is mapped to an instance of the Array interface in the Java programming * language. If a driver follows the standard implementation, an Array object logically * points to an ARRAY value on the server rather than containing the elements of the ARRAY * object, which can greatly increase efficiency. The Array interface contains methods for * materializing the elements of the ARRAY object on the client in the form of either an * array or a ResultSet object. */ case Types.ARRAY: { Array arr = result.getArray(i); return arr == null ? null : arr.getArray(); } /** * The JDBC type BIGINT represents a 64-bit signed integer value between * -9223372036854775808 and 9223372036854775807. * * <p>The corresponding SQL type BIGINT is a nonstandard extension to SQL. In practice the * SQL BIGINT type is not yet currently implemented by any of the major databases, and we * recommend that its use be avoided in code that is intended to be portable. * * <p>The recommended Java mapping for the BIGINT type is as a Java long. */ case Types.BIGINT: { Object o = result.getLong(i); return result.wasNull() ? null : o; } /** * The JDBC type BIT represents a single bit value that can be zero or one. * * <p>SQL-92 defines an SQL BIT type. However, unlike the JDBC BIT type, this SQL-92 BIT * type can be used as a parameterized type to define a fixed-length binary string. * Fortunately, SQL-92 also permits the use of the simple non-parameterized BIT type to * represent a single binary digit, and this usage corresponds to the JDBC BIT type. * Unfortunately, the SQL-92 BIT type is only required in "full" SQL-92 and is currently * supported by only a subset of the major databases. Portable code may therefore prefer to * use the JDBC SMALLINT type, which is widely supported. */ case Types.BIT: { try { Object o = result.getInt(i); return result.wasNull() ? null : o; } catch (Exception e) { String exceptionClassName = e.getClass().getName(); // postgresql can not handle boolean, it will throw PSQLException, something like "Bad // value for type int : t" if ("org.postgresql.util.PSQLException".equals(exceptionClassName)) { return "t".equals(result.getString(i)); } throw new IOException(e); } } /** * The JDBC type BOOLEAN, which is new in the JDBC 3.0 API, maps to a boolean in the Java * programming language. It provides a representation of true and false, and therefore is a * better match than the JDBC type BIT, which is either 1 or 0. */ case Types.BOOLEAN: { return result.getBoolean(i); } /** * The JDBC type BLOB represents an SQL3 BLOB (Binary Large Object). * * <p>A JDBC BLOB value is mapped to an instance of the Blob interface in the Java * programming language. If a driver follows the standard implementation, a Blob object * logically points to the BLOB value on the server rather than containing its binary data, * greatly improving efficiency. The Blob interface provides methods for materializing the * BLOB data on the client when that is desired. */ case Types.BLOB: { Blob blob = result.getBlob(i); if (blob != null) { long n = blob.length(); if (n > Integer.MAX_VALUE) { throw new IOException("can't process blob larger than Integer.MAX_VALUE"); } byte[] tab = blob.getBytes(1, (int) n); blob.free(); return tab; } break; } /** * The JDBC type CLOB represents the SQL3 type CLOB (Character Large Object). * * <p>A JDBC CLOB value is mapped to an instance of the Clob interface in the Java * programming language. If a driver follows the standard implementation, a Clob object * logically points to the CLOB value on the server rather than containing its character * data, greatly improving efficiency. Two of the methods on the Clob interface materialize * the data of a CLOB object on the client. */ case Types.CLOB: { Clob clob = result.getClob(i); if (clob != null) { long n = clob.length(); if (n > Integer.MAX_VALUE) { throw new IOException("can't process clob larger than Integer.MAX_VALUE"); } String str = clob.getSubString(1, (int) n); clob.free(); return str; } break; } case Types.NCLOB: { NClob nclob = result.getNClob(i); if (nclob != null) { long n = nclob.length(); if (n > Integer.MAX_VALUE) { throw new IOException("can't process nclob larger than Integer.MAX_VALUE"); } String str = nclob.getSubString(1, (int) n); nclob.free(); return str; } break; } /** * The JDBC type DATALINK, new in the JDBC 3.0 API, is a column value that references a file * that is outside of a data source but is managed by the data source. It maps to the Java * type java.net.URL and provides a way to manage external files. For instance, if the data * source is a DBMS, the concurrency controls it enforces on its own data can be applied to * the external file as well. * * <p>A DATALINK value is retrieved from a ResultSet object with the ResultSet methods * getURL or getObject. If the Java platform does not support the type of URL returned by * getURL or getObject, a DATALINK value can be retrieved as a String object with the method * getString. * * <p>java.net.URL values are stored in a database using the method setURL. If the Java * platform does not support the type of URL being set, the method setString can be used * instead. */ case Types.DATALINK: { return result.getURL(i); } /** * The JDBC DATE type represents a date consisting of day, month, and year. The * corresponding SQL DATE type is defined in SQL-92, but it is implemented by only a subset * of the major databases. Some databases offer alternative SQL types that support similar * semantics. */ case Types.DATE: { try { Date d = result.getDate(i, calendar); return d != null ? formatDate(d.getTime()) : null; } catch (SQLException e) { return null; } } case Types.TIME: { try { Time t = result.getTime(i, calendar); return t != null ? formatDate(t.getTime()) : null; } catch (SQLException e) { return null; } } case Types.TIMESTAMP: { try { Timestamp t = result.getTimestamp(i, calendar); return t != null ? formatDate(t.getTime()) : null; } catch (SQLException e) { // java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column ... to // TIMESTAMP. return null; } } /** * The JDBC types DECIMAL and NUMERIC are very similar. They both represent fixed-precision * decimal values. * * <p>The corresponding SQL types DECIMAL and NUMERIC are defined in SQL-92 and are very * widely implemented. These SQL types take precision and scale parameters. The precision is * the total number of decimal digits supported, and the scale is the number of decimal * digits after the decimal point. For most DBMSs, the scale is less than or equal to the * precision. So for example, the value "12.345" has a precision of 5 and a scale of 3, and * the value ".11" has a precision of 2 and a scale of 2. JDBC requires that all DECIMAL and * NUMERIC types support both a precision and a scale of at least 15. * * <p>The sole distinction between DECIMAL and NUMERIC is that the SQL-92 specification * requires that NUMERIC types be represented with exactly the specified precision, whereas * for DECIMAL types, it allows an implementation to add additional precision beyond that * specified when the type was created. Thus a column created with type NUMERIC(12,4) will * always be represented with exactly 12 digits, whereas a column created with type * DECIMAL(12,4) might be represented by some larger number of digits. * * <p>The recommended Java mapping for the DECIMAL and NUMERIC types is * java.math.BigDecimal. The java.math.BigDecimal type provides math operations to allow * BigDecimal types to be added, subtracted, multiplied, and divided with other BigDecimal * types, with integer types, and with floating point types. * * <p>The method recommended for retrieving DECIMAL and NUMERIC values is * ResultSet.getBigDecimal. JDBC also allows access to these SQL types as simple Strings or * arrays of char. Thus, Java programmers can use getString to receive a DECIMAL or NUMERIC * result. However, this makes the common case where DECIMAL or NUMERIC are used for * currency values rather awkward, since it means that application writers have to perform * math on strings. It is also possible to retrieve these SQL types as any of the Java * numeric types. */ case Types.DECIMAL: case Types.NUMERIC: { BigDecimal bd = null; try { // getBigDecimal() should get obsolete. Most seem to use getString/getObject anyway... bd = result.getBigDecimal(i); } catch (NullPointerException e) { // But is it true? JDBC NPE exists since 13 years? // http://forums.codeguru.com/archive/index.php/t-32443.html // Null values are driving us nuts in JDBC: // http://stackoverflow.com/questions/2777214/when-accessing-resultsets-in-jdbc-is-there-an-elegant-way-to-distinguish-betwee } if (bd == null || result.wasNull()) { return null; } int scale = 2; if (scale >= 0) { bd = bd.setScale(scale, BigDecimal.ROUND_UP); try { long l = bd.longValueExact(); if (Long.toString(l).equals(result.getString(i))) { // convert to long if possible return l; } else { // convert to double (with precision loss) return bd.doubleValue(); } } catch (ArithmeticException e) { return bd.doubleValue(); } } else { return bd.toPlainString(); } } /** * The JDBC type DOUBLE represents a "double precision" floating point number that supports * 15 digits of mantissa. * * <p>The corresponding SQL type is DOUBLE PRECISION, which is defined in SQL-92 and is * widely supported by the major databases. The SQL-92 standard leaves the precision of * DOUBLE PRECISION up to the implementation, but in practice all the major databases * supporting DOUBLE PRECISION support a mantissa precision of at least 15 digits. * * <p>The recommended Java mapping for the DOUBLE type is as a Java double. */ case Types.DOUBLE: { String s = result.getString(i); if (result.wasNull() || s == null) { return null; } NumberFormat format = NumberFormat.getInstance(locale); Number number = format.parse(s); return number.doubleValue(); } /** * The JDBC type FLOAT is basically equivalent to the JDBC type DOUBLE. We provided both * FLOAT and DOUBLE in a possibly misguided attempt at consistency with previous database * APIs. FLOAT represents a "double precision" floating point number that supports 15 digits * of mantissa. * * <p>The corresponding SQL type FLOAT is defined in SQL-92. The SQL-92 standard leaves the * precision of FLOAT up to the implementation, but in practice all the major databases * supporting FLOAT support a mantissa precision of at least 15 digits. * * <p>The recommended Java mapping for the FLOAT type is as a Java double. However, because * of the potential confusion between the double precision SQL FLOAT and the single * precision Java float, we recommend that JDBC programmers should normally use the JDBC * DOUBLE type in preference to FLOAT. */ case Types.FLOAT: { String s = result.getString(i); if (result.wasNull() || s == null) { return null; } NumberFormat format = NumberFormat.getInstance(locale); Number number = format.parse(s); return number.doubleValue(); } /** * The JDBC type JAVA_OBJECT, added in the JDBC 2.0 core API, makes it easier to use objects * in the Java programming language as values in a database. JAVA_OBJECT is simply a type * code for an instance of a class defined in the Java programming language that is stored * as a database object. The type JAVA_OBJECT is used by a database whose type system has * been extended so that it can store Java objects directly. The JAVA_OBJECT value may be * stored as a serialized Java object, or it may be stored in some vendor-specific format. * * <p>The type JAVA_OBJECT is one of the possible values for the column DATA_TYPE in the * ResultSet objects returned by various DatabaseMetaData methods, including getTypeInfo, * getColumns, and getUDTs. The method getUDTs, part of the new JDBC 2.0 core API, will * return information about the Java objects contained in a particular schema when it is * given the appropriate parameters. Having this information available facilitates using a * Java class as a database type. */ case Types.OTHER: case Types.JAVA_OBJECT: { return result.getObject(i); } /** * The JDBC type REAL represents a "single precision" floating point number that supports * seven digits of mantissa. * * <p>The corresponding SQL type REAL is defined in SQL-92 and is widely, though not * universally, supported by the major databases. The SQL-92 standard leaves the precision * of REAL up to the implementation, but in practice all the major databases supporting REAL * support a mantissa precision of at least seven digits. * * <p>The recommended Java mapping for the REAL type is as a Java float. */ case Types.REAL: { String s = result.getString(i); if (result.wasNull() || s == null) { return null; } NumberFormat format = NumberFormat.getInstance(locale); Number number = format.parse(s); return number.doubleValue(); } /** * The JDBC type TINYINT represents an 8-bit integer value between 0 and 255 that may be * signed or unsigned. * * <p>The corresponding SQL type, TINYINT, is currently supported by only a subset of the * major databases. Portable code may therefore prefer to use the JDBC SMALLINT type, which * is widely supported. * * <p>The recommended Java mapping for the JDBC TINYINT type is as either a Java byte or a * Java short. The 8-bit Java byte type represents a signed value from -128 to 127, so it * may not always be appropriate for larger TINYINT values, whereas the 16-bit Java short * will always be able to hold all TINYINT values. */ /** * The JDBC type SMALLINT represents a 16-bit signed integer value between -32768 and 32767. * * <p>The corresponding SQL type, SMALLINT, is defined in SQL-92 and is supported by all the * major databases. The SQL-92 standard leaves the precision of SMALLINT up to the * implementation, but in practice, all the major databases support at least 16 bits. * * <p>The recommended Java mapping for the JDBC SMALLINT type is as a Java short. */ /** * The JDBC type INTEGER represents a 32-bit signed integer value ranging between * -2147483648 and 2147483647. * * <p>The corresponding SQL type, INTEGER, is defined in SQL-92 and is widely supported by * all the major databases. The SQL-92 standard leaves the precision of INTEGER up to the * implementation, but in practice all the major databases support at least 32 bits. * * <p>The recommended Java mapping for the INTEGER type is as a Java int. */ case Types.TINYINT: case Types.SMALLINT: case Types.INTEGER: { try { Integer integer = result.getInt(i); return result.wasNull() ? null : integer; } catch (SQLDataException e) { Long l = result.getLong(i); return result.wasNull() ? null : l; } } case Types.SQLXML: { SQLXML xml = result.getSQLXML(i); return xml != null ? xml.getString() : null; } case Types.NULL: { return null; } /** * The JDBC type DISTINCT field (Types class)>DISTINCT represents the SQL3 type DISTINCT. * * <p>The standard mapping for a DISTINCT type is to the Java type to which the base type of * a DISTINCT object would be mapped. For example, a DISTINCT type based on a CHAR would be * mapped to a String object, and a DISTINCT type based on an SQL INTEGER would be mapped to * an int. * * <p>The DISTINCT type may optionally have a custom mapping to a class in the Java * programming language. A custom mapping consists of a class that implements the interface * SQLData and an entry in a java.util.Map object. */ case Types.DISTINCT: { logger.warn("JDBC type not implemented: {}", type); return null; } /** * The JDBC type STRUCT represents the SQL99 structured type. An SQL structured type, which * is defined by a user with a CREATE TYPE statement, consists of one or more attributes. * These attributes may be any SQL data type, built-in or user-defined. * * <p>The standard mapping for the SQL type STRUCT is to a Struct object in the Java * programming language. A Struct object contains a value for each attribute of the STRUCT * value it represents. * * <p>A STRUCT value may optionally be custom mapped to a class in the Java programming * language, and each attribute in the STRUCT may be mapped to a field in the class. A * custom mapping consists of a class that implements the interface SQLData and an entry in * a java.util.Map object. */ case Types.STRUCT: { logger.warn("JDBC type not implemented: {}", type); return null; } case Types.REF: { logger.warn("JDBC type not implemented: {}", type); return null; } case Types.ROWID: { logger.warn("JDBC type not implemented: {}", type); return null; } default: { logger.warn("unknown JDBC type ignored: {}", type); return null; } } return null; }