--- /dev/null
+package net.jaekl.squelch.stmt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import net.jaekl.squelch.db.DbDriverMock;
+import net.jaekl.squelch.sql.ConnectionMock;
+import net.jaekl.squelch.sql.DatabaseMetaDataMock;
+import net.jaekl.squelch.sql.ResultSetMock;
+import net.jaekl.squelch.sql.Row;
+
+import org.junit.Test;
+
+public class DescribeTest {
+
+ @Test
+ public void testHandles() {
+ final String[] AFFIRMATIVE = {
+ "\\d", "\\d ", " \\d", " \\d ",
+ "describe", "describe ", " describe", " describe ",
+ "DESCRIBE", "DESCRIBE ", " DESCRIBE", " DESCRIBE ",
+ "descRIbe", "DEscribE ", " DEScribe", " DEscRIbE ",
+ "\\d tablename", "\\d tablename ", " \\d tablename", " \\d tableName ",
+ "describe tablename", "DESCRIBE tablename ", " DesCrIbE tablename", " DESCribE fred "
+ };
+ final String[] NEGATIVE = {
+ "\\d\\q", "", null, " ", "select * from foo", " select * from foo ",
+ "DESCRIBEQ", "describeFOO", " describeJackAndDianne "
+ };
+
+ Describe describe = new Describe();
+ for (String s : AFFIRMATIVE) {
+ assertTrue("handles " + s, describe.handles(s));
+ }
+ for (String s : NEGATIVE) {
+ assertFalse("does not handle " + s, describe.handles(s));
+ }
+ }
+
+ @Test
+ public void testDescribeAll_noTables() throws IOException, SQLException
+ {
+ DatabaseMetaDataMock dbmdm = new DatabaseMetaDataMock();
+ Describe describe = new Describe();
+
+ try (
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8));
+ )
+ {
+ describe.describeAll(pw, dbmdm);
+ pw.close();
+ baos.close();
+ String actual = baos.toString();
+ final String EXPECTED = "???\n";
+ assertEquals(EXPECTED, actual);
+ }
+ }
+
+ @Test
+ public void testDescribeTable_noColumns()
+ throws IOException, SQLException
+ {
+ DatabaseMetaDataMock dbmdm = new DatabaseMetaDataMock();
+ Describe describe = new Describe();
+
+ try (
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8));
+ )
+ {
+ describe.describeTable(pw, dbmdm, "%");
+ pw.close();
+ baos.close();
+ String actual = baos.toString();
+ final String EXPECTED = "??? %\n";
+ assertEquals(EXPECTED, actual);
+ }
+ }
+
+ private DatabaseMetaDataMock construct_runs_dbmdm()
+ {
+ ResultSetMock rsmCols = new ResultSetMock();
+ ResultSetMock rsmTables = new ResultSetMock();
+
+ DatabaseMetaDataMock dbmdm = new DatabaseMetaDataMock();
+ Row[] rows = {
+ new Row(new Object[]{
+ null, // 1) table_cat
+ "public", // 2) table schema
+ "runs", // 3) table name
+ "runid", // 4) column name
+ Integer.valueOf(4), // 5) data type
+ "int4", // 6) type name
+ Integer.valueOf(10), // 7) column size
+ null, // 8) buffer length
+ null, // 9) decimal digits
+ Integer.valueOf(10), // 10) num_prec_radix
+ Integer.valueOf(DatabaseMetaData.columnNoNulls), // 11) nullable
+ null, // 12) remarks
+ null, // 13) default value for the column
+ Integer.valueOf(0), // 14) sql_data_type
+ Integer.valueOf(0), // 15) sql_datetime_sub
+ null, // 16) char_octet_length
+ Integer.valueOf(1), // 17) ordinal_position
+ "NO", // 18) is_nullable
+ null, // 19) scope_catalog
+ null, // 20) scope_schema
+ null, // 21) scope_table
+ null, // 22) source_data_type
+ "NO", // 23) is_autoincrement
+ "NO" // 24) is_generated_column
+ }),
+ new Row(new Object[]{
+ null, // 1) table_cat
+ "public", // 2) table schema
+ "runs", // 3) table name
+ "projname", // 4) column name
+ Integer.valueOf(12), // 5) data type
+ "varchar", // 6) type name
+ Integer.valueOf(80), // 7) column size
+ null, // 8) buffer length
+ null, // 9) decimal digits
+ Integer.valueOf(10), // 10) num_prec_radix
+ Integer.valueOf(DatabaseMetaData.columnNoNulls), // 11) nullable
+ null, // 12) remarks
+ null, // 13) default value for the column
+ Integer.valueOf(0), // 14) sql_data_type
+ Integer.valueOf(0), // 15) sql_datetime_sub
+ null, // 16) char_octet_length
+ Integer.valueOf(2), // 17) ordinal_position
+ "NO", // 18) is_nullable
+ null, // 19) scope_catalog
+ null, // 20) scope_schema
+ null, // 21) scope_table
+ null, // 22) source_data_type
+ "NO", // 23) is_autoincrement
+ "NO" // 24) is_generated_column
+ }),
+ new Row(new Object[]{
+ null, // 1) table_cat
+ "public", // 2) table schema
+ "runs", // 3) table name
+ "version", // 4) column name
+ Integer.valueOf(12), // 5) data type
+ "varchar", // 6) type name
+ Integer.valueOf(10), // 7) column size
+ null, // 8) buffer length
+ null, // 9) decimal digits
+ Integer.valueOf(10), // 10) num_prec_radix
+ Integer.valueOf(DatabaseMetaData.columnNullable), // 11) nullable
+ null, // 12) remarks
+ null, // 13) default value for the column
+ Integer.valueOf(0), // 14) sql_data_type
+ Integer.valueOf(0), // 15) sql_datetime_sub
+ null, // 16) char_octet_length
+ Integer.valueOf(1), // 17) ordinal_position
+ "YES", // 18) is_nullable
+ null, // 19) scope_catalog
+ null, // 20) scope_schema
+ null, // 21) scope_table
+ null, // 22) source_data_type
+ "NO", // 23) is_autoincrement
+ "NO" // 24) is_generated_column
+ })
+ };
+ rsmCols.mock_addRows(rows);
+
+ rows = new Row[] {
+ new Row(new Object[]{
+ null, // TABLE_CAT String => table catalog (may be null)
+ null, // TABLE_SCHEM String => table schema (may be null)
+ "runs", // TABLE_NAME String => table name
+ "TABLE", // TABLE_TYPE String => table type. Typical types are "TABLE", "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
+ "", // REMARKS String => explanatory comment on the table
+ null, // TYPE_CAT String => the types catalog (may be null)
+ null, // TYPE_SCHEM String => the types schema (may be null)
+ null, // TYPE_NAME String => type name (may be null)
+ null, // SELF_REFERENCING_COL_NAME String => name of the designated "identifier" column of a typed table (may be null)
+ null // REF_GENERATION String => specifies how values in SELF_REFERENCING_COL_NAME are created. Values are "SYSTEM", "USER", "DERIVED". (may be null)
+ })
+ };
+ rsmTables.mock_addRows(rows);
+
+ dbmdm.mock_setColRS(null, null, "runs", null, rsmCols);
+ dbmdm.mock_setTableRS(null, null, "runs", null, rsmTables);
+
+ return dbmdm;
+ }
+
+ private String construct_runs_expected() {
+ return "TABLE runs\n"
+ + "+--------+-----------+---------+\n"
+ + "| Column | Type |Modifiers|\n"
+ + "+--------+-----------+---------+\n"
+ + "|runid |int4(10) |NOT NULL |\n"
+ + "|projname|varchar(80)|NOT NULL |\n"
+ + "|version |varchar(10)|NULL |\n"
+ + "+--------+-----------+---------+\n"
+ + "3 row(s) returned.\n";
+ }
+
+ @Test
+ public void testDescribeTable_threeColumns()
+ throws IOException, SQLException
+ {
+ DatabaseMetaDataMock dbmdm = construct_runs_dbmdm();
+ Describe describe = new Describe();
+
+ try (
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8));
+ )
+ {
+ describe.describeTable(pw, dbmdm, "runs");
+ pw.close();
+ baos.close();
+ String actual = baos.toString();
+ String expected = construct_runs_expected();
+
+ assertEquals(expected, actual);
+ }
+ }
+
+ @Test
+ public void testExec() throws IOException, SQLException
+ {
+ final String[] SUCCESSFUL = {
+ "\\d runs", " \\d runs", "\\d runs ", " \\d runs ",
+ "DESCRIBE runs", " DescRIBe runs", "describe runs ", " describe runs "
+ };
+ String expected = construct_runs_expected();
+ for (String stmt : SUCCESSFUL) {
+ String actual = doExec(stmt);
+ assertEquals("doExec(): " + stmt, expected, actual);
+ }
+ }
+
+ public String doExec(String stmt) throws IOException, SQLException
+ {
+ DatabaseMetaDataMock dbmdm = construct_runs_dbmdm();
+ DbDriverMock driver = new DbDriverMock();
+ ConnectionMock cm = new ConnectionMock();
+ cm.mock_setDatabaseMetaData(dbmdm);
+
+ Describe describe = new Describe();
+
+ try (
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8));
+ )
+ {
+ describe.exec(driver, cm, pw, stmt);
+ pw.close();
+ baos.close();
+ String actual = baos.toString();
+
+ return actual;
+ }
+ }
+}