File Coverage

blib/lib/Ado/Command/generate/crud.pm
Criterion Covered Total %
statement 55 55 100.0
branch 5 6 83.3
condition 6 15 40.0
subroutine 8 8 100.0
pod 2 2 100.0
total 76 86 88.3


line stmt bran cond sub pod time code
1             package Ado::Command::generate::crud;
2 4     4   1681 use Mojo::Base 'Ado::Command::generate';
  4         8  
  4         24  
3 4     4   591 use Mojo::Util qw(camelize class_to_path decamelize);
  4         8  
  4         295  
4 4     4   18 use Getopt::Long qw(GetOptionsFromArray :config no_auto_abbrev no_ignore_case);
  4         6  
  4         28  
5 4     4   1333 use Time::Piece ();
  4         4570  
  4         90  
6 4     4   23 use List::Util qw(first);
  4         6  
  4         3786  
7             File::Spec::Functions->import(qw(catfile catdir splitdir));
8              
9             has description => "Generates directory structures for Ado-specific CRUD..\n";
10             has usage => sub { shift->extract_usage };
11              
12             has routes => sub {
13             $_[0]->{routes} = [];
14             foreach my $t (@{$_[0]->args->{tables}}) {
15             my $controller = camelize($t);
16             my $route = decamelize($controller);
17             push @{$_[0]->{routes}},
18             { route => "/$route",
19             via => ['GET'],
20             to => "$route#list",
21             },
22             { route => "/$route/list",
23             via => ['GET'],
24             to => "$route#list",
25             },
26             { route => "/$route/read/:id",
27             via => [qw(GET)],
28             to => "$route#read",
29             },
30             { route => "/$route/create",
31             via => [qw(GET POST)],
32             to => "$route#create",
33             over => {authenticated => 1},
34             },
35             { route => "/$route/update/:id",
36             via => [qw(GET PUT)],
37             to => "$route#update",
38             over => {authenticated => 1},
39             },
40             { route => "/$route/delete/:id",
41             via => [qw(GET DELETE)],
42             to => "$route#delete",
43             over => {authenticated => 1},
44             };
45             }
46             return $_[0]->{routes};
47             };
48              
49             sub initialise {
50 3     3 1 796 my ($self, @args) = @_;
51 3 100       23 return $self if $self->{_initialised};
52 2         12 my $args = $self->args({tables => []})->args;
53              
54             GetOptionsFromArray(
55             \@args,
56             'C|controller_namespace=s' => \$args->{controller_namespace},
57              
58             #'d|dsn=s' => \$args->{dsn},
59             'L|lib=s' => \$args->{lib},
60             'M|model_namespace=s' => \$args->{model_namespace},
61              
62             #'N|no_dsc_code' => \$args->{no_dsc_code},
63             'O|overwrite' => \$args->{overwrite},
64              
65             #'P|password=s' => \$args->{password},
66             'T|templates_root=s' => \$args->{templates_root},
67             't|tables=s@' => \$args->{tables},
68             'H|home_dir=s' => \$args->{home_dir},
69              
70             #'U|user=s' => \$args->{user},
71 2         27 );
72              
73 2         1371 @{$args->{tables}} = split(/\,/, join(',', @{$args->{tables}}));
  2         6  
  2         6  
74 2 50       2 Carp::croak $self->usage unless scalar @{$args->{tables}};
  2         8  
75 2         14 my $app = $self->app;
76 2   33     19 $args->{controller_namespace} //= $app->routes->namespaces->[0];
77             $args->{model_namespace} //=
78 4 100   4   45 (first { ref($_) eq 'HASH' and $_->{name} eq 'DSC' } @{$app->config('plugins')})
  2         15  
79 2   33     31 ->{config}{namespace};
80 2   33     9 $args->{home_dir} //= $app->home;
81 2   66     12 $args->{lib} //= catdir($args->{home_dir}, 'lib');
82 2   33     5 $args->{templates_root} //= $app->renderer->paths->[0];
83 2         4 $self->{_initialised} = 1;
84 2         7 return $self;
85             }
86              
87             sub run {
88 2     2 1 1801 my ($self) = shift->initialise(@_);
89 2         9 my $args = $self->args;
90 2         13 my $app = $self->app;
91              
92 2         8 foreach my $t (@{$args->{tables}}) {
  2         7  
93              
94             # Controllers
95 2         8 my $class_name = camelize($t);
96 2         42 $args->{class} = $args->{controller_namespace} . '::' . $class_name;
97 2         8 my $c_file = catfile($args->{lib}, class_to_path($args->{class}));
98 2         29 $args->{t} = lc $t;
99 2         30 $self->render_to_file('class', $c_file, $args);
100              
101             # Templates
102 2         17290 my $template_dir = decamelize($class_name);
103 2         49 my $template_root = $args->{templates_root};
104 2         15 my $t_file = catfile($template_root, $template_dir, 'list.html.ep');
105 2         10 $self->render_to_file('list_template', $t_file, $args);
106 2         4768 $t_file = catfile($template_root, $template_dir, 'create.html.ep');
107 2         13 $self->render_to_file('create_template', $t_file, $args);
108 2         2727 $t_file = catfile($template_root, $template_dir, 'read.html.ep');
109 2         12 $self->render_to_file('read_template', $t_file, $args);
110 2         3273 $t_file = catfile($template_root, $template_dir, 'delete.html.ep');
111 2         30 $self->render_to_file('delete_template', $t_file, $args);
112             } # end foreach tables
113              
114 2         2828 return $self;
115             }
116              
117              
118             1;
119              
120              
121             =pod
122              
123             =encoding utf8
124              
125             =head1 NAME
126              
127             Ado::Command::generate::crud - Generates MVC set of files
128              
129             =head1 SYNOPSIS
130              
131             Usage:
132             #on the command-line
133             # for one or more tables.
134             $ bin/ado generate crud --tables='news,articles'
135              
136             #programatically
137             use Ado::Command::generate::crud;
138             my $v = Ado::Command::generate::crud->new;
139             $v->run(-t => 'news,articles');
140              
141             =head1 DESCRIPTION
142              
143             B
144             The generated code is not even expected to work properly.>
145              
146             L generates directory structure for
147             a fully functional
148             L
149             set of files, based on existing tables in the database.
150             You only need to create the tables. The Model (M) classes are generated on the fly
151             from the tables when the controller classes are loaded by L for the first time.
152             You can dump them to disk if you want using the C script that
153             comes with L. You may decide to use only L
154             via the C<$c-Edbix> helper or L via C<$c-Edbix-Edbh>.
155             That's up to you.
156              
157             This tool's purpose is to promote
158             L
159             by generating the boilerplate code for controllers (C)
160             and help programmers new to L and L to quickly create
161             well structured, fully functional applications.
162              
163             In the generated actions you will find I code
164             for reading, creating, updating and deleting records from the tables you
165             specified on the command-line.
166              
167             The generated code is just boilerplate to give you a jump start, so you can
168             concentrate on writing your business-specific code. It is assumed that you will
169             modify the generated code to suit your specific needs.
170              
171             =head1 OPTIONS
172              
173             Below are the options this command accepts, described in L notation.
174              
175             =head2 C|controller_namespace=s
176              
177             Optional. The namespace for the controller classes to be generated.
178             Defaults to Croutes-Enamespaces-E[0]>, usually
179             L. If you decide to use another namespace for the controllers,
180             do not forget to add it to the list Croutes-Enamespaces>
181             in C or your plugin configuration file.
182              
183             =head2 H|home_dir=s
184              
185             Defaults to C<$ENV{MOJO_HOME}> (which is Ado home directory).
186             Used to set the root directory to which the files
187             will be dumped when L.
188              
189             =head2 L|lib=s
190              
191             Defaults to C relative to the C<--home_dir> directory.
192             If you installed L in some custom path and you wish to generate your controllers into
193             e.g. C, use this option. Do not forget to add this
194             directory to C<$ENV{PERL5LIB}>, so the classes can be found and loaded.
195              
196             =head2 M|model_namespace=s
197              
198             Optional. The namespace for the model classes to be generated.
199             Defaults to L. If you wish however to use another namespace
200             for another database, you will have to add another item for
201             L to the list of loaded plugins in C
202             or in your plugin configuration. Yes, multiple database connections/schemas
203             are supported.
204              
205             =head2 T|templates_root=s
206              
207             Defaults to Crenderer-Epaths-E[0]>. This is usually
208             C directory. If you want to use another directory,
209             do not forget to add it to the Crenderer-Epaths> list
210             in your configuration file.
211              
212             =head2 t|tables=s@
213              
214             Mandatory. List of tables separated by commas for which controllers should be generated.
215              
216             =head1 ATTRIBUTES
217              
218             L inherits all attributes from
219             L and implements the following new ones.
220              
221             =head2 description
222              
223             my $description = $command->description;
224             $command = $command->description('Foo!');
225              
226             Short description of this command, used for the command list.
227              
228             =head2 routes
229              
230             $self->routtes();
231              
232             Returns an ARRAY reference containing routes, prepared after C<$self-Eargs-E{tables}>.
233              
234             Altough L already has defined generic routes for CRUD,
235             this attribute contains more specific routes, that will secure the C,
236             C and C actions, so they are available only to an
237             authenticated user. This attribute is used for generating routes in
238             L.
239             After generating a plugin you should end up with a
240             L
241             service. The generated code uses
242             L. For details see
243             L.
244              
245             =head2 usage
246              
247             my $usage = $command->usage;
248             $command = $command->usage('Foo!');
249              
250             Usage information for this command, used for the help screen.
251              
252             =head1 METHODS
253              
254             L inherits all methods from
255             L and implements the following new ones.
256              
257             =head2 initialise
258              
259             sub run {
260             my ($self) = shift->initialise(@_);
261             #...
262             }
263              
264             Parses arguments and prepares the command to be run. Calling this method for the second time has no effect.
265             Returns C<$self>.
266              
267             =head2 run
268              
269             Ado::Command::generate::crud->new(app=>$app)->run(@ARGV);
270              
271             Run this command.
272              
273             =head1 SEE ALSO
274              
275             L,
276             L,
277             L, L,
278             L, L,
279             L L,
280             L, L
281              
282             =head1 AUTHOR
283              
284             Красимир Беров (Krasimir Berov)
285              
286             =head1 COPYRIGHT AND LICENSE
287              
288             Copyright 2014 Красимир Беров (Krasimir Berov).
289              
290             This program is free software, you can redistribute it and/or
291             modify it under the terms of the
292             GNU Lesser General Public License v3 (LGPL-3.0).
293             You may copy, distribute and modify the software provided that
294             modifications are open source. However, software that includes
295             the license may release under a different license.
296              
297             See http://opensource.org/licenses/lgpl-3.0.html for more information.
298              
299             =cut
300              
301             __DATA__