Difference between revisions of "Perl"
(Added to programming category) |
(→Mixing STDOUT and STDERR output in the right order: generating methods) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 99: | Line 99: | ||
'''might_have''' means: the same as '''has_one''', except its not guaranteed to be there. | '''might_have''' means: the same as '''has_one''', except its not guaranteed to be there. | ||
+ | |||
+ | === Cascading === | ||
+ | |||
+ | Attributes are required for the different relationships to disable cascading of delete/update. | ||
+ | |||
+ | <code>has_one</code> and <code>might_have</code> | ||
+ | |||
+ | { cascade_delete => 0, cascade_update => 0 } | ||
+ | |||
+ | <code>belongs_to</code> | ||
+ | |||
+ | { on_delete => undef, on_update => undef } | ||
+ | |||
+ | <code>has_many</code> | ||
+ | |||
+ | { cascade_delete => 0 } | ||
+ | |||
+ | === Dates === | ||
+ | |||
+ | Adding a database independent way of fetching the current date/time in UTC. | ||
+ | |||
+ | package TestApp::Schema::ResultSet::Test; | ||
+ | |||
+ | use strict; | ||
+ | use warnings; | ||
+ | |||
+ | use parent 'DBIx::Class::ResultSet'; | ||
+ | |||
+ | __PACKAGE__->load_components('Helper::ResultSet::DateMethods1'); | ||
+ | |||
+ | 1; | ||
+ | |||
+ | and then using it, get the resultset and the first test (id = 1) | ||
+ | |||
+ | my $tests = $schema->resultset('Test'); | ||
+ | my $test = $tests->find(1); | ||
+ | |||
+ | and to set the date | ||
+ | |||
+ | $test->test_date( $test->result_source->resultset->utc_now ); | ||
+ | |||
+ | or | ||
+ | |||
+ | $test->test_date( $tests->utc_now ); | ||
== Tips == | == Tips == | ||
Line 123: | Line 167: | ||
STDERR->autoflush(1); | STDERR->autoflush(1); | ||
STDOUT->autoflush(1); | STDOUT->autoflush(1); | ||
+ | |||
+ | === Generating almost identical methods === | ||
+ | |||
+ | You could use Moose to do something like this but what if you want to do something other than simple getter/setter methods? This works as far as I've tested it. I'm open to alternative suggestions though! | ||
+ | |||
+ | BEGIN { | ||
+ | foreach my $k (qw/name company address1 address2 area city postcode country phone email fax/) { | ||
+ | no strict 'refs'; | ||
+ | *{"MyModule::$k"} = sub { | ||
+ | my $self = shift; | ||
+ | my $value = shift; | ||
+ | if (defined $value) { | ||
+ | $self->{ $k } = $value; | ||
+ | } | ||
+ | return $self->{ $k }; | ||
+ | }; | ||
+ | } | ||
+ | } | ||
[[Category:Programming]] | [[Category:Programming]] |
Latest revision as of 14:04, 12 October 2018
Contents
Frameworks
Modules
DBIx::Class modules
- http://search.cpan.org/~frew/DBIx-Class/lib/DBIx/Class/ResultSet.pm
- http://search.cpan.org/~frew/DBIx-Class/lib/DBIx/Class/Schema.pm
- http://search.cpan.org/~ironcamel/Dancer-Plugin-DBIC/lib/Dancer/Plugin/DBIC.pm
- http://search.cpan.org/~flora/DBIx-Class-PassphraseColumn-0.02/lib/DBIx/Class/PassphraseColumn.pm
Custom Perl
Installing a custom version of Perl just for a single user (e.g a project) without breaking the system-wide Perl.
Packages required:
gcc patch bzip2 gcc-c++ make automake
As the unprivileged user:
$ curl -L https://install.perlbrew.pl | bash $ source ~/perl5/perlbrew/etc/bashrc $ perlbrew install perl-5.20.1 $ perlbrew switch perl-5.20.1 $ perlbrew install-cpanm $ echo 'source /home/plates/perl5/perlbrew/etc/bashrc' >> ~/.bashrc
After this you should be always using Perl 5.20.1 as this user (that's what the perlbrew switch does). To install modules, simply use cpanm followed by the module name.
Extra Perl modules for Catalyst dev
After installing a custom version of Perl as above it's a good idea to install a bunch of frequently used modules if you're doing any kind of Catalyst development.
cpanm Catalyst::Devel DBIx::Class::TimeStamp DBIx::Class::PassphraseColumn \ DBIx::Class::InflateColumn::Serializer Catalyst::Model::DBIC::Schema \ Catalyst::Plugin::Authentication Catalyst::Plugin::Authorization::Roles \ Catalyst::Plugin::Session Catalyst::Plugin::Session::Store::DBI \ Catalyst::Plugin::Session::State::Cookie Catalyst::Plugin::StatusMessage \ Catalyst::Authentication::Store::DBIx::Class Catalyst::View::TT \ Catalyst::View::JSON Log::Log4perl::Catalyst DBD::mysql Email::Valid \ Text::CSV_XS LWP::Protocol::https XML::Simple XML::Writer GD::Image \ GD::Text FCGI::ProcManager Catalyst::View::Email::Template \ Template::Plugin::DateTime HTML::Tiny Hashids Term::Size::Any Time::ParseDate
Accessing SQL Server from Perl
Install the freetds software (both main package and devel)
yum install freetds freetds-devel
Configure a server definition in the global config file, I'm not sure there's a way to avoid having to do this.
cat >> /etc/freetds.conf <<EOF [myserver] host = 192.168.1.4 port = 1433 tds version = 7.0 EOF
Test the connection using the following:
tsql -S myserver -U myuser
You should be prompted for a password (SQL auth, not Windows!) and hopefully after providing one, you should see a prompt 1)
waiting for an SQL query.
Run the following query to see the available databases.
SELECT name, database_id, create_date FROM sys.databases; GO
If this didn't work, go back and check your setup.
Install the perl module for DBD::Sybase - don't bother with the ODBC method, this way works just fine.
SYBASE=/usr cpanm DBD::Sybase
Connect using Perl and DBD::Sybase
#!/usr/bin/env perl use DBI; my $dbh = DBI->connect("DBI:Sybase:server=myserver","myuser","mypass") or die $DBI::errstr; $dbh->disconnect();
If this works, you're all set.
DBIx::Class
Relationships
belongs_to means: a field (or fields) in THIS table is a foreign key (contains the primary key of) THAT other table.
has_many means: there are multiple (zero or more) rows in THAT table which contains THIS tables primary key.
has_one means: there is a row in THAT table which contains THIS tables primary key.
might_have means: the same as has_one, except its not guaranteed to be there.
Cascading
Attributes are required for the different relationships to disable cascading of delete/update.
has_one
and might_have
{ cascade_delete => 0, cascade_update => 0 }
belongs_to
{ on_delete => undef, on_update => undef }
has_many
{ cascade_delete => 0 }
Dates
Adding a database independent way of fetching the current date/time in UTC.
package TestApp::Schema::ResultSet::Test; use strict; use warnings; use parent 'DBIx::Class::ResultSet'; __PACKAGE__->load_components('Helper::ResultSet::DateMethods1'); 1;
and then using it, get the resultset and the first test (id = 1)
my $tests = $schema->resultset('Test'); my $test = $tests->find(1);
and to set the date
$test->test_date( $test->result_source->resultset->utc_now );
or
$test->test_date( $tests->utc_now );
Tips
Mixing STDOUT and STDERR output in the right order
STDOUT and STDERR are block buffered when there is no terminal, or line buffered when there is a terminal. This has the unfortunate side effect of making output from print/warn mess up when running a script from cron when the same script works perfectly run from the command line.
Redirect STDERR to the same stream as STDOUT (equiv to 2>&1 in bash) - this isn't essential, but makes it easier to pipe the output through tail/mail/etc, or redirect the output to a logfile.
close(STDERR); open(STDERR, ">&STDOUT");
Make both streams non-buffering
select(STDERR); $| = 1; select(STDOUT); $| = 1;
Alternatively, instead of the select() above, you can use IO::Handle
use IO::Handle; STDERR->autoflush(1); STDOUT->autoflush(1);
Generating almost identical methods
You could use Moose to do something like this but what if you want to do something other than simple getter/setter methods? This works as far as I've tested it. I'm open to alternative suggestions though!
BEGIN { foreach my $k (qw/name company address1 address2 area city postcode country phone email fax/) { no strict 'refs'; *{"MyModule::$k"} = sub { my $self = shift; my $value = shift; if (defined $value) { $self->{ $k } = $value; } return $self->{ $k }; }; } }