]> Sergey Matveev's repositories - public-inbox.git/blob - lib/PublicInbox/IMAPTracker.pm
bb4a39cc41a64968b526a09d3f4fe4b972ba8ec0
[public-inbox.git] / lib / PublicInbox / IMAPTracker.pm
1 # Copyright (C) 2018-2020 all contributors <meta@public-inbox.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3 package PublicInbox::IMAPTracker;
4 use strict;
5 use DBI;
6 use DBD::SQLite;
7 use PublicInbox::Config;
8
9 sub create_tables ($) {
10         my ($dbh) = @_;
11
12         $dbh->do(<<'');
13 CREATE TABLE IF NOT EXISTS imap_last (
14         url VARCHAR PRIMARY KEY NOT NULL,
15         uid_validity INTEGER NOT NULL,
16         uid INTEGER NOT NULL,
17         UNIQUE (url)
18 )
19
20 }
21
22 sub dbh_new ($) {
23         my ($dbname) = @_;
24         my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", '', '', {
25                 AutoCommit => 1,
26                 RaiseError => 1,
27                 PrintError => 0,
28                 sqlite_use_immediate_transaction => 1,
29         });
30         $dbh->{sqlite_unicode} = 1;
31         $dbh->do('PRAGMA journal_mode = TRUNCATE');
32         create_tables($dbh);
33         $dbh;
34 }
35
36 sub get_last ($$) {
37         my ($self, $url) = @_;
38         my $sth = $self->{dbh}->prepare_cached(<<'', undef, 1);
39 SELECT uid_validity, uid FROM imap_last WHERE url = ?
40
41         $sth->execute($url);
42         $sth->fetchrow_array;
43 }
44
45 sub update_last ($$$$) {
46         my ($self, $url, $validity, $last) = @_;
47         my $sth = $self->{dbh}->prepare_cached(<<'');
48 INSERT OR REPLACE INTO imap_last (url, uid_validity, uid)
49 VALUES (?, ?, ?)
50
51         $sth->execute($url, $validity, $last);
52 }
53
54 sub new {
55         my ($class, $dbname) = @_;
56
57         # original name for compatibility with old setups:
58         $dbname //= PublicInbox::Config->config_dir() . "/imap.sqlite3";
59
60         # use the new XDG-compliant name for new setups:
61         if (!-f $dbname) {
62                 $dbname = ($ENV{XDG_DATA_HOME} //
63                         (($ENV{HOME} // '/nonexistent').'/.local/share')) .
64                         '/public-inbox/imap.sqlite3';
65         }
66         if (!-f $dbname) {
67                 require File::Path;
68                 require File::Basename;;
69                 File::Path::mkpath(File::Basename::dirname($dbname));
70         }
71
72         my $dbh = dbh_new($dbname);
73         bless { dbname => $dbname, dbh => $dbh }, $class;
74 }
75
76 1;