Артем Сыльчук - Хранение полей в Drupal. От CCK к FieldableEntityStorageControllerInterface
Upcoming SlideShare
Loading in...5

Артем Сыльчук - Хранение полей в Drupal. От CCK к FieldableEntityStorageControllerInterface






Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

Артем Сыльчук - Хранение полей в Drupal. От CCK к FieldableEntityStorageControllerInterface Артем Сыльчук - Хранение полей в Drupal. От CCK к FieldableEntityStorageControllerInterface Presentation Transcript

  • Field Storage API FieldableEntityStorageController CCK Artem Sylchuk, IntenetDevels
  • About me: Drupal developer since 2010
  • Story 1 Save 1 000 000 nodes in 1 second
  • XHProf ~ 4 seconds for 50 nodes. ~ 50% of the database time. ~ 100% of the fields update time.
  • Anatomy of the node_save() field_attach_presave('node', $node); module_invoke_all('node_presave', $node); module_invoke_all('entity_presave', $node, 'node'); drupal_write_record('node', $node); You need all this if you want own fieldable entity. Procedural code is simple, isn’t it? _node_save_revision($node, $user->uid); node_invoke($node, $op); // $op == ‘update’ || $op == ‘insert’ ------------------------------------------------------------------------------------------- // Save fields.$function = "field_attach_$op";$function('node', $node); // field_attatch_update || field_attach_insert module_invoke($storage_info['module'], 'field_storage_write', …..); field_sql_storage_field_storage_write() Long time ago in a galaxy far away... ------------------------------------------------------------------------------------------- module_invoke_all('node_' . $op, $node);module_invoke_all('entity_' . $op, $node, 'node'); node_access_acquire_grants($node, $delete); entity_get_controller('node')->resetCache(array($node->nid));
  • Field data field & field data revision
  • foreach ($field['columns'] as $column => $attributes) { $columns[] = _field_sql_storage_columnname ($field_name, $column); } $query = db_insert($table_name)->fields($columns); $revision_query = db_insert($revision_name)->fields($columns); foreach ($field_languages as $langcode) { $items = (array) $entity->{$field_name}[$langcode]; $delta_count = 0; foreach ($items as $delta => $item) { // We now know we have someting to insert. $do_insert = TRUE; $record = array( Function loops for all fields in the entity end performs Delete/Insert 'entity_type' => $entity_type, 'entity_id' => $id, 'revision_id' => $vid, 'bundle' => $bundle, 'delta' => $delta, 'language' => $langcode, ); foreach ($field['columns'] as $column => $attributes) { $record[_field_sql_storage_columnname($field_name, $column)] = isset($item[$column]) ? $item[$column] : NULL; } $query->values($record); if (isset($vid)) { $revision_query->values($record); } if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED && ++$delta_count == $field['cardinality']) { break; } } } // Execute the query if we have values to insert. $query->execute(); $revision_query->execute(); } } if ($do_insert) {
  • Can I haz some SQLs?
  • Story 2 Back in my day...
  • Content Construction Kit: Drupal 6
  • Drupal 7
  • Why, Dries, why? https://drupal.org/node/1035804#comment-6860324 “This option is the one that "makes sense" to non-Drupal coders who have written some PHP by hand before now and think they know their way around making their own database schema. It's not wrong if you are building one thing once.. Nowadays however, if you choose to use the Drupal framework and build reusable tools, • • • All Drupal text entity fields must be translatable (non-negotiable) All Drupal entity fields must be revisionable (non-negotiable) All Drupal entity fields must support being multiple (negotiable, but it's easier to allow them to be multiple as it's free to do so) If the problem *you* are solving today doesn't actually seem to need all those features right now, that's quite likely. You may also know that you'll never need to do translations, and that a number of your values aren't going to need to be multiple (according to todays business rules anyway). Next year you'll probably wish you'd supported revisions, but that's next year.” © dman
  • «I don’t need this» • Field SQL Norevisions: https://drupal.org/project/field_sql_norevisions • MongoDB: https://drupal.org/project/mongodb • Per-Bundle Storage: https://drupal.org/project/pbs • EntityFieldQuery Views Backend: https://drupal.org/project/efq_views • Own storage?
  • Imagine 1. Storage level caching 2. Multi-update: node_save_multiple 3. Check if field was changed before performing a query 4. Simple storage without delta and language columns. 5. What else?
  • I’ll write own storage with a…. 1. hook_field_storage_info(). 2. hook_field_storage_details(). 3. hook_field_storage_create_field(). 4. hook_field_storage_update_field(). 5. hook_field_storage_delete_field(). 6. hook_field_storage_load(). 7. hook_field_storage_write(). 8. hook_entity_query_alter(). 9. hook_field_storage_query(). 10. hook_field_attach_rename_bundle(). 11. hook_entity_insert(). 12. hook_entity_update(). 13. hook_field_attach_delete().
  • Let’s do it quick http://posulliv.github.io/2013/01/07/bench-field-storage/ innodb_flush_log_at_trx_commit=0 innodb_doublewrite=0 log-bin=0 innodb_support_xa=0 innodb_buffer_pool_size=6G innodb_log_file_size=512M
  • Curiosity is a way forward Drupal 8
  • https://drupal.org/node/1497374
  • extends DatabaseStorageControllerNG which extends DatabaseStorageController which extends FieldableEntityStorageControllerBase which implements FieldableEntityStorageControllerInterface
  • FieldableEntityStorageControllerBase
  • What’s next? https://drupal.org/node/2083451 Reconsider the separate field revision data tables
  • https://drupal.org/node/2068325 [META] Convert entity SQL queries to the Entity Query API
  • Questions?