=== modified file 'includes/common.inc' --- includes/common.inc 2009-02-28 07:36:06 +0000 +++ includes/common.inc 2009-03-04 20:13:57 +0000 @@ -2980,6 +2980,7 @@ function _drupal_bootstrap_full() { require_once DRUPAL_ROOT . '/includes/form.inc'; require_once DRUPAL_ROOT . '/includes/mail.inc'; require_once DRUPAL_ROOT . '/includes/actions.inc'; + require_once DRUPAL_ROOT . '/includes/queue.inc'; // Set the Drupal custom error handler. set_error_handler('_drupal_error_handler'); set_exception_handler('_drupal_exception_handler'); @@ -3269,7 +3270,7 @@ function drupal_render_page($page) { * * Recursively iterates over each of the array elements, generating HTML code. * - * HTML generation is controlled by two properties containing theme functions, + * HTML generation is controlled by two properties containing theme functions, * #theme and #theme_wrapper. * * #theme is the theme function called first. If it is set and the element has any @@ -3280,13 +3281,13 @@ function drupal_render_page($page) { * * The theme function in #theme_wrapper will be called after #theme has run. It * can be used to add further markup around the rendered children, e.g. fieldsets - * add the required markup for a fieldset around their rendered child elements. + * add the required markup for a fieldset around their rendered child elements. * A wrapper theme function always has to include the element's #children property - * in its output, as this contains the rendered children. + * in its output, as this contains the rendered children. * * For example, for the form element type, by default only the #theme_wrapper * property is set, which adds the form markup around the rendered child elements - * of the form. This allows you to set the #theme property on a specific form to + * of the form. This allows you to set the #theme property on a specific form to * a custom theme function, giving you complete control over the placement of the * form's children while not at all having to deal with the form markup itself. * @@ -3320,7 +3321,7 @@ function drupal_render(&$elements) { else { $elements += element_basic_defaults(); } - + // If #markup is not empty and no theme function is set, use theme_markup. // This allows to specify just #markup on an element without setting the #type. if (!empty($elements['#markup']) && empty($elements['#theme'])) { === modified file 'includes/database/mysql/schema.inc' --- includes/database/mysql/schema.inc 2009-01-26 14:08:40 +0000 +++ includes/database/mysql/schema.inc 2009-03-04 16:50:22 +0000 @@ -49,9 +49,11 @@ class DatabaseSchema_mysql extends Datab * An array of SQL statements to create the table. */ protected function createTableSql($name, $table) { - if (empty($table['mysql_suffix'])) { - $table['mysql_suffix'] = "/*!40100 DEFAULT CHARACTER SET UTF8 */"; - } + // Provide some defaults if needed + $table += array( + 'mysql_engine' => 'ENGINE=InnoDB ', + 'mysql_suffix' => '', + ); $sql = "CREATE TABLE {" . $name . "} (\n"; @@ -69,7 +71,7 @@ class DatabaseSchema_mysql extends Datab // Remove the last comma and space. $sql = substr($sql, 0, -3) . "\n) "; - $sql .= $table['mysql_suffix']; + $sql .= $table['mysql_engine'] . $table['mysql_suffix']; return array($sql); } === added directory 'modules/queue' === added file 'modules/queue/queue.info' --- modules/queue/queue.info 1970-01-01 00:00:00 +0000 +++ modules/queue/queue.info 2009-03-04 20:17:32 +0000 @@ -0,0 +1,9 @@ +; $Id$ + +name = Queue +description = Default queue implementation +package = Core +version = VERSION +core = 7.x +files[] = queue.module +files[] = queue.install === added file 'modules/queue/queue.install' --- modules/queue/queue.install 1970-01-01 00:00:00 +0000 +++ modules/queue/queue.install 2009-03-04 20:58:43 +0000 @@ -0,0 +1,72 @@ + 'Stores items in queues.', + 'fields' => array( + 'item_id' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'description' => 'Primary Key: Unique item ID.', + ), + 'queue_name' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The queue name.', + ), + 'status' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + 'description' => 'The item status.', + ), + 'process_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The ID of the processing.', + ), + 'data' => array( + 'type' => 'text', + 'not null' => FALSE, + 'size' => 'big', + 'serialize' => TRUE, + 'description' => 'The item itself.', + ), + 'timestamp' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The time processing started.', + ), + ), + 'primary key' => array('item_id'), + 'indexes' => array( + 'sqp' => array('status', 'queue_name', 'process_id'), + ), + ); + + $schema['queue_process_id'] = array( + 'description' => 'Stores queue process IDs, used to auto-incrament the process ID so that a unique process ID is used.', + 'fields' => array( + 'process_id' => array( + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique process ID used to make sure only one consumer gets one item.', + ), + ), + 'primary key' => array('process_id'), + ); + return $schema; +} \ No newline at end of file === added file 'modules/queue/queue.module' --- modules/queue/queue.module 1970-01-01 00:00:00 +0000 +++ modules/queue/queue.module 2009-03-04 21:02:52 +0000 @@ -0,0 +1,51 @@ +queue_name = $queue_name; + } + + function queue($item) { + $record->queue_name = $this->queue_name; + $record->status = QUEUE_NEEDS_PROCESSING; + $record->data = $item; + $record->process_id = 0; + return drupal_write_record('queue', $record); + } + + function dequeue($timeout = 30) { + if (!isset($this->process_id)) { + $this->process_id = db_insert('queue_process_id')->useDefaults(array('process_id'))->execute(); + } + $start = time(); + $item = FALSE; + $statement = db_select('queue', 'q'); + $statement->addField('q', 'item_id'); + $statement->condition('status', QUEUE_NEEDS_PROCESSING); + $statement->condition('queue_name', $this->queue_name); + $statement->range(0, 1); + do { + $item_id = $statement->execute()->fetchField(); + if ($item_id) { + db_update('queue')->fields(array('status' => QUEUE_UNDER_PROCESSING, 'process_id' => $this->process_id, 'timestamp' => time()))->condition('item_id', $item_id)->execute(); + $item = db_query('SELECT data, item_id FROM {queue} WHERE status = :status AND queue_name = :queue_name AND process_id = :process_id AND item_id = :item_id', array('status' => QUEUE_UNDER_PROCESSING, 'queue_name' => $this->queue_name, 'process_id' => $this->process_id, 'item_id' => $item_id))->fetchObject(); + } + else { + sleep(1); + } + } while (!$item && time() - $start < $timeout); + if ($item) { + $item->data = unserialize($item->data); + return $item; + } + } + + function finish($item) { + $item->status = QUEUE_DONE; + return drupal_write_record('queue', $item); + } +} === added file 'modules/queue/queue.test' --- modules/queue/queue.test 1970-01-01 00:00:00 +0000 +++ modules/queue/queue.test 2009-03-04 21:54:54 +0000 @@ -0,0 +1,50 @@ + t('Queue functionality'), + 'description' => t('Queues and dequeues an item.'), + 'group' => t('Queue') + ); + } + + function setUp() { + return parent::setUp('queue'); + } + + function testQueue() { + $queue1 = $this->randomName(); + $queue2 = $this->randomName(); + $items = array(); + for ($i = 0; $i < 4; $i++) { + $items[] = array($this->randomName() => $this->randomName()); + } + queue_queue($queue1, $items[0]); + queue_queue($queue1, $items[1]); + $new_items[] = queue_dequeue($queue1)->data; + $new_items[] = queue_dequeue($queue1)->data; + // Two dequeued items should match the two items we queued. + $this->assertEqual($this->score($items, $new_items), 2, t('Two items matched')); + queue_queue($queue1, $items[2]); + queue_queue($queue1, $items[3]); + $new_items[] = queue_dequeue($queue1)->data; + $new_items[] = queue_dequeue($queue1)->data; + // All dequeued items should match the items we queued. + $this->assertEqual($this->score($items, $new_items), 4, t('Four items matched')); + // There should not be equal dequeued items. + $this->assertEqual($this->score($new_items, $new_items), 4, t('Four items matched')); + } + + function score($items, $new_items) { + $score = 0; + foreach ($items as $item) { + foreach ($new_items as $new_item) { + if ($item === $new_item) { + $score++; + } + } + } + return $score; + } +}