Skip to content

Commit

Permalink
Add bulk create action
Browse files Browse the repository at this point in the history
  • Loading branch information
eileenmcnaughton committed Jul 2, 2019
1 parent f8df300 commit 76df6f6
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 8 deletions.
37 changes: 30 additions & 7 deletions CRM/Core/BAO/CustomField.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,19 +260,38 @@ protected static function prepareCreateParams($field, $operation) {
/**
* 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 $params
* @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 function bulkCreate($params, $defaults) {
foreach ($params as $fieldParams) {
$fieldParams = array_merge($defaults, $fieldParams);
public static function bulkCreate($bulkParams, $defaults) {
$sql = [];
$customFields = [];
foreach ($bulkParams as $fieldParams) {
$params = array_merge($defaults, $fieldParams);
$params = self::prepareCreate($params);
$customField = self::doCreate($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);
}
}

Expand Down Expand Up @@ -1762,8 +1781,12 @@ public static function defaultCustomTableSchema($params) {
* @param bool $triggerRebuild
*/
public static function createField($field, $operation, $indexExist = FALSE, $triggerRebuild = TRUE) {
$params = [];
$sql = self::getAlterFieldSQL($field, $operation, $params, $indexExist);
$params = [
'table_name' => CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomGroup', $field->custom_group_id, 'table_name'),
];
$sql = str_repeat(' ', 8);
$sql .= "ALTER TABLE {$params['table_name']}";
$sql .= self::getAlterFieldSQL($field, $operation, $params, $indexExist);

// CRM-7007: do not i18n-rewrite this query
CRM_Core_DAO::executeQuery($sql, [], TRUE, NULL, FALSE, FALSE);
Expand Down Expand Up @@ -1798,7 +1821,7 @@ public static function getAlterFieldSQL($field, $operation, &$params, $indexExis
// lets suppress the required flag, since that can cause sql issue
$params['required'] = FALSE;

return CRM_Core_BAO_SchemaHandler::buildFieldChangeSql($params, $indexExist);
return CRM_Core_BAO_SchemaHandler::getFieldAlterSQL($params, $indexExist);
}

/**
Expand Down
12 changes: 12 additions & 0 deletions CRM/Core/BAO/SchemaHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,18 @@ public static function createMissingIndices($missingIndices) {
public static function buildFieldChangeSql($params, $indexExist) {
$sql = str_repeat(' ', 8);
$sql .= "ALTER TABLE {$params['table_name']}";
$sql = self::getFieldAlterSQL($params, $indexExist, $sql);
return $sql;
}

/**
* @param array $params
* @param bool $indexExist
*
* @return string
*/
public static function getFieldAlterSQL($params, $indexExist) {
$sql = '';
switch ($params['operation']) {
case 'add':
$separator = "\n";
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
24 changes: 23 additions & 1 deletion tests/phpunit/CRM/Core/BAO/CustomFieldTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,29 @@ public function testBulkCreate() {
'extends' => 'Individual',
'title' => 'my bulk group',
]);
CRM_Core_BAO_CustomField::bulkCreate([]);
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` 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 76df6f6

Please sign in to comment.