I am using data adapters from C#, and it would be great if there is a way to print the statements executed by data adapters for debug purpose.
I can print the statements generated by OleDbCommandBuilder.GetUpdateCommand/GetDeleteCommand/GetInsertCommand, but those don't contain the actual values.
I'd like to print statements executed by 'DataAdapter.Update()', with all the values filled in.
Is that possible?
Related
If I am writing tabular output to a file as CSV, what advantage does loading an extra module
Text::CSV
and converting my data to an object get me over a basic loop and string manipulation? I have seen a couple of answers that suggest doing this: How can I get column names and row data in order with DBI in Perl and How do I create a CSV file using Perl.
Loading up an entire module seems like overkill and significant overhead for something I can write in four lines of Perl (ignoring data retrieval, etc.):
my $rptText = join(',', map { qq/"$_"/ } #head) . "\n";
foreach my $person ( #$data ) {
$rptText .= join(',', map { qq/"$person->{$_}"/ } #head) . "\n";
}
So what does loading
Text::CSV
get me over the above code?
For simple trivial data (which, admittedly, is quite common) there's no advantage. You can join , print, and go on your merry way. For a quick throw-away script that's likely all you need (and faster, too, if you'd need to consult the Text::CSV documentation).
The advantages start when your data is non-trivial.
Does it contain commas?
Does it contain double-quotes?
Does it contain newlines?
Does it contain non-ASCII characters?
Is there a distinction between undef (no value) and '' (empty string)?
Might you need to use a different separator (or let the user specify it)?
For production code, the standard pro-module advice applies:
Reuse instead of reinvent (particularly if you'll be generating more than one CSV file)
It keeps your code cleaner (more consistent and with better separation of concerns)
CPAN modules are often faster (better optimized), more robust (edge-case handling), and have a cleaner API than in-house solutions.
The overhead of loading a module is almost certainly a non-issue.
Your CSV won't be valid if $person->{col1} contains ". Also, all columns will be wrapped in double quotes, which might not be desired (e.g. numbers). You'll also get "" for undefined values, which might not work if you plan to load the CSV into a database that makes a distinction between null and ''.
I have a Perl module with a template (for processing by the Template module) stored between the __DATA__ and __END__ keywords at the end of the file. When attempting to generate a file using the template, the resulting file comes out empty with no warnings or errors output. After debugging, I found that the DATA filehandle is actually empty before it is passed to the Template module.
A previous version of this module is able to correctly read the template from DATA, but none of the changes that I have made should be affecting this part of the code. These changes consist of logic changes within completely separate functions and adding the following use statements to the module:
use DBI;
use DBI::Const::GetInfoType;
use Switch;
I have tried adding write permissions on the perl module (it was originally read-only) and removing the __END__ keyword as I found that wasn't necessary. Unfortunately the DATA filehandle still appears empty.
What kind of problems could cause the DATA filehandle to be empty, and do any of these problems apply to my situation? I am using perl v5.12.5.
The reason that the DATA filehandle is empty in this case is down to the use of the Switch module. This module works by using a source filter which is clobbering the DATA filehandle during the course of its processing.
Alternatives include using if-elsif-else or using the given-when construct, although this is an experimental feature so it may not behave the same in later versions of Perl.
EDIT: Here is a simple reproducer for the issue described above:
# use Switch;
while(<DATA>) {
print($_);
}
__DATA__
One line of data
Second line of data
Without the "use Switch", you'll see the lines printed out, but with it nothing is printed.
I don't know perl at all, but I need to change an exitsting program to give a clearer debug output.
This is the statement:
print $lfh "$ts\t$tid\t$msg\n";
where $msg will be created by joining the arguments of the function like this:
my $msg = join( "\t", #_ );
Somewhere in $msg I would like to add one of the command line arguments the user has supplied when calling the program. Is that risk for an exploit if printed to stdout?
Note also that $lfh will be taken from an environment variable (set by the script itself earlier on) if it is to write to a file, like this:
open my $lfh, ">>", $ENV{GL_LOGFILE}
The info I could find on perl security says nothing about the print statement, so maybe I'm just completely paranoid, but better safe than sorry...
You can pass arbitrary data to print, and it won't break. However:
printing to a file handle may go through various IO layers like encodings. Not all data may be valid for these layers. E.g. encoding layers will either use a substitution character or terminate the script when handed invalid data.
Perl's print doesn't care about control characters like NULs, backspaces, or carriage returns and just passes them through. Depending on how the output is viewed, it might look jumbled or could break the viewing application. Example: User input is equal to the string "\rHAHA". When you print "something$userinput", you might see HAHAthing when displayed on the console, because the carriage returns places the cursor in the 1st column. If the user input contains newlines, your output records could be broken up, e.g. "foo${userinput}bar" might become the two lines foo and bar.
If the input is condidential information, the output will be confidential as well, so you should make sure that the output can't be viewed by anyone. E.g. displaying the output including debug information on a web page could allow attackers to obtain more information about your system.
I am wondering why the perl creators chose an unusual syntax for printing to a filehandle:
print filehandle list
with no comma after filehandle. I see that it's to distinguish between "print list" and "print filehandle list", but why was the ad-hoc syntax preferred over creating two functions - one to print to stdout and one to print to given filehandle?
In my searches, I came across the explanation that this is an indirect object syntax, but didn't the print function exist in perl 4 and before, whereas the object-oriented features came into perl relatively late? Is anyone familiar with the history of print in perl?
Since the comma is already used as the list constructor, you can't use it to separate semantically different arguments to print.
open my $fh, ...;
print $fh, $foo, $bar
would just look like you were trying to print the values of 3 variables. There's no way for the parser, which operates at compile time, to tell that $fh is going to refer to a file handle at run time. So you need a different character to syntactically (not semantically) distinguish between the optional file handle and the values to actually print to that file handle.
At this point, it's no more work for the parser to recognize that the first argument is separated from the second argument by blank space than it would be if it were separated by any other character.
If Perl had used the comma to make print look more like a function, the filehandle would always have to be included if you are including anything to print besides $_. That is the way functions work: If you pass in a second parameter, the first parameter must also be included. There isn't one function I can think of in Perl where the first parameter is optional when the second parameter exists. Take a look at split. It can be written using zero to four parameters. However, if you want to specify a <limit>, you have to specify the first three parameters too.
If you look at other languages, they all include two different ways ways to print: One if you want STDOUT, and another if you're printing to something besides STDOUT. Thus, Python has both print and write. C has both printf and fprintf. However, Perl can do this with just a single statement.
Let's look at the print statement a bit more closely -- thinking back to 1987 when Perl was first written.
You can think of the print syntax as really being:
print <filehandle> <list_to_print>
To print to OUTFILE, you would say:
To print to this file, you would say:
print OUTFILE "This is being printed to myfile.txt\n";
The syntax is almost English like (PRINT to OUTFILE the string "This is being printed to myfile.txt\n"
You can also do the same with thing with STDOUT:
print STDOUT "This is being printed to your console";
print STDOUT " unless you redirected the output.\n";
As a shortcut, if the filehandle was not given, it would print to STDOUT or whatever filehandle the select was set to.
print "This is being printed to your console";
print " unless you redirected the output.\n";
select OUTFILE;
print "This is being printed to whatever the filehandle OUTFILE is pointing to\n";
Now, we see the thinking behind this syntax.
Imagine I have a program that normally prints to the console. However, my boss now wants some of that output printed to various files when required instead of STDOUT. In Perl, I could easily add a few select statements, and my problems will be solved. In Python, Java, or C, I would have to modify each of my print statements, and either have some logic to use a file write to STDOUT (which may involve some conniptions in file opening and dupping to STDOUT.
Remember that Perl wasn't written to be a full fledge language. It was written to do the quick and dirty job of parsing text files more easily and flexibly than awk did. Over the years, people used it because of its flexibility and new concepts were added on top of the old ones. For example, before Perl 5, there was no such things as references which meant there was no such thing as object oriented programming. If we, back in the days of Perl 3 or Perl 4 needed something more complex than the simple list, hash, scalar variable, we had to munge it ourselves. It's not like complex data structures were unheard of. C had struct since its initial beginnings. Heck, even Pascal had the concept with records back in 1969 when people thought bellbottoms were cool. (We plead insanity. We were all on drugs.) However, since neither Bourne shell nor awk had complex data structures, so why would Perl need them?
Answer to "why" is probably subjective and something close to "Larry liked it".
Do note however, that indirect object notation is not a feature of print, but a general notation that can be used with any object or class and method. For example with LWP::UserAgent.
use strict;
use warnings;
use LWP::UserAgent;
my $ua = new LWP::UserAgent;
my $response = get $ua "http://www.google.com";
my $response_content = decoded_content $response;
print $response_content;
Any time you write method object, it means exactly the same as object->method. Note also that parser seems to only reliably work as long as you don't nest such notations or do not use complex expressions to get object, so unless you want to have lots of fun with brackets and quoting, I'd recommend against using it anywhere except common cases of print, close and rest of IO methods.
Why not? it's concise and it works, in perl's DWIM spirit.
Most likely it's that way because Larry Wall liked it that way.
I have encountered a weird situation while updating/upgrading some legacy code.
I have a variable which contains HTML. Before I can output it, it has to be filled with lots of data. In essence, I have the following:
for my $line (#lines) {
$output = loadstuff($line, $output);
}
Inside of loadstuff(), there is the following
sub loadstuff {
my ($line, $output) = #_;
# here the process is simplified for better understanding.
my $stuff = getOtherStuff($line);
my $result = $output.$stuff;
return $result;
}
This function builds a page which consists of different areas. All area is loaded up independently, that's why there is a for-loop.
Trouble starts right about here. When I load the page from ground up (click on a link, Perl executes and delivers HTML), everything is loaded fine. Whenever I load a second page via AJAX for comparison, that HTML has broken encoding.
I tracked down the problem to this line my $result = $output.$stuff. Before the concatenation, $output and $stuff are fine. But afterward, the encoding in $result is messed up.
Does somebody have a clue why concatenation messes up my encoding? While we are on the subject, why does it only happen when the call is done via AJAX?
Edit 1
The Perl and the AJAX call both execute the very same functions for building up a page. So, whenever I fix it for AJAX, it is broken for freshly reloaded pages. It really seems to happen only if AJAX starts the call.
The only difference in this particular case is that the current values for the page are compared with an older one (it is a backup/restore function). From here, everything is the same. The encoding in the variables (as far as I can tell) are ok. I even tried the Encode functions only on the values loaded from AJAX, but to no avail. The files themselves seem to be utf8 according to "Kate".
Besides that, I have a another function with the same behavior which uses the EXACT same functions, values and files. When the call is started from Perl/Apache, the encoding is ok. Via AJAX, again, it is messed up.
I have been examinating the AJAX Request (jQuery) and could not find anything odd. The encoding seems to be utf8 too.
Perl has a “utf8” flag for every scalar value, which may be “on” or “off”. “On” state of the flag tells perl to treat the value as a string of Unicode characters.
If you take a string with utf8 flag off and concatenate it with a string that has utf8 flag on, perl converts the first one to Unicode. This is the usual source of problems.
You need to either convert both variables to bytes with Encode::encode() or to perl's internal format with Encode::decode() before concatenation.
See perldoc Encode.
Expanding on the previous answer, here's a little more information that I found useful when I started messing with character encodings in Perl.
This is an excellent introduction to Unicode in perl: http://perldoc.perl.org/perluniintro.html. The section "Perl's Unicode Model" is particularly relevant to the issue you're seeing.
A good rule to use in Perl is to decode data to Perl characters on it's way in and encode it into bytes on it's way out. You can do this explicitly using Encode::encode and Encode::decode. If you're reading from/writing to a file handle you can specify an encoding on the filehandle by using binmode and setting layer: perldoc -f binmode
You can tell which of the strings in your example has been decoded into Perl characters using Encode::is_utf8:
use Encode qw( is_utf8 );
print is_utf8($stuff) ? 'characters' : 'bytes';
A colleague of mine found the answer to this problem. It really had something to do with the fact that AJAX started the call.
The file structure is as follows:
1 Handler, accessed by Apache
1 Handler, accessed by Apache but who only contains AJAX responders. We call it the AJAX-Handler
1 package, which contains functions relevant for the entire software, who access yet other packages from our own Framework
Inside of the AJAX-Handler, we print the result as such
sub handler {
my $r = shift;
# processing output
$r->print($output);
return Apache2::Const::OK;
}
Now, when I replace $r->print($output); by print($output);, the problem disappears! I know that this is not the recommended way to print stuff in mod_perl, but this seems to work.
Still, any ideas how to do this the proper way are welcome.