Skip to content

Commit

Permalink
moved waypoint assignment code to database trigger (before insert cac…
Browse files Browse the repository at this point in the history
…hes)
  • Loading branch information
ocoliver committed Nov 17, 2012
1 parent a4aee62 commit 39a25f9
Show file tree
Hide file tree
Showing 7 changed files with 990 additions and 1,027 deletions.
47 changes: 43 additions & 4 deletions htdocs/doc/sql/stored-proc/maintain.php
Expand Up @@ -521,7 +521,43 @@
IF ISNULL(NEW.`uuid`) OR NEW.`uuid`='' THEN
SET NEW.`uuid`=CREATE_UUID();
END IF;
END;");
/* reserve and set cache waypoint
*
* Table cache_waypoint_pool is used to prevent race conditions
* when 2 caches will be inserted simultaneously
*/
IF ISNULL(NEW.`wp_oc`) OR NEW.`wp_oc`='' THEN
/* cleanup previous assignments failures /*
DELETE FROM `cache_waypoint_pool` WHERE `uuid`=NEW.`uuid`;
/* reserve a waypoint */
UPDATE `cache_waypoint_pool` SET `uuid`=NEW.`uuid` WHERE `uuid` IS NULL ORDER BY WPTODEC(`wp_oc`, '&1') ASC LIMIT 1;
IF (SELECT COUNT(*) FROM `cache_waypoint_pool` WHERE `uuid`=NEW.`uuid`) = 0 THEN
/* waypoint reservation was not successfull. Maybe we are on a development machine, where cronjob for waypoint pool
* generation did not run or the pool is empty. To get a valid waypoint, we simply increment the highest used waypoint by one.
* NOTE: This ignores the setting of $opt['logic']['waypoint_pool']['fill_gaps']
* CAUTION: This statement is realy slow and you should always keep your waypoint pool filled with some waypoint on a production server
*/
INSERT INTO `cache_waypoint_pool` (`wp_oc`, `uuid`)
SELECT DECTOWP(MAX(`dec_wp`)+1, '&1'), NEW.`uuid` AS `uuid`
FROM (
SELECT MAX(WPTODEC(`wp_oc`, '&1')) AS dec_wp FROM `caches` WHERE `wp_oc` REGEXP '&2'
UNION SELECT MAX(WPTODEC(`wp_oc`, '&1')) AS dec_wp FROM `cache_waypoint_pool`
) AS `tbl`;
END IF;
/* query and assign the reserved waypoint */
SET NEW.`wp_oc` = (SELECT `wp_oc` FROM `cache_waypoint_pool` WHERE `uuid`=`NEW`.`uuid`);
END IF;
END;",
$opt['logic']['waypoint_pool']['prefix'],
'^' . $opt['logic']['waypoint_pool']['prefix'] . '[' . $opt['logic']['waypoint_pool']['valid_chars'] . ']{1,}$');

sql_dropTrigger('cachesAfterInsert');
sql("CREATE TRIGGER `cachesAfterInsert` AFTER INSERT ON `caches`
Expand All @@ -534,9 +570,12 @@
CALL sp_update_hiddenstat(NEW.`user_id`, FALSE);
IF NEW.`status`=1 THEN
CALL sp_notify_new_cache(NEW.`cache_id`, NEW.`longitude`, NEW.`latitude`);
END IF;
IF NEW.`status`=1 THEN
CALL sp_notify_new_cache(NEW.`cache_id`, NEW.`longitude`, NEW.`latitude`);
END IF;
/* cleanup/delete reserved waypoint */
DELETE FROM `cache_waypoint_pool` WHERE `uuid`=NEW.`uuid`;
END;");

sql_dropTrigger('cachesBeforeUpdate');
Expand Down
4 changes: 2 additions & 2 deletions htdocs/doc/sql/tables/cache_waypoint_pool.sql
Expand Up @@ -2,7 +2,7 @@ SET NAMES 'utf8';
DROP TABLE IF EXISTS `cache_waypoint_pool`;
CREATE TABLE `cache_waypoint_pool` (
`wp_oc` char(7) NOT NULL,
`cache_id` int(10) unsigned default NULL,
`uuid` varchar(36) default NULL,
PRIMARY KEY (`wp_oc`),
KEY `cache_id` (`cache_id`)
UNIQUE KEY `uuid` (`uuid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
2 changes: 1 addition & 1 deletion htdocs/doc/sql/tables/caches.sql
Expand Up @@ -23,7 +23,7 @@ CREATE TABLE `caches` (
`way_length` float unsigned NOT NULL default '0',
`wp_gc` varchar(7) NOT NULL,
`wp_nc` varchar(6) NOT NULL,
`wp_oc` varchar(7) default NULL,
`wp_oc` varchar(7) NOT NULL,
`desc_languages` varchar(60) NOT NULL COMMENT 'via Trigger (cache_desc)',
`default_desclang` char(2) NOT NULL,
`date_activate` datetime default NULL,
Expand Down
37 changes: 0 additions & 37 deletions htdocs/lib/clicompatbase.inc.php
Expand Up @@ -69,43 +69,6 @@ function logentry($module, $eventid, $userid, $objectid1, $objectid2, $logtext,
$module, $eventid, $userid, $objectid1, $objectid2, $logtext, serialize($details));
}

// set a unique waypoint to this cache
function setCacheWaypoint($cacheid)
{
global $opt;

// cleanup previous assignments failures
sql("DELETE FROM `cache_waypoint_pool` WHERE `cache_id`='&1'", $cacheid);

// reserve a waypoint
sql("UPDATE `cache_waypoint_pool` SET `cache_id`='&1' WHERE `cache_id` IS NULL ORDER BY WPTODEC(`wp_oc`, '&2') ASC LIMIT 1", $cacheid, $opt['logic']['waypoint_pool']['prefix']);

if (sqlValue("SELECT `wp_oc` FROM `cache_waypoint_pool` WHERE `cache_id`='" . ($cacheid+0) . "'", "") == "")
{
// waypoint reservation was not successfull. Maybe we are on a development machine, where cronjob for waypoint pool
// generation did not run or the pool is empty. To get a valid waypoint, we simply increment the highest used waypoint by one.
// (note: this ignores the setting of $opt['logic']['waypoint_pool']['fill_gaps'])
// CAUTION: This statement is realy slow and you should always keep your waypoint pool filled with some waypoint on a production server
sql("INSERT INTO `cache_waypoint_pool` (`wp_oc`, `cache_id`)
SELECT DECTOWP(MAX(`dec_wp`)+1, '&1'), '&2' AS `cache_id`
FROM (
SELECT MAX(WPTODEC(`wp_oc`, '&1')) AS dec_wp FROM `caches` WHERE `wp_oc` REGEXP '&3'
UNION SELECT MAX(WPTODEC(`wp_oc`, '&1')) AS dec_wp FROM `cache_waypoint_pool`
) AS `tbl`",
$opt['logic']['waypoint_pool']['prefix'],
$cacheid,
'^' . $opt['logic']['waypoint_pool']['prefix'] . '[' . $opt['logic']['waypoint_pool']['valid_chars'] . ']{1,}$');
}

// assign reserved waypoint to the cache
// for the moment, we use IGNORE to catch duplicate keys that occur in any failure case
// the cache keeps without a waypoint in this case. Later we change field caches.wp_oc to NOT NULL and assign waypoint in BEFORE INSERT trigger
sql("UPDATE IGNORE `caches` INNER JOIN `cache_waypoint_pool` ON `caches`.`cache_id`=`cache_waypoint_pool`.`cache_id` SET `caches`.`wp_oc`=`cache_waypoint_pool`.`wp_oc` WHERE `caches`.`cache_id`='&1'", $cacheid);

// cleanup
sql("DELETE FROM `cache_waypoint_pool` WHERE `cache_id`='&1'", $cacheid);
}

function setLastFound($cacheid)
{
$rs = sql("SELECT MAX(`date`) `date` FROM `cache_logs` WHERE `cache_id`=&1 AND `type`=1", $cacheid);
Expand Down

0 comments on commit 39a25f9

Please sign in to comment.