| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Mojolicious::Plugin::BModel; |
|
2
|
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
1101037
|
use 5.010; |
|
|
3
|
|
|
|
|
11
|
|
|
4
|
3
|
|
|
3
|
|
23
|
use strict; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
148
|
|
|
5
|
3
|
|
|
3
|
|
45
|
use warnings; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
288
|
|
|
6
|
3
|
|
|
3
|
|
24
|
use Carp qw/ carp croak /; |
|
|
3
|
|
|
|
|
12
|
|
|
|
3
|
|
|
|
|
310
|
|
|
7
|
3
|
|
|
3
|
|
19
|
use File::Find qw/ find /; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
194
|
|
|
8
|
3
|
|
|
3
|
|
20
|
use List::Util qw/ first /; |
|
|
3
|
|
|
|
|
19
|
|
|
|
3
|
|
|
|
|
270
|
|
|
9
|
3
|
|
|
3
|
|
21
|
use File::Spec; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
110
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
3
|
|
|
3
|
|
1807
|
use Mojo::Loader; |
|
|
3
|
|
|
|
|
486845
|
|
|
|
3
|
|
|
|
|
193
|
|
|
12
|
3
|
|
|
3
|
|
25
|
use Mojo::Base 'Mojolicious::Plugin'; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
15
|
|
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
our $VERSION = '0.1'; |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
my $DEFAULT_CREATE_DIR = 1; |
|
17
|
|
|
|
|
|
|
my $DEFAULT_MODEL_DIR = 'Model'; # directory of poject for the Model-modules |
|
18
|
|
|
|
|
|
|
my %MODULES = (); |
|
19
|
|
|
|
|
|
|
my $BASE_MODEL = 'Mojolicious::BModel::Base'; |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub register { |
|
22
|
0
|
|
|
0
|
1
|
0
|
my ( $self, $app, $conf ) = @_; |
|
23
|
|
|
|
|
|
|
|
|
24
|
0
|
|
|
|
|
0
|
my $app_name = ref $app; # name of calling Mojo app |
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# namespace path to Models dir. By default it is the name of application, but it can be redefine. |
|
27
|
|
|
|
|
|
|
# For example, namespace can be MyPath::ToModel or any other |
|
28
|
0
|
0
|
|
|
|
0
|
my $namespace = $conf->{namespace} ? $conf->{namespace} : $app_name; |
|
29
|
0
|
0
|
|
|
|
0
|
if ( ! $self->_check_namespace( $namespace ) ) { |
|
30
|
0
|
|
|
|
|
0
|
croak "Wrong format of namespace $namespace. Exit"; |
|
31
|
|
|
|
|
|
|
} |
|
32
|
|
|
|
|
|
|
|
|
33
|
0
|
|
|
|
|
0
|
my $namespace_path = $self->_convert_namespace_to_path( $namespace ); |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# work with considering operation system |
|
36
|
0
|
|
|
|
|
0
|
my $path_to_model = File::Spec->catfile( $app->home->child('lib')->to_string, $namespace_path, $DEFAULT_MODEL_DIR ); |
|
37
|
0
|
|
|
|
|
0
|
my $dir_exists = $self->_check_model_dir( $path_to_model ); |
|
38
|
0
|
0
|
|
|
|
0
|
my $to_create_dir = exists $conf->{create_dir} ? $conf->{create_dir} : $DEFAULT_CREATE_DIR; |
|
39
|
|
|
|
|
|
|
|
|
40
|
0
|
0
|
0
|
|
|
0
|
if ( ! ( $dir_exists && $to_create_dir ) ) { |
|
|
|
0
|
0
|
|
|
|
|
|
41
|
0
|
|
|
|
|
0
|
carp "Directory " . File::Spec->catfile( $namespace_path, $DEFAULT_MODEL_DIR ) . " does not exist"; |
|
42
|
0
|
|
|
|
|
0
|
return 1; |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
elsif ( ! $dir_exists && $to_create_dir ) { |
|
45
|
0
|
0
|
|
|
|
0
|
mkdir $path_to_model or croak "Could not create directory $path_to_model : $!"; |
|
46
|
|
|
|
|
|
|
} |
|
47
|
|
|
|
|
|
|
|
|
48
|
0
|
|
|
|
|
0
|
$self->load_models( $path_to_model, $namespace, $app ); |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
$app->helper( |
|
51
|
|
|
|
|
|
|
model => sub { |
|
52
|
0
|
|
|
0
|
|
0
|
my ( $self, $model_name ) = @_; |
|
53
|
0
|
0
|
|
|
|
0
|
croak "Unknown model $model_name" if ! exists $MODULES{ $model_name }; |
|
54
|
0
|
|
|
|
|
0
|
return $MODULES{ $model_name }; |
|
55
|
|
|
|
|
|
|
} |
|
56
|
0
|
|
|
|
|
0
|
); |
|
57
|
|
|
|
|
|
|
|
|
58
|
0
|
|
|
|
|
0
|
return 1; |
|
59
|
|
|
|
|
|
|
} |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# check a path to the 'Model' dir |
|
62
|
|
|
|
|
|
|
sub _check_model_dir { |
|
63
|
3
|
|
|
3
|
|
8428
|
my ( $self, $path_to_model ) = @_; |
|
64
|
|
|
|
|
|
|
|
|
65
|
3
|
100
|
100
|
|
|
62
|
return 1 if -e $path_to_model && -d $path_to_model; |
|
66
|
2
|
|
|
|
|
9
|
return; |
|
67
|
|
|
|
|
|
|
} |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# check for validation of namespace |
|
70
|
|
|
|
|
|
|
sub _check_namespace { |
|
71
|
0
|
|
|
0
|
|
0
|
my ( $self, $namespace ) = @_; |
|
72
|
|
|
|
|
|
|
|
|
73
|
0
|
|
|
|
|
0
|
my @splitted_namespace = $self->_separate_namespace_name( $namespace ); |
|
74
|
0
|
0
|
|
|
|
0
|
return if ! scalar @splitted_namespace; |
|
75
|
|
|
|
|
|
|
|
|
76
|
0
|
|
|
0
|
|
0
|
my $found_wrong_name = first { $_ !~ m/[a-zA-Z0-9]/ } @splitted_namespace; |
|
|
0
|
|
|
|
|
0
|
|
|
77
|
0
|
0
|
|
|
|
0
|
return if $found_wrong_name; |
|
78
|
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
0
|
return 1; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# convert name like 'Aaaa::Bbbbb::Cccc' to 'Aaaa/Bbbbb/Cccc' for Unix-like OS or 'Aaaa\Bbbbb\Cccc' for Windows |
|
83
|
|
|
|
|
|
|
sub _convert_namespace_to_path { |
|
84
|
0
|
|
|
0
|
|
0
|
my ( $self, $namespace ) = @_; |
|
85
|
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
0
|
my @splitted_namespace = $self->_separate_namespace_name( $namespace ); |
|
87
|
0
|
0
|
|
|
|
0
|
my $path = scalar @splitted_namespace == 1 ? $splitted_namespace[0] : File::Spec->catfile( @splitted_namespace ); |
|
88
|
|
|
|
|
|
|
|
|
89
|
0
|
|
|
|
|
0
|
return $path; |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub _separate_namespace_name { |
|
93
|
0
|
|
|
0
|
|
0
|
my ( $self, $namespace ) = @_; |
|
94
|
|
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
0
|
my @splitted_name = split( /\:\:/, $namespace ); |
|
96
|
|
|
|
|
|
|
|
|
97
|
0
|
|
|
|
|
0
|
return @splitted_name; |
|
98
|
|
|
|
|
|
|
} |
|
99
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
sub _convert_model_dirs_array { |
|
101
|
6
|
|
|
6
|
|
40
|
my ( $self, @dirs ) = @_; |
|
102
|
|
|
|
|
|
|
|
|
103
|
6
|
|
|
|
|
9
|
my $canonical_name; |
|
104
|
|
|
|
|
|
|
|
|
105
|
6
|
|
|
|
|
16
|
for my $dir ( @dirs ) { |
|
106
|
15
|
100
|
|
|
|
54
|
next if $dir =~ m/^\s*$/; |
|
107
|
9
|
100
|
|
|
|
29
|
$canonical_name = ( defined $canonical_name ) ? $canonical_name . '::' . $dir : $dir; |
|
108
|
|
|
|
|
|
|
} |
|
109
|
|
|
|
|
|
|
|
|
110
|
6
|
|
|
|
|
18
|
return $canonical_name; |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
sub find_models { |
|
114
|
1
|
|
|
1
|
0
|
4175
|
my ( $self, $path_to_model, $model_path ) = @_; |
|
115
|
|
|
|
|
|
|
|
|
116
|
1
|
|
|
|
|
4
|
my @model_dirs = ( $model_path ); |
|
117
|
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
# find all subdirs in the directory of model |
|
119
|
|
|
|
|
|
|
find( |
|
120
|
|
|
|
|
|
|
sub { |
|
121
|
7
|
100
|
66
|
7
|
|
401
|
return if ! -d $File::Find::name || $File::Find::name eq $path_to_model; |
|
122
|
6
|
|
|
|
|
16
|
my $dir_name = $File::Find::name; |
|
123
|
6
|
|
|
|
|
91
|
$dir_name =~ s/$path_to_model//; # remove path to model from directory |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# split dir path name and convert it into name like 'aaa::bbb::ccc' |
|
126
|
6
|
|
|
|
|
65
|
my @dirs = File::Spec->splitdir( $dir_name ); |
|
127
|
6
|
|
|
|
|
22
|
my $canonical_dir_name = $self->_convert_model_dirs_array( @dirs ); |
|
128
|
6
|
50
|
|
|
|
24
|
if ( ! $canonical_dir_name ) { |
|
129
|
0
|
|
|
|
|
0
|
carp "Cannot parse dir name $dir_name"; |
|
130
|
0
|
|
|
|
|
0
|
return; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
6
|
|
|
|
|
809
|
push @model_dirs, $model_path . '::' . $canonical_dir_name; |
|
133
|
|
|
|
|
|
|
}, |
|
134
|
1
|
|
|
|
|
110
|
( $path_to_model ) |
|
135
|
|
|
|
|
|
|
); |
|
136
|
|
|
|
|
|
|
|
|
137
|
1
|
|
|
|
|
13
|
return \@model_dirs; |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# recursive search and download modules with models |
|
141
|
|
|
|
|
|
|
sub load_models { |
|
142
|
0
|
|
|
0
|
0
|
|
my ( $self, $path_to_model, $namespace, $app ) = @_; |
|
143
|
|
|
|
|
|
|
|
|
144
|
0
|
|
|
|
|
|
my $model_path = $namespace . '::' . $DEFAULT_MODEL_DIR; |
|
145
|
0
|
|
|
|
|
|
my @model_dirs = @{ $self->find_models( $path_to_model, $model_path ) }; |
|
|
0
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
|
|
147
|
0
|
|
|
|
|
|
my $base_load_err = Mojo::Loader::load_class( $BASE_MODEL ); |
|
148
|
0
|
0
|
|
|
|
|
croak "Loading base model $BASE_MODEL failed: $base_load_err" if ref $base_load_err; |
|
149
|
|
|
|
|
|
|
{ |
|
150
|
3
|
|
|
3
|
|
7579
|
no strict 'refs'; |
|
|
3
|
|
|
|
|
7
|
|
|
|
3
|
|
|
|
|
923
|
|
|
|
0
|
|
|
|
|
|
|
|
151
|
0
|
|
|
0
|
|
|
*{ "$BASE_MODEL\::app" } = sub { $app }; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# load modules from every dirs and subdirs of model |
|
155
|
0
|
|
|
|
|
|
for my $dir ( @model_dirs ) { |
|
156
|
0
|
|
|
|
|
|
my @model_packages = Mojo::Loader::find_modules( $dir ); |
|
157
|
0
|
|
|
|
|
|
for my $pm ( @model_packages ) { |
|
158
|
0
|
|
|
|
|
|
my $load_err = Mojo::Loader::load_class( $pm ); |
|
159
|
0
|
0
|
|
|
|
|
croak "Loading '$pm' failed: $load_err" if ref $load_err; |
|
160
|
0
|
|
|
|
|
|
my ( $basename ) = $pm =~ /$model_path\::(.*)/; |
|
161
|
0
|
|
|
|
|
|
$MODULES{ $basename } = $pm->new; |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
|
|
165
|
0
|
|
|
|
|
|
return 1; |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
1; |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
__END__ |