RT 版本

本工具支持读取 RT 4.4、5.0 和 6.0,数据库可以是 PostgreSQL、MySQL 或 MariaDB,并针对 RT 4.4.9、5.0.11 和 6.0.4 做过测试。RT 不在数据库里保存版本号,因此工具通过数据库结构(存在哪些表和列)来判断版本,并在启动时报告识别出的版本线:

Found RT 5.0

工具只读取数据库里实际存在的列,所以绝不会向 RT 4.4 数据库查询 RT 6.0 新增的内容。介于两个版本线之间的数据库(例如中途停止的升级、开发版)按其实际拥有的结构来处理。低于 4.4 的 RT 会被拒绝:请先升级。

版本识别方式

发现 含义
没有 Tickets、Transactions 或 Attachments 表 不是 RT 数据库。拒绝。
没有 CustomRoles 表,或没有 Tickets.IsMerged 或 Tickets.SLA 列 RT 版本低于 4.4。拒绝。
有 Transactions.TimeWorker 和 Tickets.Description,或有 SavedSearches 或 ObjectContents 表 RT 6.0
有 Configurations 表 RT 5.0
其他情况 RT 4.4

导出所依赖的差异

保存在数据库里的设置(5.0 及更高版本)

RT 5.0 新增了 Configurations 表,用来保存在 Web 界面中修改过的设置(值由 Perl 的 Data::Dumper 写出,或以 JSON 形式存储)。工具读取其中三项:

设置 用途 没有该设置时(RT 4.4,或未在 Web 界面中修改)
Lifecycles 每个队列的状态及其类别(initial、active、inactive) 使用 RT 的默认生命周期:new;open、stalled;resolved、rejected、deleted。其他状态按名称归类,并在报告中列出。
PriorityAsString、EnablePriorityAsString 各队列的优先级名称 RT 5.0 和 6.0:使用 RT 的默认名称 Low(0)、Medium(50)、High(100)。RT 4.4:同样这三个区间。
Timezone 确定截止日期、开始日期以及工时所属的日期 UTC,或 --timezone 指定的时区。

RT 4.4 的所有设置都保存在 RT_SiteConfig.pm 中,数据库导出无法读取。那里定义的生命周期工具并不知道;请用 --status-category-map 指定其中各状态的类别。

优先级名称(5.0 及更高版本)

RT 4.4 以数字显示优先级;RT 5.0 加入了名称($EnablePriorityAsString,默认开启)。工具使用 RT 显示的名称。对于 RT 4.4,以及 RT 以数字显示优先级的队列,工具使用上面的三个区间。数字本身始终保留在工作项的 extra 中。

谁记录了工时、记在哪一天(6.0)

RT 6.0 新增了 Transactions.TimeWorker 和 Transactions.TimeWorkedDate:可以替他人记录工时,也可以记在另一天。工具用它们作为工时记录的用户和日期。6.0 之前,工时归事务的创建者,日期为事务发生的当天(按上文的时区计算)。

工单自带的描述(6.0)

RT 6.0 新增了 Tickets.Description,这是一段独立于邮件消息的 HTML 文本。工单有描述时,它成为工作项的描述,创建工单时的那条消息则成为第一条日志记录。6.0 之前,以及描述为空时,工作项的描述就是那条首条消息。

描述的修改记录为字段 Description 的 Set 事务,导出时作为描述变更带入。

较长的事务值(6.0)

RT 6.0 把超过 255 字节的新旧值(例如修改后的描述)以 JSON 形式保存在 ObjectContents 表中,并在事务上标记 ReferenceType = 'RT::ObjectContent'。工具从该表读取这些值。

保存的搜索与仪表盘(6.0)

RT 6.0 把保存的搜索和仪表盘从 Attributes 移到了 SavedSearches 和 Dashboards。两者都不会导出;工具会从新旧两处统计其数量。

文章类型(6.0)

RT 6.0 新增了 Articles.Type。工具不需要它。

其他变化

以下变化存在,但不影响工具读取的内容:

版本 变化
5.0 Attachments.id、Transactions.id 及引用它们的列改为 64 位;Transactions.Field 扩大到 255 个字符。
5.0 新增 AuthTokens、Shorteners 表;Users.TOTPSecret;CustomFields.ValidationHint;CustomRoles.LookupType。
6.0 Users.Image;scrip、scrip 动作和条件以及模板上的 LookupType;Templates.Queue 改名为 ObjectId。
6.0 HTML 自定义字段类型(文章 Content 字段的默认类型)。更早的版本把文章的富文本存在 Text 类型的字段中。

数据库之间的差异

RT 在每种数据库上都根据自己的 schema 文件创建相同的表,表名只有大小写之别。PostgreSQL 会把名字折叠为小写(tickets.effectiveid);MySQL 按原样保留表名(Tickets),列名则不区分大小写。工具按数据库实际的拼写来称呼每张表。

内容的存储方式不同:

PostgreSQL MySQL 和 MariaDB
Attachments.Content、ObjectCustomFieldValues.LargeContent text:凡不是合法 UTF-8 的内容都以 base64(ContentEncoding = 'base64')或 quoted-printable 编码 LONGBLOB:原始字节(ContentEncoding = 'none')
Configurations.Content、Attributes.Content text LONGBLOB

工具两种都能读取,并要求 MySQL 使用 utf8mb4,即 RT 的 MySQL schema 所用的字符集。

所有版本都相同的值

  • 时间为 UTC,不带时区。未设置的日期(Told、Starts、Due、Resolved 等)存为 1970-01-01 00:00:00,工具将其读作“未设置”。
  • 已合并的工单保留自己的行,EffectiveId 指向被合并进的目标工单。
  • IP 地址类自定义字段的值以零填充形式存储(192.000.002.010)以便排序;工具按 RT 的显示形式写出(192.0.2.10)。
  • 邮件按 RT 收到时的原样存储,每个 MIME 部分占 Attachments 的一行。RT 会把文本部分转换为 UTF-8,并在 X-RT-Original-Encoding 中记录原始字符集;较早的数据可能仍是该部分自己声明的字符集。工具先尝试 UTF-8,再尝试声明的字符集。