File Coverage

blib/lib/Mojolicious/Plugin/Model/DB.pm
Criterion Covered Total %
statement 29 29 100.0
branch 5 6 83.3
condition n/a
subroutine 6 6 100.0
pod n/a
total 40 41 97.5


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::Model::DB;
2 4     4   6851 use Mojo::Base 'Mojolicious::Plugin::Model';
  4         10  
  4         29  
3 4     4   8460 use Mojo::Util 'camelize';
  4         23  
  4         183  
4 4     4   24 use Mojo::Loader qw/load_class/;
  4         11  
  4         165  
5 4     4   24 use Storable qw/dclone/;
  4         8  
  4         257  
6 4     4   3099 use Class::Method::Modifiers qw/after/;
  4         6659  
  4         3205  
7              
8             our $VERSION = '1.05';
9              
10             has 'databases' => sub {
11             [qw/Pg mysql SQLite Redis/]
12             };
13              
14             after register => sub {
15             my ($plugin, $app, $conf) = @_;
16              
17             $conf = dclone $conf;
18              
19             # check if need camelize moniker
20             my $moniker = camelize($app->moniker);
21             $moniker = $app->moniker unless -d $app->home . '/lib/' . $moniker;
22              
23             my $namespace = $conf->{namespace} // 'DB';
24             my $namespaces = $conf->{namespaces} // [$moniker . '::Model'];
25             @{$conf->{namespaces}} = map $_ . "::$namespace", @$namespaces;
26             my $databases = _load_class_databases($plugin, $conf);
27              
28             $app->helper(
29             db => sub {
30             my ($self, $name) = @_;
31             $name //= $conf->{default};
32              
33             my $model;
34             return $model if $model = $plugin->{models}{$name};
35              
36             my $class = Mojolicious::Plugin::Model::_load_class_for_name(
37             $plugin, $app, $conf, $name, $moniker
38             ) or return undef;
39              
40             # define attr to database
41             $class->attr($_) for keys %{$databases};
42              
43             my $params = $conf->{params}{$name};
44             $model = $class->new(
45             ref $params eq 'HASH' ? %$params : (),
46             %$databases,
47             app => $app
48             );
49             $plugin->{models}{$name} = $model;
50             return $model;
51             }
52             );
53             };
54              
55             sub _load_class_databases {
56 4     4   11 my ($plugin, $conf) = @_;
57              
58 4         10 my $databases = {};
59              
60 4         9 for (@{$plugin->databases}) {
  4         14  
61 16 100       52 if (defined $conf->{$_}) {
62 2         6 my $class = 'Mojo::' . $_;
63            
64 2         4 my $ref;
65            
66 2 100       11 if (ref($conf->{$_}) eq $class) {
67 1         14 $ref = $conf->{$_};
68             } else {
69 1         9 my $e = load_class $class;
70 1 50       87092 die "Loading '$class' failed: $e" if $e;
71 1         9 $ref = $class->new($conf->{$_});
72             }
73            
74 2         4006 $databases->{lc($_)} = $ref;
75             }
76             }
77              
78 4         12 return $databases;
79             }
80              
81             1;
82              
83             =encoding utf8
84              
85             =head1 NAME
86              
87             Mojolicious::Plugin::Model::DB - It is an extension of the module L for Mojolicious applications.
88              
89             =head1 SYNOPSIS
90              
91             Model Functions
92              
93             package MyApp::Model::Functions;
94             use Mojo::Base 'MojoX::Model';
95              
96             sub trim {
97             my ($self, $value) = @_;
98              
99             $value =~ s/^\s+|\s+$//g;
100              
101             return $value;
102             }
103              
104             1;
105              
106             Model DB Person
107              
108             package MyApp::Model::DB::Person;
109             use Mojo::Base 'MojoX::Model';
110              
111             sub save {
112             my ($self, $foo) = @_;
113              
114             return $self->mysql->db->insert(
115             'foo',
116             {
117             foo => $foo
118             }
119             )->last_insert_id;
120             }
121              
122             1;
123              
124             Mojolicious::Lite application
125              
126             #!/usr/bin/env perl
127             use Mojolicious::Lite;
128              
129             use lib 'lib';
130              
131             plugin 'Model::DB' => {mysql => 'mysql://user@/mydb'};
132              
133             any '/' => sub {
134             my $c = shift;
135              
136             my $foo = $c->param('foo')
137             ? $c->model('functions')->trim($c->param('foo')) # model functions
138             : '';
139              
140             # model db Person
141             my $id = $c->db('person')->save($foo);
142              
143             $c->render(text => $id);
144             };
145              
146             app->start;
147              
148             All available options
149              
150             #!/usr/bin/env perl
151             use Mojolicious::Lite;
152              
153             plugin 'Model::DB' => {
154             # Mojolicious::Plugin::Model::DB
155             namespace => 'DataBase', # default is DB
156              
157             # databases options
158             Pg => 'postgresql://user@/mydb', # this will instantiate Mojo::Pg, in model get $self->pg,
159             mysql => 'mysql://user@/mydb', # this will instantiate Mojo::mysql, in model get $self->mysql,
160             SQLite => 'sqlite:test.db', # this will instantiate Mojo::SQLite, in model get $self->sqlite,
161             Redis => 'redis://localhost', # this will instantiate Mojo::Redis, in model get $self->redis,
162            
163             # or using reference
164             Pg => Mojo::Pg->new('postgresql://postgres@/test'), # in model get $self->pg,
165             mysql => Mojo::mysql->strict_mode('mysql://username@/test'), # in model get $self->mysql,
166             SQLite => Mojo::SQLite->new('sqlite:test.db'), # in model get $self->sqlite,
167             Redis => Mojo::Redis->new("redis://localhost:6379/1"), # in model get $self->redis,
168              
169             # Mojolicious::Plugin::Model
170             namespaces => ['MyApp::Model', 'MyApp::CLI::Model'],
171             base_classes => ['MyApp::Model'],
172             default => 'MyApp::Model::Pg',
173             params => {Pg => {uri => 'postgresql://user@/mydb'}}
174             };
175              
176             =head1 DESCRIPTION
177              
178             Mojolicious::Plugin::Model::DB It is an extension of the module Mojolicious::Plugin::Model, the intention is to separate models of database from other models,
179             using Mojolicious::Plugin::Model::DB you can continue using all functions of Mojolicious::Plugin::Model. See more in L.
180              
181             =head1 OPTIONS
182              
183             =head2 namespace
184              
185             # Mojolicious::Lite
186             plugin 'Model::DB' => {namespace => 'DataBase'}; # It's will load from $moniker::Model::DataBase
187              
188             Namespace to load models from, defaults to C<$moniker::Model::DB>.
189              
190             =head2 databases
191              
192             =head3 Mojo::Pg
193              
194             # Mojolicious::Lite
195             plugin 'Model::DB' => {Pg => 'postgresql://user@/mydb'};
196              
197             # Model::DB
198             package MyApp::Model::DB::Foo;
199             use Mojo::Base 'MojoX::Model';
200              
201             sub find {
202             my ($self, $id) = @_;
203              
204             return $self->pg->db->select(
205             'foo',
206             undef,
207             {
208             id => $id
209             }
210             )->hash;
211             }
212              
213             1;
214              
215             =head3 Mojo::mysql
216              
217             # Mojolicious::Lite
218             plugin 'Model::DB' => {mysql => 'mysql://user@/mydb'};
219              
220             # Model::DB
221             package MyApp::Model::DB::Foo;
222             use Mojo::Base 'MojoX::Model';
223              
224             sub find {
225             my ($self, $id) = @_;
226              
227             return $self->mysql->db->select(
228             'foo',
229             undef,
230             {
231             id => $id
232             }
233             )->hash;
234             }
235              
236             1;
237              
238             =head3 Mojo::SQLite
239              
240             # Mojolicious::Lite
241             plugin 'Model::DB' => {SQLite => 'sqlite:test.db'};
242              
243             # Model::DB
244             package MyApp::Model::DB::Foo;
245             use Mojo::Base 'MojoX::Model';
246              
247             sub find {
248             my ($self, $id) = @_;
249              
250             return $self->sqlite->db->select(
251             'foo',
252             undef,
253             {
254             id => $id
255             }
256             )->hash;
257             }
258              
259             1;
260              
261             =head3 Mojo::Redis
262              
263             # Mojolicious::Lite
264             plugin 'Model::DB' => {Redis => 'redis://localhost'};
265              
266             # Model::DB
267             package MyApp::Model::DB::Foo;
268             use Mojo::Base 'MojoX::Model';
269              
270             sub find {
271             my ($self, $key) = @_;
272              
273             return $self->redis->db->get($key);
274             }
275              
276             1;
277              
278             =head3 Mojo::mysql and Mojo::Redis
279              
280             # Mojolicious::Lite
281             plugin 'Model::DB' => {
282             mysql => 'mysql://user@/mydb',
283             Redis => 'redis://localhost'
284             };
285              
286             # Model::DB
287             package MyApp::Model::DB::Foo;
288             use Mojo::Base 'MojoX::Model';
289              
290             sub find {
291             my ($self, $id) = @_;
292              
293             my $cache = $self->redis->db->get('foo:' . $id);
294             return $cache if $cache;
295              
296             my $foo = $self->mysql->db->select(
297             'foo',
298             undef,
299             {
300             id => $id
301             }
302             )->hash;
303              
304             $self->redis->db->set('foo:' . $id, $foo);
305              
306             return $foo;
307             }
308              
309             1;
310              
311             =head2 more options
312              
313             see in L
314              
315             =head1 HELPERS
316              
317             L implements the following helpers.
318              
319             =head2 db
320              
321             my $db = $c->db($name);
322              
323             Load, create and cache a model object with given name. Default class for
324             model db C. Return `undef` if model db not found.
325              
326             =head2 more helpers
327              
328             see in L
329              
330             =head1 SEE ALSO
331              
332             L, L, L, L.
333              
334             =head1 AUTHOR
335              
336             Lucas Tiago de Moraes C
337              
338             =head1 COPYRIGHT AND LICENSE
339              
340             This software is copyright (c) 2019 by Lucas Tiago de Moraes.
341              
342             This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
343              
344             =cut