File Coverage

blib/lib/Dao/Map/Helper.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Dao::Map::Helper;
2             #use warnings;
3 1     1   34642 use strict;
  1         3  
  1         42  
4 1     1   3102 use DBI;
  1         28593  
  1         84  
5 1     1   564 use DBD::mysql;
  0            
  0            
6             use Error qw{:try};
7             use Getopt::Long;
8             use Pod::Usage;
9             use Carp;
10             our @ISA = qw(Exporter);
11             our @EXPORT = qw(
12             );
13            
14             =head1 NAME
15            
16             Dao::Map::Helper - Simplify the creation of DAO (Data Access Objects). Kind of a low level ORM, where you can still use SQL and then map the result set to the class objects.
17            
18             =head1 VERSION
19            
20             Version 0.04
21            
22             =cut
23            
24             our $VERSION = '0.04';
25            
26             =head1 SYNOPSIS
27            
28             Simplify the creation of Dao classes and the mapping between relational table and class.
29            
30             dao-map-helper --dsn=dbi:mysql:mydb:localhost:3306 --user=root --pwd=pwd --package=package
31            
32             =head1 Description
33            
34             You might have seen helper scripts which are part of Catalyst Devel framework.
35            
36             The helper scripts create the inital structure based on which you can continue your work.
37            
38             What does Dao::Map::Helper do?
39             The Dao::Map::Helper can be invoked via command line and inturn it will create .pm files that are also called Value Objects.
40             These are just class files with attributes in them.
41            
42             Where do i use it?
43             Every time you fetch a result set from the database using DBI module like
44            
45             ...
46             $sth = $dbh->prepare("select * from user");
47             $sth->execute();
48             while ($row = $sth->fetchrow_hashref() ) {
49             push(@user_arry2,$row);
50             }
51             ...
52            
53             Template toolkit file would look like:
54            
55             ...
56             [% FOREACH user IN user_arry %]
57             [% user.id %] : [% user.username %]
58             [% END %]
59             ...
60            
61            
62             With the above approach if the database layer changes then you would have to search every view where the column name is used and change it. Instead if you had a interface. A change in a single file is all that is needed. In the above approach since you are directly passing the database hash values the impact of a change is propogated across your website, making it hard to maintain.
63            
64             The new approach would be
65            
66            
67             ...
68             $sth = $dbh->prepare("select * from user");
69             $sth->execute();
70             while ($row = $sth->fetchrow_hashref() ) {
71             my $user_obj = web_app::Vo::UserVo->new($row);
72             push(@user_arry,$user_obj);
73             }
74             ...
75            
76            
77             This way you get to create a mapping class that you can change if there is a change.
78            
79             The mapping file looks like this:
80            
81             package MyApp::Vo::userVo;
82             use strict;
83             use warnings;
84             sub new {
85             shift;
86             my($row) = @_;
87             my $self = {};
88             $self->{status}=$row->{status} || "";
89             $self->{updated_by}=$row->{updated_by} || "";
90             $self->{created_date}=$row->{created_date} || "";
91             $self->{username}=$row->{username} || "";
92             $self->{email}=$row->{email} || "";
93             $self->{password}=$row->{password} || "";
94             $self->{updated_date}=$row->{updated_date} || "";
95             $self->{id}=$row->{id} || "";
96             $self->{created_by}=$row->{created_by} || "";
97             bless($self);
98             return $self;
99             }
100             return 1;
101            
102             So if the username in the database changes to 'user_name' you dont have to modify every template view where it is used. You just need to change this mapping file.
103             Also the mapping between the database and class attributes happens in this class. So it's kind of a low level ORM, where you can still use SQL and then map the result set to the class objects.
104            
105             How do i create the mapping file?
106             If your database has say 20 tables, creating a mapping file similar to the one above is tedious task. Instead you can use the Dao::Map::Helper module which will create these classes for you. Just copy them over to the right folder and start using.
107            
108             What is the command i need to run?
109             After you install Dao::Map::Helper the helper script is available in the command line.
110             You can run the following command in the directory you want the .pm files to be present in.
111            
112             Examples:
113            
114             dao-map-helper --dsn=dbi:mysql:mydb:localhost:3306 --user=root --pwd=pwd --package=package
115            
116             What are the dependencies and limitations?
117             As of now it just works with mysql.
118            
119             =cut
120             ##################################################################################################
121             sub Main{
122             pod2usage(2) unless @ARGV;
123            
124             my ($dsn,$user,$pwd,$package);
125            
126            
127             GetOptions(
128             'dsn=s' => \$dsn,
129             'user=s' => \$user,
130             'pwd=s' => \$pwd,
131             'package=s' => \$package
132             ) || pod2usage(2);
133            
134             if (@ARGV) {
135             pod2usage(
136             -msg => "Unparseable arguments received: " . join(',', @ARGV),
137             -exitval => 2,
138             );
139             }
140            
141             create_dao($dsn,$user,$pwd,$package);
142             print "\nFinished!\n";
143             }
144             ##################################################################################################
145             sub create_dao{
146            
147             my ($dsn,$user,$pwd,$package) = @_;
148             my $dbh = DBI->connect( $dsn , $user, $pwd ) || croak("Unable to connect: $DBI::errstr\n");
149             try{
150            
151             my $sth1;
152             $sth1 = $dbh->table_info();
153             my $table_info = $sth1->fetchall_hashref('TABLE_NAME');
154             foreach my $table_name ( keys %$table_info )
155             {
156            
157             my $sth2 = $dbh->column_info(undef, undef, $table_name, undef);
158             my $col_info = $sth2->fetchall_hashref('COLUMN_NAME');
159            
160             $table_name = ucfirst($table_name);
161             print "use " . $package . "::Vo::$table_name"."_Vo;" . "\n";
162             open(FILE,">$table_name"."_Vo.pm");
163             print FILE "package ". $package . "::Vo::".$table_name."_Vo;\n";
164             print FILE "use strict;\n";
165             print FILE "use warnings;\n";
166             print FILE "sub new {\n";
167             print FILE "\tshift;\n";
168             print FILE "\tmy(\$row) = \@_;\n";
169             print FILE "\tmy \$self = {};\n";
170            
171             foreach my $column_name ( keys %$col_info )
172             {
173             print FILE "\t\$self->{$column_name}=\$row->{$column_name} || \"\";\n";
174             }
175             $sth2->finish();
176            
177             print FILE "\tbless(\$self);\n";
178             print FILE "\treturn \$self;\n";
179             print FILE "}\n";
180             print FILE "return 1;";
181            
182             close(FILE);
183            
184             }
185             $sth1->finish();
186            
187             }
188             catch Error with {
189            
190             }
191             finally{
192             $dbh->disconnect();
193             };
194             }
195             ##################################################################################################
196            
197             =head1 AUTHOR
198            
199             Arjun Surendra, C<< >>
200            
201             =head1 BUGS
202            
203             Please report any bugs or feature requests to C, or through
204             the web interface at L. I will be notified, and then you'll
205             automatically be notified of progress on your bug as I make changes.
206            
207             =head1 SUPPORT
208            
209             You can find documentation for this module with the perldoc command.
210            
211             perldoc Dao::Map::Helper
212            
213            
214             You can also look for information at:
215            
216             =over 4
217            
218             =item * RT: CPAN's request tracker
219            
220             L
221            
222             =item * AnnoCPAN: Annotated CPAN documentation
223            
224             L
225            
226             =item * CPAN Ratings
227            
228             L
229            
230             =item * Search CPAN
231            
232             L
233            
234             =back
235            
236            
237             =head1 ACKNOWLEDGEMENTS
238            
239             Like to thank Rajesh and Venky for reviewing the code.
240            
241             =head1 LICENSE AND COPYRIGHT
242            
243             Copyright 2011 Arjun Surendra.
244            
245             This program is free software; you can redistribute it and/or modify it
246             under the terms of either: the GNU General Public License as published
247             by the Free Software Foundation; or the Artistic License.
248            
249             See http://dev.perl.org/licenses/ for more information.
250            
251            
252             =cut
253            
254             1;
255             # End of Dao::Map::Helper