diff options
Diffstat (limited to 'rt/etc')
37 files changed, 1953 insertions, 0 deletions
diff --git a/rt/etc/schema.mysql b/rt/etc/schema.mysql new file mode 100644 index 000000000..c313aaf54 --- /dev/null +++ b/rt/etc/schema.mysql @@ -0,0 +1,499 @@ + +CREATE TABLE Attachments ( + id INTEGER NOT NULL AUTO_INCREMENT, + TransactionId integer NOT NULL , + Parent integer NOT NULL DEFAULT 0 , + MessageId varchar(160) CHARACTER SET ascii NULL , + Subject varchar(255) NULL , + Filename varchar(255) NULL , + ContentType varchar(80) CHARACTER SET ascii NULL , + ContentEncoding varchar(80) CHARACTER SET ascii NULL , + Content LONGBLOB NULL , + Headers LONGTEXT NULL , + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX Attachments2 ON Attachments (TransactionId) ; +CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId) ; + +CREATE TABLE Queues ( + id INTEGER NOT NULL AUTO_INCREMENT, + Name varchar(200) NOT NULL , + Description varchar(255) NULL , + CorrespondAddress varchar(120) CHARACTER SET ascii NULL, + CommentAddress varchar(120) CHARACTER SET ascii NULL, + Lifecycle varchar(32) CHARACTER SET ascii NULL, + SubjectTag varchar(120) NULL, + InitialPriority integer NOT NULL DEFAULT 0 , + FinalPriority integer NOT NULL DEFAULT 0 , + DefaultDueIn integer NOT NULL DEFAULT 0 , + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + Disabled int2 NOT NULL DEFAULT 0 , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE UNIQUE INDEX Queues1 ON Queues (Name) ; +CREATE INDEX Queues2 ON Queues (Disabled) ; + + + +CREATE TABLE Links ( + id INTEGER NOT NULL AUTO_INCREMENT, + Base varchar(240) NULL, + Target varchar(240) NULL, + Type varchar(20) NOT NULL, + LocalTarget integer NOT NULL DEFAULT 0 , + LocalBase integer NOT NULL DEFAULT 0 , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET ascii; + +CREATE INDEX Links2 ON Links (Base, Type) ; +CREATE INDEX Links3 ON Links (Target, Type) ; +CREATE INDEX Links4 ON Links (Type,LocalBase); + + + +CREATE TABLE Principals ( + id INTEGER AUTO_INCREMENT not null, + PrincipalType VARCHAR(16) not null, + ObjectId integer, # foreign key to Users or Groups, depending + Disabled int2 NOT NULL DEFAULT 0 , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET ascii; + +CREATE INDEX Principals2 ON Principals (ObjectId); + + + +CREATE TABLE Groups ( + id INTEGER NOT NULL AUTO_INCREMENT, + Name varchar(200) NULL , + Description varchar(255) NULL , + Domain varchar(64) CHARACTER SET ascii NULL, + Type varchar(64) CHARACTER SET ascii NULL, + Instance integer, + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX Groups1 ON Groups (Domain,Instance,Type,id); +CREATE INDEX Groups2 On Groups (Type, Instance); + + + +CREATE TABLE ScripConditions ( + id INTEGER NOT NULL AUTO_INCREMENT, + Name varchar(200) NULL , + Description varchar(255) NULL , + ExecModule varchar(60) CHARACTER SET ascii NULL, + Argument VARBINARY(255) NULL , + ApplicableTransTypes varchar(60) CHARACTER SET ascii NULL , + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + + +CREATE TABLE Transactions ( + id INTEGER NOT NULL AUTO_INCREMENT, + ObjectType varchar(64) CHARACTER SET ascii NOT NULL, + ObjectId integer NOT NULL DEFAULT 0 , + TimeTaken integer NOT NULL DEFAULT 0 , + Type varchar(20) CHARACTER SET ascii NULL, + Field varchar(40) CHARACTER SET ascii NULL, + OldValue varchar(255) NULL , + NewValue varchar(255) NULL , + ReferenceType varchar(255) CHARACTER SET ascii NULL, + OldReference integer NULL , + NewReference integer NULL , + Data varchar(255) NULL , + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX Transactions1 ON Transactions (ObjectType, ObjectId); + + + +CREATE TABLE Scrips ( + id INTEGER NOT NULL AUTO_INCREMENT, + Description varchar(255), + ScripCondition integer NOT NULL DEFAULT 0 , + ScripAction integer NOT NULL DEFAULT 0 , + ConditionRules text NULL , + ActionRules text NULL , + CustomIsApplicableCode text NULL , + CustomPrepareCode text NULL , + CustomCommitCode text NULL , + Stage varchar(32) CHARACTER SET ascii NULL , + Queue integer NOT NULL DEFAULT 0 , + Template integer NOT NULL DEFAULT 0 , + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + + +CREATE TABLE ACL ( + id INTEGER NOT NULL AUTO_INCREMENT, + PrincipalType varchar(25) CHARACTER SET ascii NOT NULL, #"User" "Group", "Owner", "Cc" "AdminCc", "Requestor" + + PrincipalId integer NOT NULL DEFAULT 0 , #Foreign key to principals + RightName varchar(25) CHARACTER SET ascii NOT NULL, + ObjectType varchar(25) CHARACTER SET ascii NOT NULL, + ObjectId integer NOT NULL default 0, + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX ACL1 on ACL(RightName, ObjectType, ObjectId,PrincipalType,PrincipalId); + + + +CREATE TABLE GroupMembers ( + id INTEGER NOT NULL AUTO_INCREMENT, + GroupId integer NOT NULL DEFAULT 0, + MemberId integer NOT NULL DEFAULT 0, #Foreign key to Principals + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; +CREATE UNIQUE INDEX GroupMembers1 on GroupMembers (GroupId, MemberId); + + + + +create table CachedGroupMembers ( + id int auto_increment, + GroupId int, # foreign key to Principals + MemberId int, # foreign key to Principals + Via int, #foreign key to CachedGroupMembers. (may point to $self->id) + ImmediateParentId int, #foreign key to prinicpals. + # this points to the group that the member is + # a member of, for ease of deletes. + Disabled int2 NOT NULL DEFAULT 0 , # if this cached group member is a member of this group by way of a disabled + # group or this group is disabled, this will be set to 1 + # this allows us to not find members of disabled subgroups when listing off + # group members recursively. + # Also, this allows us to have the ACL system elide members of disabled groups + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX DisGrouMem on CachedGroupMembers (GroupId,MemberId,Disabled); +CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId, ImmediateParentId); + + + +CREATE TABLE Users ( + id INTEGER NOT NULL AUTO_INCREMENT, + Name varchar(200) NOT NULL , + Password VARCHAR(256) NULL , + AuthToken VARCHAR(16) CHARACTER SET ascii NULL , + Comments TEXT NULL , + Signature TEXT NULL , + EmailAddress varchar(120) NULL , + FreeformContactInfo TEXT NULL , + Organization varchar(200) NULL , + RealName varchar(120) NULL , + NickName varchar(16) NULL , + Lang varchar(16) NULL , + EmailEncoding varchar(16) NULL , + WebEncoding varchar(16) NULL , + ExternalContactInfoId varchar(100) NULL , + ContactInfoSystem varchar(30) NULL , + ExternalAuthId varchar(100) NULL , + AuthSystem varchar(30) NULL , + Gecos varchar(16) NULL , + HomePhone varchar(30) NULL , + WorkPhone varchar(30) NULL , + MobilePhone varchar(30) NULL , + PagerPhone varchar(30) NULL , + Address1 varchar(200) NULL , + Address2 varchar(200) NULL , + City varchar(100) NULL , + State varchar(100) NULL , + Zip varchar(16) NULL , + Country varchar(50) NULL , + Timezone varchar(50) NULL , + PGPKey text NULL, + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + + +CREATE UNIQUE INDEX Users1 ON Users (Name) ; +CREATE INDEX Users4 ON Users (EmailAddress); + + + + +CREATE TABLE Tickets ( + id INTEGER NOT NULL AUTO_INCREMENT, + EffectiveId integer NOT NULL DEFAULT 0 , + Queue integer NOT NULL DEFAULT 0 , + Type varchar(16) CHARACTER SET ascii NULL , + IssueStatement integer NOT NULL DEFAULT 0 , + Resolution integer NOT NULL DEFAULT 0 , + Owner integer NOT NULL DEFAULT 0 , + Subject varchar(200) NULL DEFAULT '[no subject]' , + InitialPriority integer NOT NULL DEFAULT 0 , + FinalPriority integer NOT NULL DEFAULT 0 , + Priority integer NOT NULL DEFAULT 0 , + TimeEstimated integer NOT NULL DEFAULT 0 , + TimeWorked integer NOT NULL DEFAULT 0 , + Status varchar(64) NULL , + TimeLeft integer NOT NULL DEFAULT 0 , + Told DATETIME NULL , + Starts DATETIME NULL , + Started DATETIME NULL , + Due DATETIME NULL , + Resolved DATETIME NULL , + + + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + Disabled int2 NOT NULL DEFAULT 0 , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX Tickets1 ON Tickets (Queue, Status) ; +CREATE INDEX Tickets2 ON Tickets (Owner) ; +CREATE INDEX Tickets6 ON Tickets (EffectiveId, Type) ; + + + +CREATE TABLE ScripActions ( + id INTEGER NOT NULL AUTO_INCREMENT, + Name varchar(200) NULL , + Description varchar(255) NULL , + ExecModule varchar(60) CHARACTER SET ascii NULL, + Argument VARBINARY(255) NULL , + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + + + +CREATE TABLE Templates ( + id INTEGER NOT NULL AUTO_INCREMENT, + Queue integer NOT NULL DEFAULT 0 , + Name varchar(200) NOT NULL , + Description varchar(255) NULL , + Type varchar(16) CHARACTER SET ascii NULL , + Language varchar(16) CHARACTER SET ascii NULL , + TranslationOf integer NOT NULL DEFAULT 0 , + Content TEXT NULL , + LastUpdated DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + + + +CREATE TABLE ObjectCustomFieldValues ( + id INTEGER NOT NULL AUTO_INCREMENT, + CustomField int NOT NULL , + ObjectType varchar(255) CHARACTER SET ascii NOT NULL, # Final target of the Object + ObjectId int NOT NULL , # New -- Replaces Ticket + SortOrder integer NOT NULL DEFAULT 0 , # New -- ordering for multiple values + + Content varchar(255) NULL , + LargeContent LONGBLOB NULL, # New -- to hold 255+ strings + ContentType varchar(80) CHARACTER SET ascii NULL, # New -- only text/* gets searched + ContentEncoding varchar(80) CHARACTER SET ascii NULL , # New -- for binary Content + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + Disabled int2 NOT NULL DEFAULT 0 , # New -- whether the value was current + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (Content); +CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId); + + + +CREATE TABLE CustomFields ( + id INTEGER NOT NULL AUTO_INCREMENT, + Name varchar(200) NULL , + Type varchar(200) CHARACTER SET ascii NULL , # Changed -- 'Single' and 'Multiple' is moved out + RenderType varchar(64) CHARACTER SET ascii NULL , + MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0) + Pattern TEXT NULL , # New -- Must validate against this + Repeated int2 NOT NULL DEFAULT 0 , # New -- repeated table entry + BasedOn INTEGER NULL, + ValuesClass varchar(64) CHARACTER SET ascii NULL , + Description varchar(255) NULL , + SortOrder integer NOT NULL DEFAULT 0 , + LookupType varchar(255) CHARACTER SET ascii NOT NULL, + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + Disabled int2 NOT NULL DEFAULT 0 , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + + + +CREATE TABLE ObjectCustomFields ( + id INTEGER NOT NULL AUTO_INCREMENT, + CustomField integer NOT NULL , + ObjectId integer NOT NULL, + SortOrder integer NOT NULL DEFAULT 0 , + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + + + +CREATE TABLE CustomFieldValues ( + id INTEGER NOT NULL AUTO_INCREMENT, + CustomField int NOT NULL , + Name varchar(200) NULL , + Description varchar(255) NULL , + SortOrder integer NOT NULL DEFAULT 0 , + Category VARCHAR(255) NULL, + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField); + + + + +CREATE TABLE Attributes ( + id INTEGER NOT NULL AUTO_INCREMENT, + Name varchar(255) NULL , + Description varchar(255) NULL , + Content BLOB, + ContentType varchar(16) CHARACTER SET ascii, + ObjectType varchar(64) CHARACTER SET ascii, + ObjectId integer, # foreign key to anything + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE INDEX Attributes1 on Attributes(Name); +CREATE INDEX Attributes2 on Attributes(ObjectType, ObjectId); + + + +# sessions is used by Apache::Session to keep sessions in the database. +# We should have a reaper script somewhere. + +CREATE TABLE sessions ( + id char(32) NOT NULL, + a_session LONGBLOB, + LastUpdated TIMESTAMP, + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET ascii; + +CREATE TABLE Classes ( + id int(11) NOT NULL auto_increment, + Name varchar(255) NOT NULL default '', + Description varchar(255) NOT NULL default '', + SortOrder int(11) NOT NULL default '0', + Disabled int(2) NOT NULL default '0', + Creator int(11) NOT NULL default '0', + Created datetime default NULL, + LastUpdatedBy int(11) NOT NULL default '0', + LastUpdated datetime default NULL, + HotList int(2) NOT NULL default '0', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE Articles ( + id int(11) NOT NULL auto_increment, + Name varchar(255) NOT NULL default '', + Summary varchar(255) NOT NULL default '', + SortOrder int(11) NOT NULL default '0', + Class int(11) NOT NULL default '0', + Parent int(11) NOT NULL default '0', + URI varchar(255) character set ascii default NULL, + Creator int(11) NOT NULL default '0', + Created datetime default NULL, + LastUpdatedBy int(11) NOT NULL default '0', + LastUpdated datetime default NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE Topics ( + id int(11) NOT NULL auto_increment, + Parent int(11) NOT NULL default '0', + Name varchar(255) NOT NULL default '', + Description varchar(255) NOT NULL default '', + ObjectType varchar(64) character set ascii NOT NULL default '', + ObjectId int(11) NOT NULL default '0', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE ObjectTopics ( + id int(11) NOT NULL auto_increment, + Topic int(11) NOT NULL default '0', + ObjectType varchar(64) character set ascii NOT NULL default '', + ObjectId int(11) NOT NULL default '0', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE ObjectClasses ( + id int(11) NOT NULL auto_increment, + Class int(11) NOT NULL default '0', + ObjectType varchar(255) character set ascii NOT NULL default '', + ObjectId int(11) NOT NULL default '0', + Creator int(11) NOT NULL default '0', + Created datetime default NULL, + LastUpdatedBy int(11) NOT NULL default '0', + LastUpdated datetime default NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/rt/etc/upgrade/3.9.1/content b/rt/etc/upgrade/3.9.1/content new file mode 100644 index 000000000..acdc0adb7 --- /dev/null +++ b/rt/etc/upgrade/3.9.1/content @@ -0,0 +1,68 @@ +@Initial = ( + sub { + use strict; + $RT::Logger->debug('Make sure templates all have known types'); + + # We update all NULL rows, below. We want to find non-NULL + # rows, which weren't created by the current codebase running + # through earlier initialdatas. Type != 'Perl' enforces the + # non-NULL part, as well + my $templates = RT::Templates->new(RT->SystemUser); + $templates->Limit( + FIELD => 'Type', + OPERATOR => '!=', + VALUE => 'Perl', + ); + + if ($templates->Count) { + die "You have templates with Type already set. This will interfere with your upgrade because RT used to ignore the template Type field, but now uses it."; + } + + $templates = RT::Templates->new(RT->SystemUser); + $templates->Limit( + FIELD => 'Type', + OPERATOR => 'IS', + VALUE => 'NULL', + ); + while (my $template = $templates->Next) { + my ($status, $msg) = $template->SetType('Perl'); + $RT::Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status; + } + }, + sub { + use strict; + $RT::Logger->debug('Adding ExecuteCode right to principals that currently have ModifyTemplate or ModifyScrips'); + + my $acl = RT::ACL->new(RT->SystemUser); + $acl->Limit( + FIELD => 'RightName', + OPERATOR => '=', + VALUE => 'ModifyTemplate', + ENTRYAGGREGATOR => 'OR', + ); + $acl->Limit( + FIELD => 'RightName', + OPERATOR => '=', + VALUE => 'ModifyScrips', + ENTRYAGGREGATOR => 'OR', + ); + + while (my $ace = $acl->Next) { + my $principal = $ace->PrincipalObj; + next if $principal->HasRight( + Right => 'ExecuteCode', + Object => $RT::System, + ); + + my ($ok, $msg) = $principal->GrantRight( + Right => 'ExecuteCode', + Object => $RT::System, + ); + + if (!$ok) { + $RT::Logger->warn("Unable to grant ExecuteCode on principal " . $principal->id . ": $msg"); + } + } + }, +); + diff --git a/rt/etc/upgrade/3.9.2/content b/rt/etc/upgrade/3.9.2/content new file mode 100644 index 000000000..d0dbbfd0a --- /dev/null +++ b/rt/etc/upgrade/3.9.2/content @@ -0,0 +1,48 @@ +@Initial = ( + sub { + use strict; + $RT::Logger->debug('Removing all delegated rights'); + + my $acl = RT::ACL->new(RT->SystemUser); + $acl->Limit( CLAUSE => 'search', + FIELD => 'DelegatedBy', + OPERATOR => '>', + VALUE => '0' + ); + $acl->Limit( CLAUSE => 'search', + FIELD => 'DelegatedFrom', + OPERATOR => '>', + VALUE => '0', + ENTRYAGGREGATOR => 'OR', + ); + + while ( my $ace = $acl->Next ) { + my ( $ok, $msg ) = $ace->Delete(); + + if ( !$ok ) { + $RT::Logger->warn( + "Unable to delete ACE " . $ace->id . ": " . $msg ); + } + } + + my $groups = RT::Groups->new(RT->SystemUser); + $groups->Limit( FIELD => 'Domain', + OPERATOR => '=', + VALUE => 'Personal' + ); + while ( my $group = $groups->Next ) { + my $members = $group->MembersObj(); + while ( my $member = $members->Next ) { + my ( $ok, $msg ) = $group->DeleteMember( $member->MemberId ); + if ( !$ok ) { + $RT::Logger->warn( "Unable to remove group member " + . $member->id . ": " + . $msg ); + } + } + $group->PrincipalObj->Delete; + $group->RT::Record::Delete(); + } + }, +); + diff --git a/rt/etc/upgrade/3.9.3/schema.Oracle b/rt/etc/upgrade/3.9.3/schema.Oracle new file mode 100644 index 000000000..4ee50c446 --- /dev/null +++ b/rt/etc/upgrade/3.9.3/schema.Oracle @@ -0,0 +1,2 @@ +ALTER TABLE ACL DROP COLUMN DelegatedBy; +ALTER TABLE ACL DROP COLUMN DelegatedFrom; diff --git a/rt/etc/upgrade/3.9.3/schema.Pg b/rt/etc/upgrade/3.9.3/schema.Pg new file mode 100644 index 000000000..4ee50c446 --- /dev/null +++ b/rt/etc/upgrade/3.9.3/schema.Pg @@ -0,0 +1,2 @@ +ALTER TABLE ACL DROP COLUMN DelegatedBy; +ALTER TABLE ACL DROP COLUMN DelegatedFrom; diff --git a/rt/etc/upgrade/3.9.3/schema.mysql b/rt/etc/upgrade/3.9.3/schema.mysql new file mode 100644 index 000000000..4ee50c446 --- /dev/null +++ b/rt/etc/upgrade/3.9.3/schema.mysql @@ -0,0 +1,2 @@ +ALTER TABLE ACL DROP COLUMN DelegatedBy; +ALTER TABLE ACL DROP COLUMN DelegatedFrom; diff --git a/rt/etc/upgrade/3.9.5/backcompat b/rt/etc/upgrade/3.9.5/backcompat new file mode 100644 index 000000000..611ab5186 --- /dev/null +++ b/rt/etc/upgrade/3.9.5/backcompat @@ -0,0 +1 @@ +RT::ACE LastUpdated LastUpdatedBy Creator Created diff --git a/rt/etc/upgrade/3.9.5/schema.Oracle b/rt/etc/upgrade/3.9.5/schema.Oracle new file mode 100644 index 000000000..065776dfb --- /dev/null +++ b/rt/etc/upgrade/3.9.5/schema.Oracle @@ -0,0 +1,20 @@ +alter Table CustomFieldValues ADD Category varchar2(255); + +UPDATE CustomFieldValues SET Category = (SELECT Content FROM Attributes WHERE +Name = 'Category' AND ObjectType = 'RT::CustomFieldValue' +AND CustomFieldValues.id = Attributes.ObjectId); + +DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue'; + +ALTER TABLE Groups ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL; +ALTER TABLE Groups ADD Created DATE; +ALTER TABLE Groups ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL; +ALTER TABLE Groups ADD LastUpdated DATE; +ALTER TABLE GroupMembers ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL; +ALTER TABLE GroupMembers ADD Created DATE; +ALTER TABLE GroupMembers ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL; +ALTER TABLE GroupMembers ADD LastUpdated DATE; +ALTER TABLE ACL ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL; +ALTER TABLE ACL ADD Created DATE; +ALTER TABLE ACL ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL; +ALTER TABLE ACL ADD LastUpdated DATE; diff --git a/rt/etc/upgrade/3.9.5/schema.Pg b/rt/etc/upgrade/3.9.5/schema.Pg new file mode 100644 index 000000000..cea2c4410 --- /dev/null +++ b/rt/etc/upgrade/3.9.5/schema.Pg @@ -0,0 +1,20 @@ +alter Table CustomFieldValues ADD Column Category varchar(255); + +UPDATE CustomFieldValues SET Category = (SELECT Content FROM Attributes WHERE +Name = 'Category' AND ObjectType = 'RT::CustomFieldValue' +AND CustomFieldValues.id = Attributes.ObjectId); + +DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue'; + +ALTER TABLE Groups ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE Groups ADD COLUMN Created TIMESTAMP NULL; +ALTER TABLE Groups ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE Groups ADD COLUMN LastUpdated TIMESTAMP NULL; +ALTER TABLE GroupMembers ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE GroupMembers ADD COLUMN Created TIMESTAMP NULL; +ALTER TABLE GroupMembers ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE GroupMembers ADD COLUMN LastUpdated TIMESTAMP NULL; +ALTER TABLE ACL ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE ACL ADD COLUMN Created TIMESTAMP NULL; +ALTER TABLE ACL ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE ACL ADD COLUMN LastUpdated TIMESTAMP NULL; diff --git a/rt/etc/upgrade/3.9.5/schema.SQLite b/rt/etc/upgrade/3.9.5/schema.SQLite new file mode 100644 index 000000000..c23f89bc7 --- /dev/null +++ b/rt/etc/upgrade/3.9.5/schema.SQLite @@ -0,0 +1,19 @@ +ALTER TABLE CustomFieldValues ADD Column Category varchar(255); +UPDATE CustomFieldValues SET Category = (SELECT Content FROM Attributes WHERE +Name = 'Category' AND ObjectType = 'RT::CustomFieldValue' +AND CustomFieldValues.id = Attributes.ObjectId); + +DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue'; + +ALTER TABLE Groups ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE Groups ADD COLUMN Created DATETIME NULL; +ALTER TABLE Groups ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE Groups ADD COLUMN LastUpdated DATETIME NULL; +ALTER TABLE GroupMembers ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE GroupMembers ADD COLUMN Created DATETIME NULL; +ALTER TABLE GroupMembers ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE GroupMembers ADD COLUMN LastUpdated DATETIME NULL; +ALTER TABLE ACL ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE ACL ADD COLUMN Created DATETIME NULL; +ALTER TABLE ACL ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE ACL ADD COLUMN LastUpdated DATETIME NULL; diff --git a/rt/etc/upgrade/3.9.5/schema.mysql b/rt/etc/upgrade/3.9.5/schema.mysql new file mode 100644 index 000000000..4bd0907c0 --- /dev/null +++ b/rt/etc/upgrade/3.9.5/schema.mysql @@ -0,0 +1,20 @@ +alter Table CustomFieldValues ADD Column Category varchar(255); + +UPDATE CustomFieldValues SET Category = (SELECT Content FROM Attributes WHERE +Name = 'Category' AND ObjectType = 'RT::CustomFieldValue' +AND CustomFieldValues.id = Attributes.ObjectId); + +DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue'; + +ALTER TABLE Groups ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE Groups ADD COLUMN Created DATETIME NULL; +ALTER TABLE Groups ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE Groups ADD COLUMN LastUpdated DATETIME NULL; +ALTER TABLE GroupMembers ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE GroupMembers ADD COLUMN Created DATETIME NULL; +ALTER TABLE GroupMembers ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE GroupMembers ADD COLUMN LastUpdated DATETIME NULL; +ALTER TABLE ACL ADD COLUMN Creator integer NOT NULL DEFAULT 0; +ALTER TABLE ACL ADD COLUMN Created DATETIME NULL; +ALTER TABLE ACL ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; +ALTER TABLE ACL ADD COLUMN LastUpdated DATETIME NULL; diff --git a/rt/etc/upgrade/3.9.6/schema.Oracle b/rt/etc/upgrade/3.9.6/schema.Oracle new file mode 100644 index 000000000..ecec972f4 --- /dev/null +++ b/rt/etc/upgrade/3.9.6/schema.Oracle @@ -0,0 +1 @@ +ALTER TABLE Tickets MODIFY Status VARCHAR2(64); diff --git a/rt/etc/upgrade/3.9.6/schema.Pg b/rt/etc/upgrade/3.9.6/schema.Pg new file mode 100644 index 000000000..f4f909edc --- /dev/null +++ b/rt/etc/upgrade/3.9.6/schema.Pg @@ -0,0 +1 @@ +ALTER TABLE Tickets ALTER Status TYPE varchar(64); diff --git a/rt/etc/upgrade/3.9.6/schema.SQLite b/rt/etc/upgrade/3.9.6/schema.SQLite new file mode 100644 index 000000000..2e7b6d307 --- /dev/null +++ b/rt/etc/upgrade/3.9.6/schema.SQLite @@ -0,0 +1,69 @@ +BEGIN TRANSACTION; +CREATE TEMPORARY TABLE Tickets_backup ( + id INTEGER PRIMARY KEY , + EffectiveId integer NULL , + Queue integer NULL , + Type varchar(16) NULL , + IssueStatement integer NULL , + Resolution integer NULL , + Owner integer NULL , + Subject varchar(200) NULL DEFAULT '[no subject]' , + InitialPriority integer NULL , + FinalPriority integer NULL , + Priority integer NULL , + TimeEstimated integer NULL , + TimeWorked integer NULL , + Status varchar(64) NULL , + TimeLeft integer NULL , + Told DATETIME NULL , + Starts DATETIME NULL , + Started DATETIME NULL , + Due DATETIME NULL , + Resolved DATETIME NULL , + LastUpdatedBy integer NULL , + LastUpdated DATETIME NULL , + Creator integer NULL , + Created DATETIME NULL , + Disabled int2 NOT NULL DEFAULT 0 +); + +INSERT INTO Tickets_backup SELECT * FROM Tickets; +DROP TABLE Tickets; + +CREATE TABLE Tickets ( + id INTEGER PRIMARY KEY , + EffectiveId integer NULL , + Queue integer NULL , + Type varchar(16) NULL , + IssueStatement integer NULL , + Resolution integer NULL , + Owner integer NULL , + Subject varchar(200) NULL DEFAULT '[no subject]' , + InitialPriority integer NULL , + FinalPriority integer NULL , + Priority integer NULL , + TimeEstimated integer NULL , + TimeWorked integer NULL , + Status varchar(64) NULL , + TimeLeft integer NULL , + Told DATETIME NULL , + Starts DATETIME NULL , + Started DATETIME NULL , + Due DATETIME NULL , + Resolved DATETIME NULL , + LastUpdatedBy integer NULL , + LastUpdated DATETIME NULL , + Creator integer NULL , + Created DATETIME NULL , + Disabled int2 NOT NULL DEFAULT 0 +); + +CREATE INDEX Tickets1 ON Tickets (Queue, Status) ; +CREATE INDEX Tickets2 ON Tickets (Owner) ; +CREATE INDEX Tickets3 ON Tickets (EffectiveId) ; +CREATE INDEX Tickets4 ON Tickets (id, Status) ; +CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ; + +INSERT INTO Tickets SELECT * FROM Tickets_backup; +DROP TABLE Tickets_backup; +COMMIT; diff --git a/rt/etc/upgrade/3.9.6/schema.mysql b/rt/etc/upgrade/3.9.6/schema.mysql new file mode 100644 index 000000000..b0a9eaf9f --- /dev/null +++ b/rt/etc/upgrade/3.9.6/schema.mysql @@ -0,0 +1 @@ +ALTER TABLE Tickets Modify Status varchar(64); diff --git a/rt/etc/upgrade/3.9.7/content b/rt/etc/upgrade/3.9.7/content new file mode 100644 index 000000000..504ddf18f --- /dev/null +++ b/rt/etc/upgrade/3.9.7/content @@ -0,0 +1,82 @@ +my $move_attributes = sub { + my ($table, $type, $column) = @_; + my $query = "UPDATE $table SET $column = (SELECT Content FROM Attributes WHERE" + ." Name = ? AND ObjectType = ? AND $table.id = Attributes.ObjectId)"; + + my $res = $RT::Handle->SimpleQuery( $query, $column, $type ); + unless ( $res ) { + $RT::Logger->error("Failed to move $column on $type from Attributes into $table table"); + return; + } + + $query = 'DELETE FROM Attributes WHERE Name = ? AND ObjectType = ?'; + $res = $RT::Handle->SimpleQuery( $query, $column, $type ); + unless ( $res ) { + $RT::Logger->error("Failed to delete $column on $type from Attributes"); + return; + } + return 1; +}; + +@Initial = ( + sub { + return $move_attributes->( 'Users', 'RT::User', 'AuthToken'); + }, + sub { + return $move_attributes->( 'CustomFields', 'RT::CustomField', 'RenderType'); + }, + sub { + my $cfs = RT::CustomFields->new($RT::SystemUser); + $cfs->UnLimit; + $cfs->FindAllRows; + while ( my $cf = $cfs->Next ) { + # Explicitly remove 'ORDER BY id asc' to emulate the + # previous functionality, where Pg might return the the + # rows in arbitrary order + $cf->Attributes->OrderByCols(); + + my $attr = $cf->FirstAttribute('BasedOn'); + next unless $attr; + $cf->SetBasedOn($attr->Content); + } + $query = 'DELETE FROM Attributes WHERE Name = ? AND ObjectType = ?'; + $res = $RT::Handle->SimpleQuery( $query, 'BasedOn', 'RT::CustomField' ); + unless ( $res ) { + $RT::Logger->error("Failed to delete BasedOn CustomFields from Attributes"); + return; + } + return 1; + }, + sub { + $move_attributes->( 'CustomFields', 'RT::CustomField', 'ValuesClass') + or return; + + my $query = "UPDATE CustomFields SET ValuesClass = NULL WHERE ValuesClass = ?"; + my $res = $RT::Handle->SimpleQuery( $query, 'RT::CustomFieldValues' ); + unless ( $res ) { + $RT::Logger->error("Failed to replace default with NULLs"); + return; + } + return 1; + }, + sub { + my $attr = RT->System->FirstAttribute('BrandedSubjectTag'); + return 1 unless $attr; + + my $map = $attr->Content || {}; + while ( my ($qid, $tag) = each %$map ) { + my $queue = RT::Queue->new( RT->SystemUser ); + $queue->Load( $qid ); + unless ( $queue->id ) { + $RT::Logger->warning("Couldn't load queue #$qid. Skipping..."); + next; + } + + my ($status, $msg) = $queue->SetSubjectTag($tag); + unless ( $status ) { + $RT::Logger->error("Couldn't set subject tag for queue #$qid: $msg"); + next; + } + } + }, +); diff --git a/rt/etc/upgrade/3.9.7/schema.Oracle b/rt/etc/upgrade/3.9.7/schema.Oracle new file mode 100644 index 000000000..3c75c917d --- /dev/null +++ b/rt/etc/upgrade/3.9.7/schema.Oracle @@ -0,0 +1,6 @@ +ALTER TABLE Users ADD AuthToken VARCHAR2(16) NULL; +ALTER TABLE CustomFields ADD BasedOn NUMBER(11,0) NULL; +ALTER TABLE CustomFields ADD RenderType VARCHAR2(64) NULL; +ALTER TABLE CustomFields ADD ValuesClass VARCHAR2(64) NULL; +ALTER TABLE Queues ADD SubjectTag VARCHAR2(120) NULL; +ALTER TABLE Queues ADD Lifecycle VARCHAR2(32) NULL; diff --git a/rt/etc/upgrade/3.9.7/schema.Pg b/rt/etc/upgrade/3.9.7/schema.Pg new file mode 100644 index 000000000..1704fa673 --- /dev/null +++ b/rt/etc/upgrade/3.9.7/schema.Pg @@ -0,0 +1,6 @@ +ALTER TABLE Users ADD COLUMN AuthToken VARCHAR(16) NULL; +ALTER TABLE CustomFields ADD COLUMN BasedOn INTEGER NULL; +ALTER TABLE CustomFields ADD COLUMN RenderType VARCHAR(64) NULL; +ALTER TABLE CustomFields ADD COLUMN ValuesClass VARCHAR(64) NULL; +ALTER TABLE Queues ADD COLUMN SubjectTag VARCHAR(120) NULL; +ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR(32) NULL; diff --git a/rt/etc/upgrade/3.9.7/schema.SQLite b/rt/etc/upgrade/3.9.7/schema.SQLite new file mode 100644 index 000000000..1704fa673 --- /dev/null +++ b/rt/etc/upgrade/3.9.7/schema.SQLite @@ -0,0 +1,6 @@ +ALTER TABLE Users ADD COLUMN AuthToken VARCHAR(16) NULL; +ALTER TABLE CustomFields ADD COLUMN BasedOn INTEGER NULL; +ALTER TABLE CustomFields ADD COLUMN RenderType VARCHAR(64) NULL; +ALTER TABLE CustomFields ADD COLUMN ValuesClass VARCHAR(64) NULL; +ALTER TABLE Queues ADD COLUMN SubjectTag VARCHAR(120) NULL; +ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR(32) NULL; diff --git a/rt/etc/upgrade/3.9.7/schema.mysql b/rt/etc/upgrade/3.9.7/schema.mysql new file mode 100644 index 000000000..1be165647 --- /dev/null +++ b/rt/etc/upgrade/3.9.7/schema.mysql @@ -0,0 +1,6 @@ +ALTER TABLE Users ADD COLUMN AuthToken VARCHAR(16) CHARACTER SET ascii NULL; +ALTER TABLE CustomFields ADD COLUMN BasedOn INTEGER NULL; +ALTER TABLE CustomFields ADD COLUMN RenderType VARCHAR(64) NULL; +ALTER TABLE CustomFields ADD COLUMN ValuesClass VARCHAR(64) CHARACTER SET ascii NULL; +ALTER TABLE Queues ADD COLUMN SubjectTag VARCHAR(120) NULL; +ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR(32) NULL; diff --git a/rt/etc/upgrade/3.9.8/content b/rt/etc/upgrade/3.9.8/content new file mode 100644 index 000000000..d759db9cd --- /dev/null +++ b/rt/etc/upgrade/3.9.8/content @@ -0,0 +1,24 @@ +@Initial = sub { + my $dbh = $RT::Handle->dbh; + my $sth = $dbh->table_info( '', undef, undef, "'TABLE'"); + my $found_fm_tables = {}; + while ( my $table = $sth->fetchrow_hashref ) { + my $name = $table->{TABLE_NAME} || $table->{table_name}; + next unless $name =~ /^fm_/i; + $found_fm_tables->{lc $name}++; + } + + return unless %$found_fm_tables; + + unless ( $found_fm_tables->{fm_topics} && $found_fm_tables->{fm_objecttopics} ) { + $RT::Logger->error("You appear to be upgrading from RTFM 2.0 - We don't support upgrading this old of an RTFM yet"); + } + + $RT::Logger->error("We found RTFM tables in your database. Checking for content."); + + my $result = $dbh->selectall_arrayref("SELECT count(*) AS articlecount FROM FM_Articles", { Slice => {} } ); + + if ($result->[0]{articlecount} > 0) { + $RT::Logger->error("You appear to have RTFM Articles. You can upgrade using the etc/upgrade/upgrade-articles script. Read more about it in UPGRADING"); + } +}; diff --git a/rt/etc/upgrade/3.9.8/schema.Oracle b/rt/etc/upgrade/3.9.8/schema.Oracle new file mode 100644 index 000000000..4f823731f --- /dev/null +++ b/rt/etc/upgrade/3.9.8/schema.Oracle @@ -0,0 +1,65 @@ +CREATE SEQUENCE Classes_seq; +CREATE TABLE Classes ( +id NUMBER(11,0) + CONSTRAINT Classes_key PRIMARY KEY, +Name varchar2(255) DEFAULT '', +Description varchar2(255) DEFAULT '', +SortOrder NUMBER(11,0) DEFAULT 0 NOT NULL, +Disabled NUMBER(11,0) DEFAULT 0 NOT NULL, +Creator NUMBER(11,0) DEFAULT 0 NOT NULL, +Created DATE, +LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, +LastUpdated DATE, +HotList NUMBER(11,0) DEFAULT 0 NOT NULL +); + +CREATE SEQUENCE Articles_seq; +CREATE TABLE Articles ( +id NUMBER(11,0) + CONSTRAINT Articles_key PRIMARY KEY, +Name varchar2(255) DEFAULT '', +Summary varchar2(255) DEFAULT '', +SortOrder NUMBER(11,0) DEFAULT 0 NOT NULL, +Class NUMBER(11,0) DEFAULT 0 NOT NULL, +Parent NUMBER(11,0) DEFAULT 0 NOT NULL, +URI varchar2(255), +Creator NUMBER(11,0) DEFAULT 0 NOT NULL, +Created DATE, +LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, +LastUpdated DATE +); + + +CREATE SEQUENCE Topics_seq; +CREATE TABLE Topics ( +id NUMBER(11,0) + CONSTRAINT Topics_key PRIMARY KEY, +Parent NUMBER(11,0) DEFAULT 0 NOT NULL, +Name varchar2(255) DEFAULT '', +Description varchar2(255) DEFAULT '', +ObjectType varchar2(64) DEFAULT '' NOT NULL, +ObjectId NUMBER(11,0) NOT NULL +); + + +CREATE SEQUENCE ObjectTopics_seq; +CREATE TABLE ObjectTopics ( +id NUMBER(11,0) + CONSTRAINT ObjectTopics_key PRIMARY KEY, +Topic NUMBER(11,0) NOT NULL, +ObjectType varchar2(64) DEFAULT '' NOT NULL, +ObjectId NUMBER(11,0) NOT NULL +); + +CREATE SEQUENCE ObjectClasses_seq; +CREATE TABLE ObjectClasses ( +id NUMBER(11,0) + CONSTRAINT ObjectClasses_key PRIMARY KEY, +Class NUMBER(11,0) NOT NULL, +ObjectType varchar2(255) DEFAULT '' NOT NULL, +ObjectId NUMBER(11,0) NOT NULL, +Creator NUMBER(11,0) DEFAULT 0 NOT NULL, +Created DATE, +LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, +LastUpdated DATE +); diff --git a/rt/etc/upgrade/3.9.8/schema.Pg b/rt/etc/upgrade/3.9.8/schema.Pg new file mode 100644 index 000000000..d12e27a73 --- /dev/null +++ b/rt/etc/upgrade/3.9.8/schema.Pg @@ -0,0 +1,62 @@ +CREATE TABLE Classes ( +id SERIAL, +Name varchar(255) NOT NULL DEFAULT '', +Description varchar(255) NOT NULL DEFAULT '', +SortOrder integer NOT NULL DEFAULT 0, +Disabled smallint NOT NULL DEFAULT 0, +Creator integer NOT NULL DEFAULT 0, +Created TIMESTAMP NULL, +LastUpdatedBy integer NOT NULL DEFAULT 0, +LastUpdated TIMESTAMP NULL, +HotList smallint NOT NULL DEFAULT 0, +PRIMARY KEY (id) +); + +CREATE TABLE Articles ( +id SERIAL, +Name varchar(255) NOT NULL DEFAULT '', +Summary varchar(255) NOT NULL DEFAULT '', +SortOrder integer NOT NULL DEFAULT 0, +Class integer NOT NULL DEFAULT 0, +Parent integer NOT NULL DEFAULT 0, +URI varchar(255), +Creator integer NOT NULL DEFAULT 0, +Created TIMESTAMP NULL, +LastUpdatedBy integer NOT NULL DEFAULT 0, +LastUpdated TIMESTAMP NULL, +PRIMARY KEY (id) +); + + +CREATE TABLE Topics ( +id SERIAL, +Parent integer NOT NULL DEFAULT 0, +Name varchar(255) NOT NULL DEFAULT '', +Description varchar(255) NOT NULL DEFAULT '', +ObjectType varchar(64) NOT NULL DEFAULT '', +ObjectId integer NOT NULL, +PRIMARY KEY (id) +); + + +CREATE TABLE ObjectTopics ( +id SERIAL, +Topic integer NOT NULL, +ObjectType varchar(64) NOT NULL DEFAULT '', +ObjectId integer NOT NULL, +PRIMARY KEY (id) +); + + +CREATE TABLE ObjectClasses ( +id SERIAL, +Class integer NOT NULL, +ObjectType varchar(255) NOT NULL DEFAULT '', +ObjectId integer NOT NULL, +Creator integer NOT NULL DEFAULT 0, +Created TIMESTAMP NULL, +LastUpdatedBy integer NOT NULL DEFAULT 0, +LastUpdated TIMESTAMP NULL, +PRIMARY KEY (id) +); + diff --git a/rt/etc/upgrade/3.9.8/schema.SQLite b/rt/etc/upgrade/3.9.8/schema.SQLite new file mode 100644 index 000000000..29ed7e87a --- /dev/null +++ b/rt/etc/upgrade/3.9.8/schema.SQLite @@ -0,0 +1,55 @@ +CREATE TABLE Classes ( +id INTEGER PRIMARY KEY, +Name varchar(255) NOT NULL DEFAULT '', +Description varchar(255) NOT NULL DEFAULT '', +SortOrder integer NOT NULL DEFAULT 0, +Disabled smallint NOT NULL DEFAULT 0, +Creator integer NOT NULL DEFAULT 0, +Created TIMESTAMP NULL, +LastUpdatedBy integer NOT NULL DEFAULT 0, +LastUpdated TIMESTAMP NULL, +HotList smallint NOT NULL DEFAULT 0 +); + +CREATE TABLE Articles ( +id INTEGER PRIMARY KEY, +Name varchar(255) NOT NULL DEFAULT '', +Summary varchar(255) NOT NULL DEFAULT '', +SortOrder integer NOT NULL DEFAULT 0, +Class integer NOT NULL DEFAULT 0, +Parent integer NOT NULL DEFAULT 0, +URI varchar(255), +Creator integer NOT NULL DEFAULT 0, +Created TIMESTAMP NULL, +LastUpdatedBy integer NOT NULL DEFAULT 0, +LastUpdated TIMESTAMP NULL +); + + +CREATE TABLE Topics ( +id INTEGER PRIMARY KEY, +Parent integer NOT NULL DEFAULT 0, +Name varchar(255) NOT NULL DEFAULT '', +Description varchar(255) NOT NULL DEFAULT '', +ObjectType varchar(64) NOT NULL DEFAULT '', +ObjectId integer NOT NULL +); + + +CREATE TABLE ObjectTopics ( +id INTEGER PRIMARY KEY, +Topic integer NOT NULL, +ObjectType varchar(64) NOT NULL DEFAULT '', +ObjectId integer NOT NULL +); + +CREATE TABLE ObjectClasses ( +id INTEGER PRIMARY KEY, +Class integer NOT NULL, +ObjectType varchar(64) NOT NULL DEFAULT '', +ObjectId integer NOT NULL, +Creator integer NOT NULL DEFAULT 0, +Created TIMESTAMP NULL, +LastUpdatedBy integer NOT NULL DEFAULT 0, +LastUpdated TIMESTAMP NULL +); diff --git a/rt/etc/upgrade/3.9.8/schema.mysql b/rt/etc/upgrade/3.9.8/schema.mysql new file mode 100644 index 000000000..e7ed84de7 --- /dev/null +++ b/rt/etc/upgrade/3.9.8/schema.mysql @@ -0,0 +1,58 @@ +CREATE TABLE Classes ( + id int(11) NOT NULL auto_increment, + Name varchar(255) NOT NULL default '', + Description varchar(255) NOT NULL default '', + SortOrder int(11) NOT NULL default '0', + Disabled int(2) NOT NULL default '0', + Creator int(11) NOT NULL default '0', + Created datetime default NULL, + LastUpdatedBy int(11) NOT NULL default '0', + LastUpdated datetime default NULL, + HotList int(2) NOT NULL default '0', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE Articles ( + id int(11) NOT NULL auto_increment, + Name varchar(255) NOT NULL default '', + Summary varchar(255) NOT NULL default '', + SortOrder int(11) NOT NULL default '0', + Class int(11) NOT NULL default '0', + Parent int(11) NOT NULL default '0', + URI varchar(255) character set ascii default NULL, + Creator int(11) NOT NULL default '0', + Created datetime default NULL, + LastUpdatedBy int(11) NOT NULL default '0', + LastUpdated datetime default NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE Topics ( + id int(11) NOT NULL auto_increment, + Parent int(11) NOT NULL default '0', + Name varchar(255) NOT NULL default '', + Description varchar(255) NOT NULL default '', + ObjectType varchar(64) character set ascii NOT NULL default '', + ObjectId int(11) NOT NULL default '0', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE ObjectTopics ( + id int(11) NOT NULL auto_increment, + Topic int(11) NOT NULL default '0', + ObjectType varchar(64) character set ascii NOT NULL default '', + ObjectId int(11) NOT NULL default '0', + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE ObjectClasses ( + id int(11) NOT NULL auto_increment, + Class int(11) NOT NULL default '0', + ObjectType varchar(255) character set ascii NOT NULL default '', + ObjectId int(11) NOT NULL default '0', + Creator int(11) NOT NULL default '0', + Created datetime default NULL, + LastUpdatedBy int(11) NOT NULL default '0', + LastUpdated datetime default NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/rt/etc/upgrade/4.0.0rc2/schema.mysql b/rt/etc/upgrade/4.0.0rc2/schema.mysql new file mode 100644 index 000000000..9431213ec --- /dev/null +++ b/rt/etc/upgrade/4.0.0rc2/schema.mysql @@ -0,0 +1,10 @@ + +DROP TABLE IF EXISTS sessions; + +CREATE TABLE sessions ( + id char(32) NOT NULL, + a_session LONGBLOB, + LastUpdated TIMESTAMP, + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET ascii; + diff --git a/rt/etc/upgrade/4.0.0rc4/schema.Oracle b/rt/etc/upgrade/4.0.0rc4/schema.Oracle new file mode 100644 index 000000000..0df9d65c2 --- /dev/null +++ b/rt/etc/upgrade/4.0.0rc4/schema.Oracle @@ -0,0 +1 @@ +ALTER TABLE Users MODIFY Password VARCHAR2(256); diff --git a/rt/etc/upgrade/4.0.0rc4/schema.Pg b/rt/etc/upgrade/4.0.0rc4/schema.Pg new file mode 100644 index 000000000..728081041 --- /dev/null +++ b/rt/etc/upgrade/4.0.0rc4/schema.Pg @@ -0,0 +1 @@ +ALTER TABLE Users ALTER Password TYPE varchar(256); diff --git a/rt/etc/upgrade/4.0.0rc4/schema.mysql b/rt/etc/upgrade/4.0.0rc4/schema.mysql new file mode 100644 index 000000000..2f562bd4d --- /dev/null +++ b/rt/etc/upgrade/4.0.0rc4/schema.mysql @@ -0,0 +1 @@ +ALTER TABLE Users MODIFY Password varchar(256); diff --git a/rt/etc/upgrade/4.0.0rc7/content b/rt/etc/upgrade/4.0.0rc7/content new file mode 100644 index 000000000..d0d210b7b --- /dev/null +++ b/rt/etc/upgrade/4.0.0rc7/content @@ -0,0 +1,21 @@ +@Initial = ( + sub { + $RT::Logger->debug("Going to set lifecycle for approvals"); + + my $queue = RT::Queue->new( RT->SystemUser ); + $queue->Load('___Approvals'); + unless ( $queue->id ) { + $RT::Logger->warning("There is no ___Approvals queue in the DB"); + return 1; + } + + return 1 if $queue->Lifecycle->Name eq 'approvals'; + + my ($status, $msg) = $queue->SetLifecycle('approvals'); + unless ( $status ) { + $RT::Logger->error("Couldn't set lifecycle for '___Approvals' queue: $msg"); + return 0; + } + return 1; + }, +); diff --git a/rt/etc/upgrade/4.0.1/acl.Pg b/rt/etc/upgrade/4.0.1/acl.Pg new file mode 100644 index 000000000..6b0e7bb3d --- /dev/null +++ b/rt/etc/upgrade/4.0.1/acl.Pg @@ -0,0 +1,39 @@ + +sub acl { + my $dbh = shift; + + my @acls; + + my @tables = qw ( + classes_id_seq + Classes + articles_id_seq + Articles + topics_id_seq + Topics + objecttopics_id_seq + ObjectTopics + objectclasses_id_seq + ObjectClasses + ); + + my $db_user = RT->Config->Get('DatabaseUser'); + + my $sequence_right + = ( $dbh->{pg_server_version} >= 80200 ) + ? "USAGE, SELECT, UPDATE" + : "SELECT, UPDATE"; + + foreach my $table (@tables) { + # Tables are upper-case, sequences are lowercase + if ( $table =~ /^[a-z]/ ) { + push @acls, "GRANT $sequence_right ON $table TO \"$db_user\";" + } + else { + push @acls, "GRANT SELECT, INSERT, UPDATE, DELETE ON $table TO \"$db_user\";" + } + } + return (@acls); +} + +1; diff --git a/rt/etc/upgrade/4.0.1/content b/rt/etc/upgrade/4.0.1/content new file mode 100644 index 000000000..9b74ff1a8 --- /dev/null +++ b/rt/etc/upgrade/4.0.1/content @@ -0,0 +1,83 @@ +@Initial = ( + sub { + use strict; + $RT::Logger->debug('Removing all delegated rights'); + + my $acl = RT::ACL->new(RT->SystemUser); + my $groupjoin = $acl->NewAlias('Groups'); + $acl->Join( ALIAS1 => 'main', + FIELD1 => 'PrincipalId', + ALIAS2 => $groupjoin, + FIELD2 => 'id' + ); + $acl->Limit( ALIAS => $groupjoin, + FIELD => 'Domain', + OPERATOR => '=', + VALUE => 'Personal', + ); + + while ( my $ace = $acl->Next ) { + my ( $ok, $msg ) = $ace->Delete(); + + if ( !$ok ) { + $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); + } + } + + my $groups = RT::Groups->new(RT->SystemUser); + $groups->Limit( FIELD => 'Domain', + OPERATOR => '=', + VALUE => 'Personal' + ); + while ( my $group = $groups->Next ) { + my $members = $group->MembersObj(); + while ( my $member = $members->Next ) { + my ( $ok, $msg ) = $group->DeleteMember( $member->MemberId ); + if ( !$ok ) { + $RT::Logger->warn( "Unable to remove group member " + . $member->id . ": " + . $msg ); + } + } + $group->PrincipalObj->Delete; + $group->RT::Record::Delete(); + } + }, + sub { + use strict; + $RT::Logger->debug('Removing all Delegate and PersonalGroup rights'); + + my $acl = RT::ACL->new(RT->SystemUser); + for my $right (qw/AdminOwnPersonalGroups AdminAllPersonalGroups DelegateRights/) { + $acl->Limit( FIELD => 'RightName', VALUE => $right ); + } + + while ( my $ace = $acl->Next ) { + my ( $ok, $msg ) = $ace->Delete(); + $RT::Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName')); + + if ( !$ok ) { + $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); + } + } + }, + sub { + use strict; + $RT::Logger->debug('Removing unimplemented RejectTicket and ModifyTicketStatus rights'); + + my $acl = RT::ACL->new(RT->SystemUser); + for my $right (qw/RejectTicket ModifyTicketStatus/) { + $acl->Limit( FIELD => 'RightName', VALUE => $right ); + } + + while ( my $ace = $acl->Next ) { + my ( $ok, $msg ) = $ace->Delete(); + $RT::Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName')); + + if ( !$ok ) { + $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); + } + } + }, +); + diff --git a/rt/etc/upgrade/4.0.3/content b/rt/etc/upgrade/4.0.3/content new file mode 100644 index 000000000..3e06c89d0 --- /dev/null +++ b/rt/etc/upgrade/4.0.3/content @@ -0,0 +1,23 @@ +@ScripConditions = ( + { + + Name => 'On Forward', # loc + Description => 'Whenever a ticket or transaction is forwarded', # loc + ApplicableTransTypes => 'Forward Transaction,Forward Ticket', + ExecModule => 'AnyTransaction', }, + + { + + Name => 'On Forward Ticket', # loc + Description => 'Whenever a ticket is forwarded', # loc + ApplicableTransTypes => 'Forward Ticket', + ExecModule => 'AnyTransaction', }, + + { + + Name => 'On Forward Transaction', # loc + Description => 'Whenever a transaction is forwarded', # loc + ApplicableTransTypes => 'Forward Transaction', + ExecModule => 'AnyTransaction', }, + +); diff --git a/rt/etc/upgrade/4.0.4/content b/rt/etc/upgrade/4.0.4/content new file mode 100644 index 000000000..fdfcb3e27 --- /dev/null +++ b/rt/etc/upgrade/4.0.4/content @@ -0,0 +1,16 @@ +@Initial = ( + sub { + use strict; + my $templates = RT::Templates->new(RT->SystemUser); + $templates->Limit( + FIELD => 'Type', + OPERATOR => 'IS', + VALUE => 'NULL', + ); + while (my $template = $templates->Next) { + my ($status, $msg) = $template->SetType('Perl'); + $RT::Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status; + } + }, +); + diff --git a/rt/etc/upgrade/sanity-check-stylesheets.pl b/rt/etc/upgrade/sanity-check-stylesheets.pl new file mode 100644 index 000000000..eff469fd6 --- /dev/null +++ b/rt/etc/upgrade/sanity-check-stylesheets.pl @@ -0,0 +1,87 @@ +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# <sales@bestpractical.com> +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# +# CONTRIBUTION SUBMISSION POLICY: +# +# (The following paragraph is not intended to limit the rights granted +# to you to modify and distribute this software under the terms of +# the GNU General Public License and is only of importance to you if +# you choose to contribute your changes and enhancements to the +# community by submitting them to Best Practical Solutions, LLC.) +# +# By intentionally submitting any modifications, corrections or +# derivatives to this work, or any other work intended for use with +# Request Tracker, to Best Practical Solutions, LLC, you confirm that +# you are the copyright holder for those contributions and you grant +# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +# royalty-free, perpetual, license to use, copy, create derivative +# works based on those contributions, and sublicense and distribute +# those contributions and any derivatives thereof. +# +# END BPS TAGGED BLOCK }}} +use strict; +use warnings; + +use RT; +RT::LoadConfig(); +RT->Config->Set('LogToScreen' => 'debug'); +RT::Init(); + +$| = 1; + +use RT::Users; +my $users = RT::Users->new( $RT::SystemUser ); +$users->UnLimit(); + +my @comp_roots = RT::Interface::Web->ComponentRoots; +my %comp_root_check_cache; +sub stylesheet_exists { + my $stylesheet = shift; + + return $comp_root_check_cache{$stylesheet} + if exists $comp_root_check_cache{$stylesheet}; + + for my $comp_root (@comp_roots) { + return ++$comp_root_check_cache{$stylesheet} + if -d "$comp_root/NoAuth/css/$stylesheet"; + } + + return $comp_root_check_cache{$stylesheet} = 0; +} + +my $system_stylesheet = RT->Config->Get('WebDefaultStylesheet'); + +while (my $u = $users->Next) { + my $stylesheet = RT->Config->Get('WebDefaultStylesheet', $u); + unless (stylesheet_exists $stylesheet) { + my $prefs = $u->Preferences($RT::System); + $prefs->{WebDefaultStylesheet} = $system_stylesheet; + $u->SetPreferences($RT::System, $prefs); + } +} diff --git a/rt/etc/upgrade/upgrade-articles b/rt/etc/upgrade/upgrade-articles new file mode 100755 index 000000000..eef00aa67 --- /dev/null +++ b/rt/etc/upgrade/upgrade-articles @@ -0,0 +1,264 @@ +#!/usr/bin/perl +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# <sales@bestpractical.com> +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# +# CONTRIBUTION SUBMISSION POLICY: +# +# (The following paragraph is not intended to limit the rights granted +# to you to modify and distribute this software under the terms of +# the GNU General Public License and is only of importance to you if +# you choose to contribute your changes and enhancements to the +# community by submitting them to Best Practical Solutions, LLC.) +# +# By intentionally submitting any modifications, corrections or +# derivatives to this work, or any other work intended for use with +# Request Tracker, to Best Practical Solutions, LLC, you confirm that +# you are the copyright holder for those contributions and you grant +# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +# royalty-free, perpetual, license to use, copy, create derivative +# works based on those contributions, and sublicense and distribute +# those contributions and any derivatives thereof. +# +# END BPS TAGGED BLOCK }}} +use strict; +use warnings; + +use lib "/opt/rt3/local/lib"; +use lib "/opt/rt3/lib"; + +use RT; +RT::LoadConfig(); +RT->Config->Set('LogToScreen' => 'debug'); +RT::Init(); + +$| = 1; + +my $db_name = RT->Config->Get('DatabaseName'); +my $db_type = RT->Config->Get('DatabaseType'); + +my $dbh = $RT::Handle->dbh; + +my $sth = $dbh->table_info( '', undef, undef, "'TABLE'"); +my $found_fm_tables; +while ( my $table = $sth->fetchrow_hashref ) { + my $name = $table->{TABLE_NAME} || $table->{'table_name'}; # Oracle's table_info affected by NAME_lc + next unless $name =~ /^fm_/i; + $found_fm_tables->{lc $name}++; +} + +unless ( $found_fm_tables->{fm_topics} && $found_fm_tables->{fm_objecttopics} ) { + warn "Couldn't find topics tables, it appears you have RTFM 2.0 or earlier."; + warn "This script cannot yet upgrade RTFM versions which are that old"; + exit; +} + +{ # port over Articles + my @columns = qw(id Name Summary SortOrder Class Parent URI Creator Created LastUpdatedBy LastUpdated); + copy_tables('FM_Articles','Articles',\@columns); + +} + + +{ # port over Classes + my @columns = qw(id Name Description SortOrder Disabled Creator Created LastUpdatedBy LastUpdated); + if ( grep lc($_) eq 'hotlist', $RT::Handle->Fields('FM_Classes') ) { + push @columns, 'HotList'; + } + copy_tables('FM_Classes','Classes',\@columns); +} + +{ # port over Topics + my @columns = qw(id Parent Name Description ObjectType ObjectId); + copy_tables('FM_Topics','Topics',\@columns); +} + +{ # port over ObjectTopics + my @columns = qw(id Topic ObjectType ObjectId); + copy_tables('FM_ObjectTopics','ObjectTopics',\@columns); +} + +sub copy_tables { + my ($source, $dest, $columns) = @_; + my $column_list = join(', ',@$columns); + my $sql; + # SQLite: http://www.sqlite.org/lang_insert.html + if ( $db_type eq 'mysql' || $db_type eq 'SQLite' ) { + $sql = "insert into $dest ($column_list) select $column_list from $source"; + } + # Oracle: http://www.adp-gmbh.ch/ora/sql/insert/select_and_subquery.html + elsif ( $db_type eq 'Pg' || $db_type eq 'Oracle' ) { + $sql = "insert into $dest ($column_list) (select $column_list from $source)"; + } + $RT::Logger->debug($sql); + $dbh->do($sql); +} + +{ # create ObjectClasses + # this logic will need updating when folks have an FM_ObjectClasses table + use RT::Classes; + use RT::ObjectClass; + + my $classes = RT::Classes->new(RT->SystemUser); + $classes->UnLimit; + while ( my $class = $classes->Next ) { + my $objectclass = RT::ObjectClass->new(RT->SystemUser); + my ($ret, $msg ) = $objectclass->Create( Class => $class->Id, ObjectType => 'RT::System', ObjectId => 0 ); + if ($ret) { + warn("Applied Class '".$class->Name."' globally"); + } else { + warn("Couldn't create linkage for Class ".$class->Name.": $msg"); + } + } +} + +{ # update ACLs + use RT::ACL; + my $acl = RT::ACL->new(RT->SystemUser); + $acl->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Class' ); + $acl->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::System' ); + while ( my $ace = $acl->Next ) { + if ( $ace->__Value('ObjectType') eq 'RT::FM::Class' ) { + my ($ret, $msg ) = $ace->__Set( Field => 'ObjectType', Value => 'RT::Class'); + warn "Fixing ACL ".$ace->Id." to refer to RT::Class: $msg"; + } elsif ( $ace->__Value('ObjectType') eq 'RT::FM::System' ) { + my ($ret, $msg) = $ace->__Set(Field => 'ObjectType', Value => 'RT::System'); + warn "Fixing ACL ".$ace->Id." to refer to RT::System: $msg"; + } + } + + +} + +{ # update CustomFields + use RT::CustomFields; + my $cfs = RT::CustomFields->new(RT->SystemUser); + $cfs->Limit( FIELD => 'LookupType', VALUE => 'RT::FM::Class-RT::FM::Article' ); + while ( my $cf = $cfs->Next ) { + my ($ret, $msg) = $cf->__Set( Field => 'LookupType', Value => 'RT::Class-RT::Article' ); + warn "Update Custom Field LookupType for CF.".$cf->Id." $msg"; + } +} + +{ # update ObjectCustomFieldValues + use RT::ObjectCustomFieldValues; + my $ocfvs = RT::ObjectCustomFieldValues->new(RT->System); + $ocfvs->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' ); + while ( my $ocfv = $ocfvs->Next ) { + my ($ret, $msg) = $ocfv->__Set( Field => 'ObjectType', Value => 'RT::Article' ); + warn "Updated CF ".$ocfv->__Value('CustomField')." Value for Article ".$ocfv->__Value('ObjectId'); + } + +} + +{ # update Topics + use RT::Topics; + my $topics = RT::Topics->new(RT->SystemUser); + $topics->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Class' ); + $topics->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::System' ); + while ( my $topic = $topics->Next ) { + if ( $topic->__Value('ObjectType') eq 'RT::FM::Class' ) { + my ($ret, $msg ) = $topic->__Set( Field => 'ObjectType', Value => 'RT::Class'); + warn "Fixing Topic ".$topic->Id." to refer to RT::Class: $msg"; + } elsif ( $topic->__Value('ObjectType') eq 'RT::FM::System' ) { + my ($ret, $msg) = $topic->__Set(Field => 'ObjectType', Value => 'RT::System'); + warn "Fixing Topic ".$topic->Id." to refer to RT::System: $msg"; + } + } +} + +{ # update ObjectTopics + use RT::ObjectTopics; + my $otopics = RT::ObjectTopics->new(RT->SystemUser); + $otopics->UnLimit; + while ( my $otopic = $otopics->Next ) { + if ( $otopic->ObjectType eq 'RT::FM::Article' ) { + my ($ret, $msg) = $otopic->SetObjectType('RT::Article'); + warn "Fixing Topic ".$otopic->Topic." to apply to article: $msg"; + } + } +} + +{ # update Links + use RT::Links; + my $links = RT::Links->new(RT->SystemUser); + $links->Limit(FIELD => 'Base', VALUE => 'rtfm', OPERATOR => 'LIKE', SUBCLAUSE => 'stopanding', ENTRYAGGREGATOR => 'OR'); + $links->Limit(FIELD => 'Target', VALUE => 'rtfm', OPERATOR => 'LIKE', SUBCLAUSE => 'stopanding', ENTRYAGGREGATOR => 'OR' ); + while ( my $link = $links->Next ) { + my $base = $link->__Value('Base'); + my $target = $link->__Value('Target'); + if ( $base =~ s/rtfm/article/i ) { + my ($ret, $msg) = $link->__Set( Field => 'Base', Value => $base ); + warn "Updating base to $base: $msg for link ".$link->id; + } + if ( $target =~ s/rtfm/article/i ) { + my ($ret, $msg) = $link->__Set( Field => 'Target', Value => $target ); + warn "Updating target to $target: $msg for link ".$link->id; + } + + } +} + +{ # update Transactions + # we only keep article transactions at this point + no warnings 'once'; + use RT::Transactions; + # Next calls Type to check readability and Type calls _Accessible + # which called CurrentUserCanSee which calls Object which tries to instantiate + # an RT::FM::Article. Rather than a shim RT::FM::Article class, I'm just avoiding + # the ACL check since we're running around as the superuser. + local *RT::Transaction::Type = sub { shift->__Value('Type') }; + my $transactions = RT::Transactions->new(RT->SystemUser); + $transactions->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' ); + while ( my $t = $transactions->Next ) { + my ($ret, $msg) = $t->__Set( Field => 'ObjectType', Value => 'RT::Article' ); + warn "Updated Transaction ".$t->Id." to point to RT::Article"; + } + + # we also need to change links that point to articles + $transactions = RT::Transactions->new(RT->SystemUser); + $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' ); + $transactions->Limit( FIELD => 'NewValue', VALUE => 'rtfm', OPERATOR => 'LIKE' ); + while ( my $t = $transactions->Next ) { + my $value = $t->__Value('NewValue'); + $value =~ s/rtfm/article/; + my ($ret, $msg) = $t->__Set( Field => 'NewValue', Value => $value ); + warn "Updated Transaction ".$t->Id." to link to $value"; + } +} + +{ # update Attributes + # these are all things we should make real columns someday + use RT::Attributes; + my $attributes = RT::Attributes->new(RT->SystemUser); + $attributes->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Class' ); + while ( my $a = $attributes->Next ) { + my ($ret,$msg) = $a->__Set( Field => 'ObjectType', Value => 'RT::Class' ); + warn "Updating Attribute ".$a->Name." to point to RT::Class"; + } +} diff --git a/rt/etc/upgrade/upgrade-articles.in b/rt/etc/upgrade/upgrade-articles.in new file mode 100644 index 000000000..b0f13d674 --- /dev/null +++ b/rt/etc/upgrade/upgrade-articles.in @@ -0,0 +1,264 @@ +#!@PERL@ +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC +# <sales@bestpractical.com> +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# +# CONTRIBUTION SUBMISSION POLICY: +# +# (The following paragraph is not intended to limit the rights granted +# to you to modify and distribute this software under the terms of +# the GNU General Public License and is only of importance to you if +# you choose to contribute your changes and enhancements to the +# community by submitting them to Best Practical Solutions, LLC.) +# +# By intentionally submitting any modifications, corrections or +# derivatives to this work, or any other work intended for use with +# Request Tracker, to Best Practical Solutions, LLC, you confirm that +# you are the copyright holder for those contributions and you grant +# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, +# royalty-free, perpetual, license to use, copy, create derivative +# works based on those contributions, and sublicense and distribute +# those contributions and any derivatives thereof. +# +# END BPS TAGGED BLOCK }}} +use strict; +use warnings; + +use lib "@LOCAL_LIB_PATH@"; +use lib "@RT_LIB_PATH@"; + +use RT; +RT::LoadConfig(); +RT->Config->Set('LogToScreen' => 'debug'); +RT::Init(); + +$| = 1; + +my $db_name = RT->Config->Get('DatabaseName'); +my $db_type = RT->Config->Get('DatabaseType'); + +my $dbh = $RT::Handle->dbh; + +my $sth = $dbh->table_info( '', undef, undef, "'TABLE'"); +my $found_fm_tables; +while ( my $table = $sth->fetchrow_hashref ) { + my $name = $table->{TABLE_NAME} || $table->{'table_name'}; # Oracle's table_info affected by NAME_lc + next unless $name =~ /^fm_/i; + $found_fm_tables->{lc $name}++; +} + +unless ( $found_fm_tables->{fm_topics} && $found_fm_tables->{fm_objecttopics} ) { + warn "Couldn't find topics tables, it appears you have RTFM 2.0 or earlier."; + warn "This script cannot yet upgrade RTFM versions which are that old"; + exit; +} + +{ # port over Articles + my @columns = qw(id Name Summary SortOrder Class Parent URI Creator Created LastUpdatedBy LastUpdated); + copy_tables('FM_Articles','Articles',\@columns); + +} + + +{ # port over Classes + my @columns = qw(id Name Description SortOrder Disabled Creator Created LastUpdatedBy LastUpdated); + if ( grep lc($_) eq 'hotlist', $RT::Handle->Fields('FM_Classes') ) { + push @columns, 'HotList'; + } + copy_tables('FM_Classes','Classes',\@columns); +} + +{ # port over Topics + my @columns = qw(id Parent Name Description ObjectType ObjectId); + copy_tables('FM_Topics','Topics',\@columns); +} + +{ # port over ObjectTopics + my @columns = qw(id Topic ObjectType ObjectId); + copy_tables('FM_ObjectTopics','ObjectTopics',\@columns); +} + +sub copy_tables { + my ($source, $dest, $columns) = @_; + my $column_list = join(', ',@$columns); + my $sql; + # SQLite: http://www.sqlite.org/lang_insert.html + if ( $db_type eq 'mysql' || $db_type eq 'SQLite' ) { + $sql = "insert into $dest ($column_list) select $column_list from $source"; + } + # Oracle: http://www.adp-gmbh.ch/ora/sql/insert/select_and_subquery.html + elsif ( $db_type eq 'Pg' || $db_type eq 'Oracle' ) { + $sql = "insert into $dest ($column_list) (select $column_list from $source)"; + } + $RT::Logger->debug($sql); + $dbh->do($sql); +} + +{ # create ObjectClasses + # this logic will need updating when folks have an FM_ObjectClasses table + use RT::Classes; + use RT::ObjectClass; + + my $classes = RT::Classes->new(RT->SystemUser); + $classes->UnLimit; + while ( my $class = $classes->Next ) { + my $objectclass = RT::ObjectClass->new(RT->SystemUser); + my ($ret, $msg ) = $objectclass->Create( Class => $class->Id, ObjectType => 'RT::System', ObjectId => 0 ); + if ($ret) { + warn("Applied Class '".$class->Name."' globally"); + } else { + warn("Couldn't create linkage for Class ".$class->Name.": $msg"); + } + } +} + +{ # update ACLs + use RT::ACL; + my $acl = RT::ACL->new(RT->SystemUser); + $acl->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Class' ); + $acl->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::System' ); + while ( my $ace = $acl->Next ) { + if ( $ace->__Value('ObjectType') eq 'RT::FM::Class' ) { + my ($ret, $msg ) = $ace->__Set( Field => 'ObjectType', Value => 'RT::Class'); + warn "Fixing ACL ".$ace->Id." to refer to RT::Class: $msg"; + } elsif ( $ace->__Value('ObjectType') eq 'RT::FM::System' ) { + my ($ret, $msg) = $ace->__Set(Field => 'ObjectType', Value => 'RT::System'); + warn "Fixing ACL ".$ace->Id." to refer to RT::System: $msg"; + } + } + + +} + +{ # update CustomFields + use RT::CustomFields; + my $cfs = RT::CustomFields->new(RT->SystemUser); + $cfs->Limit( FIELD => 'LookupType', VALUE => 'RT::FM::Class-RT::FM::Article' ); + while ( my $cf = $cfs->Next ) { + my ($ret, $msg) = $cf->__Set( Field => 'LookupType', Value => 'RT::Class-RT::Article' ); + warn "Update Custom Field LookupType for CF.".$cf->Id." $msg"; + } +} + +{ # update ObjectCustomFieldValues + use RT::ObjectCustomFieldValues; + my $ocfvs = RT::ObjectCustomFieldValues->new(RT->System); + $ocfvs->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' ); + while ( my $ocfv = $ocfvs->Next ) { + my ($ret, $msg) = $ocfv->__Set( Field => 'ObjectType', Value => 'RT::Article' ); + warn "Updated CF ".$ocfv->__Value('CustomField')." Value for Article ".$ocfv->__Value('ObjectId'); + } + +} + +{ # update Topics + use RT::Topics; + my $topics = RT::Topics->new(RT->SystemUser); + $topics->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Class' ); + $topics->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::System' ); + while ( my $topic = $topics->Next ) { + if ( $topic->__Value('ObjectType') eq 'RT::FM::Class' ) { + my ($ret, $msg ) = $topic->__Set( Field => 'ObjectType', Value => 'RT::Class'); + warn "Fixing Topic ".$topic->Id." to refer to RT::Class: $msg"; + } elsif ( $topic->__Value('ObjectType') eq 'RT::FM::System' ) { + my ($ret, $msg) = $topic->__Set(Field => 'ObjectType', Value => 'RT::System'); + warn "Fixing Topic ".$topic->Id." to refer to RT::System: $msg"; + } + } +} + +{ # update ObjectTopics + use RT::ObjectTopics; + my $otopics = RT::ObjectTopics->new(RT->SystemUser); + $otopics->UnLimit; + while ( my $otopic = $otopics->Next ) { + if ( $otopic->ObjectType eq 'RT::FM::Article' ) { + my ($ret, $msg) = $otopic->SetObjectType('RT::Article'); + warn "Fixing Topic ".$otopic->Topic." to apply to article: $msg"; + } + } +} + +{ # update Links + use RT::Links; + my $links = RT::Links->new(RT->SystemUser); + $links->Limit(FIELD => 'Base', VALUE => 'rtfm', OPERATOR => 'LIKE', SUBCLAUSE => 'stopanding', ENTRYAGGREGATOR => 'OR'); + $links->Limit(FIELD => 'Target', VALUE => 'rtfm', OPERATOR => 'LIKE', SUBCLAUSE => 'stopanding', ENTRYAGGREGATOR => 'OR' ); + while ( my $link = $links->Next ) { + my $base = $link->__Value('Base'); + my $target = $link->__Value('Target'); + if ( $base =~ s/rtfm/article/i ) { + my ($ret, $msg) = $link->__Set( Field => 'Base', Value => $base ); + warn "Updating base to $base: $msg for link ".$link->id; + } + if ( $target =~ s/rtfm/article/i ) { + my ($ret, $msg) = $link->__Set( Field => 'Target', Value => $target ); + warn "Updating target to $target: $msg for link ".$link->id; + } + + } +} + +{ # update Transactions + # we only keep article transactions at this point + no warnings 'once'; + use RT::Transactions; + # Next calls Type to check readability and Type calls _Accessible + # which called CurrentUserCanSee which calls Object which tries to instantiate + # an RT::FM::Article. Rather than a shim RT::FM::Article class, I'm just avoiding + # the ACL check since we're running around as the superuser. + local *RT::Transaction::Type = sub { shift->__Value('Type') }; + my $transactions = RT::Transactions->new(RT->SystemUser); + $transactions->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' ); + while ( my $t = $transactions->Next ) { + my ($ret, $msg) = $t->__Set( Field => 'ObjectType', Value => 'RT::Article' ); + warn "Updated Transaction ".$t->Id." to point to RT::Article"; + } + + # we also need to change links that point to articles + $transactions = RT::Transactions->new(RT->SystemUser); + $transactions->Limit( FIELD => 'Type', VALUE => 'AddLink' ); + $transactions->Limit( FIELD => 'NewValue', VALUE => 'rtfm', OPERATOR => 'LIKE' ); + while ( my $t = $transactions->Next ) { + my $value = $t->__Value('NewValue'); + $value =~ s/rtfm/article/; + my ($ret, $msg) = $t->__Set( Field => 'NewValue', Value => $value ); + warn "Updated Transaction ".$t->Id." to link to $value"; + } +} + +{ # update Attributes + # these are all things we should make real columns someday + use RT::Attributes; + my $attributes = RT::Attributes->new(RT->SystemUser); + $attributes->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Class' ); + while ( my $a = $attributes->Next ) { + my ($ret,$msg) = $a->__Set( Field => 'ObjectType', Value => 'RT::Class' ); + warn "Updating Attribute ".$a->Name." to point to RT::Class"; + } +} |