NAME
Jorge - ORM Made simple.
VERSION
Version 0.01
SYNOPSIS
Not ready for Class::DBI or DBIx::Class? Dissapointed by Tangram? Still writting your own SQL?
Then, you may benefit from Jorge.
Jorge is a simple ORM (Object Relational Mapper) that will let you quick and easily interface your perl objects with a MySQL database (Suppport for PostgreSQL may arrive some day)
Usual operations are covered (insert, update, select, delete, count) but if you need JOINS or other type of queries, you should be looking for other library (DBIx::Class or Rose::DB::Object)
Jorge won't solve all your problems and may not be what you need, but if it covers your needs, you'll find it ultra easy to use, intuitive and will get used to it sooner that you may think.
USAGE
Defining your new Jorge based class
YourClass.pm
package YourClass
use base Jorge::DBEntity;
sub _fields {
my $table_name = 'YourClass';
my @fields = qw(
Id
Password
Email
Date
Md5
);
my %fields = (
Id => { pk => 1, read_only => 1 },
Date => { datetime => 1},
);
return [ \@fields, \%fields, $table_name ];
}
;1
That is enough to get you started with Jorge. Now, you need to provide Jorge with a config file containing the database info (this is likely to change in future and add options, like passing the config info as parameters)
create a config/jorge.yml file (in your current working dir, relative to the path the instance script will be working)
config/jorge.yml
database:
host: DB_HOST
db: DB_NAME
user: DB_USER
password: USER_PASSWORD
This is what the config file should have. Plain simple. Since it's YAML, you will want to double check the syntax looking for tabs/spaces.
Now, you can create a instance script and try the next.
YourInstanceScript.pl
#!/usr/bin/perl
use User;
my $user = User->new(Email => 'jorge@foo.com', Password => 'sshhhhh');
#or
my $another_user = User->new();
$another_user->Email('jorge@foo.com');
$another_user->Password('sshhhhh');
If the database info you provided in the config file was accurate and you already created the database (Jorge will not create your database, at least, not now, but likely to change in next versions) You should be able now to start interacting with it.
Try now something like this, later on your instance script:
$user->insert;
print $user->Id; #if the insert was successful, you $user->Id should
#return the inserted id.
Ideally, that should have worked fine and now you can start using Jorge.
Available method for Jorge::DBEntity based classes are:
- insert
- update
- delete
- get_by
-
All those methods are pretty self explanatory, but this should guide you through the basic operations
YourInstanceScript.pl
#!/usr/bin/perl
use User;
my $user = User->new(Email => 'jorge@foo.com', Password => 'sshhhhh');
$user->insert;
#now $user->Id returns the inserted id from the database
$user->Email('updated_mail@bar.com');
$user->update;
#same $user->Id, but $user->Email was updated in the database
$user->delete
#now, even while the $user exists in memory, is not present anymore on
the database
#now, let's try something more complex
my $user2 = User->new(Email => 'coco@foo.com', Password => 'secret');
$user2->get_by(qw[Email Password]);
print $user2->Id;
# Now, if there is a User in with Email = 'coco@foo.com' AND a Password
# = 'secret' then $user2->Id will be a positive integer. Otherwhise, it
# will return undef
$user2->get_by('Email'); #will look only for the Email field.
As you can see, you should ALLWAYS check your object to confirm that it found at match before using it.
I'm considering implementing some error checking method, but since I got used to check for Id's on my objects.
If you have a proposal to solve this, feel free to email or open a request ticket on CPAN Request Tracker at: http://rt.cpan.org/NoAuth/Bugs.html?Dist=Jorge
Another thing to consider is that, even if the get_by() method finds more than one match, it will allways use the first one.
If you need to retrieve more than 1 element at a time, then you need Jorge::ObjectCollection
Defining Your new Jorge based Object Collection
YourClassCollection.pm
package YourClassCollection;
use base 'Jorge::ObjectCollection';
use YourClass;
use strict;
sub create_object {
return new YourClass;
}
;1
And that's it. Instant gratification.
Now you can create a new YourClassCollection object and get multiple objects from the database.
How? simple. Just pass the parameters to get the matching objects from the database.
YourInstanceScript.pl
#!/usr/bin/perl
use Users; # (note the convention. for DBEntity based packages we used
# singular form of the name and the plural form form
# for ObjectCollection based objects, similar as Rail's
# Active::Record does.
my $users = Users->new();
my %params = (Email => 'coco@foo.com');
$users->get_all(%params);
while (my $user = $users->get_next){
print $user->Id;
}
Available method for Jorge::ObjectCollection based classes are:
- get_all
- get_count
- get_next
-
Again, all those methods are pretty self explanatory.
get_all and get_count can receive parameters (as a hash). If they dont, both will retrive all the rows from the database to provide a result.
Params Syntax for ObjectCollection based objects
Simplest case: Name equals some value.
my %params = (Name => 'Jorge');
Moving on...
my %params = (Name => ['!=', 'Jorge']);
Let's continue
my %params = (Price => ['>', 12]);
my %params = (Price => ['>', 12], Id => ['<', 30]); #That's a AND.
my %params = (Price => 'is null');
#OR support. Yeah!
my %params = (Name => [ 'or',[ ['=','Bill'],['=','Steve'],['=','Linus']);
#IN
my %params = (Id => [ 'in', [1,2,3,5,7,11] ]);
#BETWEEN
#NOTE: Allways provide min and max values
my %params = (Id => ['between',(1,100)]);
#Use a object as a parameter
my %params = (User => $user);
get_all, get_next: Iterating.
Once you invoke the method get_all (hint. if you invoke it without params) it will do a SELECT * FROM __table__, retrieving all the elements of that table/class.
In fact, no query will retrieve all the objects, but only their Id's (or primary keys.)
After you retrieve all the matching objects, you can start iterating pulling elements from the array of matching elements invoking the method get_next
my $elements = Elements->new;
my %params = (Field => 'Value');
$elements->get_all(%params);
while (my $element = $elements->get_next){
#We're Iterating!
print $element->Id;
}
Setup
Config File
Jorge expects a YAML config file under a certain directory/filename. Default value is config/jorge.yml relative to the working dir path If you need to override or change the location of the config file, you can modify the config_file variable in Jorge::Config file
Jorge::Config::$CONFIG_FILE = 'path to your config';
In your instance script / Main package.
AUTHORS
Mondongo, <mondongo at gmail.com> Did the important job and started this beauty.
Julian Porta, <julian.porta at gmail.com> took the code and tried to make it harder, better, faster, stronger.
BUGS
Please report any bugs or feature requests to bug-jorge at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Jorge. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Jorge
You can also look for information at:
Github Project Page
RT: CPAN's request tracker
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
ACKNOWLEDGEMENTS
Mondongo <mondongo at gmail.com> For starting this.
COPYRIGHT & LICENSE
Copyright 2009 Julian Porta, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.