1#!/usr/bin/env php
2<?php
3
4/**
5 * Kolab storage cache testing script
6 *
7 * @author Thomas Bruederli <bruederli@kolabsys.com>
8 *
9 * Copyright (C) 2014, Kolab Systems AG <contact@kolabsys.com>
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Affero General Public License as
13 * published by the Free Software Foundation, either version 3 of the
14 * License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Affero General Public License for more details.
20 *
21 * You should have received a copy of the GNU Affero General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 */
24
25define('INSTALL_PATH', __DIR__ . '/../../../');
26ini_set('display_errors', 1);
27libxml_use_internal_errors(true);
28
29require_once INSTALL_PATH . 'program/include/clisetup.php';
30
31function print_usage()
32{
33	print "Usage:  readcache.sh [OPTIONS] FOLDER\n";
34	print "-h, --host     IMAP host name\n";
35	print "-l, --limit    Limit the number of records to be listed\n";
36}
37
38// read arguments
39$opts = rcube_utils::get_opt(array(
40    'h' => 'host',
41    'l' => 'limit',
42    'v' => 'verbose',
43));
44
45$folder = $opts[0];
46$imap_host = $opts['host'];
47
48$rcmail = rcube::get_instance(rcube::INIT_WITH_DB | rcube::INIT_WITH_PLUGINS);
49
50if (empty($imap_host)) {
51    $imap_host = imap_host();
52}
53
54if (empty($folder) || empty($imap_host)) {
55    print_usage();
56    exit;
57}
58
59// connect to database
60$db = $rcmail->get_dbh();
61$db->db_connect('r');
62if (!$db->is_connected() || $db->is_error()) {
63    die("No DB connection\n");
64}
65
66
67// resolve folder_id
68if (!is_numeric($folder)) {
69    if (strpos($folder, '@')) {
70        list($mailbox, $domain) = explode('@', $folder);
71        list($username, $subpath) = explode('/', preg_replace('!^user/!', '', $mailbox), 2);
72        $folder_uri = 'imap://' . urlencode($username.'@'.$domain) . '@' . $imap_host . '/' . $subpath;
73    }
74    else {
75        die("Invalid mailbox identifier! Example: user/john.doe/Calendar@example.org\n");
76    }
77
78    print "Resolving folder $folder_uri...";
79    $sql_result = $db->query('SELECT * FROM `kolab_folders` WHERE `resource`=?', $folder_uri);
80    if ($sql_result && ($folder_data = $db->fetch_assoc($sql_result))) {
81        $folder_id = $folder_data['folder_id'];
82        print $folder_id;
83    }
84    print "\n";
85}
86else {
87    $folder_id = intval($folder);
88    $sql_result = $db->query('SELECT * FROM `kolab_folders` WHERE `folder_id`=?', $folder_id);
89    if ($sql_result) {
90        $folder_data = $db->fetch_assoc($sql_result);
91    }
92}
93
94if (empty($folder_data)) {
95    die("Can't find cache mailbox for '$folder'\n");
96}
97
98print "Querying cache for folder $folder_id ($folder_data[type])...\n";
99
100$extra_cols = array(
101    'event'   => array('dtstart','dtend'),
102    'contact' => array('type'),
103);
104
105$cache_table = $db->table_name('kolab_cache_' . $folder_data['type']);
106$extra_cols_ = $extra_cols[$folder_data['type']] ?: array();
107$sql_arr = $db->fetch_assoc($db->query("SELECT COUNT(*) as cnt FROM `$cache_table` WHERE `folder_id`=?", intval($folder_id)));
108
109print "CTag     = " . $folder_data['ctag'] . "\n";
110print "Lock     = " . $folder_data['synclock'] . "\n";
111print "Changed  = " . $folder_data['changed'] . "\n";
112print "ObjCount = " . $folder_data['objectcount'] . "\n";
113print "Count    = " . $sql_arr['cnt'] . "\n";
114print "----------------------------------------------------------------------------------\n";
115print "<MSG>\t<UUID>\t<CHANGED>\t<DATA>\t";
116print join("\t", array_map(function($c) { return '<' . strtoupper($c) . '>'; }, $extra_cols_));
117print "\n----------------------------------------------------------------------------------\n";
118
119$result = $db->limitquery("SELECT * FROM `$cache_table` WHERE `folder_id`=?", 0, $opts['limit'], intval($folder_id));
120while ($result && ($sql_arr = $db->fetch_assoc($result))) {
121    print $sql_arr['msguid'] . "\t" . $sql_arr['uid'] . "\t" . $sql_arr['changed'];
122
123    // try to unserialize data block
124    $object = json_decode($sql_arr['data']);
125    print "\t" . ($object === false ? 'FAIL!' : 'OK');
126
127    // print extra cols
128    array_walk($extra_cols_, function($c) use ($sql_arr) {
129        print "\t" . $sql_arr[$c];
130    });
131
132    print "\n";
133}
134
135print "----------------------------------------------------------------------------------\n";
136echo "Done.\n";
137
138
139function imap_host()
140{
141    global $rcmail;
142
143    $default_host = $rcmail->config->get('default_host');
144
145    if (is_array($default_host)) {
146        $key = key($default_host);
147        $imap_host = is_numeric($key) ? $default_host[$key] : $key;
148    }
149    else {
150        $imap_host = $default_host;
151    }
152
153    // strip protocol prefix
154    $uri = parse_url($imap_host);
155    if (!empty($uri['host'])) {
156        return $uri['host'];
157    }
158}
159