September 2006

Storage

small item_class/item_storage_class refactor

Currently Working On

Comments Off

Permalink

Cookbook: Adding Columns in 1.0

Introduction

I’ve updated this to reflect changes made in 0.99_11, which should be available on CPAN shortly.

As 1.0 draws near, it was about time I started on the ever popular Cookbook/Tutorial stuffs. I decided to tackle something everyone asks: how to add columns.

The methods below outline the steps necessary to add columns to the default install of Handel 1.x. The steps below generally apply to customizing most storage options, including removing columns, adding constraints, etc.

This article is broken down into three solutions: Good, Better, and Best.

Good

If you need a quick fix in a script or want to alter all instances of Handel objects within the same process, you can simple add a column to the desired classes storage using Handel::Storage::add_columns.

    #!/usr/bin/perl -w
use strict;
use warnings;
use Handel::Cart;

Handel::Cart->storage->add_columns('custom');
Handel::Cart->create_accessors;

my $carts = Handel::Cart->search;
print $carts->count;

while (my $cart = $carts->next) {
print $cart->custom, "\n";
};

Better

The example above gets the job done with a minimal amount of code. But if you’re on shared server with other people using Handel, you’re going to get a nasty phone call when every one discovers their stuff has an extra field in it.

The better, more polite approach is to make your own custom classes and use [ab]use them instead.

    package My::Cart;
use strict;
use warnings;
use base qw/Handel::Cart/;

__PACKAGE__->item_class('My::Cart::Item');
__PACKAGE__->storage->add_columns('custom');
__PACKAGE__->create_accessors;

1;

You don’t have to subclass both the cart and items classes, but for the sake of good practice, there’s no reason not to if you’ve gone this far.

    package My::Cart::Item;
use strict;
use warnings;
use base qw/Handel::Cart::Item/;

1;

Then in your script, use you’re cart instead.

    #!/usr/bin/perl -w
use strict;
use warnings;
use My::Cart;

my $carts = My::Cart->search;
print $carts->count;

while (my $cart = $carts->next) {
print $cart->custom, "\n";
};

Best

The two approaches above have one potential issue: they assume that the current classes will always use the default storage. If you add columns using only the column name, that won’t be an issue. If you add columns using the DBIx::Class C<\%column_info> syntax, you will have a problem if the new storage class doesn’t understand the syntax.

    package My::Cart;
use strict;
use warnings;

use base qw/Handel::Cart/;
__PACKAGE__->storage_class('Future::Storage::XML');

# this line goes boom!
# don't know how to add column 'HASH(0x2254b8)'
__PACKAGE__->storage->add_columns('foo' => {
data_type   => 'varchar',
size        => 50,
is_nullable => 1
});

1;

This is a potential problem when setting any storage class option from within the interface classes that uses it. To help abstract the storage specifics away from the interface classes that use them, you should go the extra mile and declare custom storage classes. I did mention that it’s a ‘framework’ right? :-)

Create Cart and Item Storage Classes

First we need to create custom storage classes for the Cart and Item interface classes.

    package My::Storage::Cart;
use strict;
use warnings;
use base qw/Handel::Storage::DBIC::Cart/;

__PACKAGE__->item_storage_class('My::Storage::Cart::Item');

__PACKAGE__->add_columns('foo' => {
data_type   => 'varchar',
size        => 50,
is_nullable => 1
});

1;

package My::Storage::Cart::Item;
use strict;
use warnings;
use base qw/Handel::Storage::DBIC::Cart::Item/;

1;

Create Cart and Item Classes

    package My::Cart;
use strict;
use warnings;
use base qw/Handel::Cart/;

__PACKAGE__->item_class('My::Cart::Item');

# No storage changes in here
# The storage class takes care of adding the column
__PACKAGE__->storage_class('My::Storage::Cart');
__PACKAGE__->create_accessors;

1;

package My::Cart::Item;
use strict;
use warnings;
use base qw/Handel::Cart::Item/;

__PACKAGE__->storage_class('My::Storage::Cart::Item');
__PACKAGE__->create_accessors;

1;

Code Away Merrill

    #!/usr/bin/perl -w
use strict;
use warnings;
use My::Cart;

my $carts = My::Cart->search;
print $carts->count;

while (my $cart = $carts->next) {
print $cart->custom, "\n";
};

Now that we’ve pushed the add column magic down into the storage class, My::Cart is blissfully unaware of any changes that storage class needs to make in order to add a column:

    package My::Storage::Cart;
use strict;
use warnings;
use base qw/Handel::Storage::DBIC::Cart/;

__PACKAGE__->item_storage_class('My::Storage::Cart::Item');
__PACKAGE__->add_columns([qw/foo varchar 50 nullable/]);

1;

Conclusion

That’s all there is to it! Like most of Handel, you can pick your level of magic based on your needs.

Articles

Comments Off

Permalink

Handel 0.99_10 Released

The coding monkeys are on crack, and they can’t be stopped!

  • Added start of Cookbook and Cookbook/AddColumns
  • Moved DBIC specific Storage classes into DBIC namespace
  • Changed process to get items->all instead of (items)

Announcements

Comments Off

Permalink

Handel 0.99_09 Released

Fresh out of the monkey pit.

  • Catalyst Helpers now require FormValidator::Simple 0.17 (Woohoo!)
  • Validation component now requires DBIx::Class::Validation 0.01001 which uses new FV::S for profile/instance/messages fixes
  • Filled in pod generated by Catalyst Helpers in a moment of weakness

Announcements

Comments Off

Permalink

S5

maybe a presentation…brain is done for the day

Currently Working On

Comments Off

Permalink

Handel 0.99_08 Released

Another quick release before I lose my energy today and forget what I was thinking about this morning.

  • Added txn_begin/commit/rollback to Storage and Storage::DBIC to help abstract Checkout::process from Storage.
  • Added Storage::DBIC::Result to get DBIC specific things out of Storage::Result
  • Minor pod fixes

Announcements

Comments Off

Permalink

Checkout

abstracting txn_commt/rollback/begin in process

Currently Working On

Comments Off

Permalink

07 is up

Helpers rewritten but still need some tweaking

Currently Working On

Comments Off

Permalink

Handel 0.99_07 Released

I can see light at the end of the tunnel. It could always be the train though. The Catalyst helpers have been reworked. They still need some tweaking, but what doesn’t. Maybe I’ll feel generous and fill in the auto generated pod. :-)

WARNING: The auto generated Catalyst helper code requires FormValidator::Simple changes/fixes that have yet to be commited or accepted until the author responds. Contact me if you need a copy of the modified version. Keep your fingers crossed that I don’t have to do a hostile takeover of the module just to fix a few bugs.

  • Moved perl_critic.t to style_perl_critic.t
  • Added style_no_tabs.t
  • Style tests now enabled via TEST_PRIVATE
  • Reworked Catalyst Helpers for Controllers and their tests.
  • Fixed issue where add_handler wasn’t assigning unique pref ids when non were specified in the plugins themselves.
  • Moved requirements to Requirements.pod
  • Cart destroy now works on a blessed object under Catalyst
  • AssignOrderNumber checkout plugin no longer sets the updated field. This will be rolled into the Order class in the next release.

Announcements

Comments Off

Permalink

Helpers

Just about done with controller helpers…need to fix tests

Currently Working On

Comments Off

Permalink