SlideShare a Scribd company logo
Using Perl Stored
Procedures
with MariaDB
Antony T Curtis <atcurtis@gmail.com>
Special thanks to LinkedIn for permitting personal projects
Why Perl?
• CPAN
• "Multiplicity" / Thread-friendly.
• Lots of Perl code already written.
• MySQL UDFs have no access control.
• MySQL UDFs cannot execute dynamic SQL.
• Faster than “native” Stored Procedures.
Perl Stored Procedures
• Implemented as Perl modules.
• Use DBD::mysql to access database.
• Runs in-process with MariaDB.
• Easier to debug than SQL stored routines.
Hello World
MariaDB [Demo]> CREATE PROCEDURE PerlHello()
-> DYNAMIC RESULT SETS 1
-> NO SQL
-> LANGUAGE Perl
-> EXTERNAL NAME "HelloWorld::test";
Query OK, 0 rows affected (0.02 sec)
MariaDB [Demo]> call PerlHello();
+-----------------------+
| message |
+-----------------------+
| Hello World from Perl |
+-----------------------+
1 row in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
package HelloWorld;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
sub test()
{
return {
'message' => 'Hello World from Perl',
};
}
1;
Hello World
MariaDB [Demo]> CREATE PROCEDURE PerlHello()
-> DYNAMIC RESULT SETS 1
-> NO SQL
-> LANGUAGE Perl
-> EXTERNAL NAME "HelloWorld::test";
Query OK, 0 rows affected (0.02 sec)
MariaDB [Demo]> call PerlHello();
+-----------------------+
| message |
+-----------------------+
| Hello World from Perl |
+-----------------------+
1 row in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
package HelloWorld;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
sub test()
{
return {
'message' => 'Hello World from Perl',
};
}
1;
Error handling or die
MariaDB [Demo]> CREATE PROCEDURE PerlError()
-> DYNAMIC RESULT SETS 1
-> NO SQL
-> LANGUAGE Perl
-> EXTERNAL NAME "GoodbyeWorld::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [Demo]> call PerlError();
ERROR 1220 (HY000): Cannot open file: No
such file or directory at /usr/local/mysql/
lib/plugin/perl/GoodbyeWorld.pm line 16.
package GoodbyeWorld;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
sub test(
{
open FILE, "</something/nonexist"
or die "Cannot open file: $!";
return {
'message' => 'Goodbye World from Perl',
};
}
1;
Reading Data
MariaDB [employees]> CREATE PROCEDURE employee(
-> empno INT)
-> DYNAMIC RESULT SETS 1
-> READS SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ReadData::test";
Query OK, 0 rows affected (0.02 sec)
MariaDB [employees]> call employee(10034)G
*************************** 1. row
***************************
birth_date: 1962-12-29
emp_no: 10034
first_name: Bader
gender: M
hire_date: 1988-09-21
last_name: Swan
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
package ReadData;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
our $DSN = ‘dbi:mysql:employees’;
use DBI;
use DBD::mysql;
sub test($)
{
my($emp_no) = @_;
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
my $s = $dbh->prepare(
“SELECT * FROM employees WHERE emp_no=?”);
$s->execute(int $emp_no);
return $s->fetchrow_hashref;
}
1;
Reading Data
MariaDB [employees]> CREATE PROCEDURE employee(
-> empno INT)
-> DYNAMIC RESULT SETS 1
-> READS SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ReadData::test";
Query OK, 0 rows affected (0.02 sec)
MariaDB [employees]> call employee(10034)G
*************************** 1. row
***************************
birth_date: 1962-12-29
emp_no: 10034
first_name: Bader
gender: M
hire_date: 1988-09-21
last_name: Swan
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
package ReadData;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
our $DSN = ‘dbi:mysql:employees’;
use DBI;
use DBD::mysql;
sub test($)
{
my($emp_no) = @_;
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
my $s = $dbh->prepare(
“SELECT * FROM employees WHERE emp_no=?”);
$s->execute(int $emp_no);
return $s->fetchrow_hashref;
}
1;
Modifying Data
MariaDB [employees]> CREATE PROCEDURE
-> makesummary(
-> empno INT)
-> MODIFIES SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ModifyData::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> call makesummary;
sub test()
{
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
$dbh->begin_work or die $!;
my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)");
my $emps = $dbh->selectall_arrayref(
"select emp_no, max(salary) salary from employees ".
"left join salaries using (emp_no) group by emp_no",
{ Slice => {} });
foreach my $emp (@$emps)
{
$ins->execute($emp->{emp_no}, $emp->{salary}) or die $!;
}
$dbh->commit or die $!;
return undef;
}
Modifying Data
MariaDB [employees]> CREATE PROCEDURE
-> makesummary(
-> empno INT)
-> MODIFIES SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ModifyData::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> call makesummary;
Query OK, 0 rows affected (18.02 sec)
sub test()
{
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
$dbh->begin_work or die $!;
my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)");
my $emps = $dbh->selectall_arrayref(
"select emp_no, max(salary) salary from employees ".
"left join salaries using (emp_no) group by emp_no",
{ Slice => {} });
foreach my $emp (@$emps)
{
$ins->execute($emp->{emp_no}, $emp->{salary}) or die $!;
}
$dbh->commit or die $!;
return undef;
}
Modifying Data
MariaDB [employees]> CREATE PROCEDURE
-> makesummary(
-> empno INT)
-> MODIFIES SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ModifyData::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> call makesummary;
Query OK, 0 rows affected (18.02 sec)
MariaDB [employees]> select count(*)
-> from summary;
+----------+
| count(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.15 sec)
sub test()
{
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
$dbh->begin_work or die $!;
my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)");
my $emps = $dbh->selectall_arrayref(
"select emp_no, max(salary) salary from employees ".
"left join salaries using (emp_no) group by emp_no",
{ Slice => {} });
foreach my $emp (@$emps)
{
$ins->execute($emp->{emp_no}, $emp->{salary}) or die $!;
}
$dbh->commit or die $!;
return undef;
}
Modifying Data
MariaDB [employees]> CREATE PROCEDURE
-> makesummary(
-> empno INT)
-> MODIFIES SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ModifyData::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> call makesummary;
Query OK, 0 rows affected (18.02 sec)
MariaDB [employees]> select count(*)
-> from summary;
+----------+
| count(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.15 sec)
sub test()
{
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
$dbh->begin_work or die $!;
my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)");
my $emps = $dbh->selectall_arrayref(
"select emp_no, max(salary) salary from employees ".
"left join salaries using (emp_no) group by emp_no",
{ Slice => {} });
foreach my $emp (@$emps)
{
$ins->execute($emp->{emp_no}, $emp->{salary}) or die $!;
}
$dbh->commit or die $!;
return undef;
}
select statement - 2 seconds
300k inserts in 16 seconds
== 18k inserts per second
More than just procs
• CPAN is a large library...
• Can extend MariaDB’s functionality.
• How about using HTTP::Daemon?
Server Monitoring
sub daemon()
{
my $d = HTTP::Daemon->new(
LocalAddr => '127.0.0.1',
LocalPort => 8080,
) ||
die "Failed in call to HTTP::Daemon->new, $!";
my $dbh = DBI->connect("dbi:mysql:mysql", undef, undef) ||
die "Failed in call to DBI->connect, $!";
while (my $c = $d->accept)
{
while (my $r = $c->get_request)
{
if (exists $pages{$r->url->path})
{
$pages{$r->url->path}->($dbh, $c, $r);
}
else
{
$c->send_error(RC_NOT_FOUND);
}
}
$c->close;
undef $c;
}
}
What if we can use
HTTP::Daemon?
Server Monitoring
'/statusz' => sub {
my ($dbh,$c,$r) = @_;
return $c->send_error(RC_FORBIDDEN)
if $r->method ne 'GET';
my $sth = $dbh->prepare_cached(q{
SELECT VARIABLE_NAME name, VARIABLE_VALUE value
FROM INFORMATION_SCHEMA.GLOBAL_STATUS
}, { Slice => {} });
$sth->execute() || die $sth->errstr;
my $response = HTTP::Response->new(200, undef,
HTTP::Headers->new(
Content_Type => "application/json",
));
my $result = {};
while (my $row = $sth->fetchrow_arrayref)
{
$result->{$row->[0]} = $row->[1];
}
$response->add_content(to_json($result,
{ ascii => 1, pretty => 1 }));
return $c->send_response($response);
},
Fetching current
server status could be
as simple as fetching
http://127.0.0.1/statusz
Status
• Code hosted at LaunchPad.
• Contributing to MariaDB 10.0 soon.
• Stuff needs to be tidied up.
• Future steps include better Table Functions.
Ad

More Related Content

What's hot (20)

New features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in actionNew features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in action
Sveta Smirnova
 
MySQL Performance Schema in Action
MySQL Performance Schema in ActionMySQL Performance Schema in Action
MySQL Performance Schema in Action
Sveta Smirnova
 
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sadDevelopers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
mCloud
 
DBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should KnowDBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should Know
Alex Zaballa
 
MySQL Performance schema missing_manual_flossuk
MySQL Performance schema missing_manual_flossukMySQL Performance schema missing_manual_flossuk
MySQL Performance schema missing_manual_flossuk
Valeriy Kravchuk
 
Mysql 56-experiences-bugs-solutions-50mins
Mysql 56-experiences-bugs-solutions-50minsMysql 56-experiences-bugs-solutions-50mins
Mysql 56-experiences-bugs-solutions-50mins
Valeriy Kravchuk
 
MariaDB for developers
MariaDB for developersMariaDB for developers
MariaDB for developers
Colin Charles
 
Summary tables with flexviews
Summary tables with flexviewsSummary tables with flexviews
Summary tables with flexviews
Justin Swanhart
 
Building node.js applications with Database Jones
Building node.js applications with Database JonesBuilding node.js applications with Database Jones
Building node.js applications with Database Jones
John David Duncan
 
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL DevroomFlame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Valeriy Kravchuk
 
Troubleshooting MySQL Performance
Troubleshooting MySQL PerformanceTroubleshooting MySQL Performance
Troubleshooting MySQL Performance
Sveta Smirnova
 
Php classes in mumbai
Php classes in mumbaiPhp classes in mumbai
Php classes in mumbai
aadi Surve
 
Introduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]sIntroduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]s
Sveta Smirnova
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQL
John David Duncan
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL Troubleshooting
Sveta Smirnova
 
Performance schema in_my_sql_5.6_pluk2013
Performance schema in_my_sql_5.6_pluk2013Performance schema in_my_sql_5.6_pluk2013
Performance schema in_my_sql_5.6_pluk2013
Valeriy Kravchuk
 
Why Use EXPLAIN FORMAT=JSON?
 Why Use EXPLAIN FORMAT=JSON?  Why Use EXPLAIN FORMAT=JSON?
Why Use EXPLAIN FORMAT=JSON?
Sveta Smirnova
 
Performance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshootingPerformance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshooting
Sveta Smirnova
 
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Alex Zaballa
 
MySQL 101 PHPTek 2017
MySQL 101 PHPTek 2017MySQL 101 PHPTek 2017
MySQL 101 PHPTek 2017
Dave Stokes
 
New features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in actionNew features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in action
Sveta Smirnova
 
MySQL Performance Schema in Action
MySQL Performance Schema in ActionMySQL Performance Schema in Action
MySQL Performance Schema in Action
Sveta Smirnova
 
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sadDevelopers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
mCloud
 
DBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should KnowDBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should Know
Alex Zaballa
 
MySQL Performance schema missing_manual_flossuk
MySQL Performance schema missing_manual_flossukMySQL Performance schema missing_manual_flossuk
MySQL Performance schema missing_manual_flossuk
Valeriy Kravchuk
 
Mysql 56-experiences-bugs-solutions-50mins
Mysql 56-experiences-bugs-solutions-50minsMysql 56-experiences-bugs-solutions-50mins
Mysql 56-experiences-bugs-solutions-50mins
Valeriy Kravchuk
 
MariaDB for developers
MariaDB for developersMariaDB for developers
MariaDB for developers
Colin Charles
 
Summary tables with flexviews
Summary tables with flexviewsSummary tables with flexviews
Summary tables with flexviews
Justin Swanhart
 
Building node.js applications with Database Jones
Building node.js applications with Database JonesBuilding node.js applications with Database Jones
Building node.js applications with Database Jones
John David Duncan
 
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL DevroomFlame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Valeriy Kravchuk
 
Troubleshooting MySQL Performance
Troubleshooting MySQL PerformanceTroubleshooting MySQL Performance
Troubleshooting MySQL Performance
Sveta Smirnova
 
Php classes in mumbai
Php classes in mumbaiPhp classes in mumbai
Php classes in mumbai
aadi Surve
 
Introduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]sIntroduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]s
Sveta Smirnova
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQL
John David Duncan
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL Troubleshooting
Sveta Smirnova
 
Performance schema in_my_sql_5.6_pluk2013
Performance schema in_my_sql_5.6_pluk2013Performance schema in_my_sql_5.6_pluk2013
Performance schema in_my_sql_5.6_pluk2013
Valeriy Kravchuk
 
Why Use EXPLAIN FORMAT=JSON?
 Why Use EXPLAIN FORMAT=JSON?  Why Use EXPLAIN FORMAT=JSON?
Why Use EXPLAIN FORMAT=JSON?
Sveta Smirnova
 
Performance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshootingPerformance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshooting
Sveta Smirnova
 
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Alex Zaballa
 
MySQL 101 PHPTek 2017
MySQL 101 PHPTek 2017MySQL 101 PHPTek 2017
MySQL 101 PHPTek 2017
Dave Stokes
 

Similar to Using Perl Stored Procedures for MariaDB (20)

DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
chuvainc
 
MySQLinsanity
MySQLinsanityMySQLinsanity
MySQLinsanity
Stanley Huang
 
DBD::SQLite
DBD::SQLiteDBD::SQLite
DBD::SQLite
charsbar
 
Triggers and Stored Procedures
Triggers and Stored ProceduresTriggers and Stored Procedures
Triggers and Stored Procedures
Tharindu Weerasinghe
 
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert VanderkelenOSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
NETWAYS
 
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuPostgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Redis Labs
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks
Damien Seguy
 
Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8
Philip Zhong
 
Instalar MySQL CentOS
Instalar MySQL CentOSInstalar MySQL CentOS
Instalar MySQL CentOS
Moisés Elías Araya
 
My sql1
My sql1My sql1
My sql1
NV Chandra Sekhar Nittala
 
veracruz
veracruzveracruz
veracruz
tutorialsruby
 
veracruz
veracruzveracruz
veracruz
tutorialsruby
 
veracruz
veracruzveracruz
veracruz
tutorialsruby
 
veracruz
veracruzveracruz
veracruz
tutorialsruby
 
php2.pptx
php2.pptxphp2.pptx
php2.pptx
ElieNGOMSEU
 
The Ring programming language version 1.7 book - Part 31 of 196
The Ring programming language version 1.7 book - Part 31 of 196The Ring programming language version 1.7 book - Part 31 of 196
The Ring programming language version 1.7 book - Part 31 of 196
Mahmoud Samir Fayed
 
Presentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-railsPresentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-rails
Novelys
 
Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTID
Mydbops
 
MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)
Seungmin Yu
 
Service discovery and configuration provisioning
Service discovery and configuration provisioningService discovery and configuration provisioning
Service discovery and configuration provisioning
Source Ministry
 
DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
chuvainc
 
DBD::SQLite
DBD::SQLiteDBD::SQLite
DBD::SQLite
charsbar
 
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert VanderkelenOSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
NETWAYS
 
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuPostgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Redis Labs
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks
Damien Seguy
 
Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8
Philip Zhong
 
The Ring programming language version 1.7 book - Part 31 of 196
The Ring programming language version 1.7 book - Part 31 of 196The Ring programming language version 1.7 book - Part 31 of 196
The Ring programming language version 1.7 book - Part 31 of 196
Mahmoud Samir Fayed
 
Presentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-railsPresentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-rails
Novelys
 
Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTID
Mydbops
 
MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)
Seungmin Yu
 
Service discovery and configuration provisioning
Service discovery and configuration provisioningService discovery and configuration provisioning
Service discovery and configuration provisioning
Source Ministry
 
Ad

Recently uploaded (20)

Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
Cyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of securityCyber Awareness overview for 2025 month of security
Cyber Awareness overview for 2025 month of security
riccardosl1
 
Mobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi ArabiaMobile App Development Company in Saudi Arabia
Mobile App Development Company in Saudi Arabia
Steve Jonas
 
tecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdftecnologias de las primeras civilizaciones.pdf
tecnologias de las primeras civilizaciones.pdf
fjgm517
 
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul Shares 5 Steps to Implement AI Agents for Maximum Business Efficien...
Noah Loul
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
AI Changes Everything – Talk at Cardiff Metropolitan University, 29th April 2...
Alan Dix
 
AI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global TrendsAI and Data Privacy in 2025: Global Trends
AI and Data Privacy in 2025: Global Trends
InData Labs
 
HCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser EnvironmentsHCL Nomad Web – Best Practices and Managing Multiuser Environments
HCL Nomad Web – Best Practices and Managing Multiuser Environments
panagenda
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
Role of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered ManufacturingRole of Data Annotation Services in AI-Powered Manufacturing
Role of Data Annotation Services in AI-Powered Manufacturing
Andrew Leo
 
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdfComplete Guide to Advanced Logistics Management Software in Riyadh.pdf
Complete Guide to Advanced Logistics Management Software in Riyadh.pdf
Software Company
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Build Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For DevsBuild Your Own Copilot & Agents For Devs
Build Your Own Copilot & Agents For Devs
Brian McKeiver
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Ad

Using Perl Stored Procedures for MariaDB

  • 1. Using Perl Stored Procedures with MariaDB Antony T Curtis <[email protected]> Special thanks to LinkedIn for permitting personal projects
  • 2. Why Perl? • CPAN • "Multiplicity" / Thread-friendly. • Lots of Perl code already written. • MySQL UDFs have no access control. • MySQL UDFs cannot execute dynamic SQL. • Faster than “native” Stored Procedures.
  • 3. Perl Stored Procedures • Implemented as Perl modules. • Use DBD::mysql to access database. • Runs in-process with MariaDB. • Easier to debug than SQL stored routines.
  • 4. Hello World MariaDB [Demo]> CREATE PROCEDURE PerlHello() -> DYNAMIC RESULT SETS 1 -> NO SQL -> LANGUAGE Perl -> EXTERNAL NAME "HelloWorld::test"; Query OK, 0 rows affected (0.02 sec) MariaDB [Demo]> call PerlHello(); +-----------------------+ | message | +-----------------------+ | Hello World from Perl | +-----------------------+ 1 row in set (0.03 sec) Query OK, 0 rows affected (0.03 sec) package HelloWorld; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; sub test() { return { 'message' => 'Hello World from Perl', }; } 1;
  • 5. Hello World MariaDB [Demo]> CREATE PROCEDURE PerlHello() -> DYNAMIC RESULT SETS 1 -> NO SQL -> LANGUAGE Perl -> EXTERNAL NAME "HelloWorld::test"; Query OK, 0 rows affected (0.02 sec) MariaDB [Demo]> call PerlHello(); +-----------------------+ | message | +-----------------------+ | Hello World from Perl | +-----------------------+ 1 row in set (0.03 sec) Query OK, 0 rows affected (0.03 sec) package HelloWorld; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; sub test() { return { 'message' => 'Hello World from Perl', }; } 1;
  • 6. Error handling or die MariaDB [Demo]> CREATE PROCEDURE PerlError() -> DYNAMIC RESULT SETS 1 -> NO SQL -> LANGUAGE Perl -> EXTERNAL NAME "GoodbyeWorld::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [Demo]> call PerlError(); ERROR 1220 (HY000): Cannot open file: No such file or directory at /usr/local/mysql/ lib/plugin/perl/GoodbyeWorld.pm line 16. package GoodbyeWorld; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; sub test( { open FILE, "</something/nonexist" or die "Cannot open file: $!"; return { 'message' => 'Goodbye World from Perl', }; } 1;
  • 7. Reading Data MariaDB [employees]> CREATE PROCEDURE employee( -> empno INT) -> DYNAMIC RESULT SETS 1 -> READS SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ReadData::test"; Query OK, 0 rows affected (0.02 sec) MariaDB [employees]> call employee(10034)G *************************** 1. row *************************** birth_date: 1962-12-29 emp_no: 10034 first_name: Bader gender: M hire_date: 1988-09-21 last_name: Swan 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) package ReadData; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; our $DSN = ‘dbi:mysql:employees’; use DBI; use DBD::mysql; sub test($) { my($emp_no) = @_; my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; my $s = $dbh->prepare( “SELECT * FROM employees WHERE emp_no=?”); $s->execute(int $emp_no); return $s->fetchrow_hashref; } 1;
  • 8. Reading Data MariaDB [employees]> CREATE PROCEDURE employee( -> empno INT) -> DYNAMIC RESULT SETS 1 -> READS SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ReadData::test"; Query OK, 0 rows affected (0.02 sec) MariaDB [employees]> call employee(10034)G *************************** 1. row *************************** birth_date: 1962-12-29 emp_no: 10034 first_name: Bader gender: M hire_date: 1988-09-21 last_name: Swan 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) package ReadData; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; our $DSN = ‘dbi:mysql:employees’; use DBI; use DBD::mysql; sub test($) { my($emp_no) = @_; my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; my $s = $dbh->prepare( “SELECT * FROM employees WHERE emp_no=?”); $s->execute(int $emp_no); return $s->fetchrow_hashref; } 1;
  • 9. Modifying Data MariaDB [employees]> CREATE PROCEDURE -> makesummary( -> empno INT) -> MODIFIES SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ModifyData::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [employees]> call makesummary; sub test() { my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; $dbh->begin_work or die $!; my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)"); my $emps = $dbh->selectall_arrayref( "select emp_no, max(salary) salary from employees ". "left join salaries using (emp_no) group by emp_no", { Slice => {} }); foreach my $emp (@$emps) { $ins->execute($emp->{emp_no}, $emp->{salary}) or die $!; } $dbh->commit or die $!; return undef; }
  • 10. Modifying Data MariaDB [employees]> CREATE PROCEDURE -> makesummary( -> empno INT) -> MODIFIES SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ModifyData::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [employees]> call makesummary; Query OK, 0 rows affected (18.02 sec) sub test() { my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; $dbh->begin_work or die $!; my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)"); my $emps = $dbh->selectall_arrayref( "select emp_no, max(salary) salary from employees ". "left join salaries using (emp_no) group by emp_no", { Slice => {} }); foreach my $emp (@$emps) { $ins->execute($emp->{emp_no}, $emp->{salary}) or die $!; } $dbh->commit or die $!; return undef; }
  • 11. Modifying Data MariaDB [employees]> CREATE PROCEDURE -> makesummary( -> empno INT) -> MODIFIES SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ModifyData::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [employees]> call makesummary; Query OK, 0 rows affected (18.02 sec) MariaDB [employees]> select count(*) -> from summary; +----------+ | count(*) | +----------+ | 300024 | +----------+ 1 row in set (0.15 sec) sub test() { my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; $dbh->begin_work or die $!; my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)"); my $emps = $dbh->selectall_arrayref( "select emp_no, max(salary) salary from employees ". "left join salaries using (emp_no) group by emp_no", { Slice => {} }); foreach my $emp (@$emps) { $ins->execute($emp->{emp_no}, $emp->{salary}) or die $!; } $dbh->commit or die $!; return undef; }
  • 12. Modifying Data MariaDB [employees]> CREATE PROCEDURE -> makesummary( -> empno INT) -> MODIFIES SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ModifyData::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [employees]> call makesummary; Query OK, 0 rows affected (18.02 sec) MariaDB [employees]> select count(*) -> from summary; +----------+ | count(*) | +----------+ | 300024 | +----------+ 1 row in set (0.15 sec) sub test() { my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; $dbh->begin_work or die $!; my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)"); my $emps = $dbh->selectall_arrayref( "select emp_no, max(salary) salary from employees ". "left join salaries using (emp_no) group by emp_no", { Slice => {} }); foreach my $emp (@$emps) { $ins->execute($emp->{emp_no}, $emp->{salary}) or die $!; } $dbh->commit or die $!; return undef; } select statement - 2 seconds 300k inserts in 16 seconds == 18k inserts per second
  • 13. More than just procs • CPAN is a large library... • Can extend MariaDB’s functionality. • How about using HTTP::Daemon?
  • 14. Server Monitoring sub daemon() { my $d = HTTP::Daemon->new( LocalAddr => '127.0.0.1', LocalPort => 8080, ) || die "Failed in call to HTTP::Daemon->new, $!"; my $dbh = DBI->connect("dbi:mysql:mysql", undef, undef) || die "Failed in call to DBI->connect, $!"; while (my $c = $d->accept) { while (my $r = $c->get_request) { if (exists $pages{$r->url->path}) { $pages{$r->url->path}->($dbh, $c, $r); } else { $c->send_error(RC_NOT_FOUND); } } $c->close; undef $c; } } What if we can use HTTP::Daemon?
  • 15. Server Monitoring '/statusz' => sub { my ($dbh,$c,$r) = @_; return $c->send_error(RC_FORBIDDEN) if $r->method ne 'GET'; my $sth = $dbh->prepare_cached(q{ SELECT VARIABLE_NAME name, VARIABLE_VALUE value FROM INFORMATION_SCHEMA.GLOBAL_STATUS }, { Slice => {} }); $sth->execute() || die $sth->errstr; my $response = HTTP::Response->new(200, undef, HTTP::Headers->new( Content_Type => "application/json", )); my $result = {}; while (my $row = $sth->fetchrow_arrayref) { $result->{$row->[0]} = $row->[1]; } $response->add_content(to_json($result, { ascii => 1, pretty => 1 })); return $c->send_response($response); }, Fetching current server status could be as simple as fetching http://127.0.0.1/statusz
  • 16. Status • Code hosted at LaunchPad. • Contributing to MariaDB 10.0 soon. • Stuff needs to be tidied up. • Future steps include better Table Functions.