CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
send to a db and then to a script

 



demon01
Novice

Mar 24, 2010, 10:23 PM

Post #1 of 22 (4937 views)
send to a db and then to a script Can't Post

I need to have a script that sends info from a form to a db and then sends info to another script. It would be great if anyone could help me even if it is just being pointed in the right direction. I don't need the exact code.


7stud
Enthusiast

Mar 25, 2010, 4:22 AM

Post #2 of 22 (4935 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post

cgi script:


Code
#!/usr/bin/env perl 
use strict;
use warnings;
use 5.010;

use CGI ;

use CGI::Carp qw{fatalsToBrowser warningsToBrowser};
#now *fatal* errors will automatically appear in the browser,
#which is useful for debugging

use DBI;


my $query = new CGI; #for retrieving form data
my $college = $query->param("college");

my $data_source = 'DBI:mysql:test';
my $user = 'root';
my $pass = '';

#dbh stands for 'db handle'
my $dbh = DBI->connect(
$data_source,
$user,
$pass,
{RaiseError => 1, AutoCommit => 0}, #1=>true, 0=>false
);

#sth stands for 'statement handle'
my $sth = $dbh->prepare(
"INSERT INTO college_counts(college, count) VALUES (?,?)"
);

$sth->execute($college, 1);
$dbh->commit(); #Because AutoCommit is false above

$dbh->disconnect();


#Open a pipe to another script. Anything you
#write to the filehandle will go to the other script's STDIN.

open my $PIPE_WRITER, '| ../helper_programs/myprog.pl'
or die "Couldn't open pipe to myprog.pl: $!";

say $PIPE_WRITER $college;
close $PIPE_WRITER;


my $query = new CGI; #for output back to browser

print $query->header;
warningsToBrowser(1);
#Inserts warnings as html comments in the html source.
#Can only be called after printing a header.

print
$query->start_html,
$query->div("Your college choice, $college, was entered into our db."),
$query->div("$college was also sent to another script"),
$query->end_html
;


Another script:


Code
#!/usr/bin/env perl 

use strict;
use warnings;
use 5.010;

#On my server, the relative path from cgi-bin to here is:
#../helper_programs/myprog.pl
#The path will most likely be different on your server.


#Open a file and write the received data to the file to prove
#that this program received the data:

open my $OUTFILE, '>', '../writables/data1.txt'
or die "Couldn't open file data1.txt: $!";

while (<STDIN>) { #this program expects line oriented input, i.e. lines that
#end with "\n". When the other program closes the pipe
#this while() loop gets an eof signal

print $OUTFILE $_;

#do whatever needs to be done with the data
}

close $OUTFILE;


Make sure both scripts have read+execute permissions, and proper shebang lines at the top.


(This post was edited by 7stud on Mar 25, 2010, 5:07 AM)


demon01
Novice

Mar 25, 2010, 5:42 AM

Post #3 of 22 (4911 views)
Re: [7stud] send to a db and then to a script [In reply to] Can't Post

The dbi part would be what ever I already have that the first script does.

The pipe will send the perameters as '../cgi-bin/myprog.pl?name=Dave&lastn=Jones' to the second script.

The last part is only any output I want from this script, I don't need that if I have no output, just writing to the database, correct?

I appreciate your help.


demon01
Novice

Mar 25, 2010, 6:25 AM

Post #4 of 22 (4907 views)
Re: [7stud] send to a db and then to a script [In reply to] Can't Post

'say' prints to the script in '$PIPE_WRITE' and '$college' is the data I want to pass to the second script, correct?

First time I've seen that commend. Just goes to show just how illiterate I am, it's very upsetting.

Thanks again.


(This post was edited by demon01 on Mar 25, 2010, 6:29 AM)


demon01
Novice

Mar 25, 2010, 10:01 PM

Post #5 of 22 (4885 views)
Re: [7stud] send to a db and then to a script [In reply to] Can't Post

I tried the PIPE routine but I get this warning: "No such file or directory at survey_REC.pl line 226."

Both the script that is running this code and the script that is receiving the PIPE are in the same directory: http://www.myvipuniversity.com/cgi-bin/surveys/serve_survey_indv.pl

What would be the path in the routine?


FishMonger
Veteran / Moderator

Mar 26, 2010, 5:34 AM

Post #6 of 22 (4877 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post

Are you actually trying to use the url when opening the pipe? If so, then that's the problem.

You need to use a relative or absolute system path, not a url.


demon01
Novice

Mar 26, 2010, 7:20 AM

Post #7 of 22 (4873 views)
Re: [FishMonger] send to a db and then to a script [In reply to] Can't Post

I am trying to use the relative path, I showed the url to show where the script was.

I was trying to see if I was getting the relative path wrong, I was using

Code
serve_survey_indv.pl

both scripts reside in the same cgi-bin folder so the relative path would be just the script name, correct. That is what I am starting to doubt.

If both scripts reside in the url folder I showed above, wouldn't the relative path be just the script name?

I've tried all these:
../cgi-bin/surveys/"script"
../surveys/"script"
../"script"
"script"

all the above give me the same error message.

Here's the code

Code
open (SURVEY, "$path|")  
or die "Couldn't open pipe to $path : $!";

print SURVEY "$survey_name , $x";
close (SURVEY);


Perl Version 5.08

Thanks.


(This post was edited by demon01 on Mar 26, 2010, 7:24 AM)


demon01
Novice

Mar 26, 2010, 7:24 AM

Post #8 of 22 (4872 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post

here's the error message"

Code
Couldn't open pipe to /serve_survey_indv.pl : No such file or directory at survey_REC.pl line 226.



FishMonger
Veteran / Moderator

Mar 26, 2010, 9:06 AM

Post #9 of 22 (4864 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post

Use the 3 arg form of open and a lexical var for the handle.

Try this test.

script1.pl

Code
#!/usr/bin/perl 

use strict;
use warnings;
use CGI;
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
use 5.010;

my $cgi = CGI->new;
my $str = "testing pipe from script1 to script2";

my $script2 = 'script2.pl';
open my $pipe, '|-', "$script2 $str"
or die "Couldn't open pipe to '$script2' : $!";

# the result of this next line surprised me,
# which is why I also passed the string in the open call
say $pipe $str;

close $pipe or die "can't close pipe $!";

print $cgi->header;
warningsToBrowser(1);

print $cgi->start_html,
$cgi->h1("pipe to $script2 was successful");


script12.pl

Code
#!/usr/bin/perl 

use strict;
use warnings;
use 5.010;

# adjust the path as needed
my $outfile = '/temp/pipetest.txt';

open my $tmpfile, '>>', $outfile
or die "Can't open '$outfile' $!";

say $tmpfile "PID:$$ \t \@ARGV: @ARGV";

while ( <STDIN> ) {
say $tmpfile "PID:$$ \t STDIN: $_";
}

close $tmpfile or die "Can't close '$outfile' $!";



7stud
Enthusiast

Mar 26, 2010, 10:06 AM

Post #10 of 22 (4859 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post

1) If you want anyone with a pc to be able to execute a script then put it in the cgi-bin directory. If you don't, then you better locate it in a non publicly accessible directory.

2)

Quote
If both scripts reside in the url folder I showed above, wouldn't the relative path be just the script name?


You need to learn some basic terminology. There are urls, and there are paths, and there are folders/directories, but there is no such thing as a url folder. If you do not use common terminology, then no one will have any idea what the hell you are talking about.

3)I've tried all these:

../cgi-bin/surveys/"script"
../surveys/"script"
../"script"
"script"

And what made you decide to put quotes around "script"?

4) If you want to execute things on a server, then it would help if you knew what the 'root directory' was on your server. Then you can construct absolute paths from the root directory. You can also fiddle around with relative paths, but it is nice to be able to fall back on an absolute path when you can't figure out the relative path.

5) If you want help on figuring out the paths, start off by posting what server you are using.


(This post was edited by 7stud on Mar 26, 2010, 10:07 AM)


7stud
Enthusiast

Mar 26, 2010, 10:19 AM

Post #11 of 22 (4854 views)
Re: [FishMonger] send to a db and then to a script [In reply to] Can't Post


Quote
# the result of this next line surprised me,
# which is why I also passed the string in the open call
say $pipe $str;

Is the parent or the child executing that statement? There is a difference between a 'pipe open' and a 'fork open'. You haven't handled the 'fork open' correctly. Even if you had, simpler is better, and a pipe open is all that is called for in the op's situation. I did overlook a problem with the 'pipe open' that needs to be handled--the case when the script being opened doesn't exist, which is particularly relevant here because the op's script doesn't actually exist due to path problems.

According to perlipc, when the script specified in the the 'pipe open' doesn't exist, the 'pipe open' will still succeed. Subsequently writing to the pipe will cause the cgi script to blow up when it receives a PIPE signal--which is sent to the cgi script when it tries to write to a pipe that has been closed. Closed pipe? But the 'pipe open' succeeded?! Yeah, but according to perlipc the fact that the 'pipe open' succeeded doesn't actually mean the pipe was ever opened. Confusing. The cgi script will only discover that the pipe wasn't opened successfully when the cgi script tries to write to the pipe.

Also of note is that the PIPE signal may only get sent to the cgi script after the cgi script calls close() on the pipe. Calling close() on the pipe causes the output buffer to be flushed, which then actually writes the output to the pipe.

To protect the cgi script from terminating due to a PIPE signal, you should add the following before the 'pipe open':


Code
$SIG{PIPE} = 'IGNORE';


However, I suspect that this is all beyond the op's comprehension.


(This post was edited by 7stud on Mar 26, 2010, 11:07 AM)


FishMonger
Veteran / Moderator

Mar 26, 2010, 11:11 AM

Post #12 of 22 (4836 views)
Re: [7stud] send to a db and then to a script [In reply to] Can't Post

Initially I did the testing on my Windows box and I was chalking up the failure of say $pipe $str; as a Windows oddity.

I ran some additional tests using the 2 arg form and included the
$SIG{PIPE} = 'IGNORE'; but still had the same results.

I then moved the testing to my linux box (with the same setup) and ran the exact same scripts. Now all I'm getting is:

Quote
Couldn't open pipe to 'script2.pl' : No such file or directory


Odd

I might do some additional testing when I have more time, but I agree that this is beyond the op's current level of understanding.


7stud
Enthusiast

Mar 26, 2010, 4:03 PM

Post #13 of 22 (4832 views)
Re: [FishMonger] send to a db and then to a script [In reply to] Can't Post

Ah, I see what you did now. You did do a 'pipe open':


Quote
perlopen

For three or more arguments if MODE is '|-' , the filename is interpreted as a command to which output is to be piped, and if MODE is '-|' , the filename is interpreted as a command which pipes output to us. In the 2-arguments (and 1-argument) form one should replace dash ('-' ) with the command.


I've never seen a pipe open written using that format. When I see '|-', I associate that with a 'fork open'--as described in perlipc section Safe Pipe Opens. In any case, either format for a 'pipe open' works for me in the script I posted (on unix like mac osx 10.4.11).

If you were attempting to pass the data to the other program as a command line argument, then according to perlopen you can do that using the 4-arg open():


Code
open my $PIPE_WRITER, '|-', '../helper_programs/myprog.pl', $college 
or die "Couldn't open pipe to myprog.pl: $!";


and then in the other program...


Code
my $received_data = shift @ARGV;



(This post was edited by 7stud on Mar 27, 2010, 1:26 AM)


demon01
Novice

Mar 26, 2010, 9:28 PM

Post #14 of 22 (4818 views)
Re: [7stud] send to a db and then to a script [In reply to] Can't Post

Sorry about the terminology.

The absolute path is: /www/cgi-bin/surveys/

(I was using "script" to stand for the actual script for purposes of this thread.)

both scripts reside in the 'surveys' directory in the cgi-bin.
The first script is 'survey_REC.pl' and it opens a pipe to script 2; serve_survey_indv.pl and is supposed to pass two arguments to script 2; $survey_name and $x. Script 2 should take the two arguments and execute, which should display a form containing the two arguments.

I apologize for my lack of terminology. This is as best as I can explain it as I am still learning and, as is evident, will for a long time.


7stud
Enthusiast

Mar 27, 2010, 2:51 AM

Post #15 of 22 (4811 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post


Quote
5) If you want help on figuring out the paths, start off by posting what server you are using.


Fail.


FishMonger
Veteran / Moderator

Mar 27, 2010, 5:13 AM

Post #16 of 22 (4808 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post


Quote
Script 2 should take the two arguments and execute, which should display a form containing the two arguments.


Why didn't you tell us that before?

Either do a redirect to script2 or convert script2 to a module and load it in script1 via a use statement, then pass the 2 parameters to a sub that outputs the form.


7stud
Enthusiast

Mar 28, 2010, 2:37 AM

Post #17 of 22 (4797 views)
Re: [FishMonger] send to a db and then to a script [In reply to] Can't Post

Why not just call script2 directly--after all it's the script that is going to send the response back to the browser? script2 can then call script1 like discussed.


(This post was edited by 7stud on Mar 28, 2010, 2:37 AM)


FishMonger
Veteran / Moderator

Mar 28, 2010, 7:09 AM

Post #18 of 22 (4792 views)
Re: [7stud] send to a db and then to a script [In reply to] Can't Post

OTOH, why not just combine the 2 scripts?

Unless there's a lot more going on than what we've been lead to believe, I don't see any reason to split this across multiple scripts.


demon01
Novice

Mar 30, 2010, 1:29 PM

Post #19 of 22 (4786 views)
Re: [FishMonger] send to a db and then to a script [In reply to] Can't Post

I was hoping not to combine the scripts since they are both rather long but I think combining the the two is the answer as you point out, FishMonger.

The scripts are long because they handle several options as well as write to a couple of dbs. Both scripts search a db, display info and then store responses into other dbs. So they get long.

The process happens between the two scripts back and forth as it collects information required to construct a survey. It is similar to Survey Monkey but more specific to our site and a bit narrower in scope.

My next mission is to create an API.


FishMonger
Veteran / Moderator

Mar 30, 2010, 1:56 PM

Post #20 of 22 (4784 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post

The better solution would probably be to convert script2 onto a proper module and load it via a use statement.


demon01
Novice

Mar 30, 2010, 3:01 PM

Post #21 of 22 (4781 views)
Re: [FishMonger] send to a db and then to a script [In reply to] Can't Post

does the module need to be on the server, like the dbi or cgi module?

Or is it like a lib file?


FishMonger
Veteran / Moderator

Mar 30, 2010, 4:32 PM

Post #22 of 22 (4777 views)
Re: [demon01] send to a db and then to a script [In reply to] Can't Post


In Reply To
does the module need to be on the server, like the dbi or cgi module?

Or is it like a lib file?

Yes, a module as well as a lib file needs to be on the server. The main difference between a lib file and a module is that the module uses the 'package' keyword which creates a new namespace.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives