SlideShare ist ein Scribd-Unternehmen logo
1 von 44
Drupal 7: DBTNG
DBTNG?

Databases:
Databases: The next generation
 A brand new database layer for drupal7
 Support for MySQL, PostgreSQL, SQL Lite
 Add-on drivers can be made
Basic Queries
Basic Queries
 Most SELECT queries are simple and
  don’t change
 Drupal calls these: static queries



 $result = db_query("SELECT name, filename FROM {system} WHERE
 type = :type AND status = :status", array(':type' => 'module', ':status' => 1));
Basic Queries
 Table names  wrapped in curly braces
 No database-specific syntax in the query.
 There are no literal values in the query.
  Instead, literal values are specified by
  placeholders.
Placeholders
 Must be unique within a query, and must
  begin with a colon.
 Should never have quotation marks
  around them, regardless of the data type.
  The database server will handle that for
  us.
 Should be used for all literal data, even if it
  will not vary.
Result Object
 The return value from a db_query() call is a
  result object.


$list = array();
foreach ($result as $record) {
      $list[] = t('@name: @filename', array(
            '@name' => $record->name,
            '@filename' => $record->filename,
            ));
}
Result as array
 By default, each $record in the result set is
  a stdClass object.
 This is how you get an array:


$result = db_query("SELECT name, filename FROM {system} WHERE type =
:type AND status = :status", array(':type' => 'module', ':status' => 1), array('fetch'
=> PDO::FETCH_ASSOC));
Fetch option
 We can also fetch a single record, or even
  just a single field:

// Fetch a single record as an object.
$record = $result->fetchObject();

// Fetch a single record as an array.
$record = $result->fetchAssoc();

// Fetch just the first field of the next record.
$field = $result->fetchField();

// Fetch the entire result set at once into an array.
$records = $result->fetchAll()
Dynamic Queries
Dynamic Queries
 To start, we create a new query object with
  db_select():

$query = db_select('node', 'n');




 The first parameter is the name of the
  base table of the query and the second is
  the alias.
Dynamic Queries
     We then call additional methods on the
      $query object in order to build up the
      query logic we want to create dynamically
$query = db_select('node', 'n');
$query->fields('n', array('nid, title'));
$u_alias = $query->innerJoin('users' ,'u', '%alias.uid = n.uid');
$query->addField($u_alias, 'name', 'username');
$query->condition("{$u_alias}.name", 'Bob');
$query->condition('n.created', REQUEST_TIME - 604800, '>=');
$query->orderBy('n.created', 'DESC');
$query->range(0, 5);
$query->addTag('node_access');
$result = $query->execute();
Dynamic Queries
 The resulting query


SELECT n.nid AS nid, n.title AS title, u.name AS username
FROM {node} n
INNER JOIN {users} u ON u.nid = n.nid
WHERE (n.created >= 1286213869)
 AND (u.name = 'Bob')
ORDER BY n.created DESC
LIMIT 5 OFFSET 0
Dynamic Queries
 There's one more important method to call
  —addTag().
 It does mark the type of query it is
 If a query has been tagged then before it
  is turned into an SQL string it will be
  passed through hook_query_alter() and
  hook_query_TAG_alter().
Dynamic Queries
 The node_access tag, is most important
  as it allows the node access system to
  alter the query, to filter out nodes that the
  current user should not have access to.
Dynamic Queries
     Most methods of the select builder return the
       select object itself and thus are chainable.
     The exceptions are the addField() and join()
       methods, as those need to return a generated
       alias instead.'n');
$query = db_select('node',
$u_alias = $query->innerJoin('users' ,'u', '%alias.uid = n.uid'); $query-
>addField($u_alias, 'name', 'username');
$result = $query
    ->fields('n', array('nid, title'));
    ->condition("{$u_alias}.name", 'Bob');
    ->condition('n.created', REQUEST_TIME - 604800, '>=');
    ->orderBy('n.created', 'DESC');
    ->range(0, 5);
    ->addTag('node_access')
    ->execute();
Dynamic Queries
 SELECT queries have both static and
  dynamic versions
 INSERT, UPDATE, DELETE, and MERGE
  queries only support a dynamic version
Insert
Insert
 all methods of Insert queries are
  chainable.

$id = db_insert('imports')
     ->fields(array(
          'name' => 'Groucho',
          'address' => '123 Casablanca Ave.',
          'phone' => '555-1212',
          ))
     ->execute();
Insert
 it supports multi-insert statements
$values[] = array(
     'name' => 'Groucho',
     'address' => '123 Casablanca Ave.',
     'phone' => '555-1212',
);
$values[] = array(
     'name' => 'Chico',
     'address' => '456 Races St.',
     'phone' => '555-1234',
);
$values[] = array(
     'name' => 'Harpo',
     'address' => '789 Horn Ave.',
     'phone' => '555-1234',
);
$values[] = array(
     'name' => 'Zeppo',
     'address' => '22 University Way',
     'phone' => '555-3579',
);
Insert
 it supports multi-insert statements

$insert = db_insert('imports')
     ->fields(array('name', 'address', 'phone' => '555-1212'));

foreach ($values as $value) {
     $insert->values($value);
}

$insert->execute();
Insert
 On databases that support multi-insert
  statements, the preceding code will be run
  as a single query. For those that don't,
  they will run as separate queries within a
  single transaction.
 Note that in a multi-insert query the return
  value from execute() is undefined and
  should be ignored.
Update
Update
 Update queries look like a hybrid of Insert
  and Select statements.
 consist of both fields to set on a table and
  conditions to restrict the query.
db_update('imports')
    ->condition('name', 'Chico')
    ->fields(array('address' => 'Go West St.'))
    ->execute();

 Resulting query:
UPDATE {imports} SET address = 'Go West St.' WHERE name = 'Chico';
Update
 Return value from execute() for Update
  queries = number of records that were
  changed.
 'changed' does not mean 'matched'.
 If the WHERE portion of the query
  matches a record but if that record already
  has the values that it would be set to, it will
  not be changed and would not count
  towards the return value from execute().
Delete
Delete
 Delete queries should come as no
  surprise, as they consist of essentially just
  a WHERE clause:
db_delete('imports')
    ->condition('name' => 'Zeppo')
    ->execute();



 Return value from execute() = number of
  records that were deleted by the query.
Merge
Merge
 one of the oft-forgotten parts of SQL
 the most popular open source databases
  do not support them directly
 "If this record exists, update it with this
  query otherwise create it with this other
  query"
 It is most useful for setting records that
  may or may not exist yet, that is, merging
  data into the table.
Merge
 A true merge query is atomic = we're
  guaranteed that it will run as a single
  uninterrupted operation or fail completely.
 Since most of the databases Drupal works
  with do not directly support Merge queries,
  Drupal emulates them with multiple
  queries and a transaction, which in most
  cases is close enough.
Merge

db_merge('variable')
   ->key(array('name' => $name))
   ->fields(array('value' => serialize($value)))
   ->execute();


 The key() method takes an associative
  array of field/value pairs that are the pivot
  of the query.
 The fields() method is about the fields to
  set
Merge
 The query can be read as:
 "If there is a record where the field 'name'
  has the value $name, set the 'value' field.
  If not, insert a new record with name equal
  to $name and value equal to the given
  string.”
Merge
 We can also define more complex logic
   using the insertFields() and updateFields()
   methods.
db_merge('people')
  ->key(array('job' => 'Speaker'))
  ->insertFields(array(
       'age' => 31,
       'name' => 'Meredith',
  ))
  ->updateFields(array( 'name' => 'Tiffany',
  ))
  ->execute();
Advanced subjects
Transactions
 A transaction in a database is a way to wrap
  two or more queries together and declare that
  they should be atomic.
 That is, either all succeed or none succeed.
 We start a transaction by creating a
  transaction object.
 Everything we do to the database is then part
  of the transaction until that object is
  destroyed, at which point the entire query is
  committed at once.
 In most cases, we let PHP destroy the
  transaction object for us when a function
  ends.
Transactions

function my_function() {
    $transaction = db_transaction();
    try {
          $id = db_insert('example')
               ->fields(array(
                    'field1' => 'mystring',
                    'field2' => 5, ))
               ->execute();
          my_other_function($id);
          return $id;
    } catch (Exception $e) {
          $transaction->rollback();
          watchdog_exception('type', $e);
    }
}
Slave servers
 Drupal also supports Master/slave
  database replication
 select queries can be run against a slave
  server to offload the work to separate
  servers
 The third parameter to db_query() or
  db_select() is an array of options that
  tweak the behavior of the query.
Slave servers
 The key of interest = target
 It specifies which database variant the
  system should try.
 Legal values: default (which is the default)
  and slave.
 If "slave" is specified, Drupal will try to run
  the query against a slave server. If one is
  not available, it will silently fall back to the
  default server.
Slave servers

$result = db_query("SELECT name, filename FROM {system} WHERE type =
:type AND status = :status", array(':type' => 'module', ':status' => 1), array('fetch'
=> PDO::FETCH_ASSOC, 'target' => 'slave'));
Slave servers
 Data on a slave server is always a little
  behind the master server
 Not all Select queries can handle their
  data being slightly stale
 After writing data, we can call
  db_ignore_slave().
 It will make a note in the active session to
  disable the slave server for the current
  user only for a configurable period of time.
  (The default is five minutes.)
Simplify code
 Especially for modules creating their own
  API
 They need their own query builder
 Example: Voting API
Drupal 6: 96 code lines                                                                                    Drupal 7: 16 code lines
<?php
/**
* Select individual votes from the database.
                                                                                                           <?php
*/
function votingapi_select_votes($criteria = array(), $limit = 0) {                                         function votingapi_select_votes($criteria = array(), $limit = 0) {
  $anon_window = variable_get('votingapi_anonymous_window', 3600);
  if (!empty($criteria['vote_source']) && $anon_window > 0) {
    $criteria['timestamp'] = time() - $anon_window;
                                                                                                             $anon_window = variable_get('votingapi_anonymous_window', 3600);
  }
  $votes = array();                                                                                          if (!empty($criteria['vote_source']) && $anon_window >= 0) {
  $result = _votingapi_select('vote', $criteria, $limit);
  while ($vote = db_fetch_array($result)) {
    $votes[] = $vote;
                                                                                                               $criteria['timestamp'] = REQUEST_TIME - $anon_window;
  }
  return $votes;                                                                                             }
}

/**
                                                                                                             $query = db_select('votingapi_vote')->fields('votingapi_vote');
* Internal helper function constructs WHERE clauses. Don't use unless you're me.
*/                                                                                                           foreach ($criteria as $key => $value) {
function _votingapi_query($table = 'vote', $criteria = array(), $alias = 'v.') {
  $criteria += array(
    'vote_id' => NULL,
                                                                                                               $query->condition($key, $value, is_array($value) ? 'IN' : '=');
    'vote_cache_id' => NULL,
    'content_id' => NULL,                                                                                    }
    'content_type' => NULL,
    'value_type' => NULL,
    'value' => NULL,
                                                                                                             if (!empty($limit)) {
    'tag' => NULL,
    'uid' => NULL,                                                                                             $query->range(0, $limit);
    'timestamp' => NULL,
    'vote_source' => NULL,
    'function' => NULL,
                                                                                                             }
  );
                                                                                                             return $query->execute()->fetchAll(PDO::FETCH_ASSOC);
    $query = '';
    $args = array();
    if (!empty($criteria['vote_id'])) {
                                                                                                           }
    }
      _votingapi_query_builder($alias . 'vote_id', $criteria['vote_id'], $query, $args);
                                                                                                           ?>
    elseif (!empty($criteria['vote_cache_id'])) {
      _votingapi_query_builder($alias . 'vote_cache_id', $criteria['vote_cache_id'], $query, $args);
    }
    else {
      _votingapi_query_builder($alias . 'content_type', $criteria['content_type'], $query, $args, TRUE);
      _votingapi_query_builder($alias . 'content_id', $criteria['content_id'], $query, $args);
      _votingapi_query_builder($alias . 'value_type', $criteria['value_type'], $query, $args, TRUE);
      _votingapi_query_builder($alias . 'tag', $criteria['tag'], $query, $args, TRUE);
      _votingapi_query_builder($alias . 'function', $criteria['function'], $query, $args, TRUE);
      _votingapi_query_builder($alias . 'uid', $criteria['uid'], $query, $args);
      _votingapi_query_builder($alias . 'vote_source', $criteria['vote_source'], $query, $args, TRUE);
      _votingapi_query_builder($alias . 'timestamp', $criteria['timestamp'], $query, $args);
    }
    return array('query' => $query, 'args' => $args);
}

/**
* Internal helper function constructs individual elements of WHERE clauses.
* Don't use unless you're me.
*/
function _votingapi_query_builder($name, $value, &$query, &$args, $col_is_string = FALSE) {
  if (!isset($value)) {
    // Do nothing
  }
  elseif ($name === 'timestamp') {
    $query .= " AND timestamp >= %d";
    $args[] = $value;
  }
  elseif ($name === 'v.timestamp') {
    $query .= " AND v.timestamp >= %d";
    $args[] = $value;
  }
  else {
    if (is_array($value)) {
      if ($col_is_string) {
        $query .= " AND $name IN (" . db_placeholders($value, 'varchar') . ")";
        $args = array_merge($args, $value);
      }
      else {
        $query .= " AND $name IN (" . db_placeholders($value, 'int') . ")";
        $args = array_merge($args, $value);
      }
    }
    else {
      if ($col_is_string) {
        $query .= " AND $name = '%s'";
        $args[] = $value;
      }
      else {
        $query .= " AND $name = %d";
        $args[] = $value;
      }
    }
  }
}
?>
See you in another Galaxy

Weitere ähnliche Inhalte

Was ist angesagt?

Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Fabien Potencier
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Editionddiers
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm OldRoss Tuck
 
A Tour to MySQL Commands
A Tour to MySQL CommandsA Tour to MySQL Commands
A Tour to MySQL CommandsHikmat Dhamee
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsPierre MARTIN
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF Luc Bors
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks Damien Seguy
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of LithiumNate Abele
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 

Was ist angesagt? (20)

Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
How te bring common UI patterns to ADF
How te bring common UI patterns to ADFHow te bring common UI patterns to ADF
How te bring common UI patterns to ADF
 
Things I Believe Now That I'm Old
Things I Believe Now That I'm OldThings I Believe Now That I'm Old
Things I Believe Now That I'm Old
 
A Tour to MySQL Commands
A Tour to MySQL CommandsA Tour to MySQL Commands
A Tour to MySQL Commands
 
Internationalizing CakePHP Applications
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
 
Agile database access with CakePHP 3
Agile database access with CakePHP 3Agile database access with CakePHP 3
Agile database access with CakePHP 3
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
 
Laravel
LaravelLaravel
Laravel
 
Quebec pdo
Quebec pdoQuebec pdo
Quebec pdo
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks
 
Oops in php
Oops in phpOops in php
Oops in php
 
The State of Lithium
The State of LithiumThe State of Lithium
The State of Lithium
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 

Ähnlich wie Drupal7 dbtng

DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7chuvainc
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
CodeIgniter Class Reference
CodeIgniter Class ReferenceCodeIgniter Class Reference
CodeIgniter Class ReferenceJamshid Hashimi
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutesBarang CK
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
Difference between mysql_fetch_array and mysql_fetch_assoc in PHPDifference between mysql_fetch_array and mysql_fetch_assoc in PHP
Difference between mysql_fetch_array and mysql_fetch_assoc in PHPVineet Kumar Saini
 
Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0Eyal Vardi
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128PrinceGuru MS
 
テストデータどうしてますか?
テストデータどうしてますか?テストデータどうしてますか?
テストデータどうしてますか?Yuki Shibazaki
 
Ex[1].3 php db connectivity
Ex[1].3 php db connectivityEx[1].3 php db connectivity
Ex[1].3 php db connectivityMouli Chandira
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsDavid Golden
 

Ähnlich wie Drupal7 dbtng (20)

DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Database api
Database apiDatabase api
Database api
 
CodeIgniter Class Reference
CodeIgniter Class ReferenceCodeIgniter Class Reference
CodeIgniter Class Reference
 
laravel tricks in 50minutes
laravel tricks in 50minuteslaravel tricks in 50minutes
laravel tricks in 50minutes
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
php2.pptx
php2.pptxphp2.pptx
php2.pptx
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
Difference between mysql_fetch_array and mysql_fetch_assoc in PHPDifference between mysql_fetch_array and mysql_fetch_assoc in PHP
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
 
Quebec pdo
Quebec pdoQuebec pdo
Quebec pdo
 
Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0Component lifecycle hooks in Angular 2.0
Component lifecycle hooks in Angular 2.0
 
Php tips-and-tricks4128
Php tips-and-tricks4128Php tips-and-tricks4128
Php tips-and-tricks4128
 
テストデータどうしてますか?
テストデータどうしてますか?テストデータどうしてますか?
テストデータどうしてますか?
 
Ex[1].3 php db connectivity
Ex[1].3 php db connectivityEx[1].3 php db connectivity
Ex[1].3 php db connectivity
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 

Kürzlich hochgeladen

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 

Kürzlich hochgeladen (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 

Drupal7 dbtng

  • 3. Databases: The next generation  A brand new database layer for drupal7  Support for MySQL, PostgreSQL, SQL Lite  Add-on drivers can be made
  • 5. Basic Queries  Most SELECT queries are simple and don’t change  Drupal calls these: static queries $result = db_query("SELECT name, filename FROM {system} WHERE type = :type AND status = :status", array(':type' => 'module', ':status' => 1));
  • 6. Basic Queries  Table names  wrapped in curly braces  No database-specific syntax in the query.  There are no literal values in the query. Instead, literal values are specified by placeholders.
  • 7. Placeholders  Must be unique within a query, and must begin with a colon.  Should never have quotation marks around them, regardless of the data type. The database server will handle that for us.  Should be used for all literal data, even if it will not vary.
  • 8. Result Object  The return value from a db_query() call is a result object. $list = array(); foreach ($result as $record) { $list[] = t('@name: @filename', array( '@name' => $record->name, '@filename' => $record->filename, )); }
  • 9. Result as array  By default, each $record in the result set is a stdClass object.  This is how you get an array: $result = db_query("SELECT name, filename FROM {system} WHERE type = :type AND status = :status", array(':type' => 'module', ':status' => 1), array('fetch' => PDO::FETCH_ASSOC));
  • 10. Fetch option  We can also fetch a single record, or even just a single field: // Fetch a single record as an object. $record = $result->fetchObject(); // Fetch a single record as an array. $record = $result->fetchAssoc(); // Fetch just the first field of the next record. $field = $result->fetchField(); // Fetch the entire result set at once into an array. $records = $result->fetchAll()
  • 12. Dynamic Queries  To start, we create a new query object with db_select(): $query = db_select('node', 'n');  The first parameter is the name of the base table of the query and the second is the alias.
  • 13. Dynamic Queries  We then call additional methods on the $query object in order to build up the query logic we want to create dynamically $query = db_select('node', 'n'); $query->fields('n', array('nid, title')); $u_alias = $query->innerJoin('users' ,'u', '%alias.uid = n.uid'); $query->addField($u_alias, 'name', 'username'); $query->condition("{$u_alias}.name", 'Bob'); $query->condition('n.created', REQUEST_TIME - 604800, '>='); $query->orderBy('n.created', 'DESC'); $query->range(0, 5); $query->addTag('node_access'); $result = $query->execute();
  • 14. Dynamic Queries  The resulting query SELECT n.nid AS nid, n.title AS title, u.name AS username FROM {node} n INNER JOIN {users} u ON u.nid = n.nid WHERE (n.created >= 1286213869) AND (u.name = 'Bob') ORDER BY n.created DESC LIMIT 5 OFFSET 0
  • 15. Dynamic Queries  There's one more important method to call —addTag().  It does mark the type of query it is  If a query has been tagged then before it is turned into an SQL string it will be passed through hook_query_alter() and hook_query_TAG_alter().
  • 16. Dynamic Queries  The node_access tag, is most important as it allows the node access system to alter the query, to filter out nodes that the current user should not have access to.
  • 17. Dynamic Queries  Most methods of the select builder return the select object itself and thus are chainable.  The exceptions are the addField() and join() methods, as those need to return a generated alias instead.'n'); $query = db_select('node', $u_alias = $query->innerJoin('users' ,'u', '%alias.uid = n.uid'); $query- >addField($u_alias, 'name', 'username'); $result = $query ->fields('n', array('nid, title')); ->condition("{$u_alias}.name", 'Bob'); ->condition('n.created', REQUEST_TIME - 604800, '>='); ->orderBy('n.created', 'DESC'); ->range(0, 5); ->addTag('node_access') ->execute();
  • 18. Dynamic Queries  SELECT queries have both static and dynamic versions  INSERT, UPDATE, DELETE, and MERGE queries only support a dynamic version
  • 20. Insert  all methods of Insert queries are chainable. $id = db_insert('imports') ->fields(array( 'name' => 'Groucho', 'address' => '123 Casablanca Ave.', 'phone' => '555-1212', )) ->execute();
  • 21. Insert  it supports multi-insert statements $values[] = array( 'name' => 'Groucho', 'address' => '123 Casablanca Ave.', 'phone' => '555-1212', ); $values[] = array( 'name' => 'Chico', 'address' => '456 Races St.', 'phone' => '555-1234', ); $values[] = array( 'name' => 'Harpo', 'address' => '789 Horn Ave.', 'phone' => '555-1234', ); $values[] = array( 'name' => 'Zeppo', 'address' => '22 University Way', 'phone' => '555-3579', );
  • 22. Insert  it supports multi-insert statements $insert = db_insert('imports') ->fields(array('name', 'address', 'phone' => '555-1212')); foreach ($values as $value) { $insert->values($value); } $insert->execute();
  • 23. Insert  On databases that support multi-insert statements, the preceding code will be run as a single query. For those that don't, they will run as separate queries within a single transaction.  Note that in a multi-insert query the return value from execute() is undefined and should be ignored.
  • 25. Update  Update queries look like a hybrid of Insert and Select statements.  consist of both fields to set on a table and conditions to restrict the query. db_update('imports') ->condition('name', 'Chico') ->fields(array('address' => 'Go West St.')) ->execute();  Resulting query: UPDATE {imports} SET address = 'Go West St.' WHERE name = 'Chico';
  • 26. Update  Return value from execute() for Update queries = number of records that were changed.  'changed' does not mean 'matched'.  If the WHERE portion of the query matches a record but if that record already has the values that it would be set to, it will not be changed and would not count towards the return value from execute().
  • 28. Delete  Delete queries should come as no surprise, as they consist of essentially just a WHERE clause: db_delete('imports') ->condition('name' => 'Zeppo') ->execute();  Return value from execute() = number of records that were deleted by the query.
  • 29. Merge
  • 30. Merge  one of the oft-forgotten parts of SQL  the most popular open source databases do not support them directly  "If this record exists, update it with this query otherwise create it with this other query"  It is most useful for setting records that may or may not exist yet, that is, merging data into the table.
  • 31. Merge  A true merge query is atomic = we're guaranteed that it will run as a single uninterrupted operation or fail completely.  Since most of the databases Drupal works with do not directly support Merge queries, Drupal emulates them with multiple queries and a transaction, which in most cases is close enough.
  • 32. Merge db_merge('variable') ->key(array('name' => $name)) ->fields(array('value' => serialize($value))) ->execute();  The key() method takes an associative array of field/value pairs that are the pivot of the query.  The fields() method is about the fields to set
  • 33. Merge  The query can be read as:  "If there is a record where the field 'name' has the value $name, set the 'value' field. If not, insert a new record with name equal to $name and value equal to the given string.”
  • 34. Merge  We can also define more complex logic using the insertFields() and updateFields() methods. db_merge('people') ->key(array('job' => 'Speaker')) ->insertFields(array( 'age' => 31, 'name' => 'Meredith', )) ->updateFields(array( 'name' => 'Tiffany', )) ->execute();
  • 36. Transactions  A transaction in a database is a way to wrap two or more queries together and declare that they should be atomic.  That is, either all succeed or none succeed.  We start a transaction by creating a transaction object.  Everything we do to the database is then part of the transaction until that object is destroyed, at which point the entire query is committed at once.  In most cases, we let PHP destroy the transaction object for us when a function ends.
  • 37. Transactions function my_function() { $transaction = db_transaction(); try { $id = db_insert('example') ->fields(array( 'field1' => 'mystring', 'field2' => 5, )) ->execute(); my_other_function($id); return $id; } catch (Exception $e) { $transaction->rollback(); watchdog_exception('type', $e); } }
  • 38. Slave servers  Drupal also supports Master/slave database replication  select queries can be run against a slave server to offload the work to separate servers  The third parameter to db_query() or db_select() is an array of options that tweak the behavior of the query.
  • 39. Slave servers  The key of interest = target  It specifies which database variant the system should try.  Legal values: default (which is the default) and slave.  If "slave" is specified, Drupal will try to run the query against a slave server. If one is not available, it will silently fall back to the default server.
  • 40. Slave servers $result = db_query("SELECT name, filename FROM {system} WHERE type = :type AND status = :status", array(':type' => 'module', ':status' => 1), array('fetch' => PDO::FETCH_ASSOC, 'target' => 'slave'));
  • 41. Slave servers  Data on a slave server is always a little behind the master server  Not all Select queries can handle their data being slightly stale  After writing data, we can call db_ignore_slave().  It will make a note in the active session to disable the slave server for the current user only for a configurable period of time. (The default is five minutes.)
  • 42. Simplify code  Especially for modules creating their own API  They need their own query builder  Example: Voting API
  • 43. Drupal 6: 96 code lines Drupal 7: 16 code lines <?php /** * Select individual votes from the database. <?php */ function votingapi_select_votes($criteria = array(), $limit = 0) { function votingapi_select_votes($criteria = array(), $limit = 0) { $anon_window = variable_get('votingapi_anonymous_window', 3600); if (!empty($criteria['vote_source']) && $anon_window > 0) { $criteria['timestamp'] = time() - $anon_window; $anon_window = variable_get('votingapi_anonymous_window', 3600); } $votes = array(); if (!empty($criteria['vote_source']) && $anon_window >= 0) { $result = _votingapi_select('vote', $criteria, $limit); while ($vote = db_fetch_array($result)) { $votes[] = $vote; $criteria['timestamp'] = REQUEST_TIME - $anon_window; } return $votes; } } /** $query = db_select('votingapi_vote')->fields('votingapi_vote'); * Internal helper function constructs WHERE clauses. Don't use unless you're me. */ foreach ($criteria as $key => $value) { function _votingapi_query($table = 'vote', $criteria = array(), $alias = 'v.') { $criteria += array( 'vote_id' => NULL, $query->condition($key, $value, is_array($value) ? 'IN' : '='); 'vote_cache_id' => NULL, 'content_id' => NULL, } 'content_type' => NULL, 'value_type' => NULL, 'value' => NULL, if (!empty($limit)) { 'tag' => NULL, 'uid' => NULL, $query->range(0, $limit); 'timestamp' => NULL, 'vote_source' => NULL, 'function' => NULL, } ); return $query->execute()->fetchAll(PDO::FETCH_ASSOC); $query = ''; $args = array(); if (!empty($criteria['vote_id'])) { } } _votingapi_query_builder($alias . 'vote_id', $criteria['vote_id'], $query, $args); ?> elseif (!empty($criteria['vote_cache_id'])) { _votingapi_query_builder($alias . 'vote_cache_id', $criteria['vote_cache_id'], $query, $args); } else { _votingapi_query_builder($alias . 'content_type', $criteria['content_type'], $query, $args, TRUE); _votingapi_query_builder($alias . 'content_id', $criteria['content_id'], $query, $args); _votingapi_query_builder($alias . 'value_type', $criteria['value_type'], $query, $args, TRUE); _votingapi_query_builder($alias . 'tag', $criteria['tag'], $query, $args, TRUE); _votingapi_query_builder($alias . 'function', $criteria['function'], $query, $args, TRUE); _votingapi_query_builder($alias . 'uid', $criteria['uid'], $query, $args); _votingapi_query_builder($alias . 'vote_source', $criteria['vote_source'], $query, $args, TRUE); _votingapi_query_builder($alias . 'timestamp', $criteria['timestamp'], $query, $args); } return array('query' => $query, 'args' => $args); } /** * Internal helper function constructs individual elements of WHERE clauses. * Don't use unless you're me. */ function _votingapi_query_builder($name, $value, &$query, &$args, $col_is_string = FALSE) { if (!isset($value)) { // Do nothing } elseif ($name === 'timestamp') { $query .= " AND timestamp >= %d"; $args[] = $value; } elseif ($name === 'v.timestamp') { $query .= " AND v.timestamp >= %d"; $args[] = $value; } else { if (is_array($value)) { if ($col_is_string) { $query .= " AND $name IN (" . db_placeholders($value, 'varchar') . ")"; $args = array_merge($args, $value); } else { $query .= " AND $name IN (" . db_placeholders($value, 'int') . ")"; $args = array_merge($args, $value); } } else { if ($col_is_string) { $query .= " AND $name = '%s'"; $args[] = $value; } else { $query .= " AND $name = %d"; $args[] = $value; } } } } ?>
  • 44. See you in another Galaxy