# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Usage: # # 1. Define AUTOPREFIX_APP_UUID as a universally unique identifier for your # application (see RFC 4122). # # 2. Define AUTOPREFIX_SUGGESTED_PREFIX as a 2-33 character string containing # the suggested prefix for your application's database tables. (For example, # "yourapp_") # # 3. Optionally define AUTOPREFIX_APP_INSTANCE as string representing this # specific instance of your application. This value should be configurable by # the administrator. The default value is the empty string. A good default # for AUTOPREFIX_APP_INSTANCE is $_SERVER['SERVER_NAME']. Note that the # $app_instance parameter overrides this setting. # # 4. Optionally define AUTOPREFIX_GEN_PREFIX as a prefix that will be used in # case your AUTOPREFIX_SUGGESTED_PREFIX is already taken. # # 5. Optionally define AUTOPREFIX_META_PREFIX as a string that will be # prepended to *every* table name used and returned by this script. # # 6. Call autoprefix_mysql_get_prefix to get the database table prefix for # your application. require_once "mysqlext.php"; require_once "uuid.php"; function autoprefix_mysql_get_prefix($db_conn, $app_instance=null) { # Perform sanity checks on the inputs if (!defined('AUTOPREFIX_APP_UUID') or !uuid_is_valid(AUTOPREFIX_APP_UUID)) { die("AUTOPREFIX_APP_UUID must be defined and a valid UUID string"); } if (!defined('AUTOPREFIX_SUGGESTED_PREFIX') or !preg_match('/^[[:alpha:][:digit:]_]{2,33}$/s', AUTOPREFIX_SUGGESTED_PREFIX)) { die("AUTOPREFIX_SUGGESTED_PREFIX must be set, must contain only " . "alphanumerics and underscores, and must be between 2 and 33 " . "characters in length."); } if (!is_resource($db_conn)) { die("db_conn must be a mysql connection resource"); } # Define some useful variables if (!isset($app_instance) or is_null($app_instance)) { $app_instance = defined('AUTOPREFIX_APP_INSTANCE') ? AUTOPREFIX_APP_INSTANCE : ''; } $meta_prefix = defined('AUTOPREFIX_META_PREFIX') ? AUTOPREFIX_META_PREFIX : ''; $gen_prefix = defined('AUTOPREFIX_GEN_PREFIX') ? AUTOPREFIX_GEN_PREFIX : 'autoprefix_'; $main_table = $meta_prefix.'autoprefix_24823d5c-0803-11db-8b07-0002a50ec775_0'; # Check if the prefix-list table exists $result = mysql_execute($db_conn, "SHOW TABLES LIKE ?", array($main_table)) or die("Error listing autoprefix table"); $table_exists = false; while($row = mysql_fetch_row($result)) { if ($row[0] === $main_table) { $table_exists = true; break; } } mysql_free_result($result); # If the prefix-list table does not exist, create it. if (!$table_exists) { $result = mysql_execute($db_conn, " CREATE TABLE `$main_table` ( id BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, uuid CHAR(36), instance VARCHAR(255), prefix VARCHAR(64), UNIQUE INDEX(uuid, instance), UNIQUE INDEX(prefix) )") or die("Could not create autoprefix table"); mysql_free_result($result); } unset($table_exists); # Attempt to find out the existing prefix $result = mysql_execute($db_conn, "SELECT prefix FROM `$main_table` WHERE uuid = ? AND instance = ? AND prefix IS NOT NULL LIMIT 1", array(AUTOPREFIX_APP_UUID, $app_instance)); $row = mysql_fetch_array($result); mysql_free_result($result); if ($row) { # Existing entry was found. Return it. return $meta_prefix . $row['prefix']; } # No existing entry was found. Create a blank entry, which we will # populate later. $result = mysql_execute($db_conn, "INSERT INTO `$main_table` (uuid, instance, prefix) VALUES (NULL, NULL, NULL)") or die("Couldn't create autoprefix entry"); $entry_id = mysql_insert_id($db_conn); mysql_free_result($result); # Attempt to set the prefix to the suggested prefix. This will fail (due # to the UNIQUE INDEX) if the prefix is already in use. $prefix = AUTOPREFIX_SUGGESTED_PREFIX; $result = mysql_execute($db_conn, "UPDATE `$main_table` SET prefix = ? WHERE id = ?", array($prefix, $entry_id)); if (!$result) { # The prefix is already in use. Generate a new one based on the # id field in the database. $prefix = $gen_prefix . $entry_id . '_'; $result = mysql_execute($db_conn, "UPDATE `$main_table` SET prefix = ? WHERE id = ?", array($prefix, $entry_id)) or die("Could not set auto-generated prefix ('$prefix')"); } mysql_free_result($result); # Set the uuid and instance fields $result = mysql_execute($db_conn, "UPDATE `$main_table` SET uuid = ?, instance = ? WHERE id = ?", array(AUTOPREFIX_APP_UUID, $app_instance, $entry_id)) or die("Could not set autoprefix uuid and instance (id=$entry_id)"); mysql_free_result($result); return $meta_prefix . $prefix; } # vim:set ts=4 sw=4 sts=4 expandtab: