Using SQLITE database with Perl on OpenWRT - ScienceChronicle
ScienceChronicle
August 21, 2024

Using SQLITE database with Perl on OpenWRT

Posted on August 21, 2024  •  3 minutes  • 485 words
Table of contents

This article discusses using an SQLite database with Perl on the OpenWRT openwrt-23.05 branch (git-23.233.52805-dae2684). We aim to use an SQLite database with Perl.

First, we need to install the DBI module and then find and install DBD for SQLite. Let’s examine the directory of Perl modules available on OpenWRT: Perl Modules on OpenWRT .

One can see that the DBI module is present: perl-dbi . After installing it, let’s check which DBD modules are included:

Let’s find the Perl installation path:

perl -MDBI -e 'print $INC{"DBI.pm"}, "\n";'
/usr/lib/perl5/5.28/DBI.pm

Next, we look for DBD modules:

ls /usr/lib/perl5/5.28/DBD
DBM.pm       ExampleP.pm  File.pm      Gofer        Gofer.pm     Mem.pm       NullP.pm     Proxy.pm     Sponge.pm

Unfortunately, we don’t have the SQLite DBD module. Additionally, we cannot find any precompiled package named “perl-dbd-sqlite” in the package list.

One possible solution is to compile the module on the required architecture and copy it to OpenWRT. The architecture on OpenWRT is:

Linux OpenWrt 5.15.150 #0 SMP Fri Mar 22 22:09:42 2024 aarch64 GNU/Linux

We could do this with QEMU, but in this post, we chose another approach. We’ll install sqlite3-cli and write a Perl wrapper around it.

Install the Utility

First, install the utility:

opkg update 
opkg install sqlite3-cli

Write the Wrapper

Next, we write a wrapper:

package My::Sqlite;

use strict;
use warnings;

use JSON::PP;
use Try::Tiny;

sub new {
  my ($class, $dbname) = @_;
  my $self = {};
  $self->{dbname} = $dbname;
  $self->{codec} = JSON::PP->new->pretty; 
  bless $self, $class;  
  return $self;
}

sub exec {
  my ($self, $sql) = @_;
  my $dbname = $self->{dbname};
  my $json = `sqlite3 -cmd ".timeout 1000" -json $dbname "$sql"`;
  my $h = [];
  if ($json ne "") {
    try {
      $h = $self->{codec}->decode($json);
    } 
    catch {
      $h = undef;
    };
  }
  return $h;
}

1;

Note that the module uses the JSON::PP and Try::Tiny modules, which are available in the Perl repository for OpenWRT.

We use the -cmd option for sqlite3 to avoid the “database is locked (6)” error. By default, the timeout for sqlite3 is 0. For more details, refer to the SQLite documentation: busy_timeout .

Using the Module

Place the Sqlite.pm module into the perllib/My folder. To use the module:

use strict;
use warnings;

use lib "perllib";
use My::Sqlite;

my $db = My::Sqlite->new("test.db");
my $response1 = $db->exec("CREATE TABLE IF NOT EXISTS client(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
if (! defined $response1 ) {
  die "Error using DB";
}

my $response2 = $db->exec("INSERT INTO client(name) VALUES('John')");
if (! defined $response2 ) {
  die "Error using DB";
}

my $response3 = $db->exec("SELECT * FROM client");
if (! defined $response3 ) {
  die "Error using DB";
}

foreach my $row (@$response3) {
  print "id: ", $row->{id}, " name: ", $row->{name}, "\n";
}

Thus, with a simple wrapper, we can simplify our work without needing to compile DBD for the OpenWRT architecture. Happy coding!


This version should be clearer and more polished while maintaining all the technical details and code you provided.


Share


Tags


Counters

Support us

Science Chronicle