2009-02-11 17:18:38 +01:00
|
|
|
## @file
|
|
|
|
# DBI storage methods for notifications
|
|
|
|
|
|
|
|
## @class
|
|
|
|
# DBI storage methods for notifications
|
2016-06-02 23:20:36 +02:00
|
|
|
package Lemonldap::NG::Common::Notifications::DBI;
|
2009-02-11 17:18:38 +01:00
|
|
|
|
|
|
|
use strict;
|
2016-06-02 23:20:36 +02:00
|
|
|
use Mouse;
|
2009-03-04 09:37:08 +01:00
|
|
|
use Time::Local;
|
|
|
|
use DBI;
|
2016-06-02 23:20:36 +02:00
|
|
|
use Encode;
|
2009-02-11 17:18:38 +01:00
|
|
|
|
2019-12-23 16:56:35 +01:00
|
|
|
our $VERSION = '2.0.8';
|
2009-06-08 18:29:13 +02:00
|
|
|
|
2016-06-02 23:20:36 +02:00
|
|
|
extends 'Lemonldap::NG::Common::Notifications';
|
2017-02-15 07:41:50 +01:00
|
|
|
|
2017-01-31 20:11:59 +01:00
|
|
|
sub import {
|
|
|
|
shift;
|
2017-02-15 07:41:50 +01:00
|
|
|
return Lemonldap::NG::Common::Notifications->import(@_);
|
2017-01-31 20:11:59 +01:00
|
|
|
}
|
2016-06-02 23:20:36 +02:00
|
|
|
|
|
|
|
has dbiTable => (
|
|
|
|
is => 'ro',
|
2018-11-16 17:30:57 +01:00
|
|
|
lazy => 1,
|
2016-06-02 23:20:36 +02:00
|
|
|
default => sub { $_[0]->{table} || 'notifications' }
|
|
|
|
);
|
|
|
|
|
|
|
|
has dbiChain => (
|
|
|
|
is => 'ro',
|
|
|
|
required => 1
|
|
|
|
);
|
|
|
|
|
|
|
|
has dbiUser => (
|
|
|
|
is => 'ro',
|
2018-11-16 17:30:57 +01:00
|
|
|
lazy => 1,
|
2016-06-02 23:20:36 +02:00
|
|
|
default => sub {
|
2017-02-15 07:41:50 +01:00
|
|
|
$_[0]->{p}->logger->warn('Warning: "dbiUser" parameter is not set');
|
2016-06-02 23:20:36 +02:00
|
|
|
return '';
|
2009-02-11 17:18:38 +01:00
|
|
|
}
|
2016-06-02 23:20:36 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
has dbiPassword => ( is => 'ro', default => '' );
|
|
|
|
|
|
|
|
# Database handle object
|
|
|
|
has _dbh => (
|
|
|
|
is => 'rw',
|
|
|
|
lazy => 1,
|
|
|
|
builder => sub {
|
|
|
|
my $self = shift;
|
|
|
|
my $r = DBI->connect_cached(
|
|
|
|
$self->{dbiChain}, $self->{dbiUser},
|
2017-10-19 16:59:19 +02:00
|
|
|
$self->{dbiPassword}, { RaiseError => 1 }
|
2016-06-02 23:20:36 +02:00
|
|
|
);
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error($DBI::errstr) unless ($r);
|
2016-06-02 23:20:36 +02:00
|
|
|
return $r;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
# Current query
|
|
|
|
has sth => ( is => 'rw' );
|
2009-02-11 17:18:38 +01:00
|
|
|
|
2009-03-04 09:37:08 +01:00
|
|
|
# Returns notifications corresponding to the user $uid.
|
2009-02-11 17:18:38 +01:00
|
|
|
# If $ref is set, returns only notification corresponding to this reference.
|
|
|
|
sub get {
|
|
|
|
my ( $self, $uid, $ref ) = @_;
|
|
|
|
return () unless ($uid);
|
2016-06-02 23:20:36 +02:00
|
|
|
$self->_execute(
|
2018-11-16 17:30:57 +01:00
|
|
|
"SELECT * FROM "
|
|
|
|
. $self->dbiTable
|
|
|
|
. " WHERE done IS NULL AND uid=?"
|
2013-07-12 09:54:35 +02:00
|
|
|
. ( $ref ? " AND ref=?" : '' )
|
2019-02-06 14:29:33 +01:00
|
|
|
. " ORDER BY date",
|
2013-07-12 09:54:35 +02:00
|
|
|
$uid,
|
|
|
|
( $ref ? $ref : () )
|
|
|
|
) or return ();
|
2009-02-11 17:18:38 +01:00
|
|
|
my $result;
|
2016-06-02 23:20:36 +02:00
|
|
|
while ( my $h = $self->sth->fetchrow_hashref() ) {
|
2020-02-09 17:47:25 +01:00
|
|
|
|
|
|
|
# Get XML message
|
|
|
|
my $xml = $h->{xml};
|
|
|
|
|
|
|
|
# Decode it to get the correct uncoded string
|
|
|
|
Encode::from_to( $xml, "utf8", "iso-8859-1", Encode::FB_CROAK );
|
|
|
|
|
|
|
|
# Store message in result
|
|
|
|
my $identifier =
|
|
|
|
&getIdentifier( $self, $h->{uid}, $h->{ref}, $h->{date} );
|
|
|
|
$result->{$identifier} = $xml;
|
|
|
|
}
|
|
|
|
$self->logger->warn( $self->sth->err() ) if ( $self->sth->err() );
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
# Returns accepted notifications corresponding to the user $uid.
|
|
|
|
# If $ref is set, returns only notification corresponding to this reference.
|
|
|
|
sub getAccepted {
|
|
|
|
my ( $self, $uid, $ref ) = @_;
|
|
|
|
return () unless ($uid);
|
|
|
|
$self->_execute(
|
|
|
|
"SELECT * FROM "
|
|
|
|
. $self->dbiTable
|
2020-04-06 23:55:04 +02:00
|
|
|
. " WHERE uid=? AND ref=? ORDER BY date",
|
2020-02-09 17:47:25 +01:00
|
|
|
$uid,
|
|
|
|
( $ref ? $ref : () )
|
|
|
|
) or return ();
|
|
|
|
my $result;
|
|
|
|
while ( my $h = $self->sth->fetchrow_hashref() ) {
|
2011-06-11 15:45:22 +02:00
|
|
|
|
|
|
|
# Get XML message
|
|
|
|
my $xml = $h->{xml};
|
|
|
|
|
2012-03-27 22:16:31 +02:00
|
|
|
# Decode it to get the correct uncoded string
|
2016-02-25 17:44:23 +01:00
|
|
|
Encode::from_to( $xml, "utf8", "iso-8859-1", Encode::FB_CROAK );
|
2012-03-27 22:16:31 +02:00
|
|
|
|
2011-06-11 15:45:22 +02:00
|
|
|
# Store message in result
|
2016-02-24 18:26:52 +01:00
|
|
|
my $identifier =
|
|
|
|
&getIdentifier( $self, $h->{uid}, $h->{ref}, $h->{date} );
|
|
|
|
$result->{$identifier} = $xml;
|
2009-02-11 17:18:38 +01:00
|
|
|
}
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn( $self->sth->err() ) if ( $self->sth->err() );
|
2009-02-11 17:18:38 +01:00
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2009-03-04 09:37:08 +01:00
|
|
|
## @method hashref getAll()
|
2019-12-20 21:34:52 +01:00
|
|
|
# Return all pending notifications.
|
2009-03-04 09:37:08 +01:00
|
|
|
# @return hashref where keys are internal reference and values are hashref with
|
2019-12-20 21:34:52 +01:00
|
|
|
# keys date, uid, ref and condition.
|
2009-03-04 09:37:08 +01:00
|
|
|
sub getAll {
|
|
|
|
my $self = shift;
|
2019-02-06 14:29:33 +01:00
|
|
|
$self->_execute( 'SELECT * FROM '
|
|
|
|
. $self->dbiTable
|
|
|
|
. ' WHERE done IS NULL ORDER BY date' );
|
2009-03-04 09:37:08 +01:00
|
|
|
my $result;
|
2019-12-20 21:34:52 +01:00
|
|
|
while ( my $h = $self->sth->fetchrow_hashref() ) {
|
|
|
|
$result->{"$h->{date}#$h->{uid}#$h->{ref}"} = {
|
|
|
|
date => $h->{date},
|
|
|
|
uid => $h->{uid},
|
|
|
|
ref => $h->{ref},
|
|
|
|
condition => $h->{condition}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
$self->logger->warn( $self->sth->err() ) if ( $self->sth->err() );
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
## @method hashref getExisting()
|
|
|
|
# Return all notifications.
|
|
|
|
# @return hashref where keys are internal reference and values are hashref with
|
|
|
|
# keys date, uid, ref and condition.
|
|
|
|
sub getExisting {
|
|
|
|
my $self = shift;
|
2019-12-23 21:18:44 +01:00
|
|
|
$self->_execute( 'SELECT * FROM ' . $self->dbiTable . ' ORDER BY date' );
|
2019-12-20 21:34:52 +01:00
|
|
|
my $result;
|
2016-06-02 23:20:36 +02:00
|
|
|
while ( my $h = $self->sth->fetchrow_hashref() ) {
|
2011-06-29 17:06:04 +02:00
|
|
|
$result->{"$h->{date}#$h->{uid}#$h->{ref}"} = {
|
|
|
|
date => $h->{date},
|
|
|
|
uid => $h->{uid},
|
|
|
|
ref => $h->{ref},
|
|
|
|
condition => $h->{condition}
|
|
|
|
};
|
2009-03-04 09:37:08 +01:00
|
|
|
}
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn( $self->sth->err() ) if ( $self->sth->err() );
|
2009-03-04 09:37:08 +01:00
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2009-02-11 17:18:38 +01:00
|
|
|
## @method boolean delete(string myref)
|
|
|
|
# Mark a notification as done.
|
2009-03-04 09:37:08 +01:00
|
|
|
# @param $myref identifier returned by get() or getAll()
|
2009-02-11 17:18:38 +01:00
|
|
|
sub delete {
|
|
|
|
my ( $self, $myref ) = @_;
|
|
|
|
my ( $d, $u, $r );
|
2009-02-13 10:26:02 +01:00
|
|
|
unless ( ( $d, $u, $r ) = ( $myref =~ /^([^#]+)#(.+?)#(.+)$/ ) ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn("Bad reference $myref");
|
2009-02-11 17:18:38 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
my @ts = localtime();
|
|
|
|
$ts[5] += 1900;
|
|
|
|
$ts[4]++;
|
2019-02-06 14:29:33 +01:00
|
|
|
return $self->_execute( 'UPDATE '
|
|
|
|
. $self->dbiTable
|
|
|
|
. " SET done='$ts[5]-$ts[4]-$ts[3] $ts[2]:$ts[1]' "
|
|
|
|
. 'WHERE done IS NULL AND uid=? AND ref=? AND date=?',
|
2016-06-02 23:20:36 +02:00
|
|
|
$u, $r, $d );
|
2009-03-04 09:37:08 +01:00
|
|
|
}
|
|
|
|
|
2012-09-25 17:09:31 +02:00
|
|
|
## @method boolean purge(string myref, boolean force)
|
2009-03-04 09:37:08 +01:00
|
|
|
# Purge notification (really delete record)
|
|
|
|
# @param $myref identifier returned by get or getAll
|
2012-09-25 17:09:31 +02:00
|
|
|
# @param $force force purge for not deleted session
|
2009-03-04 09:37:08 +01:00
|
|
|
# @return true if something was deleted
|
|
|
|
sub purge {
|
2012-09-25 17:09:31 +02:00
|
|
|
my ( $self, $myref, $force ) = @_;
|
2009-03-04 09:37:08 +01:00
|
|
|
my ( $d, $u, $r );
|
|
|
|
unless ( ( $d, $u, $r ) = ( $myref =~ /^([^#]+)#(.+?)#(.+)$/ ) ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn("Bad reference $myref");
|
2009-03-04 09:37:08 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2019-06-12 09:55:06 +02:00
|
|
|
unless ( $d =~ s/^(\d{4})(\d{2})(\d{2}).*$/$1-$2-$3/
|
|
|
|
or $d =~ s/^(\d{4}-\d{2}-\d{2}).*$/$1/ )
|
|
|
|
{
|
2019-02-06 14:29:33 +01:00
|
|
|
$self->logger->warn("Bad date $d");
|
|
|
|
return 0;
|
|
|
|
}
|
2012-09-25 17:09:31 +02:00
|
|
|
|
|
|
|
my $clause;
|
|
|
|
$clause = "done IS NOT NULL AND" unless ($force);
|
|
|
|
|
2019-02-06 14:29:33 +01:00
|
|
|
return $self->_execute( 'DELETE FROM '
|
|
|
|
. $self->dbiTable
|
|
|
|
. " WHERE $clause uid=? AND ref=? AND date=?",
|
2016-06-02 23:20:36 +02:00
|
|
|
$u, $r, $d );
|
2009-02-11 17:18:38 +01:00
|
|
|
}
|
|
|
|
|
2011-06-29 17:06:04 +02:00
|
|
|
## @method boolean newNotif(string date, string uid, string ref, string condition, string xml)
|
2009-02-11 17:18:38 +01:00
|
|
|
# Insert a new notification
|
|
|
|
# @param date Date
|
|
|
|
# @param uid UID
|
|
|
|
# @param ref Reference of the notification
|
2011-06-29 17:06:04 +02:00
|
|
|
# @param condition Condition for the notification
|
2009-02-11 17:18:38 +01:00
|
|
|
# @param xml XML notification
|
|
|
|
# @return true if succeed
|
|
|
|
sub newNotif {
|
2011-06-29 17:06:04 +02:00
|
|
|
my ( $self, $date, $uid, $ref, $condition, $xml ) = @_;
|
2019-12-23 21:18:44 +01:00
|
|
|
my @t = split( /\D+/, $date );
|
|
|
|
$t[1]--;
|
|
|
|
eval {
|
|
|
|
timelocal( $t[5] || 0, $t[4] || 0, $t[3] || 0, $t[2], $t[1], $t[0] );
|
|
|
|
};
|
|
|
|
return ( 0, "Bad date" ) if ($@);
|
2011-06-29 17:06:04 +02:00
|
|
|
my $res =
|
|
|
|
$condition =~ /.+/
|
2019-02-06 14:29:33 +01:00
|
|
|
? $self->_execute( 'INSERT INTO '
|
|
|
|
. $self->dbiTable
|
|
|
|
. ' (date,uid,ref,cond,xml) VALUES(?,?,?,?,?)',
|
2016-06-02 23:20:36 +02:00
|
|
|
$date, $uid, $ref, $condition, $xml )
|
2019-02-06 14:29:33 +01:00
|
|
|
: $self->_execute( 'INSERT INTO '
|
|
|
|
. $self->dbiTable
|
|
|
|
. ' (date,uid,ref,xml) VALUES(?,?,?,?)',
|
2016-06-02 23:20:36 +02:00
|
|
|
$date, $uid, $ref, $xml );
|
2011-06-29 17:06:04 +02:00
|
|
|
return $res;
|
2009-03-04 09:37:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
## @method hashref getDone()
|
|
|
|
# Returns a list of notification that have been done
|
|
|
|
# @return hashref where keys are internal reference and values are hashref with
|
|
|
|
# keys notified, uid and ref.
|
|
|
|
sub getDone {
|
|
|
|
my ($self) = @_;
|
2019-02-06 14:29:33 +01:00
|
|
|
$self->_execute( 'SELECT * FROM '
|
|
|
|
. $self->dbiTable
|
|
|
|
. ' WHERE done IS NOT NULL ORDER BY done' );
|
2009-03-04 09:37:08 +01:00
|
|
|
my $result;
|
2016-06-02 23:20:36 +02:00
|
|
|
while ( my $h = $self->sth->fetchrow_hashref() ) {
|
2009-03-04 09:37:08 +01:00
|
|
|
my @t = split( /\D+/, $h->{date} );
|
2019-12-23 16:56:35 +01:00
|
|
|
$t[1]--;
|
2019-12-23 21:18:44 +01:00
|
|
|
my $done = eval {
|
|
|
|
timelocal( $t[5] || 0, $t[4] || 0, $t[3] || 0, $t[2], $t[1],
|
|
|
|
$t[0] );
|
|
|
|
};
|
|
|
|
if ($@) {
|
|
|
|
$self->logger->warn("Bad date: $h->{date}");
|
|
|
|
return {};
|
|
|
|
}
|
2009-03-04 09:37:08 +01:00
|
|
|
$result->{"$h->{date}#$h->{uid}#$h->{ref}"} =
|
|
|
|
{ notified => $done, uid => $h->{uid}, ref => $h->{ref}, };
|
|
|
|
}
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn( $self->sth->err() ) if ( $self->sth->err() );
|
2009-03-04 09:37:08 +01:00
|
|
|
return $result;
|
2009-02-11 17:18:38 +01:00
|
|
|
}
|
|
|
|
|
2013-07-12 09:54:35 +02:00
|
|
|
## @method private object _execute(string query, array args)
|
2009-02-11 17:18:38 +01:00
|
|
|
# Execute a query and catch errors
|
|
|
|
# @return number of lines touched or 1 if select succeed
|
|
|
|
sub _execute {
|
2013-07-12 09:54:35 +02:00
|
|
|
my ( $self, $query, @args ) = @_;
|
2017-10-19 16:59:19 +02:00
|
|
|
my $dbh = $self->_dbh or die "DB connection unavailable";
|
2016-06-02 23:20:36 +02:00
|
|
|
unless ( $self->sth( $dbh->prepare($query) ) ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn( $dbh->errstr() );
|
2009-02-11 17:18:38 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
my $tmp;
|
2016-06-02 23:20:36 +02:00
|
|
|
unless ( $tmp = $self->sth->execute(@args) ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->warn( $self->sth->errstr() );
|
2009-02-11 17:18:38 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return $tmp;
|
|
|
|
}
|
|
|
|
|
2016-02-24 18:26:52 +01:00
|
|
|
## @method string getIdentifier(string uid, string ref, string date)
|
|
|
|
# Get notification identifier
|
|
|
|
# @param $uid uid
|
|
|
|
# @param $ref ref
|
|
|
|
# @param $date date
|
|
|
|
# @return the notification identifier
|
|
|
|
sub getIdentifier {
|
|
|
|
my ( $self, $uid, $ref, $date ) = @_;
|
|
|
|
return $date . "#" . $uid . "#" . $ref;
|
|
|
|
}
|
|
|
|
|
2009-02-11 17:18:38 +01:00
|
|
|
1;
|
|
|
|
|