Skip to content

Commit

Permalink
dev/core#1093 add a bulkCreate action for many customFields in one go
Browse files Browse the repository at this point in the history
Add bulkCreate function for CustomField with a view towards this being a new protocol for how bulk create actions would look from a code POV which we could expose via apiv4
  • Loading branch information
eileenmcnaughton committed Jul 5, 2019
1 parent 7aa6ebb commit 9cbea12
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
37 changes: 37 additions & 0 deletions CRM/Core/BAO/CustomField.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,43 @@ public static function create($params) {
return $customField;
}

/**
* Create several fields at once in a mysql efficient way.
*
* https://lab.civicrm.org/dev/core/issues/1093
*
* The intention is that apiv4 would expose any BAO with bulkCreate as a new action.
*
* Note that in the first instance this supports 'create' only. It's possible edit
* is fine in the same function - just treading slowly.
*
* @param array $bulkParams
* Array of arrays as would be passed into create
* @param array $defaults
* Default parameters to be be merged into each of the params.
*/
public static function bulkCreate($bulkParams, $defaults) {
$sql = [];
$customFields = [];
foreach ($bulkParams as $fieldParams) {
$params = array_merge($defaults, $fieldParams);
$customField = self::createCustomFieldRecord($params);
// Only doing 'add' for now - so hard coded & no indexExists.
$fieldSQL = self::getAlterFieldSQL($customField, 'add', $params);
$sql[$params['table_name']][] = $fieldSQL;
$customFields[] = $customField;
}
foreach ($sql as $tableName => $statements) {
// CRM-7007: do not i18n-rewrite this query
CRM_Core_DAO::executeQuery("ALTER TABLE $tableName " . implode(', ', $statements), [], TRUE, NULL, FALSE, FALSE);
Civi::service('sql_triggers')->rebuild($params['table_name'], TRUE);
}
CRM_Utils_System::flushCache();
foreach ($customFields as $customField) {
CRM_Utils_Hook::post('create', 'CustomField', $customField->id, $customField);
}
}

/**
* Fetch object based on array of properties.
*
Expand Down
1 change: 1 addition & 0 deletions CRM/Utils/Migrate/Import.php
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ public function customFields(&$xml, &$idMap) {

// Only rebuild the table's trigger on the last field added to avoid un-necessary
// and slow rebuilds when adding many fields at the same time.
// @todo - call bulkCreate instead.
$triggerRebuild = FALSE;
if ($count == $total) {
$triggerRebuild = TRUE;
Expand Down
33 changes: 33 additions & 0 deletions tests/phpunit/CRM/Core/BAO/CustomFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -636,4 +636,37 @@ public function testGetFieldsForImport() {
$this->assertEquals($expected, CRM_Core_BAO_CustomField::getFieldsForImport());
}

/**
* Test the bulk create function works.
*/
public function testBulkCreate() {
$customGroup = $this->customGroupCreate([
'extends' => 'Individual',
'title' => 'my bulk group',
]);
CRM_Core_BAO_CustomField::bulkCreate([
[
'label' => 'Test',
'data_type' => 'String',
'html_type' => 'Text',
'column_name' => 'my_text',
],
[
'label' => 'test_link',
'data_type' => 'Link',
'html_type' => 'Link',
'is_search_range' => '0',
],
],
[
'custom_group_id' => $customGroup['id'],
'is_active' => 1,
'is_searchable' => 1,
]);
$dao = CRM_Core_DAO::executeQuery(('SHOW CREATE TABLE ' . $customGroup['values'][$customGroup['id']]['table_name']));
$dao->fetch();
$this->assertContains('`test_link_2` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL', $dao->Create_Table);
$this->assertContains('KEY `INDEX_my_text` (`my_text`)', $dao->Create_Table);
}

}

0 comments on commit 9cbea12

Please sign in to comment.