| View previous topic :: View next topic |
| Author |
Message |
MikeM Voice
Joined: 09 Sep 2007 Posts: 2
|
Posted: Sun Sep 09, 2007 10:20 pm Post subject: External Program (mysql) Partyline Interface |
|
|
Hi,
I'm trying to provide a partyline interface to mysql-client, for convenience, and a bit of interest as to the method.
Basically I want to pipe the i/o to and from the external program (mysql), to display results in the dcc partyline.
Not to be confused, I already use a mysql module for code - I want to emulate the entire mysql client by executing it externally.
After a tip from someone, and looking at user's code on another forum topic, I came up with this:
| Code: |
bind dcc n mysql mysql_1
proc mysql_1 {h i a} {
# hack to honor the "must-be-owner" setting:
*dcc:tcl $h $i [list mysql_2 $h $i $a]
}
proc mysql_2 {h i a} {
global dbi
set dbi [open "|mysql -u user --password=pwd db" r+]
fconfigure $dbi -blocking 0 -buffering line
fileevent $dbi readable [list gotline $dbi]
control $i [list mysql_3 $h]
return "Type 'exit' to return to the real world."
}
proc mysql_3 {h i a} {
global dbi
if {$a=="exit"} {
unset a
close $dbi
return 1
} {
puts $dbi $a
flush $dbi
putserv "privmsg empus :(debug) puts $dbi $a"
set a ""
}
append a \n
return 0
}
# EDIT: Added this proc for stupid irc clients that
# are incapable of displaying the tab character (\x09)
# Remove it if you don't need it.
proc putdcc {i a} {::putdcc $i [string map {\t " "} $a]}
proc gotline {dbi} {
if {![eof $dbi]} {
if {[gets $dbi] != ""} {
putserv "privmsg empus :(debug) [gets $dbi]"
#putdcc $i "mysql: [gets $dbi]"
}
}
}
putlog "\[@\] MySQL Interface Loaded."
|
However, it appears as though gotline is not being triggered - for whatever reason. I get nothing back, which begs the question - is mysql receiving anything in the first place?
Something is wrong here, but I'm not quite sure what... any help would be much appreciated.
Cheers,
-Mike |
|
| Back to top |
|
 |
user

Joined: 18 Mar 2003 Posts: 1452 Location: Norway
|
Posted: Mon Sep 10, 2007 2:36 am Post subject: Re: External Program (mysql) Partyline Interface |
|
|
| MikeM wrote: | | Code: | proc gotline {dbi} {
if {![eof $dbi]} {
if {[gets $dbi] != ""} {
putserv "privmsg empus :(debug) [gets $dbi]"
#putdcc $i "mysql: [gets $dbi]"
}
}
} |
|
Try something like this inside the first 'if': | Code: | | while {[gets $dbi line]>-1} {putserv "PRIVMSG empus :(debug) $line"} |
_________________ Have you ever read "The Manual"? |
|
| Back to top |
|
 |
MikeM Voice
Joined: 09 Sep 2007 Posts: 2
|
Posted: Mon Sep 10, 2007 3:07 am Post subject: Re: External Program (mysql) Partyline Interface |
|
|
Doesnt seem to have any effect.
If I put a debug line on the second line of the proc (before first if statement), it enters an endless loop, but never meets the other requirements.
It's as though nothing is coming back from mysql-client (either because the code is wrong, or mysql-client never receives anything in the first place).
[gets $dbi] seems to always return ""
Ideas? Can this even be done? |
|
| Back to top |
|
 |
user

Joined: 18 Mar 2003 Posts: 1452 Location: Norway
|
Posted: Mon Sep 10, 2007 9:06 am Post subject: |
|
|
I added some error handling...try this: | Code: | bind dcc n mysql mysql_init
proc mysql_init {h i a} {
*dcc:tcl $h $i [list mysql_init2 $h $i $a]
}
proc mysql_init2 {h i a} {
if {[catch {open "|mysql -u user --password=pwd db" r+} dbi]} {
return "Open error: $dbi"
} {
fconfigure $dbi -blocking 0 -buffering line
fileevent $dbi readable [list mysql_out $dbi $i]
control $i [list mysql_in $dbi]
return "Type 'exit' to return to the real world."
}
}
proc mysql_in {dbi i a} {
if {$a=="exit"||$a==""} {
close $dbi
return 1
} elseif {[catch {puts $dbi $a; flush $dbi} err]} {
putdcc $i "Write error: $err"
close $dbi
return 1
} {
return 0
}
}
proc mysql_out {dbi i} {
if {[eof $dbi]} {
close $dbi
putdcc $i "EOF."
control $i {}
} elseif {[catch {
while {![fblocked $dbi]&&[gets $dbi line]>-1} {
putdcc $i $line
}
} err]} {
close $dbi
putdcc $i "Read error: $err"
control $i {}
}
} | (not tested) _________________ Have you ever read "The Manual"? |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Mon Sep 10, 2007 10:52 am Post subject: |
|
|
There's a couple of argument mismatches in the script.
mysql_in expects three arguments, yet while setting up the fileevent controller, you only define two. Also, the 'control' event is set up to pass one additional argument, which is not supported by mysql_out. Sort those out, and my guess is it'll work like a charm.
Edit:
I would also recommend implementing the bgerror error reporting mechanism when trying to debug scripts using tcl's native event-handler, as errors here tend to go unnoticed due to the very nature of the handler. _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
user

Joined: 18 Mar 2003 Posts: 1452 Location: Norway
|
Posted: Mon Sep 10, 2007 1:56 pm Post subject: |
|
|
| nml375 wrote: | mysql_in expects three arguments, yet while setting up the fileevent controller, you only define two. Also, the 'control' event is set up to pass one additional argument, which is not supported by mysql_out. Sort those out, and my guess is it'll work like a charm.
|
The fileevent invokes mysql_out, and dcc input is handled by mysql_in, so it seems about right to me (but I'm pretty tired right now, so I might have missed/messed up something ) Having a bgerror proc is a good idea though, but getting the output to the user under 'control' is a bit messy... _________________ Have you ever read "The Manual"? |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Mon Sep 10, 2007 2:48 pm Post subject: |
|
|
Or my head is messed up enough already (with a blocked nose and nice cold)
Would have to agree you've got the arguments right..
As for bgerror, I would just dump the info to the logging facility. Usually should'nt be anything interresting there for your average user, but rather developer and/or botadmin. _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
|