Dancer::Tutorial connect to SQLite - perl

I'm create database
sqlite3 database
create table if not exists entries (
id integer primary key autoincrement,
title string not null,
text string not null
);
^D
Where should i put this database ?
After
sub connect_db {
my $dbh = DBI->connect("dbi:SQLite:dbname=".setting('database')) or
die $DBI::errstr;
return $dbh;
}
sub init_db {
my $db = connect_db();
my $schema = read_file('./schema.sql');
$db->do($schema) or die $db->errstr;
}
get '/' => sub {
my $db = connect_db();
my $sql = 'select id, title, text from entries order by id desc';
my $sth = $db->prepare($sql) or die $db->errstr;
$sth->execute or die $sth->errstr;
template 'show_entries.tt', {
'msg' => get_flash(),
'add_entry_url' => uri_for('/add'),
'entries' => $sth->fetchall_hashref('id'),
};
};
Recieve an Error
Runtime Error
near "desk" : syntax error at /home/ultramozg/App/lib/App.pm line 40, line 16
What it's my mistake ?

I highly recommend you use Dancer::Plugin::Database instead of the connect_db routine you're proposing. The way you're doing it will probably create leftover open connections and therefore all sorts of problems. Dancer::Plugin::Database handles persistent connections for you. Doc for plugin:
https://metacpan.org/pod/Dancer::Plugin::Database
Once you install Dancer::Plugin::Database and configure it in config.yml, then whenever you need to a database handle, you just:
my $dbh => database('my_database_name');
and don't bother disconnecting when done.
If you're using ubuntu, just:
apt-get install libdancer-plugin-database-perl
Good luck on your project!

You have a ^D character for starters - last line in the first section. Please learn to read output. It tells you line 16.
Check where the word "desk" appears in your code as well.

Related

Perl DBI Sybase Asanywhere Problems with bind variables

I have to switch my webserver (internal use only) to a more recent version and so I have also new perl and new DBD:Sybase instead of DBD:ASAny I used before.
I use statements with bind variables regulary, they worked fine, but with DBD:Sybase I get the following error:
AH01215: DBD::Sybase::st execute failed: Server >message number=12006 severity=16 state=0 line=0 text=SQL Anywhere-Fehler >-110: Element 'DBD1' ist bereits vorhanden
The versions:
New: DBD::Sybase
/usr/local/lib/x86_64-linux-gnu/perl/5.22.1/DBD/Sybase.pm
Installed: 1.15
Old: DBD::ASAny
DBD::ASAny version 1.14.
#!/usr/bin/perl
use DBI;
print "Content-type: text/html\n\n";
$dbh = DBI->connect( "DBI:Sybase:server=tl", 'xxx', 'yyy', {PrintError => 1, AutoCommit => 0} ) or die "Connection failed\n Connection string: $connstr\n Error message : $DBI::errstr\n";
$dbh2 = DBI->connect( "DBI:Sybase:server=tl", 'xxx', 'yyy', {PrintError => 1, AutoCommit => 0} ) or die "Connection failed\n Connection string: $connstr\n Error message : $DBI::errstr\n";
$select="select artnr, bez1, bez2 from art where artnr like 'F%12%.00'";
$sth_t=$dbh->prepare($select);
$sth_t->execute();
$select="select lager_nr, bestand from bestand where art_nr = ? and coalesce(bestand,0) > 0 ";
$sth_lager=$dbh2->prepare($select) or die "Prep sthlager nix:".$dbh2->errstr()."\n";
while ( ($artnr, $gtnr, $bez)=$sth_t->fetchrow())
{
print $artnr."; ".$gtnr."; ".$bez;
$sth_lager->execute($artnr) or die "exec sthlager nix:".$dbh2->errstr()."\n";
while ( ($lager,$bestand) = $sth_lager->fetchrow())
{
print $lager." : ".$bestand." || ";
}
$sth_lager->finish();
print "\n<br>";
}
The offending line is "$sth_lager->execute($artnr)"
Thanks to You all, especially simbabque, he was on the right track. The answer is simple:
DBD::ASAny was written to handle SQL Anywhere, whereas DBD::Sybase is for Sybase Adaptive Server Enterprise, and these two systems are actually quite different.
I used the wrong tool. Mist.

Sybase Warning messages from perl DBI

I am connecting to sybase 12 from a perl script and calling storedprocs, I get the following warnings
DBD::Sybase::db prepare failed: Server message number=2401 severity=11 state=2 line=0 server=SERVER_NAME text=Character
set conversion is not available between client character set 'utf8' and server character set 'iso_1'.
Server message number=2411 severity=10 state=1 line=0 server=SERVER_NAME text=No conversions will be done.
at line 210.
Now, I understand these are only warnings, and my process works perfectly fine, but I am calling my stored proc in a loop and throughout the day and hence it creates a lot of warning message in my log files which causes the entire process to run a bit slower than expected. Can someone help me how can i suppress these please?
You can use a callback to handle the messages you want ignored. See the DBD::Sybase docs. The below is derived from the docs. You specify the message numbers you would like to ignore.
%blocked_msgs = map { $_ => 1 } ( 2401, 2411 );
sub err_handler {
my($err, $sev, $state, $line, $server, $proc, $msg, $sql, $err_type) = #_;
if ( exists $blocked_msgs{$err} ) { # it's a blocked message
return 0; # This is not an error
}
return 1;
}
This is how you might use it:
$dbh = DBI->connect('dbi:Sybase:server=troll', 'sa', '');
$dbh->{syb_err_handler} = \&err_handler;
$dbh->do("exec someproc");
$dbh->disconnect;

How to create trigger in DB with help of `DBIx::Class` using add_trigger method?

I want to add trigger into my database. I use DBIx::Class and follow these examples: 1, 2.
My code is:
package App::Schema;
use base qw/DBIx::Class::Schema/;
__PACKAGE__->load_namespaces();
sub sqlt_deploy_hook {
my ($self, $schema) = #_;
$schema->add_trigger( name => 'foo' );
}
1;
But I get this error:
Failed to translate to YAML: translate: Error with producer 'SQL::Translator::Producer::YAML': Can't call method "name" on an undefined value at /home/kes/work/projects/x/app/local/lib/perl5/SQL/Translator/Schema/Trigger.pm line 198
When run command with all environment variables as required by dbic-migration:
dbic-migration --force --schema_class App::Schema --database PostgreSQL -Ilib prepare
Which point me somewhere into SQL::Translator::Schema::Trigger
What did I miss? How to fix this error?
UPD
Even when I add all arguments I got error:
Failed to translate to YAML: translate: Error with parser 'SQL::Translator::Parser::DBIx::Class': Table named users doesn't exist at /home/kes/work/projects/x/app/local/lib/perl5/SQL/Translator/Schema/Trigger.pm line 54
Here the target line:
my $table = $args->{schema}->get_table($arg)
or die "Table named $arg doesn't exist";
Modified code:
sub sqlt_deploy_hook {
my ($self, $schema) = #_;
warn "TABLES: " ,$schema->get_tables ,"\n";
$schema->add_trigger(()
,name => 'foo'
,perform_action_when => 'after'
,database_events => 'insert'
,on_table => 'users'
,action => 'text'
,scope => 'row'
);
}
This code produce next warnings:
TABLES: users
TABLES: dbix_class_deploymenthandler_versions
But DB has only one table at the moment. I expect it at least should produce:
TABLES: users dbix_class_deploymenthandler_versions
How to create trigger in DB?
There maybe the problem with DBIx::Class::ResultSource::default_sqlt_deploy_hook:
which was originally designed to expect the Result class name and the $sqlt_table instance of the table being deployed
As work around add next line of code before add_trigger:
return unless grep $_ eq 'users', $schema->get_tables;
But the recommend way is to create deploy/upgrade/downgrade .sql files manually

How can I get output "Table created" with perl DBI

There is a code I would like to get output with Perl DBI "Table created":
use DBI;
use DBD::Oracle qw(:ora_session_modes);
$dbh=DBI->connect( "dbi:Oracle:", "", "", { ora_session_mode =>
ORA_SYSDBA , RaiseError => 1, PrintError => 1 } );
$dbh->do(qq{ create table test ( customer_id number(10) NOT NULL ) } );
How can I get this output "Table created" from DBI?
I don't think you can get this answer directly from DBI. DBI does not really care about what it is executing, it just passes things to and fom the database. Only you (or the code you wrote) know that the statement you ran was a CREATE TABLE statement.
So if you want to print TABLE CREATED, or even TABLE test CREATED, you must check the return value as suggested by some other answers here and assemble the message yourself.
If the Query is not executed successfully print the error message.
$Local_Dbh->do($Query) or print " Unable to execute the query $Local_Dbh->errstr";
If the table is not created , It will return the undef or -1 otherwise return the value like
Result : 0E0

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

Whenever I'm executing the program below, I get the error message Can't call method "execute" on an undefined value from following line:
$sth->execute($agent_name,$service_id,$call_start_time,$call_end_time);
but in same program I'm able to execute the first SQL query indicated in the comments below:
#!/usr/bin/perl -w
use strict;
use DBI;
my $DSN = q/dbi:ODBC:SQLSERVER/;
my $uid = q/ivr/;
my $pwd = q/ivr/;
my $DRIVER = "Freetds";
my $dbh = DBI->connect($DSN,$uid,$pwd) or die "Coudn't Connect SQL";
my $servernumber = 2;
my $service_name = "JM";
my $agent_name= 'Balaji';
my $call_start_time='2013-07-01 15:46:50.865';
my $call_end_time='2013-07-15 15:46:50.789';
my $call_rec_file_name;
my $rows_fund = $dbh->selectrow_array("select count(service_name) from cti_services where service_name='$service_name'");
my $rows_agent = $dbh->selectrow_array("select count(agent_name) from cti_agents where agent_name='$agent_name'");
# This query successfully executes:
my $sql_fund = "select service_id from cti_services where service_name='$service_name'";
my $sth_fund = $dbh->prepare($sql_fund);
$sth_fund->execute() or die $DBI::errstr;
my $service_id = $sth_fund->fetchrow();
print $service_id,"\n";
if( $rows_fund == 1 && $rows_agent == 1 )
{
my $sql="select top(10) service_name,agent_name,call_rec_file_name,call_start_time,call_end_time from cti_agents join cti_call_master on (agent_name = call_agent_name) join cti_services on (call_service_id = service_id) where agent_name = ? and call_rec_file_name is not null and service_id=? and call_start_time between ? and ?";
my $sth = $dbh->prepare($sql);
# The problem is with this query. I'm getting the error "Can't call method "execute" on an undefined value".
$sth->execute($agent_name,$service_id,$call_start_time,$call_end_time);
print "Service Name","Agent Name","Call Start Time ","Call End Time","Sound File " ;
while (my #data = $sth->fetchrow_array())
{
my ($service_name,$agent_name,$call_rec_file_name,$call_start_time,$call_end_time ) = #data;
print "$service_name","$agent_name ","$call_start_time ","$call_end_time "," $call_rec_file_name ";
}
}
else
{
print "<em>","There is no data found","</em>";
}
$dbh->disconnect;
What could be causing the error message?
$sth is undefined because your call to $dbh->prepare is failing for some reason.
If you replace your DBI->connect() call with the following, you'll get the error from the prepare call rather than it failing silently and bombing out when you try to call execute:
my $dbh = DBI->connect($DSN,$uid,$pwd, { RaiseError => 1 });
You can read more about RaiseError and the other attributes available to DBI calls here: https://metacpan.org/module/DBI#RaiseError
I must admit I can't immediately see the error, my hunch is an SQL syntax issue, but I don't speak SQLServer.
Change the first two lines inside the if to this
my $sth = $dbh->prepare(<<__SQL__) or die $dbh->errstr;
SELECT TOP(10) service_name, agent_name, call_rec_file_name, call_start_time, call_end_time
FROM cti_agents
JOIN cti_call_master ON (agent_name = call_agent_name)
JOIN cti_services ON (call_service_id = service_id)
WHERE agent_name = ?
AND call_rec_file_name IS NOT NULL
AND service_id = ?
AND call_start_time BETWEEN ? AND ?
__SQL__
then you will see the reason for the error.
Note that there must be no spaces before or after __SQL__.
Put quotes inside the sql for the datetimes, it may be seeing the white space during parsing?