File Coverage

blib/lib/Jorge.pm
Criterion Covered Total %
statement 6 6 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 8 8 100.0


line stmt bran cond sub pod time code
1             package Jorge;
2              
3 1     1   20504 use warnings;
  1         3  
  1         27  
4 1     1   4 use strict;
  1         2  
  1         125  
5              
6             =head1 NAME
7              
8             Jorge - ORM Made simple.
9              
10             =head1 VERSION
11              
12             Version 0.04
13              
14             =cut
15              
16             our $VERSION = '0.04';
17              
18             =head1 SYNOPSIS
19              
20             Not ready for Class::DBI or DBIx::Class? Dissapointed by Tangram? Still
21             writting your own SQL?
22              
23             Then, you may benefit from Jorge.
24              
25             Jorge is a simple ORM (Object Relational Mapper) that will let you
26             quick and easily interface your perl objects with a MySQL database
27             (Suppport for PostgreSQL may arrive some day)
28              
29             Usual operations are covered (insert, update, select, delete, count) but
30             if you need JOINS or other type of queries, you should be looking for
31             other library (DBIx::Class or Rose::DB::Object)
32              
33             Jorge won't solve all your problems and may not be what you need, but if
34             it covers your needs, you'll find it ultra easy to use, intuitive and
35             will get used to it sooner that you may think.
36              
37              
38             =head1 USAGE
39              
40             =head2 Defining your new Jorge based class
41              
42             =head3 Start with: YourClass.pm
43              
44             package YourClass
45             use base Jorge::DBEntity;
46              
47             sub _fields {
48              
49             my $table_name = 'YourClass';
50              
51             my @fields = qw(
52             Id
53             Password
54             Email
55             Date
56             Md5
57             );
58              
59             my %fields = (
60             Id => { pk => 1, read_only => 1 },
61             Date => { datetime => 1},
62             );
63              
64             return [ \@fields, \%fields, $table_name ];
65             }
66             ;1
67              
68              
69              
70              
71             That is enough to get you started with Jorge.
72             Now, you need to provide Jorge with a config file containing
73             the database info (this is likely to change in future and add options,
74             like passing the config info as parameters)
75              
76             create a config/jorge.yml file (in your current working dir, relative
77             to the path the instance script will be working)
78              
79             =head3 Configuration. config/jorge.yml
80              
81             database:
82             host: DB_HOST
83             db: DB_NAME
84             user: DB_USER
85             password: USER_PASSWORD
86             config
87             This is what the config file should have. Plain simple. Since it's YAML,
88             you will want to double check the syntax looking for tabs/spaces.
89              
90              
91             Now, you can create a instance script and try the next.
92              
93             =head3 Creating a new Object.
94              
95             YourInstanceScript.pl
96              
97             #!/usr/bin/perl
98             use User;
99              
100             my $user = User->new(Email => 'jorge@foo.com', Password => 'sshhhhh');
101              
102             #or
103              
104             my $another_user = User->new();
105             $another_user->Email('jorge@foo.com');
106             $another_user->Password('sshhhhh');
107              
108             If the database info you provided in the config file was accurate and you
109             already created the database (Jorge will not create your database, at least,
110             not now, but likely to change in next versions) You should be able now to
111             start interacting with it.
112              
113             Try now something like this, later on your instance script:
114              
115             $user->insert;
116             print $user->Id; #if the insert was successful, you $user->Id should
117             #return the inserted id.
118              
119             Ideally, that should have worked fine and now you can start using Jorge.
120              
121             Available method for Jorge::DBEntity based classes are:
122              
123             =over 2
124              
125             =item insert
126              
127             =item update
128              
129             =item delete
130              
131             =item get_by
132              
133             All those methods are pretty self explanatory, but this should guide you
134             through the basic operations
135              
136             =back
137              
138             =head3 Creating a new object, insert, delete and get from/to the Database.
139              
140             YourInstanceScript.pl
141              
142             #!/usr/bin/perl
143             use User;
144              
145             my $user = User->new(Email => 'jorge@foo.com', Password => 'sshhhhh');
146             $user->insert;
147             #now $user->Id returns the inserted id from the database
148             $user->Email('updated_mail@bar.com');
149             $user->update;
150             #same $user->Id, but $user->Email was updated in the database
151             $user->delete
152             #now, even while the $user exists in memory, is not present anymore on
153             the database
154              
155             #now, let's try something more complex
156             my $user2 = User->new(Email => 'coco@foo.com', Password => 'secret');
157             $user2->get_by(qw[Email Password]);
158             print $user2->Id;
159             # Now, if there is a User in with Email = 'coco@foo.com' AND a Password
160             # = 'secret' then $user2->Id will be a positive integer. Otherwhise, it
161             # will return undef
162              
163             $user2->get_by('Email'); #will look only for the Email field.
164              
165              
166             As you can see, you should ALLWAYS check your object to confirm that it
167             found at match before using it.
168              
169             I'm considering implementing some error checking method, but since I got
170             used to check for Id's on my objects.
171              
172             If you have a proposal to solve this, feel free to email or open a
173             request ticket on CPAN Request Tracker at:
174             L
175            
176             Another thing to consider is that, even if the get_by() method finds more
177             than one match, it will allways use the first one.
178              
179             If you need to retrieve more than 1 element at a time, then you need
180             Jorge::ObjectCollection
181              
182             =head2 Defining Your new Jorge based Object Collection
183              
184             =head3 Collections: YourClassCollection.pm
185              
186             package YourClassCollection;
187             use base 'Jorge::ObjectCollection';
188              
189             use YourClass;
190              
191             use strict;
192              
193             sub create_object {
194             return new YourClass;
195             }
196              
197             ;1
198              
199             And that's it. Instant gratification.
200              
201             Now you can create a new YourClassCollection object and get multiple
202             objects from the database.
203              
204             How? simple. Just pass the parameters to get the matching objects from the
205             database.
206              
207             =head3 Using Collections: YourInstanceScript.pl
208              
209            
210             #!/usr/bin/perl
211             use Users; # (note the convention. for DBEntity based packages we used
212             # singular form of the name and the plural form form
213             # for ObjectCollection based objects, similar as Rail's
214             # Active::Record does.
215              
216             my $users = Users->new();
217             my %params = (Email => 'coco@foo.com');
218             $users->get_all(%params);
219             while (my $user = $users->get_next){
220             print $user->Id;
221             }
222              
223             Available method for Jorge::ObjectCollection based classes are:
224              
225             =over 2
226              
227             =item get_all
228              
229             =item get_count
230              
231             =item get_next
232              
233              
234             Again, all those methods are pretty self explanatory.
235              
236             get_all and get_count can receive parameters (as a hash). If they dont,
237             both will retrive all the rows from the database to provide a result.
238              
239             =back
240              
241             =head2 Params Syntax for ObjectCollection based objects
242              
243             Simplest case: Name equals some value.
244              
245             my %params = (Name => 'Jorge');
246              
247             Moving on...
248              
249             my %params = (Name => ['!=', 'Jorge']);
250              
251             Let's continue
252              
253             my %params = (Price => ['>', 12]);
254              
255             my %params = (Price => ['>', 12], Id => ['<', 30]); #That's a AND.
256            
257             my %params = (Price => 'is null');
258            
259             #OR support. Yeah!
260             my %params = (Name => [ 'or',[ ['=','Bill'],['=','Steve'],['=','Linus']);
261            
262             #IN
263             my %params = (Id => [ 'in', [1,2,3,5,7,11] ]);
264            
265             #BETWEEN
266             #NOTE: Allways provide min and max values
267             my %params = (Id => ['between',(1,100)]);
268            
269             #Use a object as a parameter
270             my %params = (User => $user);
271              
272              
273             =head2 get_all, get_next: Iterating.
274              
275             Once you invoke the method get_all (hint. if you invoke it without params)
276             it will do a SELECT * FROM __table__, retrieving all the elements of that
277             table/class.
278              
279             In fact, no query will retrieve all the objects, but only their Id's (or
280             primary keys.)
281              
282             After you retrieve all the matching objects, you can start iterating pulling
283             elements from the array of matching elements invoking the method get_next
284              
285             my $elements = Elements->new;
286             my %params = (Field => 'Value');
287             $elements->get_all(%params);
288             while (my $element = $elements->get_next){
289             #We're Iterating!
290             print $element->Id;
291             }
292              
293             =head1 Setup
294              
295             =head2 Config File
296              
297             Jorge expects a YAML config file under a certain directory/filename.
298             Default value is config/jorge.yml relative to the working dir path
299             If you need to override or change the location of the config file, you can
300             modify the config_file variable in Jorge::Config file
301              
302             Jorge::Config::$CONFIG_FILE = 'path to your config';
303              
304             In your instance script / Main package.
305              
306             =head1 Plugins
307              
308             You can create plugins for Jorge. Plugin support right now it's very raw,
309             but has a lot of potential. Included in the distro you will find Jorge::Plugin::Md5
310             which imports a subroutine into the Jorge::DBEntity based objects named
311             encodeMd5.
312             You can read the code to get an idea of how you can write your own Jorge
313             plugins and how to extend your Jorge based objects. Feedback will be appreciated.
314              
315              
316             =head2 Jorge::Plugin::Md5
317              
318             package Jorge::Plugin::Md5;
319             use Digest::MD5;
320             use vars qw($VERSION @EXPORT);
321             use warnings;
322             use strict;
323              
324             @EXPORT = qw(
325             encodeMd5
326             );
327             our $VERSION = '0.01';
328             sub import {
329             my $pkg = shift;
330             my $callpkg = caller;
331             no strict 'refs';
332             foreach my $sym (@EXPORT) {
333             *{"${callpkg}::$sym"} = \&{$sym};
334             }
335             }
336             sub encodeMd5 {
337             my $self = shift;
338             my @params = @_;
339              
340             my $md5 = Digest::MD5->new;
341              
342             foreach my $key (@params) {
343             my $k = $self->{$key};
344             $md5->add($k);
345             }
346             return substr( $md5->hexdigest, 0, 8 );
347             }
348              
349             To enable Jorge::Plugin::Md5 in your Jorge::DBEntity based objects, just
350             use it in your package and the encodeMd5 subroutine will be available in
351             your objects.
352              
353             =head3 Using Plugins: YourClass.pm
354              
355             package User;
356              
357             use base 'Jorge::DBEntity';
358             use Jorge::Plugin::Md5;
359              
360              
361             sub _fields {
362            
363             my $table_name = 'User';
364            
365             my @fields = qw(
366             Id
367             Password
368             Date
369             Md5
370             Email
371             );
372              
373             my %fields = (
374             Id => { pk => 1, read_only => 1 },
375             Date => { datetime => 1},
376             );
377              
378             return [ \@fields, \%fields, $table_name ];
379             }
380             ;1
381              
382             =head3 Using Plugins: YourInstanceScript.pl
383              
384              
385             #!/usr/bin/perl
386              
387             use User;
388             my $user = User->new(Email => 'jorge@foo.com', Password => 'sshhhhh');
389             print $user->encodeMd5(qw[Email Password]); #will print a Md5 hash
390              
391              
392             =head1 AUTHORS
393              
394             Joaquin Perez, C<< >> had the original idea after
395             being frustrated by Catalyst and Tangram.
396              
397             Julian Porta, C<< >> took the code and tried
398             to make it harder, better, faster, stronger. And packaged it.
399              
400             =head1 BUGS
401              
402             Please report any bugs or feature requests to C,
403             or through the web interface at
404             L.
405             I will be notified, and then you'll
406             automatically be notified of progress on your bug as I make changes.
407              
408              
409             =head1 SUPPORT
410              
411             You can find documentation for this module with the perldoc command.
412              
413             perldoc Jorge
414              
415              
416             You can also look for information at:
417              
418             =over 4
419              
420             =item * Github Project Page
421              
422             L
423              
424             =item * RT: CPAN's request tracker
425              
426             L
427              
428             =item * AnnoCPAN: Annotated CPAN documentation
429              
430             L
431              
432             =item * CPAN Ratings
433              
434             L
435              
436             =item * Search CPAN
437              
438             L
439              
440             =back
441              
442              
443             =head1 ACKNOWLEDGEMENTS
444              
445             Joaquin Perez C<< >> For starting this.
446              
447             =head1 COPYRIGHT & LICENSE
448              
449             Copyright 2009 Julian Porta, all rights reserved.
450              
451             This program is free software; you can redistribute it and/or modify it
452             under the same terms as Perl itself.
453              
454              
455             =cut
456              
457             1; # End of Jorge
458