X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMooseX%2FStorage.pm;h=72a0b74b37e41cff398cf7b49410dc7f9bb8021a;hb=4747c531e32782b51fca0f2744698bfb6c1bcd05;hp=e3e2c3ecf5155857b3808115b4cc24a20c235231;hpb=e97396242e8acc8dff6cf3f4f5961ee1fbd8498e;p=gitmo%2FMooseX-Storage.git
diff --git a/lib/MooseX/Storage.pm b/lib/MooseX/Storage.pm
index e3e2c3e..72a0b74 100644
--- a/lib/MooseX/Storage.pm
+++ b/lib/MooseX/Storage.pm
@@ -1,32 +1,265 @@
package MooseX::Storage;
+use Moose qw(confess);
+
+use MooseX::Storage::Meta::Attribute::DoNotSerialize;
+
+our $VERSION = '0.07';
+our $AUTHORITY = 'cpan:STEVAN';
sub import {
my $pkg = caller();
+
+ return if $pkg eq 'main';
+
+ ($pkg->can('meta'))
+ || confess "This package can only be used in Moose based classes";
+
$pkg->meta->alias_method('Storage' => sub {
- my $engine_name = 'MooseX::Storage::' . (shift);
- Class::MOP::load_class($engine_name)
- || die "Could not load engine ($engine_name) for package ($pkg)";
- return $engine_name;
+ my %params = @_;
+
+ if (exists $params{'base'}) {
+ $params{'base'} = ('Base::' . $params{'base'});
+ }
+ else {
+ $params{'base'} = 'Basic';
+ }
+
+ my @roles = (
+ ('MooseX::Storage::' . $params{'base'}),
+ );
+
+ # NOTE:
+ # you don't have to have a format
+ # role, this just means you dont
+ # get anything other than pack/unpack
+ push @roles => 'MooseX::Storage::Format::' . $params{'format'}
+ if exists $params{'format'};
+
+ # NOTE:
+ # if you do choose an IO role, then
+ # you *must* have a format role chosen
+ # since load/store require freeze/thaw
+ if (exists $params{'io'}) {
+ (exists $params{'format'})
+ || confess "You must specify a format role in order to use an IO role";
+ push @roles => 'MooseX::Storage::IO::' . $params{'io'};
+ }
+
+ Class::MOP::load_class($_)
+ || die "Could not load role (" . $_ . ") for package ($pkg)"
+ foreach @roles;
+
+ return @roles;
});
}
-package MooseX::Storage::Base;
-use Moose::Role;
+1;
-requires 'pack';
-requires 'unpack';
+__END__
-requires 'freeze';
-requires 'thaw';
+=pod
-requires 'load';
-requires 'store';
+=head1 NAME
-1;
+MooseX::Storage - An serialization framework for Moose classes
-__END__
+=head1 SYNOPSIS
-=pod
+ package Point;
+ use Moose;
+ use MooseX::Storage;
+
+ our $VERSION = '0.01';
+
+ with Storage('format' => 'JSON', 'io' => 'File');
+
+ has 'x' => (is => 'rw', isa => 'Int');
+ has 'y' => (is => 'rw', isa => 'Int');
+
+ 1;
+
+ my $p = Point->new(x => 10, y => 10);
+
+ ## methods to pack/unpack an
+ ## object in perl data structures
+
+ # pack the class into a hash
+ $p->pack(); # { __CLASS__ => 'Point-0.01', x => 10, y => 10 }
+
+ # unpack the hash into a class
+ my $p2 = Point->unpack({ __CLASS__ => 'Point-0.01', x => 10, y => 10 });
+
+ ## methods to freeze/thaw into
+ ## a specified serialization format
+ ## (in this case JSON)
+
+ # pack the class into a JSON string
+ $p->freeze(); # { "__CLASS__" : "Point-0.01", "x" : 10, "y" : 10 }
+
+ # unpack the JSON string into a class
+ my $p2 = Point->thaw('{ "__CLASS__" : "Point-0.01", "x" : 10, "y" : 10 }');
+
+ ## methods to load/store a class
+ ## on the file system
+
+ $p->store('my_point.json');
+
+ my $p2 = Point->load('my_point.json');
+
+=head1 DESCRIPTION
+
+MooseX::Storage is a serialization framework for Moose, it provides
+a very flexible and highly pluggable way to serialize Moose classes
+to a number of different formats and styles.
+
+=head2 Important Note
+
+This is still an early release of this module, so use with caution.
+It's outward facing serialization API should be considered stable,
+but I still reserve the right to make tweaks if I need too. Anything
+beyond the basic pack/unpack, freeze/thaw and load/store should not
+be relied on.
+
+=head2 Levels of Serialization
+
+There are 3 levels to the serialization, each of which builds upon
+the other and each of which can be customized to the specific needs
+of your class.
+
+=over 4
+
+=item B
+
+The first (base) level is C and C. In this level the
+class is serialized into a Perl HASH reference, it is tagged with the
+class name and each instance attribute is stored. Very simple.
+
+This level is not optional, it is the bare minumum that
+MooseX::Storage provides and all other levels build on top of this.
+
+=item B
+
+The second (format) level is C and C. In this level the
+output of C is sent to C or the output of C is sent
+to C. This levels primary role is to convert to and from the
+specific serialization format and Perl land.
+
+This level is optional, if you don't want/need it, you don't have to
+have it. You can just use C/C instead.
+
+=item B
+
+The third (io) level is C and C. In this level we are reading
+and writing data to file/network/database/etc.
+
+This level is also optional, it does however require the C level
+to be present (at least the current state does).
+
+=back
+
+=head2 How we serialize
+
+There are always limits to any serialization framework, there are just
+some things which are really difficult to serialize properly and some
+things which cannot be serialized at all.
+
+=head2 What can be serialized?
+
+Currently only numbers, string, ARRAY refs, HASH refs and other
+MooseX::Storage enabled objects are supported.
+
+With Array and Hash references the first level down is inspected and
+any objects found are serialized/deserialized for you. We do not do
+this recusively by default, however this feature may become an
+option eventually.
+
+The specific serialize/deserialize routine is determined by the
+Moose type constraint a specific attribute has. In most cases subtypes
+of the supported types are handled correctly, and there is a facility
+for adding handlers for custom types as well. This will get documented
+eventually, but it is currently still in development.
+
+=head2 What can not be serialized?
+
+We do not support CODE references yet, but this support might be added
+in using B::Deparse or some other deep magic.
+
+Scalar refs are not supported, mostly because there is no way to know
+if the value being referenced will be there when the object is inflated.
+I highly doubt will be ever support this in a general sense, but it
+would be possible to add this yourself for a small specific case.
+
+Circular references are specifically disallowed, however if you break
+the cycles yourself then re-assemble them later you can get around this.
+The reason we disallow circular refs is because they are not always supported
+in all formats we use, and they tend to be very tricky to do for all
+possible cases. It is almost always something you want to have tight control
+over anyway.
+
+=head1 CAVEAT
+
+This is B a persistence framework, changes to your object after
+you load or store it will not be reflected in the stored class.
+
+=head1 EXPORTS
+
+=over 4
+
+=item B
+
+This module will export the C method will can be used to
+load a specific set of MooseX::Storage roles to implement a specific
+combination of features. It is meant to make things easier, but it
+is by no means the only way. You can still compose your roles by
+hand if you like.
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item B
+
+=back
+
+=head2 Introspection
+
+=over 4
+
+=item B
+
+=back
+
+=head1 TODO
+
+This module needs docs and probably a Cookbook of some kind as well.
+This is an early release, so that is my excuse for now :)
+
+For the time being, please read the tests and feel free to email me
+if you have any questions. This module can also be discussed on IRC
+in the #moose channel on irc.perl.org.
+
+=head1 BUGS
+
+All complex software has bugs lurking in it, and this module is no
+exception. If you find a bug please either email me, or add the bug
+to cpan-RT.
+
+=head1 AUTHOR
+
+Chris Prather Echris.prather@iinteractive.comE
+
+Stevan Little Estevan.little@iinteractive.comE
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 by Infinity Interactive, Inc.
+
+L
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
=cut