Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

v0.60 - Mass refactoring and improvements

  • Loading branch information...
commit c152739fa168ea4779c702162e71c2349d6251e2 1 parent f367833
@kberov authored
View
11 Changes
@@ -1,5 +1,16 @@
Revision history for Mojolicious::Plugin::DSC
+
+0.60 2012-08-09 22:48 EEST
+ - Jumping from 0.06 to 0.60 to be closer to DBIx::Simple::Class.
+ - Multiple dbix helpers. My->dbix can be different from Your->dbix if overriden. See DBIx::Simple::Class/dbix
+ - Try to guess default namespace for loading classes
+ from $config->{database} and $config->{dsn}.
+ Supported drivers:mysql, SQLite, Pg.
+ - Using Carp instead of Mojo::Exception.
+ - Removed default $DRIVER_ATTRIBUTES
+ - Improved Makefile.PL.
+
0.06 2012-08-05 23:49 EEST
- README is a text file now
- enhanced documentation
View
2  MANIFEST
@@ -9,5 +9,7 @@ t/basic.t
t/lib/My.pm
t/lib/My/Groups.pm
t/lib/My/User.pm
+t/lib/Your.pm
+t/lib/Your/User.pm
t/pod-coverage.t
t/pod.t
View
11 Makefile.PL
@@ -10,7 +10,16 @@ WriteMakefile(
AUTHOR => q{Красимир Беров <berov@cpan.org>},
LICENSE => 'artistic_2',
PREREQ_PM => {'Mojolicious' => '2.0', 'DBIx::Simple::Class' => '0.62'},
- test => {TESTS => 't/*.t'},
+ META_MERGE => {
+ requires => {perl => '5.010001'},
+ resources => {
+ license => 'http://www.opensource.org/licenses/artistic-license-2.0',
+ repository => 'https://github.com/kberov/Mojolicious--Plugin--DSC',
+ bugtracker => 'https://github.com/kberov/Mojolicious--Plugin--DSC/issues'
+ },
+ no_index => {directory => ['t']}
+ },
+ test => {TESTS => 't/*.t'},
dist => {COMPRESS => 'gzip -9f', SUFFIX => 'gz',},
clean => {FILES => 'Mojolicious-Plugin-DSC-*'},
);
View
70 lib/Mojolicious/Plugin/DSC.pm
@@ -1,24 +1,19 @@
package Mojolicious::Plugin::DSC;
use Mojo::Base 'Mojolicious::Plugin';
use DBIx::Simple::Class;
+use Mojo::Util qw(camelize);
+use Carp;
-our $VERSION = '0.06';
+our $VERSION = '0.60';
#some known good defaults
-my %COMMON_ATTRIBUTES = (
+my $COMMON_ATTRIBUTES = {
RaiseError => 1,
- HandleError => sub { Carp::croak(shift) },
AutoCommit => 1,
-);
-
-my $DRIVER_ATTRIBUTES = {
- 'mysql' => {mysql_enable_utf8 => 1, mysql_bind_type_guessing => 1},
- 'SQLite' => {sqlite_unicode => 1},
- 'Pg' => {pg_enable_utf8 => 1}
};
-my $MEx = 'Mojo::Exception';
+
has config => sub { {} };
sub register {
@@ -26,46 +21,53 @@ sub register {
# This stuff is executed, when the plugin is loaded
# Config
- $config ||= {};
+ $config ||= {};
$config->{load_classes} ||= [];
- $config->{namespace} ||= '';
$config->{DEBUG} //= ($app->mode =~ /^dev/ ? 1 : 0);
$config->{dbh_attributes} ||= {};
#prepared Data Source Name?
if (!$config->{dsn}) {
$config->{driver}
- || $MEx->throw(
- 'Please choose and set a database driver like "mysql","SQLite","Pg"!..');
- $config->{database} || $MEx->throw('Please set "database"!');
+ || croak('Please choose and set a database driver like "mysql","SQLite","Pg"!..');
+ $config->{database} || croak('Please set "database"!');
$config->{host} ||= 'localhost';
$config->{dsn} = 'dbi:'
. $config->{driver}
. ':database='
. $config->{database}
. ';host='
- . $config->{host};
+ . $config->{host}
+ . ($config->{port} ? ';port=' . $config->{port} : '');
+ $config->{database} =~ m/(\w+)/x and do {
+ $config->{namespace} ||= camelize($1);
+ };
+ $config->{namespace} ||= camelize($config->{database});
+ }
+ else {
+ my ($scheme, $driver, $attr_string, $attr_hash, $driver_dsn) =
+ DBI->parse_dsn($config->{dsn})
+ || croak("Can't parse DBI DSN! dsn=>'$config->{dsn}'");
+ $config->{driver} = $driver;
+ $scheme =~ m/(database|dbname)=\W?(\w+)/x and do {
+ $config->{namespace} ||= camelize($2);
+ };
+ $config->{dbh_attributes} =
+ {%{$config->{dbh_attributes}}, ($attr_hash ? %$attr_hash : ())};
}
- #check if it is ok
- DBI->parse_dsn($config->{dsn})
- || $MEx->throw("Can't parse DBI DSN! dsn=>'$config->{dsn}'");
-
-
- $MEx->throw('"load_classes" configuration directive '
+ croak('"load_classes" configuration directive '
. 'must be an ARRAY reference containing a list of classes to load.')
unless (ref($config->{load_classes}) eq 'ARRAY');
- if (@{$config->{load_classes}} && !$config->{namespace}) {
- $MEx->throw('Please define namespace for your model classes!');
- }
+
DBIx::Simple::Class->DEBUG($config->{DEBUG});
#ready... Go!
my $dbix = DBIx::Simple->connect(
$config->{dsn},
- $config->{user},
- $config->{password},
- { %COMMON_ATTRIBUTES, %{$DRIVER_ATTRIBUTES->{$config->{driver}} || {}},
+ $config->{user} || '',
+ $config->{password} || '',
+ { %$COMMON_ATTRIBUTES,
%{$config->{dbh_attributes}}
}
);
@@ -80,7 +82,9 @@ sub register {
$config->{dbix_helper} ||= 'dbix';
$app->attr($config->{dbix_helper}, sub {$dbix});
$app->helper($config->{dbix_helper}, $app->dbix); #add helper dbix
- DBIx::Simple::Class->dbix($app->dbix); #do not forget
+ my $DSC = $config->{namespace} || 'DBIx::Simple::Class';
+ eval { Mojo::Loader->load($DSC) || $DSC->dbix($app->dbix) }
+ || DBIx::Simple::Class->dbix($app->dbix); #do not forget
$self->_load_classes($config);
@@ -93,22 +97,22 @@ sub _load_classes {
if ($config->{namespace} && @{$config->{load_classes}}) {
my @classes = @{$config->{load_classes}};
my $namespace = $config->{namespace};
- $namespace .= '::' unless $namespace =~ /\:\:$/;
+ $namespace .= '::' unless $namespace =~ /:{2}$/;
foreach my $class (@classes) {
if ($class =~ /$namespace/) {
my $e = Mojo::Loader->load($class);
- $MEx->throw($e) if $e;
+ carp($e) if ref $e;
next;
}
my $e = Mojo::Loader->load($namespace . $class);
- $MEx->throw($e) if $e;
+ carp($e) if ref $e;
}
}
elsif ($config->{namespace} && !@{$config->{load_classes}}) {
my @classes = Mojo::Loader->search($config->{namespace});
foreach my $class (@classes) {
my $e = Mojo::Loader->load($class);
- $MEx->throw($e) if $e;
+ croak($e) if ref $e;
}
}
}
View
23 t/advanced.t
@@ -8,7 +8,7 @@ BEGIN {
use lib qw(t/lib);
}
-use Test::More tests => 10;
+use Test::More tests => 12;
package main;
@@ -21,12 +21,11 @@ my $config = {
DEBUG => 0,
namespace => 'My',
load_classes => ['Groups'],
- dbh_attributes => {},
+ dbh_attributes => {sqlite_unicode => 1},
driver => 'SQLite',
onconnect_do => [],
dbix_helper => 'dbix',
- host => 'localhost',
- dsn => 'dbi:SQLite:database=:memory:;host=localhost'
+ dsn => 'dbi:SQLite:database=:memory:'
};
isa_ok(plugin('DSC', $config), 'Mojolicious::Plugin::DSC');
@@ -56,6 +55,19 @@ my $user = My::User->new(
);
$user->save;
+#additional dbix
+my $your_config = {
+ namespace => 'Your',
+ load_classes => ['User'],
+ user => 'me',
+ dbix_helper => 'your_dbix',
+ dsn => 'dbi:SQLite:database=:memory:'
+};
+my $your_dbix = plugin('DSC', $your_config);
+
+can_ok(app, 'your_dbix');
+isnt(app->your_dbix, app->dbix, 'two schemas loaded');
+
get '/' => sub {
my $self = shift;
$self->render_text(
@@ -76,5 +88,4 @@ $t->get_ok('/')->status_is(200);
$t->content_is('Hello ' . $user->login_name . ' from group ' . $group->group . '!');
$t->post_form_ok('/edit/user', {id => 1, login_password => 'alabala123'})
- ->status_is(200);
-$t->content_is('New password for user петър is alabala123');
+ ->status_is(200)->content_is('New password for user петър is alabala123');
View
37 t/basic.t
@@ -7,28 +7,31 @@ BEGIN {
use lib qw(t/lib);
}
-use Test::More tests => 7;
+use Test::More tests => 8;
package main;
+use Mojolicious::Plugin::DSC;
use Mojolicious::Lite;
use Test::Mojo;
use Data::Dumper;
-my $config = {};
+my $help_count = 1;
+my $config = {};
like(
(eval { plugin 'DSC' }, $@),
qr/Please choose and set a database driver/,
' no driver'
);
$config->{driver} = 'SQLite';
-is((eval { plugin 'DSC', $config }, $@), 'Please set "database"!', 'no database');
+like((eval { plugin 'DSC', $config }, $@), qr'Please set "database"!', 'no database');
$config->{database} = ':memory:';
+my $generated_config = plugin('DSC', $config)->config;
is_deeply(
- plugin('DSC', $config)->config,
+ $generated_config,
{ database => ':memory:',
DEBUG => 1,
load_classes => [],
- namespace => '',
+ namespace => 'Memory',
dbh_attributes => {},
driver => 'SQLite',
onconnect_do => [],
@@ -36,18 +39,32 @@ is_deeply(
host => 'localhost',
dsn => 'dbi:SQLite:database=:memory:;host=localhost'
},
- 'default minimal config'
+ 'default generated from minimal config'
);
-is(eval { plugin 'DSC', $config; 1; }, 1, 'database');
+
+#warn app->dumper($generated_config);
+$config->{dbix_helper} = $config->{dbix_helper} . $help_count++;
+isa_ok(eval { plugin('DSC', $config) } || $@, 'Mojolicious::Plugin::DSC', 'database');
$config = {dsn => 'garbage'};
-like((eval { plugin 'DSC', $config }, $@), qr/Can't parse DBI DSN/, 'dsn');
-$config = {dsn => 'dbi:SQLite:dbname=:memory:', load_classes => 'someclass'};
+like((eval { plugin 'DSC', $config }, $@), qr/Can't parse DBI DSN/, 'garbage dsn');
+$config = {
+ dsn => 'dbi:SQLite:dbname=:memory:',
+ load_classes => 'someclass',
+ dbix_helper => 'dbix_' . $help_count++
+};
+
like(
(eval { plugin 'DSC', $config }, $@),
qr/must be an ARRAY reference /,
'load_classes'
);
+$config->{namespace} = '';
$config->{load_classes} = ['My::User'];
-like((eval { plugin 'DSC', $config }, $@), qr/Please define namespace/, 'namespace');
+#get namespace from dbname/$schema
+is(plugin('DSC', $config)->config->{namespace}, 'Memory', 'namespace');
+$config = {dsn => 'dbi:SQLite:dbname=:memory:', dbix_helper => 'dbix_' . $help_count++};
+
+isa_ok(plugin('DSC', $config), 'Mojolicious::Plugin::DSC', 'proper dsn');
+
View
4 t/lib/My/User.pm
@@ -28,14 +28,14 @@ sub id {
$self->{data}{id} //= $self->CHECKS->{id}{default}; #getting value
}
-my $users_table = <<"T";
+my $users_table = <<"TAB";
CREATE TABLE users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
group_id INT default 1,
login_name VARCHAR(12),
login_password VARCHAR(100)
)
-T
+TAB
my $dbh = __PACKAGE__->dbix->dbh;
$dbh->do($users_table)
View
17 t/lib/Your.pm
@@ -0,0 +1,17 @@
+{
+
+ package Your; #our second schema
+ use 5.010;
+ use strict;
+ use warnings;
+ use utf8;
+ use base qw(DBIx::Simple::Class);
+
+ sub dbix {
+
+ # Singleton DBIx::Simple instance
+ state $DBIx;
+ return ($DBIx = $_[1] ? $_[1] : $DBIx) || Carp::croak('DBIx::Simple is not instantiated for schema "Your"');
+ }
+}
+1;
View
43 t/lib/Your/User.pm
@@ -0,0 +1,43 @@
+package Your::User;
+use Mojo::Base 'Your';
+
+sub TABLE {'users'}
+sub COLUMNS { [qw(id group_id login_name login_password)] }
+sub WHERE { {disabled => 1} }
+
+#See Params::Check
+my $_CHECKS = {
+ id => {allow => qr/^\d+$/x},
+ group_id => {allow => qr/^\d+$/x, default => 1},
+ login_name => {allow => qr/^\p{IsAlnum}{4,12}$/x},
+ login_password => {
+ required => 1,
+ allow => sub { $_[0] =~ /^[\w\W]{8,20}$/x; }
+ }
+};
+sub CHECKS {$_CHECKS}
+
+sub id {
+ my ($self, $value) = @_;
+ if (defined $value) { #setting value
+ $self->{data}{id} = $self->_check(id => $value);
+
+ #make it chainable
+ return $self;
+ }
+ $self->{data}{id} //= $self->CHECKS->{id}{default}; #getting value
+}
+
+my $users_table = <<"TAB";
+CREATE TABLE users(
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ login_name VARCHAR(12),
+ login_password VARCHAR(100)
+ )
+TAB
+
+my $dbh = __PACKAGE__->dbix->dbh;
+$dbh->do($users_table)
+ unless $dbh->table_info(undef, undef, 'users', 'TABLE')->fetchrow_hashref;
+
+1;
Please sign in to comment.
Something went wrong with that request. Please try again.