25
Field Storage API FieldableEntityStorageController CCK Artem Sylchuk, IntenetDevels

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

Embed Size (px)

Citation preview

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

Field Storage API

FieldableEntityStorageController

CCK

Artem Sylchuk, IntenetDevels

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

About me:

Drupal developer since 2010

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

Story 1Save 1 000 000 nodes in 1 second

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

XHProf~ 4 seconds for 50 nodes.~ 50% of the database time.~ 100% of the fields update time.

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

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);

_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()

-------------------------------------------------------------------------------------------

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));

You need all this if you want own fieldable entity.Procedural code is simple, isn’t it?

Long time ago in a galaxy far away...

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

Field data field & field data revision

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

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(

'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. if ($do_insert) {

$query->execute();

$revision_query->execute();

}

}

Function loops for all fields in the entity end performs Delete/Insert

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

Can I haz some SQLs?

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

Story 2Back in my day...

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

Content Construction Kit: Drupal 6

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

Drupal 7

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

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 re-usable 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

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

«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?

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

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?

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

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().

14.hook_entity_info_alter().

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

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

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

Curiosity is a way forward

Drupal 8

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

https://drupal.org/node/1497374

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

extends DatabaseStorageControllerNG

which extends DatabaseStorageController

which extends FieldableEntityStorageControllerBase

which implements FieldableEntityStorageControllerInterface

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

FieldableEntityStorageControllerBase

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

What’s next?

https://drupal.org/node/2083451

Reconsider the separate field revision data tables

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

https://drupal.org/node/2068325

[META] Convert entity SQL queries to the Entity Query API

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

Questions?

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