From 04cd6ba570f479d258ba927b96e3c823aab15dfa Mon Sep 17 00:00:00 2001
From: Sascha Grossenbacher <saschagros@gmail.com>
Date: Mon, 21 Mar 2011 22:31:07 +0100
Subject: [PATCH] Issue #1097286 by Berdir: Fixed outdated query builder documentation.

---
 privatemsg.api.php |  205 ++++++++++++++++------------------------------------
 privatemsg.module  |   28 +++++++
 2 files changed, 92 insertions(+), 141 deletions(-)

diff --git a/privatemsg.api.php b/privatemsg.api.php
index 46998cf..ea67436 100644
--- a/privatemsg.api.php
+++ b/privatemsg.api.php
@@ -20,90 +20,16 @@
 
 /**
  * @defgroup sql Query Builder
- * Privatemsg does use its own simple query builder which allows to extend
- * SELECT-Queries in an easy way. The function _privatemsg_assemble_query
- * creates the query, based on an array $fragments with the following content.
- * Except primary_table, each key is an array itself to allow multiple values
- *
- *  - primary_table: The main table to select from
- *  - select: The fields that should be selected. This can be a simple field, a
- *    field with alias or even a subquery.
- *  - inner_join: The tables that should be joined. This is not specific to
- *    inner joins.
- *    Example: INNER JOIN pm_index pmi ON (pmi.mid = pm.mid)
- *  - where: The where conditions. The conditions are always AND, but it is
- *    possible to use OR inside a condition.
- *    Example: ⁽pmi.is_new = 1 OR pmi.deleted = 1)
- *  - order_by: Order By values, example: pm.timestamp ASC
- *  - query_args: It is possible to use the placeholders like %s in each part of
- *    the query. The values of query_args are then inserted into these.
- *    query_args consists of three arrays (join, where, having), one for each
- *    key that currently supports arguments.
- *
- * Use _privatemsg_assemble_query
- *
- * The privatemsg_assemble_query function takes a query_id as first argument
- * and optionally one or multiple arguments. query_id can either be a
- * string ('some_id') or an array('group_name', 'query_id'), if a string
- * is supplied, group_name defaults to 'privatemsg'. Returned is an array
- * with the keys 'query' (normal query) and 'count' (count query for pager).
- *
- * For the actual query data, the function group_name_sql_query_id is executed,
- * this functions does have $fragments as first parameter and then the
- * optional parameters.
- *
- * A short example:
- * @code
- * // First, create the sql function.
- * function privatemsg_sql_getsubject(&$fragments, $mid, $uid) {
- *   // Set the primary table.
- *   $fragments['primary_table'] = '{pm_message} pm';
- *
- *   // Add a field.
- *   $fragments['select'][] = 'pm.subject';
- *
- *   // Join another table
- *   $fragment['inner_join'][] = 'INNER JOIN {pm_index} pi ON (pi.mid = pm.mid AND pi.uid = %d)';
- *   $fragment['query_args']['join'][] $uid;
- *
- *   // And finally add a condition.
- *   $fragments['where'][] = 'pm.mid = %d';
- *   $fragments['query_args']['where'][] = $mid;
- * }
- *
- * // Now we can use that query everywhere.
- * $query = _privatemsg_assemble_query('getsubject', 5);
- * $result = db_query($query['query']);
- * @endcode
- * Extend existing queries
  *
- * To extend a privatemsg query, use hook_group_name_sql_query_id_alter.
- * This hook does use the same parameters as the sql function.
+ * Query builder and related hooks
  *
- * Example:
- * @code
- * function mymodule_privatemsg_sql_getsubject_alter(&$fragments, $mid) {
- * // we want to load the body too..
- *  $fragments['select'][] = 'pm.body';
- * }
- * @endcode
+ * Privatemsg uses SelectQuery combined with custom tags to allow to customize
+ * almost all SELECT queries. For more information about SelectQuery, see
+ * http://drupal.org/developing/api/database and http://drupal.org/node/310075.
  *
- * - List of sql query hooks.
- *  - list: List of messages, Parameters: $fragments, $accounty
- *  - list_sent: List of sent messages, Parameters: $fragments, $accounty
- *  - load: Load a single message, Parameters: $fragments, $pmid, $account
- *  - messages: Load the messages of a thread,
- *    Parameters: $fragments, $thread_id, $account
- *  - autocomplete: Searching usernames for the autocomplete feature,
- *    Parameters: $fragments, $search, $names
- *  - participants: Loads all participants of a thread,
- *    Parameters: $fragments, $thread_id
- *  - unread_count: Number of unread messages for a user,
- *    Parameters: $fragments, $account
+ * Arguments to a given query is stored in the metadata, with numerical keys
+ * (arg_%d) according to the position of the argument.
  *
- * - The following query_id's are used in pm_block_user
- *  - threadautors: Return all authors of one or multiple threads,
- *    Parameters: $fragments, $threads
  */
 
 /**
@@ -114,94 +40,91 @@
 /**
  * Query to search for autocomplete usernames.
  *
- * @param $fragments
- *   Query fragments
- * @param $search
- *   Search for that username
- * @param $names
- *   Names that are already in the list and are excluded
+ * @param $query
+ *   Query object
+ *
+ * @see privatemsg_sql_autocomplete().
+ * @see hook_query_alter()
  */
-function hook_privatemsg_sql_autocomplete_alter(&$fragments, $search, $names) {
+function hook_query_privatemsg_autocomplete_alter($query) {
   global $user;
-  // Extend the query that searches for usernames
 
-  // $fragments is explained in the api documentation in detail
+  $search = $query->getMetaData('arg_1');
+  $names = $query->getMetaData('arg_2');
 
-  // The query is already set up, it's searching for usernames which start with
-  // $search and are not $names (may be empty)
-  // the main table is {user} a
-
-  // for example, add a join on a table where the user connections are stored
+  // For example, add a join on a table where the user connections are stored
   // and specify that only users connected with the current user should be
   // loaded.
-  $fragments['inner_join'] = 'INNER JOIN {my_table} m ON (m.user1 = u.uid AND m.user2 = %d)';
-  $fragments['query_args'][] = $user->uid;
+  $query->innerJoin('my_table', 'm', 'm.user1 = u.uid AND m.user2 = :user2', array(':user2' => $user->uid));
 }
 
 /**
  * Display a list of threads.
  *
- * @param $fragments
- *   Query fragments
- * @param $account
- *   User object
- */
-function hook_privatemsg_sql_list_alter(&$fragment, $account) {
-
-}
-
-/**
- * Query definition to load a message.
+ * @param $query
+ *   Query object
  *
- * @param $fragments
- *   Query fragments array
- * @param $pmid
- *   the id of the message
- * @param $account
- *   User object of account for which to load the message
+ * @see privatemsg_sql_list()
+ * @see hook_query_alter()
  */
-function hook_privatemsg_sql_load_alter(&$fragment, $pmid, $account = NULL) {
-
+function hook_query_privatemsg_sql_list_alter($query) {
+  $account = $query->getMetaData('arg_1');
 }
+
 /**
  * Query definition to load messages of one or multiple threads.
  *
- * @param $fragments
- *   Query fragments array.
- * @param $threads
- *   Array with one or multiple thread id's.
- * @param $account
- *   User object for which the messages are being loaded.
- * @param $load_all
- *   Deleted messages are only loaded if this is set to TRUE.
+ * @param $query
+ *   Query object
+ *
+ * @see privatemsg_sql_messages()
+ * @see hook_query_alter()
  */
-function hook_privatemsg_sql_messages_alter(&$fragment, $threads, $account = NULL, $load_all = FALSE) {
-
+function hook_query_privatemsg_messages_alter($query) {
+  $threads = $query->getMetaData('arg_1');
+  $account = $query->getMetaData('arg_2');
+  $load_all = $query->getMetaData('arg_3');
 }
 
 /**
  * Alter the query that loads the participants of a thread.
  *
- * @param $fragments
- *   Query fragments
- * @param $thread_id
- *   Thread id, pmi.thread_id is the same as the mid of the first
- *   message of that thread
+ * @param $query
+ *   Query object
+ *
+ * @see privatemsg_sql_participants()
+ * @see hook_query_alter()
  */
-function hook_privatemsg_sql_participants_alter(&$fragment, $thread_id) {
-
+function hook_query_privatemsg_participants_alter($query) {
+  $thread_id = $query->getMetaData('arg_1');
+  $account = $query->getMetaData('arg_2');
 }
 
 /**
  * Loads all unread messages of a user (only the count query is used).
  *
- * @param $fragments
- *   Query fragments
- * @param $account
- *   User object
+ * @param $query
+ *   Query object
+ *
+ * @see privatemsg_sql_unread_count()
+ * @see hook_query_alter()
  */
-function hook_privatemsg_sql_unread_count_alter(&$fragment, $account) {
+function hook_query_privatemsg_unread_count_alter($query) {
+  $account = $query->getMetaData('arg_1');
+}
 
+/**
+ * Alter the query that loads deleted messages to flush them.
+ *
+ * @param $query
+ *   Query object
+ *
+ * @see privatemsg_sql_deleted()
+ * @see hook_query_alter()
+ */
+function hook_query_privatemsg_deleted_alter($query) {
+  $days = $query->getMetaData('arg_1');
+  $max = $query->getMetaData('arg_2');
 }
 
 /**
diff --git a/privatemsg.module b/privatemsg.module
index e3aad10..3395810 100644
--- a/privatemsg.module
+++ b/privatemsg.module
@@ -980,6 +980,8 @@ function privatemsg_privatemsg_name_lookup($string) {
  *  User object for which the messages are being loaded.
  * @param $argument
  *  string argument which can be used in the query builder to modify the thread listing.
+ *
+ * @see hook_query_privatemsg_list_alter().
  */
 function privatemsg_sql_list($account, $argument = 'list') {
   $query = db_select('pm_message', 'pm')->extend('TableSort')->extend('PagerDefault');
@@ -1044,6 +1046,8 @@ function privatemsg_sql_list($account, $argument = 'list') {
  *   User object for which the messages are being loaded.
  * @param $load_all
  *   Deleted messages are only loaded if this is set to TRUE.
+ *
+ * @see hook_query_privatemsg_messages_alter().
  */
 function privatemsg_sql_messages($threads, $account = NULL, $load_all = FALSE) {
   $query = db_select('pm_index', 'pmi');
@@ -1076,6 +1080,10 @@ function privatemsg_sql_messages($threads, $account = NULL, $load_all = FALSE) {
  *
  * @param $thread_id
  *   Thread id from which the participants should be loaded.
+ * @param $account
+ *   User account that should be considered when loading participants.
+ *
+ * @see hook_query_privatemsg_participants_alter().
  */
 function privatemsg_sql_participants($thread_id, $account = NULL) {
   $query = db_select('pm_index', 'pmi');
@@ -1108,6 +1116,14 @@ function privatemsg_sql_participants($thread_id, $account = NULL) {
     ->groupBy('pmi.type');
 }
 
+/**
+ * Count threads with unread messages.
+ *
+ * @param $account
+ *   User account for which should be checked.
+ *
+ * @see hook_query_privatemsg_unread_count_alter().
+ */
 function privatemsg_sql_unread_count($account) {
   $query = db_select('pm_index', 'pmi');
   $query->addExpression('COUNT(DISTINCT thread_id)', 'unread_count');
@@ -1118,6 +1134,16 @@ function privatemsg_sql_unread_count($account) {
     ->condition('pmi.type', array('hidden', 'user'));
 }
 
+/**
+ * Looks up autocomplete suggestions for users.
+ *
+ * @param $search
+ *   The string that is being searched for.
+ * @param $names
+ *   Array of names which are already selected and should be excluded.
+ *
+ * @see hook_query_privatemsg_autocomplete_alter().
+ */
 function privatemsg_sql_autocomplete($search, $names) {
   $query = db_select('users', 'u')
     ->fields('u', array('uid'))
@@ -1140,6 +1166,8 @@ function privatemsg_sql_autocomplete($search, $names) {
  *   Select messages older than x days.
  * @param $max
  *   Select no more than $max messages.
+ *
+ * @see hook_query_privatemsg_deleted_alter().
  */
 function privatemsg_sql_deleted($days, $max) {
   $query = db_select('pm_message', 'pm');
-- 
1.7.4.1

