Seitenanfang

Creating Tie::Hash::MongoDB from scratch using Padre

Dieser Post wurde aus meiner alten WordPress-Installation importiert. Sollte es Darstellungsprobleme, falsche Links oder fehlende Bilder geben, bitte einfach hier einen Kommentar hinterlassen. Danke.


Perl's hash is very powerful, it stores any kind of data, but it's kept in memory and this is not always wanted. The powerful "tie" function binds a hash to a Perl module which could do whatever_it_wants with the data.

Today I'ld like to show you how easy a has could be connected to a database. A module which connects a hash to SQL is already on CPAN, so let's go with MongoDB.

It will be called Tie::Hash::MongoDB, because it connects a has to a MongoDB document.

A German saying is "Aller Anfang ist schwer" meaning something like "the first step is always the hardest", but this is not true for the new module. Let's open Padre, the famous Perl IDE, and click on "file", "new..." and "Perl distribution". Fill in the name, author name and the other few things which Padre requires to build the new distro.

Clicking OK instructs Padre to create the directory structure and required files for the new distribution and open the main module source file lib/Tie/Hash/MongoDB.pm

First thing to do within the source is replacing some comments with real values:

  • the great new Tie::Hash::MongoDB in line 8
  • the summary starting at line 21
  • remove the "EXPORT" block starting at line 30 and
  • cut down "SUBROUTINES/METHODS" to "METHODS" because the module will be OOP only.
Padre show the two predefined functions "function1" and "function2" on the right, because I enabled the functions pane. The project's directory structure is shown on the left (maybe because I enabled the directory/project browser).

Enough comments and text, let's start developing the module.

tie expects some fixed named methods for working with the hash:

  • TIEHASH - tie the hash to the data source (the MongoDB document for our module)
  • DELETE - delete a key
  • EXISTS - check if a named key exists
  • FETCH - fetch a key (and it's value) from the data source
  • FIRSTKEY - get the first key from the list of keys
  • NEXTKEY - get the next key from the list of keys or undef at the end of the list
  • STORE - write a key (and it's value) to the data source
  • UNTIE - close the data source, remove the connection between the hash and the MongoDB document
Sounds pretty easy. Let's start creating the methods by grabbing the list and pushing it through Padres "filter through Perl" plugin.

The input/output option is set to "wrap in map" which puts map { } around the code in the first text window:

<<_EOT_;=head2 $_

\$object->$_(\$key)

Does something...

=cut

sub $_ { my \$self = shift; my \$key = shift;

return;}_EOT_

This code generates a skeleton for every fixed named method expected by tie and I also added the key as the first argument, because most of the methods will need it anyway.

Clicking "run filter", the left button at the bottom creates the final source and "Insert" (the middle button) surprisingly inserts the final code into the MongoDB.pm file.

Finally, the skeleton is ready!

TIEHASH will be called as a constructor for Tie::Hash::MongoDB and will receive all tie-arguments starting at the third:

sub TIEHASH { my $class = shift; my $id = shift; my $args = shift || {};

# Fill in some defaults my $server_name = $args->{server} || 'localhost'; my $port = $args->{port} || 27017; my $database_name = $args->{database} || 'default'; my $collection_name = $args->{collection} || 'default';

# Create the object my $self = bless {}, $class;

# Connect to the server, select the database and get a collection handle my $connection = MongoDB::Connection->new(host => $server_name, port => $port); my $database = $connection->$database_name; $self->{collection} = $database->collection_name;

if (defined($args{id})) # Create an id object $self->{id} = MongoDB::OID->new( value => $args{id} );

# Create a new document using the given id unless it's already on the server $self->{id} = $self->{collection}->insert({_id => $id }) unless $self->{collection}->query({_id => $id })->count; } else { # Create an empty document if no id was found $self->{id} = $self->{collection}->insert({}); }

return $self;}

This looks much more complicated than it is:
  • the TIEHASH constructor receives the class, the id and the connection data as arguments
  • every argument is copied into local variables (the given hash would be changed otherwise) and missing data is filled using default values
  • a new object is being born, blessed to the (current) class
  • the module connects to the server, selects the database and requests a collection handle using the MongoDB driver
  • a fresh, clean, empty document is being written to the server if an id is given and it's not already existent, otherwise a new id is being created using an empty document
  • the new object is returned to the caller
Thats all, tie will do the magic connecting a hash to the new object.

The following steps are easy, they will be shown in the second part of this guide (hopefully tomorrow).

 

2 Kommentare. Schreib was dazu

  1. Warning: file_get_contents(http://api.hostip.info/country.php?ip=86.178.88.131) [function.file-get-contents]: failed to open stream: HTTP request failed! HTTP/1.1 503 Service Temporarily Unavailable in /var/www/pal-blog.de/wp-content/plugins/statsurfer/append.php on line 314

  2. Oh I really love Updates :-( Thanks for the advice

Schreib was dazu

Die folgenden HTML-Tags sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>