NAME
DBIx::Counter - Manipulate named counters stored in a database
WARNING
This is the initial release! It has been tested to work with SQLite, Mysql, Postgresql and MS SQL Server, under perl 5.6 and 5.8.
I would appreciate feedback, and some help on making it compatible with older versions of perl. I know 'use warnings' and 'our' don't work before 5.6, but that's where my historic knowledge ends.
SYNOPSIS
use DBIx::Counter;
$c = DBIx::Counter->new('my counter',
dsn => 'dbi:mysql:mydb',
login => 'username',
password => 'secret'
);
$c->inc;
print $c->value;
$c->dec;
DESCRIPTION
This module creates and maintains named counters in a database. It has a simple interface, with methods to increment and decrement the counter by one, and a method for retrieving the value. It supports operator overloading for increment (++), decrement (--) and stringification ("").
It should perform well in persistent environments, since it uses the connect_cached and prepare_cached methods of DBI.
The biggest advantage over its main inspiration - File::CounterFile - is that it allows distributed, concurrent access to the counters and isn't tied to a single file system.
Connection settings can be set in the constructor. The table name is configurable, but the column names are currently hard-coded to counter_id and value.
The following SQL statement can be used to create the table:
CREATE TABLE counters (
counter_id varchar(64) primary key,
value int not null default 0
);
This module attempts to mimick the File::CounterFile interface, except currently it only supports integer counters. The locking functions in File::CounterFile are present for compatibility only: they always return 0.
EXAMPLES
Some other ways to call new():
# with an initial value, and a different table name
$c = DBIx::Counter->new('my counter',
42,
dsn => 'dbi:mysql:mydb',
tablename => 'gauges'
);
# with a predefined connection
$c = DBIx::Counter->new('my counter', dbh => $dbh);
A very basic real-world example:
# a hit counter!
# demonstrates operator overloading and stringification
use CGI qw/:standard/;
use DBIx::Counter;
print header(),
start_html(),
h1("Welcome");
my $c = DBIx::Counter->new('my_favorite_page',
dsn => 'dbi:mysql:mydb',
login => 'username',
password => 'secret'
);
$c++;
print
em("this page has been accessed $c times!"),
end_html();
METHODS
- new
-
Creates a new counter instance.
First parameter is the required counter name. Second, optional, argument is an initial value for the counter on its very first use. It also accepts named parameters for an already existing database handle, or the dbi connection string, dbi login and dbi password, and the table name:
- inc
-
increases the counter by one.
$c->inc; # or using overload: $c++;
- dec
-
decreases the counter by one.
$c->dec; # or using overload: $c--;
- value
-
returns the current value of the counter.
print $c->value; # or using overload: print "Item $c is being processed\n";
- lock
-
Noop. Only provided for API compatibility with File::CounterFile.
- unlock
-
Noop. Only provided for API compatibility with File::CounterFile.
- locked
-
Noop. Only provided for API compatibility with File::CounterFile.
GLOBAL SETTINGS
In addition to passing settings through the constructor, it's also possible to use the package variables $DSN, $LOGIN and $PASSWORD and $TABLENAME. This allows you to specify the settings application-wide, or within a block of code where you need multiple counters. Each of those variables supplies a default for the lowercase parameters to "new".
However, be aware that using global variables is not recommended. Setting them in more than one place will make it difficult to track down bugs. Using them in multiple applications in persistent environments such as mod_perl will result in unpredictable behaviour. If you really need to use this feature, always try to use "local".
Here's an example:
use DBIx::Counter;
sub count_stuff {
local $DBIx::Counter::DSN = 'dbi:SQLite:dbname=counters.sqlt';
local $DBIx::Counter::TABLENAME = 'my_own_counters';
my $c1 = DBIx::Counter->new('gauge one');
my $c2 = DBIx::Counter->new('gauge two');
# ...
}
SEE ALSO
AUTHOR
Rhesa Rozendaal, <rhesa@cpan.org>.
COPYRIGHT AND LICENSE
Copyright (C) 2005 by Rhesa Rozendaal
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.2 or, at your option, any later version of Perl 5 you may have available.