Index: uuid.admin.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/uuid/uuid.admin.inc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 uuid.admin.inc
--- uuid.admin.inc	11 Jun 2009 18:07:13 -0000	1.1.2.2
+++ uuid.admin.inc	26 Aug 2009 14:44:23 -0000
@@ -5,65 +5,170 @@
  * Menu callback: options for UUID.
  */
 function uuid_admin() {
-  $form = array();
-
-  $form['content'] = array(
+  $form = array(
+    '#submit' => array('uuid_admin_submit'),
+  );
+  
+  $form['node'] = array(
     '#type' => 'fieldset',
     '#title' => t('Content UUID Settings'),
   );
-  $types = node_get_types('names');
-  $form['content']['uuid_automatic_for_nodes'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Content Types With Automatic UUIDs'),
-    '#default_value' => variable_get('uuid_automatic_for_nodes', array()),
-    '#options' => $types,
-    '#description' => t('Selected content types to have UUIDs automatically generated.'),
-    '#required' => FALSE,
-  );
+  
+  if ($options = node_get_types('names')) {
+    $form['node']['uuid_automatic_for_nodes'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Content types with automatic UUIDs'),
+      '#default_value' => variable_get('uuid_automatic_for_nodes', array()),
+      '#options' => $options,
+      '#description' => t('Selected content types to have UUIDs automatically generated.'),
+      '#required' => FALSE,
+    );
+  } else {
+    $form['node']['uuid_automatic_for_nodes'] = array(
+      '#type' => 'item',
+      '#value' => t('There is currently no content type defined.'),
+    );
+  }
 
   $form['user'] = array(
     '#type' => 'fieldset',
     '#title' => t('User UUID Settings'),
   );
+  
   $form['user']['uuid_automatic_for_users'] = array(
     '#type' => 'checkbox',
-    '#title' => t('Automatic UUIDs For Users?'),
+    '#title' => t('Automatic UUIDs for users?'),
     '#default_value' => variable_get('uuid_automatic_for_users', FALSE),
     '#description' => t('Should UUIDs be created automatically for every existing, and new user?'),
     '#required' => FALSE,
   );
 
-  // TODO: Is this "sync" button really necessary?  Handle this better.
-  $form['settings'] = array(
+  $form['taxonomy'] = array(
     '#type' => 'fieldset',
-    '#title' => t('General Settings'),
-  );
-  $form['settings']['sync'] = array(
-    '#type' => 'submit',
-    '#value' => t('Create Missing UUIDs'),
-    '#submit' => array('uuid_sync'),
-    '#weight' => 10,
-  );
-  $form['settings']['rebuild_help'] = array(
-    '#value' => '<div class="description">' . t("If UUID settings have changed recently some content or users may be missing their UUIDs.") . '</div>',
-    '#weight' => 11,
+    '#title' => t('Taxonomy UUID Settings'),
   );
+  
+  if ($options = array_map(create_function('$voc', 'return $voc->name;'), taxonomy_get_vocabularies())) {
+    $form['taxonomy']['uuid_automatic_for_taxonomy'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Automatic UUIDs for taxonomy'),
+      '#default_value' => variable_get('uuid_automatic_for_taxonomy', array()),
+      '#options' => $options,
+      '#description' => t('Selected vocabularies to have UUIDs automatically generated.'),
+      '#required' => FALSE,
+    );
+  } else {
+    $form['taxonomy']['uuid_automatic_for_taxonomy'] = array(
+      '#type' => 'item',
+      '#value' => t('There is currently no vocabulary defined.'),
+    );
+  }
 
   return system_settings_form($form);
 }
 
+function uuid_admin_submit($form, &$form_state) {
+  $values = $form_state['values'];
+  $types = node_get_types('names');
+  $vocabularies = array_map(create_function('$voc', 'return $voc->name;'), taxonomy_get_vocabularies());
+  
+  // Nodes
+  $uuid_nodes = array_filter($form_state['values']['uuid_automatic_for_nodes']);
+  $uuid_nodes = array_diff($uuid_nodes, $form['node']['uuid_automatic_for_nodes']['#default_value']);
+  
+  // Users
+  $uuid_users = $form_state['values']['uuid_automatic_for_users'];
+  $uuid_users = ($uuid_users && $uuid_users != $form['user']['uuid_automatic_for_users']['#default_value']);
+  
+  // Taxonomy
+  $uuid_taxonomy = array_filter($form_state['values']['uuid_automatic_for_taxonomy']);
+  $uuid_taxonomy = array_diff($uuid_taxonomy, $form['taxonomy']['uuid_automatic_for_taxonomy']['#default_value']);
+  
+  $update = array(
+    'uuid_automatic_for_nodes'    => array_keys($uuid_nodes),
+    'uuid_automatic_for_users'    => $uuid_users,
+    'uuid_automatic_for_taxonomy' => array_keys($uuid_taxonomy),
+  );
+  
+  // Synchronize all new elements types
+  uuid_sync($update);
+}
+
 /**
  * Ensure all content and users have UUIDs, if they are supposed to.
+ * 
+ * @param array Internal use only:
+ *   an array containing all elements to which force update. Only used when modifying admin settings.
  */
-function uuid_sync() {
-  if (variable_get('uuid_automatic_for_users', FALSE)) {
-    db_query("INSERT INTO {uuid_users} SELECT u.uid, UUID() FROM {users} AS u WHERE NOT EXISTS (SELECT uid FROM {uuid_users} WHERE uid = u.uid)");
+function uuid_sync($update = array()) {
+  $types = node_get_types('names');
+  $vocabularies = array_map(create_function('$voc', 'return $voc->name;'), taxonomy_get_vocabularies());
+  
+  $uuid_automatic_for_nodes    = variable_get('uuid_automatic_for_nodes', array());
+  $uuid_automatic_for_users    = variable_get('uuid_automatic_for_users', FALSE);
+  $uuid_automatic_for_taxonomy = variable_get('uuid_automatic_for_taxonomy', array());
+  
+  if ($update) {
+    extract($update, EXTR_OVERWRITE);
   }
 
-  foreach (variable_get('uuid_automatic_for_nodes', array()) as $type) {
-    db_query("INSERT INTO {uuid_node} SELECT n.nid, UUID() FROM {node} AS n WHERE n.type = '%s' AND NOT EXISTS (SELECT nid FROM {uuid_node} WHERE nid = n.nid)", $type);
-    db_query("INSERT INTO {uuid_node_revisions} SELECT nr.vid, UUID() FROM {node_revisions} AS nr INNER JOIN {node} n ON nr.nid = n.nid WHERE n.type = '%s' AND NOT EXISTS (SELECT vid FROM {uuid_node_revisions} WHERE vid = nr.vid)", $type);
+  // Nodes
+  foreach ($uuid_automatic_for_nodes as $type) {
+    // Create missing uuid
+    $result = db_query("SELECT n.nid FROM {node} n LEFT JOIN {uuid} u ON u.oid = n.nid AND u.object = '%s' AND u.module = '%s' WHERE ISNULL(u.uuid) AND n.type = '%s'", UUID_NODE_OBJECT, 'uuid', $type);
+    
+    if (db_affected_rows()) {
+      drupal_set_message(t('Missing UUIDs have been created for nodes of type %type.', array('%type' => $types[$type])));
+    }
+    
+    while ($nid = db_result($result)) {
+      uuid_create_uuid($nid, UUID_NODE_OBJECT);
+    }
+    
+    // Node revisions
+    $result = db_query("SELECT r.vid FROM {node_revisions} r INNER JOIN {node} n ON n.vid = r.vid LEFT JOIN {uuid} u ON u.oid = r.vid AND u.object = '%s' AND u.module = '%s' WHERE ISNULL(u.uuid) AND n.type = '%s'", UUID_NODE_REVISION_OBJECT, 'uuid', $type);
+    
+    if (db_affected_rows()) {
+      drupal_set_message(t('Missing UUIDs have been created for nodes revisions of type %type.', array('%type' => $types[$type])));
+    }
+    
+    while ($vid = db_result($result)) {
+      uuid_create_uuid($vid, UUID_NODE_REVISION_OBJECT);
+    }
+  }
+  
+  // Users
+  if ($uuid_automatic_for_users) {
+    // Create missing uuid
+    $result = db_query("SELECT u.uid FROM {users} u LEFT JOIN {uuid} uu ON uu.oid = u.uid AND uu.object = '%s' AND uu.module = '%s' WHERE ISNULL(uu.uuid)", UUID_USER_OBJECT, 'uuid');
+    
+    if (db_affected_rows()) {
+      drupal_set_message(t('Missing UUIDs have been created for users.'));
+    }
+    
+    // Use db_fetch_object because uid 0 exists.
+    while ($user = db_fetch_object($result)) {
+      uuid_create_uuid($user->uid, UUID_USER_OBJECT);
+    }
+  }
+  
+  // Taxonomy
+  foreach ($uuid_automatic_for_taxonomy as $vid) {
+    // Create missing uuid for vocabulary
+    if (! db_result(db_query("SELECT oid FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $vid, UUID_VOCABULARY_OBJECT, 'uuid'))) {
+      uuid_create_uuid($vid, UUID_VOCABULARY_OBJECT);
+      drupal_set_message(t('Missing UUIDs have been created for vocabulary %vocabulary.', array('%vocabulary' => $vocabularies[$vid])));
+    }
+
+    // Create missing uuid for terms
+    $result = db_query("SELECT td.tid FROM {term_data} td LEFT JOIN {uuid} u ON u.oid = td.tid AND u.object = '%s' AND u.module = '%s' WHERE ISNULL(u.uuid) AND td.vid = '%d'", UUID_TERM_OBJECT, 'uuid', $vid) ;
+    
+    if (db_affected_rows()) {
+      drupal_set_message(t('Missing UUIDs have been created for terms belonging to vocabulary %vocabulary.', array('%vocabulary' => $vocabularies[$vid])));
+    }
+    
+    while ($tid = db_result($result)) {
+      uuid_create_uuid($tid, UUID_TERM_OBJECT);
+    }
   }
-
-  drupal_set_message(t("UUID tables have been updated."));
 }
Index: uuid.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/uuid/uuid.install,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 uuid.install
--- uuid.install	19 May 2009 21:55:41 -0000	1.1.2.2
+++ uuid.install	26 Aug 2009 14:26:45 -0000
@@ -5,64 +5,61 @@
  * Implementation of hook_install().
  */
 function uuid_install() {
-  // Create tables.
   drupal_install_schema('uuid');
-
-  require_once(dirname(__FILE__) . '/uuid.admin.inc');
-  uuid_sync();
+  
+  // Check if the PGSQL version support UUID().
+  // This part of code has not been tested, because I use MySQL. If PGSQL user encounter any bug, please report it.
+  $version = ($GLOBALS['db_type'] == 'pgsql' && version_compare(db_version(), '8.4', '<')) ? 0 : 1;
+  variable_set('uuid_db_function_exists', $version);
 }
 
 /**
  * Implementation of hook_schema().
  */
 function uuid_schema() {
-  return array(
-    'uuid_node' => uuid_table_schema('node', 'nid'),
-    'uuid_users' => uuid_table_schema('users', 'uid'),
-    'uuid_node_revisions' => uuid_table_schema('node_revisions', 'vid'),
-  );
-}
-
-/**
- * Return schema for a uuid table.
- *
- * @param $key
- *   Name of key field, e.g. nid for nodes.
- * @return
- *   Array with table structure definition (schema).
- */
-function uuid_table_schema($table, $key = 'key') {
-  return array(
+  $schema = array();
+  
+  $schema['uuid'] = array(
+    'description' => 'Stores UUID data.',
     'fields' => array(
-      $key => array(
+      'oid' => array(
         'type' => 'int',
         'unsigned' => TRUE,
         'not null' => TRUE,
-        'default' => 0,
-        'description' => t('The primary key of the record which this UUID was generated for.'),
+        'description' => 'The primary key of the object which this UUID was generated for.',
       ),
       'uuid' => array(
         'type' => 'varchar',
+        'length' => 36,
+        'not null' => TRUE,
+        'description' => 'The Universally Unique Identifier.',
+      ),
+      'object' => array(
+        'type' => 'varchar',
         'length' => 64,
         'not null' => TRUE,
-        'default' => '',
-        'description' => t('The Universally Unique Identifier.'),
+        'description' => "The Drupal object targeted (node, user, taxonomy...).",
+      ),
+      'module' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => 'uuid',
+        'description' => "The module which manage object of such type.",
       ),
     ),
-    'primary key' => array($key),
-    'indexes' => array(
-      'uuid_'. $table .'_uuid_idx' => array('uuid'),
+    'primary key' => array('oid', 'object', 'module'),
+    'unique keys' => array(
+      'uuid' => array('uuid'),
     ),
   );
+  
+  return $schema;
 }
 
 /**
  * Implementation of hook_uninstall().
  */
 function uuid_uninstall() {
-  variable_del('uuid_automatic_for_nodes');
-  variable_del('uuid_automatic_for_users');
-
-  // Remove tables.
   drupal_uninstall_schema('uuid');
 }
Index: uuid.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/uuid/uuid.module,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 uuid.module
--- uuid.module	11 Jun 2009 18:07:13 -0000	1.1.2.4
+++ uuid.module	26 Aug 2009 14:45:46 -0000
@@ -1,6 +1,12 @@
 <?php
 // $Id: uuid.module,v 1.1.2.4 2009/06/11 18:07:13 recidive Exp $
 
+DEFINE('UUID_NODE_OBJECT',          'node');
+DEFINE('UUID_NODE_REVISION_OBJECT', 'node_revision');
+DEFINE('UUID_USER_OBJECT',          'user');
+DEFINE('UUID_TERM_OBJECT',          'term');
+DEFINE('UUID_VOCABULARY_OBJECT',    'vocabulary');
+
 /**
  * Implementation of hook_menu()
  */
@@ -9,7 +15,7 @@
 
   $items['admin/settings/uuid'] = array(
     'title' => 'Universally Unique IDentifier',
-    'description' => 'UUID generation settings',
+    'description' => 'UUIDs generation settings',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('uuid_admin'),
     'access arguments' => array('administer content types'),
@@ -24,49 +30,41 @@
  * Implementation of hook_nodeapi().
  */
 function uuid_nodeapi(&$node, $op, $teaser, $page) {
-  $automatic_types = variable_get('uuid_automatic_for_nodes', array());
-
-  switch ($op) {
-    case 'load':
-      return array(
-        'uuid' => db_result(db_query('SELECT uuid FROM {uuid_node} WHERE nid = %d', $node->nid)),
-        'revision_uuid' => db_result(db_query('SELECT uuid FROM {uuid_node_revisions} WHERE vid = %d', $node->vid))
-      );
-    case 'insert':
-      // Handle the case where automatic UUID generation is turned OFF but a
-      // node is created, node_save(), intentionally with the $node->uuid
-      // attribute.
-      if (isset($node->uuid) && uuid_is_valid($node->uuid)) {
-        db_query("INSERT INTO {uuid_node} (nid, uuid) VALUES (%d, '%s')", $node->nid, $node->uuid);
-
-        if (isset($node->revision_uuid) && uuid_is_valid($node->revision_uuid)) {
-          db_query("INSERT INTO {uuid_node_revisions} (vid, uuid) VALUES (%d, '%s')", $node->vid, $node->revision_uuid);
-        }
-        else {
-          db_query("INSERT INTO {uuid_node_revisions} (vid, uuid) VALUES (%d, UUID())", $node->vid);
-        }
-      }
-      else if (in_array($node->type, $automatic_types)) {
-        db_query('INSERT INTO {uuid_node} (nid, uuid) VALUES (%d, UUID())', $node->nid);
-        db_query('INSERT INTO {uuid_node_revisions} (vid, uuid) VALUES (%d, UUID())', $node->vid);
-      }
-      break;
-    case 'update':
-      if ($node->revision) {
-        if (isset($node->revision_uuid) && uuid_is_valid($node->revision_uuid)) {
-          db_query("INSERT INTO {uuid_node_revisions} (vid, uuid) VALUES (%d, '%s')", $node->vid, $node->revision_uuid);
+  // The strict parameter for in_array() is absolutly necessary here: $node->type will be casted as
+  // an integer (value 0) because array values may be integer when the node type is not enabled.
+  // So the test will return TRUE instead of FALSE when node type is not enabled.
+  if (in_array($node->type, array_values(variable_get('uuid_automatic_for_nodes', array())), TRUE)) {
+    switch ($op) {
+      case 'load':
+        return array(
+          'uuid'          => uuid_get_uuid($node->nid, UUID_NODE_OBJECT),
+          'revision_uuid' => uuid_get_uuid($node->vid, UUID_NODE_REVISION_OBJECT),
+        );
+      case 'insert':
+        // Handle the case where automatic UUID generation is turned OFF but a
+        // node is created, node_save(), intentionally with the $node->uuid
+        // attribute.
+        $uuid = (isset($node->uuid) && uuid_is_valid($node->uuid)) ? $node->uuid : NULL;
+        $node->uuid = uuid_create_uuid($node->nid, UUID_NODE_OBJECT, 'uuid', $uuid);
+        
+        // Node revision UUID need to be checked even if node->uuid does not exist, because it is not
+        // possible to have several UUID for a same revision (@see primary key).
+        $uuid = (isset($node->revision_uuid) && uuid_is_valid($node->revision_uuid)) ? $node->revision_uuid : NULL;
+        $node->revision_uuid = uuid_create_uuid($node->vid, UUID_NODE_REVISION_OBJECT, 'uuid', $uuid);
+        break;
+      case 'update':
+        if ($node->revision) {
+          $uuid = (isset($node->revision_uuid) && uuid_is_valid($node->revision_uuid)) ? $node->revision_uuid : NULL;
+          $node->revision_uuid = uuid_create_uuid($node->vid, UUID_NODE_REVISION_OBJECT, 'uuid', $uuid);
         }
-        else {
-          db_query("INSERT INTO {uuid_node_revisions} (vid, uuid) VALUES (%d, UUID())", $node->vid);
-        }
-      }
-      break;
-    case 'delete':
-      db_query('DELETE FROM {uuid_node} WHERE nid = %d', $node->nid);
-      break;
-    case 'delete revision':
-      db_query('DELETE FROM {uuid_node_revisions} WHERE vid = %d', $node->vid);
-      break;
+        break;
+      case 'delete':
+        db_query("DELETE FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $node->nid, UUID_NODE_OBJECT, 'uuid');
+        break;
+      case 'delete revision':
+        db_query("DELETE FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $node->vid, UUID_NODE_REVISION_OBJECT, 'uuid');
+        break;
+    }
   }
 }
 
@@ -77,13 +75,15 @@
  * @return $node or FALSE
  *   Either the $node object, or FALSE on failure.
  */
-function node_get_by_uuid($uuid) {
+function node_get_by_uuid($uuid, $module = 'uuid') {
   $nid = db_result(db_query(db_rewrite_sql(
     "SELECT n.nid
      FROM {node} AS n
-     INNER JOIN {uuid_node} AS un ON n.nid = un.nid
-     WHERE un.uuid = '%s'"),
-    $uuid
+     INNER JOIN {uuid} AS un ON n.nid = un.oid
+     WHERE un.uuid = '%s'
+     AND un.object = '%s'
+     AND un.module = '%s'"),
+    $uuid, UUID_NODE_REVISION_OBJECT, $module
   ));
 
   if ($nid) {
@@ -97,13 +97,15 @@
 /**
  * Returns the node associated with a revision UUID.
  */
-function node_get_by_revision_uuid($revision_uuid) {
+function node_get_by_revision_uuid($revision_uuid, $module = 'uuid') {
   $node = db_fetch_object(db_query(db_rewrite_sql(
     "SELECT n.nid, n.vid
      FROM {node} AS n
-     INNER JOIN {uuid_node_revisions} AS unr ON n.vid = unr.vid
-     WHERE unr.uuid = '%s'"),
-    $revision_uuid
+     INNER JOIN {uuid} AS unr ON n.vid = unr.oid
+     WHERE unr.uuid = '%s'
+     AND unr.object = '%s'
+     AND unr.module = '%s'"),
+    $revision_uuid, UUID_NODE_OBJECT, $module
   ));
 
   if ($node->nid && $node->vid) {
@@ -118,30 +120,19 @@
  * Implementation of hook_user().
  */
 function uuid_user($op, &$edit, &$user, $category = NULL) {
-  switch ($op) {
-    case 'load':
-      $user->uuid = db_result(db_query('SELECT uuid FROM {uuid_users} WHERE uid = %d', $user->uid));
-      break;
-    case 'insert':
-      if (isset($user->uuid) && uuid_is_valid($user->uuid)) {
-        db_query("INSERT INTO {uuid_users} (uid, uuid) VALUES (%d, '%s')", $user->uid, $user->uuid);
-      }
-      else if (variable_get('uuid_automatic_for_users', FALSE)) {
-        db_query('INSERT INTO {uuid_users} (uid, uuid) VALUES (%d, UUID())', $user->uid);
-      }
-      break;
-    case 'update':
-      if (isset($user->uuid) && uuid_is_valid($user->uuid)) {
-        $exists = db_result(db_query('SELECT 1 FROM {uuid_users} WHERE uid = %d', $user->uid));
-
-        if (!$exists) {
-          db_query("INSERT INTO {uuid_users} (uid, uuid) VALUES (%d, '%s')", $user->uid, $user->uuid);
-        }
-      }
-      break;
-    case 'delete':
-      db_query('DELETE FROM {uuid_users} WHERE uid = %d', $node->uid);
-      break;
+  if (variable_get('uuid_automatic_for_users', FALSE)) {
+    switch ($op) {
+      case 'load':
+        $user->uuid = uuid_get_uuid($user->uid, UUID_USER_OBJECT);
+        break;
+      case 'insert':
+        $uuid = (isset($user->uuid) && uuid_is_valid($user->uuid)) ? $user->uuid : NULL;
+        $user->uuid = uuid_create_uuid($user->uid, UUID_USER_OBJECT, 'uuid', $uuid);
+        break;
+      case 'delete':
+        db_query("DELETE FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $user->uid, 'user', 'uuid');
+        break;
+    }
   }
 }
 
@@ -151,8 +142,14 @@
  * @return $account or FALSE
  *   Either the $account object, or FALSE on failure.
  */
-function user_get_by_uuid($uuid) {
-  $uid = db_result(db_query("SELECT uid FROM {uuid_users} uuid = '%s'"));
+function user_get_by_uuid($uuid, $module = 'uuid') {
+  $uid = db_result(db_query(
+    "SELECT oid FROM {uuid}
+     WHERE uuid = '%s'
+     AND object = '%s'
+     AND module = '%s'",
+    $uuid, UUID_NODE_OBJECT, $module
+  ));
 
   if ($uid) {
     return user_load(array('uid' => $uid));
@@ -163,8 +160,149 @@
 }
 
 /**
+ * Implementation of hook_taxonomy().
+ */
+function uuid_taxonomy($op, $type, $array = NULL) {
+  $types = array(
+    'term' => array(
+      'colname' => 'tid',
+      'object'  => UUID_TERM_OBJECT,
+    ),
+    'vocabulary' => array(
+      'colname' => 'vid',
+      'object'  => UUID_VOCABULARY_OBJECT,
+    ),
+  );
+  
+  if (array_key_exists($type, $types) && in_array($array['vid'], variable_get('uuid_automatic_for_taxonomy', array()))) {
+    switch ($op) {
+      case 'insert':
+        $uuid = (isset($array['uuid']) && uuid_is_valid($array['uuid'])) ? $array['uuid'] : NULL;
+        $array['uuid'] = uuid_create_uuid($array[$types[$type]['colname']], $types[$type]['object'], 'uuid', $array['uuid']);
+        break;
+      case 'delete':
+        db_query("DELETE FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'",
+          $array[$types[$type]['colname']], $types[$type]['object'], 'uuid');
+        break;
+    }
+  }
+}
+
+/**
+ * Implementation of hook_enable().
+ */
+function uuid_enable() {
+  module_load_include('inc', 'uuid', 'uuid.admin');
+  uuid_sync();
+}
+
+/**
  * Determines if a UUID is valid.
  */
 function uuid_is_valid($uuid) {
   return (boolean) preg_match('/^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$/', $uuid);
 }
+
+/**
+ * @return a Universally Unique IDentifier
+ */
+function uuid_uuid() {
+  if (variable_get('uuid_db_function_exists', 0)) {
+    return db_result(db_query("SELECT UUID();"));
+  }
+  
+  /**
+   * @desc  Generates a Universally Unique IDentifier, version 4.
+   * 
+   * RFC 4122 (http://www.ietf.org/rfc/rfc4122.txt) defines a special type of Globally
+   * Unique IDentifiers (GUID), as well as several methods for producing them. One
+   * such method, described in section 4.4, is based on truly random or pseudo-random
+   * number generators, and is therefore implementable in a language like PHP.
+   *
+   * We choose to produce pseudo-random numbers with the Mersenne Twister, and to always
+   * limit single generated numbers to 16 bits (ie. the decimal value 65535). That is
+   * because, even on 32-bit systems, PHP's RAND_MAX will often be the maximum *signed*
+   * value, with only the equivalent of 31 significant bits. Producing two 16-bit random
+   * numbers to make up a 32-bit one is less efficient, but guarantees that all 32 bits
+   * are random.
+   *
+   * The algorithm for version 4 UUIDs (ie. those based on random number generators)
+   * states that all 128 bits separated into the various fields (32 bits, 16 bits, 16 bits,
+   * 8 bits and 8 bits, 48 bits) should be random, except : (a) the version number should
+   * be the last 4 bits in the 3rd field, and (b) bits 6 and 7 of the 4th field should
+   * be 01. We try to conform to that definition as efficiently as possible, generating
+   * smaller values where possible, and minimizing the number of base conversions.
+   *
+   * @copyright   Copyright (c) CFD Labs, 2006. This function may be used freely for
+   *              any purpose ; it is distributed without any form of warranty whatsoever.
+   * @author      David Holmes <dholmes@cfdsoftware.net>
+   *
+   * @return  string  A UUID, made up of 32 hex digits and 4 hyphens.
+   * 
+   * @see  http://php.net/manual/en/function.uniqid.php#65879
+   */
+   
+  // If the function provided by the uuid pecl extension is available, use that.
+  if( function_exists("uuid_create")) {
+    return uuid_create(UUID_TYPE_DEFAULT);
+  }
+
+  // The field names refer to RFC 4122 section 4.1.2
+  return sprintf('%04x%04x-%04x-%03x4-%04x-%04x%04x%04x',
+    mt_rand(0, 65535), mt_rand(0, 65535), // 32 bits for "time_low"
+    mt_rand(0, 65535), // 16 bits for "time_mid"
+    mt_rand(0, 4095),  // 12 bits before the 0100 of (version) 4 for "time_hi_and_version"
+    bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '01', 6, 2)),
+      // 8 bits, the last two of which (positions 6 and 7) are 01, for "clk_seq_hi_res"
+      // (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d)
+      // 8 bits for "clk_seq_low"
+    mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535) // 48 bits for "node" 
+  );
+}
+
+/**
+ * @desc Store a new UUID in the database
+ * @param int Object ID
+ * @param string Object type (node, user, term, vocabulary...)
+ * @param string The name of the module that add the UUID
+ * @return The UUID on suucess, else FALSE
+ */
+function uuid_create_uuid($oid, $object, $module = 'uuid', $uuid = NULL) {
+  global $db_type;
+  
+  if (is_numeric($oid)) {
+    if (empty($uuid)) {
+      $uuid = uuid_uuid();
+    }
+    
+    switch ($db_type) {
+      case 'mysql':
+      case 'mysqli':
+        // Avoid having 2 queries as with pgsql
+        // Try to decrease the queries number because of query SELECT UUID(); which is
+        // called for each new object 
+        db_query("INSERT INTO {uuid} (oid, uuid, object, module) VALUES (%d, '%s', '%s', '%s') ON DUPLICATE KEY UPDATE `uuid` = %d", $oid, $uuid, $object, $module, $uuid);
+        break;
+      case 'pgsql':
+        // ON DUPLICATE KEY does not exist
+        db_query("DELETE FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $oid, $object, $module);
+        db_query("INSERT INTO {uuid} (oid, uuid, object, module) VALUES (%d, '%s', '%s', '%s')", $oid, $uuid, $object, $module);
+        break;
+    }
+    
+    return $uuid;
+  }
+  
+  return FALSE;
+}
+
+/**
+ * @desc Retrieve an existing UUID from the database
+ * @param int Object ID
+ * @param string Object type (node, user, term, vocabulary...)
+ * @param string The name of the module that add the UUID
+ * @return The UUID on suucess, else FALSE
+ */
+function uuid_get_uuid($oid, $object, $module = 'uuid') {
+  return db_result(db_query("SELECT uuid FROM {uuid} WHERE oid = %d AND object = '%s' AND module = '%s'", $oid, $object, $module));
+}

