2 # Copyright (C) 2008 Michal Vaner (vorner@ucw.cz)
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # he Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 use base 'PciIds::DBQAny';
24 my $adminDumpSql = 'SELECT
25 locations.id, locations.name, locations.note, locations.mainhistory, musers.email, musers.login, main.discussion, main.time,
26 history.id, history.discussion, history.nodename, history.nodenote, users.email, users.login, history.time
28 locations INNER JOIN history ON history.location = locations.id
29 LEFT OUTER JOIN users ON history.owner = users.id
30 LEFT OUTER JOIN history AS main ON locations.mainhistory = main.id
31 LEFT OUTER JOIN users AS musers ON main.owner = musers.id
32 WHERE history.seen = "0" AND locations.id LIKE ?
33 ORDER BY locations.id, history.id
38 my $node = 'SELECT id, name, note, mainhistory FROM locations WHERE parent = ? ORDER BY ';
39 my $noder = 'SELECT id, name, note, mainhistory FROM locations WHERE parent = ? AND id LIKE ? ORDER BY ';
40 return bless PciIds::DBQAny::new( $dbh, {
41 'nodes-id' => $node.'id',
42 'nodes-name' => $node.'name',
43 'nodes-rid' => $node.'id DESC',
44 'nodes-rname' => $node.'name DESC',
45 'nodes-id-r' => $noder.'id',
46 'nodes-name-r' => $noder.'name',
47 'nodes-rid-r' => $noder.'id DESC',
48 'nodes-rname-r' => $noder.'name DESC',
49 'item' => 'SELECT parent, name, note, mainhistory FROM locations WHERE id = ?',
50 'login' => 'SELECT id FROM users WHERE login = ?',
51 'email' => 'SELECT id FROM users WHERE email = ?',
52 'adduser' => 'INSERT INTO users (login, email, passwd) VALUES(?, ?, ?)',
53 'adduser-null' => 'INSERT users (email, passwd) VALUES(?, ?)',
54 'loginfomail' => 'SELECT id, passwd, logtime, lastlog FROM users WHERE email = ?',
55 'loginfoname' => 'SELECT id, passwd, logtime, lastlog, email FROM users WHERE login = ?',
56 'resetinfo' => 'SELECT id, login, passwd FROM users WHERE email = ?',
57 'changepasswd' => 'UPDATE users SET passwd = ? WHERE id = ?',
58 'setlastlog' => 'UPDATE users SET logtime = now(), lastlog = ? WHERE id = ?',
59 'rights' => 'SELECT rightId FROM rights WHERE userId = ?',
60 'newitem' => 'INSERT INTO locations (id, parent) VALUES(?, ?)',
61 'newhistory' => 'INSERT INTO history (location, owner, discussion, nodename, nodenote) VALUES(?, ?, ?, ?, ?)',
62 'history' => 'SELECT history.id, history.discussion, history.time, history.nodename, history.nodenote, history.seen, users.login, users.email FROM history LEFT OUTER JOIN users ON history.owner = users.id WHERE history.location = ? ORDER BY history.time',
63 'admindump' => "$adminDumpSql 100",#Dumps new discussion submits with their senders and corresponding main history and names
64 'delete-hist' => 'DELETE FROM history WHERE id = ?',
65 'mark-checked' => 'UPDATE history SET seen = 1 WHERE id = ?',
66 'delete-item' => 'DELETE FROM locations WHERE id = ?',
67 'set-mainhist' => 'UPDATE locations SET
69 name = ( SELECT nodename FROM history WHERE id = ? ),
70 note = ( SELECT nodenote FROM history WHERE id = ? )
73 'profiledata' => 'SELECT email, xmpp, login, mailgather, xmppgather FROM users WHERE id = ?',
74 'pushprofile' => 'UPDATE users SET xmpp = ?, login = ?, mailgather = ?, xmppgather = ? WHERE id = ?',
75 'setemail' => 'UPDATE users SET email = ?, passwd = ? WHERE id = ?',
76 'notifuser' => 'SELECT location, recursive FROM notifications WHERE user = ? ORDER BY location',
77 'notifdata' => 'SELECT recursive, type, notification FROM notifications WHERE user = ? AND location = ?',
78 'drop-notif' => 'DELETE FROM notifications WHERE user = ? AND location = ?',
79 'new-notif' => 'INSERT INTO notifications (user, location, recursive, type, notification) VALUES (?, ?, ?, ?, ?)',
80 'notify' => 'INSERT INTO pending (user, history, notification, reason) SELECT DISTINCT user, ?, ?, ? FROM notifications WHERE ( notification = 2 OR notification = ? ) AND type <= ? AND ( location = ? OR ( recursive = 1 AND SUBSTR( ?, 1, LENGTH( location ) ) = location ) )',
81 'newtime-mail' => 'UPDATE users SET nextmail = FROM_UNIXTIME( UNIX_TIMESTAMP( NOW() ) + 60 * mailgather ) WHERE nextmail < NOW() AND EXISTS ( SELECT 1 FROM notifications WHERE ( notification = 0 OR notification = 2 ) AND type <= ? AND ( location = ? OR ( recursive = 1 AND SUBSTR( ?, 1, LENGTH( location ) ) = location ) ) )',
82 'newtime-xmpp' => 'UPDATE users SET nextxmpp = FROM_UNIXTIME( UNIX_TIMESTAMP( NOW() ) + 60 * xmppgather ) WHERE nextxmpp < NOW() AND EXISTS ( SELECT 1 FROM notifications WHERE ( notification = 1 OR notification = 2 ) AND type <= ? AND ( location = ? OR ( recursive = 1 AND SUBSTR( ?, 1, LENGTH( location ) ) = location ) ) )',
84 pending.user, users.email,
85 pending.reason, history.discussion, history.nodename, history.nodenote, history.time,
86 auth.login, history.location, locations.name, locations.note
89 INNER JOIN users ON users.id = pending.user
90 INNER JOIN history ON history.id = pending.history
91 INNER JOIN locations ON history.location = locations.id
92 INNER JOIN users AS auth ON auth.id = history.owner
94 pending.notification = 0
95 AND users.nextmail <= ?
97 pending.user, pending.reason, history.time, history.location',
99 pending.user, users.xmpp,
100 pending.reason, history.discussion, history.nodename, history.nodenote, history.time,
101 auth.login, history.location, locations.name, locations.note
104 INNER JOIN users ON users.id = pending.user
105 INNER JOIN history ON history.id = pending.history
106 INNER JOIN locations ON history.location = locations.id
107 INNER JOIN users AS auth ON auth.id = history.owner
109 pending.notification = 1
110 AND users.nextxmpp <= ?
112 pending.user, pending.reason, history.time, history.location',
113 'dropnotifsxmpp' => 'DELETE FROM pending WHERE notification = 1 AND EXISTS ( SELECT 1 FROM users WHERE users.id = pending.user AND nextxmpp <= ? )',
114 'dropnotifsmail' => 'DELETE FROM pending WHERE notification = 0 AND EXISTS ( SELECT 1 FROM users WHERE users.id = pending.user AND nextmail <= ? )',
115 'time' => 'SELECT NOW()',
116 'searchname' => 'SELECT l.id, l.name, p.name FROM locations AS l JOIN locations AS p ON l.parent = p.id WHERE l.name LIKE ? ORDER BY l.id',
117 'searchlocalname' => 'SELECT l.id, l.name, p.name FROM locations AS l JOIN locations AS p ON l.parent = p.id WHERE l.name LIKE ? AND l.id LIKE ? ORDER BY l.id',
118 'hasChildren' => 'SELECT DISTINCT 1 FROM locations WHERE parent = ?',
119 'hasMain' => 'SELECT DISTINCT 1 FROM locations WHERE id = ? AND mainhistory IS NOT NULL',
120 'notif-exists' => 'SELECT DISTINCT 1 FROM notifications WHERE user = ? AND ( location = ? OR ( recursive = 1 AND type <= 1 AND SUBSTR( ?, 1, LENGTH( location ) ) = location ) )'
124 sub hasChildren( $$ ) {
125 my( $self, $parent ) = @_;
126 return scalar @{$self->query( 'hasChildren', [ $parent ] )};
130 my( $self, $id ) = @_;
131 return scalar @{$self->query( 'hasMain', [ $id ] )};
134 my %sorts = ( 'id' => 1, 'rid' => 1, 'name' => 1, 'rname' => 1 );
137 my( $self, $parent, $args, $restrict ) = @_;
139 $q = $args->{'sort'} if( defined( $args->{'sort'} ) && defined( $sorts{$args->{'sort'}} ) );
140 if( defined( $restrict ) && ( $restrict ne "" ) ) {
141 return $self->query( 'nodes-'.$q.'-r', [ $parent, $parent.'/'.$restrict.'%' ] );
143 return $self->query( 'nodes-'.$q, [ $parent ] );
148 my( $self, $id ) = @_;
149 my $result = $self->query( "item", [ $id ] );
150 if( scalar @{$result} ) {
151 return $result->[ 0 ];
158 my( $self, $login ) = @_;
159 my $result = $self->query( 'login', [ $login ] );
160 return scalar @{$result};
164 my( $self, $email ) = @_;
165 my $result = $self->query( 'email', [ $email ] );
166 return scalar @{$result};
169 sub addUser( $$$$ ) {
170 my( $self, $login, $email, $passwd ) = @_;
172 if( ( defined $login ) && ( $login ne '' ) ) {
173 $self->command( 'adduser', [ $login, $email, $passwd ] );
175 $self->command( 'adduser-null', [ $email, $passwd ] );
181 return $self->last();
185 sub getLogInfo( $$ ) {
186 my( $self, $info ) = @_;
188 if( $info =~ /@/ ) {#An email address
189 $data = $self->query( 'loginfomail', [ $info ] );
191 $data = $self->query( 'loginfoname', [ $info ] );
193 if( scalar @{$data} ) {
194 my( $id, $passwd, $logtime, $lastlog, $email ) = @{$data->[ 0 ]};
196 $logstring = "Last logged from $lastlog at $logtime" if( defined $logtime && defined $lastlog );
197 $email = $info if( $info =~ /@/ );
198 return( $id, $passwd, $email, $logstring );
205 my( $self, $id ) = @_;
206 return $self->query( 'rights', [ $id ] );
209 sub setLastLog( $$$ ) {
210 my( $self, $id, $from ) = @_;
211 $self->command( 'setlastlog', [ $from, $id ] );
215 my( $self, $addr ) = @_;
216 return $self->query( 'history', [ $addr ] );
219 sub submitItem( $$$ ) {
220 my( $self, $data, $auth ) = @_;
221 my( $addr ) = ( $data->{'address'} );
222 foreach( @{$addr->addressDeps()} ) {
223 my( $dep, $error ) = @{$_};
224 return ( $error, undef ) unless defined $self->item( $dep->get(), 0 );
226 return( 'exists', undef ) if( defined( $self->item( $addr->get(), 0 ) ) );
228 $self->command( 'newitem', [ $addr->get(), $addr->parent()->get() ] );
229 $self->command( 'newhistory', [ $addr->get(), $auth->{'authid'}, $data->{'discussion'}, $data->{'name'}, $data->{'note'} ] );
233 return( 'internal: '.$@, undef );
235 return( '', $self->last() );
238 sub submitHistory( $$$$ ) {
239 my( $self, $data, $auth, $address ) = @_;
240 if( $data->{'delete'} ) {
241 $self->command( 'newhistory', [ $address->get(), $auth->{'authid'}, $data->{'text'}, '', $data->{'note'} ], 1 );
243 $data->{'name'} = undef if defined $data->{'name'} && $data->{'name'} eq '';
244 $self->command( 'newhistory', [ $address->get(), $auth->{'authid'}, $data->{'text'}, $data->{'name'}, $data->{'note'} ], 1 );
246 return $self->last();
249 sub adminDump( $$$ ) {
250 my( $self, $prefix, $limit ) = @_;
252 $limit = int( $limit * 1.2 );
253 my $q = $self->{'dbh'}->prepare( "$adminDumpSql $limit" );
254 $q->execute( "$prefix%" );
255 my @result = @{$q->fetchall_arrayref()};#Copy the array, finish() deletes the content
259 return $self->query( 'admindump', [ "$prefix%" ] );
263 sub deleteHistory( $$ ) {
264 my( $self, $id ) = @_;
265 $self->command( 'delete-hist', [ $id ] );
268 sub markChecked( $$ ) {
269 my( $self, $id ) = @_;
270 $self->command( 'mark-checked', [ $id ] );
273 sub deleteItem( $$ ) {
274 my( $self, $id ) = @_;
275 $self->command( 'delete-item', [ $id ] );
278 sub setMainHistory( $$$ ) {
279 my( $self, $location, $history ) = @_;
280 $self->command( 'set-mainhist', [ $history, $history, $history, $location ] );
283 sub resetInfo( $$ ) {
284 my( $self, $mail ) = @_;
285 my $result = $self->query( 'resetinfo', [ $mail ] );
286 if( scalar @{$result} ) {
287 return ( @{$result->[0]} );
293 sub changePasswd( $$$ ) {
294 my( $self, $id, $passwd ) = @_;
295 $self->command( 'changepasswd', [ $passwd, $id ] );
298 sub profileData( $$ ) {
299 my( $self, $id ) = @_;
301 ( $result{'email'}, $result{'xmpp'}, $result{'login'}, $result{'email_time'}, $result{'xmpp_time'} ) = @{$self->query( 'profiledata', [ $id ] )->[0]};
305 sub setEmail( $$$$ ) {
306 my( $self, $id, $email, $passwd ) = @_;
307 $self->command( 'setemail', [ $email, $passwd, $id ] );
310 sub pushProfile( $$$$$$ ) {
311 my( $self, $id, $login, $xmpp, $mailgather, $xmppgather ) = @_;
312 $self->command( 'pushprofile', [ $xmpp, $login, $mailgather, $xmppgather, $id ] );
315 sub notificationsUser( $$ ) {
316 my( $self, $uid ) = @_;
317 return $self->query( 'notifuser', [ $uid ] );
320 sub getNotifData( $$$ ) {
321 my( $self, $uid, $location ) = @_;
322 my $result = $self->query( 'notifdata', [ $uid, $location ] );
324 my( $recursive, $notification, $way ) = @{$result->[0]};
326 'recursive' => $recursive,
327 'notification' => $notification,
330 return { 'recursive' => 1 };
334 sub submitNotification( $$$$ ) {
335 my( $self, $uid, $location, $data ) = @_;
336 $self->command( 'drop-notif', [ $uid, $location ] );
337 $self->command( 'new-notif', [ $uid, $location, $data->{'recursive'}, $data->{'notification'}, $data->{'way'} ] ) unless( $data->{'notification'} == 3 );
340 sub pushNotifications( $$$$$ ) {
341 my( $self, $location, $history, $priority, $reason ) = @_;
342 $self->command( 'notify', [ $history, 0, $reason, 0, $priority, $location, $location ] );
343 $self->command( 'notify', [ $history, 1, $reason, 1, $priority, $location, $location ] );
344 $self->command( 'newtime-mail', [ $priority, $location, $location ] );
345 $self->command( 'newtime-xmpp', [ $priority, $location, $location ] );
348 sub notifExists( $$$ ) {
349 my( $self, $user, $location ) = @_;
350 return scalar @{$self->query( 'notif-exists', [ $user, $location, $location ] )};
353 sub mailNotifs( $$ ) {
354 my( $self, $time ) = @_;
355 return $self->query( 'mailout', [ $time ] );
358 sub xmppNotifs( $$ ) {
359 my( $self, $time ) = @_;
360 return $self->query( 'xmppout', [ $time ] );
365 return $self->query( 'time', [] )->[0]->[0];
368 sub dropNotifs( $$ ) {
369 my( $self, $time ) = @_;
370 $self->command( 'dropnotifsmail', [ $time ] );
371 $self->command( 'dropnotifsxmpp', [ $time ] );
374 sub searchName( $$$ ) {
375 my( $self, $search, $prefix ) = @_;
376 return $self->query( 'searchlocalname', [ "%$search%", "$prefix/%" ] ) if defined $prefix;
377 return $self->query( 'searchname', [ "%$search%" ] );