Permalink
Browse files

Too much to write out. Finishing ideas from last night. Should be rea…

…dy to release.
  • Loading branch information...
1 parent cef0a1a commit fdb02b0d2d6da08764f2a09b80cbe3f123bb9019 @gphat committed Sep 5, 2009
View
2 Changes
@@ -1,4 +1,4 @@
-Revision history for Data-Verifier
+Revision history for Data-SearchEngine
0.06
* Add post_check key
View
25 MANIFEST
@@ -1,25 +0,0 @@
-Changes
-ignore.txt
-inc/Module/Install.pm
-inc/Module/Install/Base.pm
-inc/Module/Install/Can.pm
-inc/Module/Install/Fetch.pm
-inc/Module/Install/Makefile.pm
-inc/Module/Install/Metadata.pm
-inc/Module/Install/Win32.pm
-inc/Module/Install/WriteAll.pm
-lib/Data/Verifier.pm
-lib/Data/Verifier/Filters.pm
-lib/Data/Verifier/Results.pm
-Makefile.PL
-MANIFEST This list of files
-META.yml
-README
-t/00-load.t
-t/01-simple.t
-t/02-types.t
-t/03-filters.t
-t/04-lengths.t
-t/05-result-merge.t
-t/06-dependents.t
-t/07-post-check.t
View
45 README
@@ -1,49 +1,22 @@
-Data::Verifier - Profile based data verification with Moose type constraints.
+NAME
+
+Data::SearchEngine - A role for search engines and cacheable results.
SYNOPSIS
-Data::Verifier allows you verify data (such as web forms, which was the
-original idea) by leveraging the power of Moose's type constraint system.
-
- use Data::Verifier;
-
- my $dv = Data::Verifier->new(
- filters => [ qw(trim) ]
- profile => {
- name => {
- required => 1,
- type => 'Str',
- filters => [ qw(collapse) ]
- }
- age => {
- type => 'Int';
- },
- sign => {
- required => 1,
- type => 'Str'
- }
- }
- );
-
- my $results = $dv->verify({
- name => 'Cory', age => 'foobar'
- });
-
- $results->success; # no
-
- $results->is_invalid('name'); # no
- $results->is_invalid('age'); # yes
-
- $results->is_missing('name'); # no
- $results->is_missing('sign'); # yes
+There are B<lots> of search engine libraries. Each has a different interface.
+The goal of Data::SearchEngine is to provide a simple, extensive set of
+classes and roles that you can use to wrap a search implementation. The net
+result will be an easily swappable backend with a common set of features, such
+as serialize of results for use with a cache.
AUTHOR
Cory G Watson, C<< <gphat at cpan.org> >>
COPYRIGHT & LICENSE
-Copyright 2009 Cold Hard Code, LLC
+Copyright 2009 Cory G Watson
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
View
2 ignore.txt
@@ -6,5 +6,5 @@ _build*
pm_to_blib*
*.tar.gz
.lwpcookies
-Data-Verifier-*
+Data-SearchEngine-*
cover_db
View
174 lib/Data/SearchEngine.pm
@@ -20,179 +20,35 @@ classes and roles that you can use to wrap a search implementation. The net
result will be an easily swappable backend with a common set of features, such
as serialize of results for use with a cache.
-The first step is to use the L<Data::SearchEngine> role in a class that wraps
-your search implemenation:
-
- package MySearch::Wrapper;
- use Moose;
-
- with 'Data::SearchEngine';
-
- # implement query
-
-Data::Verifier allows you verify data (such as web forms, which was the
-original idea) by leveraging the power of Moose's type constraint system.
-
- use Data::Verifier;
-
- my $dv = Data::Verifier->new(
- filters => [ qw(trim) ]
- profile => {
- name => {
- required => 1,
- type => 'Str',
- filters => [ qw(collapse) ]
- }
- age => {
- type => 'Int';
- },
- sign => {
- required => 1,
- type => 'Str'
- }
- }
- );
-
- my $results = $dv->verify({
- name => 'Cory', age => 'foobar'
- });
-
- $results->success; # no
-
- $results->is_invalid('name'); # no
- $results->is_invalid('age'); # yes
-
- $results->is_missing('name'); # no
- $results->is_missing('sign'); # yes
-
- $results->get_value('name'); # Filtered, valid value
- $results->get_value('age'); # undefined, as it's invalid
-
-=head1 MOTIVATION
-
-Data::Verifier firstly intends to leverage Moose's type constraint system,
-which is significantly more powerful than anything I could create for the
-purposes of this module. Secondly it aims to keep a fairly simple interface
-by leveraging the aforementioned type system to keep options to a minumum.
-
-=head1 WARNING
-
-This module is under very active development and, while the current API
-will likely not be changed, features will be added rapidly.
-
-=head1 ATTRIBUTES
-
-=head2 filters
-
-An optional arrayref of filter names through which B<all> values will be
-passed.
-
-=head2 profile
-
-The profile is a hashref. Each value you'd like to verify is a key. The
-values specify all the options to use with the field. The available options
-are:
-
-=over 4
-
-=item B<coerce>
-
-If true then the value will be given an opportunity to coerce via Moose's
-type system.
-
-=item B<dependent>
-
-Allows a set of fields to be specifid as dependents of this one. The argument
-for this key is a full-fledged profile as you would give to the profile key:
+=head2 Step 2 - Extend the Query
- my $verifier = Data::Verifier->new(
- profile => {
- password => {
- dependent => {
- password2 => {
- required => 1,
- }
- }
- }
- }
- );
+Subclass the L<Data::SearchEngine::Query> object and add attributes that are
+needed for your implementation. Be sure to use the Digestable trait for any
+attributes that contribute to the results to guarantee uniqueness.
-In the above example C<password> is not required. If it is provided then
-password2 must also be provided. If any depedents of a field are missing or
-invalid then that field is B<invalid>. In our example if password is provided
-and password2 is missing then password will be invalid.
+=head2 Step 2 - Wrap a search implementation
-=item B<filters>
-
-An optional list of filters through which this specific value will be run.
-See the documentation for L<Data::Verifier::Filters> to learn more. This value
-may be either a string or an arrayref of strings.
-
-=item B<max_length>
-
-An optional length which the value may not exceed.
-
-=item B<min_length>
-
-An optional length which the value may not be less.
-
-=item B<post_check>
-
-The C<post_check> key takes a subref and, after all verification has finished,
-executes the subref with the results of the verification as it's only argument.
-The subref's return value determines if the field to which the post_check
-belongs is invalid. A typical example would be when the value of one field
-must be equal to the other, like an email confirmation:
-
- my $verifier = Data::Verifier->new(
- profile => {
- email => {
- required => 1,
- dependent => {
- email2 => {
- required => 1,
- }
- },
- post_check => sub {
- my $r = shift;
- return $r->get_value('email') eq $r->get_value('email2');
- }
- },
- }
- );
-
- my $results = $verifier->verify({
- email => 'foo@example.com', email2 => 'foo2@example.com'
- });
-
- $results->success; # false
- $results->is_valid('email'); # false
- $results->is_valid('email2); # true, as it has no post_check
-
-In the above example, C<success> will return false, because the value of
-C<email> does not match the value of C<email2>. C<is_valid> will return false
-for C<email> but true for C<email2>, since nothing specifically invalidated it.
-In this example you should rely on the C<email> field, as C<email2> carries no
-significance but to confirm C<email>.
-
-=item B<required>
+The first step is to use the L<Data::SearchEngine> role in a class that wraps
+your search implemenation. You can find an example in
+L<Data::SearchEngine::Results>.
-Determines if this field is required for verification.
+=head2 Step 3 - Profit!!!
-=item B<type>
+Optionally setup a caching implementation using Query's C<digest> method and
+the C<freeze>/C<thaw> methods from Results.
-The name of the Moose type constraint to use with verifying this field's
-value.
+=head1 WARNING
-=back
+This module is under very active development and the API may change. Consider
+this a development release and please send along sugguestions!
=head1 AUTHOR
Cory G Watson, C<< <gphat at cpan.org> >>
=head1 COPYRIGHT & LICENSE
-Copyright 2009 Cold Hard Code, LLC
+Copyright 2009 Cory G Watson
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
View
59 lib/Data/SearchEngine/Meta/Attribute/Trait/Digestable.pm
@@ -0,0 +1,59 @@
+package Data::SearchEngine::Meta::Attribute::Trait::Digestable;
+use Moose::Role;
+
+has digest_value => (
+ is => 'ro',
+ isa => 'CodeRef',
+ predicate => 'has_digest_value'
+);
+
+1;
+
+__END__
+
+=head1 NAME
+
+Data::SearchEngine::Meta::Attribute::Trait::Digestable - Digest flag & configuration
+
+=head1 SYNOPSIS
+
+If a L<Data::SearchEngine::Query> attribute has this meta-attribute, then it
+will be added to the digest that identifies the uniqueness of a Query.
+
+If the attribute is a scalar, you do not need to specify a C<digest_value>.
+The scalar value can just be added to the digest.
+
+For example, if your Query subclass allows the choice of a particular
+category to search within, you would obviously want queries with different
+categories (or lack thereof) to have different digests.
+
+ has 'category' => (
+ traits => [qw(Digestable)],
+ is => 'rw',
+ isa => 'MyApp::Category',
+ digest_value=> sub { $self->category->name }
+ );
+
+When computing it's digest, your query will now add the value of the category
+to the computation, thereby guaranteeing uniqueness!
+
+=head1 ATTRIBUTES
+
+=head2 digest_value
+
+A coderef that will return a string identifying the value of this attribute
+for adding to the Query's digst.
+
+=head1 AUTHOR
+
+Cory G Watson, C<< <gphat at cpan.org> >>
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2009 Cory G Watson
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of either: the GNU General Public License as published
+by the Free Software Foundation; or the Artistic License.
+
+See http://dev.perl.org/licenses/ for more information.
View
5 lib/Data/SearchEngine/Modifiable.pm
@@ -10,7 +10,8 @@ __END__
=head1 NAME
-Data::SearchEngine::Modifiable - A role for search engines with an updateable index.
+Data::SearchEngine::Modifiable - A role for search engines with an updateable
+index.
=head1 SYNOPSIS
@@ -43,7 +44,7 @@ Cory G Watson, C<< <gphat at cpan.org> >>
=head1 COPYRIGHT & LICENSE
-Copyright 2009 Cold Hard Code, LLC
+Copyright 2009 Cory G Watson
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
View
62 lib/Data/SearchEngine/Query.pm
@@ -4,27 +4,32 @@ use MooseX::Storage;
with Storage(format => 'JSON', io => 'File');
+use Data::SearchEngine::Meta::Attribute::Trait::Digestable;
use Digest::SHA1;
has count => (
+ traits => [qw(Digestable)],
is => 'ro',
isa => 'Int',
default => 10
);
has order => (
+ traits => [qw(Digestable)],
is => 'ro',
isa => 'Str',
predicate => 'has_order'
);
has page => (
+ traits => [qw(Digestable)],
is => 'ro',
isa => 'Int',
default => 1
);
has query => (
+ traits => [qw(Digestable)],
is => 'ro',
isa => 'Str',
required => 1
@@ -34,12 +39,24 @@ sub digest {
my $self = shift;
my $digester = Digest::SHA1->new;
- $digester->add($self->count);
- if($self->has_order) {
- $digester->add($self->order);
+
+ my $attributes = $self->meta->get_attribute_map;
+ foreach my $aname (keys(%{ $attributes })) {
+ my $attr = $attributes->{$aname};
+
+ next unless $attr->does('Digest::SearchEngine::Meta::Attribute::Trait::Digestable');
+
+ if($attr->has_digest_value) {
+ $digester->add(lc($attr->digest_value));
+ } else {
+ my $reader = $attr->get_read_method;
+ my $val = $attr->$reader;
+ if(defined($val)) {
+ $digester->add(lc($val));
+ }
+ }
+
}
- $digester->add($self->page);
- $digester->add(lc($self->query));
return $digester->b64digest;
}
@@ -51,35 +68,17 @@ __END__
=head1 NAME
-Data::Verifier::Query - Query to pass to an engine.
+Data::SearchEngine::Query - Query to pass to an engine.
=head1 SYNOPSIS
The query object has some common attributes one would expect when performing
-a search. It has the added benefit of producing a digest that can be used
+a search. It has the added benefit of producing a digest that can be used
with L<Data::SearchEngine::Results> ability to serialize to implement caching.
-Since your query may have different information, it is recommended that you
-subclass this class and add whatever attributes you need. Keep in mind,
-however, that you will need to implement your own C<digest> method if you
-add any new attributes.
-
- sub digest {
- my $self = shift;
-
- my $digester = Digest::SHA1->new;
- $digester->add($self->count);
- if($self->has_order) {
- $digester->add($self->order);
- }
- $digester->add($self->page);
- $digester->add(lc($self->query));
- return $digester->b64digest;
- }
-
-Adding a new attribute or two is as simple as copying the above code and
-adding them to the C<$digester> above so that they contribute to the
-uniqueness of the query
+If you add new attributes to a subclass, be sure and add the Digestable
+trait to any attributes you want to be included in the digest as document in
+L<Data::SearchEngine::Meta::Attribute::Trait::Digestable>.
=head1 ATTRIBUTES
@@ -99,6 +98,13 @@ Which page of results to show.
The query string to search for.
+=head1 METHODS
+
+=head2 digest
+
+Returns a unique digest identifying this Query. Useful as a key when
+caching.
+
=head1 AUTHOR
Cory G Watson, C<< <gphat at cpan.org> >>
View
17 lib/Data/SearchEngine/Results.pm
@@ -15,7 +15,7 @@ has items => (
isa => 'ArrayRef[Data::SearchEngine::Item]',
default => sub { [] },
provides => {
- count => 'total_items',
+ count => 'count',
get => 'get',
push => 'add',
}
@@ -25,6 +25,11 @@ has query => (
isa => 'Data::SearchEngine::Query',
required => 1,
);
+has total_count => (
+ is => 'ro',
+ isa => 'Int',
+ default => 0
+);
__PACKAGE__->meta->make_immutable;
@@ -34,7 +39,7 @@ __END__
=head1 NAME
-Data::Verifier::Results - Results of a Data::SearchEngine serach
+Data::SearchEngine::Results - Results of a Data::SearchEngine serach
=head1 SYNOPSIS
@@ -48,9 +53,13 @@ C<thaw> thanks to L<MooseX::Storage>.
use Time::HiRes;
sub query {
- # boring implementation
+
+ # boring, search specific implementation
- my $results = Data::SearchEngine::Results->new(query => $query);
+ my $results = Data::SearchEngine::Results->new(
+ query => $query
+ total_count => $total
+ );
my $start = time;
foreach $product (@sorted_products) {
View
5 lib/Moose/Meta/Attribute/Custom/Trait/Digestable.pm
@@ -0,0 +1,5 @@
+package Moose::Meta::Attribute::Custom::Trait::Digestable;
+
+sub register_implementation { 'Data::SearchEngine::Meta::Attribute::Trait::Digestable' }
+
+1;
View
9 t/00-load.t
@@ -1,9 +0,0 @@
-#!perl
-
-use Test::More tests => 1;
-
-BEGIN {
- use_ok( 'Data::Verifier' );
-}
-
-diag( "Testing Data::Verifier $Data::Verifier::VERSION, Perl $], $^X" );

0 comments on commit fdb02b0

Please sign in to comment.