The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Package::Transporter::Generator::SQL_Table - store your subroutines in a database

SYNOPSIS

        use Package::Transporter sub{eval shift};
        use Package::Transporter::Generator::SQL_Table;

        use DBI;
        my $dbh = DBI->connect('DBI:mysql:perlsub', LOGIN, PASSWORD)
        || Carp::confess("connect: $DBI::errstr\n");
        
        # a lexical variable visible to hello_world()
        my $date = scalar(localtime(time()));
        
        {
                my $pkg = Package::Transporter->new(sub{eval shift});
                my $generator = Package::Transporter::Generator::SQL_Table
                        ->new($pkg, $dbh);
                $generator->prototypes($pkg, $dbh);
                $pkg->register_potential($generator, 'FOR_SELF', $generator->matcher($dbh));
        };
                
        yn(!potentially_defined('hello_worlds'));
        yn(potentially_defined('hello_world'));
        yn(!defined(&hello_world));

        #hello_world(7); # try this to see $date
        hello_world();

        yn(defined(&hello_world));
        exit(0);

DESCRIPTION

The generator can be used to keep the subroutines of a module as rows in a SQL database table. In case your module has a huge number of subroutines, out of which only a few are typically used, keeping the subroutines in an external source might conserve time and memory.

Executes a SQL select statement to identify a suitable subroutine defintion. Control over the database means control over your program.

Prototypes

Prototype definitions are supported, but have to be explicitely requested. It only makes sense if defining and requesting package are the same (therefore the explicit request). Beside that, the correct prototype might not be known at compile time. However, for AUTOLOADed subroutines the prototype is not checked in Perl5, so for the moment prototypes are pretty much useless.

SQL STATEMENTS

Database Creation

        CREATE DATABASE IF NOT EXISTS perlsub;
        USE perlsub;

Table Creation

        DROP TABLE IF EXISTS _subroutines;
        CREATE TABLE _subroutines (
                sub_event enum('on_load', 'on_demand') NOT NULL default 'on_demand',
                sub_package varchar(255),
                sub_argc int,
                sub_signature varchar(255),
                sub_name varchar(251) NOT NULL,
                sub_prototype varchar(255),
                sub_body text NOT NULL,
                __id int(10) unsigned NOT NULL auto_increment,
                PRIMARY KEY (__id),
                UNIQUE KEY __id (__id)
        );
        
        INSERT INTO _subroutines
        (sub_name, sub_prototype, sub_body, sub_argc) VALUES
        ('yn', '$', 'print STDOUT ($_[0] ? \'Yes\' : \'No\'), "\n";', NULL),
        ('hello_world', NULL, 'print "Hello World.\n";', NULL),
        ('hola_mundo', NULL, 'print "Hola Mundo.\n";', NULL),
        ('salut_monde', NULL, 'print "Salut Monde.\n";', NULL),
        ('hello_world', '$', 'print "Hello World. ($date)\n";', 1),
        ('hola_mundo', '$', 'print "Hola Mundo. ($date)\n";', 1),
        ('salut_monde', '$', 'print "Salut Monde. ($date)\n";', 1);
                

Access to Table

        CREATE DATABASE IF NOT EXISTS perlsub;
        GRANT SELECT ON perlsub.* TO autoloader@localhost
                IDENTIFIED BY __PASSWORD__;
        

Query For Subroutines

        SELECT sub_prototype, sub_body
        FROM _subroutines
        WHERE (sub_name = ?)
        AND (sub_event = 'on_demand')
        AND ((sub_package = ?) OR ISNULL(sub_package))
        AND ((sub_argc = ?) OR ISNULL(sub_argc))
        ORDER BY sub_package DESC, sub_argc DESC
        LIMIT 1
        

ANYTHING ELSE

Please see the documentation of the upstream package Package::Transporter.