File Coverage

blib/lib/Coat/Persistent/Meta.pm
Criterion Covered Total %
statement 22 42 52.3
branch 0 4 0.0
condition 0 4 0.0
subroutine 7 13 53.8
pod 0 5 0.0
total 29 68 42.6


line stmt bran cond sub pod time code
1             package Coat::Persistent::Meta;
2              
3 3     3   58720 use strict;
  3         7  
  3         113  
4 3     3   70 use warnings;
  3         6  
  3         101  
5 3     3   16 use base 'Exporter';
  3         4  
  3         2407  
6              
7             # The placeholder for all meta-information saved for Coat::Persistent models.
8             my $META = {};
9              
10             # supported meta attributes for models
11             my @attributes = qw(table_name primary_key accessor);
12              
13             # accessor to the meta information of a model
14             # ex: Coat::Persistent::Meta->model('User')
15 0     0 0 0 sub registry { $META->{ $_[1] } }
16              
17             sub attribute {
18 0     0 0 0 my ($self, $class, $attribute) = @_;
19 0   0     0 $META->{ $class }{attributes} ||= [];
20 0         0 push @{ $META->{ $class }{'attributes'} }, $attribute;
  0         0  
21             }
22              
23             sub attribute_exists {
24 0     0 0 0 my ($self, $class, $attribute) = @_;
25 0         0 return grep /^$attribute$/, @{ $META->{ $class }{'attributes'} };
  0         0  
26             }
27              
28             sub attributes {
29 0     0 0 0 my ($self, $class) = @_;
30 0   0     0 $META->{ $class }{'attributes'} ||= [];
31 0         0 return @{ $META->{ $class }{'attributes'} };
  0         0  
32             }
33              
34             sub linearized_attributes {
35 0     0 0 0 my ($self, $class) = @_;
36            
37 0         0 my @all = ();
38 0         0 foreach my $c (reverse Coat::Meta->linearized_isa( $class ) ) {
39 0         0 foreach my $attr (Coat::Persistent::Meta->attributes( $c )) {
40 0 0       0 push(@all, $attr) unless (grep(/^$attr$/, @all));
41             }
42             }
43 0         0 return @all;
44             }
45              
46             # this is to avoid writing several times the same setters and
47             # writers for the class
48             # (closures are the hidden gold behind Perl!)
49             # Examples:
50             # - set the table name for a model
51             # Coat::Persistent::Meta->table_name('User', 'users');
52             # - get the primary_key
53             # Coat::Persistent::Meta->primary_key('User');
54             #
55             sub _create_model_accessor {
56 9     9   14 my ($attribute) = @_;
57              
58             my $sub_class_accessor = sub {
59 0     0   0 my ($self, $model, $value) = @_;
60 0 0       0 (@_ == 2)
61             ? return $META->{$model}{$attribute}
62             : return $META->{$model}{$attribute} = $value;
63 9         32 };
64            
65             # the real magic occurs now!
66 9         18 my $symbol = "Coat::Persistent::Meta::${attribute}";
67             {
68 3     3   21 no strict 'refs';
  3         10  
  3         189  
  9         10  
69 3     3   15 no warnings 'redefine';
  3         81  
  3         561  
70 9         59 *$symbol = $sub_class_accessor;
71             }
72             }
73              
74             # When the package is imported, define the symbols
75             sub import {
76 3     3   27 _create_model_accessor($_) for @attributes;
77 3         266 __PACKAGE__->export_to_level( 1, @_ );
78             }
79              
80             1;
81             __END__