Skip to content

Commit

Permalink
Merge pull request #1604 from tripal/tv4g2-1594-debuggingChadoStorage
Browse files Browse the repository at this point in the history
Better Debugging of ChadoStorage for Field Development
  • Loading branch information
spficklin committed Aug 18, 2023
2 parents 376c87c + d4af111 commit e626dee
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 9 deletions.
8 changes: 8 additions & 0 deletions tripal/config/schema/tripal.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ field.storage.tripal_entity.*:
max_length:
type: integer
label: 'Storage Maximum length'
debug:
type: boolean
label: 'Flag to Enable field debugging'
nullable: true
storage_plugin_id:
type: string
label: 'Tripal Storage Plugin Machine Name'
Expand All @@ -120,6 +124,10 @@ field.field.tripal_entity.*.*:
termAccession:
type: string
label: 'Term Accession'
debug:
type: boolean
label: 'Flag to Enable field debugging'
nullable: true
fixed_value:
type: string
label: "A fixed value for the field that cannot be changed."
Expand Down
18 changes: 17 additions & 1 deletion tripal/src/TripalField/TripalFieldItemBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@ public static function defaultFieldSettings() {
$settings = [
'termIdSpace' => '',
'termAccession' => '',
# 'max_delta' => 100
# 'max_delta' => 100,
// A simple flag to indicate that we should enable debugging information
// for this field type.
// This will be used by ChadoStorage to tell the ChadoFieldDebugger service
// to display debugging information. All you need to do as a developer is
// set this variable to TRUE in your field and debuggin information will be
// displayed on the screen and in the drupal logs when you create, edit,
// and load content that has you field attached.
'debug' => FALSE,
];
return $settings + parent::defaultFieldSettings();
}
Expand Down Expand Up @@ -158,6 +166,14 @@ public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$vocabulary = NULL;
$termIdSpace = $this->getSetting('termIdSpace');
$termAccession = $this->getSetting('termAccession');
$debug = $this->getSetting('debug');

$elements['debug'] = [
'#type' => 'checkbox',
'#title' => 'Enable Debugging',
'#description' => 'Enabling debugging on the field will print out a number of debugging messages both on screen and in the logs to help developers diagnose any problems which may be occuring.',
'#default_value' => $debug,
];

$default_vocabulary_term = '';
$vocabulary_term = $form_state->getValue(['settings', 'field_term_fs', 'vocabulary_term']);
Expand Down
72 changes: 64 additions & 8 deletions tripal_chado/src/Plugin/TripalStorage/ChadoStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Drupal\tripal\Services\TripalLogger;
use Drupal\tripal_chado\Database\ChadoConnection;
use Drupal\tripal_chado\Services\ChadoFieldDebugger;

/**
* Chado implementation of the TripalStorageInterface.
Expand Down Expand Up @@ -57,6 +58,13 @@ class ChadoStorage extends TripalStorageBase implements TripalStorageInterface {
*/
protected $connection;

/**
* A service to provide debugging for fields to developers.
*
* @ var Drupal\tripal_chado\Services\ChadoFieldDebugger
*/
protected $field_debugger;

/**
* Implements ContainerFactoryPluginInterface->create().
*
Expand All @@ -77,7 +85,8 @@ public static function create(ContainerInterface $container, array $configuratio
$plugin_id,
$plugin_definition,
$container->get('tripal.logger'),
$container->get('tripal_chado.database')
$container->get('tripal_chado.database'),
$container->get('tripal_chado.field_debugger')
);
}

Expand All @@ -95,10 +104,11 @@ public static function create(ContainerInterface $container, array $configuratio
* @param Drupal\tripal\Services\TripalLogger $logger
* @param Drupal\tripal_chado\Database\ChadoConnection $connection
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, TripalLogger $logger, ChadoConnection $connection) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, TripalLogger $logger, ChadoConnection $connection, ChadoFieldDebugger $field_debugger) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $logger);

$this->connection = $connection;
$this->field_debugger = $field_debugger;
}

/**
Expand Down Expand Up @@ -162,6 +172,23 @@ public function removeTypes(string $field_name, array $types) {
}
}

/**
* @{inheritdoc}
*/
public function addFieldDefinition(string $field_name, object $field_definition) {
parent::addFieldDefinition($field_name, $field_definition);

// Now check if the field debugger should be enabled for this particular field.
$settings = $field_definition->getSettings();
if (array_key_exists('debug', $settings) AND $settings['debug']) {
$this->field_debugger->addFieldToDebugger($field_name);
$this->logger->notice('Debugging has been enabled for :name field.',
[':name' => $field_name],
['drupal_set_message' => TRUE, 'logger' => FALSE]
);
}
}

/**
* Inserts a single record in a Chado table.
* @param array $records
Expand All @@ -180,6 +207,9 @@ private function insertChadoRecord(&$records, $chado_table, $delta, $record) {
// Insert the record.
$insert = $this->connection->insert('1:' . $chado_table);
$insert->fields($record['fields']);

$this->field_debugger->reportQuery($insert, "Insert Query for $chado_table ($delta)");

$record_id = $insert->execute();

if (!$record_id) {
Expand All @@ -199,11 +229,12 @@ public function insertValues(&$values) : bool {

$schema = $this->connection->schema();

$this->field_debugger->printHeader('Insert');
$this->field_debugger->summarizeChadoStorage($this, 'At the beginning of ChadoStorage::insertValues');

$build = $this->buildChadoRecords($values, TRUE);
$records = $build['records'];

// @debug print "Build Records: " . print_r($records, TRUE);

$transaction_chado = $this->connection->startTransaction();
try {

Expand Down Expand Up @@ -324,6 +355,9 @@ private function updateChadoRecord(&$records, $chado_table, $delta, $record) {
foreach ($record['conditions'] as $chado_column => $cond_value) {
$update->condition($chado_column, $cond_value['value']);
}

$this->field_debugger->reportQuery($update, "Update Query for $chado_table ($delta). Note: aguements may only include the conditional ones, see Drupal Issue #2005626.");

$rows_affected = $update->execute();
if ($rows_affected == 0) {
throw new \Exception($this->t('Failed to update record in the Chado "@table" table. Record: @record',
Expand All @@ -341,6 +375,9 @@ private function updateChadoRecord(&$records, $chado_table, $delta, $record) {
*/
public function updateValues(&$values) : bool {

$this->field_debugger->printHeader('Update');
$this->field_debugger->summarizeChadoStorage($this, 'At the beginning of ChadoStorage::updateValues');

$build = $this->buildChadoRecords($values, TRUE);
$records = $build['records'];

Expand Down Expand Up @@ -466,6 +503,8 @@ public function selectChadoRecord(&$records, $base_tables, $chado_table, $delta,
}
}

$this->field_debugger->reportQuery($select, "Select Query for $chado_table ($delta)");

// Execute the query.
$results = $select->execute();
if (!$results) {
Expand All @@ -480,6 +519,9 @@ public function selectChadoRecord(&$records, $base_tables, $chado_table, $delta,
*/
public function loadValues(&$values) : bool {

$this->field_debugger->printHeader('Load');
$this->field_debugger->summarizeChadoStorage($this, 'At the beginning of ChadoStorage::loadValues');

$build = $this->buildChadoRecords($values, FALSE);
$records = $build['records'];
$base_tables = $build['base_tables'];
Expand All @@ -497,6 +539,9 @@ public function loadValues(&$values) : bool {
$transaction_chado->rollback();
throw new \Exception($e);
}

$this->field_debugger->reportValues($values, 'The values after loading is complete.');

return TRUE;
}

Expand Down Expand Up @@ -525,6 +570,9 @@ private function deleteChadoRecord(&$records, $chado_table, $delta, $record) {
foreach ($record['conditions'] as $chado_column => $cond_value) {
$delete->condition($chado_column, $cond_value['value']);
}

$this->field_debugger->reportQuery($delete, "Delete Query for $chado_table ($delta)");

$rows_affected = $delete->execute();
if ($rows_affected == 0) {
throw new \Exception($this->t('Failed to delete a record in the Chado "@table" table. Record: @record',
Expand All @@ -544,6 +592,9 @@ private function deleteChadoRecord(&$records, $chado_table, $delta, $record) {
*/
public function deleteValues($values) : bool {

$this->field_debugger->printHeader('Delete');
$this->field_debugger->summarizeChadoStorage($this, 'At the beginning of ChadoStorage::deleteValues');

return FALSE;
}

Expand All @@ -552,6 +603,9 @@ public function deleteValues($values) : bool {
*/
public function findValues($match) {

$this->field_debugger->printHeader('Find');
$this->field_debugger->summarizeChadoStorage($this, 'At the beginning of ChadoStorage::findValues');

}


Expand Down Expand Up @@ -791,7 +845,7 @@ protected function buildChadoRecords($values, bool $is_store) {
$records = [];
$base_record_ids = [];

// @debug dpm(array_keys($values), '1st level: field names');
$this->field_debugger->reportValues($values, 'The values submitted to ChadoStorage');

// Iterate through the value objects.
foreach ($values as $field_name => $deltas) {
Expand All @@ -804,11 +858,8 @@ protected function buildChadoRecords($values, bool $is_store) {
continue;
}

// @debug dpm(array_keys($deltas), "2nd level: deltas ($field_name)");
foreach ($deltas as $delta => $keys) {
// @debug dpm(array_keys($keys), "3rd level: field key name ($delta)");
foreach ($keys as $key => $info) {
// @debug dpm(array_keys($info), "4th level: info key-value pairs ($key)");

// Ensure we have a value to work with.
if (!array_key_exists('value', $info) OR !is_object($info['value'])) {
Expand Down Expand Up @@ -954,6 +1005,8 @@ protected function buildChadoRecords($values, bool $is_store) {
}
}

$this->field_debugger->summarizeBuiltRecords($base_record_ids, $records);

return [
'base_tables' => $base_record_ids,
'records' => $records
Expand Down Expand Up @@ -1390,6 +1443,9 @@ public function validateSize($values, $chado_table, $record_id, $record, &$viola
*/
public function validateValues($values) {

$this->field_debugger->printHeader('Validate');
$this->field_debugger->summarizeChadoStorage($this, 'At the beginning of ChadoStorage::validateValues');

$build = $this->buildChadoRecords($values, TRUE);
$base_tables = $build['base_tables'];
$records = $build['records'];
Expand Down

0 comments on commit e626dee

Please sign in to comment.