r20434 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r20433‎ | r20434 | r20435 >
Date:03:14, 14 March 2007
Author:river
Status:old
Tags:
Comment:
nicer pager
add readme
allow multi-line sql commands (detect ; output string to terminate)
Modified paths:
  • /trunk/skirmish/README (added) (history)
  • /trunk/skirmish/skirmish.cc (modified) (history)
  • /trunk/skirmish/terminal.cc (modified) (history)
  • /trunk/skirmish/terminal.h (modified) (history)

Diff [purge]

Index: trunk/skirmish/README
@@ -0,0 +1,17 @@
 2+ Skirmish
 3+ ========
 4+
 5+Skirmish is a command-line SQL client with support for several DBMSs:
 6+
 7+ * MySQL
 8+ * PostgreSQL
 9+ * Oracle
 10+ * MaxDB
 11+ * SQLite
 12+ * Any other ODBC-compliant database
 13+
 14+The client connects to the database and executes SQL command in a similar
 15+manner to the database's native client. Multiple connections can be opened
 16+and used from within a single client instance.
 17+
 18+For more information, see the manual page skirmish(1).
Index: trunk/skirmish/terminal.cc
@@ -1,9 +1,11 @@
22 #include <stdio.h>
 3+#include <unistd.h>
34 #include <readline/readline.h>
45 #include <readline/history.h>
56
67 #include <cstdlib>
78 #include <iostream>
 9+#include <sstream>
810
911 #include <sys/types.h>
1012 #include <sys/ioctl.h>
@@ -13,11 +15,19 @@
1416
1517 terminal::terminal(void)
1618 : rows_output(0)
 19+ , rows(0)
 20+ , cols(0)
1721 {
18 - struct winsize wz;
19 - ioctl(0, TIOCGWINSZ, &wz);
20 - rows = wz.ws_row;
21 - cols = wz.ws_col;
 22+ if (isatty(STDOUT_FILENO)) {
 23+ struct winsize wz;
 24+ ioctl(STDOUT_FILENO, TIOCGWINSZ, &wz);
 25+ rows = wz.ws_row;
 26+ cols = wz.ws_col;
 27+ }
 28+
 29+ tcgetattr(0, &norm);
 30+ std::memcpy(&raw, &norm, sizeof(norm));
 31+ cfmakeraw(&raw);
2232 }
2333
2434 terminal::~terminal(void)
@@ -88,12 +98,15 @@
8999 return;
90100 }
91101
92 - std::string rest = line;
93 - while (rest.size() > cols) {
94 - really_put_line(rest.substr(0, cols));
95 - rest = rest.substr(cols);
 102+ std::istringstream strm(line);
 103+ std::string rest;
 104+ while (std::getline(strm, rest)) {
 105+ while (rest.size() > cols) {
 106+ really_put_line(rest.substr(0, cols));
 107+ rest = rest.substr(cols);
 108+ }
 109+ really_put_line(rest);
96110 }
97 - really_put_line(rest);
98111 }
99112
100113 void
@@ -101,10 +114,39 @@
102115 {
103116 if (rows - 1 == rows_output) {
104117 rows_output = 0;
105 - std::cout << "-- More --";
106 - std::string dummy;
107 - std::getline(std::cin, dummy);
 118+ std::cout << "-- More --" << std::flush;
 119+ char c;
 120+ if (!rawread(c))
 121+ return;
 122+ switch (c) {
 123+ case ' ':
 124+ rows_output = 0;
 125+ break;
 126+ default:
 127+ case '\n':
 128+ rows_output = rows - 2;
 129+ break;
 130+ }
 131+ std::cout << '\r';
108132 }
109133 std::cout << line << '\n';
110134 ++rows_output;
111135 }
 136+
 137+void
 138+terminal::reset_pager(void)
 139+{
 140+ rows_output = 0;
 141+}
 142+
 143+bool
 144+terminal::rawread(char &c)
 145+{
 146+ tcsetattr(0, TCSANOW, &raw);
 147+ if (read(0, &c, 1) < 1) {
 148+ tcsetattr(0, TCSANOW, &norm);
 149+ return false;
 150+ }
 151+ tcsetattr(0, TCSANOW, &norm);
 152+ return true;
 153+}
Index: trunk/skirmish/terminal.h
@@ -4,6 +4,8 @@
55 #include <string>
66 #include <map>
77
 8+#include <termio.h>
 9+
810 struct terminal {
911 terminal();
1012 ~terminal();
@@ -11,6 +13,8 @@
1214 bool readline(std::string &, std::string const &);
1315 void set_prompt_variable(std::string const &var, std::string const &value);
1416 void putline(std::string const &line);
 17+ void reset_pager(void);
 18+ bool rawread(char &c);
1519
1620 private:
1721 std::string form_prompt(std::string const &);
@@ -19,6 +23,7 @@
2024 std::map<std::string, std::string> promptvars;
2125 int rows, cols;
2226 int rows_output;
 27+ struct termios norm, raw;
2328 };
2429
2530 #endif
Index: trunk/skirmish/skirmish.cc
@@ -12,6 +12,7 @@
1313 static db::connectionptr open_connection(std::string const &);
1414 static void show_connection();
1515 static void handle_internal(std::string const &);
 16+static bool read_input_line(std::string &, std::string const &);
1617
1718 static void add_connection(std::string const &);
1819 static void list_connections(std::string const &);
@@ -82,6 +83,7 @@
8384 db::connectionptr conn;
8485 std::string input;
8586 for (;;) {
 87+ term.reset_pager();
8688 std::string cnrs;
8789 if (cnr == -1) {
8890 term.set_prompt_variable("desc", "not connected");
@@ -91,7 +93,7 @@
9294 term.set_prompt_variable("desc", conns[cnr]->desc);
9395 }
9496
95 - if (!term.readline(input, prompt))
 97+ if (!read_input_line(input, prompt))
9698 break;
9799
98100 if (input.empty())
@@ -152,7 +154,7 @@
153155 }
154156
155157 for (int row = 0; row < data.size(); ++row) {
156 - std::stringstream output;
 158+ std::ostringstream output;
157159
158160 for (int col = 0; col < ncols; ++col) {
159161 output << ' ' << std::setw(sizes[col]) << std::left << data[row][col];
@@ -178,7 +180,7 @@
179181 }
180182
181183 if (nrows)
182 - term.putline(str(boost::format("\nOK (%d rows).\n") % nrows));
 184+ term.putline(str(boost::format("\nOK (%d rows).") % nrows));
183185 }
184186 }
185187
@@ -410,3 +412,41 @@
411413 else
412414 prompt = arg;
413415 }
 416+
 417+static bool
 418+read_input_line(std::string &input, std::string const &prompt)
 419+{
 420+ std::string ti, rp = prompt;
 421+ bool instr = false;
 422+
 423+ input = "";
 424+ for (;;) {
 425+ if (!term.readline(ti, rp))
 426+ return false;
 427+
 428+ if (!ti.empty() && input.empty() && ti[0] == '\\') {
 429+ input = ti;
 430+ return true;
 431+ }
 432+
 433+ for (int i = 0; i < ti.size(); ++i) {
 434+ switch (ti[i]) {
 435+ case '\'':
 436+ instr = !instr;
 437+ break;
 438+ default:
 439+ ;
 440+ }
 441+ }
 442+
 443+ if (!instr && ti[ti.size() - 1] == ';') {
 444+ ti.resize(ti.size() - 1);
 445+ input += ti;
 446+ return true;
 447+ }
 448+
 449+ input += ti + '\n';
 450+ rp = "... ";
 451+ }
 452+ return true;
 453+}