views:

105

answers:

1

Presently, I'm thoroughly dissatisfied by the command-line program /usr/bin/mysql! It does not, e.g., let me leverage:

(a) various Unix tools (like, grep, sed...), and

(b) Unix concepts such as io-redirection, piping.

(Btw, IIRC, a command-line shell for Sybase used to allow piping and sufficiently powerful, Unix-style command-line usage.)

So... I'm wondering, if it's possible to create a shell wrapper on my own for this sucker?

My first version looks like this.

# #!/bin/bash
sqlUser=USER_NAME
sqlPassword=    # The password will be taken from ~/.my.cnf .

# Sql statements specified via stdin.
while read -p 'SQL> ' x
do
  if [ "$x" = "quit" ]; then
    # Quit the loop.
    echo "Goodbye."
    break
  else
    eval "mysql -u$sqlUser -e '$x' "
    echo
  fi
done

Sample usage:

[sd@host:~/tmp]
$ ./mysqlsh
SQL> select * from bankdb.loan;
+---------+---------------+--------+
| loan_no | branch_name   | amount |
+---------+---------------+--------+
| L-11    | Round Hill    |    900 | 
| L-14    | Downtown      |   1500 | 
| L-15    | Perryridge    |   1500 | 
| L-16    | Perryridge    |   1300 | 
| L-17    | Downtown      |   1000 | 
| L-23    | Redwood       |   2000 | 
| L-93    | Mianus        |    500 | 
+---------+---------------+--------+

SQL> quit
Goodbye.
[sd@host:~/tmp]
$
  1. Now, while I could add the piping/redirection feature by saying to myself that... anything preceding the semi-colon ';' in the user input to read() would be the SQL, and anything following the ';' would be the Unix shell constructs to be passed straight to eval() above. But, I'm not sure if this is the greatest way!

  2. Another very serious limitation that would still persist is: There will be no concept of a session... due to a new invocation of /usr/bin/mysql in every iteration of the while-loop. So, what I'd really like to be able to do is: (a) launch one, single instance of /usr/bin/mysql, and (b) somehow wire /usr/bin/mysql's stdin, stdout, stderr streams to my wrapper program's. Now, is this stunt possible? Note that I tried [sd@host:~/tmp] $ mysql -uSD 2>&1 | tee sql.out and it did not work as 'expected'. Meaning, I did not get the familiar mysql interactive messages to my sql.out file, so wondering what's going on here!!

  3. If this is not possible via shell (bash), could this be done via a C-program...? that uses MySQL's C API, say, to open a database connection and then provide a sense of session over this connection?

  4. Could Perl help here?

Many thanks for listening.

A: 

The built-in mysql command-line application absolutely supports piping, I/O redirection, et cetera.

For example, I might execute this command directly at my shell prompt:

$ echo "SELECT things FROM some_table" | mysql some_database | grep excitement > output.txt
VoteyDisciple
Upvoting. Hmm. What I meant to say was: an interactive mysql shell that supports piping, redirection, etc ... so that I get a sense of an "rdbms session" via commands like 'use XYZdb;', start/end transaction, etc. Currently, If I operate from within mysql, I don't get piping/redirection, and if I operate from without (like you suggested above) then the whole thing starts to get a little too long and unwieldy. Which is why I started thinking of having a wrapper somehow. (Thanks, btw, for writing. My reputation is currently not high enough to be able to upvote your answer.)
Harry
Since no one else responded, I guess, I'll go ahead and select yours as the best answer. Also, after having used it mysql for several more hours since your response, I'm more or less coming to terms with it. :-)
Harry