Redis::Object - Use Redis with an ORMish interface
Implements a scaled down ORM-like interface to access Redis as a database. If you want to use Redis as a cache, use Redis instead.
package MyRedisDatabase; use Moose; extends qw/ Redis::Object /; has tables => ( isa => 'ArrayRef[Str]', is => 'ro', default => sub { [ qw/ SomeTable / ] } ); __PACKAGE__->make_immutable; package MyRedisDatabase::SomeTable; use Moose; with qw/ Redis::Object::Table /; has attrib1 => ( isa => 'Str', is => 'rw', default => 'Something' ); has attrib2 => ( isa => 'StrIndexed', is => 'rw', required => 1 ); has attrib3 => ( isa => 'StrIndexedSafe', is => 'rw', required => 1 ); has attrib4 => ( isa => 'Int', is => 'rw' ); has attrib5 => ( isa => 'HashRef', is => 'rw' ); has attrib6 => ( isa => 'ArrayRef', is => 'rw' ); __PACKAGE__->make_immutable; package main; # init database my $db = MyRedisDatabase->new( server => '127.0.0.1:6379' ); # create item my $item = $db->create( SomeTable => { attrib1 => "Hello", attrib2 => "Will be indexed", attrib3 => "Will-too-be-indexed", attrib4 => 123, attrib5 => { something => "serializeable" }, attrib6 => [ 1..99 ] } ); print "Created ". $item->id; # fetch item by id my $item = $db->find( SomeTable => $id ); print $item->attrib1. "\n"; # search items my $result = $db->search( SomeTable => { attrib1 => "Hello", attrib2 => 123 } ); while( my $item = $result->next ) { print "Found ". $item->id. "\n"; } # update item $item->attrib1( "bla" ); # set directly, will be persisted in the next update $db->update( $item, { # set additonal attrib2 => 333 } ); $item->attrib2( 999 ); $item->update( { # call update on the item, with additional new values attrib1 => "Hallo" } ); # remove an item $db->remove( $item ); $item->remove; # clear a table (remvoe all entries!) $db->truncate( 'SomeTable' );
Redis is more than a simple key-value store - but it is no relational database, by any means. So limit your expectations towards complex searching or sorting (actually, there is no sorting at all, yet).
This interface implements searching by primary key (an integer ID, which is automatically assigened to each "row" in the database), searching indexed String values with compare- and prefix-search. All search capability aside from this results in a full "table" scan.
This interface allows you to define certain columes as indexed. Those columes have to be of the following tyhoes:
StrIndexed
Can contain anything you want - howver, it is not guranteed, that this index will really work in if you use special chars, which (i had no tested and) are not searchable by the wildcard-keysearch. Use on your own risk and run your own tests!
StrIndexedSafe
Can only contain safe characters "a".."z", "A".."Z" and 0..9. Also the length is limited to 256 characters. However, you can possibly use very long keys in redis. Also you should account for the prefix length (composed of the prefix, the table name and the attribute name). However, if you need longer contents, go with StrIndexed.
"a".."z", "A".."Z"
0..9
The indices can be search with a wildcard search, such as Something* or even Some*thing*.
Something*
Some*thing*
The table
package MyRedisDatabase::MyTable; use Moose; with qw/ Redis::Object::Table /; has indexedkey => ( isa => "StrIndexed", is => "rw", required => 1 ); has safeindexedkey => ( isa => "StrIndexedSafe", is => "rw", required => 1 );
Using the search
$db->create( MyTable => { indexed => "Some content", safeindexedkey => "Some-safe-content" } ); my $result = $db->search( MyTable => { safeindexedkey => "Some*" } ); while( my $item = $result->next ) { .. }
This interface will store your instances, represented by Redis::Object::Table-objects, in a distinct structure. Do not try to use this interface with pre-existing data! Also modifying the data manually later on is at your own risk!
The structure relates to the Moose attributes of your classes. Assuming the following table-class:
package MyRedisDatabase::MyTable; use Moose; with qw/ Redis::Object::Table /; has somekey => ( isa => "StrIndexed", is => "rw", required => 1 ); has otherkey => ( isa => "Int", is => "rw", required => 1 );
Assumnug you create an create like so:
$db->create( MyTable => { somekey => "Some Content", otherkey => 123 } );
The resulting "rows" for the entry (with the ID 999) would look something like this:
999
# contains the an ID timestamp, used for certain lookups mytable:999:_ # = timestamp # contains the values of both attributes mytable:999:somekey # Some Content mytable:999:otherkey # = 123 # indexed key "somekey" for fast lookup mytable:999:_:somekey:Some_Content # timestamp
There is also a special key/value per table, which contains an incrementing integer (the "primary key")
mytable:_id # = last id
Defaults to 127.0.0.1:6379
Additional args forwarded to the "new" in Redis method.
Array of table names
Optional prefix for all key names in Redis
server
The Redis server and port, defaults to '127.0.0.1:6379'
tables
Arrayref of table names. A table has to be implemented as a perl module with the same name.
Create new item
The name of the table
The attributes of the object to be created
Update existing item into database
Finds a single item by id
Name of the table
ID of the item
Search multiple items by attribute filter.
You can
The search condition can have multiple shapes:
A ref to a grep-like sub. Example:
my $sub_filter = sub { my ( $item ) = @_; # add item to list return 1 if ( $item->attribute eq "something" ); # drop item return 0; };
A whole table scan will be performed
A subset of keys and value constraints, Example:
# this is an AND-filter: all constraints have to fit my $filter_ref = { # simple string matching attribute1 => 'something', # string matches one attribute1 => 'something', # regex filter attribute2 => qr/^123/, # custom filter attribute3 => sub { my ( $value) = @_; return $value =~ /^xx/ && length( $value ) > 99; } }
Searches on indexed attributes (of the type Str)
or_search
Perform an or-search instead (default: and-search)
Example
my $result = $db->search( TableName => { attrib => "bla" } ); while( my $item = $result->next ) { # .. }
Remove a single or multiple items
Single usage
$db->remove( $item );
Multie usage
$db->remove( $table => $search_ref );
Empties a whole table. ID will be reset. Use with caution.
Returns the total amount of entries in a table.
Ulrich Kautz <uk@fortrabbit.de>
Copyright (c) 2011 the "AUTHOR" as listed above
Same license as Perl itself.
1 POD Error
The following errors were encountered while parsing the POD:
Unterminated L<...> sequence
To install Redis::Object, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Redis::Object
CPAN shell
perl -MCPAN -e shell install Redis::Object
For more information on module installation, please visit the detailed CPAN module installation guide.