changeset 450:b9f82064fe0c

Implemented PreparedStatement.toString() as requested by https://github.com/MonetDB/monetdb-java/issues/8
author Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
date Wed, 03 Mar 2021 18:52:03 +0100 (2021-03-03)
parents 5ddfc0aa7f0e
children 3dfcd06fd8ba
files ChangeLog src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java tests/JDBC_API_Tester.java
diffstat 3 files changed, 38 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
 # This file is updated with Maddlog
 
 * Wed Mar  3 2021 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
+- Implemented PreparedStatement.toString() as requested by
+  https://github.com/MonetDB/monetdb-java/issues/8
+
+* Wed Mar  3 2021 Martin van Dinther <martin.van.dinther@monetdbsolutions.com>
 - Implemented fix for released monetdb-jdbc-3.0.jre8.jar and
   monetdb-mcl-1.19.jre8.jar when it is was run using java build
   1.8.0_###.  It would throw:  java.lang.NoSuchMethodError:
--- a/src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java
+++ b/src/main/java/org/monetdb/jdbc/MonetPreparedStatement.java
@@ -62,12 +62,13 @@ import java.util.Map;
  *
  * @author Fabian Groffen
  * @author Martin van Dinther
- * @version 0.6
+ * @version 0.7
  */
 public class MonetPreparedStatement
 	extends MonetStatement
 	implements PreparedStatement, AutoCloseable
 {
+	private final String sqlStatement;
 	private final String[] monetdbType;
 	private final int[] javaType;
 	private final int[] digits;
@@ -124,6 +125,7 @@ public class MonetPreparedStatement
 		if (!super.execute("PREPARE " + prepareQuery))
 			throw new SQLException("Unexpected server response", "M0M10");
 
+		sqlStatement = prepareQuery;
 		// cheat a bit to get the ID and the number of columns
 		id = ((MonetConnection.ResultSetResponse)header).id;
 		size = (int)((MonetConnection.ResultSetResponse)header).tuplecount;
@@ -2716,6 +2718,23 @@ public class MonetPreparedStatement
 		close();
 	}
 
+	/**
+	 * @return the prepared SQL statement including parameter types and parameter values that were already set.
+	 */
+	public String toString​() {
+		final StringBuilder sb = new StringBuilder(256);
+		sb.append("Prepared SQL: ").append(sqlStatement).append("\n");
+		int param = 1;
+		for (int i = 0; i < size; i++) {
+			/* when column[i] == null it is a parameter, when column[i] != null it is a result column of the prepared query */
+			if (column[i] == null) {
+				sb.append(" parameter ").append(param++).append(" ").append(monetdbType[i]);
+				sb.append(", set value: ").append((values[i] != null) ? values[i] : "<null>").append("\n");
+			}
+		}
+		return sb.toString();
+	}
+
 	//== Java 1.8 methods (JDBC 4.2)
 
 	@Override
@@ -2799,6 +2818,7 @@ public class MonetPreparedStatement
 		return buf.toString();
 	}
 
+
 	/**
 	 * Small helper method that formats the "Invalid Parameter Index number ..." message
 	 * and creates a new SQLDataException object whose SQLState is set
--- a/tests/JDBC_API_Tester.java
+++ b/tests/JDBC_API_Tester.java
@@ -1003,6 +1003,7 @@ final public class JDBC_API_Tester {
 
 			pstmt.executeBatch();
 			sb.append(" passed\n");
+			sb.append(pstmt.toString());	// test showing prepared statement
 
 			sb.append("2b. closing PreparedStatement...");
 			pstmt.close();
@@ -1058,6 +1059,11 @@ final public class JDBC_API_Tester {
 			"0. false	false\n" +
 			"1. creating test table...success\n" +
 			"2a. inserting 3 records as batch... passed\n" +
+			"Prepared SQL: INSERT INTO table_Test_PSgetObject (ti,si,i,bi) VALUES (?,?,?,?)\n" +
+			" parameter 1 tinyint, set value: -127\n" +
+			" parameter 2 smallint, set value: -12700\n" +
+			" parameter 3 int, set value: -1270000\n" +
+			" parameter 4 bigint, set value: -127000000\n" +
 			"2b. closing PreparedStatement... passed\n" +
 			"3a. selecting records... passed\n" +
 			"  Retrieved row data: ti=-127 si=-12700 i=-1270000 bi=-127000000\n" +
@@ -1297,6 +1303,7 @@ final public class JDBC_API_Tester {
 		PreparedStatement pstmt = null;
 		try {
 			pstmt = con.prepareStatement("SELECT CASE WHEN myint IS NULL THEN 0 ELSE 1 END AS intnull, * FROM table_Test_PSmetadata WHERE myint = ?");
+			sb.append(pstmt.toString());	// test showing prepared statement
 
 			// testing and showing result set meta data
 			ResultSetMetaData rsmd = pstmt.getMetaData();
@@ -1338,6 +1345,8 @@ final public class JDBC_API_Tester {
 
 		compareExpectedOutput("Test_PSmetadata",
 			"0. false\tfalse\n" +
+			"Prepared SQL: SELECT CASE WHEN myint IS NULL THEN 0 ELSE 1 END AS intnull, * FROM table_Test_PSmetadata WHERE myint = ?\n" +
+			" parameter 1 int, set value: <null>\n" +
 			"rsmd. 6 columns:\n" +
 			"RCol 1\n" +
 			"  classname     java.lang.Short\n" +
@@ -1554,6 +1563,7 @@ final public class JDBC_API_Tester {
 			pstmt.setObject(2, turl);
 			// insert first record
 			pstmt.execute();
+			sb.append(pstmt.toString());	// test showing prepared statement
 
 			try {
 				tinet.setNetmaskBits(16);
@@ -1605,6 +1615,9 @@ final public class JDBC_API_Tester {
 			"  type      12\n" +
 			"  typename  url\n" +
 			"  classname org.monetdb.jdbc.types.URL\n" +
+			"Prepared SQL: INSERT INTO table_Test_PSsqldata VALUES (?, ?)\n" +
+			" parameter 1 inet, set value: inet '172.5.5.5/24'\n" +
+			" parameter 2 url, set value: url 'http://www.monetdb.org/'\n" +
 			"1.	172.5.5.5/24\n" +
 			"  172.5.5.5/24\n" +
 			"  /172.5.5.5\n" +