not able to give filename through a variable in XML::Excel - perl

Not sure if there is any other way or something, but when i pass the filename as :
$excel_obj = XML::Excel->new();
$filename = "/tmp/"testresults-2013-07-01.xls"
$excel_obj->parse_doc("testresults-2013-07-01.xls" , {headings => 1});
it works, but if i pass :
$excel_obj->parse_doc("$filename" , {headings => 1});
it does not work
is there any special way to pass a filename through a variable....

When this happens you should try and print out your file name or use debugging mode.
This line seems to be wrong
$filename = "/tmp/"testresults-2013-07-01.xls"
You wither need to replace it with this
$filename = "/tmp/testresults-2013-07-01.xls"
removing the double quotes after /tmp/

Related

Access environment variable in perl written in double quotes via config file

I have an environment variable $ROOT. For eg. $ROOT = "/someroot" It is accessed in a Perl file via config file parameters.
Eg
In config file :
path = '$ROOT/abc/somepath'
In Perl file while using this variable when I write config->{$path} in back ticks config->{$path} value of $ROOT is accessible i.e /someroot/abc/somepath but when in double quotes "config->{$path}" the result is $ROOT/abc/somepath.
I need this to be written in double quotes for opening files : open (filehandle,"config->{$path}"); How can achieve the value of config->{$path} in double quotes.
P.S I have also used $ENV{'config->{$path}'};
Try
my path = $ENV{"ROOT"} . config->{$path};
open(filehandle, path);
But now you do not have to precede your configured path with $ROOT.
config file: path = '/abc/somepath'
Are you looking for this?
sub get_conf {
my ($config, $key) = #_;
my $val = $config{key};
return undef if !defined($val);
$val =~ s{\$ROOT\b}{$ENV{ROOT}}g;
return $val;
}
my $path = get_conf(config, 'path');
For a more general solution, try one of the String::Interpolate modules on CPAN. I favor String::Interpolate::RE (disclaimer: I wrote it):
use String::Interpolate::RE 'strinterp';
my $path = strinterp( $config{path}, {}, { useENV=> 1 } );

inserting new line with OpenOffice::OODoc

I am having quite the issue creating a new line with this module and feel like I am just missing something.
my perl code looks like this:
use OpenOffice::OODoc;
my $name = "foo <br> bar";
$name=~s/<br>/\n/g;
my $outdir = "template.odt";
my $doc = ooDocument(file => $outdir);
my #pars = $doc->getParagraphList();
for my $p (#pars)
{
$doc->substituteText($p,'{TODAY}',$date);
$doc->substituteText($p,'{NAME}',$name);
...
Problem is when I open it in word or open office I have no newlines. Although if it open it in a text edit I have my new lines.. Any ideas of how to fix this?
Ok I figured it out, hopefully this will save someone hours of searching for the same thing. I added:
use Encode qw(encode);
ooLocalEncoding('utf8');
my $linebreak = encode('utf-8', "\x{2028}");
$doc->substituteText($p,'<br>', $linebreak);
So my final code looks like this:
use OpenOffice::OODoc;
use Encode qw(encode);
ooLocalEncoding('utf8');
my $linebreak = encode('utf-8', "\x{2028}");
my $outdir = "template.odt";
my $name = "foo <br> bar";
my $outdir = "template.odt";
my $doc = ooDocument(file => $outdir);
my #pars = $doc->getParagraphList();
for my $p (#pars)
{
$doc->substituteText($p,'{TODAY}',$date);
$doc->substituteText($p,'{NAME}',$name);
$doc->substituteText($p,'<br>', $linebreak);
...
Maybe not the best way to do things but it worked!
You could try and insert and empty para after the current one:
If the 'text' option is empty, calling this method is the equivalent
of adding a line feed.
This sequence (in a text document) inserts a linefeed immediately after paragraph 4. Replace 4 with current position.
$doc->insertElement
(
'//text:p', 4, 'text:p',
position => 'after',
text => '',
);

addFilter Rename ZendFramework

i need to Rename a file with Zend_File_Transfer() only if new file match with old one in the server using some convention like newfile-1.ext where the -1 is the string that is added but Rename filter is strange, i really dont understand so good.
For example, is necesary some like this:
if(file_exists($file)){
$upload->addFilter('Rename', $file);
}
or Rename does it?
thanks
Here is an example from one of my apps. File is recvieved by an Zend_Form
$upload->receive();
$name = $upload->getFileName();
$newFile = 'mynewfile.xyz'
$filterFileRename = new Zend_Filter_File_Rename(array(
'target' => $this->path . $newFile, // path to file
'overwrite' => true
));
$file = $filterFileRename->filter($name);

Perl referencing and deferencing hash values when passing to subroutine?

I've been banging my head over this issue for about 5 hours now, I'm really frustrated and need some assistance.
I'm writing a Perl script that pulls jobs out of a MySQL table and then preforms various database admin tasks. The current task is "creating databases". The script successfully creates the database(s), but when I got to generating the config file for PHP developers it blows up.
I believe it is an issue with referencing and dereferencing variables, but I'm not quite sure what exactly is happening. I think after this function call, something happens to
$$result{'databaseName'}. This is how I get result: $result = $select->fetchrow_hashref()
Here is my function call, and the function implementation:
Function call (line 127):
generateConfig($$result{'databaseName'}, $newPassword, "php");
Function implementation:
sub generateConfig {
my($inName) = $_[0];
my($inPass) = $_[1];
my($inExt) = $_[2];
my($goodData) = 1;
my($select) = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = '$inName'");
my($path) = $documentRoot.$inName."_config.".$inExt;
$select->execute();
if ($select->rows < 1 ) {
$goodData = 0;
}
while ( $result = $select->fetchrow_hashref() )
{
my($insert) = $dbh->do("INSERT INTO $configTableName(databaseId, username, password, path)".
"VALUES('$$result{'id'}', '$inName', '$inPass', '$path')");
}
return 1;
}
Errors:
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 142.
Use of uninitialized value in concatenation (.) or string at ./dbcreator.pl line 154.
Line 142:
$update = $dbh->do("UPDATE ${tablename}
SET ${jobStatus}='${newStatus}'
WHERE id = '$$result{'id'}'");
Line 154:
print "Successfully created $$result{'databaseName'}\n";
The reason I think the problem comes from the function call is because if I comment out the function call, everything works great!
If anyone could help me understand what's going on, that would be great.
Thanks,
p.s. If you notice a security issue with the whole storing passwords as plain text in a database, that's going to be addressed after this is working correctly. =P
Dylan
You do not want to store a reference to the $result returned from fetchrow_hashref, as each subsequent call will overwrite that reference.
That's ok, you're not using the reference when you are calling generate_config, as you are passing data in by value.
Are you using the same $result variable in generate_config and in the calling function? You should be using your own 'my $result' in generate_config.
while ( my $result = $select->fetchrow_hashref() )
# ^^ #add my
That's all that can be said with the current snippets of code you've included.
Some cleanup:
When calling generate_config you are passing by value, not by reference. This is fine.
you are getting an undef warning, this means you are running with 'use strict;'. Good!
create lexical $result within the function, via my.
While $$hashr{key} is valid code, $hashr->{key} is preferred.
you're using dbh->prepare, might as well use placeholders.
sub generateConfig {
my($inName, inPass, $inExt) = #_;
my $goodData = 1;
my $select = $dbh->prepare("SELECT id FROM $databasesTableName WHERE name = ?");
my $insert = $dbh->prepare("
INSERT INTO $configTableName(
databaseID
,username
,password
,path)
VALUES( ?, ?, ?, ?)" );
my $path = $documentRoot . $inName . "_config." . $inExt;
$select->execute( $inName );
if ($select->rows < 1 ) {
$goodData = 0;
}
while ( my $result = $select->fetchrow_hashref() )
{
insert->execute( $result->{id}, $inName, $inPass, $path );
}
return 1;
}
EDIT: after reading your comment
I think that both errors have to do with your using $$result. If $result is the return value of fetchrow_hashref, like in:
$result = $select->fetchrow_hashref()
then the correct way to refer to its values should be:
print "Successfully created " . $result{'databaseName'} . "\n";
and:
$update = $dbh->do("UPDATE ${tablename}
SET ${jobStatus}='${newStatus}'
WHERE id = '$result{'id'}'");
OLD ANSWER:
In function generateConfig, you can pass a reference in using this syntax:
generateConfig(\$result{'databaseName'},$newPassword, "php");
($$ is used to dereference a reference to a string; \ gives you a reference to the object it is applied to).
Then, in the print statement itself, I would try:
print "Successfully created $result->{'databaseName'}->{columnName}\n";
indeed, fetchrow_hashref returns a hash (not a string).
This should fix one problem.
Furthermore, you are using the variable named $dbh but you don't show where it is set. Is it a global variable so that you can use it in generateConfig? Has it been initialized when generateConfig is executed?
This was driving me crazy when I was running hetchrow_hashref from Oracle result set.
Turened out the column names are always returned in upper case.
So once I started referencing the colum in upper case, problem went away:
insert->execute( $result->{ID}, $inName, $inPass, $path );

Double Quote Problem after Saving an INI file with Zend_Config

I got a problem when I want to write and save an INI file. I use Zend_Config_Ini to handle this procedure.
The problem is I always got 'Double Quote' in the value for every line that use integer or number afer saving process. Here is the example
The original application.ini file
resources.session.use_only_cookies = 1
resources.session.remember_me_seconds = 86400
After I run these lines of code
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini',
null,
array('skipExtends' => true,
'allowModifications' => true));
// Modify a value
$config->production->resources->db->adapter = 'foobar';
// Write the config file
$writer = new Zend_Config_Writer_Ini(array('config' => $config,
'filename' => APPLICATION_PATH . '/configs/application.ini'));
$writer->write();
The application.ini lines become
resources.session.use_only_cookies = "1" //double quote appears T_T
resources.session.remember_me_seconds = "86400" //double quote appears T_T
What I want is the integer value must still remain the same (without double quotes).
Anyone can help me to solve this problem?
Thank you very much in advance
As Phil-Brown notes, when reading an ini file in PHP using parse_ini_file(), you always get strings back. Also, for for any value that isn't alphanumeric characters only, you should encase in double quotes, so Zend_Config_Writer encases all values.
Anyway,
In my solution, I had to remove some lines of code in Zend. The file that I changed was \Zend\Config\Writer\Ini.php for method _prepareValue() in line 150 to be like below
protected function _prepareValue($value)
{
/*
I comment it
if (is_integer($value) || is_float($value)) {
return $value;
} elseif (is_bool($value)) {
return ($value ? 'true' : 'false');
} else {
return '"' . addslashes($value) . '"';
}*/
return $value; // my line
}
just comment the original code of Zend and just pass and return $value.
So, by changing this file I never get any double quote anymore for string, boolean or even number. This is that what I want. :)
Thank you everyone.