field_sql_storage.install 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. <?php
  2. /**
  3. * @file
  4. * Install, update and uninstall functions for the field_sql_storage module.
  5. */
  6. /**
  7. * Implements hook_schema().
  8. */
  9. function field_sql_storage_schema() {
  10. $schema = array();
  11. // Dynamic (data) tables.
  12. if (db_table_exists('field_config')) {
  13. $fields = field_read_fields(array(), array('include_deleted' => TRUE, 'include_inactive' => TRUE));
  14. drupal_load('module', 'field_sql_storage');
  15. foreach ($fields as $field) {
  16. if ($field['storage']['type'] == 'field_sql_storage') {
  17. $schema += _field_sql_storage_schema($field);
  18. }
  19. }
  20. }
  21. return $schema;
  22. }
  23. /**
  24. * Utility function: write field data directly to SQL storage.
  25. *
  26. * This function can be used for databases whose schema is at field module
  27. * version 7000 or higher.
  28. *
  29. * @ingroup update_api
  30. */
  31. function _update_7000_field_sql_storage_write($entity_type, $bundle, $entity_id, $revision_id, $field_name, $data) {
  32. $table_name = "field_data_{$field_name}";
  33. $revision_name = "field_revision_{$field_name}";
  34. db_delete($table_name)
  35. ->condition('entity_type', $entity_type)
  36. ->condition('entity_id', $entity_id)
  37. ->execute();
  38. db_delete($revision_name)
  39. ->condition('entity_type', $entity_type)
  40. ->condition('entity_id', $entity_id)
  41. ->condition('revision_id', $revision_id)
  42. ->execute();
  43. $columns = array();
  44. foreach ($data as $langcode => $items) {
  45. foreach ($items as $delta => $item) {
  46. $record = array(
  47. 'entity_type' => $entity_type,
  48. 'entity_id' => $entity_id,
  49. 'revision_id' => $revision_id,
  50. 'bundle' => $bundle,
  51. 'delta' => $delta,
  52. 'language' => $langcode,
  53. );
  54. foreach ($item as $column => $value) {
  55. $record[_field_sql_storage_columnname($field_name, $column)] = $value;
  56. }
  57. $records[] = $record;
  58. // Record the columns used.
  59. $columns += $record;
  60. }
  61. }
  62. if ($columns) {
  63. $query = db_insert($table_name)->fields(array_keys($columns));
  64. $revision_query = db_insert($revision_name)->fields(array_keys($columns));
  65. foreach ($records as $record) {
  66. $query->values($record);
  67. if ($revision_id) {
  68. $revision_query->values($record);
  69. }
  70. }
  71. $query->execute();
  72. $revision_query->execute();
  73. }
  74. }
  75. /**
  76. * @addtogroup updates-6.x-to-7.x
  77. * @{
  78. */
  79. /**
  80. * Field SQL storage update version placeholder.
  81. */
  82. function field_sql_storage_update_7000() {
  83. // Some update helper functions (such as
  84. // _update_7000_field_sql_storage_write()) modify the database directly. They
  85. // can be used safely only if the database schema matches the field module
  86. // schema established for Drupal 7.0 (i.e. version 7000). This function exists
  87. // solely to set the schema version to 7000, so that update functions calling
  88. // those helpers can do so safely by declaring a dependency on
  89. // field_sql_storage_update_7000().
  90. }
  91. /**
  92. * Remove the field_config_entity_type table and store 'entity_type' strings.
  93. */
  94. function field_sql_storage_update_7001(&$sandbox) {
  95. if (!isset($sandbox['progress'])) {
  96. // Collect current etids.
  97. $sandbox['etids'] = db_query('SELECT etid, type FROM {field_config_entity_type}')->fetchAllKeyed();
  98. // Collect affected tables: field data, field revision data, 'deleted'
  99. // tables.
  100. $sandbox['tables'] = array();
  101. $results = db_select('field_config', 'fc', array('fetch' => PDO::FETCH_ASSOC))
  102. ->fields('fc')
  103. ->condition('storage_module', 'field_sql_storage')
  104. ->execute();
  105. foreach ($results as $field) {
  106. if ($field['deleted']) {
  107. $sandbox['tables']["field_deleted_data_{$field['id']}"] = 'data';
  108. $sandbox['tables']["field_deleted_revision_{$field['id']}"] = 'revision';
  109. }
  110. else {
  111. $sandbox['tables']["field_data_{$field['field_name']}"] = 'data';
  112. $sandbox['tables']["field_revision_{$field['field_name']}"] = 'revision';
  113. }
  114. }
  115. reset($sandbox['tables']);
  116. $sandbox['total'] = count($sandbox['tables']);
  117. $sandbox['progress'] = 0;
  118. }
  119. if ($sandbox['tables']) {
  120. // Grab the next table to process.
  121. $table = key($sandbox['tables']);
  122. $type = array_shift($sandbox['tables']);
  123. if (db_table_exists($table)) {
  124. // Add the 'entity_type' column.
  125. if (!db_field_exists($table, 'entity_type')) {
  126. $column = array(
  127. 'type' => 'varchar',
  128. 'length' => 128,
  129. 'not null' => TRUE,
  130. 'default' => '',
  131. 'description' => 'The entity type this data is attached to.',
  132. );
  133. db_add_field($table, 'entity_type', $column);
  134. // Populate the 'entity_type' column based on the 'etid' column.
  135. foreach ($sandbox['etids'] as $etid => $entity_type) {
  136. db_update($table)
  137. ->fields(array('entity_type' => $entity_type))
  138. ->condition('etid', $etid)
  139. ->execute();
  140. }
  141. // Index the new column.
  142. db_add_index($table, 'entity_type', array('entity_type'));
  143. }
  144. // Use the 'entity_type' column in the primary key.
  145. db_drop_primary_key($table);
  146. $primary_keys = array(
  147. 'data' => array('entity_type', 'entity_id', 'deleted', 'delta', 'language'),
  148. 'revision' => array('entity_type', 'entity_id', 'revision_id', 'deleted', 'delta', 'language'),
  149. );
  150. db_add_primary_key($table, $primary_keys[$type]);
  151. // Drop the 'etid' column.
  152. if (db_field_exists($table, 'etid')) {
  153. db_drop_field($table, 'etid');
  154. }
  155. }
  156. // Report progress.
  157. $sandbox['progress']++;
  158. $sandbox['#finished'] = min(0.99, $sandbox['progress'] / $sandbox['total']);
  159. }
  160. else {
  161. // No more tables left: drop the field_config_entity_type table.
  162. db_drop_table('field_config_entity_type');
  163. // Drop the previous 'field_sql_storage_ENTITYTYPE_etid' system variables.
  164. foreach ($sandbox['etids'] as $etid => $entity_type) {
  165. variable_del('field_sql_storage_' . $entity_type . '_etid');
  166. }
  167. // We're done.
  168. $sandbox['#finished'] = 1;
  169. }
  170. }
  171. /**
  172. * Fix primary keys in field revision data tables.
  173. */
  174. function field_sql_storage_update_7002() {
  175. $results = db_select('field_config', 'fc', array('fetch' => PDO::FETCH_ASSOC))
  176. ->fields('fc')
  177. ->condition('storage_module', 'field_sql_storage')
  178. ->execute();
  179. foreach ($results as $field) {
  180. // Revision tables of deleted fields do not need to be fixed, since no new
  181. // data is written to them.
  182. if (!$field['deleted']) {
  183. $table = "field_revision_{$field['field_name']}";
  184. db_drop_primary_key($table);
  185. db_add_primary_key($table, array('entity_type', 'entity_id', 'revision_id', 'deleted', 'delta', 'language'));
  186. }
  187. }
  188. }
  189. /**
  190. * @} End of "addtogroup updates-6.x-to-7.x".
  191. */