Seitenanfang

Finishing Tie::Hash::MongoDB

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.


The first part of this guide explained how to create the skeleton of the new module and how to create the backend for tie'ing a hash to a MongoDB document.

This second part will finish the job by putting some useful code into the skeleton methods.

I'll walk through the methods in a (hopefully) logical order, but keep them in alphabetical order within the module.

STORE

The store method requires two arguments (not counting $self as it's OOP-tax and isn't being passed by the user), a key name and a value - which may be undef or empty - and should return the new value on success.
sub STORE { my $self = shift; my $key = shift; my $value = shift;

$self->{collection}->update({_id => $self->{id}}, {'$set' => {$key => $value}});

return $value;}

Easy job, isn't it? The new value is pushed into the document using the $set modifier (otherwise it'ld overwrite the whole document). MongoDB usually flushs updates and inserts in the background, so the module does. It neither gets nor checks any return value from ->update.

EXISTS

Wanna know if a key exists (defined or not) but not fetch it? No problem, use the brand new EXISTS method.
sub EXISTS { my $self = shift; my $key = shift;

return $self->{collection}->query({_id => $self->{id}, $key => {'$exists' => 'true'} })->count ? 1 : 0;}

The document id is unique, a maximum of one (our currently tied) document could match a query using the id. This query adds a check for the requested key. The return value must be either 1 (document containing the id and key found) or 0 (no document found) and the final ? 1 : 0 forces everything unexpected to clean true or false.

FETCH

Fetching a value out of the document is easy, too.
sub FETCH { my $self = shift; my $key = shift;

my $doc = $self->{collection}->find_one({_id => $self->{id}},{$key => 1});

return $doc ? $doc->{$key} : undef;}

Request the document from the database, but limit the returned data to the one key which is actually being requested. Return the value of the key or undef in case no document returned.

FIRSTKEY

Perl's keys() function consists of two backend functions: FIRSTKEY which should always return the first key of the list and NEXTKEY which returns the next key until all keys are fetched or FIRSTKEY is called again.

MongoDB doesn't support fetching only a list of keys which makes this call the most expensive one of the whole module, because it has to fetch the complete document.

sub FIRSTKEY { my $self = shift;

my $doc = $self->{collection}->find_one({_id => $id});

return unless $doc;

$self->{keys} = [keys(%$doc)];

return $self->NEXTKEY;}

No return value is given if no document could be found. If a document was fetched, the list of keys is being stored within the object and NEXTKEY is called to return the first key.

NEXTKEY

The co-function for FIRSTKEY returning keys from the list until is's empty.
sub NEXTKEY { my $self = shift;

return shift(@{$self->{keys}});}

The Tie::Hash::MongoDB's NEXTKEY ist really, really simple: Remove the first key from the list and return it.

If there is no list or the list is empty, Perl won't complain and return undef (as expected).

DELETE

Easy job again: Update the document using the MongoDB $unset modifier.
sub DELETE { my $self = shift; my $key = shift;

$self->{collection}->update({_id => $self->{id}}, {'$unset' => {$key => 1}});

}

Like UPDATE, delete has no return value from the MongoDB update call.

UNTIE

Every action is being passed to the database, there is really nothing to do here, because the database connection (collection handler) living in $self->{collection} is being killed by the destruction of the $self object instantly following the UNTIE call.
sub UNTIE {}
That's is, nothing to do here.

Done?

Yes, every method required by tie is there, but few things are left:
  • Some typos or syntax errors might wait to be fixed.
  • One or more test scripts should be written to check the new Tie::Hash::MongoDB module.
  • Every single document tie()'d to the database is currently opening a new connection to the MongoDB server, this should be changed, at least documents from the same collection should use the same connection.
  • The source should go through Perltidy before being submitted, maybe using Padre's Perltidy plugin.
  • The module should be pushed to CPAN.
 

Noch keine Kommentare. Schreib was dazu

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>