File Coverage

blib/lib/Mojolicious/Plugin/Model/DB.pm
Criterion Covered Total %
statement 24 24 100.0
branch 2 2 100.0
condition n/a
subroutine 6 6 100.0
pod n/a
total 32 32 100.0


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