NAME

DBIx::QuickORM - Actively maintained, quick to start, powerful ORM tool.

DESCRIPTION

An actively maintained ORM tool that is qucik and easy to start with, but powerful and expandable for long term and larger projects. An alternative to DBIx::Class, but not a drop-in replacement.

SYNOPSIS

FIXME!

PRIMARY INTERFACE

See DBIx::QuickORM for the primary interface documentation,

RECIPES

See DBIx::QuickORM::Recipes for documentation on specific scenarios that may fit your need.

FEATURE SUMMARY

Declarative syntax

See DBIx::QuickORM.

Perl schema to SQL conversion/generation
my $sql = $orm->generate_schema_sql;
$orm->generate_and_load_schema();
SQL schema to perl conversion/generation
orm { db { ... }; autofill(); } # Populate from the database!

Also

my $schema = $db->connect->generate_schema();

Also

my $schema = DBIx::QuickORM::Util::SchemaBuilder->generate_schema($orm->connection);
Async query support - single connection
my $async = $orm->select({...})->async();
until( $async->ready ) { ... }
my @rows = $async->all;
Multiple concurrent async query support - multiple connections on 1 process
my $aside1 = $orm->select({...})->aside();
my $aside2 = $orm->select({...})->aside();
my $aside3 = $orm->select({...})->aside();

until( $aside1->ready ) { ... }
my @rows = $aside1->all;
...
Multiple concurrent async query support - emulation via forking
my $forked1 = $orm->select({...})->forked();
my $forked2 = $orm->select({...})->forked();
my $forked3 = $orm->select({...})->forked();

until( $forked1->ready ) { ... }
my @rows = $forked1->all;
...
Plugin system - Lots of hooks available
plugin sub { ... }; # On the fly plugin writing
plugin Some::Plugin; # Use a plugin class (does not have or need a new method)
plugin Other::Plugin->new(...); Plugin that need to be blessed

Define custom plugin hooks in your custom tools:

plugin_hook NAME => \%params; # Any/All plugins can take action here.
Ability to customize relationship names when generating perl schema from SQL schema

This is done va plugins, See DBIx::QuickORM::Plugin.

Can have multiple ORMs on any number of databases in a single app

Any number of orms with any number of schemas, they can all talk to the same DB or to different ones.

Select object system that closely resembles ResultSets from DBIx::Class

ResultSet was a good idea, regardless of your opinion on DBIx::Class. The DBIx::QuickORM::Select objects implement most of the same things.

Uses SQL::Abstract under the hood, so query syntax should be familiar to DBIx::Class users

See SQL::Abstract.

my $sel = $orm->select(\%sql_abstract_where, $order_by);
my $sel = $orm->select(where => \%where, order_by => $order_by, ...);
Build in support for transactions and savepoints

The transaction(sub { ... }) method can be accessed via the orm, select, source and row objects.

$orm->transaction(sub { ... });
$sel->transaction(sub { ... });
$src->transaction(sub { ... });
$row->transaction(sub { ... });
Per-connection source/row caches
First-class Inflation/Deflation (conflation (yes, its a bad pun)) support
Multiple databases supported:

See the DBIx::QuickORM::DB for the database base class all drivers build upon. You can even add your own if yours is not on this list.

PostgreSQL

See DBIx::QuickORM::DB::PostgreSQL, which uses DBD::Pg under the hood.

MySQL (Generic)

See DBIx::QuickORM::DB::MySQL, which supports both DBD::mysql and DBD::MariaDB for connections.

MySQL (Percona)

See DBIx::QuickORM::DB::Percona, which supports both DBD::mysql and DBD::MariaDB for connections.

MariaDB

See DBIx::QuickORM::DB::MariaDB, which supports both DBD::mysql and DBD::MariaDB for connections.

SQLite

See DBIx::QuickORM::DB::SQLite, which uses DBD::SQLite under the hood.

MOTIVATION

The most widely accepted ORM for perl, DBIx::Class is for all intents and purposes, dead. There is only 1 maintainer, and that person has stated that the project is feature complete. The project will recieve no updates apart from critical bugs. The distribution has been marked such that it absolutely can never be transferred to anyone else.

There are 4 ways forward:

Use DBIx::Class it as it is.

Many people continue to do this.

Monkeypatch DBIx::Class

I know a handful of people who are working on a way to do this that is not terrible and will effectively keep DBIx::Class on life support.

Fork DBIx::Class

I was initially going to take this route. But after a couple hours in the codebase I realized I dislike the internals of DBIx::Class almost as much as I dislike using it as an app developer.

Write an alternative

I decided to take this route. I have never liked DBIx::Class, I find it difficult to approach, and it is complicated to start a project with it. The interface is unintuitive, and the internals are very opaque.

My goal is to start with the interface, make it approachable, easy to start, etc. I also want the interface to be intuitive to use. I also want expandability. I also want to make sure I adopt the good ideas and capabilities from DBIx::Class. Only a fol would say DBIx::Class has nothing of value.

GOALS

Quick to start

It should be very simple to start a project. The ORM should stay out of your way until you want to make it do something for you.

Intuitive

Names, interfaces, etc should make sense and be obvious.

Declarative Syntax

DBIx::Class had an abysmal interface calling __PACKAGE__->blah all over the place. You also had to create a lot of classes to line up with your tables. With DBIx::QuickORM You can declare your table structure anywhere, and they do not need associated clases per table. That said it is also trivial to define a class for any given table and add your own custom methods.

Make as few assumptions as possible

DBIx::Class and other orms tend to make some assumptions such as:

Only 1 database connection at a time
Only 1 database server at a time
Only 1 instance of the schema at a time
Expandability

Should be easy to extend and expand the functionality.

Inflation/Deflation should be trivial, and "just work" in fetched objects, inserts, selects, etc.

The way DBIx::Class handled inflation and deflation left a lot of places where you had to ask "Can I pass an inflated form here? or do I need to deflate it first?". In DBIx::QuickORM this should never be a question, there will be few if any places where inflation and deflation is not automatic.

In this project I am calling it "conflation", yes it is a terrible pun, and thr word "conflate" has no real connection to "inflate" or "deflate" as far as I know... but I like it as a blanket term to encapsulate both "inflate" and "deflate". Most inflation and deflation occurs with conflator classes.

Easy to generate the perl side orm from the database itself if the schema is already in the database

If you tell the orm how to connect to the database, you can ask it to just generate the table based data. If it does not generate them exactly how you want (object or relationship names are not ideal) then you have hooks to use to tell it how to name them.

This is a core functionality of DBIx::QuickORM, not a secondary project or side-thought.

Easy to generate the sql to initialize the database if you have the perl code already defined

If you write perl code that defines your database structure, table layout, relations, etc. Then you can ask the orm to give you an SQL dump in whatever supported SQL variant you want. You can then take this SQL and load it into your database. You can even tell the DB to load the schema into a database once you are connected.

This is a core functionality of DBIx::QuickORM, not a secondary project or side-thought.

Built-in support for PostgreSQL, MariaDB, SQLite and MySQL.

These are my big 4 for initial support. Additional DB's can be supported, and you can write your own database-orm inferface modules if you want something else supported.

With a properly written DB class the ORM can even handle translating concepts from one database to another. For example MySQL is the only one of the big 4 that does not have a builtin UUID type. The ORM will let you use BINARY(16), VARCHAR(36) on MySQL, or even other types to store the UUID, and with the UUID conflator (inflation/deflation) you can make it completely transparent to the app. The same schema definition (on perls side) will work just as well on any of the 4 database servers.

Async capabilities

Async is supported in multiple ways:

Using native Async functionality on the current connection

Send off a query, then do somthing else until it is ready. Even works inside transactions! The caveat is you cannot use the db connection for anything else while you wait.

This feature is accessed as $select->async. See DBIx::QuickORM::Select.

Using native Async functionality with multiple connections

You can make Async requests where each one operates on a different connection so they can operate concurrently. The caching is managed for you as well. The main caveat here is that you cannot use it with transactions and multiple connections cannot share a transaction.

Exceptions will be thrown if you start one of these during a transaction.

Exceptions will be thrown if you start a transaction while one of these is running.

This feature is accessed as $select->aside. See DBIx::QuickORM::Select.

Using fork + Different connections

The queries each run on their own connection and in their own processes, then the data will be send to the primary process. This is useful for databases that do not support async queries natively, such as SQLite.

Exceptions will be thrown if you start one of these during a transaction.

Exceptions will be thrown if you start a transaction while one of these is running.

This feature is accessed as $select->forked. See DBIx::QuickORM::Select.

Transaction Management

DBIx::QuickORM provides easy ways to start and mnage transactions, as well as using savepoints for an effective "nested transactions" functionality.

Caveat: If combined with external transaction management, things can go bad, or be confusing.

Cache Management

DBIx::QuickORM provides a caching layer that associates cache with a specific connection. You can clear all the cache for the connection, or all the cache for a specific table in the connection. You can also disable cache or ignore cache at any time. There is also sane handling of caching with transactions.

SCOPE

The primary scope of this project is to write a good ORM for perl. It is very easy to add scope, and try to focus on things outside this scope. I am not opposed to such things being written around the ORM fucntionality, afterall the project has a lot of useful code, and knowledge of the database. But th primary focus must always be the ORM functionality, and it must not suffer in favor of functionality beyond that scope.

MAINTENANCE COMMITMENT

I want to be sure that what happened to DBIx::Class cannot happen to this project. I will maintain this as long as I am able. When I am not capable I will let others pick up where I left off.

I am stating here, in the docs, for all to see for all time:

If I become unable to maintain this project, I approve of others being given cpan and github permissions to develop and release this distribution.

Peferably maint will be handed off to someone who has been a contributor, or to a group of contributors, If none can be found, or none are willing, I trust the cpan toolchain group to takeover.

SOURCE

The source code repository for DBIx-QuickORM can be found at http://github.com/exodist/DBIx-QuickORM/.

MAINTAINERS

Chad Granum <exodist@cpan.org>

AUTHORS

Chad Granum <exodist@cpan.org>

COPYRIGHT

Copyright Chad Granum <exodist7@gmail.com>.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

See http://dev.perl.org/licenses/