Skip to content
Browse files

additional logging adjustments; add instance setup code

  • Loading branch information...
1 parent 661c33e commit 8b689fada4f9850ed08e9a36d23f5c0cd5546539 @lcdservices lcdservices committed
View
254 civicrm/custom/php/CRM/Logging/Differ.php
@@ -0,0 +1,254 @@
+<?php
+
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.1 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2011 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+*/
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2011
+ * $Id$
+ *
+ */
+
+require_once 'CRM/Contribute/PseudoConstant.php';
+require_once 'CRM/Core/PseudoConstant.php';
+
+class CRM_Logging_Differ
+{
+ private $db;
+ private $log_conn_id;
+ private $log_date;
+
+ function __construct($log_conn_id, $log_date)
+ {
+ $dsn = defined('CIVICRM_LOGGING_DSN') ? DB::parseDSN(CIVICRM_LOGGING_DSN) : DB::parseDSN(CIVICRM_DSN);
+ $this->db = $dsn['database'];
+ $this->log_conn_id = $log_conn_id;
+ $this->log_date = $log_date;
+ }
+
+ function diffsInTables($tables)
+ {
+ $diffs = array();
+ foreach ($tables as $table) {
+ $diff = $this->diffsInTable($table);
+ if (!empty($diff)) $diffs[$table] = $diff;
+ }
+ return $diffs;
+ }
+
+ function diffsInTable($table)
+ {
+ $diffs = array();
+
+ $params = array(
+ 1 => array($this->log_conn_id, 'Integer'),
+ 2 => array($this->log_date, 'String'),
+ );
+
+ // find ids in this table that were affected in the given connection (based on connection id and a ±10 s time period around the date)
+ $sql = "SELECT DISTINCT id FROM `{$this->db}`.`log_$table` WHERE log_conn_id = %1 AND log_date BETWEEN DATE_SUB(%2, INTERVAL 10 SECOND) AND DATE_ADD(%2, INTERVAL 10 SECOND)";
+ $dao = CRM_Core_DAO::executeQuery($sql, $params);
+ while ($dao->fetch()) {
+ $diffs = array_merge($diffs, $this->diffsInTableForId($table, $dao->id));
+ }
+
+ return $diffs;
+ }
+
+ private function diffsInTableForId($table, $id)
+ {
+ $diffs = array();
+
+ $params = array(
+ 1 => array($this->log_conn_id, 'Integer'),
+ 2 => array($this->log_date, 'String'),
+ 3 => array($id, 'Integer'),
+ );
+
+ // look for the last change in the given connection that happended less than 10 seconds later than log_date to the given id to catch multi-query changes
+ $changedSQL = "SELECT * FROM `{$this->db}`.`log_$table` WHERE log_conn_id = %1 AND log_date < DATE_ADD(%2, INTERVAL 10 SECOND) AND id = %3 ORDER BY log_date DESC LIMIT 1";
+ $changed = $this->sqlToArray($changedSQL, $params);
+
+ // return early if nothing found
+ if (empty($changed)) return array();
+
+ switch ($changed['log_action']) {
+ case 'Delete':
+ // the previous state is kept in the current state, current should keep the keys and clear the values
+ $original = $changed;
+ foreach ($changed as &$val) $val = null;
+ $changed['log_action'] = 'Delete';
+ break;
+ case 'Insert':
+ // the previous state does not exist
+ $original = array();
+ break;
+ case 'Update':
+ // look for the previous state (different log_conn_id) of the given id
+ $originalSQL = "SELECT * FROM `{$this->db}`.`log_$table` WHERE log_conn_id != %1 AND log_date < %2 AND id = %3 ORDER BY log_date DESC LIMIT 1";
+ $original = $this->sqlToArray($originalSQL, $params);
+ break;
+ }
+
+ // populate $diffs with only the differences between $changed and $original
+ $skipped = array('log_action', 'log_conn_id', 'log_date', 'log_user_id');
+ foreach (array_keys(array_diff_assoc($changed, $original)) as $diff) {
+ if (in_array($diff, $skipped)) {
+ continue;
+ }
+
+ if ( CRM_Utils_Array::value($diff,$original) === CRM_Utils_Array::value($diff,$changed) ) {
+ continue;
+ }
+
+ $diffs[] = array(
+ 'action' => $changed['log_action'],
+ 'id' => $id,
+ 'field' => $diff,
+ 'from' => CRM_Utils_Array::value($diff,$original),
+ 'to' => CRM_Utils_Array::value($diff,$changed),
+ );
+ }
+
+ return $diffs;
+ }
+
+ function titlesAndValuesForTable($table)
+ {
+ // static caches for subsequent calls with the same $table
+ static $titles = array();
+ static $values = array();
+
+ // FIXME: split off the table → DAO mapping to a GenCode-generated class
+ static $daos = array(
+ 'civicrm_address' => 'CRM_Core_DAO_Address',
+ 'civicrm_contact' => 'CRM_Contact_DAO_Contact',
+ 'civicrm_email' => 'CRM_Core_DAO_Email',
+ 'civicrm_im' => 'CRM_Core_DAO_IM',
+ 'civicrm_openid' => 'CRM_Core_DAO_OpenID',
+ 'civicrm_phone' => 'CRM_Core_DAO_Phone',
+ 'civicrm_website' => 'CRM_Core_DAO_Website',
+ 'civicrm_contribution' => 'CRM_Contribute_DAO_Contribution',
+ );
+
+ if (!isset($titles[$table]) or !isset($values[$table])) {
+
+ if (in_array($table, array_keys($daos))) {
+ // FIXME: these should be populated with pseudo constants as they
+ // were at the time of logging rather than their current values
+ $values[$table] = array(
+ 'contribution_page_id' => CRM_Contribute_PseudoConstant::contributionPage(),
+ 'contribution_status_id' => CRM_Contribute_PseudoConstant::contributionStatus(),
+ 'contribution_type_id' => CRM_Contribute_PseudoConstant::contributionType(),
+ 'country_id' => CRM_Core_PseudoConstant::country(),
+ 'gender_id' => CRM_Core_PseudoConstant::gender(),
+ 'location_type_id' => CRM_Core_PseudoConstant::locationType(),
+ 'payment_instrument_id' => CRM_Contribute_PseudoConstant::paymentInstrument(),
+ 'phone_type_id' => CRM_Core_PseudoConstant::phoneType(),
+ 'preferred_communication_method' => CRM_Core_PseudoConstant::pcm(),
+ 'preferred_language' => CRM_Core_PseudoConstant::languages(),
+ 'prefix_id' => CRM_Core_PseudoConstant::individualPrefix(),
+ 'provider_id' => CRM_Core_PseudoConstant::IMProvider(),
+ 'state_province_id' => CRM_Core_PseudoConstant::stateProvince(),
+ 'suffix_id' => CRM_Core_PseudoConstant::individualSuffix(),
+ 'website_type_id' => CRM_Core_PseudoConstant::websiteType(),
+ );
+
+ require_once str_replace('_', DIRECTORY_SEPARATOR, $daos[$table]) . '.php';
+ eval("\$dao = new $daos[$table];");
+ foreach ($dao->fields() as $field) {
+ $titles[$table][$field['name']] = CRM_Utils_Array::value('title',$field);
+
+ if ($field['type'] == CRM_Utils_Type::T_BOOLEAN) {
+ $values[$table][$field['name']] = array('0' => ts('false'), '1' => ts('true'));
+ }
+ }
+ } elseif (substr($table, 0, 14) == 'civicrm_value_') {
+ list($titles[$table], $values[$table]) = $this->titlesAndValuesForCustomDataTable($table);
+ }
+ }
+
+ return array($titles[$table], $values[$table]);
+ }
+
+ private function sqlToArray($sql, $params)
+ {
+ $dao = CRM_Core_DAO::executeQuery($sql, $params);
+ $dao->fetch();
+ return $dao->toArray();
+ }
+
+ private function titlesAndValuesForCustomDataTable($table)
+ {
+ $titles = array();
+ $values = array();
+
+ $params = array(
+ 1 => array($this->log_conn_id, 'Integer'),
+ 2 => array($this->log_date, 'String'),
+ 3 => array($table, 'String'),
+ );
+
+ $sql = "SELECT id, title FROM `{$this->db}`.log_civicrm_custom_group WHERE log_date <= %2 AND table_name = %3 ORDER BY log_date DESC LIMIT 1";
+ $cgDao = CRM_Core_DAO::executeQuery($sql, $params);
+ $cgDao->fetch();
+
+ $params[3] = array($cgDao->id, 'Integer');
+ $sql = "SELECT column_name, data_type, label, name, option_group_id FROM `{$this->db}`.log_civicrm_custom_field WHERE log_date <= %2 AND custom_group_id = %3 ORDER BY log_date";
+ $cfDao = CRM_Core_DAO::executeQuery($sql, $params);
+
+ while ($cfDao->fetch()) {
+ $titles[$cfDao->column_name] = "{$cgDao->title}: {$cfDao->label}";
+
+ switch ($cfDao->data_type) {
+ case 'Boolean':
+ $values[$cfDao->column_name] = array('0' => ts('false'), '1' => ts('true'));
+ break;
+ case 'String':
+ $values[$cfDao->column_name] = array();
+ if ( !empty( $cfDao->option_group_id ) ) {
+ $params[3] = array($cfDao->option_group_id, 'Integer');
+ $sql = "
+SELECT label, value
+FROM `{$this->db}`.log_civicrm_option_value
+WHERE log_date <= %2
+AND option_group_id = %3
+ORDER BY log_date
+";
+ $ovDao = CRM_Core_DAO::executeQuery($sql, $params);
+ while ($ovDao->fetch()) {
+ $values[$cfDao->column_name][$ovDao->value] = $ovDao->label;
+ }
+ }
+ break;
+ }
+ }
+
+ return array($titles, $values);
+ }
+}
View
12 civicrm/custom/php/CRM/Logging/Schema.php
@@ -311,9 +311,15 @@ private function deleteReports()
*/
public function isEnabled()
{
- //return $this->tablesExist() and $this->triggersExist();
+ //NYSS alter how logging enabled is determined
+ $isEnabled = 0;
$config = CRM_Core_Config::singleton();
- return $config->logging;
+ if ( $this->tablesExist() &&
+ $this->triggersExist() &&
+ $config->logging ) {
+ $isEnabled = 1;
+ }
+ return $isEnabled;
}
/**
@@ -330,7 +336,7 @@ private function tablesExist()
private function triggersExist()
{
// FIXME: probably should be a bit more thorough…
- return (bool) CRM_Core_DAO::singleValueQuery("SHOW TRIGGERS LIKE 'civicrm_contact'");
+ return (bool) CRM_Core_DAO::singleValueQuery("SHOW TRIGGERS LIKE 'civicrm_domain'"); //NYSS
}
//NYSS 5067
View
3 scripts/copyInstance.sh
@@ -112,4 +112,7 @@ echo "Loading Drupal database for instance $destinst with data from $temp_drup_f
$execSql --create -i $destinst --drupal || die 4
$execSql -f $temp_drup_file -i $destinst --drupal || die 5
+echo "Creating Log database for instance $destinst"
+$execSql --create -i $destinst --log || die 6
+
die 0
View
9 scripts/deleteInstance.sh
@@ -47,6 +47,7 @@ fi
[ "$domain" ] || domain=`$readConfig --ig $instance base.domain` || domain="$DEFAULT_BASE_DOMAIN"
db_civi_prefix=`$readConfig --ig $instance db.civicrm.prefix` || db_civi_prefix="$DEFAULT_DB_CIVICRM_PREFIX"
db_drup_prefix=`$readConfig --ig $instance db.drupal.prefix` || db_drup_prefix="$DEFAULT_DB_DRUPAL_PREFIX"
+db_log_prefix=`$readConfig --ig $instance db.log.prefix` || db_log_prefix="$DEFAULT_DB_LOG_PREFIX"
db_basename=`$readConfig --ig $instance db.basename` || db_basename="$instance"
drupal_rootdir=`$readConfig --ig $instance drupal.rootdir` || drupal_rootdir="$DEFAULT_DRUPAL_ROOTDIR"
data_rootdir=`$readConfig --ig $instance data.rootdir` || data_rootdir="$DEFAULT_DATA_ROOTDIR"
@@ -63,6 +64,7 @@ if [ $force_ok -eq 0 ]; then
echo "Domain: $domain"
echo "CiviCRM DB Prefix: $db_civi_prefix"
echo "Drupal DB Prefix: $db_drup_prefix"
+ echo "Log DB Prefix: $db_log_prefix"
echo "Drupal Root Directory: $drupal_rootdir"
echo "Data Root Directory: $data_rootdir"
if [ $db_only -ne 1 ]; then
@@ -72,6 +74,7 @@ if [ $force_ok -eq 0 ]; then
if [ $files_only -ne 1 ]; then
echo "Will delete DB: $db_drup_prefix$db_basename"
echo "Will delete DB: $db_civi_prefix$db_basename"
+ echo "Will delete DB: $db_log_prefix$db_basename"
fi
echo
echo -n "Are you sure that you want to delete instance $instance ([N]/y)? "
@@ -101,6 +104,12 @@ if [ $files_only -ne 1 ]; then
$execSql -c "drop database $db_civi_prefix$db_basename"
) || errcode=$(($errcode | 4))
set +x
+
+ echo "Deleting Log database for instance [$instance]"
+ ( set -x
+ $execSql -c "drop database $db_log_prefix$db_basename"
+ ) || errcode=$(($errcode | 4))
+ set +x
fi
exit $errcode
View
3 scripts/execSql.sh
@@ -16,7 +16,7 @@ readConfig=$script_dir/readConfig.sh
. $script_dir/defaults.sh
usage() {
- echo "Usage: $prog [-f sqlFile | -c sqlCommand] [-d] [-t table] [-i instance] [-h host] [-u user] [-p password] [--column-names] [--quiet|-q] [--create] [--drupal] [dbName]" >&2
+ echo "Usage: $prog [-f sqlFile | -c sqlCommand] [-d] [-t table] [-i instance] [-h host] [-u user] [-p password] [--column-names] [--quiet|-q] [--create] [--drupal] [--log] [dbName]" >&2
}
if [ $# -lt 1 ]; then
@@ -53,6 +53,7 @@ while [ $# -gt 0 ]; do
--col*) colname_arg="--column-names" ;;
--create) create_db=1 ;;
--drupal) db_prefix_keyname=db.drupal.prefix; default_db_prefix="$DEFAULT_DB_DRUPAL_PREFIX" ;;
+ --log) db_prefix_keyname=db.log.prefix; default_db_prefix="$DEFAULT_DB_LOG_PREFIX" ;;
-*) echo "$prog: $1: Invalid option" >&2; exit 1 ;;
*) dbname="$1" ;;
esac

0 comments on commit 8b689fa

Please sign in to comment.
Something went wrong with that request. Please try again.