Add query-only mode for piping results to visidata/pspg/less
Query mode auto-activates when destination flags are omitted, outputting CSV/TSV to stdout for interactive data exploration of DB2 iSeries queries. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
85355efe8f
commit
6c9b0f96a0
@ -27,6 +27,8 @@ public class jrunner {
|
|||||||
String nr = "";
|
String nr = "";
|
||||||
String nc = "";
|
String nc = "";
|
||||||
String nl = "\n";
|
String nl = "\n";
|
||||||
|
Boolean queryMode = false;
|
||||||
|
String outputFormat = "csv";
|
||||||
String msg = "";
|
String msg = "";
|
||||||
Connection scon = null;
|
Connection scon = null;
|
||||||
Connection dcon = null;
|
Connection dcon = null;
|
||||||
@ -50,6 +52,7 @@ public class jrunner {
|
|||||||
msg = msg + nl + "-dt fully qualified name of destination table";
|
msg = msg + nl + "-dt fully qualified name of destination table";
|
||||||
msg = msg + nl + "-t trim text";
|
msg = msg + nl + "-t trim text";
|
||||||
msg = msg + nl + "-c clear target table";
|
msg = msg + nl + "-c clear target table";
|
||||||
|
msg = msg + nl + "-f output format (csv, tsv, table, json) - default: csv";
|
||||||
msg = msg + nl + "--help info";
|
msg = msg + nl + "--help info";
|
||||||
|
|
||||||
//---------------------------------------parse args into variables-------------------------------------------------
|
//---------------------------------------parse args into variables-------------------------------------------------
|
||||||
@ -104,6 +107,9 @@ public class jrunner {
|
|||||||
case "-c":
|
case "-c":
|
||||||
clear = true;
|
clear = true;
|
||||||
break;
|
break;
|
||||||
|
case "-f":
|
||||||
|
outputFormat = args[i+1].toLowerCase();
|
||||||
|
break;
|
||||||
case "-v":
|
case "-v":
|
||||||
System.out.println(msg);
|
System.out.println(msg);
|
||||||
return;
|
return;
|
||||||
@ -127,15 +133,25 @@ public class jrunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("------------db info---------------------------------------");
|
// Detect query mode when destination flags are not provided
|
||||||
System.out.println("source db uri: " + scu);
|
queryMode = dcu.isEmpty() && dcn.isEmpty() && dcp.isEmpty() && dt.isEmpty();
|
||||||
System.out.println("source db username: " + scn);
|
|
||||||
System.out.println("destination db uri: " + dcu);
|
if (queryMode) {
|
||||||
System.out.println("destination username: " + dcn);
|
System.err.println("------------query mode------------------------------------");
|
||||||
System.out.println("------------source sql------------------------------------");
|
System.err.println("source db uri: " + scu);
|
||||||
System.out.println(sq);
|
System.err.println("source db username: " + scn);
|
||||||
System.out.println("------------destination table-----------------------------");
|
System.err.println("output format: " + outputFormat);
|
||||||
System.out.println(dt);
|
} else {
|
||||||
|
System.out.println("------------db info---------------------------------------");
|
||||||
|
System.out.println("source db uri: " + scu);
|
||||||
|
System.out.println("source db username: " + scn);
|
||||||
|
System.out.println("destination db uri: " + dcu);
|
||||||
|
System.out.println("destination username: " + dcn);
|
||||||
|
System.out.println("------------source sql------------------------------------");
|
||||||
|
System.out.println(sq);
|
||||||
|
System.out.println("------------destination table-----------------------------");
|
||||||
|
System.out.println(dt);
|
||||||
|
}
|
||||||
|
|
||||||
//return;
|
//return;
|
||||||
|
|
||||||
@ -149,7 +165,11 @@ public class jrunner {
|
|||||||
|
|
||||||
//-------------------------------------------establish connections-------------------------------------------------
|
//-------------------------------------------establish connections-------------------------------------------------
|
||||||
//source database
|
//source database
|
||||||
System.out.println("------------open database connections---------------------");
|
if (queryMode) {
|
||||||
|
System.err.println("------------open database connection---------------------");
|
||||||
|
} else {
|
||||||
|
System.out.println("------------open database connections---------------------");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
scon = DriverManager.getConnection(scu, scn, scp);
|
scon = DriverManager.getConnection(scu, scn, scp);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
@ -159,14 +179,16 @@ public class jrunner {
|
|||||||
}
|
}
|
||||||
System.out.println(" ✅ source database");
|
System.out.println(" ✅ source database");
|
||||||
//destination database
|
//destination database
|
||||||
try {
|
if (!queryMode) {
|
||||||
dcon = DriverManager.getConnection(dcu, dcn, dcp);
|
try {
|
||||||
} catch (SQLException e) {
|
dcon = DriverManager.getConnection(dcu, dcn, dcp);
|
||||||
System.out.println("issue connecting to destination:");
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
System.out.println("issue connecting to destination:");
|
||||||
System.exit(0);
|
e.printStackTrace();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
System.out.println(" ✅ destination database");
|
||||||
}
|
}
|
||||||
System.out.println(" ✅ destination database");
|
|
||||||
//----------------------------------------open resultset------------------------------------------------------------
|
//----------------------------------------open resultset------------------------------------------------------------
|
||||||
try {
|
try {
|
||||||
stmt = scon.createStatement();
|
stmt = scon.createStatement();
|
||||||
@ -204,7 +226,7 @@ public class jrunner {
|
|||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
//-------------------------clear the target table if requeted----------------------------------------------------
|
//-------------------------clear the target table if requeted----------------------------------------------------
|
||||||
if (clear) {
|
if (!queryMode && clear) {
|
||||||
System.out.println("------------clear target table----------------------------");
|
System.out.println("------------clear target table----------------------------");
|
||||||
sql = "DELETE FROM " + dt;
|
sql = "DELETE FROM " + dt;
|
||||||
try {
|
try {
|
||||||
@ -217,11 +239,20 @@ public class jrunner {
|
|||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("------------row count-------------------------------------");
|
if (queryMode) {
|
||||||
//-------------------------------build & execute sql-------------------------------------------------------------
|
//-------------------------------output query results--------------------------------------------------------
|
||||||
try {
|
try {
|
||||||
sql = "";
|
outputQueryResults(rs, cols, dtn, outputFormat);
|
||||||
while (rs.next()) {
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("------------row count-------------------------------------");
|
||||||
|
//-------------------------------build & execute sql-------------------------------------------------------------
|
||||||
|
try {
|
||||||
|
sql = "";
|
||||||
|
while (rs.next()) {
|
||||||
r++;
|
r++;
|
||||||
t++;
|
t++;
|
||||||
nr = "";
|
nr = "";
|
||||||
@ -350,26 +381,111 @@ public class jrunner {
|
|||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//System.out.println(sql);
|
//System.out.println(sql);
|
||||||
|
|
||||||
//---------------------------------------close connections--------------------------------------------------------
|
//---------------------------------------close connections--------------------------------------------------------
|
||||||
try {
|
try {
|
||||||
scon.close();
|
scon.close();
|
||||||
dcon.close();
|
if (!queryMode && dcon != null) {
|
||||||
|
dcon.close();
|
||||||
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.out.println("issue closing connections");
|
System.out.println("issue closing connections");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
System.out.println(" rows written");
|
if (!queryMode) {
|
||||||
tsEnd = Timestamp.from(Instant.now());
|
System.out.println(" rows written");
|
||||||
System.out.println(tsStart);
|
tsEnd = Timestamp.from(Instant.now());
|
||||||
System.out.println(tsEnd);
|
System.out.println(tsStart);
|
||||||
|
System.out.println(tsEnd);
|
||||||
|
}
|
||||||
//long time = Duration.between(tsStart, tsEnd).toMillis();
|
//long time = Duration.between(tsStart, tsEnd).toMillis();
|
||||||
//System.out.println("time elapsed: " + time);
|
//System.out.println("time elapsed: " + time);
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void outputQueryResults(ResultSet rs, int cols, String[] dtn, String format) throws SQLException {
|
||||||
|
switch (format) {
|
||||||
|
case "csv":
|
||||||
|
outputCSV(rs, cols);
|
||||||
|
break;
|
||||||
|
case "tsv":
|
||||||
|
outputTSV(rs, cols);
|
||||||
|
break;
|
||||||
|
case "table":
|
||||||
|
System.err.println("Table format not yet implemented, defaulting to CSV");
|
||||||
|
outputCSV(rs, cols);
|
||||||
|
break;
|
||||||
|
case "json":
|
||||||
|
System.err.println("JSON format not yet implemented, defaulting to CSV");
|
||||||
|
outputCSV(rs, cols);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.err.println("Unknown format: " + format + ", defaulting to CSV");
|
||||||
|
outputCSV(rs, cols);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void outputCSV(ResultSet rs, int cols) throws SQLException {
|
||||||
|
// Print header row
|
||||||
|
for (int i = 1; i <= cols; i++) {
|
||||||
|
if (i > 1) System.out.print(",");
|
||||||
|
System.out.print(escapeCSV(rs.getMetaData().getColumnName(i)));
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// Print data rows
|
||||||
|
while (rs.next()) {
|
||||||
|
for (int i = 1; i <= cols; i++) {
|
||||||
|
if (i > 1) System.out.print(",");
|
||||||
|
String value = rs.getString(i);
|
||||||
|
if (rs.wasNull() || value == null) {
|
||||||
|
// Empty field for NULL
|
||||||
|
} else {
|
||||||
|
System.out.print(escapeCSV(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void outputTSV(ResultSet rs, int cols) throws SQLException {
|
||||||
|
// Print header row
|
||||||
|
for (int i = 1; i <= cols; i++) {
|
||||||
|
if (i > 1) System.out.print("\t");
|
||||||
|
System.out.print(escapeTSV(rs.getMetaData().getColumnName(i)));
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// Print data rows
|
||||||
|
while (rs.next()) {
|
||||||
|
for (int i = 1; i <= cols; i++) {
|
||||||
|
if (i > 1) System.out.print("\t");
|
||||||
|
String value = rs.getString(i);
|
||||||
|
if (rs.wasNull() || value == null) {
|
||||||
|
// Empty field for NULL
|
||||||
|
} else {
|
||||||
|
System.out.print(escapeTSV(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String escapeCSV(String value) {
|
||||||
|
if (value.contains(",") || value.contains("\"") || value.contains("\n") || value.contains("\r")) {
|
||||||
|
return "\"" + value.replaceAll("\"", "\"\"") + "\"";
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String escapeTSV(String value) {
|
||||||
|
return value.replaceAll("\t", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user