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