diff --git a/bootstrap.php b/bootstrap.php index 4b64227a839c1e9cd864db6cc74a1930e9906f98..085ad9dc1c8250ce407046ead5ccac0f7ccfaf27 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -102,6 +102,7 @@ class Bootstrap { define('THREAD_COLLABORATOR_TABLE', $prefix.'thread_collaborator'); define('TICKET_STATUS_TABLE', $prefix.'ticket_status'); define('TICKET_PRIORITY_TABLE',$prefix.'ticket_priority'); + define('EVENT_TABLE',$prefix.'event'); define('TASK_TABLE', $prefix.'task'); define('TASK_CDATA_TABLE', $prefix.'task__cdata'); diff --git a/include/class.report.php b/include/class.report.php index 12d7322d3dbc6665fed18b86d8b738d49eb091ba..c2aa391ef9ec52527c3af6f30ddb13a914f663bf 100644 --- a/include/class.report.php +++ b/include/class.report.php @@ -77,26 +77,32 @@ class OverviewReport { function getPlotData() { list($start, $stop) = $this->getDateRange(); + $states = array("created", "closed", "reopened", "assigned", "overdue", "transferred"); + $event_ids = array(); + foreach ($states as $state) { + $eid = Event::getIdByName($state); + $event_ids[] = $eid; + } # Fetch all types of events over the timeframe $res = db_query('SELECT DISTINCT(state) FROM '.THREAD_EVENT_TABLE .' WHERE timestamp BETWEEN '.$start.' AND '.$stop - .' AND state IN ("created", "closed", "reopened", "assigned", "overdue", "transferred")' + .' AND event_id IN ('.implode($event_ids).')' .' ORDER BY 1'); $events = array(); while ($row = db_fetch_row($res)) $events[] = $row[0]; # TODO: Handle user => db timezone offset # XXX: Implement annulled column from the %ticket_event table - $res = db_query('SELECT state, DATE_FORMAT(timestamp, \'%Y-%m-%d\'), ' + $res = db_query('SELECT event_id, DATE_FORMAT(timestamp, \'%Y-%m-%d\'), ' .'COUNT(DISTINCT T.id)' .' FROM '.THREAD_EVENT_TABLE. ' E ' .' JOIN '.THREAD_TABLE. ' T ON (T.id = E.thread_id AND T.object_type = "T") ' .' WHERE E.timestamp BETWEEN '.$start.' AND '.$stop .' AND NOT annulled' - .' AND E.state IN ("created", "closed", "reopened", "assigned", "overdue", "transferred")' - .' GROUP BY E.state, DATE_FORMAT(E.timestamp, \'%Y-%m-%d\')' + .' AND E.event_id IN ('.implode($event_ids).')' + .' GROUP BY E.event_id, DATE_FORMAT(E.timestamp, \'%Y-%m-%d\')' .' ORDER BY 2, 1'); # Initialize array of plot values $plots = array(); @@ -148,8 +154,8 @@ class OverviewReport { )) ->constrain(array( 'thread__events' => array( - 'thread__events__state' => 'created', - 'state' => 'closed', + 'thread__events__event_id' => Event::getIdByName('created'), + 'event_id' => Event::getIdByName('closed'), 'annulled' => 0, ), )) @@ -174,27 +180,27 @@ class OverviewReport { ->aggregate(array( 'Opened' => SqlAggregate::COUNT( SqlCase::N() - ->when(new Q(array('state' => 'created')), 1) + ->when(new Q(array('event_id' => Event::getIdByName('created'))), 1) ), 'Assigned' => SqlAggregate::COUNT( SqlCase::N() - ->when(new Q(array('state' => 'assigned')), 1) + ->when(new Q(array('event_id' => Event::getIdByName('assigned'))), 1) ), 'Overdue' => SqlAggregate::COUNT( SqlCase::N() - ->when(new Q(array('state' => 'overdue')), 1) + ->when(new Q(array('event_id' => Event::getIdByName('overdue'))), 1) ), 'Closed' => SqlAggregate::COUNT( SqlCase::N() - ->when(new Q(array('state' => 'closed')), 1) + ->when(new Q(array('event_id' => Event::getIdByName('closed'))), 1) ), 'Reopened' => SqlAggregate::COUNT( SqlCase::N() - ->when(new Q(array('state' => 'reopened')), 1) + ->when(new Q(array('event_id' => Event::getIdByName('reopened'))), 1) ), 'Deleted' => SqlAggregate::COUNT( SqlCase::N() - ->when(new Q(array('state' => 'deleted')), 1) + ->when(new Q(array('event_id' => Event::getIdByName('deleted'))), 1) ), )); diff --git a/include/class.thread.php b/include/class.thread.php index 2aa82cd494a89ba6f3a6c8f2adf73b519dea6bf2..0807834b39590c969aacd266fb4e0c51c33c0fb2 100644 --- a/include/class.thread.php +++ b/include/class.thread.php @@ -2049,16 +2049,59 @@ class ThreadEvent extends VerySimpleModel { $subclasses[$class::$state] = $class; } } + $this->state = Event::getNameById($this->event_id); if (!($class = $subclasses[$this->state])) return $this; return new $class($this->ht); } } +class Event extends VerySimpleModel { + static $meta = array( + 'table' => EVENT_TABLE, + 'pk' => array('id'), + ); + + function getInfo() { + return $this->ht; + } + + function getId() { + return $this->id; + } + + function getName() { + return $this->name; + } + + function getNameById($id) { + $row = Event::objects() + ->filter(array('id'=>$id)) + ->values_flat('name') + ->first(); + + return $row ? $row[0] : 0; + } + + function getIdByName($name) { + $row = Event::objects() + ->filter(array('name'=>$name)) + ->values_flat('id') + ->first(); + + return $row ? $row[0] : 0; + } + + function getDescription() { + return $this->description; + } +} + class ThreadEvents extends InstrumentedList { function annul($event) { + $event_id = Event::getIdByName($event); $this->queryset - ->filter(array('state' => $event)) + ->filter(array('event_id' => $event_id)) ->update(array('annulled' => 1)); } @@ -2113,7 +2156,7 @@ class ThreadEvents extends InstrumentedList { } } $event->username = $username; - $event->state = $state; + $event->event_id = Event::getIdByName($state); if ($data) { if (is_array($data)) diff --git a/include/class.user.php b/include/class.user.php index 53a8627c3bd4d95e319d86e26d9e1f8498f5a4d4..d9ca8463e93a35a32b3cb5929d73a3f48cb0578a 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -635,7 +635,8 @@ implements TemplateVariable, Searchable { } function deleteAllTickets() { - $deleted = TicketStatus::lookup(array('state' => 'deleted')); + $event_id = Event::getIdByName('deleted'); + $deleted = TicketStatus::lookup(array('event_id' => $event_id)); foreach($this->tickets as $ticket) { if (!$T = Ticket::lookup($ticket->getId())) continue; diff --git a/include/client/templates/thread-entries.tmpl.php b/include/client/templates/thread-entries.tmpl.php index 93843210969e4e3d79aea05b4ad692805dc5f95f..8457698caf820605482ee839492d4001fc6fbb55 100644 --- a/include/client/templates/thread-entries.tmpl.php +++ b/include/client/templates/thread-entries.tmpl.php @@ -1,6 +1,12 @@ <?php +$states = array('created', 'closed', 'reopened', 'edited', 'collab'); +$event_ids = array(); +foreach ($states as $state) { + $eid = Event::getIdByName($state); + $event_ids[] = $eid; +} $events = $events - ->filter(array('state__in' => array('created', 'closed', 'reopened', 'edited', 'collab'))) + ->filter(array('event_id__in' => $event_ids)) ->order_by('id'); $events = new IteratorIterator($events->getIterator()); $events->rewind(); diff --git a/include/upgrader/streams/core.sig b/include/upgrader/streams/core.sig index fbebb45e63ee1f85f4388d1ead81fa6b7403dd4f..cd7008c3cb852cd0758773f740849bb01329bdb3 100644 --- a/include/upgrader/streams/core.sig +++ b/include/upgrader/streams/core.sig @@ -1 +1 @@ -26fd79dc5443f37779f9d2c4108058f4 +226da4e7298917160c7499cb63370f83 diff --git a/include/upgrader/streams/core/0ca85857-86707325.patch.sql b/include/upgrader/streams/core/0ca85857-86707325.patch.sql index 2962d23e40f284614bd877ee0317e1183f7a21bf..2daaf3b7cdab96ac80265205de51dbe6fc0926ef 100644 --- a/include/upgrader/streams/core/0ca85857-86707325.patch.sql +++ b/include/upgrader/streams/core/0ca85857-86707325.patch.sql @@ -17,10 +17,6 @@ CREATE TABLE `%TABLE_PREFIX%thread_referral` ( KEY `thread_id` (`thread_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -ALTER TABLE `%TABLE_PREFIX%thread_event` - CHANGE `state` `state` enum('created','closed','reopened','assigned','transferred', 'referred', 'overdue','edited','viewed','error','collab','resent', 'deleted') NOT NULL; - - -- Finished with patch UPDATE `%TABLE_PREFIX%config` SET `value` = '86707325fc571e56242fccc46fd24466' diff --git a/include/upgrader/streams/core/26fd79dc-226da4e7.cleanup.sql b/include/upgrader/streams/core/26fd79dc-226da4e7.cleanup.sql new file mode 100644 index 0000000000000000000000000000000000000000..50cad9d04f5cb4a2ee7b773c2841637a6659a2de --- /dev/null +++ b/include/upgrader/streams/core/26fd79dc-226da4e7.cleanup.sql @@ -0,0 +1,3 @@ +-- Drop the state field from thread_events +ALTER TABLE `%TABLE_PREFIX%thread_event` + DROP COLUMN `state`; diff --git a/include/upgrader/streams/core/26fd79dc-226da4e7.patch.sql b/include/upgrader/streams/core/26fd79dc-226da4e7.patch.sql new file mode 100644 index 0000000000000000000000000000000000000000..e6dae706577e7323ca7a3539cf5e4ec6044ae3e4 --- /dev/null +++ b/include/upgrader/streams/core/26fd79dc-226da4e7.patch.sql @@ -0,0 +1,28 @@ +/** +* @signature 226da4e7298917160c7499cb63370f83 +* @version v1.11.0 +* @title Database Optimization +* +* This patch is for optimizing our database to handle large amounts of data +* more smoothly. +* +* 1. remove states in thread_event table and add them to their own event table +*/ + +-- Create a new table to store events +CREATE TABLE `%TABLE_PREFIX%event` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `description` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- Add event_id column to thread_events +ALTER TABLE `%TABLE_PREFIX%thread_event` + ADD `event_id` int(11) unsigned AFTER `thread_id`; + +-- Finished with patch +UPDATE `%TABLE_PREFIX%config` + SET `value` = '226da4e7298917160c7499cb63370f83', `updated` = NOW() + WHERE `key` = 'schema_signature' AND `namespace` = 'core'; diff --git a/include/upgrader/streams/core/26fd79dc-226da4e7.task.php b/include/upgrader/streams/core/26fd79dc-226da4e7.task.php new file mode 100644 index 0000000000000000000000000000000000000000..3fb5b806562278ff391fba27e77561399044694d --- /dev/null +++ b/include/upgrader/streams/core/26fd79dc-226da4e7.task.php @@ -0,0 +1,28 @@ +<?php + +class EventEnumRemoval extends MigrationTask { + var $description = "Remove the Enum 'state' field from ThreadEvents"; + + function run() { + // Move states into the new table as events + $states = array('created','closed','reopened','assigned', 'released', 'transferred', 'referred', 'overdue','edited','viewed','error','collab','resent', 'deleted'); + foreach ($states as $state) { + $sql= "INSERT INTO ".EVENT_TABLE." (`name`, `description`) + VALUES('". + $state. "', '')"; + db_query($sql); + } + + $sql = "UPDATE ".THREAD_EVENT_TABLE. " AS this + INNER JOIN ( + SELECT id, name + FROM ". EVENT_TABLE. ") AS that + SET this.event_id = that.id + WHERE this.state = that.name"; + db_query($sql); + } + +} +return 'EventEnumRemoval'; + +?> diff --git a/include/upgrader/streams/core/70921d5c-26fd79dc.patch.sql b/include/upgrader/streams/core/70921d5c-26fd79dc.patch.sql index f3bc7e0b201ea76bb59c6ff4de8f1ed272740d82..fd5953f5b6870f0cd53ffd5e42f8e36ea0019670 100644 --- a/include/upgrader/streams/core/70921d5c-26fd79dc.patch.sql +++ b/include/upgrader/streams/core/70921d5c-26fd79dc.patch.sql @@ -5,10 +5,6 @@ * * This patch is for final revisions needed for v1.11 */ - -ALTER TABLE `%TABLE_PREFIX%thread_event` - CHANGE `state` `state` enum('created','closed','reopened','assigned', 'released', 'transferred', 'referred', 'overdue','edited','viewed','error','collab','resent', 'deleted') NOT NULL; - ALTER TABLE `%TABLE_PREFIX%attachment` ADD INDEX `file_object` (`file_id`,`object_id`); diff --git a/setup/inc/streams/core/install-mysql.sql b/setup/inc/streams/core/install-mysql.sql index fbbb6e45050facca4ad2c6390657073d14b23c96..bb13f3944ca3e2fd87aea3f2ef98b05716178fe2 100644 --- a/setup/inc/streams/core/install-mysql.sql +++ b/setup/inc/streams/core/install-mysql.sql @@ -711,6 +711,15 @@ CREATE TABLE `%TABLE_PREFIX%lock` ( KEY `staff_id` (`staff_id`) ) DEFAULT CHARSET=utf8; +DROP TABLE IF EXISTS `%TABLE_PREFIX%event`; +CREATE TABLE `%TABLE_PREFIX%event` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(60) NOT NULL, + `description` varchar(60) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `name` (`name`), +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + DROP TABLE IF EXISTS `%TABLE_PREFIX%thread_event`; CREATE TABLE `%TABLE_PREFIX%thread_event` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT,