+ All Categories
Home > Technology > Drupal II: The SQL

Drupal II: The SQL

Date post: 18-Dec-2014
Category:
Upload: ddiers
View: 3,057 times
Download: 0 times
Share this document with a friend
Description:
It's back... AND it's better than ever, DBTNG (Database: The Next Generation) is nothing to be scared of and we'll show how easy it is to create both static and dynamic query statements for use in your custom modules and Drupal 6 to Drupal 7 module migration work. In this session we'll take a look at the Drupal 7 database abstraction layer and the database API and cover: To db_query or not to db_query? Dynamic query syntax and fluid interfaces Working with result sets Joins, conditional statements, subselects and sorting with db_select Tagging your db_select queries for hook awareness Decorator patterns for db_select - db_update, db_insert, db_delete and our new friend, db_merge Explore alternatives to views and how and when to make that call. After this session attendees will be ready for Drupal III: Drupalicon Takes Manhattan
38
Drupal II: The SQL David Diers, Developer Four Kitchens Austin, TX D.O - thebruce @beautyhammer
Transcript
Page 1: Drupal II: The SQL

Drupal II: The SQL

David Diers, DeveloperFour KitchensAustin, TX

D.O - thebruce@beautyhammer

Page 2: Drupal II: The SQL

What we’ll cover

Basics of the Drupal DB APIUsing db_queryUsing and building dynamic queries including

Criteria clauses, joins, sorting, sub-selects, extenders, and tagging

How to work with result sets

Page 3: Drupal II: The SQL

Drupal and the DBDrupal uses the DB to:

Store content - where "content" is thought of very broadly.Store user or module configurations Store system values

Drupal retrieves these values all of the time.

Page 4: Drupal II: The SQL

Drupal and DB Abstraction

What is DB Abstraction?A way of uniformly interacting and leveraging SQL commands with multiple types of database products.A structured way of dynamically constructing SQL statements

DB Abstraction is nothing new for Drupal

Page 5: Drupal II: The SQL

Drupal 7 DB API uses PDO

In D7 the DB Abstraction layer got a face-liftBuilt on PDO

PDO is PHPOOPDrupal extends PDO classesPDO used in many projects

Page 6: Drupal II: The SQL

Why learn the DB API?

Isn’t most of this stuff in functions already?Doesn’t views do this for me?Can’t I just use raw SQL like they did in ye olde days ™?

Page 7: Drupal II: The SQL

Why Learn the DB API?

Need a result set that you can’t get or requires custom views development?Writing or supporting custom modules with their own schema?Need results from the contrib module’s schema but there isn’t a function to do so?Patching an existing modules’ database functionality?Need additional ways besides features, views, panels to transfer configuration via update hooks? Need to implement custom sql statements to improve the performance of your site?

Page 8: Drupal II: The SQL

Using the DB API

2 Primary ways to interact with data in D7dbquery – performant, limited transferability.Dynamic queries - more complex, high transferability, powerful, less performant.

Page 9: Drupal II: The SQL

db_query – the basics

IN SQL:

SELECT nid, titleFROM nodeWHERE type = ‘article’;

IN db_query: <?php$type = ‘article’;$result = db_query("SELECT nid, title FROM {node} WHERE type = :type", array(':type' => $type,));

Page 10: Drupal II: The SQL

db_query – the breakdown

$result = db_query("SELECT nid, title FROM {node} WHERE type = :type", array(':type' => $type,));

db_query($query, $placeholders, $options)enclose tables in { } Placeholders start with ":"

EX: WHERE type = :type", array(':type' => 'page',))

Options array - 2 common ones are:Target (default or slave)Fetch (pdo fetch type)

http://druptest7.dev:8888/example_dbq

Page 11: Drupal II: The SQL

db_query d6 => d7 transitions

In transitioning D6 db_query to D7 be aware:The syntax signature has changed –• D6 parameters were the $query, followed by a

variable number of arguments or an array of query substitutions.• % syntax for placeholders• Varied sql commands executed via db_query.

Page 12: Drupal II: The SQL

Dynamic sql – the basics

Dynamic QueriesMuch more transportable.You MUST use for ( INSERT, UPDATE, DELETE)You may use for (SELECT) • http://www.lullabot.com/articles/simplify-your-c

ode-with-drupal-7s-database-api ).

Page 13: Drupal II: The SQL

db_select – the basics

IN SQL:

SELECT nid, titleFROM nodeWHERE type = ‘article’;

IN db_select: <?php$type = ‘article’;$query = db_select(‘node’, ’n’);$result = $query->fields(‘n’, array(‘nid’,’title’) ->condition(‘n.type’,$type) ->execute();

Page 14: Drupal II: The SQL

db_select – the basics

(‘node’, ‘n’) Name of Table / Alias

(fields(‘n’, array(‘nid’, ‘title’))

Alias, array of fields

Single quotes are important for transferability.

IN db_select: <?php$type = ‘article’;$query = db_select(‘node’, ’n’);$result = $query->fields(‘n’, array(‘nid’,’title’) ->condition(‘n.type’,$type) ->execute();

Page 15: Drupal II: The SQL

Dynamic Queries – of note$query = db_select(‘node’, ’n’);$result = $query->fields(‘n’, array(‘nid’,’title’) ->condition(‘n.type’,$type) ->execute();

Fluid Interface - allows method chainingQuery statements are executed by ->execute();  easy to forget, but don't.You’ll get back a result set / statement object

Page 16: Drupal II: The SQL

Working with Result Sets

Use - foreach loop oror - Specificaly get the next record

$record = $result->fetch(); // Use the default fetch mode.$record = $result->fetchObject();  // Fetch as a stdClass object.$record = $result->fetchAssoc();   // Fetch as an associative array.

or - to get a single field$record = $result->fetchField($column_index);

Page 17: Drupal II: The SQL

Which should I use?

Is your query static? Use db_query it is faster.Does your query need to be constructed at run time? Use dynamic queriesDo you need to INSERT, UPDATE, or DELETE? Use Dynamic queries.Are you querying the node table – Use Dynamic queries to respect node access.

Page 18: Drupal II: The SQL

More with Dynamic Queries

How to add fields or select *Conditional StatementsAND / OR Sub-selectsJOINSSORT

Page 19: Drupal II: The SQL

Fields and db_select

Adding fields to a query:$query->fields('n', array('nid', 'title', 'created', 'uid'));

"select *"  is fields with no field array indicated:$query->fields('n');

http://druptest7.dev:8888/example_dyn

Page 20: Drupal II: The SQL

Conditional Statements

Signature:  $query->condition($field, $value = NULL, $operator = '=')Default operator is SQL =  can take ANSI sql comparators <, >, LIKE, = >=

EX: $query->condition('nid',1)EX: $query->condition('nid',1, '<>')

In or between:EX: $query->condition('myfield', array(1, 2, 3), 'IN');

Page 21: Drupal II: The SQL

Conditional Statements (more)

Nested Conditionals:db_and() / db_or() / db_xor()  are used to handle nested conditionals such as:->condition(db_or()

->condition('field2', 5) ->condition('field3', 6))

Testing for NULL:$query->isNull('myfield');$query->isNotNull('myfield');

Page 22: Drupal II: The SQL

An example from the field…

Original query:$result = db_query('SELECT * FROM {users} WHERE ((access <> 0 AND login <> 0 AND access < (%d - %d)) OR (login = 0 AND created < (%d - %d))) AND uid <> 1', REQUEST_TIME, $warn_time, REQUEST_TIME, $warn_time);

Page 23: Drupal II: The SQL

Now In dynamic query format

$query = db_select('users', 'u'); $query->fields('u', array('uid', 'name', 'mail', 'created', 'access')) ->condition(db_or() ->condition(db_and() ->condition('u.access', 0, '<>') ->condition('u.login', 0, '<>') ->condition('u.access', REQUEST_TIME - $warn_time, '<')) ->condition(db_and() ->condition('u.login', 0) ->condition('u.created', REQUEST_TIME - $warn_time, '<')) ) ->condition('u.uid', 1, '<>');

$results = $query->execute();

Page 24: Drupal II: The SQL

Subselects

Subselects - form a query using dbtng then instead of executing it -use that query variable in a condition.

Most successful when one value is returned, or a one column return value is used with an IN clause.

$query->condition('myfield', $querysubselect, 'IN');

Page 25: Drupal II: The SQL

JOINS & db_select

<?php$query = db_select('node', 'n');$query->join('field_data_body', 'b', 'n.nid = b.entity_id');$query->fields('n', array('nid', 'title'))->condition('n.type', 'page')->condition('n.status', '1')->orderBy('n.created', 'DESC')->addTag('node_access');?>

Page 26: Drupal II: The SQL

dynamic queries: sorting

orderBy(‘field’, ‘ASC’/’DESC’)

$result = db_select(‘node’, ‘n’) ->fields(‘n’, array(‘title’)) ->orderBy(‘n.created’, ‘DESC’) ->execute();

Page 27: Drupal II: The SQL

db_select Tagging

Tagging – lets alter hooks take action

ex: $query->addTag('node_access');  - this should be implemented on all queries that retrieve nodes.

Node access query alter will then check to see if a user can see the nodes in the result.

(http://druptest7.dev:8888/example_tag)

Page 28: Drupal II: The SQL

What about the others?

db_update, db_insert, db_deleteSimilar syntaxAssemble and execute.

Page 29: Drupal II: The SQL

db_insert

Syntax: $query = db_insert('node', $options);

$nid = db_insert('node')->fields(array(    'title' => ’This Example',    'uid' => 1,    'created' => REQUEST_TIME,))->execute();

db_insert returns the auto-increment value defined by hook_schema.

(http://druptest7.dev:8888/example_insert)

Page 30: Drupal II: The SQL

db_update   

$num_updated = db_update('node')->fields(array(    'uid' => 1))->condition('uid', 2)->execute();

db_update returns the number of records updated.

http://druptest7.dev:8888/example_update

Page 31: Drupal II: The SQL

db_delete

Signature: $query = db_delete('node', $options);

$num_deleted = db_delete('node')->condition('nid', 5)->execute();

db_delete returns the number of rows deleted.http://druptest7.dev:8888/example_delete

Page 32: Drupal II: The SQL

db_select extendersExtenders - implements a decorator pattern, currently only two in core

TableSort and PagerQuery = adds the methods for these extension to query

example:$query = $query->extend('TableSort')->orderByHeader($header);

Put these near the start.Not chainable, if you forget to return it to itself it will have odd results.

http://druptest7.dev:8888/example_extend

Page 33: Drupal II: The SQL

TIME FOR BONUS ROUND

YUB NUB

Page 34: Drupal II: The SQL

What is the ?Now that you have Drupal DB Chops You may start to consider…

To VIEWS ornot toVIEWS

Page 35: Drupal II: The SQL

DB API an Alternative to Views

Who will maintain the functionality?Does it require a lot of custom views code?Are you doing a lot of aggregated data work?Do you need a highly tuned SQL statement for performance?Do you need a lot of user facing, non programmer modifications, will site builders be cloning views or modifying displays?Are you integrating with other modules (panels, voting, etc)?How complex are the changes you need to views default queries/output?

To views or not to views (http://drupal.org/node/242311 )

Page 36: Drupal II: The SQL

Quick case study:

• Client wanted private comments• Client wanted to see a listing of all

comments made against all nodes• Views can do this but it is described as

“hacky” • Created a db_select with pager and table

extenders

Page 37: Drupal II: The SQL

Questions and Thank you!

David Diers, DeveloperFour [email protected]

D.O - thebruce@beautyhammer

Page 38: Drupal II: The SQL

Recommended