import rt 3.6.10
[freeside.git] / rt / sbin / rt-dump-database
diff --git a/rt/sbin/rt-dump-database b/rt/sbin/rt-dump-database
new file mode 100755 (executable)
index 0000000..647781d
--- /dev/null
@@ -0,0 +1,173 @@
+#!/usr/bin/perl -w
+# BEGIN BPS TAGGED BLOCK {{{
+# 
+# COPYRIGHT:
+#  
+# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC 
+#                                          <jesse@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 lib "/opt/rt3/local/lib";
+use lib "/opt/rt3/lib";
+
+use RT;
+use XML::Simple;
+
+RT::LoadConfig();
+RT::Init();
+
+my $LocalOnly = @ARGV ? shift(@ARGV) : 1;
+
+my %RV;
+my %Ignore = (
+    All => [qw(
+       id Created Creator LastUpdated LastUpdatedBy
+    )],
+    Templates => [qw(
+       TranslationOf
+    )],
+);
+
+my $SystemUserId = $RT::SystemUser->Id;
+my @classes = qw(
+    Users Groups Queues ScripActions ScripConditions
+    Templates Scrips ACL CustomFields
+);
+foreach my $class (@classes) {
+    require "RT/$class.pm";
+    my $objects = "RT::$class"->new($RT::SystemUser);
+    $objects->{find_disabled_rows} = 1;
+    $objects->UnLimit;
+
+    if ($class eq 'CustomFields') {
+        $objects->OrderByCols(
+            { FIELD => 'LookupType' },
+            { FIELD => 'SortOrder' },
+            { FIELD => 'Id' },
+        );
+    }
+    else {
+        $objects->OrderBy( FIELD => 'Id' );
+    }
+
+    if ($LocalOnly) {
+        next if $class eq 'ACL'; # XXX - would go into infinite loop - XXX
+       $objects->Limit( FIELD => 'LastUpdatedBy', OPERATOR => '!=', VALUE => $SystemUserId )
+           unless $class eq 'Groups';
+       $objects->Limit( FIELD => 'Id', OPERATOR => '!=', VALUE => $SystemUserId )
+           if $class eq 'Users';
+       $objects->Limit( FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined' )
+           if $class eq 'Groups';
+    }
+
+    my %fields;
+    while (my $obj = $objects->Next) {
+       next if $obj->can('LastUpdatedBy') and $obj->LastUpdatedBy == $SystemUserId;
+
+       if (!%fields) {
+           %fields = map { $_ => 1 } keys %{$obj->_ClassAccessible};
+           delete @fields{
+               @{$Ignore{$class}||=[]},
+               @{$Ignore{All}||=[]},
+           };
+       }
+
+       my $rv;
+       # next if $obj-> # skip default names
+       foreach my $field (sort keys %fields) {
+           my $value = $obj->__Value($field);
+           $rv->{$field} = $value if length($value);
+       }
+       delete $rv->{Disabled} unless $rv->{Disabled};
+
+       foreach my $record (map { /ACL/ ? 'ACE' : substr($_, 0, -1) } @classes) {
+           foreach my $key (map "$record$_", ('', 'Id')) {
+               next unless exists $rv->{$key};
+               my $id = $rv->{$key} or next;
+               my $obj = "RT::$record"->new($RT::SystemUser);
+               $obj->LoadByCols( Id => $id ) or next;
+               $rv->{$key} = $obj->__Value('Name') || 0;
+           }
+       }
+
+       if ($class eq 'Users' and defined $obj->Privileged) {
+           $rv->{Privileged} = int($obj->Privileged);
+       }
+       elsif ($class eq 'CustomFields') {
+           my $values = $obj->Values;
+           while (my $value = $values->Next) {
+               push @{$rv->{Values}}, {
+                   map { ($_ => $value->__Value($_)) } qw(
+                       Name Description SortOrder
+                   ),
+               };
+           }
+       }
+
+       if (eval { require RT::Attributes; 1 }) {
+           my $attributes = $obj->Attributes;
+           while (my $attribute = $attributes->Next) {
+               my $content = $attribute->Content;
+               $rv->{Attributes}{$attribute->Name} = $content if length($content);
+           }
+       }
+
+       push @{$RV{$class}}, $rv;
+    }
+}
+
+print(<< ".");
+no strict; use XML::Simple; *_ = XMLin(do { local \$/; readline(DATA) }, ForceArray => [qw(
+ @classes Values
+)], NoAttr => 1, SuppressEmpty => ''); *\$_ = (\$_{\$_} || []) for keys \%_; 1; # vim: ft=xml
+__DATA__
+.
+
+print XMLout(
+    { map { ($_ => ($RV{$_} || [])) } @classes },
+    RootName => 'InitialData',
+    NoAttr => 1,
+    SuppressEmpty => '',
+    XMLDecl => '<?xml version="1.0" encoding="UTF-8"?>',
+);