<groupId>net.jaekl.squelch</groupId>
<artifactId>squelch</artifactId>
<packaging>jar</packaging>
- <version>0.1a-SNAPSHOT</version>
+ <version>0.1b-SNAPSHOT</version>
<name>squelch</name>
<url>http://maven.apache.org</url>
<build>
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
+import java.util.HashMap;
import java.util.Locale;
public abstract class DbDriver {
- private boolean m_suppressNulls = false;
+ // Well-known setting names
+ public static final String SUPPRESS_NULLS = "suppress_nulls";
+
+ private HashMap<String, Setting> m_settings;
// Returns true iff. this DbDriver knows how to connect to the given JDBC URL
abstract public boolean handles(String jdbcUrl);
// Execute line as a statement of this type
abstract String getJdbcDriverClassName();
+ DbDriver() {
+ m_settings = new HashMap<String, Setting>();
+ m_settings.put(SUPPRESS_NULLS, new Setting(SUPPRESS_NULLS, Boolean.class, Boolean.valueOf(false)));
+ }
+
// -------------------
// Getters and setters
+ public Setting[] getSettings()
+ {
+ return m_settings.values().toArray(new Setting[m_settings.size()]);
+ }
- public boolean isSuppressNulls() { return m_suppressNulls; }
- public void setSuppressNulls(boolean value) { m_suppressNulls = value; }
-
-
+ public boolean isSet(String name)
+ {
+ Setting setting = m_settings.get(name);
+ if (null != setting) {
+ return setting.getBoolean();
+ }
+ return false;
+ }
+ public void set(String name, Object value)
+ {
+ String lcName = name.toLowerCase(Locale.CANADA);
+ Setting setting = m_settings.get(lcName);
+ if (null != setting) {
+ setting.set(value);
+ }
+ else {
+ throw new IllegalArgumentException("Setting \"" + name + "\" not found.");
+ }
+ }
+
// Open a new Connection to the database. Note that the caller must close() this at some point.
public Connection connect(String jdbcUrl, String userName, String password) throws ClassNotFoundException, SQLException
{
--- /dev/null
+package net.jaekl.squelch.db;
+
+import java.util.Locale;
+
+public class Setting {
+ private String m_name;
+ private Class<?> m_type;
+ private Object m_value;
+
+ public Setting(String name, Class<?> type, Object defaultValue)
+ {
+ m_name = name;
+ m_type = type;
+ m_value = defaultValue;
+ }
+
+ public String getName() { return m_name; }
+
+ public boolean getBoolean()
+ {
+ assert(Boolean.class == m_type);
+
+ if (m_value instanceof Boolean) {
+ return ((Boolean)m_value).booleanValue();
+ }
+ return false;
+ }
+
+ public void set(Object value)
+ {
+ if (Boolean.class == m_type) {
+ if (value instanceof String) {
+ m_value = parseBoolean((String)value);
+ }
+ else if (value instanceof Boolean) {
+ m_value = value;
+ }
+ }
+ else {
+ throw new IllegalArgumentException("This type not yet supported.");
+ }
+ }
+
+ private boolean parseBoolean(String value)
+ {
+ if (null == value) {
+ return false;
+ }
+
+ String setting = value.trim().toLowerCase(Locale.CANADA);
+
+ if (setting.equals("yes") || setting.equals("true") || setting.equals("on") || setting.equals("1")) {
+ return true;
+ }
+ if (setting.equals("no") || setting.equals("false") || setting.equals("off") || setting.equals("0")) {
+ return false;
+ }
+
+ throw new IllegalArgumentException("UnrecognizedBooleanValue: \"" + value + "\"");
+ }
+}
import java.util.Locale;
import net.jaekl.squelch.db.DbDriver;
+import net.jaekl.squelch.db.Setting;
public class PSet extends Stmt {
- private static final String SUPPRESS_NULLS = "suppress_nulls";
-
@Override
public boolean handles(String line) {
if (null == line) {
public int exec(DbDriver driver, Connection conn, PrintWriter pw, String line)
throws IOException, SQLException
{
- String trimmed = line.substring(6).trim();
+ String trimmed = line.substring(5).trim();
int equPos = trimmed.indexOf('=');
if (equPos > 0) {
return setValue(driver, pw, trimmed, equPos);
}
- else if (trimmed.length() > 0) {
- return displayValue(driver, pw, trimmed);
- }
else {
- // TODO: StringTable
- pw.println("???");
- return 0;
+ return displayValue(driver, pw, trimmed);
}
}
private int displayValue(DbDriver driver, PrintWriter pw, String trimmed)
{
- String lcName = trimmed.toLowerCase(Locale.CANADA);
+ Setting[] settings = driver.getSettings();
- if (SUPPRESS_NULLS.equals(lcName)) {
- // TODO: StringTable
- pw.println(SUPPRESS_NULLS + ": " + (driver.isSuppressNulls() ? "on" : "off"));
- }
- else {
- // TODO: StringTable
- pw.println("??? Unrecognized setting: \"" + trimmed + "\". Ignored.");
+ for (Setting setting : settings) {
+ String lcName = trimmed.toLowerCase(Locale.CANADA);
+
+ if ("".equals(lcName) || setting.getName().equals(lcName)) {
+ // TODO: StringTable
+ pw.println(setting.getName() + ": " + (setting.getBoolean()));
+ }
}
return 0;
}
- private boolean parseBoolean(String value)
- {
- if (null == value) {
- return false;
- }
-
- String setting = value.trim().toLowerCase(Locale.CANADA);
-
- if (setting.equals("yes") || setting.equals("true") || setting.equals("on") || setting.equals("1")) {
- return true;
- }
- if (setting.equals("no") || setting.equals("false") || setting.equals("off") || setting.equals("0")) {
- return false;
- }
-
- throw new IllegalArgumentException("UnrecognizedBooleanValue: \"" + value + "\"");
- }
-
private int setValue(DbDriver driver, PrintWriter pw, String trimmed, int equPos)
{
String name = trimmed.substring(0, equPos).trim();
String value = trimmed.substring(equPos + 1).trim();
- String lcName = name.toLowerCase(Locale.CANADA);
-
- if (lcName.equals("suppress_nulls")) {
- driver.setSuppressNulls(parseBoolean(value));
- }
- else {
- // TODO: Stringtable
- pw.println("??? Unrecognized setting name \"" + name + "\" ignored.");
- return 0;
- }
+ driver.set(name, value);
return 1;
}
if (pending > 0) {
writeHeader(pw, cols, colWidths, suppressed);
writeRowBuffer(pw, rowBuf, colWidths, suppressed);
- rowCount = rowBuf.getPending();
+ rowCount = pending;
}
- if (driver.isSuppressNulls()) {
- // TODO: StringTable
- pw.println("Row limit for suppress_nulls has been reached; output may have been truncated.");
- writeDivider(pw, colWidths, suppressed);
- }
- else {
- while (pending > 0) {
- rowBuf = bufferRows(driver, colWidths);
- writeRowBuffer(pw, rowBuf, colWidths, suppressed);
- pending = rowBuf.getPending();
- rowCount += pending;
+ rowBuf = bufferRows(driver, colWidths);
+ pending = rowBuf.getPending();
+ while (pending > 0) {
+ if (driver.isSet(DbDriver.SUPPRESS_NULLS)) {
+ writeDivider(pw, colWidths, suppressed);
+ pw.println("Row limit for suppress_nulls has been reached; output may have been truncated.");
+ break;
}
+ writeRowBuffer(pw, rowBuf, colWidths, suppressed);
+ rowCount += pending;
+ rowBuf = bufferRows(driver, colWidths);
+ pending = rowBuf.getPending();
}
if (rowCount > 0) {
}
}
- if ((!allColsNull) || (!driver.isSuppressNulls()))
+ if ((!allColsNull) || (!driver.isSet(DbDriver.SUPPRESS_NULLS)))
{
rowBuf.addRow(row);
// Check whether all values in this row will fit in the current column widths
for (int colIdx = 0; colIdx < colWidths.length; ++colIdx) {
- int width = ("" + row.getValue(colIdx + 1)).length();
+ int width = stringify(row.getValue(colIdx + 1)).length();
if (width > colWidths[colIdx]) {
// Widen the column to fit this value
colWidths[colIdx] = width;
{
boolean[] result = new boolean[cols.length];
- if (rowBuf.getPending() < 1) {
- // No data rows, so do not suppress any columns.
+ if ( !(driver.isSet(DbDriver.SUPPRESS_NULLS))
+ || (rowBuf.getPending() < 1) )
+ {
+ // Null-suppression is turned off, or
+ // there are no data rows,
+ // so do not suppress any columns.
for (int colIdx = 0; colIdx < cols.length; ++colIdx) {
result[colIdx] = false;
}
writeDivider(pw, colWidths, suppressed);
for (int idx = 0; idx < cols.length; ++idx) {
- Column col = cols[idx];
- pw.print("| " + centrePad(col.getLabel(), colWidths[idx]) + " ");
+ if (!suppressed[idx]) {
+ Column col = cols[idx];
+ pw.print("| " + centrePad(col.getLabel(), colWidths[idx]) + " ");
+ }
}
pw.println("|");
if (!suppressed[colIdx]) {
Object obj = row.getValue(colIdx + 1);
String value = stringify(obj);
- int width = stringWidth(obj);
+ int width = stringWidth(value);
String padding = repChar(' ', colWidths[colIdx] - width);
pw.print("| " + value + padding + " ");
}
import java.io.PrintWriter;
import java.sql.SQLException;
+import net.jaekl.squelch.db.DbDriver;
import net.jaekl.squelch.db.DbDriverMock;
import net.jaekl.squelch.sql.ConnectionMock;
for (String value : on) {
pset.exec(driver, conn, pw, "\\pset suppress_nulls=" + value);
- assertTrue(driver.isSuppressNulls());
+ assertTrue(driver.isSet(DbDriver.SUPPRESS_NULLS));
pset.exec(driver, conn, pw, "\\pset Suppress_NULLS=" + value);
- assertTrue(driver.isSuppressNulls());
+ assertTrue(driver.isSet(DbDriver.SUPPRESS_NULLS));
}
for (String value : off) {
pset.exec(driver, conn, pw, "\\pset suppress_nulls=" + value);
- assertFalse(driver.isSuppressNulls());
+ assertFalse(driver.isSet(DbDriver.SUPPRESS_NULLS));
pset.exec(driver, conn, pw, "\\pset Suppress_NULLS=" + value);
- assertFalse(driver.isSuppressNulls());
+ assertFalse(driver.isSet(DbDriver.SUPPRESS_NULLS));
}
for (String value : on) {
pset.exec(driver, conn, pw, "\\PSET SuPPreSS_NuLLs=" + value);
- assertTrue(driver.isSuppressNulls());
+ assertTrue(driver.isSet(DbDriver.SUPPRESS_NULLS));
}
pw.close();
for (String cmd : cmds) {
DbDriverMock driver = new DbDriverMock();
- driver.setSuppressNulls(true);
+ driver.set(DbDriver.SUPPRESS_NULLS, true);
String output = doExec(driver, cmd);
- assertEquals("suppress_nulls: on\n", output);
+ assertEquals("suppress_nulls: true\n", output);
- driver.setSuppressNulls(false);
+ driver.set(DbDriver.SUPPRESS_NULLS, false);
output = doExec(driver, cmd);
- assertEquals("suppress_nulls: off\n", output);
+ assertEquals("suppress_nulls: false\n", output);
}
}
+ @Test
+ public void testExec_displayAll() throws IOException, SQLException
+ {
+ String[] cmds = { "\\pset", "\\pset ", "\\pset ",
+ "\\PsET", "\\PsET ", "\\PSET", "\\PSET " };
+
+ for (String cmd : cmds) {
+ DbDriverMock driver = new DbDriverMock();
+
+ driver.set(DbDriver.SUPPRESS_NULLS, true);
+ String output = doExec(driver, cmd);
+ assertTrue(output.contains("suppress_nulls: true\n"));
+
+ driver.set(DbDriver.SUPPRESS_NULLS, false);
+ output = doExec(driver, cmd);
+ assertTrue(output.contains("suppress_nulls: false\n"));
+ }
+ }
+
private String doExec(DbDriverMock driver, String cmd) throws IOException, SQLException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
import junit.framework.Assert;
+import net.jaekl.squelch.db.DbDriver;
import net.jaekl.squelch.db.DbDriverMock;
import net.jaekl.squelch.sql.Column;
import net.jaekl.squelch.sql.Row;
}
}
+ @Test
+ public void test_printTable_withNulls() throws IOException, SQLException
+ {
+ DbDriverMock driver = new DbDriverMock();
+
+ TabularMock tabular = createTableWithNulls();
+ driver.set(DbDriver.SUPPRESS_NULLS, true);
+
+ try (
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8));
+ )
+ {
+ tabular.printTable(driver, pw, "No rows returned.");
+ pw.close();
+ baos.close();
+ String actual = baos.toString();
+ assertEquals( "+---------+--------+------------+\n"
+ + "| EmpId | Value1 | Value3 |\n"
+ + "+---------+--------+------------+\n"
+ + "| 12345 | Fred | Flintstone |\n"
+ + "| 7654321 | Barney | Rubble |\n"
+ + "+---------+--------+------------+\n"
+ + "2 row(s) returned.\n",
+ actual);
+ }
+
+ tabular = createTableWithNulls();
+ driver.set(DbDriver.SUPPRESS_NULLS, false);
+
+ try (
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8));
+ )
+ {
+ tabular.printTable(driver, pw, "No rows returned.");
+ pw.close();
+ baos.close();
+ String actual = baos.toString();
+ assertEquals( "+---------+--------+--------+------------+\n"
+ + "| EmpId | Value1 | Value2 | Value3 |\n"
+ + "+---------+--------+--------+------------+\n"
+ + "| 12345 | Fred | null | Flintstone |\n"
+ + "| 7654321 | Barney | null | Rubble |\n"
+ + "+---------+--------+--------+------------+\n"
+ + "2 row(s) returned.\n",
+ actual);
+ }
+
+ }
+
@Test
public void test_repChar() {
Tabular tabular = new TabularMock();
return tabular;
}
+
+ private TabularMock createTableWithNulls()
+ {
+ TabularMock tabular = new TabularMock();
+
+ Column[] cols = {
+ new Column("EmpId", Long.class, 10),
+ new Column("Value1", String.class, 14),
+ new Column("Value2", String.class, 14),
+ new Column("Value3", String.class, 14)
+ };
+ tabular.mock_setCols(cols);
+
+ Row row = new Row(cols.length);
+ row.setValue(1, Long.valueOf(12345));
+ row.setValue(2, "Fred");
+ row.setValue(3, null);
+ row.setValue(4, "Flintstone");
+ tabular.mock_addRow(row);
+
+ row = new Row(cols.length);
+ row.setValue(1, Long.valueOf(7654321));
+ row.setValue(2, "Barney");
+ row.setValue(3, null);
+ row.setValue(4, "Rubble");
+ tabular.mock_addRow(row);
+
+ return tabular;
+ }
}