File Coverage

blib/lib/Mojolicious/Plugin/Model/DB.pm
Criterion Covered Total %
statement 25 25 100.0
branch 3 4 75.0
condition n/a
subroutine 6 6 100.0
pod n/a
total 34 35 97.1


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