NAME
DBIx::Inline::Manual - A manual for DBIx::Inline
DESCRIPTION
The users manual for DBIx::Inline. The pod for the actual module was beginning to get too big, so I decided to move it to its own manual.
CONTENT
Starting off
Connecting
There are two ways to begin using DBIx::Inline - using models, or connecting directly within your package. If you're wanting to reuse the same schema over and over again you're best method would to create a file called inline.yml, put your configuration in there and reuse the model when you need it. If it's just going to be a small once-off, it may be easier to just connect directly.
Using Models
A simple inline.yml file will look like this
---
MySchema:
connect: 'SQLite:mydb.db'
FooSchema:
connect: 'Pg:host=localhost;dbname=foo'
user: 'foo',
pass: 'foopass'
That gives us two reusable schemas. One using a simple SQLite driver, and the other Postgres. To use them in our package we reference them using model like so.
package main;
my $schema = main->model('MySchema');
my $foo = main->model('FooSchema')->resultset('a_table')->all;
You can also use config to move the config somewhere else..
package main;
use base 'DBIx::Class';
main->config('/var/schemas/myschema.yml');
my $schema = main->model('Foo');
We successfully now have two schemas running in the same package. The first one returns a schema, the second one chained a resultset onto it.
The other way is connecting directly.
Using the connect Schema method
Connecting directly is easy enough with connect
my $schema = main->connect(
dbi => 'Pg:host=localhost;dbname=foo',
user => 'foo_user',
pass => 'baz_pass',
);
Obviously you can leave out the user and pass if you're using SQLite. And remember, you can chain a table to a schema.
my $schema = main->connect(
dbi => 'SQLite:/path/to/sqlite.db'
)->resultset('my_table');
Once your schema has a resultset (at this point a resultset is just a table.. I need to rename the schema method from resultset to table, really), you can start searching, finding, updating, etc. A resultset is just a class holding multiple records.
ResultSet
Searching
The main part to doing anything at all in DBIx::Inline is returning a resulset via search. Search is a powerful method with a few different options. I'll show you how to return a simple resultset, and how to use it to paginate results for a web query with ease. First up, let's perform a simple search.
# search the table where the rows status = 'active', but only return the id and name
my $rs = $table->search([qw/id name/], { status => 'active' });
# search the table where the rows status = 'active', but only return 5 results
# also, order by id first
my $rs = $table->search([], { status => 'active' }, { rows => 5, order => ['id'] });
# now paginate the entire resultset returning 5 records at a time
my $page1 = $table->all->search([], {}, { page => 1, rows => 5 });
my $page2 = $table->all->search([], {}, { page => 2, rows => 5 });
# get the first and last records of a result by chaining
my $first = $table->all->first;
my $last = $table->search([], { code => 5485 })->last;
Inserting
Inserting requires nothing but a resultset. However, should you want to return the last inserted key with insert_id
, then you will need to set a primary key. This is very handy when wanting to see if the query worked or not. You can set the primary key on its own or chain it with a resultset.
$rs->primary_key('id'); # on its own
$rs = main->model('Foo')->resultset('users')->primary_key('id')
As you'll notice most methods are chainable. To actually insert a new row you just supply the required keys in a hash
# bring up the resultset
$rs = main->model('Foo')
->resultset('users')
->primary_key('id');
$rs->insert({
user => 'test',
password => 'testpass',
name => 'Mr Foo',
});
# technically, the user should be added, let's make sure we get a return ID
print "Added user with ID# " . $rs->insert_id
if $rs->insert_id;
Inserting actually returns the successful new row as a Result. So you can do things like..
my $user = $rs->insert({
user => 'foo',
pass => 'fooness',
name => 'The Foo',
});
$user->load_accessors;
print "New Name: " . $user->name;
print "Last Insert Primary key: " . $rs->insert_id . "\n"; # or you could use $user->id
What to do with ResultSet results
You can iterate through results using next.
while(my $row = $rs->next) {
say $row->{column_name};
}
Alternatively, you can update or delete them
my $rs = $table->search([], { foo => 'baz' });
$rs->update({ status => 'active' });
$rs->delete;
Less SQL queries = happy.
When you iterate through a resultset using next, it returns the result as a DBIx::Inline::Result. Another way to return a result from a resultset is using find. If you use 'find' it will return a single row.
my $result = $rs->find([], { foo => 'baz' });
say $result->{name};
As you can see it works the same as search, but will not return a resultset, and only returns 1 row.
Results
There isn't a great deal you can do with results compared to resulsets - they simply hold the row data for the current result in a hash.
$result->{name}
$result->{id}
etc..
You can create accessors for all of columns with load_accessors
$result->load_accessors;
say $result->name;
say $result->id;
But what if you have long column names and want them shortened? No problem, use accessorize.
$result->accessorize(
name => 'long_name_column',
id => 'repeat_id',
);
say $result->name; # instead of $result->{long_name_column}
If you pass arguments after load_accessors to any of the subroutines it creates you will update their value.
$result->load_accesors;
$result->name('New Name');