Gossamer Forum
Home : Products : Gossamer Links : Development, Plugins and Globals :

Can't call method "quote" on an undefined value

Quote Reply
Can't call method "quote" on an undefined value
I have 2 import subs in a plugin. They are nearly identical, and one errors and the other doesn't.

The erorr I get is:
Can't call method "quote" on an undefined value at /admin/GT/SQL/Driver.pm line 451.

Line 451
Code:
$insert_value .= $zipcode_table->quote($value) . ",";

Heck, here's the whole thing THIS ONE GIVES THE ERROR ABOVE. Unless I quote values by hand.
It is in my file ZipCodeSearch.pm
Code:
print $IN->header();

# Some html here

my $table_name = 'ZipCodes';
my $zip_data = $IN->param('zipcode_data_file');

my $col_names = "";
my @column_names = $DB->table($table_name)->ordered_columns;

foreach (@column_names) {
$col_names .= "$_,";
# print $_ . " = " . $IN->param($_) . "<br>";
}
$col_names = substr($col_names, 0, - 1);

my $db_delim = ',';
my $prefix_plus_table = $DB->prefix . $table_name;
my $zipcode_table = $DB->table($table_name) || return $GT::SQL::error;
my $filename = $CFG->{admin_root_path} ."/Plugins/ZipCodeData/". $zip_data;

my (@db);
open (DB, "$filename") || return $GT::SQL::error;
chomp (my $unused_field_names = <DB> );
@db = <DB>;
close DB;

my $replace_count = 0;
my $replaced_total = 0;

my $col;
my $value;
my $row = 1;
my ($sth, $i, @item, %item, $insert_value);
foreach (@db) {
$i = 0;
$_ =~ s/\"//g;
$_ =~ s/\n//;
$_ =~ s/\r//;
@item = split /$db_delim/, $_;
$insert_value = "";

$col = 0;
foreach (@column_names) {

if ($_ eq "CountryCode") {
$value = $IN->param($_);
}
elsif($IN->param($_) eq '-1') {
$value = "";
}
else {
$value = $item[$IN->param($_)];
}

if($_ eq 'DST') {
if (lc $value eq 'n') { $value = '0'; }
if (lc $value eq 'y') { $value = '1'; }
}
# If I quote this by hand, it does NOT error, but it errors on single quotes in the data.
# $insert_value .= "'".$value."'" . ",";
$insert_value .= $zipcode_table->quote($value) . ",";
$col++;
}
$insert_value = substr($insert_value, 0, - 1);
if ($row < 4) { print "$row) $insert_value <br>"; }
elsif ($row == 4) { print "$row) ... Please be patient.<br>"; }
$sth = $zipcode_table->prepare ("REPLACE INTO $prefix_plus_table ($col_names) VALUES ($insert_value)") or die "Unable to prepare query: " .$GT::SQL::error;
$replace_count = $sth->execute() or die "Unable to execute query: " .$GT::SQL::error;
$row++;

if ($replace_count > 1) {
$replaced_total++;
}
}
$row--;
$sth->finish;

# More html here


THIS WORKS PERFECTLY. It is in my file Install.pm and is a subroutine called from my sub install,
immediately after $creator->load_table(); Which creates the table during install sub.
Code:
sub install_zips {
# -------------------------------------------------------------------
# Assumes we just created the table. Uses the default US data and .def
#

my $results = "";
my $table_name = 'ZipCodes';
my $zip_data = 'free_us_zipcodes.csv';
# my $zip_data = 'free_us_test.csv';
my $zip_format = 'free_us_format.def';

my $col_names = "";
my @column_names = $DB->table($table_name)->ordered_columns;

foreach (@column_names) {
$col_names .= "$_, ";
}
$col_names = substr($col_names, 0, - 2); # minus 2 to drop comma+space. I add spaces so col names wrap on success page

my $db_delim = ',';
my $prefix_plus_table = $DB->prefix . $table_name;
my $zipcode_table = $DB->table($table_name) || return $GT::SQL::error;
my $filename = $CFG->{admin_root_path} ."/Plugins/ZipCodeData/". $zip_data;

my (@db, $fields, @fields);
open (DB, "$filename") || return $GT::SQL::error;
chomp ($fields = <DB> );
@fields = split /$db_delim/, $fields;
@db = <DB>;
close DB;

my $col;
my $value;
my $row = 1;
my ($sth, $i, @item, $insert_name, $insert_value);
foreach (@db) {
$i = 0;
$_ =~ s/\"//g;
$_ =~ s/\n//;
$_ =~ s/\r//;
@item = split /$db_delim/, $_;
$insert_value = "";

$col = 0;
foreach (@column_names) {

if ($_ eq "CountryCode") {
$value = "US";
}
else {
$value = $item[$col];
}

$insert_value .= $zipcode_table->quote($value) . ",";
$col++;
}
$insert_value = substr($insert_value, 0, - 1);
if ($row < 4) { print "$row) $insert_value <br>"; }
elsif ($row == 4) { print "$row) ... Please be patient.<br>"; }
$sth = $zipcode_table->prepare ("INSERT INTO $prefix_plus_table ($col_names) VALUES ($insert_value)") or die "Unable to prepare query: " .$GT::SQL::error;
$sth->execute() or die "Unable to execute query: " .$GT::SQL::error;
$row++;
}
$row--;
$sth->finish;
print "$row) $insert_value <br>";

$results .= "<b>$row</b> zip codes were imported to the ZipCodes table.<br>";
return($results);
}

This beat me up for a while once before, and I thought I had it fixed by
manually quoting values, then I ran into the single quote in the data which is causing me to
come back to this once again. Unsure

Thanks for any assistance.
Chris
RGB World, Inc. - Software &amp; Web Development.
rgbworld.com

Last edited by:

rgbworld: Jun 20, 2006, 3:25 AM
Quote Reply
Re: [rgbworld] Can't call method "quote" on an undefined value In reply to
I think that error means that it thinks that $zipcode_table is not defined. I have no idea why.
Quote Reply
Re: [afinlr] Can't call method "quote" on an undefined value In reply to
I have no idea why either. That's why I am asking :-)

This is the pertinent code:
Code:
my $table_name = 'ZipCodes';
my $prefix_plus_table = $DB->prefix . $table_name;
my $zipcode_table = $DB->table($table_name) || return $GT::SQL::error;
$insert_value .= $zipcode_table->quote($value) . ",";

# This is giving me the object to use for quote method correct?
Code:
my $zipcode_table = $DB->table($table_name) || return $GT::SQL::error;

Then I cannot figure out why it works in one case and not the other.
Should I be using the method or not?

Can I just escape the single quotes manually with this
code for the same effect as method 'quote'?.
i.e. $_ =~ s/\'/\\\'/g;


Unless someone can figure out what's wrong with the non-working example
in my original post. This issue is going to go unresolved and I will quote
manually. I think it is a GT code problem though ?

Thanks,
Chris
RGB World, Inc. - Software &amp; Web Development.
rgbworld.com
Quote Reply
Re: [rgbworld] Can't call method "quote" on an undefined value In reply to
I don't suppose that you are using data from a different install of Links or Forum on your site? I have a similar problem that seems to be related to this.
Quote Reply
Re: [afinlr] Can't call method "quote" on an undefined value In reply to
Not sure what you mean by "different install". I have 2 installs on same server.
1 for Live, 1 for development. The data in the dev site (which has the error) was
exported from the live site and imported to the dev site. I haven't tried to see
if I get the same error on Live site.

Chris
RGB World, Inc. - Software &amp; Web Development.
rgbworld.com
Quote Reply
Re: [rgbworld] Can't call method "quote" on an undefined value In reply to
I pull in data from GForum and occasionally this seems to confuse things. Your problem seems to be unrelated. Sorry - I don't really have any other suggestions.
Quote Reply
Re: [afinlr] Can't call method "quote" on an undefined value In reply to
Actually, $zipcode_table is defined, it's this line (451 of Driver.pm) that's causing the problem:
Code:
(values %CONN)[0]->quote($val);
%CONN at the time must have been an empty hash, and it looks like it contains the connection data. So the problem is that at that point, the connection to the database hasn't been established yet. So a simple $DB->table('tablename')->connect will do the trick.

Adrian